GNU/Linux >> Linux Esercitazione >  >> Panels >> Docker

Come utilizzare il comando Ispeziona Docker

Uno dei comandi essenziali di Docker è l'ispezione della finestra mobile. Ti consente di estrarre informazioni su vari oggetti docker, sapere come usarlo è qualcosa di TUTTI dovrebbe sapere.

Nel caso te lo stavi chiedendo, gli oggetti o le risorse Docker sono semplicemente cose come contenitori, volumi, reti ecc.

Il principale punto di forza di inspect deriva dalle sue capacità di formattazione.

Ad esempio, puoi estrarre l'indirizzo IP di un container in esecuzione ispezionandolo e formattando in modo specifico.

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

Docker utilizza i modelli go per formattare l'output.

In questo articolo, prima esaminerò le basi del comando Docker inspect, quindi mi concentrerò su come formattare l'output in base alle tue esigenze specifiche.

Cosa fa Docker inspect?

Inspect ti fornisce una serie di metadati su tutti i diversi oggetti gestiti dalla finestra mobile. Il tipo di informazioni varia da oggetto a oggetto.

Ad esempio, se ispezioni un volume, otterrai informazioni relative a quando è stato creato, al driver del volume in uso, alla posizione nel filesystem host, alle etichette, ecc.

Se stai ispezionando una rete, otterrai elementi come la subnet, il gateway, i container connessi e i relativi indirizzi IP, etichette e altre informazioni.

Per capire meglio cosa prevede inspect per un determinato oggetto, ti consiglio di eseguire i comandi e vedere di persona.

Quali sono gli oggetti che possono essere ispezionati?

Nella finestra mobile, un oggetto o un tipo di oggetto sono tutti i costrutti controllati dalla finestra mobile. Ciò include quanto segue:-

  1. Contenitori.
  2. Immagini.
  3. Reti.
  4. Volumi.
  5. Contesti.
  6. Plugin.
  7. Nodi (oggetto sciame).
  8. Servizi (oggetto sciame).
  9. Segreti (oggetto sciame).
  10. Configurazioni (oggetto sciame).

Utilizzo del comando di ispezione Docker

Ci sono due modi in cui puoi usare inspect sottocomando.

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

Il secondo metodo è quello che dovresti usare sempre . Il inspect il sottocomando fornisce un output JSON, ne parlerò tra un momento.

Crea un volume denominato unique .

docker volume create unique

Ora crea una rete con lo stesso nome, unique .

docker network create unique

Ora proviamo a ispezionare l'oggetto denominato unique utilizzando la prima sintassi.

docker inspect unique

Il mio risultato:-

➟ 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": {}
    }
]

Nel mio sistema, come puoi vedere inspect ho ispezionato la rete, ma se avessi intenzione di ispezionare il volume?

Questo è il problema con docker inspect , quando hai due oggetti diversi con lo stesso nome, non puoi semplicemente usare docker inspect [object_name] . Per ispezionare esattamente ciò che desideri, dovrai utilizzare l'ID dell'oggetto o utilizzare il --type=[object_type] opzione. Puoi scrivere il comando precedente con --type opzione in questo modo:-

docker inspect --type=volume unique

Sebbene funzioni, credo che ciò non sia necessario poiché abbiamo già l'altra sintassi. Puoi semplicemente usare il sottocomando specifico dell'oggetto come sto facendo qui:-

docker volume inspect unique

È meno da scrivere e molto più facile da leggere.

Alcuni utili esempi di comandi di ispezione Docker

In questa sezione, registrerò un elenco di query comuni e l'aspetto del comando di ispezione pertinente per ottenere tali informazioni.

Query sui contenitori

Per gli esempi, avrò un contenitore nginx di esempio in esecuzione e tutti i comandi verranno eseguiti su questo contenitore in esecuzione. Il comando che ho usato per eseguire questo contenitore:-

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 di un contenitore per nome

Puoi ottenere l'ID del contenitore usando il seguente comando:-

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

Esempio:-

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

2. Il processo principale del contenitore

Il processo principale del contenitore è fondamentalmente ENTRYPOINT + CMD .

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

Esempio:-

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

3. Elenco dei collegamenti delle porte

Il comando seguente elenca tutte le associazioni di porta da contenitore a host.

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

Esempio:-

➟ 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
Puoi ottenere lo stesso risultato con docker container port comando.

4. Elenco dei suoi indirizzi IP

Un container può essere connesso a più reti, invece di stampare uno di quei tanti indirizzi IP, puoi stampare tutti quegli indirizzi IP con questo comando.

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

Esempio:-

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

5. Elenco delle variabili d'ambiente

Puoi anche elencare la variabile di ambiente di un container.

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

Esempio:-

➟ 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. Elencare i volumi/i montaggi di binding insieme alla modalità

Il comando seguente stampa i mount di collegamento in questo formato, "[sorgente] -> [destinazione], modalità:[modalità]".

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

Esempio:-

➟ 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

Query sul volume

Non c'è molto da ispezionare un volume se non per conoscere la posizione dell'host, che è in data-dir/volumes . Puoi ottenere queste informazioni con il seguente comando:-

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

Esempio:-

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

Query di rete

Ci sono due domande che personalmente mi ritrovo a fare frequentemente, una è conoscere una sottorete di rete e tutti i container che sono connessi a quella rete e gli IP ad essi associati.

Per questo ho creato una semplice rete con la docker network create unique comando.

1. Ottenere la sottorete

Per ottenere la sottorete, utilizzare il seguente comando:-

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

Esempio:-

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

2. Elenco dei container collegati insieme ai loro indirizzi IP

Il comando è simile a questo,

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

Esempio:-

➟ 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

Formattazione dell'output del comando Docker inspect

inspect ci fornisce un array JSON per l'output, che puoi filtrare usando qualcosa come jq . Quindi, se hai esperienza con jq , potresti semplicemente usarlo. Il problema con jq è che non viene preinstallato nella maggior parte delle distribuzioni Linux, mentre il meccanismo di formattazione predefinito di docker .. inspect è già lì ed è molto potente.

Docker usa i modelli go per formattare il suo output. Questo articolo non riguarderà i go-template, ma se vuoi saperne di più, puoi leggerlo qui.

Internamente i JSON sono rappresentati utilizzando varie strutture di dati Go. Ecco perché i modelli go funzionano effettivamente con i tipi di dati go. Dal momento che non voglio spiegare quali sono queste strutture di dati, invece di usare quei termini, userò termini JSON per renderlo più comprensibile.

Estrazione di campi semplici

Considera un oggetto JSON come il seguente:-

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

Supponiamo di voler estrarre le informazioni associate alla chiave mary . Per fare ciò, ciò che usi è la notazione punto [.], in cui anteponi alla chiave un punto e aggiungi le chiavi in ​​modo ricorsivo per qualsiasi chiave nidificata. È lo stesso di jq . Quindi .mary qui sarebbero 43.

Considera ora il seguente JSON.

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

In questo caso .mary.jane sarebbe 43, e allo stesso modo .mary.soyas sarebbero 56.

Una sintassi simile può essere utilizzata con i modelli go. Per formattare l'output, devi passare il modello a -f o --format opzione del inspect sottocomando. Rivediamo l'output dell'ispezione del volume.

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

Se vuoi conoscere il Mountpoint , useresti il ​​seguente comando:-

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

Probabilmente stai notando le parentesi graffe proprio lì, sono come blocchi, le espressioni sono incapsulate all'interno di questi blocchi.

Proviamo ora qualcosa annidato. Ispeziona la rete e cerca il IPAM sezione.

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

Guardando questo puoi facilmente capire qual è il driver di questa rete. Ma invece di cercarlo in questo modo, puoi formattarlo dall'intero output JSON.

Nota il Driver la chiave è nidificata all'interno di IPAM . Quindi l'espressione punto per estrarre il driver sarebbe .IPAM.Driver . Guardalo in azione:-

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

Ciclo su oggetti o elenchi (intervallo)

Gli oggetti JSON sono come array associativi in ​​Bash, o Hash, dove le chiavi sono stringhe e i valori possono essere di qualsiasi tipo di dati.

Per farti capire questo un po' più facilmente, inizierò con un esempio pratico. Considera il .NetworkSettings.Networks sezione in un risultato di ispezione di un contenitore. Elenca le reti a cui è connesso il container e, per ciascuna rete, alcuni dettagli più associati come l'indirizzo IP.

Pensa se qualcuno ti chiede di comunicargli l'indirizzo IP di un container. Scegliere una sola rete e l'IP associato non ha molto senso, sarebbe meglio elencare tutti gli indirizzi IP associati a tutte le reti.

Puoi ottenere questo risultato con un semplice ciclo bash for se conosci già i nomi di rete. Come nel mio caso, posso fare qualcosa del genere:-

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

Ma ovviamente questo è limitante su larga scala poiché non possiamo ricordare sempre tutti i nomi di rete.

Puoi mitigare questo problema utilizzando l'azione del modello range . range va su una mappa (un array associativo o un oggetto JSON) e ci fornisce non la chiave, ma i valori per ogni iterazione (questo comportamento è modificabile).

Quindi, in questo caso, puoi scrivere un blocco come {{range .NetworkSettings.Networks}} per scorrere i valori di ciascuna rete o i dati associati a ciascuna rete, e da questo puoi estrarre l'indirizzo IP come faresti da una normale struttura simile a JSON, ovvero {{.IPAddress}}} . Una cosa da ricordare è di terminare sempre l'intero modello che inizia con range , con {{end}} .

Mettendo tutto insieme, puoi riscrivere il precedente ciclo for proprio in questo modo:-

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

Esempio di output:-

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

     172.17.0.2
     172.21.0.2

Utilizzo dell'index funzione su array e oggetti

Puoi usare l'index funzione per estrarre parti dall'oggetto o dall'array JSON. Se la struttura è un oggetto JSON, dovresti utilizzare {{index .Field "key"}} , se la struttura è un array JSON, dovresti utilizzare {{index .Field index}} .

Nell'esempio precedente hai stampato tutti gli indirizzi IP di un container. Supponiamo che tu conosca una delle reti a cui è connesso (bridge) e desideri stampare l'indirizzo IP associato a quella rete. Puoi farlo con index funziona in questo modo:-

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

Uscita:-

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

Utilizzo di json funzione

I dati esportati dopo la formattazione non in JSON, è in una struttura di dati go. Ma puoi convertirlo in JSON usando json funzione.

Il livello superiore dell'oggetto JSON è . . Quindi per stamparlo faresti qualcosa del genere:-

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[]}

Quello che stai vedendo qui è una grande struttura composta da altri tipi di dati e mappe di base di strutture. Questi non sono molto leggibili, né utilizzabili al di fuori di go. Ma puoi convertirli in JSON usando json funzione. Basta anteporre un campo con json come sto facendo qui:-

➟ 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":{}}

Per farlo sembrare un po' migliore invialo a 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": {}
}

È così? Assolutamente no. Consiglio vivamente di leggere come utilizzare i modelli go.

Qui ho provato a iniziare a usarlo senza dover sapere molto sui modelli go. Spero di esserci riuscito.

Per qualsiasi chiarimento non esitare ad utilizzare la sezione commenti.


Docker
  1. Come utilizzare il comando vmstat

  2. Come usare il comando Su in Linux

  3. Come usare Docker Compose

  4. Come configurare la finestra mobile per utilizzare il proxy

  5. Come utilizzare l'opzione --since con il comando docker logs

Come usare il comando pkill

Come utilizzare il comando LDD in Linux

Come installare e utilizzare Docker su Rocky Linux 8

Come usare il comando PS

Come usare il comando TOP

Come installare e utilizzare Podman (alternativa Docker)