내장 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

또한 컨테이너 이름 만 사용하여 IP 주소를 할당 할 수 없었습니다. 컨테이너와 DHCP 구성을 위해 MAC 주소를 하드 코딩해야했습니다.
HRJ

@HRJ, dnsmasq.conf 파일을 게시 해 주시겠습니까?
tonytony

@HRJ Ubuntu 14.04에서 lxc-netlxcbr0 브리지를 제거하지 않으면 다시 시작해도 도움이되지 않습니다. 내 대답을 참조하십시오.
Adam Ryczkowski

답변:


17

최근 에이 문제가 발생하여 쉬운 해결책을 찾았습니다. 나는 우분투 14.04에서 테스트했다.

먼저 / etc / default / lxc-net 줄의 주석을 해제하십시오 :

LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf

/etc/lxc/dnsmasq.conf에서 dhcp-hosts 파일을 정의하십시오.

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을 다시 시작해야하지만 한 번만 다시 시작해야합니다. 도움이 되었기를 바랍니다.


호스트 목록을 외부 파일로 위임한다는 아이디어가 마음에 듭니다. 게다가, 귀하의 방법은로 인해 내 것과 다릅니다 killall -s SIGHUP dnsmasq. "SIGHUP-ing"dnsmasq 만 전체 데몬을 다시 시작하는 것보다 효율적입니다 (특히 시작 스크립트를 패치하지 않고 작동하지 않는 경우).
Adam Ryczkowski

서비스를 다시 시작하면 lxc-netdnsmasq가 /etc/lxc/dnsmasq.conf의 구성을 사용하도록해야합니다 (이 정보는 /etc/default/lxc-net에 알려지지 않음 dnsmasq). 이전에 설정 한 경우 다른 SIGHUP만으로도 충분합니다.
Adam Ryczkowski

주의 : 실행중인 컨테이너가있는 경우 lxc-net은 dnsmasq를 다시 시작하지 않습니다.
s3v3n

IMO 이것이 최고의 답변입니다.
s3v3n

kill -HUP $(cat /var/run/lxc/dnsmasq.pid)killall다른 dnsmasq인스턴스 를 설치 하거나 다시로드 하지 않으려는 경우
gertas

4

우분투 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

예, 사실 것을, 그것은 :( 아주 불편 내가 편집에 훨씬 쉽게 솔루션을 찾을 수 있습니다. /var/lib/lxc/<container-name>/rootfs/etc/network/interfaces컨테이너에 파일을 할당 정적 IP 주소를.
Tombart

그러나 두 명의 게스트에게 동일한 IP를 제공하는 것을 막을 방법은 없습니다. 내 대답을 참조하십시오-문제를 해결합니다.
Adam Ryczkowski

1

Tombart의 답변은 DNS 새로 고침을 기다릴만큼 충분히 기다려서 나중에 컨테이너 (게스트)를 다시 시작하려는 경우 작동합니다.

다음은 가능한 다른 모든 lxc 컨테이너를 종료 해야하는 레시피입니다 . 당신이 그것을 감당할 수 없다면, 나는 새로운 dnsmasq 구성을 강요 할 방법이 없습니다. (어떤 이유로 dnsmasq의 pid에 HUP 신호를 보내는 것도 /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하지만 일반적으로 값이있는 경우 with 의 값을 얻을 수 있습니다 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.conf Ubuntu 14.04 dnsmasq에는 브리지 장치가 호스트 용으로 다운되지 않는 한 재로드를 방지 있습니다.


0

이 솔루션은 lxc upstart 스크립트를 패치하여 작동합니다. lxcbr0 브리지를 시작하고 시작하는 복잡한 작업 dnsmasq을 두 개의 개별 작업으로 분할합니다 . 이제 전체 lxc-net브리지를 다시 시작하기 위해 다시 로드 할 필요가 없습니다 .dnsmasq 다시로드하는 sudo service restart lxc-dnsmasq것으로 충분하며 브리지를 종료 할 필요가 없습니다.

  1. lxc-net 서비스를 중지하고 sudo service lxc-net stoplxcbr0 (또는 이와 동등한) 브리지가 없는지 확인하십시오.
  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 임대를 해제하는 간단한 파이썬 스크립트입니다. 호스트 컴퓨터에서 실행하거나 다른 컨테이너에서 위조 할 수 있습니다.

#!/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 library입니다.

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

내 답변이 몇 년 늦었다는 것을 알고 있지만 다른 사람에게 도움이 될 수 있습니다. 문제는 스크립트 자체 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=""
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.