01. [15p] Conectare logică a două containere

Până acum în laboratorul de Rețele Locale am simulat o topologie de rețea folosind containere LXC (Linux Containers). Pentru a vedea ce containere LXC sunt disponibile într-un sistem folosim pe stația host comanda lxc-list:

root@host:~# lxc-list
RUNNING
 
FROZEN
 
STOPPED
  blue (auto)
  green (auto)
  red (auto)

Pe stația host sunt disponibile, pe moment, două interfețe: interfața de loopback (lo) și intefața de rețea a stației (eth0). Putem observa acest lucru folosind comanda

root@host:~# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
[...]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
[...]

Observăm că sunt 3 containere în sistem (blue, green și red), toate în starea STOPPED (oprite). Pentru a porni container-ul blue vom folosi comanda lxc-start -d -n blue:

root@host:~# lxc-start -n blue -d
root@host:~# lxc-list
RUNNING
  blue (auto)
 
FROZEN
 
STOPPED
  green (auto)
  red (auto)
 
root@host:~# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
[...]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
[...]
20: veth-blue: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000

Observăm că starea container-ului blue este RUNNING. Parametrul -d este folosit pentru a porni containerul în mod daemon, iar -n specifică numele containerului ce se dorește a fi pornit. De asemenea, observăm apariția interfeței virtuale veth-blue, interfață ce face legătura stației host cu stația blue (mai precis cu interfața eth0 internă stației blue).

Trebuie să folosim parametrul -d al comenzii lxc-start pentru a porni containerul ca un daemon (în background). Altfel, terminalul curent va fi blocat de comenzile rulate în container și nu vom putea ieși din acesta folosind combinația de taste Ctrl+a și apoi q.

Porniți container-ul green și verificați că este în starea RUNNING

root@host:~# lxc-start -n green -d
root@host:~# lxc-list
RUNNING
  blue (auto)
  green (auto)
 
FROZEN
 
STOPPED
  red (auto)
 
root@host:~# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
[...]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
[...]
20: veth-blue: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
[...]
23: veth-green: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000

Observăm că acum sunt pornite containerele blue și green. Observăm că pe stația host există două interfețe virtuale: veth-blue (legătura cu stația blue) si veth-green (legătura cu stația green).

Dorim să conectăm cele 2 containere (blue și green) în același switch virtual. Pe Linux putem simula un switch folosind noțiunea de bridge. Pentru crearea și configurarea unui bridge vom folosi comanda brctl.

Pe stația host vom crea un bridge (denumit br0) executând comanda:

root@host:~# brctl addbr br0

Pentru a verifica că bridge-ul a fost creat folosim comanda brctl show:

root@host:~# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.000000000000       no

Pentru a permite conectivitatea între containere și între containere și stația host va trebui să legăm interfețele virtuale aferente în bridge-ul proaspăt creat. Altfel spus, dorim să conectăm la bridge-ul br0 interfețele aferente de pe stația host ale lui blue (adică interfața veth-blue) și lui green (interfața veth-green). Vom folosi comanda brctl addif:

root@host:~# brctl addif br0 veth-blue
root@host:~# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.7acc4f8a0686       no              veth-blue
root@host:~# brctl addif br0 veth-green
root@host:~# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.3a89dafa5a72       no              veth-blue
                                                        veth-green

Pentru a valida operațiunea de adăugare folosim comanda brctl show.

Exercițiu: Pentru a testa conectivitatea între containere, trebuie configurate adrese IP pe interfețele interne (eth0) alte containerelor. Configurați pe interfața eth0 a stației blue adresa IP 192.168.1.4/24 și pe interfața eth0 a stației green adresa IP 192.168.1.3/24. Pentru reamintire, puteți parcurge 1. [10p] Conectare SSH folosind cheie publică.

Nu trebuie să configurați adrese IP pe interfețele de tip veth de pe stația host. Adică interfețele veth-red, veth-blue și veth-green nu vor avea adrese IP configurate.

Pentru testarea conectivității între containere folosim comanda ping dintr-un container sau altul:

root@blue:~# ping -c 2 192.168.1.3
PING 192.168.1.3 (192.168.1.3) 56(84) bytes of data.
From 192.168.1.4 icmp_seq=1 Destination Host Unreachable
From 192.168.1.4 icmp_seq=2 Destination Host Unreachable
 
--- 192.168.1.3 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 999ms
pipe 2
root@blue:~# ip r s
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.4 
 
root@green:~# ping -c 2 192.168.1.4
PING 192.168.1.4 (192.168.1.4) 56(84) bytes of data.
From 192.168.1.3 icmp_seq=1 Destination Host Unreachable
From 192.168.1.3 icmp_seq=2 Destination Host Unreachable
 
--- 192.168.1.4 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1007ms
pipe 2
root@green:~# ip r s   
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.3 

Observăm că nu avem conectivitate deși interfețele sunt active și adresele IP fac parte din aceeași rețea și tabela de rutare conține intrarea corespunzătoare. Problema poate fi de la bridge. Pe stația host verificăm legătura de nivel 2 a bridge-ului br0:

root@host:~# ip link show dev br0
20: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN
    link/ether 3a:89:da:fa:5a:72 brd ff:ff:ff:ff:ff:ff

Observăm că bridge-ul este inactiv (state DOWN). Activăm bridge-ul:

root@host:~# ip link set dev br0 up
root@host:~# ip link show dev br0
20: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 3a:89:da:fa:5a:72 brd ff:ff:ff:ff:ff:ff

Testăm din nou conectivitatea între containerele green și blue:

root@green:~# ping -c 2 192.168.1.4
PING 192.168.1.4 (192.168.1.4) 56(84) bytes of data.
64 bytes from 192.168.1.4: icmp_req=1 ttl=64 time=0.070 ms
64 bytes from 192.168.1.4: icmp_req=2 ttl=64 time=0.045 ms
 
--- 192.168.1.4 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.045/0.057/0.070/0.014 ms
 
root@blue:~# ping -c 2 192.168.1.3
PING 192.168.1.3 (192.168.1.3) 56(84) bytes of data.
64 bytes from 192.168.1.3: icmp_req=1 ttl=64 time=0.036 ms
64 bytes from 192.168.1.3: icmp_req=2 ttl=64 time=0.029 ms
 
--- 192.168.1.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.029/0.032/0.036/0.006 ms

Acum există conectivitate între cele două containere.