h.rvé.netContactSe connecter
  • Contact

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Le(s) réseau(x) de Docker Swarm, deep dive

Posted by herve on 12 Sep 2021 in Linux et logiciel libre

Petite investigation sur le réseau Swarm.

Introduction

Il y a pas mal de littérature sur le réseau avec Docker et Swarm, notamment:

  • L'utilisation des réseaux Overlay avec Docker dans la doc officielle
  • Des articles avec des schémas pour creuser un peu plus comme celui-ci de Nigel Poulton


Mais concrètement, comment observer tout ça sur mes serveurs, dans mon terminal ? J'ai trouvé un très bon article ici mais je voulais mieux comprendre:

  • Le load balancing par IPVS
  • Où est effectué le port forwarding

Je vais donc explorer ça ici !

Setup

Prenons un cluster de 3 nodes swarm (parce que 1 ça n'est pas redondant, 2 ça n'est pas robuste au split, et plus de 3 c'est overkill :D).

Sur lequel on a démarré créé un service web tout simple dont voici le composefile:

---
version: '3.8'

services:
  web:
    image: httpd
    ports:
      - 8091:80
    deploy:
      replicas: 2
    networks:
      - testnet

networks:
  testnet:
    attachable: true

Pour démarrer cette stack:

docker stack deploy -c docker-compose.yml webtest

 

Check

On vérifie que c'est bien déployé, et que ça répond:

[herve@node0 test]$ docker service ls
ID             NAME                MODE         REPLICAS   IMAGE                     PORTS
ox7io3soug7o   webtest_web         replicated   2/2        httpd:latest              *:8091->80/tcp
[herve@node0 test]$ docker service ps webtest_web 
ID             NAME            IMAGE          NODE          DESIRED STATE   CURRENT STATE    ERROR   PORTS
mjyuczobcrb4   webtest_web.1   httpd:latest   node0         Running         Running 13 minutes ago             
klj0q37g2k22   webtest_web.2   httpd:latest   node1         Running         Running 13 minutes ago             
[herve@node0 test]$ curl 127.0.0.1:8091
<html><body><h1>It works!</h1></body></html>
[herve@node0 test]$

Exploration

Les réseaux utilisés par un container:

# pour avoir l'outil "ip"
herve@node0:~$ docker exec -ti webtest_web.2.klj0q37g2k22a1ar9f6sp7wai \
bash -c "apt-get update && apt-get install -y iproute2"
[snip]
herve@node0:~$ docker exec -ti webtest_web.2.klj0q37g2k22a1ar9f6sp7wai ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
25274: eth0@if25275: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default 
    link/ether 02:42:0a:00:00:c5 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.0.197/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
25276: eth2@if25277: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:0c brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet 172.18.0.12/16 brd 172.18.255.255 scope global eth2
       valid_lft forever preferred_lft forever
25278: eth1@if25279: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default 
    link/ether 02:42:0a:00:05:04 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet 10.0.5.4/24 brd 10.0.5.255 scope global eth1
       valid_lft forever preferred_lft forever
herve@node0:~$

On a donc 3 IPs, sur 3 réseaux:

  • 10.0.0.197/24 sur eth0
  • 10.0.5.4/24 sur eth1
  • 172.18.0.12/16 sur eth2

Sur l'autre container:

  • 10.0.0.196/24 sur eth0
  • 10.0.5.3/24 sur eth1
  • 172.18.0.6/16 sur eth2

Comparons ça aux réseaux docker:

herve@node0:~$ docker network ls
NETWORK ID     NAME                   DRIVER    SCOPE
a815e8c6b042   bridge                 bridge    local
040fa5ce7313   docker_gwbridge        bridge    local
918497e0a927   host                   host      local
yewz22nd9rf7   ingress                overlay   swarm
c53d64081620   none                   null      local
i0ylvjdz6sqg   webtest_testnet        overlay   swarm
herve@node0:~$ docker network inspect --format '{{ json .Containers  }}' docker_gwbridge | jq '.'
{
  "1b2ffd90e4f770b1f6db42bd48eef81d0c9c3edfe3d6298df1e4213a54b9e43c": {
    "Name": "gateway_161c8a8cd5e7",
    "EndpointID": "8cdadbc8543d4dc343ca6b3882e26d7a12251cb16c3b651bfe7ac636b673eef6",
    "MacAddress": "02:42:ac:12:00:06",
    "IPv4Address": "172.18.0.6/16",
    "IPv6Address": ""
  },
  "7d05626b82efc45c7d7834eafd55f025f8098b3e1dabe4ffd6e55754a8522e45": {
    "Name": "gateway_b5b17964f1aa",
    "EndpointID": "b5ab1d4a5f4b05a564653e3cf7132313487d74c1b6b9fb31535baf263dc8b1c5",
    "MacAddress": "02:42:ac:12:00:0c",
    "IPv4Address": "172.18.0.12/16",
    "IPv6Address": ""
  }, 
  "ingress-sbox": {
    "Name": "gateway_ingress-sbox",
    "EndpointID": "6a6974e33a38e0c97eb35f63688dda840731a4f74da6e7fc32f2202a2281bc17",
    "MacAddress": "02:42:ac:12:00:02",
    "IPv4Address": "172.18.0.2/16",
    "IPv6Address": ""
  }
}
herve@node0:~$ docker network inspect --format '{{ json .Containers  }}' ingress | jq '.'
{
  "7d05626b82efc45c7d7834eafd55f025f8098b3e1dabe4ffd6e55754a8522e45": {
    "Name": "webtest_web.2.klj0q37g2k22a1ar9f6sp7wai",
    "EndpointID": "65009589cd3e3083228c27c907c8dc956dc4e58e36b168eeb6b3955ee9174e4c",
    "MacAddress": "02:42:0a:00:00:c5",
    "IPv4Address": "10.0.0.197/24",
    "IPv6Address": ""
  },
  "ingress-sbox": {
    "Name": "ingress-endpoint",
    "EndpointID": "898b76a4aeb2144a60a7bd3066113e647974b0f639bb76934ac4c4ee43da68f5",
    "MacAddress": "02:42:0a:00:00:04",
    "IPv4Address": "10.0.0.4/24",
    "IPv6Address": ""
  }
}
herve@node0:~$ docker network inspect --format '{{ json .Containers  }}' webtest_testnet | jq '.'
{
  "7d05626b82efc45c7d7834eafd55f025f8098b3e1dabe4ffd6e55754a8522e45": {
    "Name": "webtest_web.2.klj0q37g2k22a1ar9f6sp7wai",
    "EndpointID": "619345cf52266f5b1c810ff1ccd3d8299952c226689234a13625ee62432e8eb9",
    "MacAddress": "02:42:0a:00:05:04",
    "IPv4Address": "10.0.5.4/24",
    "IPv6Address": ""
  },
  "lb-webtest_testnet": {
    "Name": "webtest_testnet-endpoint",
    "EndpointID": "3b3736e50d02ef8fb8abedaf721ef57b7f58f16a17cb8fa16fe0dd98cfb5aba2",
    "MacAddress": "02:42:0a:00:05:05",
    "IPv4Address": "10.0.5.5/24",
    "IPv6Address": ""
  }
}
herve@node0:~$

Décryptage:

Le réseau webtest_testnet (10.0.5.0/24) est un réseau overlay spécifique à mon service. Et je n'y vois que les containers présents sur le node.

Le réseau ingress (10.0.0.0/24) est un réseau overlay commun à tous mes services (D'autres containers de services Swarn sur le même host y apparaîtraient). Je n'y vois que les containers présents sur le node, référencés par leur nom.

Le réseau docker_gwbridge (172.18.0.0/16) est un réseau bridge (= qui fait le "pont" avec le host) commun à tous mes services. Et j'y voir des containers hébergés sur les hosts voisins. Par contre les noms "gateway_xxxx" ne sont pas associables directement à un container.

Un peu de sondage avec curl

herve@node0:~$ curl 172.18.0.1:8091
<html><body><h1>It works!</h1></body></html>
herve@node0:~$ curl 172.18.0.2:8091
<html><body><h1>It works!</h1></body></html>
herve@node0:~$ curl 172.18.0.6:8091
curl: (7) Failed to connect to 172.18.0.6 port 8091: Connection refused
herve@node0:~$ curl 172.18.0.12:8091
curl: (7) Failed to connect to 172.18.0.12 port 8091: Connection refused
herve@node0:~$ curl 172.18.0.6:80
curl: (7) Failed to connect to 172.18.0.6 port 80: Connection refused
herve@node0:~$ curl 172.18.0.12:80
<html><body><h1>It works!</h1></body></html>
herve@node0:~$
  • 172.18.0.1 est une IP portée par le host (interface docker_gwbridge). Elle permet d'accéder à mon service.
  • Via 172.18.0.2, l'IP de la gateway_ingress-sbox du réseau docker docker_gwbridge, ça marche aussi.
  • Par contre avec 172.18.0.6 et 172.18.0.12, les IPs des containers, ça ne marche plus sur le port exposé sur le host (8091)
  • Mais sur 172.18.0.12, l'ip du container qui tourne sur le host en cours, je peux interroger le port exposé dans le container (80).

Il semble se passer des choses intéressantes dans ce réseau &#58;&#68;

iptables et namespaces réseau

Commencons par le début, ce qui arrive sur notre host

herve@node0:~$ sudo iptables -nv -L PREROUTING -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in  out  source         destination         
 222M   20G DOCKER-INGRESS  all  --  *   *  0.0.0.0/0   0.0.0.0/0      ADDRTYPE match dst-type LOCAL
 173M   17G DOCKER     all  --  *   *    0.0.0.0/0      0.0.0.0/0      ADDRTYPE match dst-type LOCAL
herve@node0:~$

PREROUTING (et OUTPUT) passent les paquets dans les tables DOCKER-INGRESS et DOCKER. DOCKER pour les containers standard Docker, DOCKER-INGRESS pour Swarm.
Intéressons-nous à DOCKER-INGRESS

herve@node0:~$ sudo iptables -nv -L DOCKER-INGRESS -t nat | grep 8091
    4   240 DNAT       tcp  --  *    *     0.0.0.0/0      0.0.0.0/0       tcp dpt:8091 to:172.18.0.2:8091
herve@node0:~$ 

Le port 8091 va être redirigé vers 172.18.0.2.
Tout traffic entrant sur mon host sur le port 8091 est redirigé vers le réseau docker_gwbridge.
Nickel.

La suite se passe dans un autre namespace réseau, nommé ingress_sbox

Commençons par regarder les namespaces réseau:

herve@node0:~$ sudo ls -l /run/docker/netns
total 0
-r--r--r-- 1 root root 0 Sep 11 08:01 1-i0ylvjdz6s
-r--r--r-- 1 root root 0 Jul 16 13:15 1-yewz22nd9r
-r--r--r-- 1 root root 0 Sep 11 08:01 b5b17964f1aa
-r--r--r-- 1 root root 0 Jul 16 13:15 ingress_sbox
-r--r--r-- 1 root root 0 Sep 11 08:01 lb_i0ylvjdz6
herve@node0:~$ 

Inventaire:

  • 1-xxx correspond à un réseau overlay
  • 1-i0ylvjdz6s pour le réseau docker i0ylvjdz6sqg - webtest_testnet
  • 1-yewz22nd9r pour le réseau docker yewz22nd9rf7 - ingress
  • lb_i0ylvjdz6 pour le load balancer du réseau i0ylvjdz6sqg - webtest_testnet
  • ingress_sbox - au moins lui il a un nom parlant !
  • b5b17964f1aa pour finir: spécifique à notre container. (il n'y en a qu'un, car l'autre container est sur un autre host).

On peuc retrouver l'ID du netns de notre container en l'inspectant:

herve@node0:~$ docker inspect \
--format '{{ json .NetworkSettings.SandboxKey  }}' webtest_web.2.klj0q37g2k22a1ar9f6sp7wai \
| jq '.'
"/var/run/docker/netns/b5b17964f1aa"
herve@node0:~$ 

Exploration du namespace ingress_sbox

herve@node0:~$ sudo nsenter --net=/run/docker/netns/ingress_sbox \
iptables -t mangle -L PREROUTING -vn | head -n 2
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in   out  source            destination         
herve@node0:~$ sudo nsenter --net=/run/docker/netns/ingress_sbox \
iptables -t mangle -L PREROUTING -vn | grep 8091
   42  2792 MARK       tcp  --  *    *    0.0.0.0/0         0.0.0.0/0      tcp dpt:8091 MARK set 0x27f2
herve@node0:~$ sudo nsenter --net=/run/docker/netns/ingress_sbox \
iptables -t mangle -L INPUT -vn | grep 27f2
    0     0 MARK       all  --  *    *    0.0.0.0/0         10.0.0.195     MARK set 0x27f2
herve@node0:~$ # 0x27f2 = 10226 en base 10
herve@node0:~$ sudo nsenter --net=/run/docker/netns/ingress_sbox \
ipvsadm | grep -A 3 10226
FWM  10226 rr
  -> 10.0.0.196:0                 Masq    1      0          0         
  -> 10.0.0.197:0                 Masq    1      0          0         
herve@node0:~$

On voit ici que les paquets à destination de TCP:8091 sont taggés "0x27f2", ainsi que tous ceux à destination de 10.0.0.195.

Ensuite, IPVS a des règles de routage pour les paquets taggés "0x27f2", indiquant qu'il faut faire du round robin entre 10.0.0.196 et 10.0.0.197.

Les paquets sont donc transmis à chaque container du service à tour de rôle, tout en gardant le même port pour le moment (8091)

Port-forwarding

Pour terminer, le port forwarding se passe dans le namespace spécifique à chaque container:

herve@node0:~$ sudo nsenter --net=/var/run/docker/netns/b5b17964f1aa iptables -L PREROUTING -t nat -nv
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out   source          destination         
   86  5160 REDIRECT   tcp  --  *      *     0.0.0.0/0       10.0.0.197      tcp dpt:8091 redir ports 80
herve@node0:~$ 

Conclusion

On a vu:

  • Le routage des paquets extérieurs, du réseau host vers le docker_gwbridge
  • Leur tagging vers pour utilisation sur un load-balancer IPVS
  • la redirection du load-balancer vers une IP privée sur le réseau ingress
  • la redirection du port exposé par Docker vers le port exposé par le service dans le container

On n'a pas vu:

  • les vxlans, ou comment abstraire le fait que les containers sont sur différents hosts
  • le lien entre réseaux docker et namespaces réseau
  • les communications d'un container à un autre
  • ...et plein d'autres choses passionnantes...

Personnellement, c'est un truc que je trouve génial avec Docker: ça repose énormément sur des mécanismes système, présents bien avant Docker.

C'est donc possible d'explorer tout ça sans lire le code source, juste en observant les serveurs.

À vous de continuer à explorer &#58;&#68; et vivement qu'on se croise à un meetup pour discuter de tout ça &#59;&#41;

Versions utilisées

  • Version de Docker: 20.10.7
  • Hosts: Debian 10
Réagir »

Waterfall scrum

Posted by herve on 03 Nov 2017 in Linux et logiciel libre

/!\ Caution: do not try it at home, you may suffer severe tunnel effect injuries /!\

 

This statement may seem familiar to you :

"We want to do scrum, but we are a big and serious company, we can't afford to break prod.
The best way to ensure we don't break anything is to validate each step of our software engineering by architects and managers."

 

The resulting process looks like that :

  • one sprint to play with the foreseen technologies
  • one sprint to define the architecture
  • two or three sprints to actually write the code
  • one sprint for QA to test the application
  • one sprint for deployment

With 1-month sprints, that makes 6 months before we deliver anything to production.
It looks more like waterfall than like Scrum.

 

 

I guess the main problem is bad MVP definition.
The MVP often includes a lot of security, operability, resiliency, high availability, observability, whatever-y requirements that, while important, may not be needed for a first version.

 

And what leads to this bad MVP definition is:

  1. Lack of trust. I often hear "If we don't do it right now, [they] won't let us do it later."

  2. Lack of identification of roles. Who are [they] ? Could we negociate something with them ?

  3. Lack of communication with customer. Even when the customer is in the same company, in the next door office, we often consider (without asking them) he won't accept a feature that is not rock-solid, even if delivered as "beta version", a few months before the planned "rock-solid" delivery date.

  4. Lack of communication with accountable experts. The architects and various experts that have to validate your architecture just want to make sure you won't break existing features in production. They may accept that new features could be broken under some conditions, but that has to be negociated.

  

 

At the end, the missing bits are:

  • Individuals and interactions over processes and tools
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan
  • (Working software over comprehensive documentation)

 

Scrum is useless if we forget the bases: http://agilemanifesto.org/

Réagir »

Retour sur les 24HSeries au Castelet

Posted by herve on 10 Mai 2017 in Non catégorisé, Linux et logiciel libre

Altran, mon employeur, m'a invité aux 24HSeries au circuit Paul Ricard (http://www.24hseries.com/2017/24h-circuit-paul-ricard-2017/start), pour suivre la course de la team Altran.

 

Présentation de la course

C'est donc une course d'endurance de 24H: l'objectif étant, en 24H, d'alligner le plus de tours de circuit possible. La mécanique est très sollicitée, et sur cette épreuve quasiment 1/3 des concurrents n'ont pas réussi à courrir jusqu'à la fin de la course.

Une équipe est constituée principalement de:

  • pilotes, qui se relaient au volant toutes les 2H maximum.
  • mécaniciens, pour la maintenance aux stands (pneus, freins, et autres)
  • équipe de stratégie, dans la salle de télémétrie, qui communiquent avec les pilotes et établissent la stratégie de course
  • pompistes, car la pompe à essence n'est pas dans le stand de l'équipe

 

Les deux voitures du Team Altran sont des 308 RC, de 1100Kg pour environ 310CV. L'équipe courrait avant en 208, et les 308 sont toutes neuves. Elles n'ont fait qu'une course de 12H peu de temps avant. Tous les réglages (chassis, cartographie, transmission…) sont encore jeunes, et l'équipe ne connaît pas encore bien les voitures. 

Retour sur les 24HSeries au Castelet

 

Début de journée

À partir de 10H, nous avons visité les stands et découvert les voitures. Les mécanos avaient travaillé une bonne partie de la nuit (jusque 4:30 du matin!) pour changer les boites de vitesses, et monter des pièces d'embrayage ajustées en urgence la veille. Au matin, ils effectuaient les dernières vérifications, avant le début des échauffements à 11H.

De 11H à 12H, échauffements. Là, ils se rendent compte que les embrayages ne se comportent pas comme attendu. Investigations en urgence avant le placement sur la grille de départ, prévu à 13H ! Il faut alors identifier la cause (4/10e de mm d'usinage en trop lors de la modif de la veille), déterminer un correctif et appliquer, le tout avant le départ de la course! Timing très tendu, mais ça passe!

À 13H, placement sur la grille de départ, que nous pouvons aller visiter. Là, toutes les équipes hésitent entre les pneus slick et les pneus pluie. En effet la météo est très hésitante. Une grosse averse se déclare avant le départ, mettant tout le monde d'accord pour les pneus pluie.

Pendant la course

Une fois la course démarrée, on pourrait se dire "c'est parti, il n'y a plus qu'à alligner les tours pendant 24H". Si seulement!

Assez rapidement, les voitures rencontrent des problèmes. Les retours que j'ai eu sont assez flous: problèmes de turbo, problèmes de capteur de pression de carburant, ou encore qualité des mousses de réservoir.

J'ai pu observer les mécaniciens en situation d'urgence, agir de manière calme et efficace, investiguer, se partager les tâches, négocier avec l'équipe stratégie pour trouver des solutions sur la durée de la course.

J'ai vraiment apprécié cet aspect de la course, car le parallèle avec mon métier de SRE m'a frappé. Pour faire tenir un site web le temps d'un pic d'audience comme pour faire courrir une voiture pendant 24H, il faut du sang froid, réfléchir vite et trouver des solutions innovantes. Et en tirer des leçons, pour anticiper la prochaine situation de crise.

J'imagine que les équipes du Team Altran rédigent un "post-mortem" retraçant les incidents et avaries de la course, les résolutions tentées et les résultats de ces résolutions.
#teamaltran, si vous me lisez, j'adorerais lire ce document! C'est un aspect de la course qui m'a fasciné!

 

Réagir »

[docker] premiers pas avec Moby et LinuxKit

Posted by herve on 19 Avr 2017 in Linux et logiciel libre

Intro

Lors de la Dockercon, Docker vient d'annoncer

  •  Moby: "A new open-source project for to advance the software containerization movement" (https://blog.docker.com/2017/04/introducing-the-moby-project/)
  • Linuxkit: "A toolkit for building secure, lean and portable Linux subsystems" (https://blog.docker.com/2017/04/introducing-linuxkit-container-os-toolkit/)

Je ne sais pas pour vous, mais j'ai trouvé ces annonces un peu nébuleuses.
Si on y ajoute le fait que github.com/docker/docker a été renommé en moby/moby, il y a vraiment de quoi se perdre.

Le meilleur de moyen de se faire une idée, c'est de jouer avec!
Direction le github de linuxkit: https://github.com/linuxkit/linuxkit

 

Prise en main

Et c'est parti pour un essai, en suivant les instructions.

Récupération du dépôt:

[herve@salon git]$ git clone https://github.com/linuxkit/linuxkit.git
Clonage dans 'linuxkit'...
remote: Counting objects: 19756, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 19756 (delta 1), reused 0 (delta 0), pack-reused 19746
Réception d'objets: 100% (19756/19756), 15.66 MiB | 703.00 KiB/s, fait.
Résolution des deltas: 100% (11869/11869), fait.
Vérification de la connectivité... fait.
[herve@salon git]$ cd linuxkit/
Compilation de moby:
[herve@salon linuxkit]$ make
tar cf - vendor src/initrd src/pad4 -C src/cmd/moby . | docker run --rm --net=none --log-driver=none -i  linuxkit/go-compile:4513068d9a7e919e4ec42e2d7ee879ff5b95b7f5@sha256:bdfadbe3e4ec699ca45b67453662321ec270f2d1a1dbdbf09625776d3ebd68c5 --package github.com/linuxkit/linuxkit --ldflags "-X main.GitCommit=f2d6752751318477ec86e4677514d5a4890249c1 -X main.Version="0.0" " -o bin/moby > tmp_moby_bin.tar
Unable to find image 'linuxkit/go-compile:4513068d9a7e919e4ec42e2d7ee879ff5b95b7f5@sha256:bdfadbe3e4ec699ca45b67453662321ec270f2d1a1dbdbf09625776d3ebd68c5' locally
sha256:bdfadbe3e4ec699ca45b67453662321ec270f2d1a1dbdbf09625776d3ebd68c5: Pulling from linuxkit/go-compile
627beaf3eaaf: Pulling fs layer
1b3a1005911c: Pulling fs layer
 
[...]
d58e6f1740ab: Pull complete
49418cbb2668: Pull complete
Digest: sha256:bdfadbe3e4ec699ca45b67453662321ec270f2d1a1dbdbf09625776d3ebd68c5
Status: Downloaded newer image for linuxkit/go-compile@sha256:bdfadbe3e4ec699ca45b67453662321ec270f2d1a1dbdbf09625776d3ebd68c5
gofmt...
govet...
golint...
ineffassign...
go build...
tar xf tmp_moby_bin.tar > bin/moby
rm tmp_moby_bin.tar
touch bin/moby
[herve@salon linuxkit]$
On voit donc que la compilation se fait dans un container, qui sort un fichier bin/moby.
C'est un binaire go, compilé en statique.
 
Et il fait quoi ce binaire ?
[herve@salon linuxkit]$ ./bin/moby --help
USAGE: moby [options] COMMAND

Commands:
build Build a Moby image from a YAML file
run Run a Moby image on a local hypervisor or remote cloud
version Print version information
help Print this message

Run 'moby COMMAND --help' for more information on the command

Options:
-q Quiet execution
-v Verbose execution
[herve@salon linuxkit]$ ./bin/moby build --help
USAGE: ./bin/moby build [options] <file>[.yml]
 
Options:
  -name string
    Name to use for output files
  -pull
    Always pull images
[herve@salon linuxkit]$
Il a en gros deux fonctions:
  • création d'une "image moby"
  • exécution d'une "image moby"
On crée notre première image avec le fichier yaml d'exemple.
[herve@salon linuxkit]$ ./bin/moby build linuxkit.yml 
Extract kernel image: mobylinux/kernel:4.9.x
Add init containers:
Process init image: linuxkit/init:42fe8cb1508b3afed39eb89821906e3cc7a70551
Process init image: mobylinux/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9
Process init image: linuxkit/containerd:60e2486a74c665ba4df57e561729aec20758daed
Process init image: mobylinux/ca-certificates:eabc5a6e59f05aa91529d80e9a595b85b046f935
Add onboot containers:
  Create OCI config for mobylinux/sysctl:2cf2f9d5b4d314ba1bfc22b2fe931924af666d8c
  Create OCI config for linuxkit/binfmt:8881283ac627be1542811bd25c85e7782aebc692
  Create OCI config for linuxkit/dhcpcd:48e249ebef6a521eed886b3bce032db69fbb4afa
Add service containers:
  Create OCI config for mobylinux/rngd:3dad6dd43270fa632ac031e99d1947f20b22eec9
  Create OCI config for nginx:alpine
Add files:
  etc/docker/daemon.json
Create outputs:
  linuxkit-bzImage linuxkit-initrd.img linuxkit-cmdline
  linuxkit.iso
  linuxkit-efi.iso
[herve@salon linuxkit]$ 
 
Il a donc travaillé à partir d'images disponibles sur le hub docker, et a créé quelques fichiers posés dans le répertoire courant.
Une vue rapide sur ce qu'il a récupéré et créé:
[herve@salon linuxkit]$ docker images 
REPOSITORY                  TAG                                        IMAGE ID            CREATED             SIZE
linuxkit/containerd         60e2486a74c665ba4df57e561729aec20758daed   afaa98d7b77e        4 days ago          83.1MB
linuxkit/init               42fe8cb1508b3afed39eb89821906e3cc7a70551   52ad30265955        4 days ago          4.55MB
linuxkit/dhcpcd             48e249ebef6a521eed886b3bce032db69fbb4afa   4a8d5b4ecdda        5 days ago          6.86MB
linuxkit/binfmt             8881283ac627be1542811bd25c85e7782aebc692   dd624a622fea        6 days ago          10.6MB
linuxkit/go-compile         <none>                                     3bea6c95b424        6 days ago          411MB
linuxkit/mkimage-iso-bios   <none>                                     9fc22c04f66c        6 days ago          18.9MB
linuxkit/mkimage-iso-efi    <none>                                     123a3bc2f714        7 days ago          21.6MB
mobylinux/kernel            4.9.x                                      26ec714a55ef        9 days ago          7.8MB
mobylinux/ca-certificates   eabc5a6e59f05aa91529d80e9a595b85b046f935   ce2c43db3a0f        12 days ago         275kB
mobylinux/runc              b0fb122e10dbb7e4e45115177a61a3f8d68c19a9   cb5eaf524002        12 days ago         6.87MB
nginx                       alpine                                     bedece1f06cc        13 days ago         54.3MB
mobylinux/sysctl            2cf2f9d5b4d314ba1bfc22b2fe931924af666d8c   c62b83d03caa        5 weeks ago         1.8MB
mobylinux/rngd              3dad6dd43270fa632ac031e99d1947f20b22eec9   818d6105077e        3 months ago        129kB
[herve@salon linuxkit]$ ls -ltr
 
[...]
-rw-r--r--.  1 herve herve 52013237 19 avril 20:03 linuxkit-initrd.img
-rw-r--r--.  1 herve herve  7021136 19 avril 20:03 linuxkit-bzImage
-rw-r--r--.  1 herve herve       40 19 avril 20:03 linuxkit-cmdline
-rw-r--r--.  1 herve herve 59768832 19 avril 20:04 linuxkit.iso
-rw-r--r--.  1 herve herve 59949056 19 avril 20:04 linuxkit-efi.iso
[herve@salon linuxkit]$ 
 
Exécution!
[herve@salon linuxkit]$ ./bin/moby run linuxkit
[    0.000000] Linux version 4.9.21-moby (root@84baa8e89c00) (gcc version 6.2.1 20160822 (Alpine 6.2.1) ) #1 SMP Sun Apr 9 22:21:32 UTC 2017
[    0.000000] Command line: console=ttyS0 console=tty0 page_poison=1
[    0.000000] x86/fpu: Legacy x87 FPU detected.
[    0.000000] x86/fpu: Using 'eager' FPU context switches.
[    0.000000] e820: BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
[    0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
 
[...]
[    3.082403] Freeing unused kernel memory: 1184K (ffff91e15ecd8000 - ffff91e15ee00000)
[    3.570774] tsc: Refined TSC clocksource calibration: 3600.004 MHz
[    3.571355] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x33e456ed7d0, max_idle_ns: 440795322762 ns
 
Welcome to LinuxKit
 
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/
 
 
/ #
 
Woohoo, il m'a lancé… un container? Avec un microkernel? Ou une VM?
[herve@salon ~]$ pstree -la $(pgrep moby)
moby run linuxkit
  ├─qemu-system-x86 -device virtio-rng-pci -smp 1 -m 1024 -enable-kvm -machine q35,accel=kvm:tcg -kernel linuxkit-bzImage -initrd linuxkit-initrd.img -append console=ttyS0 console=tty0 page_poison=1 -nographic
  │   └─2*[{qemu-system-x86}]
  └─4*[{moby}]
[herve@salon ~]$ 
Une VM qemu visiblement!
À noter: un objectif est de démarrer ça sur des serveurs virtuels sur un IaaS, ou même sur des machines physiques via PXE. 
 
Retournons sur notre VM.
À part les process kernel, qu'est-ce qui tourne?
/ # cat /etc/alpine-release
3.5.2
/ # ps edf | grep -v "\[.*\]"
PID   USER     TIME   COMMAND
    1 root       0:02 /sbin/init
  276 root       0:00 /usr/bin/containerd
  280 root       0:00 {containers} /bin/sh /etc/init.d/containers
  288 root       0:00 /bin/sh --
  289 root       0:00 /bin/sh --
  417 root       0:00 ctr run --runtime-config /containers/services/nginx/config.json --rootfs /containers/services/nginx/rootfs --id nginx
  433 root       0:00 containerd-shim
  447 root       0:00 nginx: master process nginx -g daemon off;
  532 100        0:00 nginx: worker process
  600 root       0:00 ps edf
/ #
On a vraiment très peu de process. Init, sh, et un container nginx.
Mais pas de Docker!
Regardons ctr de plus près:
/ # ctr --help
NAME:
   ctr - 
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/
 
containerd client
 
 
USAGE:
   ctr [global options] command [command options] [arguments...]
 
VERSION:
   1.0-dev+unknown
 
COMMANDS:
     run      run a container
     events   display containerd events
     delete   delete an existing container
     list     list containers
     info     get info about a container
     kill     signal a container
     pprof    provides golang pprof outputs for containerd
     exec     execute additional processes in an existing container
     shim     interact with a shim directly
     help, h  Shows a list of commands or help for one command
 
GLOBAL OPTIONS:
   --debug                    enable debug output in logs
   --address value, -a value  address for containerd's GRPC server (default: "/run/containerd/containerd.sock")
   --root value               path to content store root (default: "/var/lib/containerd")
   --help, -h                 show help
   --version, -v              print the version
/ # ctr list
ID        PID       STATUS
nginx     447       RUNNING
/ # ctr info --id nginx
{
"id": "nginx",
"pid": 447,
"status": 2
}
/ #
C'est un outil permettant de gérer ses containers, mais beaucoup plus limité que docker.
Par exemple, je n'ai pas réussi à puller une nouvelle image avec.
 

Conclusion: 

Il y a quelque chose de pas clair sur le nommage linuxkit / moby.
Moby automatise la création d'images OS, linuxkit fournit toutes les briques pour cette création. Et les briques de base sont du Alpine.
Mais dans ce cas, pourquoi avoir renommé le dépôt docker/docker sur github? Ça semble deux produits bien différents!
 
Pour ce qui est de l'utilité de ces images OS, j'ai ma petite idée. En suivant le principe du pet vs cattle, du standard et jetable, il est logique d'aller jusqu'à des serveurs jetables.
On appelle ça des serveurs Phoenix, ou on peut aller encore plus loin avec des serveurs immuables.
On change le cycle de intégration/release/déploiement, pour livrer des images d'OS (50Mo l'image nginx créée pour l'article), et pour déployer on reboote les serveurs, ou on recycle les VMs. 
 
 
 

 

Réagir »

Fabrication et pose d'une fibre optique sous-marine

Posted by herve on 19 Déc 2016 in Linux et logiciel libre
Réagir »
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
Février 2023
Lun Mar Mer Jeu Ven Sam Dim
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28          
 << <   > >>

Rechercher

Catégories

Blog h.rvé

  • Linux et logiciel libre
  • Musique
  • Non catégorisé
  • Vie du blog
  • Vie sociale et citoyenne

Flux XML

  • RSS 2.0: Posts, Commentaires
  • Atom: Posts, Commentaires
What is RSS?

Posts récents

  • Le(s) réseau(x) de Docker Swarm, deep dive
  • Waterfall scrum
  • Retour sur les 24HSeries au Castelet
  • [docker] premiers pas avec Moby et LinuxKit
  • Fabrication et pose d'une fibre optique sous-marine
  • Docker et les Go Templates
  • Megaprocessor - un processeur dont on peut voir chaque transistor
  • Keynote: State of the Linux Kernel, Greg Kroah-Hartman
  • L'art de se débarrasser ce qui est inutile.
  • La magie de l'Internet des Objets: quand "sécurité" est un gros mot

Commentaires récents

  • afix le Docker: volumes et dépendances croisées
  • afix le Docker: volumes et dépendances croisées
  • Richard le Les empreintes digitales pour remplacer les mots de passe: bad idea!
  • Henri le Megaprocessor - un processeur dont on peut voir chaque transistor
  • Henri le L'art de se débarrasser ce qui est inutile.
  • herve le L'art de se débarrasser ce qui est inutile.
  • Henri le L'art de se débarrasser ce qui est inutile.
  • Joel le Unikernels et Docker: une explication claire.
  • Henri le "The End of the Internet Dream", ou pas.
  • Agnès le Haken, rock progressif
  • herve le Une imprimante 3D pour $60
  • Agnès le Une imprimante 3D pour $60
  • Henri le Une imprimante 3D pour $60
  • Agnès le Bienvenue!
  • herve le Bienvenue!
  • Agnès le Bienvenue!
  • Agnès le Site parlement-et-citoyens.fr
  • Agnès le Bienvenue!
  • herve le Bienvenue!
  • Fabien le Bienvenue!

Licence Creative Commons
Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International. • Contact • Aide • Community software

CMS with Bootstrap

Cookies are required to enable core site functionality.