Salah satu perintah Docker yang penting adalah memeriksa buruh pelabuhan. Ini memungkinkan Anda mengekstrak informasi tentang berbagai objek buruh pelabuhan, mengetahui cara menggunakannya adalah sesuatu SEMUA ORANG harus tahu tentang.
Jika Anda bertanya-tanya, objek atau sumber daya Docker hanyalah hal-hal seperti wadah, volume, jaringan, dll.
Kekuatan utama inspect
berasal dari kemampuan pemformatannya.
Misalnya, Anda dapat mengekstrak alamat IP container yang sedang berjalan dengan memeriksanya, dan memformatnya dengan cara tertentu.
➟ docker container inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx
172.17.0.2
Docker menggunakan go-template untuk memformat outputnya.
Dalam artikel ini, pertama saya akan membahas dasar-dasar perintah inspeksi Docker, dan kemudian saya akan fokus pada cara memformat output sesuai kebutuhan spesifik Anda.
Apa yang dilakukan pemeriksaan Docker?
Inspect memberi Anda sekumpulan metadata tentang semua objek berbeda yang dikelola oleh buruh pelabuhan. Jenis informasi bervariasi dari objek ke objek.
Misalnya, jika Anda memeriksa sebuah volume, Anda akan mendapatkan informasi terkait saat dibuat, driver volume yang digunakan, lokasi di sistem file host, label, dll.
Jika itu adalah jaringan yang Anda periksa, maka Anda akan mendapatkan hal-hal seperti subnet, gateway, container yang terhubung dan alamat IP, label, dan informasi lainnya.
Untuk memahami lebih baik apa yang disediakan inspeksi untuk objek tertentu, saya sarankan Anda menjalankan perintah dan melihatnya sendiri.
Apa saja objek yang dapat diperiksa?
Di buruh pelabuhan, objek atau tipe objek adalah semua konstruksi yang dikendalikan oleh buruh pelabuhan. Ini termasuk yang berikut:-
- Wadah.
- Gambar.
- Jaringan.
- Volume.
- Konteks.
- Plugin.
- Node (objek gerombolan).
- Layanan (objek gerombolan).
- Rahasia (objek gerombolan).
- Konfigurasi (objek gerombolan).
Menggunakan perintah inspeksi Docker
Ada dua cara Anda dapat menggunakan inspect
sub-perintah.
docker inspect [object] [options]
docker [object_type] inspect [object] [options]
Metode kedua adalah yang harus Anda gunakan selalu . inspect
sub-perintah memberikan output JSON, saya akan membahasnya sebentar lagi.
Buat volume bernama unique
.
docker volume create unique
Sekarang buat jaringan dengan nama yang sama, unique
.
docker network create unique
Sekarang mari kita coba memeriksa objek yang bernama unique
menggunakan sintaks pertama.
docker inspect unique
Hasil saya:-
➟ 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": {}
}
]
Di sistem saya, seperti yang Anda lihat inspect
memeriksa jaringan, tetapi bagaimana jika saya bermaksud memeriksa volumenya?
Ini adalah masalah dengan docker inspect
, ketika Anda memiliki dua objek berbeda bernama sama, Anda tidak bisa hanya menggunakan docker inspect [object_name]
. Untuk memeriksa dengan tepat apa yang Anda inginkan, Anda harus menggunakan ID objek, atau menggunakan --type=[object_type]
pilihan. Anda dapat menulis perintah sebelumnya dengan --type
pilihan seperti ini:-
docker inspect --type=volume unique
Meskipun ini berhasil, saya yakin ini tidak perlu karena kita sudah memiliki sintaks lainnya. Anda bisa menggunakan sub-perintah khusus objek seperti yang saya lakukan di sini:-
docker volume inspect unique
Lebih sedikit untuk menulis, dan jauh lebih mudah untuk dibaca.
Beberapa contoh perintah inspeksi Docker yang berguna
Di bagian ini, saya akan merekam daftar pertanyaan umum dan seperti apa perintah inspeksi yang relevan untuk mendapatkan informasi tersebut.
Kueri penampung
Sebagai contoh, saya akan menjalankan contoh container nginx, dan semua perintah akan dijalankan terhadap container yang sedang berjalan ini. Perintah yang saya gunakan untuk menjalankan wadah ini:-
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 penampung berdasarkan nama
Anda bisa mendapatkan ID wadah menggunakan perintah berikut:-
docker container inspect -f '{{.Id}}' [container_name]
Contoh:-
➟ docker container inspect -f '{{.Id}}' nginx
0409779fc2d976387170d664a6aed5ee80a460f8a8dd02c44a02af97df0bb956
2. Proses utama container
Proses kontainer utama pada dasarnya adalah ENTRYPOINT
+ CMD
.
docker container inspect -f '{{printf "%s " .Path}}{{range .Args}}{{printf "%s " .}}{{end}}' [container_name|id]
Contoh:-
➟ docker container inspect -f '{{printf "%s " .Path}}{{range .Args}}{{printf "%s " .}}{{end}}' nginx
/docker-entrypoint.sh nginx -g daemon off;
3. Mencantumkan binding port
Perintah berikut mencantumkan semua binding port container-to-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]
Contoh:-
➟ 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
Anda dapat mencapai hal yang sama dengan docker container port
perintah.
4. Mencantumkan alamat IP-nya
Sebuah wadah dapat dihubungkan ke beberapa jaringan, alih-alih mencetak salah satu dari banyak alamat IP tersebut, Anda dapat mencetak semua alamat IP tersebut dengan perintah ini.
docker container inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container_name|id]
Contoh:-
➟ docker container inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nginx
172.17.0.2
5. Mencantumkan variabel lingkungan
Anda juga dapat membuat daftar variabel lingkungan wadah.
docker container inspect -f '{{range .Config.Env}}{{printf "%s\n" .}}{{end}}' [container_name|id]
Contoh:-
➟ 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. Mencantumkan volume/bind mount bersama dengan modenya
Perintah berikut mencetak bind mount dalam format ini, "[source] -> [destination], mode:[mode]".
docker container inspect -f '{{range .Mounts}}{{printf "%s -> %s, mode: %s\n" .Source .Destination .Mode}}{{end}}' [container_name|id]
Contoh:-
➟ 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
Kueri volume
Tidak banyak untuk memeriksa volume kecuali untuk mengetahui lokasi host, yang ada di data-dir/volumes
. Anda bisa mendapatkan informasi itu dengan perintah berikut:-
docker volume inspect -f '{{.Mountpoint}}' [volume_name|id]
Contoh:-
➟ docker volume create unique
unique
~
➟ docker volume inspect -f '{{.Mountpoint}}' unique
/var/lib/docker/volumes/unique/_data
Kueri jaringan
Ada dua pertanyaan yang saya pribadi sering lakukan, satu adalah mengetahui subnet jaringan dan semua wadah yang terhubung ke jaringan itu dan IP yang terkait dengannya.
Untuk ini saya membuat jaringan sederhana dengan docker network create unique
perintah.
1. Mendapatkan subnet
Untuk mendapatkan subnet, gunakan perintah berikut:-
docker network inspect -f '{{range .IPAM.Config}}{{.Subnet}}{{end}}' [network_name|id]
Contoh:-
➟ docker network inspect -f '{{range .IPAM.Config}}{{.Subnet}}{{end}}' unique
172.21.0.0/16
2. Mencantumkan container yang terhubung bersama dengan alamat IP-nya
Perintahnya seperti ini,
docker network inspect -f '{{range .Containers}}{{printf "%s -> %s\n" .Name .IPv4Address}}{{end}}' [network_name|id]
Contoh:-
➟ 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
Memformat output perintah inspeksi Docker
inspect
memberi kami array JSON untuk output, yang dapat Anda filter menggunakan sesuatu seperti jq
. Jadi jika Anda berpengalaman dalam jq
, Anda mungkin ingin menggunakannya saja. Masalah dengan jq
adalah bahwa itu tidak diinstal sebelumnya di sebagian besar distribusi Linux, sedangkan mekanisme pemformatan default docker .. inspect
sudah ada, dan sangat kuat.
Docker menggunakan go-template untuk memformat outputnya. Artikel ini tidak akan membahas tentang go-template, tetapi jika Anda ingin mempelajari lebih lanjut, Anda dapat membacanya di sini.
JSON internal diwakili menggunakan berbagai struktur data Go. Itulah mengapa template go benar-benar berfungsi dengan tipe data go. Karena saya tidak ingin menjelaskan apa itu struktur data, alih-alih menggunakan istilah tersebut, saya akan menggunakan istilah JSON agar lebih mudah dipahami.
Mengekstrak bidang sederhana
Pertimbangkan objek JSON seperti berikut:-
{
"mary": 43,
"john": 44
}
Katakanlah Anda ingin mengekstrak informasi yang terkait dengan kunci mary
. Untuk melakukannya, yang Anda gunakan adalah notasi titik [.], di mana Anda mengawali kunci dengan titik, dan menambahkan kunci secara rekursif untuk setiap kunci bersarang. Ini sama dengan jq
. Jadi .mary
di sini akan menjadi 43.
Pertimbangkan JSON berikut sekarang.
{
"mary": {
"jane": 43,
"soyas": 56
},
"john": 65
}
Dalam hal ini .mary.jane
akan menjadi 43, dan juga .mary.soyas
akan menjadi 56.
Sintaks serupa dapat digunakan dengan go-template. Untuk memformat output, Anda harus meneruskan template ke -f
atau --format
opsi inspect
sub-perintah. Mari kita revisi output dari pemeriksaan volume.
[
{
"CreatedAt": "2021-05-07T15:53:10+05:30",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/unique/_data",
"Name": "unique",
"Options": {},
"Scope": "local"
}
]
Jika Anda ingin mengetahui Mountpoint
, Anda akan menggunakan perintah berikut:-
docker volume inspect -f '{{.Mountpoint}}' unique
➟ docker volume inspect -f '{{.Mountpoint}}' unique
/var/lib/docker/volumes/unique/_data
Anda mungkin memperhatikan kurung kurawal di sana, ini seperti blok, ekspresi dienkapsulasi di dalam blok ini.
Mari kita coba sesuatu yang bersarang sekarang. Periksa jaringan, dan cari IPAM
bagian.
➟ docker network inspect unique
<snipped>
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
<snipped>
Melihat ini, Anda dapat dengan mudah mengetahui apa driver jaringan ini. Namun alih-alih mencarinya seperti ini, Anda dapat memformatnya dari seluruh keluaran JSON.
Perhatikan Driver
kunci bersarang di dalam IPAM
. Jadi ekspresi titik untuk mengekstrak driver adalah .IPAM.Driver
. Lihat aksinya:-
➟ docker network inspect -f '{{.IPAM.Driver}}' unique
default
Mengulangi objek atau daftar (rentang)
Objek JSON seperti array asosiatif di Bash, atau Hash, di mana kuncinya adalah string dan nilainya dapat berupa tipe data apa pun.
Untuk memudahkan Anda memahami ini, saya akan mulai dengan contoh praktis. Pertimbangkan .NetworkSettings.Networks
bagian dalam hasil pemeriksaan wadah. Ini mencantumkan jaringan tempat wadah terhubung, dan untuk setiap jaringan, beberapa detail terkait lainnya seperti alamat IP.
Pikirkan jika seseorang meminta Anda untuk memberi tahu dia alamat IP sebuah wadah. Memilih hanya satu jaringan dan IP yang terkait tidak masuk akal, yang akan lebih baik adalah mencantumkan semua alamat IP yang terkait dengan semua jaringan.
Anda dapat mencapai ini dengan bash sederhana untuk loop jika Anda sudah tahu nama jaringan. Seperti dalam kasus saya, saya dapat melakukan sesuatu seperti berikut:-
for network in bridge unique; do
docker container inspect -f \
"{{.NetworkSettings.Networks.$network.IPAddress}}" nginx
done
Tapi jelas ini membatasi dalam skala besar karena kita tidak mungkin selalu mengingat semua nama jaringan.
Anda dapat mengurangi masalah ini dengan menggunakan tindakan template range
. range
menelusuri peta (array asosiatif atau objek JSON) dan memberi kita bukan kunci, tetapi nilai untuk setiap iterasi (perilaku ini dapat diubah).
Jadi dalam hal ini, Anda dapat menulis blok seperti {{range .NetworkSettings.Networks}}
untuk mengulang nilai setiap jaringan atau data yang terkait dengan setiap jaringan, dan dari sana Anda dapat mengekstrak alamat IP seperti yang Anda lakukan dari struktur seperti JSON normal, yaitu {{.IPAddress}}}
. Satu hal yang perlu diingat adalah untuk selalu mengakhiri seluruh template yang dimulai dengan range
, dengan {{end}}
.
Menyatukan semua itu, Anda dapat menulis ulang for loop sebelumnya dengan cara ini:-
docker container inspect -f \
'{{range .NetworkSettings.Networks}}
{{.IPAddress}}{{end}}' nginx
Contoh keluaran:-
➟ docker container inspect -f \
> '{{range .NetworkSettings.Networks}}
> {{.IPAddress}}{{end}}' nginx
172.17.0.2
172.21.0.2
Menggunakan index
fungsi pada array &objek
Anda dapat menggunakan index
berfungsi untuk mengekstrak bagian dari objek atau larik JSON Anda. Jika strukturnya adalah objek JSON, Anda akan menggunakan {{index .Field "key"}}
, jika strukturnya adalah larik JSON, Anda akan menggunakan {{index .Field index}}
.
Pada contoh sebelumnya Anda mencetak semua alamat IP dari sebuah wadah. Katakanlah Anda tahu salah satu jaringan yang terhubung (jembatan) dan ingin mencetak alamat IP yang terkait dengan jaringan itu. Anda dapat melakukannya dengan index
fungsinya seperti ini:-
docker container inspect -f '{{(index .NetworkSettings.Networks "bridge").IPAddress}}' nginx
Keluaran:-
➟ docker container inspect -f '{{(index .NetworkSettings.Networks "bridge").IPAddress}}' nginx
172.17.0.2
Menggunakan json
fungsi
Data yang diekspor setelah pemformatan tidak di JSON, ada di beberapa struktur data go. Tetapi Anda dapat mengonversinya ke JSON dengan menggunakan json
fungsi.
Level teratas dari objek JSON adalah .
. Jadi untuk mencetak bahwa Anda akan melakukan sesuatu seperti ini:-
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[]}
Apa yang Anda lihat di sini adalah struct besar yang terdiri dari tipe data dasar dan peta struct lainnya. Ini tidak terlalu mudah dibaca, juga tidak dapat digunakan di luar perjalanan. Tetapi Anda dapat mengonversinya ke JSON menggunakan json
fungsi. Cukup tambahkan bidang dengan json
seperti yang saya lakukan di sini:-
➟ 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":{}}
Untuk membuatnya terlihat sedikit lebih baik, kirimkan ke 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": {}
}
Itu saja? Sama sekali tidak. Saya sangat menyarankan Anda membaca tentang cara menggunakan template go.
Di sini saya sudah mencoba untuk mulai menggunakannya tanpa harus tahu banyak tentang go template sama sekali. Saya harap saya berhasil.
Untuk klarifikasi apa pun, silakan gunakan bagian komentar.