วิธีการให้ DHCP ในตัวกำหนด IP แบบคงที่ให้กับคอนเทนเนอร์ LXC ตามชื่อไม่ใช่ที่อยู่ MAC


10

ผมรู้ว่าผมสามารถกำหนด IP /etc/network/interfacesแบบคงที่ด้วยตนเองโดยใช้

ฉันยังรู้ว่าฉันสามารถอ่านที่อยู่ MAC ของภาชนะ LXC (เช่นโดยการมองหาlxc.network.hwaddrรายการใน/var/lib/lxc/<container-name>/configและกำหนดไอพีโดยใช้รายการใน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 โดยใช้ชื่อคอนเทนเนอร์เพียงอย่างเดียว ฉันต้องฮาร์ดโค้ดที่อยู่ MAC ของคอนเทนเนอร์และสำหรับการกำหนดค่า DHCP
HRJ

@HRJ คุณช่วยโพสต์ไฟล์ dnsmasq.conf ของคุณได้มั้ย
tonytony

@HRJ บน Ubuntu 14.04 การรีสตาร์ทlxc-netไม่ช่วยถ้าคุณไม่เอา lxcbr0 bridge ของคุณ ดูคำตอบของฉัน
Adam Ryczkowski

คำตอบ:


17

ฉันวิ่งเข้าไปในนี้เมื่อเร็ว ๆ นี้และฉันคิดว่าฉันพบทางออกที่ง่าย ฉัน (เท่านั้น) ทดสอบบน Ubuntu 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 นั้นมีประสิทธิภาพมากกว่าจากนั้นรีสตาร์ท daemon ทั้งหมด (โดยเฉพาะถ้ามันใช้งานไม่ได้
Adam Ryczkowski

การรีสตาร์ทเซอร์วิสlxc-netจำเป็นต้องมีเพื่อให้ dnsmasq ใช้การกำหนดค่าจาก /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

มันทำงานได้ดีใน 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

ใช่ว่าเป็นจริงก็ไม่สะดวกค่อนข้าง :( ผมหาทางออกง่ายมากที่จะแก้ไข. /var/lib/lxc/<container-name>/rootfs/etc/network/interfacesไฟล์และที่อยู่ IP แบบคงที่กำหนดกับภาชนะบรรจุ.
Tombart

จริง แต่ไม่มีอะไรที่จะปกป้องคุณจากการให้ IP แขกคนเดียวกัน ดูคำตอบที่ฉันยอมรับ - มันช่วยแก้ปัญหาได้
Adam Ryczkowski

1

คำตอบของ Tombart ใช้งานได้หากคุณอดทนรอการรีเฟรช DNS และคุณยินดีที่จะรีสตาร์ทคอนเทนเนอร์ (แขก) หลังจากนั้น

สิ่งต่อไปนี้เป็นสูตรที่กำหนดว่าภาชนะบรรจุ LXC อาจจะทำงานอื่น ๆ ทั้งหมดจะปิดตัวลง หากคุณไม่สามารถจ่ายได้ฉันก็จะเห็นว่าไม่มีทางบังคับให้ตั้งค่า dnsmasq ใหม่ (สำหรับการส่งสัญญาณ HUP บางครั้งถึง pid ของ dnsmasq ที่พบใน/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-toolslxcbr0

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 bridge ขึ้นและเริ่มdnsmasqงานแยกกันสองงาน ตอนนี้คุณไม่จำเป็นต้องรีสตาร์ท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 lease คุณสามารถเรียกใช้จากเครื่องโฮสต์หรือปลอมจากภาชนะอื่น - ใช่ว่าใช้งานได้!:

#!/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.