GNU/Linux >> LINUX-Kenntnisse >  >> Panels >> Docker

So verwenden Sie den Docker-Inspect-Befehl

Einer der wichtigsten Docker-Befehle ist docker inspect. Es lässt Sie Informationen über verschiedene Docker-Objekte extrahieren, zu wissen, wie man es benutzt, ist etwas JEDER wissen sollten.

Falls Sie sich fragen, Docker-Objekte oder -Ressourcen sind einfach Dinge wie Container, Volumes, Netzwerke usw.

Die größte Stärke von inspect kommt von seinen Formatierungsfähigkeiten.

Beispielsweise können Sie die IP-Adresse eines laufenden Containers extrahieren, indem Sie ihn untersuchen und auf eine bestimmte Weise formatieren.

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

Docker verwendet Go-Templates zum Formatieren seiner Ausgabe.

In diesem Artikel gehe ich zuerst auf die Grundlagen des Docker-Inspect-Befehls ein und konzentriere mich dann darauf, wie Sie die Ausgabe Ihren spezifischen Anforderungen entsprechend formatieren.

Was macht Docker inspect?

Inspect bietet Ihnen eine Reihe von Metadaten zu all den verschiedenen Objekten, die von Docker verwaltet werden. Die Art der Informationen variiert von Objekt zu Objekt.

Wenn Sie beispielsweise ein Volume untersuchen, erhalten Sie Informationen über das Erstellungsdatum, den verwendeten Volume-Treiber, den Speicherort im Host-Dateisystem, Labels usw.

Wenn Sie ein Netzwerk untersuchen, erhalten Sie Dinge wie sein Subnetz, Gateway, verbundene Container und ihre IP-Adressen, Labels und andere Informationen.

Um besser zu verstehen, was inspect für ein bestimmtes Objekt bietet, empfehle ich Ihnen, die Befehle auszuführen und selbst zu sehen.

Welche Objekte können inspiziert werden?

In Docker sind ein Objekt oder Objekttyp alle Konstrukte, die von Docker gesteuert werden. Dies beinhaltet Folgendes:-

  1. Container.
  2. Bilder.
  3. Netzwerke.
  4. Volumen.
  5. Kontexte.
  6. Plugins.
  7. Knoten (Schwarmobjekt).
  8. Dienste (Schwarmobjekt).
  9. Geheimnisse (Schwarmobjekt).
  10. Konfigurationen (Schwarmobjekt).

Docker-Inspect-Befehl verwenden

Es gibt zwei Möglichkeiten, wie Sie inspect verwenden können Unterbefehl.

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

Die zweite Methode sollten Sie immer verwenden . Die inspect Unterbefehl liefert eine JSON-Ausgabe, darauf werde ich gleich eingehen.

Erstellen Sie ein Volume mit dem Namen unique .

docker volume create unique

Erstellen Sie nun ein Netzwerk mit dem gleichen Namen, unique .

docker network create unique

Lassen Sie uns nun versuchen, das Objekt mit dem Namen unique zu inspizieren mit der ersten Syntax.

docker inspect unique

Meine Ausgabe:-

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

In meinem System, wie Sie inspect sehen können das Netzwerk inspiziert, aber was ist, wenn ich beabsichtigte, das Volume zu inspizieren?

Das ist das Problem mit docker inspect , wenn Sie zwei verschiedene Objekte mit demselben Namen haben, können Sie nicht einfach docker inspect [object_name] verwenden . Um genau das zu untersuchen, was Sie wollen, müssen Sie entweder die ID des Objekts oder --type=[object_type] verwenden Möglichkeit. Sie können den vorherigen Befehl mit --type schreiben Option wie folgt:-

docker inspect --type=volume unique

Obwohl dies funktioniert, glaube ich, dass dies unnötig ist, da wir bereits die andere Syntax haben. Sie können einfach den objektspezifischen Unterbefehl verwenden, wie ich es hier mache:-

docker volume inspect unique

Es ist weniger zu schreiben und viel einfacher zu lesen.

Einige nützliche Docker-Inspect-Befehlsbeispiele

In diesem Abschnitt werde ich eine Liste gängiger Abfragen aufzeichnen und erläutern, wie der relevante Inspect-Befehl aussehen würde, um diese Informationen zu erhalten.

Containerabfragen

Für die Beispiele lasse ich einen Beispiel-Nginx-Container laufen, und alle Befehle werden für diesen laufenden Container ausgeführt. Der Befehl, mit dem ich diesen Container ausgeführt habe:-

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 eines Containers nach Namen

Sie können die ID des Containers mit dem folgenden Befehl abrufen:-

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

Beispiel:-

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

2. Hauptprozess des Containers

Der Hauptcontainerprozess ist im Grunde ENTRYPOINT + CMD .

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

Beispiel:-

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

3. Auflisten der Portbindungen

Der folgende Befehl listet alle Container-zu-Host-Portbindungen auf.

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

Beispiel:-

➟ 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
Dasselbe erreichen Sie mit docker container port Befehl.

4. Auflisten seiner IP-Adressen

Ein Container kann mit mehreren Netzwerken verbunden werden, anstatt eine dieser vielen IP-Adressen zu drucken, können Sie mit diesem Befehl alle diese IP-Adressen drucken.

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

Beispiel:-

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

5. Auflisten der Umgebungsvariablen

Sie können auch die Umgebungsvariable eines Containers auflisten.

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

Beispiel:-

➟ 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. Auflisten der Volumes/Bind-Mounts zusammen mit dem Modus

Der folgende Befehl druckt die Bind-Mounts in diesem Format, "[source] -> [destination], mode:[mode]".

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

Beispiel:-

➟ 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

Volumenabfragen

Es gibt nicht viel, um ein Volume zu inspizieren, außer den Speicherort des Hosts zu kennen, der sich in data-dir/volumes befindet . Sie können diese Informationen mit dem folgenden Befehl abrufen:-

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

Beispiel:-

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

Netzwerkabfragen

Es gibt zwei Abfragen, die ich persönlich häufig durchführe, eine ist, ein Netzwerk-Subnetz und alle Container zu kennen, die mit diesem Netzwerk verbunden sind, und die ihnen zugeordneten IPs.

Dazu habe ich mit dem docker network create unique ein einfaches Netzwerk erstellt Befehl.

1. Abrufen des Subnetzes

Um das Subnetz abzurufen, verwenden Sie den folgenden Befehl:-

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

Beispiel:-

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

2. Auflisten der verbundenen Container mit ihren IP-Adressen

Der Befehl sieht folgendermaßen aus:

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

Beispiel:-

➟ 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

Formatierung der Ausgabe des Docker-Inspect-Befehls

inspect stellt uns ein JSON-Array für die Ausgabe zur Verfügung, das Sie mit so etwas wie jq filtern können . Wenn Sie also Erfahrung mit jq haben , vielleicht möchten Sie es einfach verwenden. Das Problem mit jq ist, dass es in den meisten Linux-Distributionen nicht vorinstalliert ist, während der Standardformatierungsmechanismus von docker .. inspect ist bereits vorhanden und sehr mächtig.

Docker verwendet Go-Templates, um seine Ausgabe zu formatieren. In diesem Artikel geht es nicht um Go-Templates, aber wenn Sie mehr erfahren möchten, können Sie hier darüber lesen.

Intern werden JSONs durch verschiedene Go-Datenstrukturen dargestellt. Aus diesem Grund funktionieren Go-Vorlagen tatsächlich mit Go-Datentypen. Da ich nicht erklären möchte, was diese Datenstrukturen sind, verwende ich anstelle dieser Begriffe JSON-Begriffe, um es verständlicher zu machen.

Einfache Felder extrahieren

Stellen Sie sich ein JSON-Objekt wie das folgende vor:-

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

Angenommen, Sie möchten die Informationen extrahieren, die dem Schlüssel mary zugeordnet sind . Dazu verwenden Sie die Notation Punkt [.], bei der Sie dem Schlüssel einen Punkt voranstellen und Schlüssel rekursiv für alle verschachtelten Schlüssel hinzufügen. Dies ist dasselbe wie jq . Also .mary hier wäre 43.

Betrachten Sie jetzt das folgende JSON.

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

In diesem Fall .mary.jane wäre 43, und ähnlich .mary.soyas wäre 56.

Eine ähnliche Syntax kann mit Go-Templates verwendet werden. Um die Ausgabe zu formatieren, müssen Sie die Vorlage an -f übergeben oder --format Option des inspect Unterbefehl. Lassen Sie uns die Ausgabe der Volumenprüfung überarbeiten.

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

Wenn Sie den Mountpoint wissen wollen , würden Sie den folgenden Befehl verwenden:-

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

Sie bemerken wahrscheinlich genau dort die geschweiften Klammern, diese sind wie Blöcke, Ausdrücke sind in diesen Blöcken eingekapselt.

Versuchen wir jetzt etwas Verschachteltes. Untersuchen Sie das Netzwerk und suchen Sie nach IPAM Abschnitt.

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

Wenn Sie sich das ansehen, können Sie ziemlich leicht herausfinden, was der Treiber dieses Netzwerks ist. Aber anstatt so danach zu suchen, können Sie es aus der gesamten JSON-Ausgabe formatieren.

Beachten Sie den Driver Der Schlüssel ist in IPAM verschachtelt . Der Punktausdruck zum Extrahieren des Treibers wäre also .IPAM.Driver . Sehen Sie es in Aktion:-

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

Schleifen über Objekte oder Listen (Bereich)

JSON-Objekte sind wie assoziative Arrays in Bash oder Hashes, bei denen die Schlüssel Zeichenfolgen sind und die Werte jeden Datentyp haben können.

Damit Sie das etwas leichter verstehen, beginne ich mit einem praktischen Beispiel. Betrachten Sie .NetworkSettings.Networks Abschnitt in einem Inspektionsergebnis eines Behälters. Es listet die Netzwerke auf, mit denen der Container verbunden ist, und für jedes Netzwerk einige weitere zugehörige Details wie die IP-Adresse.

Stellen Sie sich vor, jemand bittet Sie, ihm/ihr die IP-Adresse eines Containers mitzuteilen. Es macht wenig Sinn, nur ein Netzwerk und die zugehörige IP auszuwählen, besser wäre es, alle IP-Adressen aufzulisten, die mit allen Netzwerken verbunden sind.

Sie können dies mit einer einfachen Bash-For-Schleife if erreichen Sie kennen bereits die Netzwerknamen. Wie in meinem Fall kann ich so etwas tun:-

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

Aber offensichtlich ist dies in großem Umfang einschränkend, da wir uns unmöglich immer alle Netzwerknamen merken können.

Sie können dieses Problem entschärfen, indem Sie die Vorlagenaktion range verwenden . range geht über eine Karte (ein assoziatives Array oder JSON-Objekt) und liefert uns nicht den Schlüssel, sondern die Werte für jede Iteration (dieses Verhalten ist änderbar).

In diesem Fall können Sie also einen Block wie {{range .NetworkSettings.Networks}} schreiben um die Werte jedes Netzwerks oder die mit jedem Netzwerk verbundenen Daten zu durchlaufen, und daraus können Sie die IP-Adresse wie aus einer normalen JSON-ähnlichen Struktur extrahieren, d. h. {{.IPAddress}}} . Denken Sie daran, immer das gesamte Template zu beenden, das mit range beginnt , mit {{end}} .

Wenn Sie das alles zusammenfassen, können Sie die vorherige for-Schleife folgendermaßen umschreiben:-

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

Beispielausgabe:-

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

     172.17.0.2
     172.21.0.2

Verwendung des index Funktion auf Arrays und Objekten

Sie können den index verwenden Funktion zum Extrahieren von Teilen aus Ihrem JSON-Objekt oder -Array. Wenn die Struktur ein JSON-Objekt ist, würden Sie {{index .Field "key"}} verwenden , wenn die Struktur ein JSON-Array ist, würden Sie {{index .Field index}} verwenden .

Im vorherigen Beispiel haben Sie alle IP-Adressen eines Containers gedruckt. Angenommen, Sie kennen eines der Netzwerke, mit denen es verbunden ist (Bridge), und möchten die diesem Netzwerk zugeordnete IP-Adresse drucken. Das geht mit index Funktion so:-

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

Ausgabe:-

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

Mit json Funktion

Die nach der Formatierung exportierten Daten sind nicht in JSON befindet es sich in einer Go-Datenstruktur. Sie können dies jedoch mithilfe von json in JSON konvertieren Funktion.

Die oberste Ebene des JSON-Objekts ist . . Um das zu drucken, würden Sie etwa so vorgehen:-

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

Was Sie hier sehen, ist eine große Struktur, die aus anderen Strukturen, grundlegenden Datentypen und Karten besteht. Diese sind weder gut lesbar noch außerhalb von unterwegs verwendbar. Aber Sie können diese mit json in JSON konvertieren Funktion. Stellen Sie einfach einem Feld json voran wie ich es hier mache:-

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

Damit es ein bisschen besser aussieht, leiten Sie es an jq weiter .

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

Ist es das? Absolut nicht. Ich empfehle Ihnen dringend, sich über die Verwendung von Go-Vorlagen zu informieren.

Hier habe ich versucht, mit der Verwendung zu beginnen, ohne viel über Go-Vorlagen wissen zu müssen. Ich hoffe, es ist mir gelungen.

Für Klarstellungen können Sie gerne den Kommentarbereich verwenden.


Docker
  1. Verwendung des vmstat-Befehls

  2. So verwenden Sie den Su-Befehl unter Linux

  3. So verwenden Sie Docker Compose

  4. So konfigurieren Sie Docker für die Verwendung von Proxy

  5. So verwenden Sie die Option --since mit dem Befehl docker logs

So verwenden Sie den pkill-Befehl

So verwenden Sie den LDD-Befehl unter Linux

So installieren und verwenden Sie Docker unter Rocky Linux 8

So verwenden Sie den PS-Befehl

So verwenden Sie den TOP-Befehl

So installieren und verwenden Sie Podman (Docker-Alternative)