web-dev-qa-db-ja.com

ビルトインDHCPがMACアドレスではなく名前に基づいて静的IPをLXCコンテナに割り当てる方法

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

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

ファイル/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

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

10
Adam Ryczkowski

このソリューションは、lxc upstartスクリプトにパッチを適用することで機能します。 lxcbr0ブリッジを起動して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 <[email protected]>"

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 <[email protected]>"

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
Adam Ryczkowski

私は最近これに遭遇し、簡単な解決策を見つけたと思います。私は、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を一度だけ再起動する必要があります。お役に立てれば。

16
mtp

Ubuntu 14.04.1で正常に動作します

この行のコメントを解除/etc/default/lxc-net

#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

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

service lxc-net restart

/etc/lxc/dnsmasq.confでIPアドレスを設定します

dhcp-Host={NAME},10.0.3.2

{NAME}はLXCコンテナの名前です:

/var/lib/lxc/{NAME}
4
Tombart

DNSの更新を待つだけの忍耐があり、その後コンテナ(ゲスト)を再起動しても構わない場合、Tombartの答えは機能します。

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

したがって、すぐに動作し、実行中の他の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

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

1
Adam Ryczkowski

私の答えは何年も遅れていることを理解していますが、おそらく他の誰かに役立つでしょう。問題は、write_lxc_netスクリプト自体では処理されず、文字列として別の宛先に書き込まれることを意図したLXC Ubuntuパッケージ固有のコード(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=""
0
Adrian

以下は、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を再利用する新しいコンテナを開始する前にIPを停止する必要があります。

0
gertas