![如何让内置 DHCP 根据名称而不是 MAC 地址为 LXC 容器分配静态 IP](https://linux22.com/image/852329/%E5%A6%82%E4%BD%95%E8%AE%A9%E5%86%85%E7%BD%AE%20DHCP%20%E6%A0%B9%E6%8D%AE%E5%90%8D%E7%A7%B0%E8%80%8C%E4%B8%8D%E6%98%AF%20MAC%20%E5%9C%B0%E5%9D%80%E4%B8%BA%20LXC%20%E5%AE%B9%E5%99%A8%E5%88%86%E9%85%8D%E9%9D%99%E6%80%81%20IP.png)
我知道,我可以使用 手动分配静态 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
这会满足我的需要;但不幸的是,这样做没有效果。
答案1
我最近遇到了这个问题,我想我找到了一个简单的解决方案。我(仅)在 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 并向 dnsmasq 发送 SIGHUP 信号:
killall -s SIGHUP dnsmasq
所以是的,您需要重新启动 lxc-net,但只需重新启动一次。希望这能有所帮助。
答案2
它在 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}
答案3
如果您有足够的耐心等待 DNS 刷新并且愿意随后重新启动容器(客户机),那么 Tombart 的答案就会有效。
接下来是需要所有其他可能正在运行的 lxc 容器都已关闭。如果您负担不起,那么我认为没有办法强制使用新的 dnsmasq 配置。(出于某种原因,向 dnsmasq 的 pid 发送 HUP 信号/run/lxc/dnsmasq.pid
也不起作用。)
因此,如果您想要立即运行某些东西,并且没有其他 lxc 容器正在运行,请按照我的回答操作。$name
是我们要重置分配的节点的名称,是 LXC 桥接适配器的名称。如果您安装了,您可以使用例如$internalif
获取的值,但通常它只是。$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
答案4
以下是释放 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 的新容器之前应停止容器。