docker 查看容器信息---格式化
鏡像,ID,端口號,狀態
docker ps -a --format "table {{.Image}}\t{{.ID}}\t{{.Ports}}\t{{.Status}}"
首字母大寫+小寫
table是帶head **鏡像也一樣
列出正在運行的容器
docker ps -a -f "status=running"
列出已經退出的容器
docker ps -a -f "status=exited"
status 所有的狀態
- status (
created|restarting|running|removing|paused|exited|dead
)
獲取單個容器的ip
docker inspect <container id> ###輸出容器的詳細信息,需要逐行查看尋找ip,也可以配合grep等過濾,下面兩個語句可以直接顯示ip docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container-ID> docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
上面方法的函數實現
將下面內容寫到 ~/.bashrc中
function docker_ip() { sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' $1 }
source ~/.bashrc 然后:
$ docker_ip <container-ID>
獲取所有容器的ip
以下三條命令都可以
docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}' $(docker ps -aq) docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq) docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
Docker格式化輸出命令:"docker inspect --format" 學習筆記
Docker --format 參數提供了基於 Go模板 的日志格式化輸出輔助功能,並提供了一些內置的增強函數。
什么是模板?
上圖是大家熟悉的 MVC 框架(Model View Controller): Model(模型,通常在服務端)用於處理數據、View(視圖,客戶端代碼)用於展現結果、Controller(控制器)用於控制數據流,確保 M 和 V 的同步,即一旦 M 改變,V 也應該同步更新。
而對於 View 端的處理,在很多動態語言中是通過在靜態 HTML 代碼中插入動態數據來實現的。例如 JSP 的 <%=....=%> 和 PHP 的 <?php.....?> 語法。
由於最終展示給用戶的信息大部分是靜態不變的,只有少部分數據會根據用戶的不同而動態生成。比如,對於 docker ls 的輸出信息會根據附加參數的不同而不同,但其表頭信息是固定的。所以,將靜態信息固化為模板可以復用代碼,提高展示效率。
Go語言提供了簡單靈活的模板支持,而基於 Go 開發的 Docker 繼承了該強大能力,使其可以脫離 Shell 的相關操作,直接對結果進行格式化輸出。所有支持 --format 擴展的 Docker CLI 指令均支持該操作。
Go模板常用語法
注釋
格式: {{/*注釋內容*/}}
示例:
1
|
docker network inspect --
format
=
'{{/*查看容器的默認網關*/}}{{range .IPAM.Config}}{{.Gateway}}{{end}}'
$INSTANCE_ID
|
變量
系統變量 {{.}}
點號表示當前對象及上下文,和 Java、C++ 中的 this 類似。可以直接通過{{.}}獲取當前對象。
另外,如果返回結果也是一個 Struct 對象(Json 中以花括號/大括號包含),則可以直接通過點號級聯調用,獲取子對象的指定屬性值。
示例代碼:
1
2
|
#可以通過級聯調用直接讀取子對象 State 的 Status 屬性,以獲取容器的狀態信息:
docker inspect --
format
'{{/*讀取容器狀態*/}}{{.State.Status}}'
$INSTANCE_ID
|
注意: 如果需要獲取的屬性名稱包含點號(比如下列示例數據)或者以數字開頭,則不能直接通過級聯調用獲取信息。因為屬性名稱中的點號會被解析成級聯信息,進而導致返回錯誤結果。即便使用引號將其包含也會提示語法格式錯誤。此時,需要通過 index 來讀取指定屬性信息。
1
2
3
4
5
6
7
8
|
"Options"
: {
"com.docker.network.bridge.default_bridge"
:
"true"
,
"com.docker.network.bridge.enable_icc"
:
"true"
,
"com.docker.network.bridge.enable_ip_masquerade"
:
"true"
,
"com.docker.network.bridge.host_binding_ipv4"
:
"0.0.0.0"
,
"com.docker.network.bridge.name"
:
"docker0"
,
"com.docker.network.driver.mtu"
:
"1500"
},
|
示例操作:
1
2
3
4
5
6
7
8
9
10
11
|
# 直接級聯調用會提示找不到數據:
docker inspect --
format
'{{.Options.com.docker.network.driver.mtu}}'
bridge
<no value>
# 用引號括起來會提示語法錯誤:
docker inspect --
format
'{{.Options."com.docker.network.driver.mtu"}}'
bridge
Template parsing error: template: :1: bad character U+0022
'"'
# 正確的用法,必須用 index 讀取指定屬性名稱的屬性值:
docker inspect --
format
'{{/*讀取網絡在hosts上的名稱*/}}{{index .Options "com.docker.network.bridge.name"}}'
bridge
docker0
|
自定義變量
可以在處理過程中設置自定義變量,然后結合自定義變量做更復雜的處理。 如果自定義變量的返回值是對象,則可以通過點號進一步級聯訪問其屬性。比如 {{$Myvar.Field1}}。
示例操作:
1
2
3
4
5
6
7
|
# 結合變量的使用,對輸出結果進行組裝展現,以輸出容器的所有綁定端口列表:
docker inspect --
format
'{{/*通過變量組合展示容器綁定端口列表*/}}已綁定端口列表:{{println}}{{range $p,$conf := .NetworkSettings.Ports}}{{$p}} -> {{(index $conf 0).HostPort}}{{println}}{{end}}'
Web_web_1
# 示例輸出信息
已綁定端口列表:
80
/tcp
-> 32770
8081
/tcp
-> 8081
|
遍歷(循環):range
格式:
1
2
|
{{range pipeline}}{{.}}{{end}}
{{range pipeline}}{{.}}{{
else
}}{{.}}{{end}}
|
range 用於遍歷結構內返回值的所有數據。支持的類型包括 array, slice, map 和 channel。使用要點:
- 對應的值長度為 0 時,range 不會執行。
- 結構內部如要使用外部的變量,需要在前面加 引用,比如Var2。
- range 也支持 else 操作。效果是:當返回值為空或長度為 0 時執行 else 內的內容。
示例操作:
1
2
3
4
5
6
7
8
|
# 查看容器網絡下已掛載的所有容器名稱,如果沒有掛載任何容器,則輸出 "With No Containers"
docker inspect --
format
'{{range .Containers}}{{.Name}}{{println}}{{else}}With No Containers{{end}}'
bridge
brtest
peaceful_brown
test
docker inspect --
format
'{{range .Containers}}{{.Name}}{{println}}{{else}}With No Containers{{end}}'
none
With No Containers
|
索引: index
如果返回結果是一個 map, slice, array 或 string,則可以使用 index 加索引序號(從零開始計數)來讀取屬性值。
示例代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# docker inspect $INSTANCE_ID 查看容器綁定的端口信息,其 Config 屬性就是一個 Map,包含了所有子網信息。
...
"IPAM"
: {
"Driver"
:
"default"
,
"Options"
: null,
"Config"
: [
{
"Subnet"
:
"172.31.254.1/24"
,
"Gateway"
:
"172.31.254.1"
}
]
},
...
|
示例操作:
1
2
|
# 通過索引序號讀取默認網關
docker inspect bridge --
format
'{{/*查看網絡的默認網關*/}}{{(index .IPAM.Config 0).Gateway}}'
|
判斷:if … else … end
基本判斷
1) not
返回單一參數的布爾否定值,即返回輸入參數的否定值。
示例:
1
2
|
# 如果容器的 restarting 設置為 false,則返回信息“容器沒有配置重啟策略”
docker inspect --
format
'{{if not .State.Restarting}}容器沒有配置重啟策略{{end}}'
$(docker
ps
-q)
|
2) or
- {{or x y}}: 表示如果 x 為真返回 x,否則返回 y。
- {{or x y z}}:后面跟多個參數時會逐一判斷每個參數,並返回第一個非空的參數。如果都為 false,則返回最后一個參數。
- 除了 null(空)和 false 被識別為 false,其它值(字符串、數字、對象等)均被識別為 true。
示例:
1
|
docker inspect --
format
'{{or .State.Status .State.Restarting}}'
$INSTANCE_ID
|
判斷條件
判斷語句通常需要結合判斷條件一起使用,使用格式基本相同:
1
|
{{
if
判斷條件 .Var1 .Var2}}{{end}}
|
go模板支持如下判斷方式:
1) eq: 相等,即 arg1 == arg2。比較特殊的是,它支持多個參數進行與比較,此時,它會將第一個參數和其余參數依次比較,返回下式的結果:
1
2
3
|
{{
if
eq
true
.Var1 .Var2 .Var3}}{{end}}
# 效果等同於:
arg1==arg2 || arg1==arg3 || arg1==arg4 ...
|
2) ne: 不等,即 arg1 != arg2。
3) lt: 小於,即 arg1 < arg2。
4) le: 小於等於,即 arg1 <= arg2。
5) gt: 大於,即 arg1 > arg2。
6) ge: 大於等於,即 arg1 >= arg2。
判斷的使用
格式:
1
2
3
|
{{
if
pipeline}}{{end}}
{{
if
pipeline}}{{
else
}}{{
if
pipeline}}{{end}}{{end}}
{{
if
pipeline}}{{
else
if
pipeline}}{{
else
}}{{end}}
|
示例:
1
2
3
4
5
6
7
|
# 輸出所有已停止的容器名稱:
docker inspect --
format
'{{if ne 0.0 .State.ExitCode}}{{.Name}}{{end}}'
$(docker
ps
-aq)
docker inspect --
format
'{{if ne 0.0 .State.ExitCode}}{{.Name}}{{else}}該容器還在運行{{end}}'
$(docker
ps
-aq)
docker inspect --
format
'{{if ne 0.0 .State.ExitCode}}{{.Name}}{{else if .}}該容器還在運行{{end}}'
$(docker
ps
-aq)
# 輸出所有已停止或配置了 Restarting 策略的容器名稱
docker inspect --
format
'{{if ne 0.0 .State.ExitCode}}{{.Name}}{{else if eq .State.Restarting true}}容器{{.Name}}配置了Restarting策略.{{else}}{{end}}'
$(docker
ps
-aq)
|
打印信息
docker --format 默認調用 go語言的 print 函數對模板中的字符串進行輸出。而 go語言還有另外 2 種相似的內置函數,對比說明如下:
print: 將傳入的對象轉換為字符串並寫入到標准輸出中。如果后跟多個參數,輸出結果之間會自動填充空格進行分隔。
println: 功能和 print 類似,但會在結尾添加一個換行符。也可以直接使用 {{println}} 來換行。
printf: 與 shell 等環境一致,可配合占位符用於格式化輸出。
對比示例輸出:
1
2
3
4
5
6
7
8
9
10
11
12
|
docker inspect --
format
'{{.State.Pid}}{{.State.ExitCode}}'
$INSTANCE_ID
240390
docker inspect --
format
'{{print .State.Pid .State.ExitCode}}'
$INSTANCE_ID
24039 0
docker inspect --
format
'{{.State.Pid}}{{println " 從這換行"}}{{.State.ExitCode}}'
$INSTANCE_ID
24039 從這換行
0
docker inspect --
format
'{{printf "Pid:%d ExitCode:%d" .State.Pid .State.ExitCode}}'
$INSTANCE_ID
Pid:24039 ExitCode:0
|
管道
管道 即 pipeline ,與 shell 中類似,可以是上下文的變量輸出,也可以是函數通過管道傳遞的返回值。
示例:
1
2
|
{{.Con | markdown | addlinks}}
{{.Name |
printf
"%s"
}}
|
內置函數 len
內置函數 len 返回相應對象的長度。
示例:
1
|
docker inspect --
format
'{{len .Name}}'
$INSTANCE_ID
|
Docker 增強模板及函數
Docker 基於 go模板的基礎上,構建了一些內置函數。
json
Docker 默認以字符串顯示返回結果。而該函數可以將結果格式化為壓縮后的 json 格式數據。
示例:
1
2
|
# 獲取 Config 字段對應的 json 數據
docker inspect --
format
=
'{{json .Config}}'
$INSTANCE_ID
|
join
用指定的字符串將返回結果連接后一起展示。操作對象必須是字符串數組。
示例:
1
2
|
# 輸出容器配置的所有 Entrypoint 參數,以 " , " 分隔:
docker inspect --
format
'{{join .Config.Entrypoint " , "}}'
$INSTANCE_ID
|
lower
將返回結果中的字母全部轉換為小寫。操作對象必須是字符串。
1
|
docker inspect --
format
"{{lower .Name}}"
$INSTANCE_ID
|
upper
將返回結果中的字母全部轉換為大寫。操作對象必須是字符串。
1
|
docker inspect --
format
"{{upper .Name}}"
$INSTANCE_ID
|
title
將返回結果的首字母轉換為大寫。操作對象必須是字符串,而且不能是純數字。
1
|
docker inspect --
format
"{{title .State.Status}}"
$INSTANCE_ID
|
split
使用指定分隔符將返回結果拆分為字符串列表。操作對象必須是字符串且不能是純數字。同時,字符串中必須包含相應的分隔符,否則會直接忽略操作。
1
|
docker inspect --
format
'{{split .HostsPath "/"}}'
$INSTANCE_ID
|
============================常用docker inspect --format 輸出示例========================
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
[root@node1 ~]
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ed603e52896 172.16.60.214:5000
/kevin_nginx
"/bin/sh -c '/usr/..."
13 minutes ago Up 13 minutes docker-test111
24e6607534f1 172.16.60.214:5000
/kevin_nginx
"/bin/sh -c '/usr/..."
13 minutes ago Up 13 minutes docker-test11
19be6b264b6e 172.16.60.214:5000
/kevin_nginx
"/bin/sh -c '/usr/..."
13 minutes ago Up 13 minutes docker-test1
1) 獲取容器的IP (后面使用容器名或容器ID都可以)
[root@node1 ~]
# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q)
192.10.160.193
173.20.19.128
17.16.10.128
[root@node1 ~]
# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-test1
17.16.10.128
2) 獲取容器的MAC地址
[root@node1 ~]
# docker inspect --format='{{range .NetworkSettings.Networks}}{{.MacAddress}}{{end}}' $(docker ps -a -q)
ee:ee:ee:ee:ee:ee
ee:ee:ee:ee:ee:ee
ee:ee:ee:ee:ee:ee
[root@node1 ~]
# docker inspect --format='{{range .NetworkSettings.Networks}}{{.MacAddress}}{{end}}' docker-test1
ee:ee:ee:ee:ee:ee
3) 獲取容器Name
[root@node1 ~]
# docker inspect --format='{{.Name}}' $(docker ps -aq)
/docker-test111
/docker-test11
/docker-test1
/calico-node
[root@node1 ~]
# docker inspect --format='{{.Name}}' $(docker ps -aq)|cut -d"/" -f2
docker-test111
docker-test11
docker-test1
[root@node1 ~]
# docker inspect --format='{{.Name}}' docker-test1
/docker-test1
[root@node1 ~]
# docker inspect --format='{{.Name}}' docker-test1|cut -d"/" -f2
docker-test1
4) 獲取容器Hostname
[root@node1 ~]
# docker inspect --format '{{ .Config.Hostname }}' $(docker ps -q)
2ed603e52896
24e6607534f1
19be6b264b6e
[root@node1 ~]
# docker inspect --format '{{ .Config.Hostname }}' docker-test1
19be6b264b6e
5) Hostname Name IP
[root@node1 ~]
# docker inspect --format 'Hostname:{{ .Config.Hostname }} Name:{{.Name}} IP:{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q)
Hostname:2ed603e52896 Name:
/docker-test111
IP:192.10.160.193
Hostname:24e6607534f1 Name:
/docker-test11
IP:173.20.19.128
Hostname:19be6b264b6e Name:
/docker-test1
IP:17.16.10.128
[root@node1 ~]
# docker inspect --format 'Hostname:{{ .Config.Hostname }} Name:{{.Name}} IP:{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' docker-test1
Hostname:19be6b264b6e Name:
/docker-test1
IP:17.16.10.128
6) 獲取容器的log path
[root@node1 ~]
# docker inspect --format='{{.LogPath}}' `docker ps -a -q`
[root@node1 ~]
# docker inspect --format='{{.LogPath}}' docker-test1
7) 獲取容器的image鏡像名稱
[root@node1 ~]
# docker inspect --format='{{.Config.Image}}' `docker ps -a -q`
172.16.60.214:5000
/kevin_nginx
172.16.60.214:5000
/kevin_nginx
172.16.60.214:5000
/kevin_nginx
quay.io
/calico/node
:v2.6.10
[root@node1 ~]
# docker inspect --format='{{.Config.Image}}' docker-test1
172.16.60.214:5000
/kevin_nginx
8) 獲取容器綁定的端口(port bindings)
[root@node1 ~]
# docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' `docker ps -a -q`
[root@node1 ~]
# docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' docker-test1
9) 獲取service實例的Ip
[root@swarm-manager-node ~]
# docker service ps my-test
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
t71gqufekv2o my-
test
.1 172.16.60.214:5000
/kevin_nginx
:latest swarm-node2 Running Running 16 seconds ago
9cuq2yf10d60 my-
test
.2 172.16.60.214:5000
/kevin_nginx
:latest swarm-manager-node Running Running 16 seconds ago
srt2yo817kpv my-
test
.3 172.16.60.214:5000
/kevin_nginx
:latest swarm-node1 Running Running 16 seconds ago
[root@swarm-manager-node ~]
# docker inspect ` docker service ps my-test -q` --format '{{range .NetworksAttachments}}{{.Addresses}}{{end}}' | cut -d '[' -f2|cut -d ']' -f1
10.255.0.7
/16
10.255.0.8
/16
10.255.0.9
/16
10) 獲取service示例的container ID (獲取的是ID的全稱,一般只要取ID前面12個字符就可以了)
[root@swarm-manager-node ~]
# docker inspect ` docker service ps my-test -q` --format '{{ .Status.ContainerStatus.ContainerID }}'
c6c18a74a465163757fe928fec9e633223200f92d1c59e5d2d77eabfaa5ae93a
5f558bb014ea3d3eef5c8d4bd70e2e3048d7fc6725538303be960ac658d93b32
dde578bf60190a63ed5c8c4a9f5a3044566a159e8debe8717342e263c6199f26
|