- L3 a kontejnery bez overlay: Project Calico prakticky (1) – architektura
- L3 a kontejnery bez overlay: Project Calico prakticky (2) – rozjezd
- L3 a kontejnery bez overlay: Project Calico prakticky (3) – BGP
- L3 a kontejnery bez overlay: Project Calico prakticky (4) – mikrosegmentace
- L3 a kontejnery bez overlay: Project Calico prakticky (5) – Docker libnetwork plugin
- L3 a kontejnery bez overlay: Project Calico prakticky (6) – Docker Swarm
L3 networking s Calico nepoužívá subnety a filtraci mezi nimi. Vše je (ideálně) flat L3 prostor. Jak zajistit, že kontejner může mluvit jen s těmi dalšími kontejnery, externími systémy a uživatelskými sítěmi, s kterými chceme? Ke slovu přichází mikrosegmentace a tagování. To si vyzkoušíme dnes.
IP segmentace
Začneme IP segmentací. V příštím díle, kdy budeme využívat plugin do orchestrátoru, nám toto základní rozdělení zajistí driver automaticky, ale prostředí z minulých částí seriálu je v tomto ohledu ruční. Jak říci který kontejner s kterým může mluvit? Používáme zde koncept profilů, či chcete-li tagů. Vytvoříte si profil s nějakým názvem a do něj přidáte kontejnery – to je vše.
Vytvořte profil modrý a červený.
docker@node1:~$ calicoctl profile add modra docker@node1:~$ calicoctl profile add cervena
Na node1 přidejte srv1 do modrého a srv2 do červeného a podobně na node2. Až budeme používat vyšších orchestrátorů uvidíte, že už nebude potřeba skákat do konkrétních hostitelů, ale tam zatím nejsme.
docker@node1:~$ calicoctl container srv1 profile append modra docker@node1:~$ calicoctl container srv2 profile append cervena docker@node2:~$ calicoctl container srv3 profile append modra docker@node2:~$ calicoctl container srv4 profile append cervena
Skočíme teď dovnitř kontejneru srv3 a zkusíme, kam se dopingáme. Uvidíte, že to jde do modrých, ale ne do červených.
docker@node2:~$ docker exec -ti srv3 sh / # ping 10.111.0.1 -c 1 PING 10.111.0.1 (10.111.0.1): 56 data bytes 64 bytes from 10.111.0.1: seq=0 ttl=62 time=0.537 ms --- 10.111.0.1 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.537/0.537/0.537 ms / # ping 10.111.0.2 -c 1 PING 10.111.0.2 (10.111.0.2): 56 data bytes ^C --- 10.111.0.2 ping statistics --- 1 packets transmitted, 0 packets received, 100% packet loss / # exit docker@node2:~$ docker exec -ti srv4 sh / # ping 10.111.0.1 -c 1 PING 10.111.0.1 (10.111.0.1): 56 data bytes ^C --- 10.111.0.1 ping statistics --- 1 packets transmitted, 0 packets received, 100% packet loss / # ping 10.111.0.2 -c 1 PING 10.111.0.2 (10.111.0.2): 56 data bytes 64 bytes from 10.111.0.2: seq=0 ttl=62 time=0.476 ms --- 10.111.0.2 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.476/0.476/0.476 ms / # exit
Jak to Calico udělá? Vypište si modrá pravidla.
docker@node1:~$ calicoctl profile modra rule show Inbound rules: 1 allow from tag modra Outbound rules: 1 allow
Směrem k modrým kontejnerů mohou mluvit pouze jiné modré kontejnery. Fyzicky je to implementováno v kernelu s použitím iptables a ipsetů.
docker@node1:~$ sudo iptables -S felix-p-modra-i -N felix-p-modra-i -A felix-p-modra-i -j MARK --set-xmark 0x1000000/0x1000000 -A felix-p-modra-i -m set --match-set felix-v4-modra src -j RETURN -A felix-p-modra-i -m comment --comment "No match, fall through to next profile" -j MARK --set-xmark 0x0/0x1000000
Vidíme inbound pravidlo v iptables, kde povolujeme komunikaci, která přichází z modrých kolegů. Bohužel hostitel vytvořený přes docker-machine nemá příkaz ipset, ale v něm byste viděli, že felix-v4-modra obsahuje výčet IP adres modrých kontejnerů. Připomeňme, že tato pravidla jsou stavová – nejde o jednoduché ACL, ale spíše o jednoduchý stavový firewall.
To je mikrosegmentace. Ve světě kontejnerů a mikroslužeb je už takové množství komponent, že tradiční řešení na velkém firewallu s desítkami tisíc pravidel je už naprosto neudržitelné (a ono je vlastně i dnes bez kontejnerů, prohlédněte si svoje firewall pravidla). Mikrosegmentace řeší situaci velmi elegantně tam, kde je vše dobře pochopitelné a udržitelné – tedy u samotných VM nebo kontejnerů.
Pokročilejší pravidla
Jasně, izolace kontejnerů podle skupin je fajn, ale potřebujeme víc. To není problém – Calico umí nejen pracovat se skupinami či IP adresami, ale také na L4. Ukažme si o malinko složitější nastavení.
Chceme, aby červení mohli přistupovat na modré webové servery na portu 80. Zařídíme to takhle:
docker@node1:~$ calicoctl profile modra rule add inbound allow tcp from tag cervena to ports 80
A protože rádi pingáme, povolíme ping na modré kontejnery komukoli.
docker@node1:~$ calicoctl profile modra rule add inbound allow icmp
Příslušné nastavení se nám pochopitelně promítne do iptables na všech hostitelých, kde běží nějaké modré kontejnery.
docker@node1:~$ sudo iptables -S felix-p-modra-i -N felix-p-modra-i -A felix-p-modra-i -j MARK --set-xmark 0x1000000/0x1000000 -A felix-p-modra-i -m set --match-set felix-v4-modra src -j RETURN -A felix-p-modra-i -p tcp -m set --match-set felix-v4-cervena src -m multiport --dports 80 -j RETURN -A felix-p-modra-i -p icmp -j RETURN -A felix-p-modra-i -m comment --comment "No match, fall through to next profile" -j MARK --set-xmark 0x0/0x1000000
Příkazová řádka vám třeba nevyhovuje a raději byste pravidla udržovali v nějakém souboru? I to je možné – stačí je popsat v následující JSON struktuře.
docker@node1:~$ cat pravidlo.json { "id": "modra", "inbound_rules": [ { "action": "allow", "protocol": "tcp", "dst_ports": [21] }, { "action": "allow", "protocol": "icmp", "icmp_type": 8 } ], "outbound_rules": [ { "action": "allow" } ] }
Tu následně můžete do profilu nahrát.
docker@node1:~$ calicoctl profile modra rule update < pravidlo.json docker@node1:~$ calicoctl profile modra rule show Inbound rules: 1 allow tcp to ports 21 2 allow icmp type 8 Outbound rules: 1 allow