GNU/Linux >> Tutoriels Linux >  >> Panels >> Docker

Comment utiliser la commande Docker Inspect

L'une des commandes essentielles de Docker est docker inspect. Il vous permet d'extraire des informations sur divers objets docker, savoir comment l'utiliser est quelque chose TOUT LE MONDE devrait savoir.

Au cas où vous vous poseriez la question, les objets ou ressources Docker sont simplement des éléments tels que des conteneurs, des volumes, des réseaux, etc.

La principale force de inspect vient de ses capacités de formatage.

Par exemple, vous pouvez extraire l'adresse IP d'un conteneur en cours d'exécution en l'inspectant et en le formatant d'une manière spécifique.

➟ docker container inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx
172.17.0.2

Docker utilise des modèles go pour formater sa sortie.

Dans cet article, je vais d'abord passer en revue les bases de la commande Docker inspect, puis je me concentrerai sur la façon de formater la sortie selon vos besoins spécifiques.

Que fait Docker inspect ?

Inspect vous fournit un tas de métadonnées sur tous les différents objets gérés par docker. Le type d'information varie d'un objet à l'autre.

Par exemple, si vous inspectez un volume, vous obtiendrez des informations sur sa date de création, le pilote de volume utilisé, l'emplacement dans le système de fichiers hôte, les étiquettes, etc.

S'il s'agit d'un réseau que vous inspectez, vous obtiendrez des éléments tels que son sous-réseau, sa passerelle, ses conteneurs connectés et leurs adresses IP, étiquettes et autres informations.

Pour mieux comprendre ce que fournit inspect pour un objet donné, je vous recommande d'exécuter les commandes et de voir par vous-même.

Quels sont les objets qui peuvent être inspectés ?

Dans docker, un objet ou un type d'objet correspond à toutes les constructions contrôlées par docker. Cela inclut les éléments suivants :-

  1. Conteneurs.
  2. Images.
  3. Réseaux.
  4. Volumes.
  5. Contextes.
  6. Plug-ins.
  7. Nœuds (objet essaim).
  8. Services (objet essaim).
  9. Secrets (objet en essaim).
  10. Configurations (objet essaim).

Utilisation de la commande Docker inspect

Il y a deux façons d'utiliser le inspect sous-commande.

  1. docker inspect [object] [options]
  2. docker [object_type] inspect [object] [options]

La deuxième méthode est celle que vous devriez utiliser toujours . Le inspect la sous-commande fournit une sortie JSON, j'y reviendrai dans un instant.

Créez un volume nommé unique .

docker volume create unique

Créez maintenant un réseau portant le même nom, unique .

docker network create unique

Essayons maintenant d'inspecter l'objet nommé unique en utilisant la première syntaxe.

docker inspect unique

Ma sortie :-

➟ docker inspect unique
[
    {
        "Name": "unique",
        "Id": "09a7e2163ee058b1057d95599f764d571ec6a42a5792803dc125e706caa525b0",
        "Created": "2021-05-07T15:47:20.341493099+05:30",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

Dans mon système, comme vous pouvez le voir inspect inspecté le réseau, mais que se passerait-il si j'avais l'intention d'inspecter le volume ?

C'est le problème avec docker inspect , lorsque vous avez deux objets différents portant le même nom, vous ne pouvez pas simplement utiliser docker inspect [object_name] . Pour inspecter exactement ce que vous voulez, vous devrez soit utiliser l'ID de l'objet, soit utiliser le --type=[object_type] option. Vous pouvez écrire la commande précédente avec le --type option comme ceci :-

docker inspect --type=volume unique

Bien que cela fonctionne, je pense que ce n'est pas nécessaire puisque nous avons déjà l'autre syntaxe. Vous pouvez simplement utiliser la sous-commande spécifique à l'objet comme je le fais ici :-

docker volume inspect unique

C'est moins à écrire et beaucoup plus facile à lire.

Quelques exemples utiles de commandes d'inspection Docker

Dans cette section, je vais enregistrer une liste de requêtes courantes et à quoi ressemblerait la commande inspect appropriée pour obtenir ces informations.

Requêtes de conteneur

Pour les exemples, j'aurai un exemple de conteneur nginx en cours d'exécution, et toutes les commandes seront exécutées sur ce conteneur en cours d'exécution. La commande que j'ai utilisée pour exécuter ce conteneur :-

docker container run \
	--rm --name nginx \
    -p target=80,published=127.0.0.1:8081,protocol=tcp \
    -p target=80,published=[::1]:8081,protocol=tcp \
    -e ENV_VAR=somevalue \
    -e ENV_VAR2=linux \
    -v $PWD:/mnt:ro \
    -v /tmp:/tmp:ro \
    -d nginx

1. ID d'un conteneur par nom

Vous pouvez obtenir l'ID du conteneur à l'aide de la commande suivante :-

docker container inspect -f '{{.Id}}' [container_name]

Exemple :-

➟ docker container inspect -f '{{.Id}}' nginx
0409779fc2d976387170d664a6aed5ee80a460f8a8dd02c44a02af97df0bb956

2. Processus principal du conteneur

Le processus de conteneur principal est essentiellement ENTRYPOINT + CMD .

docker container inspect -f '{{printf "%s " .Path}}{{range .Args}}{{printf "%s " .}}{{end}}' [container_name|id]

Exemple :-

➟ docker container inspect -f '{{printf "%s " .Path}}{{range .Args}}{{printf "%s " .}}{{end}}' nginx
/docker-entrypoint.sh nginx -g daemon off;

3. Liste des liaisons de port

La commande suivante répertorie toutes les liaisons de port conteneur-hôte.

docker container inspect -f '{{range $target, $published := .NetworkSettings.Ports}}{{range $published}}{{printf "%s -> %s:%s\n" $target .HostIp .HostPort}}{{end}}{{end}}' [container_name|id]

Exemple :-

➟ docker container inspect -f '{{range $target, $published := .NetworkSettings.Ports}}{{range $published}}{{printf "%s -> %s:%s\n" $target .HostIp .HostPort}}{{end}}{{end}}' nginx
80/tcp -> ::1:8081
80/tcp -> 127.0.0.1:8081
Vous pouvez obtenir la même chose avec docker container port commande.

4. Lister ses adresses IP

Un conteneur peut être connecté à plusieurs réseaux, au lieu d'imprimer l'une de ces nombreuses adresses IP, vous pouvez imprimer toutes ces adresses IP avec cette commande.

docker container inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container_name|id]

Exemple :-

➟ docker container inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx
172.17.0.2

5. Lister les variables d'environnement

Vous pouvez également lister la variable d'environnement d'un conteneur.

docker container inspect -f '{{range .Config.Env}}{{printf "%s\n" .}}{{end}}' [container_name|id]

Exemple :-

➟ docker container inspect -f '{{range .Config.Env}}{{printf "%s\n" .}}{{end}}' nginx
ENV_VAR=somevalue
ENV_VAR2=linux
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NGINX_VERSION=1.19.10
NJS_VERSION=0.5.3
PKG_RELEASE=1~buster

6. Liste des volumes/montages liés avec le mode

La commande suivante imprime les montages liés dans ce format, "[source] -> [destination], mode :[mode]".

docker container inspect -f '{{range .Mounts}}{{printf "%s -> %s, mode: %s\n" .Source .Destination .Mode}}{{end}}' [container_name|id]

Exemple :-

➟ docker container inspect -f '{{range .Mounts}}{{printf "%s -> %s, mode: %s\n" .Source .Destination .Mode}}{{end}}' nginx
/home/debdut -> /mnt, mode: ro
/tmp -> /tmp, mode: ro

Requêtes de volume

Il n'y a pas grand-chose à inspecter un volume, sauf pour connaître l'emplacement de l'hôte, qui se trouve dans data-dir/volumes . Vous pouvez obtenir ces informations avec la commande suivante :-

docker volume inspect -f '{{.Mountpoint}}' [volume_name|id]

Exemple :-

➟ docker volume create unique 
unique
~ 
➟ docker volume inspect -f '{{.Mountpoint}}' unique 
/var/lib/docker/volumes/unique/_data

Requêtes réseau

Il y a deux requêtes que je me pose fréquemment, l'une est de connaître un sous-réseau de réseaux et tous les conteneurs qui sont connectés à ce réseau et les adresses IP qui leur sont associées.

Pour cela j'ai créé un réseau simple avec le docker network create unique commande.

1. Obtenir le sous-réseau

Pour obtenir le sous-réseau, utilisez la commande suivante :-

docker network inspect -f '{{range .IPAM.Config}}{{.Subnet}}{{end}}' [network_name|id]

Exemple :-

➟ docker network inspect -f '{{range .IPAM.Config}}{{.Subnet}}{{end}}' unique 
172.21.0.0/16

2. Liste des conteneurs connectés avec leurs adresses IP

La commande ressemble à ceci,

docker network inspect -f '{{range .Containers}}{{printf "%s -> %s\n" .Name .IPv4Address}}{{end}}' [network_name|id]

Exemple :-

➟ docker network inspect -f '{{range .Containers}}{{printf "%s -> %s\n" .Name .IPv4Address}}{{end}}' unique 
cranky_wescoff -> 172.21.0.5/16
nginx -> 172.21.0.2/16
upbeat_carson -> 172.21.0.3/16
objective_jones -> 172.21.0.4/16

Formater la sortie de la commande Docker inspect

inspect nous fournit un tableau JSON pour la sortie, que vous pouvez filtrer en utilisant quelque chose comme jq . Donc, si vous avez de l'expérience en jq , vous voudrez peut-être simplement l'utiliser. Le problème avec jq est qu'il n'est pas préinstallé dans la plupart des distributions Linux, tandis que le mécanisme de formatage par défaut de docker .. inspect est déjà là, et il est très puissant.

Docker utilise des modèles go pour formater sa sortie. Cet article ne portera pas sur les go-templates, mais si vous voulez en savoir plus, vous pouvez en savoir plus ici.

En interne, les JSON sont représentés à l'aide de diverses structures de données Go. C'est pourquoi les modèles go fonctionnent réellement avec les types de données go. Comme je ne veux pas expliquer ce que sont ces structures de données, au lieu d'utiliser ces termes, j'utiliserai des termes JSON pour le rendre plus compréhensible.

Extraire des champs simples

Considérez un objet JSON comme celui-ci :-

{
	"mary": 43,
    "john": 44
}

Supposons que vous souhaitiez extraire les informations associées à la clé mary . Pour ce faire, vous utilisez la notation point [.], où vous préfixez la clé avec un point et ajoutez des clés de manière récursive pour toutes les clés imbriquées. C'est la même chose que jq . Donc .mary ici serait 43.

Considérez le JSON suivant maintenant.

{
	"mary": {
    	"jane": 43,
        "soyas": 56
    },
    "john": 65
}

Dans ce cas .mary.jane serait 43, et de même .mary.soyas serait 56.

Une syntaxe similaire peut être utilisée avec les go-templates. Pour formater la sortie, vous devez passer le modèle à -f ou --format option de inspect sous-commande. Révisons le résultat de l'inspection du volume.

[
    {
        "CreatedAt": "2021-05-07T15:53:10+05:30",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/unique/_data",
        "Name": "unique",
        "Options": {},
        "Scope": "local"
    }
]

Si vous voulez connaître le Mountpoint , vous utiliseriez la commande suivante :-

docker volume inspect -f '{{.Mountpoint}}' unique
➟ docker volume inspect -f '{{.Mountpoint}}' unique
/var/lib/docker/volumes/unique/_data

Vous remarquez probablement les accolades ici, ce sont comme des blocs, les expressions sont encapsulées à l'intérieur de ces blocs.

Essayons quelque chose d'imbriqué maintenant. Inspectez le réseau et recherchez le IPAM rubrique.

➟ docker network inspect unique
<snipped>
 "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
<snipped>

En regardant cela, vous pouvez assez facilement comprendre quel est le pilote de ce réseau. Mais au lieu de le rechercher comme ceci, vous pouvez le formater à partir de l'ensemble de la sortie JSON.

Remarquez le Driver la clé est imbriquée dans IPAM . Ainsi, l'expression pointée pour extraire le pilote serait .IPAM.Driver . Voyez-le en action :-

➟ docker network inspect -f '{{.IPAM.Driver}}' unique
default

Boucle sur des objets ou des listes (range)

Les objets JSON sont comme des tableaux associatifs dans Bash ou Hashes, où les clés sont des chaînes et les valeurs peuvent être de n'importe quel type de données.

Pour vous faire comprendre cela un peu plus facilement, je vais commencer par un exemple pratique. Considérez le .NetworkSettings.Networks section dans un résultat d'inspection d'un conteneur. Il répertorie les réseaux auxquels le conteneur est connecté, et pour chaque réseau, quelques détails supplémentaires associés comme l'adresse IP.

Pensez si quelqu'un vous demande de lui dire l'adresse IP d'un conteneur. Choisir un seul réseau et l'IP associée n'a pas beaucoup de sens, le mieux serait de lister toutes les adresses IP qui sont associées à tous les réseaux.

Vous pouvez y parvenir avec un simple bash for loop if vous connaissez déjà les noms de réseau. Comme dans mon cas, je peux faire quelque chose comme ce qui suit :-

for network in bridge unique; do
	docker container inspect -f \
    	"{{.NetworkSettings.Networks.$network.IPAddress}}" nginx
done

Mais évidemment, cela est limité à grande échelle car nous ne pouvons pas toujours nous souvenir de tous les noms de réseau.

Vous pouvez atténuer ce problème en utilisant l'action de modèle range . range parcourt une carte (un tableau associatif ou un objet JSON) et nous fournit non pas la clé, mais les valeurs pour chaque itération (ce comportement est modifiable).

Donc dans ce cas, vous pouvez écrire un bloc comme {{range .NetworkSettings.Networks}} pour boucler sur les valeurs de chaque réseau ou les données associées à chaque réseau, et à partir de là, vous pouvez extraire l'adresse IP comme vous le feriez à partir d'une structure normale de type JSON, c'est-à-dire {{.IPAddress}}} . Une chose à retenir est de toujours terminer tout le modèle qui commence par range , avec {{end}} .

En mettant tout cela ensemble, vous pouvez réécrire la boucle for précédente de cette façon :-

docker container inspect -f \
	'{{range .NetworkSettings.Networks}}
     {{.IPAddress}}{{end}}' nginx

Exemple de sortie :-

➟ docker container inspect -f \
> '{{range .NetworkSettings.Networks}}
>      {{.IPAddress}}{{end}}' nginx

     172.17.0.2
     172.21.0.2

Utilisation de l'index fonction sur les tableaux et les objets

Vous pouvez utiliser l'index pour extraire des parties de votre objet ou tableau JSON. Si la structure est un objet JSON, vous utiliserez {{index .Field "key"}} , si la structure est un tableau JSON, vous utiliserez {{index .Field index}} .

Dans l'exemple précédent, vous avez imprimé toutes les adresses IP d'un conteneur. Supposons que vous connaissiez l'un des réseaux auxquels il est connecté (pont) et que vous souhaitiez imprimer l'adresse IP associée à ce réseau. Vous pouvez le faire avec index fonctionner comme ceci :-

docker container inspect -f '{{(index .NetworkSettings.Networks "bridge").IPAddress}}' nginx

Sortie :-

➟ docker container inspect -f '{{(index .NetworkSettings.Networks "bridge").IPAddress}}' nginx
172.17.0.2

Utilisation de json fonction

Les données exportées après le formatage ne sont pas dans JSON, c'est dans une structure de données go. Mais vous pouvez le convertir en JSON en utilisant le json fonction.

Le niveau supérieur de l'objet JSON est . . Donc, pour imprimer cela, vous feriez quelque chose comme ceci :-

docker network inspect -f '{{.}}' unique
➟ docker network inspect -f '{{.}}' unique 
{unique 09a7e2163ee058b1057d95599f764d571ec6a42a5792803dc125e706caa525b0 2021-05-07 15:47:20.341493099 +0530 IST local bridge false {default map[] [{172.21.0.0/16  172.21.0.1 map[]}]} false false false {} false map[2646cbbde5efc218bb6f3a5c882f8eb9e3e4331d090ad46ccc0a2eec9c2eea1b:{nginx c0291394a48f7e8e8aa98fd31631eb00e68daacbee9cf24bac530f16359d051d 02:42:ac:15:00:02 172.21.0.2/16 }] map[] map[] [] map[]}

Ce que vous voyez ici est une grande structure composée d'autres types de données de base et de cartes. Celles-ci ne sont pas très lisibles, ni utilisables en dehors du go. Mais vous pouvez les convertir en JSON en utilisant le json une fonction. Ajoutez simplement un champ avec json comme je le fais ici :-

➟ docker network inspect -f '{{json .}}' unique
➟ docker network inspect -f '{{json .}}' unique 
{"Name":"unique","Id":"09a7e2163ee058b1057d95599f764d571ec6a42a5792803dc125e706caa525b0","Created":"2021-05-07T15:47:20.341493099+05:30","Scope":"local","Driver":"bridge","EnableIPv6":false,"IPAM":{"Driver":"default","Options":{},"Config":[{"Subnet":"172.21.0.0/16","Gateway":"172.21.0.1"}]},"Internal":false,"Attachable":false,"Ingress":false,"ConfigFrom":{"Network":""},"ConfigOnly":false,"Containers":{"2646cbbde5efc218bb6f3a5c882f8eb9e3e4331d090ad46ccc0a2eec9c2eea1b":{"Name":"nginx","EndpointID":"c0291394a48f7e8e8aa98fd31631eb00e68daacbee9cf24bac530f16359d051d","MacAddress":"02:42:ac:15:00:02","IPv4Address":"172.21.0.2/16","IPv6Address":""}},"Options":{},"Labels":{}}

Pour le rendre un peu meilleur, dirigez-le vers jq .

➟ docker network inspect -f '{{json .}}' unique | jq
{
  "Name": "unique",
  "Id": "09a7e2163ee058b1057d95599f764d571ec6a42a5792803dc125e706caa525b0",
  "Created": "2021-05-07T15:47:20.341493099+05:30",
  "Scope": "local",
  "Driver": "bridge",
  "EnableIPv6": false,
  "IPAM": {
    "Driver": "default",
    "Options": {},
    "Config": [
      {
        "Subnet": "172.21.0.0/16",
        "Gateway": "172.21.0.1"
      }
    ]
  },
  "Internal": false,
  "Attachable": false,
  "Ingress": false,
  "ConfigFrom": {
    "Network": ""
  },
  "ConfigOnly": false,
  "Containers": {
    "2646cbbde5efc218bb6f3a5c882f8eb9e3e4331d090ad46ccc0a2eec9c2eea1b": {
      "Name": "nginx",
      "EndpointID": "c0291394a48f7e8e8aa98fd31631eb00e68daacbee9cf24bac530f16359d051d",
      "MacAddress": "02:42:ac:15:00:02",
      "IPv4Address": "172.21.0.2/16",
      "IPv6Address": ""
    }
  },
  "Options": {},
  "Labels": {}
}

Est-ce que c'est ça? Absolument pas. Je vous recommande fortement de lire comment utiliser les modèles go.

Ici, j'ai essayé de commencer à l'utiliser sans avoir à en savoir beaucoup sur les modèles go. J'espère avoir réussi.

Pour toute clarification, n'hésitez pas à utiliser la section des commentaires.


Docker
  1. Comment utiliser la commande vmstat

  2. Comment utiliser la commande Su sous Linux

  3. Comment utiliser Docker Compose

  4. Comment configurer docker pour utiliser le proxy

  5. Comment utiliser l'option --since avec la commande docker logs

Comment utiliser la commande pkill

Comment utiliser la commande LDD sous Linux

Comment installer et utiliser Docker sur Rocky Linux 8

Comment utiliser la commande PS

Comment utiliser la commande TOP

Comment installer et utiliser Podman (alternative à Docker)