Diferencia entre revisiones de «LXD per a SX»
Sin resumen de edición |
Sin resumen de edición |
||
(No se muestran 44 ediciones intermedias del mismo usuario) | |||
Línea 1: | Línea 1: | ||
Amb la tecnologia [[LXD]] es pot configurar un servidor que proporcione un entorn virtual per a fer pràctiques | Amb la tecnologia [[LXD]] es pot configurar un servidor que proporcione un entorn virtual per a fer pràctiques. | ||
{{nota| No cal entrar en detalls en alguns comandaments, la manera de fer-los està explicada en [[LXD]].}} | {{nota| No cal entrar en detalls en alguns comandaments, la manera de fer-los està explicada en [[LXD]].}} | ||
El cas (real) que ens ocupa tracta de crear un servidor per a una classe de 15 alumnes per a que practiquen en Servicis en Xarxa. Es tracta de provar DHCP, DNS i altres servidors i clients. Cada alumne té accés a 2 contenidors prèviament configurats per a que tinguen l'estructura de xarxa típica de client servidor. Ells els controlen totalment, però no poden accedir als dels companys. | El cas (real) que ens ocupa tracta de crear un servidor per a una classe de 15 alumnes per a que practiquen en Servicis en Xarxa. Es tracta de provar DHCP, DNS i altres servidors i clients. Cada alumne té accés a 2 contenidors prèviament configurats per a que tinguen l'estructura de xarxa típica de client servidor. Ells els controlen totalment, però no poden accedir als dels companys. | ||
== Configuració del servidor == | |||
Abans de tot, cal configurar el servidor correctament segons [https://github.com/lxc/lxd/blob/master/doc/production-setup.md aquest manual]. | Abans de tot, cal configurar el servidor correctament segons [https://github.com/lxc/lxd/blob/master/doc/production-setup.md aquest manual]. | ||
Línea 22: | Línea 24: | ||
fs.inotify.max_user_watches=1048576 | fs.inotify.max_user_watches=1048576 | ||
vm.max_map_count=262144 | vm.max_map_count=262144 | ||
vm.swappiness=10 | |||
</pre> | |||
=== Configurar ZFS === | |||
Anem a configurar [[ZFS]] per a fer un '''Striped Mirrored VDEVs''' que és similar a un RAID10, ja que volem rendiment i seguretat. | |||
<pre class="code"> | |||
# zpool create lxczfs mirror /dev/disk/by-id/wwn-0x5000c5007d44d0b1 /dev/disk/by-id/wwn-0x50014ee2b1d33221 | |||
# zpool add lxczfs mirror /dev/disk/by-id/wwn-0x50014ee2b1d33236 /dev/disk/by-id/wwn-0x5000c5007d44b288 | |||
</pre> | </pre> | ||
Amb aquests comandaments hem creat dos ''mirrors'' i els hem unit en un ''raid0'' entre ells. | |||
Podem mirar l'estatus del ZFS: | |||
<pre class="code"> | |||
pool: lxczfs | |||
state: ONLINE | |||
scan: none requested | |||
config: | |||
NAME STATE READ WRITE CKSUM | |||
lxczfs ONLINE 0 0 0 | |||
mirror-0 ONLINE 0 0 0 | |||
wwn-0x5000c5007d44d0b1 ONLINE 0 0 0 | |||
wwn-0x50014ee2b1d33221 ONLINE 0 0 0 | |||
mirror-1 ONLINE 0 0 0 | |||
wwn-0x50014ee2b1d33236 ONLINE 0 0 0 | |||
wwn-0x5000c5007d44b288 ONLINE 0 0 0 | |||
errors: No known data errors | |||
</pre> | |||
=== Configurar Btrfs === | |||
Btrfs és un sistema d'arxius no tan estable com ZFS, però permet fer que els subcontenidors siguen btrfs també, i aprofites els seus avantatges com el '''copy on write''' o snapshots. | |||
Com que no pretén ser un manual de btrfs, ací deixe els comandaments que hem utilitzat en un ordinador real amb 4 discs durs per a fer un brtfs amb RAID 10: | |||
<pre class="code"> | |||
mkfs.btrfs -f -m raid10 -d raid10 /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sde1 | |||
mkdir /media/btrfs | |||
mount /dev/sda1 /media/btrfs/ | |||
</pre> | |||
I a la hora de fer el '''lxd init''' es tria el directori /media/btrfs i es clava en /etc/fstab: | |||
UUID=e5b5c118-fb56-4fad-a45d-ff5fad9a649d /data btrfs user_subvol_rm_allowed 0 0 | |||
=== Configurar LXD === | |||
A continuació, cal iniciar lxd: | A continuació, cal iniciar lxd: | ||
<pre class="code"> | <pre class="code"> | ||
# lxd init | # lxd init | ||
# Se configura amb quasi tot per defecte | # Se configura amb quasi tot per defecte (Si pot ser en zfs en raid, millor) | ||
# | # lxc launch ubuntu:16.04 plantillla -c security.nesting=true | ||
# | # lxc config edit plantilla | ||
# Es canvia la eth0 de bridged a macvlan amb la targeta del server. | # Es canvia la eth0 de bridged a macvlan amb la targeta del server (també es pot fer el mateix en 'profiles'). | ||
</pre> | </pre> | ||
Dins del container cal fer algunes coses: | Dins del container cal fer algunes coses: | ||
* | * Reconfigurar openssh-server per permetre entrar amb contrasenya per SSH, ('''PasswordAuthentication yes''') | ||
* Donar password a ubuntu per poder accedir per | * Donar password a ubuntu per poder accedir per SSH. (Els containers d'ubuntu tenen un usuari anomenat ubuntu que és sudoer però que no té contrasenya) | ||
* Crear els containers: | * Crear els containers: | ||
** Fer | ** Fer una xarxa interna sols accesible per els containers de dins. (lxc network create br0 ipv4.address=none ipv6.address=none) | ||
** Fer que el client tinga sols el pont i el servidor una en el br0 i l'altra en lxdbr0 | ** Fer que el client tinga sols el pont i el servidor una en el br0 i l'altra en lxdbr0 (lxc network attach br0 client eth1 eth1) | ||
D'aquesta manera, cada alumne entra per ssh a un container, canvia la contrasenya de ubuntu i té disponible una configuració de dos containers dins del seu o pot configurar el que necessite. | D'aquesta manera, cada alumne entra per ssh a un container, canvia la contrasenya de ubuntu i té disponible una configuració de dos containers dins del seu o pot configurar el que necessite. | ||
Línea 47: | Línea 96: | ||
</pre> | </pre> | ||
Aquest for es pot utilitzar després per iniciar-los tots o parar-los. | Aquest for es pot utilitzar després per iniciar-los tots o parar-los. | ||
Al copiar un contenidor la MAC és modificada, però no la dels contenidors que conté. Si algú està en macvlan, pot donar problemes. Cal especificar manualment la MAC dels contenidors interns una vegada copiat en de l'alumne. | |||
<pre class="code"> | |||
# for i in {1..15}; do lxc exec alumne$i -- lxc config set firewall volatile.wan.hwaddr 00:16:3e:e7:ba:$((10+$i)); done | |||
</pre> | |||
'''Avís''' | '''Avís''' | ||
Cal pensar que són 15x2 + 15 = 45 contenidors en total els que té que suportar el servidor. Pot ser interessant fer un sleep en el for d'arrancar-los tots per donar temps a que es configuren totalment. L'arranc total pot durar uns minuts en els que els disc dur té molt de treball. Una vegada en marxa tot funciona perfectament. El coll de botella és el disc dur. El meu servidor és un | Cal pensar que són 15x2 + 15 = 45 contenidors en total els que té que suportar el servidor. Pot ser interessant fer un sleep en el for d'arrancar-los tots per donar temps a que es configuren totalment. L'arranc total pot durar uns minuts en els que els disc dur té molt de treball. Una vegada en marxa tot funciona perfectament. El coll de botella és el disc dur. El meu servidor és un i3 amb 16GB de RAM | ||
{{nota|Un altre problema és que els contenidors Ubuntu venen amb el '''unattended upgrades'''. Caldria desinstal·lar-lo}} | |||
<pre class="code"> | |||
for i in {1..15}; do lxc exec alumne$i -- lxc exec server1 -- apt remove -y unattended-upgrades ; done | |||
</pre> | |||
Quan arranquem tots els contenidors també arranquen els subcontenidors, la manera més simple de evitar saturar el servidor és que els alumnes els arranquen sols quan els necessiten. Hem de desactivar el '''autostart''': | |||
<pre class="code"> | |||
lxc list -c n --format csv | while read l; do lxc config set $l boot.autostart false; echo $l; done | |||
</pre> | |||
Una bona pràctica és limitar la memòria RAM de cada contenidor. En el meu cas, vull repartir 8GB per a 24 alumnes, així que podem donar a cadascun 341MB, els donarem 340 per a que sobre un poc: | |||
<pre class="code"> | |||
for i in {1..24}; do lxc config set alumne$i limits.memory 340MB; echo -n " $i"; done | |||
</pre> | |||
Pot ser que els contenidors no poden ser accedits per SSH. Cal modificar la contrasenya d'ubuntu, el fitxer de ssh i reiniciar el servei. | |||
<pre class="code"> | |||
# for i in {1..24}; do lxc file push shadow simulacre$i/etc/shadow; done | |||
# for i in {1..24}; do lxc exec simulacre$i -- sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config; done | |||
# for i in {1..24}; do lxc exec simulacre$i -- service sshd restart; done | |||
</pre> | |||
Exemple de cóm queda: | Exemple de cóm queda: | ||
<pre class="code"> | <pre class="code"> | ||
Línea 110: | Línea 179: | ||
</pre> | </pre> | ||
=== Configuració amb Xarxa pont === | |||
Quan tenim moltes targetes Macvlan es provoquen problemes en algunes targetes de xarxa. A banda de que necessitem reservar, modificar i recordar moltes IPs. Per fer el mateix que abans en xarxa '''bridged''': | |||
El primer de tot és fer que tots els clients tinguen IP fixa. Per a fer això, necessitem afegir la xarxa al contenidor i forçar una IP fixa: | |||
<pre class="code"> | |||
$ lxc network attach lxdbr0 contanier1 eth0 eth0 | |||
$ lxc config device set container1 eth0 ipv4.address 10.72.105.100 | |||
</pre> | |||
Es pot fer un for per a aplicar-ho a tots els contenidors: | |||
<pre class="code"> | |||
$ for i in {101..113}; do echo $i; lxc copy ex ex$i; lxc config device set ex$i eth0 ipv4.address 10.72.105.$i; done | |||
</pre> | |||
Per últim, cal fer les IPtables corresponents per redirigir el port: | |||
<pre class="code"> | <pre class="code"> | ||
$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2101 -j DNAT --to 10.72.105.101:22 | |||
</pre> | |||
== Script per gestionar targetes:== | |||
(Obsolet, no l'esborre perquè té comandaments interessants, però en LXD 2.5 ja es poden fer les coses més fàcils i en Ubuntu 18.04 utilitza Netplan) | |||
<div class="toccolours mw-collapsible mw-collapsed" style="overflow: hidden;"> | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#!/bin/bash | #!/bin/bash | ||
function crear_ponts { | function crear_ponts { | ||
echo -e "Crear Ponts\nAquesta opció crea un pont de xarxa sense connexió a res. És útil per crear switchs virtuals" | echo -e "Crear Ponts\nAquesta opció crea un pont de xarxa sense connexió a res. És útil per crear switchs virtuals" | ||
Línea 119: | Línea 212: | ||
read -p "IP del pont: " adr | read -p "IP del pont: " adr | ||
echo -e "\n\nauto $nom\niface $nom inet static\naddress $adr\nnetmask 255.255.255.0\nbridge-ports none" >> /etc/network/interfaces | echo -e "\n\nauto $nom\niface $nom inet static\naddress $adr\nnetmask 255.255.255.0\nbridge-ports none" >> /etc/network/interfaces | ||
brctl addbr $nom | brctl addbr $nom | ||
ifup $nom | ifup $nom | ||
} | } | ||
function crear_targeta { | function crear_targeta { | ||
echo "Crear targeta" | echo "Crear targeta" | ||
Línea 135: | Línea 228: | ||
read -p "Nom del parent: " parent | read -p "Nom del parent: " parent | ||
read -p "Tipus de targeta [bridged macvlan]: " tipus | read -p "Tipus de targeta [bridged macvlan]: " tipus | ||
lxc config device add $nom $eth nic nictype=$tipus parent=$parent name=$ | lxc config device add $nom $eth nic nictype=$tipus parent=$parent name=$eth | ||
lxc config show --expanded $nom | lxc config show --expanded $nom | ||
} | } | ||
function crear_targeta_bridged { | function crear_targeta_bridged { | ||
echo "Crear targeta bridged en varis containers" | echo "Crear targeta bridged en varis containers" | ||
Línea 149: | Línea 242: | ||
for i in $noms | for i in $noms | ||
do | do | ||
lxc config device add $i $eth nic nictype=bridged parent=$parent name=$ | lxc config device add $i $eth nic nictype=bridged parent=$parent name=$eth | ||
lxc config show --expanded $i | lxc config show --expanded $i | ||
done | done | ||
} | } | ||
function crear_targeta_profile { | |||
echo "Crear targeta" | |||
lxc profile list | |||
read -p "Nom del profile: " nom | |||
echo "Configuració del profile:" | |||
lxc profile show $nom | |||
read -p "Nom de la nova targeta: " eth | |||
echo "Lista de targetes i ponts:" | |||
ifconfig | grep "Link" | |||
read -p "Nom del parent: " parent | |||
read -p "Tipus de targeta [bridged macvlan]: " tipus | |||
lxc profile device add $nom $eth nic nictype=$tipus parent=$parent name=$eth | |||
lxc profile show $nom | |||
} | |||
function ip_estatica { | |||
echo "Donar una IP estàtica a una container" | |||
lxc list | |||
read -p "Nom del container: " nom | |||
echo "Configuració del contenidor:" | |||
lxc config show --expanded $nom | |||
read -p "Nom de la targeta: " eth | |||
read -p "IP de la targeta: " ip | |||
read -p "Màscara de la targeta: " masc | |||
echo -e "\n\nauto $eth\niface $eth inet static\naddress $ip\nnetmask $masc" > /tmp/${eth}.cfg && lxc file push /tmp/${eth}.cfg ${nom}/etc/network/interfaces.d/ | |||
lxc exec $nom -- ifdown $eth | |||
lxc exec $nom -- ifup $eth | |||
} | |||
echo "Configurador LXD" | echo "Configurador LXD" | ||
echo "MENU" | echo "MENU" | ||
Línea 160: | Línea 282: | ||
echo "2) Crear una targeta en un container" | echo "2) Crear una targeta en un container" | ||
echo "3) Crear una targeta bridged en varis containers" | echo "3) Crear una targeta bridged en varis containers" | ||
echo "4) Crear una targeta en un profile" | |||
echo "5) IP estàtica a container" | |||
read -p "Opció: " opcio | read -p "Opció: " opcio | ||
case $opcio in | case $opcio in | ||
1) crear_ponts;; | 1) crear_ponts;; | ||
2) crear_targeta;; | 2) crear_targeta;; | ||
3) crear_targeta_bridged;; | 3) crear_targeta_bridged;; | ||
4) crear_targeta_profile;; | |||
5) ip_estatica;; | |||
*) echo "Opció no valida" | *) echo "Opció no valida" | ||
esac | esac | ||
</ | </syntaxhighlight> | ||
</div> | |||
== Scripts per a crear xarxes completes == | |||
(Scripts amb parts obsoletes) | |||
=== Projecte 2017 === | |||
<div class="toccolours mw-collapsible mw-collapsed" style="overflow: hidden;"> | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#!/bin/bash | |||
lxc launch images:alpine/3.6 firewall | |||
lxc launch images:alpine/3.6 router1 | |||
lxc launch ubuntu:16.04 servidorDHCP | |||
lxc launch ubuntu:16.04 servidorWeb | |||
lxc launch images:alpine/3.6 router2 | |||
lxc launch images:alpine/3.6 client1 | |||
lxc launch images:alpine/3.6 client2 | |||
lxc launch images:alpine/3.6 firewallintern | |||
for i in {1..6} | |||
do | |||
echo -e "\n\nauto switch$i\niface switch$i inet static\naddress 192.168.99.$i\nnetmask 255.255.255.0\nbridge-ports none" >> /etc/network/interfaces | |||
brctl addbr switch$i | |||
ifup switch$i | |||
done | |||
lxc config device add firewall eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add firewall wan nic nictype=macvlan parent=eth0 name=wan | |||
lxc config device add router1 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add router1 eth2 nic nictype=bridged parent=switch2 name=eth2 | |||
lxc config device add router1 eth3 nic nictype=bridged parent=switch3 name=eth3 | |||
lxc config device add firewallintern eth3 nic nictype=bridged parent=switch3 name=eth3 | |||
lxc config device add firewallintern eth4 nic nictype=bridged parent=switch4 name=eth4 | |||
lxc config device add router2 eth4 nic nictype=bridged parent=switch4 name=eth4 | |||
lxc config device add router2 eth5 nic nictype=bridged parent=switch5 name=eth5 | |||
lxc config device add router2 eth6 nic nictype=bridged parent=switch6 name=eth6 | |||
lxc config device add servidorDHCP eth1 nic nictype=bridged parent=switch2 name=eth1 | |||
lxc config device add servidorWeb eth1 nic nictype=bridged parent=switch2 name=eth1 | |||
#lxc config device add servidorDNS1 eth1 nic nictype=bridged parent=switch2 name=eth1 | |||
#lxc config device add servidorDNS2 eth1 nic nictype=bridged parent=switch2 name=eth1 | |||
lxc config device add client1 eth1 nic nictype=bridged parent=switch6 name=eth1 | |||
lxc config device add client2 eth1 nic nictype=bridged parent=switch5 name=eth1 | |||
</syntaxhighlight> | |||
</div> | |||
=== Exemple === | |||
<div class="toccolours mw-collapsible mw-collapsed" style="overflow: hidden;"> | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#!/bin/bash | |||
lxc launch images:alpine/3.6 firewall | |||
lxc launch images:alpine/3.6 router1 | |||
lxc launch ubuntu:16.04 servidorDHCP | |||
lxc launch images:alpine/3.6 client1 | |||
lxc launch images:alpine/3.6 client2 | |||
echo "#Configuracio" > /etc/network/interfaces.d/99-conf.cfg | |||
for i in {1..3} | |||
do | |||
echo -e "\n\nauto switch$i\niface switch$i inet static\naddress 192.168.99.$i\nnetmask 255.255.255.0\nbridge-ports none" >> /etc/network/interfaces.d/99-conf.cfg | |||
brctl addbr switch$i | |||
ifup switch$i | |||
done | |||
lxc config device add firewall eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add router1 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add router1 eth2 nic nictype=bridged parent=switch2 name=eth2 | |||
lxc config device add router1 eth3 nic nictype=bridged parent=switch3 name=eth3 | |||
lxc config device remove router1 eth0 | |||
lxc config device add servidorDHCP eth2 nic nictype=bridged parent=switch2 name=eth2 | |||
lxc config device add servidorDHCP eth3 nic nictype=bridged parent=switch3 name=eth3 | |||
lxc config device remove servidorDHCP eth0 | |||
lxc config device add client1 eth1 nic nictype=bridged parent=switch2 name=eth1 | |||
lxc config device add client2 eth1 nic nictype=bridged parent=switch3 name=eth1 | |||
lxc config device remove client1 eth0 | |||
lxc config device remove client2 eth0 | |||
</syntaxhighlight> | |||
</div> | |||
=== Exercici1 === | |||
<div class="toccolours mw-collapsible mw-collapsed" style="overflow: hidden;"> | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#!/bin/bash | |||
# --------- | |||
# |client1| | |||
# --------- | |||
# | | |||
# /switch3/ | |||
# | | |||
# --------- | |||
# |router1| | |||
# --------- | |||
# / \ ---------- | |||
# /switch4/ /switch1/--------|Firewall| | |||
# / \ ---------- | |||
# --------- --------- | |||
# |router3|--/switch5/---|router2| | |||
# -------- --------- | |||
# | | | |||
# /switch6/ /switch2/ | |||
# | | | |||
# --------- --------- | |||
# |client3| |client2| | |||
# --------- --------- | |||
# | |||
lxc launch images:alpine/3.6 firewall | |||
lxc launch images:alpine/3.6 router1 | |||
lxc launch images:alpine/3.6 router2 | |||
lxc launch images:alpine/3.6 router3 | |||
lxc launch images:alpine/3.6 client1 | |||
lxc launch images:alpine/3.6 client2 | |||
lxc launch images:alpine/3.6 client3 | |||
apt update | |||
apt install bridge-utils | |||
echo "#Configuracio" > /etc/network/interfaces.d/99-conf.cfg | |||
for i in {1..6} | |||
do | |||
echo -e "\n\nauto switch$i\niface switch$i inet static\naddress 192.168.99.$i\nnetmask 255.255.255.0\nbridge-ports none" >> /etc/network/interfaces.d/99-conf.cfg | |||
brctl addbr switch$i | |||
ifup switch$i | |||
done | |||
lxc config device add firewall eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add router1 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add router1 eth3 nic nictype=bridged parent=switch3 name=eth3 | |||
lxc config device add router1 eth4 nic nictype=bridged parent=switch4 name=eth4 | |||
lxc config device add router2 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add router2 eth2 nic nictype=bridged parent=switch2 name=eth2 | |||
lxc config device add router2 eth5 nic nictype=bridged parent=switch5 name=eth5 | |||
lxc config device add router3 eth4 nic nictype=bridged parent=switch4 name=eth4 | |||
lxc config device add router3 eth5 nic nictype=bridged parent=switch5 name=eth5 | |||
lxc config device add router3 eth6 nic nictype=bridged parent=switch6 name=eth6 | |||
lxc config device add client1 eth1 nic nictype=bridged parent=switch3 name=eth1 | |||
lxc config device add client2 eth1 nic nictype=bridged parent=switch2 name=eth1 | |||
lxc config device add client3 eth1 nic nictype=bridged parent=switch6 name=eth1 | |||
lxc profile create xarxa | |||
lxc profile set xarxa security.privileged true | |||
lxc profile apply router1 xarxa | |||
lxc profile apply router2 xarxa | |||
lxc profile apply router3 xarxa | |||
lxc profile apply client1 xarxa | |||
lxc profile apply client2 xarxa | |||
lxc profile apply client3 xarxa | |||
</syntaxhighlight> | |||
</div> | |||
=== Exercici2 === | |||
<div class="toccolours mw-collapsible mw-collapsed" style="overflow: hidden;"> | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#!/bin/bash | |||
# | |||
# --------- --------- | |||
# |router1| |client2| | |||
# --------- --------- | |||
# / \ / ---------- | |||
# /switch2/ /switch1/--------|Firewall| | |||
# / \ / \ ---------- | |||
# --------- --------- --------- | |||
# |client3| |DHCP | |client1| | |||
# -------- --------- --------- | |||
# | |||
lxc launch images:alpine/3.6 firewall | |||
lxc launch images:alpine/3.6 router1 | |||
lxc launch images:alpine/3.6 client1 | |||
lxc launch images:alpine/3.6 client2 | |||
lxc launch ubuntu:16.04 dhcp | |||
apt update | |||
apt install bridge-utils | |||
echo "#Configuracio" > /etc/network/interfaces.d/99-conf.cfg | |||
for i in {1..2} | |||
do | |||
echo -e "\n\nauto switch$i\niface switch$i inet static\naddress 192.168.99.$i\nnetmask 255.255.255.0\nbridge-ports none" >> /etc/network/interfaces.d/99-conf.cfg | |||
brctl addbr switch$i | |||
ifup switch$i | |||
done | |||
lxc config device add firewall eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add router1 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add router1 eth2 nic nictype=bridged parent=switch2 name=eth2 | |||
lxc config device add client1 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add client2 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add dhcp eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add dhcp eth2 nic nictype=bridged parent=switch2 name=eth2 | |||
lxc profile create xarxa | |||
lxc profile set xarxa security.privileged true | |||
lxc profile apply router1 xarxa | |||
lxc profile apply client1 xarxa | |||
lxc profile apply client2 xarxa | |||
lxc profile apply dhcp xarxa | |||
</syntaxhighlight> | |||
</div> | |||
=== Simulacre === | |||
<div class="toccolours mw-collapsible mw-collapsed" style="overflow: hidden;"> | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#!/bin/bash | |||
# /switch3/ | |||
# / \ | |||
# --------- ----------- | |||
# |router1| |client1-2| | |||
# --------- ----------- | |||
# / \ ---------- | |||
# /switch2/ /switch1/--------|Firewall| | |||
# / / \ ---------- | |||
# ----------- --------- ----------- | |||
# |client3-6| |DHCP | |client7-9| | |||
# ---------- --------- ----------- | |||
# | |||
lxc profile create xarxa | |||
lxc profile set xarxa security.privileged true | |||
lxc launch images:alpine/3.6 firewall | |||
lxc launch images:alpine/3.6 router1 --profile=xarxa | |||
lxc launch images:alpine/3.6 client1 --profile=xarxa | |||
lxc launch images:alpine/3.6 client2 --profile=xarxa | |||
lxc launch images:alpine/3.6 client3 --profile=xarxa | |||
lxc launch images:alpine/3.6 client4 --profile=xarxa | |||
lxc launch images:alpine/3.6 client5 --profile=xarxa | |||
lxc launch images:alpine/3.6 client6 --profile=xarxa | |||
lxc launch images:alpine/3.6 client7 --profile=xarxa | |||
lxc launch images:alpine/3.6 client8 --profile=xarxa | |||
lxc launch images:alpine/3.6 client9 --profile=xarxa | |||
lxc launch ubuntu:16.04 dhcp --profile=xarxa | |||
apt update | |||
apt install bridge-utils | |||
echo "#Configuracio" > /etc/network/interfaces.d/99-conf.cfg | |||
for i in {1..3} | |||
do | |||
echo -e "\n\nauto switch$i\niface switch$i inet static\naddress 192.168.99.$i\nnetmask 255.255.255.0\nbridge-ports none" >> /etc/network/interfaces.d/99-conf.cfg | |||
brctl addbr switch$i | |||
ifup switch$i | |||
done | |||
lxc config device add firewall eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add router1 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add router1 eth2 nic nictype=bridged parent=switch2 name=eth2 | |||
lxc config device add router1 eth3 nic nictype=bridged parent=switch3 name=eth3 | |||
lxc config device add client1 eth1 nic nictype=bridged parent=switch3 name=eth1 | |||
lxc config device add client2 eth1 nic nictype=bridged parent=switch3 name=eth1 | |||
lxc config device add client3 eth1 nic nictype=bridged parent=switch2 name=eth1 | |||
lxc config device add client4 eth1 nic nictype=bridged parent=switch2 name=eth1 | |||
lxc config device add client5 eth1 nic nictype=bridged parent=switch2 name=eth1 | |||
lxc config device add client6 eth1 nic nictype=bridged parent=switch2 name=eth1 | |||
lxc config device add client7 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add client8 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add client9 eth1 nic nictype=bridged parent=switch1 name=eth1 | |||
lxc config device add dhcp eth1 nic nictype=bridged parent=switch1 name=eth | |||
</syntaxhighlight> | |||
I per fer que tots tinguen nano e iptables: | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
for i in client1 client2 client3 client4 client5 client6 client7 client8 client9 firewall router1; | |||
do | |||
lxc start $i; sleep 5; | |||
lxc profile apply $i default; | |||
lxc exec $i -- reboot; sleep 10; | |||
lxc exec $i -- apk update; | |||
lxc exec $i -- apk add nano; | |||
lxc exec $i -- apk add iptables; | |||
lxc profile apply $i xarxa; | |||
done | |||
</syntaxhighlight> | |||
</div> | |||
=== Script 2019 === | |||
(El més actualitzat) | |||
<div class="toccolours mw-collapsible mw-collapsed" style="overflow: hidden;"> | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#/bin/bash | |||
cat init.yaml | lxd init --preseed | |||
echo -e "lxd init" | |||
lxc image copy ubuntu:18.04 local: --alias localubuntu | |||
lxc image copy images:alpine/3.8 local: --alias localalpine | |||
lxc init localalpine firewall | |||
lxc init localalpine router1 | |||
lxc init localalpine router2 | |||
lxc init localalpine client1 | |||
lxc init localalpine client2 | |||
lxc init localalpine client3 | |||
lxc init localubuntu server1 | |||
lxc init localubuntu server2 | |||
lxc network create switch1 ipv4.address=none ipv6.address=none | |||
lxc network create switch2 ipv4.address=none ipv6.address=none | |||
lxc network create switch3 ipv4.address=none ipv6.address=none | |||
lxc network create switch4 ipv4.address=none ipv6.address=none | |||
lxc network create switch5 ipv4.address=none ipv6.address=none | |||
lxc network attach switch1 firewall eth1 eth1 | |||
lxc network attach switch1 router1 eth1 eth1 | |||
lxc network attach switch2 router1 eth2 eth2 | |||
lxc network attach switch3 router1 eth3 eth3 | |||
lxc network attach switch4 router1 eth4 eth4 | |||
lxc network attach switch2 client1 eth2 eth2 | |||
lxc network attach switch3 server1 eth3 eth3 | |||
lxc network attach switch4 server2 eth4 eth4 | |||
lxc network attach switch4 router2 eth4 eth4 | |||
lxc network attach switch5 router2 eth5 eth5 | |||
lxc network attach switch5 client2 eth5 eth5 | |||
lxc network attach switch5 client3 eth3 eth3 | |||
lxc profile copy default sensexarxa | |||
lxc network detach-profile lxdbr0 sensexarxa | |||
lxc profile assign router1 sensexarxa | |||
lxc profile assign router2 sensexarxa | |||
lxc profile assign server1 sensexarxa | |||
lxc profile assign server2 sensexarxa | |||
lxc profile assign client1 sensexarxa | |||
lxc profile assign client2 sensexarxa | |||
lxc profile assign client3 sensexarxa | |||
lxc start server1 server2 | |||
lxc exec server1 -- apt remove -y unattended-upgrades | |||
lxc exec server2 -- apt remove -y unattended-upgrades | |||
apt remove -y unattended-upgrades | |||
</syntaxhighlight> | |||
</div> | |||
=== Altres scripts === | |||
'''Script per a crear un contenidor plantilla''' | |||
Necessita previament un '''profile''' anomenat ''externa'' que configura la xarxa com '''macvlan''': | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#/bin/bash | |||
container=${1:-'plantilla'} | |||
lxc launch ubuntu:18.04 $container -c security.nesting=true | |||
lxc profile assign $container externa | |||
lxc restart $container | |||
</syntaxhighlight> | |||
'''Script per a clonar la plantilla''' | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#!/bin/bash | |||
# $1 es la plantilla | |||
# $2 es la quantitat | |||
# $3 es el nom dels clons | |||
lxc stop $1 | |||
for i in $(seq 1 $2); do | |||
echo $3$i | |||
lxc copy $1 $3$i | |||
lxc start $3$i | |||
sleep 10 | |||
# La configuració del netplan | |||
echo ' | |||
network: | |||
version: 2 | |||
ethernets: | |||
eth0: | |||
dhcp4: false | |||
addresses: [10.100.23.'$(($i+100))'/23] | |||
gateway4: 10.100.22.1 | |||
nameservers: | |||
addresses: [8.8.8.8]' > /tmp/50-cloud-init.yaml | |||
lxc file push /tmp/50-cloud-init.yaml $3$i/etc/netplan/ | |||
# La contrasenya d'ubuntu | |||
lxc exec $3$i -- bash -c "echo ubuntu:1234 | chpasswd"; | |||
# Poder entrar per SSH per password | |||
lxc exec $3$i -- sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config | |||
lxc restart $3$i | |||
sleep 10 | |||
done | |||
</syntaxhighlight> | |||
'''Script per a generar un mapa de la xarxa:''' | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#!/bin/bash | |||
echo 'digraph { | |||
graph [pad="0.5", nodesep="0.5", ranksep="2", splines=ortho,]; | |||
node [shape=none] | |||
rankdir=LR;' | |||
bridges=($(brctl show | tail -n +2 |cut -f1 | tr "\n" " ")) | |||
for i in ${bridges[@]} | |||
do | |||
echo "$i [label=\"$i\" shape=box];" | |||
done | |||
containers=($(lxc list | egrep '(STOPPED|RUNNING)' | cut -d" " -f2 | tr "\n" " ")) | |||
xarxes="$(lxc list --format json | jq -r '.[] | {container: .name, dev: .expanded_devices[]} | [.container,.dev.name,.dev.parent,.dev.type] | @csv' | grep '"nic"$')" | |||
relations="" | |||
for i in ${containers[@]} | |||
do | |||
pc="$i [label=<<table border=\"0\" cellborder=\"1\" cellspacing=\"0\"><tr><td bgcolor=\"#CCCCCC\" >$i</td></tr>" | |||
while read dev | |||
do | |||
nom=$(echo $dev | cut -d "," -f2 | tr -d '"') | |||
switch=$(echo $dev | cut -d"," -f3 | tr -d '"') | |||
pc=$pc"<tr><td port=\"$nom\">$nom</td></tr>" | |||
#La IP | |||
ip=$(lxc info $i | tr "\t" " " | grep "$nom: inet " | tr -s " " | cut -d" " -f4) | |||
relations=$relations"$switch -> $i:$nom [dir=none headlabel=\"$ip\"] \n" | |||
relations=$relations"//$i:$nom -> $switch [dir=none taillabel=\"$ip\"] \n" | |||
done <<< "$(echo "$xarxes" | grep "$i")" | |||
pc=$pc"</table>>];" | |||
echo $pc | |||
done | |||
echo -e "$relations" | |||
echo '}' | |||
</syntaxhighlight> | |||
'''Script per a mostrar la RAM que utilitzen contenidors i subcontenidors''': | |||
<syntaxhighlight lang="bash" style="font-family:monospace"> | |||
#!/bin/bash | |||
export LANG=C | |||
function explorar { | |||
local contenidor="$1" | |||
#echo $contenidor | |||
local contenidors=$(lxc exec $contenidor -- lxc list -c n --format csv 2> /dev/null) | |||
#echo "lxc exec $contenidor -- lxc list -c n --format csv 2> /dev/null" | |||
#echo $contenidors | |||
[[ $contenidors != "" ]] && echo "$2⤷" | |||
for i in $contenidors | |||
do | |||
nom=$i | |||
estat=$(lxc exec $contenidor -- lxc info $i | grep 'Status' | cut -d" " -f2 2> /dev/null) | |||
memoria='0MB' | |||
if [[ $estat == 'Running' ]]; then | |||
memoria=$(lxc exec $contenidor -- lxc info $i | grep 'Memory (current)' | awk '{print $3}' 2> /dev/null) | |||
fi | |||
echo "$2 $nom : $memoria" | |||
cont="$contenidor -- lxc exec $nom" | |||
explorar "$cont" "$2 " 2> /dev/null | |||
done | |||
} | |||
contenidors=$(lxc list -c n --format csv) | |||
for i in $contenidors | |||
do | |||
nom=$i | |||
estat=$(lxc info $i | grep 'Status' | cut -d" " -f2) | |||
memoria='0MB' | |||
if [[ $estat == 'Running' ]]; then | |||
memoria=$(lxc info $i | grep 'Memory (current)' | awk '{print $3}') | |||
fi | |||
echo "$nom : $memoria" | |||
explorar "$i" " " 2> /dev/null | |||
done | |||
</syntaxhighlight> |
Revisión actual - 15:42 1 may 2020
Amb la tecnologia LXD es pot configurar un servidor que proporcione un entorn virtual per a fer pràctiques.
El cas (real) que ens ocupa tracta de crear un servidor per a una classe de 15 alumnes per a que practiquen en Servicis en Xarxa. Es tracta de provar DHCP, DNS i altres servidors i clients. Cada alumne té accés a 2 contenidors prèviament configurats per a que tinguen l'estructura de xarxa típica de client servidor. Ells els controlen totalment, però no poden accedir als dels companys.
Configuració del servidor
Abans de tot, cal configurar el servidor correctament segons aquest manual.
En /etc/security/limits.conf:
* soft nofile 1048576 * hard nofile 1048576 root soft nofile 1048576 root hard nofile 1048576 * soft memlock unlimited * hard memlock unlimited
En /etc/sysctrl.conf:
fs.inotify.max_queued_events=1048576 fs.inotify.max_user_instances=1048576 fs.inotify.max_user_watches=1048576 vm.max_map_count=262144 vm.swappiness=10
Configurar ZFS
Anem a configurar ZFS per a fer un Striped Mirrored VDEVs que és similar a un RAID10, ja que volem rendiment i seguretat.
# zpool create lxczfs mirror /dev/disk/by-id/wwn-0x5000c5007d44d0b1 /dev/disk/by-id/wwn-0x50014ee2b1d33221 # zpool add lxczfs mirror /dev/disk/by-id/wwn-0x50014ee2b1d33236 /dev/disk/by-id/wwn-0x5000c5007d44b288
Amb aquests comandaments hem creat dos mirrors i els hem unit en un raid0 entre ells.
Podem mirar l'estatus del ZFS:
pool: lxczfs state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM lxczfs ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 wwn-0x5000c5007d44d0b1 ONLINE 0 0 0 wwn-0x50014ee2b1d33221 ONLINE 0 0 0 mirror-1 ONLINE 0 0 0 wwn-0x50014ee2b1d33236 ONLINE 0 0 0 wwn-0x5000c5007d44b288 ONLINE 0 0 0 errors: No known data errors
Configurar Btrfs
Btrfs és un sistema d'arxius no tan estable com ZFS, però permet fer que els subcontenidors siguen btrfs també, i aprofites els seus avantatges com el copy on write o snapshots.
Com que no pretén ser un manual de btrfs, ací deixe els comandaments que hem utilitzat en un ordinador real amb 4 discs durs per a fer un brtfs amb RAID 10:
mkfs.btrfs -f -m raid10 -d raid10 /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sde1 mkdir /media/btrfs mount /dev/sda1 /media/btrfs/
I a la hora de fer el lxd init es tria el directori /media/btrfs i es clava en /etc/fstab:
UUID=e5b5c118-fb56-4fad-a45d-ff5fad9a649d /data btrfs user_subvol_rm_allowed 0 0
Configurar LXD
A continuació, cal iniciar lxd:
# lxd init # Se configura amb quasi tot per defecte (Si pot ser en zfs en raid, millor) # lxc launch ubuntu:16.04 plantillla -c security.nesting=true # lxc config edit plantilla # Es canvia la eth0 de bridged a macvlan amb la targeta del server (també es pot fer el mateix en 'profiles').
Dins del container cal fer algunes coses:
- Reconfigurar openssh-server per permetre entrar amb contrasenya per SSH, (PasswordAuthentication yes)
- Donar password a ubuntu per poder accedir per SSH. (Els containers d'ubuntu tenen un usuari anomenat ubuntu que és sudoer però que no té contrasenya)
- Crear els containers:
- Fer una xarxa interna sols accesible per els containers de dins. (lxc network create br0 ipv4.address=none ipv6.address=none)
- Fer que el client tinga sols el pont i el servidor una en el br0 i l'altra en lxdbr0 (lxc network attach br0 client eth1 eth1)
D'aquesta manera, cada alumne entra per ssh a un container, canvia la contrasenya de ubuntu i té disponible una configuració de dos containers dins del seu o pot configurar el que necessite.
Una vegada tot configurat, es paren els containers de dins i el container plantilla. Després es copia la plantilla:
# for n in {1..15}; do echo "Copiant $n"; lxc copy plantilla alumne$n; done
Aquest for es pot utilitzar després per iniciar-los tots o parar-los. Al copiar un contenidor la MAC és modificada, però no la dels contenidors que conté. Si algú està en macvlan, pot donar problemes. Cal especificar manualment la MAC dels contenidors interns una vegada copiat en de l'alumne.
# for i in {1..15}; do lxc exec alumne$i -- lxc config set firewall volatile.wan.hwaddr 00:16:3e:e7:ba:$((10+$i)); done
Avís Cal pensar que són 15x2 + 15 = 45 contenidors en total els que té que suportar el servidor. Pot ser interessant fer un sleep en el for d'arrancar-los tots per donar temps a que es configuren totalment. L'arranc total pot durar uns minuts en els que els disc dur té molt de treball. Una vegada en marxa tot funciona perfectament. El coll de botella és el disc dur. El meu servidor és un i3 amb 16GB de RAM
for i in {1..15}; do lxc exec alumne$i -- lxc exec server1 -- apt remove -y unattended-upgrades ; done
Quan arranquem tots els contenidors també arranquen els subcontenidors, la manera més simple de evitar saturar el servidor és que els alumnes els arranquen sols quan els necessiten. Hem de desactivar el autostart:
lxc list -c n --format csv | while read l; do lxc config set $l boot.autostart false; echo $l; done
Una bona pràctica és limitar la memòria RAM de cada contenidor. En el meu cas, vull repartir 8GB per a 24 alumnes, així que podem donar a cadascun 341MB, els donarem 340 per a que sobre un poc:
for i in {1..24}; do lxc config set alumne$i limits.memory 340MB; echo -n " $i"; done
Pot ser que els contenidors no poden ser accedits per SSH. Cal modificar la contrasenya d'ubuntu, el fitxer de ssh i reiniciar el servei.
# for i in {1..24}; do lxc file push shadow simulacre$i/etc/shadow; done # for i in {1..24}; do lxc exec simulacre$i -- sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config; done # for i in {1..24}; do lxc exec simulacre$i -- service sshd restart; done
Exemple de cóm queda:
lliurex@2smxv:~$ lxc list +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | NOMBRE | ESTADO | IPV4 | IPV6 | TIPO | SNAPSHOTS | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne1 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fe31:1c2d (eth0) | PERSISTENT | 0 | | | | 192.168.0.218 (eth0) | | | | | | | 10.235.78.1 (lxdbr0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne10 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fe67:f1f7 (eth0) | PERSISTENT | 0 | | | | 192.168.0.227 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne11 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:feb9:a80c (eth0) | PERSISTENT | 0 | | | | 192.168.0.228 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne12 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fecc:e507 (eth0) | PERSISTENT | 0 | | | | 192.168.0.232 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne13 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:feee:768d (eth0) | PERSISTENT | 0 | | | | 192.168.0.229 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne14 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fe95:14d0 (eth0) | PERSISTENT | 0 | | | | 192.168.0.230 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne15 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fe60:cc7c (eth0) | PERSISTENT | 0 | | | | 192.168.0.231 (eth0) | | | | | | | 10.235.78.1 (lxdbr0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne2 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fe21:6a76 (eth0) | PERSISTENT | 0 | | | | 192.168.0.219 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne3 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fe6b:7f64 (eth0) | PERSISTENT | 0 | | | | 192.168.0.220 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne4 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fec2:86ea (eth0) | PERSISTENT | 0 | | | | 192.168.0.221 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne5 | RUNNING | 192.168.0.222 (eth0) | fd62:5f40:e210:0:216:3eff:fe9c:f3aa (eth0) | PERSISTENT | 0 | | | | 192.168.66.1 (br0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne6 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fe16:bea4 (eth0) | PERSISTENT | 0 | | | | 192.168.0.223 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne7 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fe73:c391 (eth0) | PERSISTENT | 0 | | | | 192.168.0.224 (eth0) | | | | | | | 10.235.78.1 (lxdbr0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne8 | RUNNING | 192.168.66.1 (br0) | fd62:5f40:e210:0:216:3eff:fe90:163e (eth0) | PERSISTENT | 0 | | | | 192.168.0.225 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | alumne9 | RUNNING | 10.235.78.1 (lxdbr0) | fd62:5f40:e210:0:216:3eff:feaa:d8 (eth0) | PERSISTENT | 0 | | | | 192.168.66.1 (br0) | | | | | | | 192.168.0.226 (eth0) | | | | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+ | plantilla| STOPPED | | | PERSISTENT | 0 | +----------+---------+--------------------------------+--------------------------------------------+------------+-----------+
Configuració amb Xarxa pont
Quan tenim moltes targetes Macvlan es provoquen problemes en algunes targetes de xarxa. A banda de que necessitem reservar, modificar i recordar moltes IPs. Per fer el mateix que abans en xarxa bridged:
El primer de tot és fer que tots els clients tinguen IP fixa. Per a fer això, necessitem afegir la xarxa al contenidor i forçar una IP fixa:
$ lxc network attach lxdbr0 contanier1 eth0 eth0 $ lxc config device set container1 eth0 ipv4.address 10.72.105.100
Es pot fer un for per a aplicar-ho a tots els contenidors:
$ for i in {101..113}; do echo $i; lxc copy ex ex$i; lxc config device set ex$i eth0 ipv4.address 10.72.105.$i; done
Per últim, cal fer les IPtables corresponents per redirigir el port:
$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2101 -j DNAT --to 10.72.105.101:22
Script per gestionar targetes:
(Obsolet, no l'esborre perquè té comandaments interessants, però en LXD 2.5 ja es poden fer les coses més fàcils i en Ubuntu 18.04 utilitza Netplan)
Scripts per a crear xarxes completes
(Scripts amb parts obsoletes)
Projecte 2017
Exemple
Exercici1
Exercici2
Simulacre
Script 2019
(El més actualitzat)
Altres scripts
Script per a crear un contenidor plantilla
Necessita previament un profile anomenat externa que configura la xarxa com macvlan:
#/bin/bash
container=${1:-'plantilla'}
lxc launch ubuntu:18.04 $container -c security.nesting=true
lxc profile assign $container externa
lxc restart $container
Script per a clonar la plantilla
#!/bin/bash
# $1 es la plantilla
# $2 es la quantitat
# $3 es el nom dels clons
lxc stop $1
for i in $(seq 1 $2); do
echo $3$i
lxc copy $1 $3$i
lxc start $3$i
sleep 10
# La configuració del netplan
echo '
network:
version: 2
ethernets:
eth0:
dhcp4: false
addresses: [10.100.23.'$(($i+100))'/23]
gateway4: 10.100.22.1
nameservers:
addresses: [8.8.8.8]' > /tmp/50-cloud-init.yaml
lxc file push /tmp/50-cloud-init.yaml $3$i/etc/netplan/
# La contrasenya d'ubuntu
lxc exec $3$i -- bash -c "echo ubuntu:1234 | chpasswd";
# Poder entrar per SSH per password
lxc exec $3$i -- sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
lxc restart $3$i
sleep 10
done
Script per a generar un mapa de la xarxa:
#!/bin/bash
echo 'digraph {
graph [pad="0.5", nodesep="0.5", ranksep="2", splines=ortho,];
node [shape=none]
rankdir=LR;'
bridges=($(brctl show | tail -n +2 |cut -f1 | tr "\n" " "))
for i in ${bridges[@]}
do
echo "$i [label=\"$i\" shape=box];"
done
containers=($(lxc list | egrep '(STOPPED|RUNNING)' | cut -d" " -f2 | tr "\n" " "))
xarxes="$(lxc list --format json | jq -r '.[] | {container: .name, dev: .expanded_devices[]} | [.container,.dev.name,.dev.parent,.dev.type] | @csv' | grep '"nic"$')"
relations=""
for i in ${containers[@]}
do
pc="$i [label=<<table border=\"0\" cellborder=\"1\" cellspacing=\"0\"><tr><td bgcolor=\"#CCCCCC\" >$i</td></tr>"
while read dev
do
nom=$(echo $dev | cut -d "," -f2 | tr -d '"')
switch=$(echo $dev | cut -d"," -f3 | tr -d '"')
pc=$pc"<tr><td port=\"$nom\">$nom</td></tr>"
#La IP
ip=$(lxc info $i | tr "\t" " " | grep "$nom: inet " | tr -s " " | cut -d" " -f4)
relations=$relations"$switch -> $i:$nom [dir=none headlabel=\"$ip\"] \n"
relations=$relations"//$i:$nom -> $switch [dir=none taillabel=\"$ip\"] \n"
done <<< "$(echo "$xarxes" | grep "$i")"
pc=$pc"</table>>];"
echo $pc
done
echo -e "$relations"
echo '}'
Script per a mostrar la RAM que utilitzen contenidors i subcontenidors:
#!/bin/bash
export LANG=C
function explorar {
local contenidor="$1"
#echo $contenidor
local contenidors=$(lxc exec $contenidor -- lxc list -c n --format csv 2> /dev/null)
#echo "lxc exec $contenidor -- lxc list -c n --format csv 2> /dev/null"
#echo $contenidors
[[ $contenidors != "" ]] && echo "$2⤷"
for i in $contenidors
do
nom=$i
estat=$(lxc exec $contenidor -- lxc info $i | grep 'Status' | cut -d" " -f2 2> /dev/null)
memoria='0MB'
if [[ $estat == 'Running' ]]; then
memoria=$(lxc exec $contenidor -- lxc info $i | grep 'Memory (current)' | awk '{print $3}' 2> /dev/null)
fi
echo "$2 $nom : $memoria"
cont="$contenidor -- lxc exec $nom"
explorar "$cont" "$2 " 2> /dev/null
done
}
contenidors=$(lxc list -c n --format csv)
for i in $contenidors
do
nom=$i
estat=$(lxc info $i | grep 'Status' | cut -d" " -f2)
memoria='0MB'
if [[ $estat == 'Running' ]]; then
memoria=$(lxc info $i | grep 'Memory (current)' | awk '{print $3}')
fi
echo "$nom : $memoria"
explorar "$i" " " 2> /dev/null
done