Comprenez ce que signifie partager un espace de noms Linux via $ podman pod create --share namespace.

Dernière fois Lorsque j'étudiais comment gérer les pods pour l'intégration multi-conteneurs dans podman, podman-pod-create / markdown / podman-pod-create.1.md) C'est facile car je n'étais pas sûr de ce qu'était exactement le "namespace shared" avec l'option `` `--share``` de la commande. J'ai essayé de le rendre intuitivement compréhensible grâce à la pratique.

introduction

J'ai écrit cet article dans le but de comprendre ce qui suit à la fin de la lecture.

Qu'est-ce que --share * namespace *?

C'est l'une des options qui peuvent être utilisées lors de la création d'un pod avec la commande podman pod create. Le rôle et le format sont décrits dans le référentiel [libpod](create https://github.com/containers/podman/blob/master/docs/source/markdown/podman-pod-create.1.md).

####--share=namespace A comma delimited list of kernel namespaces to share. If none or "" is specified, no namespaces will be shared. The namespaces to choose from are ipc, net, pid, user, uts.

--Option pour spécifier l'espace de noms partagé dans le pod. --Spécifiez plusieurs éléments dans une liste séparée par des virgules.

Ah, je vois. ** Je comprends parfaitement. ** Ce n'est qu'une explication, mais il semble que certaines connaissances préalables soient nécessaires pour le comprendre.

Qu'est-ce qu'un espace de noms en premier lieu?

Grand-mère disait. Chaque fois que vous recherchez quelque chose, regardez-le à partir de la source principale. Selon la page de manuel des espaces de noms, c'est comme suit.

L'espace de noms est un mécanisme qui couvre les ressources système globales avec une couche d'abstraction pour faire apparaître les processus dans l'espace de noms comme s'ils avaient leurs propres ressources globales distinctes. Les modifications apportées aux ressources globales sont visibles par les autres processus membres de l'espace de noms, mais pas par les autres processus. Une utilisation des espaces de noms consiste à implémenter des conteneurs.

Hmmm. C'était le cas. Je le savais. C'est vrai! Ensuite, je vais expliquer en utilisant l'espace de noms PID comme exemple! ??

En d'autres termes, s'il y a deux Yutas dans la même classe à une certaine école, il ne sera pas uniquement déterminé lequel pointer lorsqu'il est appelé **, ce qui est un problème, mais ** les deux Yutas sont du groupe A. Cela signifie qu'il n'y a pas de collision ** car il est divisé en groupes B et existe.

Exemples d'utilisation d'espaces de noms

Si vous utilisez ce mécanisme pour sécuriser un espace séparé de l'hôte non seulement pour les processus mais aussi pour diverses ressources ... Cela fonctionne sur l'hôte même s'il n'émule pas le matériel ** Virtuel Avez-vous le sentiment de pouvoir fabriquer quelque chose comme une machine **? Comme il se comporte comme s'il s'agissait d'une machine distincte, il ne devrait pas être étrange d'avoir les fonctionnalités suivantes, par exemple ... ou pas, n'est-ce pas? Celles-ci devraient être possibles en séparant les espaces de noms.

--Dispose de ses propres NIC, IP, paramètres de pare-feu et table de routage et reconnaît la machine hôte comme une autre machine sur le réseau. (Séparation de l'espace de noms réseau de l'hôte.)

Maintenant, comme vous l'avez peut-être remarqué, ** exécuter des processus dans un espace séparé de l'hôte pour diverses ressources ** est ce qu'est réellement la technologie des conteneurs. Cependant, «à part la déconnexion de l'hôte, il n'est pas pratique de coopérer avec plusieurs processus si tout est étroitement séparé entre les conteneurs», de sorte que certains espaces de noms sont partagés entre plusieurs conteneurs. Le pod est un moyen pratique de le gérer.

Dans le chapitre suivant, nous examinerons la différence entre le moment où un espace de noms est partagé et celui qui ne l'est pas, en créant un pod dans Podman et en comparant les différences de comportement des conteneurs à l'intérieur du pod.

network namespace

L'espace de noms réseau est un mécanisme permettant de séparer les informations sur le réseau telles que la carte réseau, la table de routage et les paramètres de stratégie de pare-feu.

Tout d'abord, vérifiez l'espace de noms réseau qui existe sur le système d'exploitation avec la commande suivante. Rien n'est sorti. Cela signifie que l'espace de noms réseau n'a pas encore été créé.

# ip netns

- partager le net pour les pods

Créez un pod Netshared qui partage l'espace de noms réseau avec podman. Configurez également la redirection de port pour qu'elle passe de 8080 côté hôte à 80 sur le pod. Un conteneur Apache nommé net1 est en cours d'exécution dans le pod.

# podman pod create --name netshared --share net -p 8080:80
# podman run --pod netshared --rm -d -name net1 httpd

Vous pouvez voir que le conteneur d'infrastructure et le conteneur httpd ont été créés. Le conteneur d'infrastructure est un conteneur de gestion de pod destiné à contenir l'espace de noms associé au pod. Il est toujours endormi et ne fait pratiquement rien.

# podman container ls -a
CONTAINER ID  IMAGE                           COMMAND           CREATED         STATUS                         PORTS                 NAMES
6d320abc7fa5  docker.io/library/httpd:latest  httpd-foreground  41 seconds ago  Up 40 seconds ago              0.0.0.0:8080->80/tcp  net1
76630b31f5c6  k8s.gcr.io/pause:3.1                              51 seconds ago  Up 41 seconds ago              0.0.0.0:8080->80/tcp  d1d99b6ed720-infra

Découvrons les adresses IP du conteneur d'infrastructure et du conteneur net1. L'adresse IP `` 10.88.0.83 / 16 '' est attribuée au conteneur d'infrastructure, mais pas au conteneur net1.

# podman inspect d1d99b6ed720-infra | grep -E "^.*\"IPAddress" -A1
            "IPAddress": "10.88.0.83",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
# podman inspect net1  | grep -E "^.*\"IPAddress" -A1
            "IPAddress": "",
            "IPPrefixLen": 0,

Maintenant que nous avons créé le pod, vérifions à nouveau l'espace de noms réseau. Vous pouvez voir qu'un nouvel espace de noms réseau a été créé.

# ip netns
cni-07de2651-2761-c638-a1fd-2af594ad9503 (id: 0)

Cet espace de noms réseau est utilisé par le pod netshared que nous avons créé précédemment. L'exécution de la commande ip a sur cet espace de noms réseau renverra des informations sur la carte réseau virtuelle partagée par réseau.

# ip netns exec cni-07de2651-2761-c638-a1fd-2af594ad9503 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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
3: eth0@if85: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:71:25:ce:de:49 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.88.0.83/16 brd 10.88.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::71:25ff:fece:de49/64 scope link
       valid_lft forever preferred_lft forever

eth0@if85 vaut 10.88.0.83/Vous avez 16 adresses IP. Il correspond à l'adresse IP du conteneur d'infrastructure que vous avez vérifié précédemment.



 Voyons si la redirection de port fonctionne également.

curl localhost:8080

It works!

```

La page de test Apache est de retour. La réponse est renvoyée même si le conteneur Apache n'a pas d'adresse IP car le conteneur Apache partage la carte réseau virtuelle du conteneur d'infrastructure.

--partager aucun Pour les pods

De la même manière, créez cette fois un pod qui ne partage aucun espace de noms. Il n'y a rien de spécial sauf que la redirection de port est maintenant 9090-> 80 et `` `` --share none.

# podman pod create --name none --share none -p 9090:80
# podman run --pod none --rm -d --name none1 -d httpd
# podman start 55db2b908174-infra
# podman container ls -a
CONTAINER ID  IMAGE                           COMMAND           CREATED         STATUS             PORTS                 NAMES
8b91672858a9  docker.io/library/httpd:latest  httpd-foreground  4 minutes ago   Up 4 minutes ago                         none1
f4069bf6aad1  k8s.gcr.io/pause:3.1                              4 minutes ago  Up 3 minutes ago   0.0.0.0:9090->80/tcp  55db2b908174-infra
6d320abc7fa5  docker.io/library/httpd:latest  httpd-foreground  10 minutes ago  Up 40 seconds ago              0.0.0.0:8080->80/tcp  net1
76630b31f5c6  k8s.gcr.io/pause:3.1                              10 minutes ago  Up 41 seconds ago              0.0.0.0:8080->80/tcp  d1d99b6ed720-infra

En se concentrant sur la colonne PORTS, il n'y a pas de paramètre de transfert de port dans le conteneur Apache comme c'était le cas dans le pod netshared. Le paramètre de transfert de port avec l'option -p spécifiée lors de la création du pod est en fait similaire au paramètre de transfert du conteneur d'infrastructure. De plus, les cartes réseau virtuelles du conteneur d'infrastructure et du conteneur Apache ne sont pas partagées, il ne semble donc pas être transféré vers le conteneur Apache. Qu'arrive-t-il à la carte réseau virtuelle du conteneur Apache lorsqu'elle n'est pas partagée?

Découvrez l'adresse IP du conteneur qui appartient au pod none.

# podman inspect 55db2b908174-infra | grep -E "^.*\"IPAddress" -A1
            "IPAddress": "10.88.0.85",
            "IPPrefixLen": 16,
# podman inspect none1 | grep -E "^.*\"IPAddress" -A1
            "IPAddress": "10.88.0.84",
            "IPPrefixLen": 16,

Dans le pod Netshared, seul le conteneur d'infrastructure avait une adresse IP, mais maintenant les deux conteneurs ont une adresse IP. Le conteneur Apache semble avoir sa propre carte réseau virtuelle. Peut-être que si l'espace de noms réseau n'est pas partagé dans le pod, l'espace de noms réseau unique continuera-t-il à croître à chaque fois qu'un conteneur est créé?

ip netnsVérifions avec.

# ip netns 
cni-209074d8-5a08-7f59-bb73-6b258c228cf4 (id: 2)
cni-dc45758c-a9e2-91a2-db2c-a0f3406b9568 (id: 1)
cni-07de2651-2761-c638-a1fd-2af594ad9503 (id: 0)

Deux espaces de noms réseau ont été créés en plus de l'espace de noms réseau pour le pod netshared précédemment.

Vous pouvez voir la carte réseau virtuelle avec les 84 dernières adresses dans l'espace de noms réseau avec l'ID: 1. Cela provient du conteneur d'infrastructure aucun pod.

id1


# ip netns exec cni-dc45758c-a9e2-91a2-db2c-a0f3406b9568 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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
3: eth0@if86: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 7a:11:aa:8e:52:ef brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.88.0.84/16 brd 10.88.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::7811:aaff:fe8e:52ef/64 scope link
       valid_lft forever preferred_lft forever

Vous pouvez voir la carte réseau virtuelle avec les 85 dernières adresses dans l'espace de noms réseau avec l'ID: 2. Cela provient du conteneur none1 exécutant Apache.

id2


# ip netns exec cni-209074d8-5a08-7f59-bb73-6b258c228cf4 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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
3: eth0@if87: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether b2:93:94:3c:05:7e brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.88.0.85/16 brd 10.88.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::b093:94ff:fe3c:57e/64 scope link
       valid_lft forever preferred_lft forever

Vérifiez également le fonctionnement de la redirection de port. Contrairement au pod netshared, curl vers localhost: 9090 ne répond pas d'Apache. En effet, ce sera une boucle vers le conteneur d'infrastructure en sommeil. À cet égard, le curl vers localhost: 8080 qui a été effectué dans le pod netshared peut être considéré comme le curl vers le même conteneur d'infrastructure, mais le pod netshared est vers le conteneur Apache car le conteneur d'infrastructure et le conteneur Apache ont partagé la carte réseau virtuelle. La demande est arrivée. C'est comme si plusieurs conteneurs étaient connectés et fonctionnaient comme une seule machine virtuelle.

Notez que si vous curl directement à none1 (10.88.0.84) où Apache est en cours d'exécution, vous obtiendrez une réponse, donc Apache lui-même semble fonctionner.

# curl localhost:9090
curl: (7) Failed to connect to localhost port 9090:Connexion rejetée
# curl 10.88.0.84
<html><body><h1>It works!</h1></body></html>
# curl 10.88.0.85
curl: (7) Failed to connect to 10.88.0.85 port 80:Connexion rejetée

Je vais le vérifier au cas où, mais il ne semble pas avoir été joué par firewalld.

# firewall-cmd --list-all --zone=public | grep -E "^\s*ports"
  ports: 8080/tcp 9090/tcp

Nous avons pu confirmer le comportement lorsque l'espace de noms réseau n'est pas partagé entre les conteneurs.

uts namespace

Un espace de noms qui sépare les noms d'hôte et les noms de domaine NIS.

UTS signifie Unix Time-sharing System (un mécanisme utilisé sous UNIX pour gérer un seul ordinateur avec plusieurs utilisateurs), mais il semble que sa signification a été perdue maintenant. Le temps n'a pas d'importance.

NIS est un mécanisme utilisé pour gérer de manière centralisée plusieurs ordinateurs, et le domaine NIS est un identifiant pour ce mécanisme. Cette fois, nous nous concentrerons sur la séparation des noms d'hôtes.

- partager des uts pour les pods

Créez un pod utsshared qui partage l'espace de noms uts et créez un conteneur Apache uts1 et un conteneur CentOS7 uts2 à l'intérieur.

# podman pod create --name utsshared --share uts
# podman run -d --pod utsshared --name uts1 --rm httpd
# podman run -it -d --pod utsshared --name uts2 --rm centos:7

Affiche les noms d'hôte pour uts1 et uts2. Il a renvoyé utsshared, qui est identique au nom du pod. Il semble certainement que l'espace de noms uts soit partagé.

# podman exec uts1 hostname
utsshared
# podman exec uts2 hostname
utsshared

--partager aucun Pour les pods

Créons un environnement similaire avec le pod none créé précédemment et affichons le nom d'hôte.

# podman exec none1 hostname
8b91672858a9
# podman exec none2 hostname
692b66d45c4a

Les noms d'hôte pour none1 et none2 avaient le même contenu que leur propre ID de conteneur. On peut dire que l'espace de noms uts n'est pas partagé.

ipc namespace

Espace de noms Inter-Process Communication. Si l'espace de noms ipc est partagé, la communication entre les processus est possible. Les conteneurs qui n'appartiennent pas au même pod et les conteneurs aux hôtes sont généralement séparés, mais les conteneurs qui appartiennent au même pod partagent un espace de noms ipc, de sorte qu'une communication interprocessus est possible.

J'ai emprunté cette image pour démontrer la communication IPC dans le même pod. https://github.com/allingeek/ch6_ipc/tree/e9fa9a13198903bebcd983bf88bcb75950823d85

allingeek/ch6_ipc


FROM ubuntu:latest
RUN apt-get update && apt-get -y install gcc libc-dev
COPY . /work/ipc
WORKDIR /work/ipc
RUN gcc -o ipc ipc.c -lrt
ENTRYPOINT ["./ipc"]

Il s'agit d'une image Ubuntu avec un fichier exécutable appelé ipc à l'intérieur. ipcAu moment de l'exécution-producerEnvoie un message de nombre aléatoire et un message de fin. ipcAu moment de l'exécution-consumerAvec-producerReçoit le message émis par et l'affiche dans la sortie standard.

- partager le pod ipc

Comme d'habitude, créez un pod ipcshared qui partage l'espace de noms ipc, avec ipc1 étant -producer et ipc2 étant `` `` -consumer dedans.

# podman pod create --name ipcshared --share ipc
# podman run -d --pod ipcshared --name ipc1 --entrypoint /work/ipc/ipc ch6_ipc -producer
# podman run -d --pod ipcshared --name ipc2 --entrypoint /work/ipc/ipc ch6_ipc -consumer

Vérifiez le fichier journal pour voir si vous pouvez envoyer et recevoir.

# podman logs --tail 5 ipc1 | tac
Produced: 86 
Produced: 86
Produced: 67
Produced: 2b 
Produced: b9 

# podman logs --tail 6 ipc2 | tac
Consumed: 86
Consumed: 86
Consumed: 67
Consumed: 2b
Consumed: b9
Consumed: done

Les chiffres produits par producteur et consommateur correspondent. J'ai pu confirmer que la transmission et la réception se sont déroulées correctement.

--partager aucun Pour les pods

Faites de même pour aucun pod qui ne partage pas l'espace de noms ipc. Ici, le consommateur ne parvient pas à recevoir le message.

# podman pod create --name none --share none
# podman run -d --pod ipcshared --name ipc1 --entrypoint /work/ipc/ipc ch6_ipc -producer
# podman run -d --pod ipcshared --name ipc2 --entrypoint /work/ipc/ipc ch6_ipc -consumer
# podman logs --tail 5 ipc_unshare1
Produced: 9c
Produced: 98
Produced: 53
Produced: b9
Produced: 45
# podman logs --tail 6 ipc_unshare2
Either the producer has not been started or maybe I cannot access the same memory...

La séparation de l'espace de noms ipc a empêché les processus du pod de communiquer.

user namespace Un espace de noms qui sépare les UID et les GID. Il semble que je regarde la documentation, mais il semble qu'elle n'est pas encore implémentée.

# podman pod create --name usershared --share user
Error: unable to create pod: User sharing functionality not supported on pod level
# podman pod create --share help
Error: unable to create pod: Invalid kernel namespace to share: help. Options are: net, pid, ipc, uts or none

pid namespace

Il s'agit de l'espace de noms lié aux numéros de processus mentionnés au début.

--share pid Pour les pods

Créez un pod partagé avec un espace de noms pid partagé. Laissez le conteneur Apache être pid1, le conteneur MySQL être pid2 et le conteneur CentOS7 être pid3 et aller à l'intérieur de pid3.

# podman pod create --share pid --name pidshared
# podman run -d --pod pidshared --name pid1 --rm httpd
# podman run -d --pod pidshared --name pid2 --rm -e MYSQL_ROOT_PASSWORD=password mysql
# podman run -it --pod pidshared --name pid3 --rm centos:7 /bin/bash
[container_id /]#

Vérifiez le processus.

[container_id /]# ps -ef
root         1     0  0 01:33 ?        00:00:00 /pause
root       114     0  0 01:44 ?        00:00:00 httpd -DFOREGROUND
bin        120   114  0 01:44 ?        00:00:00 httpd -DFOREGROUND
bin        121   114  0 01:44 ?        00:00:00 httpd -DFOREGROUND
bin        122   114  0 01:44 ?        00:00:00 httpd -DFOREGROUND
999        284     0  1 01:48 ?        00:00:02 mysqld
root       484     0  4 01:51 pts/0    00:00:00 /bin/bash
root       499   484  0 01:51 pts/0    00:00:00 ps -ef

Vous pouvez voir les processus httpd et mysqld s'exécuter dans d'autres conteneurs.

--partager aucun Pour les pods

Faites de même pour le module none.

# podman pod create --name none
# podman run -d --pod none --name none1 --rm httpd
# podman run -d --pod none --name none2 --rm -e MYSQL_ROOT_PASSWORD=password mysql
# podman run -it --pod none --name none3 --rm centos:7 /bin/bash
[container_id /]#
[container_id /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0 12 02:02 pts/0    00:00:00 /bin/bash
root        14     1  0 02:02 pts/0    00:00:00 ps -ef

Je ne peux voir que les processus en cours d'exécution à l'intérieur du conteneur pid3. C'est parce que l'espace de noms pid n'est pas partagé.

à la fin

Podman a créé des pods avec trois espaces de noms partagés par défaut: net, uts et ipc. Par conséquent, le pod par défaut présente les caractéristiques suivantes.

En d'autres termes, les conteneurs du pod ressemblent à ** la même machine ** sur le réseau, contrairement aux conteneurs disjoints qui n'appartiennent pas au pod, et ** peuvent communiquer via la communication interprocessus (IPC) **. Cela signifie qu'il y en a. Vous avez surmonté l'inconvénient causé par le principe selon lequel un processus doit s'exécuter dans un conteneur en partageant certains espaces de noms entre les conteneurs. En ce qui concerne le principe du processus 1 conteneur 1, il existe diverses raisons telles que le problème PID 1 et la commodité lors du fonctionnement en partant du principe que le conteneur est jetable, mais la marge est trop étroite pour l'écrire, donc ici.

référence

Je l'ai utilisé comme référence lors de la démonstration de la communication IPC.

Communication inter-processus des conteneurs dans le même pod par Kubernetes https://qiita.com/mamorita/items/15437a1dbcc00919fa4e

Recommended Posts

Comprenez ce que signifie partager un espace de noms Linux via $ podman pod create --share namespace.
Essayez de créer une nouvelle commande sous Linux
Lorsque vous connectez SSD à Linux et créez un serveur de fichiers, il est préférable d'utiliser NTFS.
Comment créer un référentiel local pour le système d'exploitation Linux