組み込みDHCPがMACアドレスではなく名前に基づいてLXCコンテナーに静的IPを割り当てるようにする方法


10

私は、を使用して静的IPを手動で割り当てることができることを知ってい/etc/network/interfacesます。

また、LXCコンテナのMACアドレスを読み取ることができることも知っています(たとえば、でlxc.network.hwaddrエントリを探し、のエントリ/var/lib/lxc/<container-name>/configを使用してIPを割り当てることdhcp-host=<mac-addr>,10.0.3.3によって)/etc/dnsmasq.d/<some file>

/etc/default/lxc-net私が読んだファイル

# Uncomment the next line if you'd like to use a conf-file for the lxcbr0
# dnsmasq.  For instance, you can use 'dhcp-host=mail1,10.0.3.100' to have
# container 'mail1' always get ip address 10.0.3.100.
#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

それは私のニーズに合うでしょう。残念ながらそうしても効果はありません。


2
私には問題ありませんが、有効にするにはlxc-netを再起動する必要があることに注意してください。また、コンテナが現在起動されている場合、lxc-netが再起動しないという既知の問題があります。それらのすべてを停止してから、lxc-netサービスを再起動する必要があります。
HRJ 2014

また、コンテナー名だけを使用してIPアドレスを割り当てることができませんでした。コンテナーとDHCP構成のMACアドレスをハードコーディングする必要がありました。
HRJ 2014

@ HRJ、dnsmasq.confファイルを投稿してください。
トニートニー2014

@HRJ Ubuntu 14.04ではlxc-net、lxcbr0ブリッジを削除しないと、再起動しても効果がありません。私の答えを見てください。
Adam Ryczkowski、2014年

回答:


17

最近これに遭遇し、簡単な解決策を見つけたと思います。私は(のみ)Ubuntu 14.04でテストしました。

まず、この行/ etc / default / lxc-netのコメントを解除します。

LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

/etc/lxc/dnsmasq.confで、dhcp-hostsfileを定義します。

dhcp-hostsfile=/etc/lxc/dnsmasq-hosts.conf

次に、次のように/etc/lxc/dnsmasq-hosts.confにエントリを追加します。

mail,10.0.3.16
web,10.0.3.17

注意:lxc-net(dnsmasqを再起動)を再起動すると、変更が有効になります。

service lxc-net restart

その後、/ etc / lxc / dnsmasq-hosts.confを変更して、SIGHUPシグナルをdnsmasqに送信できます。

killall -s SIGHUP dnsmasq

つまり、lxc-netを再起動する必要がありますが、1回だけです。お役に立てれば。


ホストのリストを外部ファイルに委任するのが好きです。それ以外に、あなたの方法はkillall -s SIGHUP dnsmasq。のために私のものとは異なります。私は同意します。「SIGHUPを実行する」dnsmasqはデーモン全体を再起動するよりも効率的です(特に、upstartスクリプトにパッチを適用しないと機能しない場合)。
Adam Ryczkowski、2015年

サービスを再lxc-net起動する必要があるのは、dnsmasqが/etc/lxc/dnsmasq.confからの構成を使用できるようにするためだけです(この情報は、/etc/default/lxc-netには不明なにありますdnsmasq)。以前に設定したことがある場合は、別のSIGHUPで十分です。
Adam Ryczkowski、2015年

注意:実行中のコンテナがある場合、lxc-netはdnsmasqを再起動しません。
s3v3n 2015年

IMOこれが最良の答えです
s3v3n 2015年

kill -HUP $(cat /var/run/lxc/dnsmasq.pid)killall他のdnsmasqインスタンスをインストールまたはリロードしたくない場合
gertas

4

Ubuntu 14.04.1では問題なく動作します

この行のコメントを外します /etc/default/lxc-net

#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

すべてのコンテナを停止し、lxc-netを再起動します。

service lxc-net restart

でIPアドレスを構成する /etc/lxc/dnsmasq.conf

dhcp-host={NAME},10.0.3.2

どこ{NAME}あなたのLXCコンテナの名前は次のようになります。

/var/lib/lxc/{NAME}

それは作品のスクリプトがlxcbr0ネットワークシャットダウンできる場合にのみ実行されている他のLXCコンテナがある場合を除外し、。つまり、現在のところ、すべてのコンテナを再起動せずに静的DHCPリースを割り当てることはできません。
Adam Ryczkowski、2014年

。はい、本当、それはかなり不便:(だ私が編集にはるかに簡単に解決策を見つけること/var/lib/lxc/<container-name>/rootfs/etc/network/interfaces。ファイルやコンテナへの割り当て静的IPアドレスを
Tombart

正しいですが、2人のゲストに同じIPを与えることからあなたを守るものは何もありません。私の受け入れられた答えを見てください-それは問題を解決します。
Adam Ryczkowski、2014年

1

Tombartの回答は、DNSの更新を待つのに十分な忍耐力があり、後でコンテナー(ゲスト)を再起動する意思がある場合に機能します。

以下は、実行中の他のすべてのlxcコンテナをシャットダウンする必要があるレシピです。余裕がない場合は、新しいdnsmasq構成を強制する方法はありません。(何らかの理由で、HUPがdnsmasqのpidにあるpidに信号を送っ/run/lxc/dnsmasq.pidても機能しません。)

したがって、すぐに機能するものがあり、実行中の他のlxcコンテナがない場合は、私の答えに従ってください。$name割り当てをリセットするノード$internalifの名前であり、LXCのブリッジアダプターの名前です。あなたは、の値を得ることができる$internalifなどしてaugtool -L -A --transform "Shellvars incl /etc/default/lxc-net" get "/files/etc/default/lxc-net/LXC_BRIDGE" | sed -En 's/\/.* = (.*)/\1/p'、インストールする場合はaugeas-tools通常、それだけですlxcbr0

sudo lxc-stop -n $name >/dev/null
sudo service lxc-net stop >/dev/null
if [ -d /sys/class/net/$internalif ]; then
   sudo brctl delbr $internalif >/dev/null #Why? See below.
fi
sudo rm /var/lib/misc/dnsmasq.$internalif.leases
sudo service lxc-net start >/dev/null
sudo lxc-start -d -n $name >/dev/null
sleep 5

残念ながら、/etc/init/lxc-net.confUbuntu 14.04のにはバグがあり(機能?)dnsmasq、ブリッジデバイスがホストに対してダウンしていない限り、のリロードが妨げられます。


0

このソリューションは、lxc upstartスクリプトにパッチを適用することで機能します。lxcbr0ブリッジを起動してa dnsmasqを開始するという複雑なタスクを2つの別々のジョブに分割します。今、あなたは全体の再起動する必要はありませんlxc-netだけでリロードにブリッジをdnsmasqリロードする- sudo service restart lxc-dnsmasq十分であり、橋をシャットダウンする必要はありません。

  1. lxc-netサービスsudo service lxc-net stopを停止し、lxcbr0 (または同等の)ブリッジアップがないことを確認します。
  2. の内容を/etc/init/lxc-net.conf次の内容に置き換えます。

description "lxc network"
author "Serge Hallyn <serge.hallyn@canonical.com>"

start on starting lxc
stop on stopped lxc

env USE_LXC_BRIDGE="true"
env LXC_BRIDGE="lxcbr0"
env LXC_ADDR="10.0.3.1"
env LXC_NETMASK="255.255.255.0"
env LXC_NETWORK="10.0.3.0/24"
env varrun="/run/lxc"
env LXC_DOMAIN=""

pre-start script
    [ -f /etc/default/lxc ] && . /etc/default/lxc

    [ "x$USE_LXC_BRIDGE" = "xtrue" ] || { stop; exit 0; }

    use_iptables_lock="-w"
    iptables -w -L -n > /dev/null 2>&1 || use_iptables_lock=""
    cleanup() {
        # dnsmasq failed to start, clean up the bridge
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT
        iptables $use_iptables_lock -D FORWARD -i ${LXC_BRIDGE} -j ACCEPT
        iptables $use_iptables_lock -D FORWARD -o ${LXC_BRIDGE} -j ACCEPT
        iptables $use_iptables_lock -t nat -D POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE || true
        iptables $use_iptables_lock -t mangle -D POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
        ifconfig ${LXC_BRIDGE} down || true
        brctl delbr ${LXC_BRIDGE} || true
    }
    if [ -d /sys/class/net/${LXC_BRIDGE} ]; then
        if [ ! -f ${varrun}/network_up ]; then
            # bridge exists, but we didn't start it
            stop;
        fi
        exit 0;
    fi

    # set up the lxc network
    brctl addbr ${LXC_BRIDGE} || { echo "Missing bridge support in kernel"; stop; exit 0; }
    echo 1 > /proc/sys/net/ipv4/ip_forward
    mkdir -p ${varrun}
    ifconfig ${LXC_BRIDGE} ${LXC_ADDR} netmask ${LXC_NETMASK} up
    iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT
    iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT
    iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT
    iptables $use_iptables_lock -I INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT
    iptables $use_iptables_lock -I FORWARD -i ${LXC_BRIDGE} -j ACCEPT
    iptables $use_iptables_lock -I FORWARD -o ${LXC_BRIDGE} -j ACCEPT
    iptables $use_iptables_lock -t nat -A POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE
    iptables $use_iptables_lock -t mangle -A POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill

    touch ${varrun}/network_up
end script

post-stop script
    [ -f /etc/default/lxc ] && . /etc/default/lxc
    [ -f "${varrun}/network_up" ] || exit 0;
    # if $LXC_BRIDGE has attached interfaces, don't shut it down
    ls /sys/class/net/${LXC_BRIDGE}/brif/* > /dev/null 2>&1 && exit 0;

    if [ -d /sys/class/net/${LXC_BRIDGE} ]; then
        use_iptables_lock="-w"
        iptables -w -L -n > /dev/null 2>&1 || use_iptables_lock=""
        ifconfig ${LXC_BRIDGE} down
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 67 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 67 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 53 -j ACCEPT
        iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 53 -j ACCEPT
        iptables $use_iptables_lock -D FORWARD -i ${LXC_BRIDGE} -j ACCEPT
        iptables $use_iptables_lock -D FORWARD -o ${LXC_BRIDGE} -j ACCEPT
        iptables $use_iptables_lock -t nat -D POSTROUTING -s ${LXC_NETWORK} ! -d ${LXC_NETWORK} -j MASQUERADE || true
        iptables $use_iptables_lock -t mangle -D POSTROUTING -o ${LXC_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
        pid=`cat ${varrun}/dnsmasq.pid 2>/dev/null` && kill -9 $pid || true
        rm -f ${varrun}/dnsmasq.pid
        brctl delbr ${LXC_BRIDGE}
    fi
    rm -f ${varrun}/network_up
end script
  1. /etc/init/lxc-dnsmasq次の内容の別のファイルを追加します。

description "lxc dnsmasq service"
author "Adam Ryczkowski, ispired by Serge Hallyn <serge.hallyn@canonical.com>"

expect fork

start on started lxc-net
stop on stopped lxc-net

env USE_LXC_BRIDGE="true"
env LXC_BRIDGE="lxcbr0"
env LXC_ADDR="10.0.3.1"
env LXC_NETMASK="255.255.255.0"
env LXC_NETWORK="10.0.3.0/24"
env LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
env LXC_DHCP_MAX="253"
env LXC_DHCP_CONFILE=""
env varrun="/run/lxc-dnsmasq"
env LXC_DOMAIN=""

pre-start script
    [ -f /etc/default/lxc ] && . /etc/default/lxc

    [ "x$USE_LXC_BRIDGE" = "xtrue" ] || { stop; exit 0; }

    if [ ! -d ${varrun} ]; then
        mkdir -p ${varrun}
    fi
    opts="$LXC_DOMAIN_ARG -u lxc-dnsmasq --strict-order --bind-interfaces --pid-file=${varrun}/dnsmasq.pid --conf-file=${LXC_DHCP_CONFILE} --listen-address ${LXC_ADDR} --dhcp-range ${LXC_DHCP_RANGE} --dhcp-lease-max=${LXC_DHCP_MAX} --dhcp-no-override --except-interface=lo --interface=${LXC_BRIDGE} --dhcp-leasefile=/var/lib/misc/dnsmasq2.${LXC_BRIDGE}.leases --dhcp-authoritative --keep-in-foreground"

    /usr/sbin/dnsmasq $opts &

end script

post-stop script
    if [ -f ${varrun}/dnsmasq.pid ]; then
        PID=`cat ${varrun}/dnsmasq.pid`
        kill $PID
    fi
end script

0

LXC dnsmasqリースを解放する単純なpythonスクリプトを次に示します。ホストマシンから実行することも、別のコンテナから偽造することもできます-はい、動作します!:

#!/usr/bin/env python
from scapy.all import *
conf.checkIPaddr=False
leaseMAC = '00:16:3e:11:71:b0' #container MAC here
releaseIP='10.0.3.33' #container IP here
serverIP='10.0.3.1'
hostname='container-name-here'
rawMAC = leaseMAC.replace(':','').decode('hex')
send(IP(dst=serverIP) / \
     UDP(sport=68,dport=67) / \
     BOOTP(chaddr=rawMAC, ciaddr=releaseIP, xid=RandInt()) / \
     DHCP(options=[('message-type','release'),('server_id',serverIP),('hostname',hostname), ('end')]))

上記の前提条件は、scapy pythonライブラリです。

pip install scapy

実行すると、次のようなシステムログが表示されます。

dnsmasq-dhcp[3242]: DHCPRELEASE(lxcbr0) 10.0.3.33 00:16:3e:11:71:b0 container-name-here

確認するには、エントリがから削除されているかどうかを確認し/var/lib/misc/dnsmasq.lxcbr0.leasesます。コンテナー自体はIPを保持するため、IPを再利用する新しいコンテナーを開始する前に停止する必要があります。


1
カッコいい!DHCPがサポートしていることさえ知りませんでした!動作確認後すぐに賛成票を投じます。
Adam Ryczkowski

0

私の答えは何年も遅れていることに気づきましたが、多分それが誰かを助けるでしょう。問題は、LXC Ubuntuパッケージ(write_lxc_net関数)に固有のコードを編集したことです。このコードは、lxc-netスクリプト自体では処理されず、文字列として別の宛先に書き込まれることを意図していたのです。

その結果、dnsmasqプロセスは、渡そうとした設定ファイルを受信しなかったため、言うように「影響なし」のままになります。

代わりに、残りのスクリプトの中で、この変数をスクリプトの上部近くに設定します。

#!/bin/sh -

distrosysconfdir="/etc/default"
varrun="/run/lxc"
varlib="/var/lib"

# These can be overridden in /etc/default/lxc
#   or in /etc/default/lxc-net

USE_LXC_BRIDGE="true"
LXC_BRIDGE="lxcbr0"
LXC_BRIDGE_MAC="00:16:3e:00:00:00"
LXC_ADDR="10.0.3.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="10.0.3.0/24"
LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
LXC_DHCP_MAX="253"
LXC_DHCP_CONFILE="/etc/lxc/dnsmasq.conf"   <-- Here for instance
LXC_DOMAIN=""
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.