Je sais que je peux attribuer une adresse IP statique manuellement, en utilisant /etc/network/interfaces
.
Je sais aussi que je peux lire l’adresse MAC du conteneur LXC (par exemple, en cherchant l’entrée lxc.network.hwaddr
dans /var/lib/lxc/<container-name>/config
et en assignant l’adresse IP en utilisant les entrées dhcp-Host=<mac-addr>,10.0.3.3
dans /etc/dnsmasq.d/<some file>
.
Dans le fichier /etc/default/lxc-net
j'ai lu
# 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
Cela conviendrait à mes besoins. Malheureusement, cela n'a aucun effet.
Cette solution fonctionne en corrigeant les scripts de démarrage lxc. Il divise la tâche complexe consistant à activer le pont lxcbr0 et à démarrer un dnsmasq
en deux travaux distincts. Maintenant, vous n'avez pas besoin de redémarrer le pont lxc-net
au complet pour recharger simplement le dnsmasq
- le rechargement du Sudo service restart lxc-dnsmasq
est suffisant et ne nécessite pas l'arrêt du pont.
Sudo service lxc-net stop
et assurez-vous qu’il n’ya pas de passerelle lxcbr0 (ou équivalente)./etc/init/lxc-net.conf
par le contenu suivant:.
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
/etc/init/lxc-dnsmasq
avec le contenu suivant:.
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
Je me suis heurté à cela récemment et je pense avoir trouvé une solution facile. Je l'ai (seulement) testé sur Ubuntu 14.04.
Commencez par décommenter cette ligne/etc/default/lxc-net:
LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf
Dans /etc/lxc/dnsmasq.conf, définissez un fichier dhcp-hosts:
dhcp-hostsfile=/etc/lxc/dnsmasq-hosts.conf
Ajoutez ensuite des entrées dans /etc/lxc/dnsmasq-hosts.conf comme ceci:
mail,10.0.3.16
web,10.0.3.17
Attention: les modifications entreront en vigueur après le redémarrage de lxc-net (qui redémarre dnsmasq):
service lxc-net restart
Ensuite, vous pouvez modifier /etc/lxc/dnsmasq-hosts.conf et envoyer le signal SIGHUP à dnsmasq:
killall -s SIGHUP dnsmasq
Donc oui, vous devez redémarrer lxc-net, mais une seule fois. J'espère que cela t'aides.
Cela fonctionne très bien dans Ubuntu 14.04.1
Décommentez cette ligne /etc/default/lxc-net
#LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf
arrêtez tous les conteneurs, redémarrez lxc-net:
service lxc-net restart
Configurez les adresses IP dans /etc/lxc/dnsmasq.conf
dhcp-Host={NAME},10.0.3.2
où {NAME}
est le nom de votre conteneur LXC:
/var/lib/lxc/{NAME}
La réponse de Tombart fonctionne si vous êtes suffisamment patient pour attendre l'actualisation DNS ET si vous souhaitez redémarrer le conteneur (l'invité) par la suite.
Ce qui suit est la recette qui nécessite que tous les autres conteneurs éventuellement exécutés lxc sont arrêtés. Si vous ne pouvez pas vous le permettre, je ne vois aucun moyen de forcer la nouvelle configuration Dnsmasq. (Pour certains cas, signaler HUP au pid de dnsmasq trouvé dans /run/lxc/dnsmasq.pid
ne fonctionne pas non plus.)
Donc, si vous voulez avoir quelque chose qui fonctionne instantanément et qu'il n'y a pas d'autres conteneurs lxc en cours d'exécution, suivez ma réponse. $name
est le nom du noeud pour lequel on veut réinitialiser l'affectation, et $internalif
est le nom de l'adaptateur ponté de LXC. Vous pouvez obtenir la valeur de $internalif
avec, par exemple, augtool -L -A --transform "Shellvars incl /etc/default/lxc-net" get "/files/etc/default/lxc-net/LXC_BRIDGE" | sed -En 's/\/.* = (.*)/\1/p'
si vous installez augeas-tools
mais il s’agit généralement de 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
Malheureusement, il existe un bogue (fonctionnalité?) Dans le /etc/init/lxc-net.conf
dans Ubuntu 14.04 qui empêche de recharger le dnsmasq
à moins que le périphérique de pont ne soit hors service pour l'hôte.
Je me rends compte que ma réponse a plusieurs années de retard, mais peut-être que cela aide quelqu'un d'autre. Le problème était que vous aviez édité du code spécifique au paquet LXC Ubuntu (fonction write_lxc_net
) destiné à être écrit dans une autre destination sous forme de chaîne, non traité dans le script lxc-net
!
En conséquence, le processus dnsmasq n'a pas reçu le fichier de configuration que vous avez essayé de transmettre, ce qui vous laisse "sans effet", comme vous le dites.
Au lieu de cela, vous voudriez définir cette variable près du haut du script, parmi les autres:
#!/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=""
Voici un simple script python qui publie le bail LXC dnsmasq. Vous pouvez l'exécuter à partir de la machine hôte ou le falsifier à partir d'un autre conteneur - oui, cela fonctionne !:
#!/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')]))
Le prérequis pour ce qui précède est scapy python bibliothèque:
pip install scapy
Une fois exécuté, vous devriez voir dans le journal système quelque chose comme:
dnsmasq-dhcp[3242]: DHCPRELEASE(lxcbr0) 10.0.3.33 00:16:3e:11:71:b0 container-name-here
Pour confirmer, vérifiez si l'entrée est supprimée de /var/lib/misc/dnsmasq.lxcbr0.leases
. Le conteneur lui-même conservera l'adresse IP. Il convient donc de l'arrêter avant de démarrer tout nouveau conteneur devant réutiliser l'adresse IP.