Fantastic Docker Inspect template

docker inspect

Simply put,  the argument to -f  is a Go template

Let's take a closer look at the magic of Go templates. For example, we can use templates to find all container names with non-zero exit codes:

$ docker inspect -f '{{if ne 0.0 .State.ExitCode }}{{.Name}} {{.State.ExitCode}}{{ end }}' $(docker ps -aq)

/tender_colden 1
/clever_mcclintock 126

/grave_bartik 1

(Whether there is a match or not, one line will be output for each container)

Or  find the directory of the volume /var/jenkins_home  corresponding to the host in the jenkins-data  container   :

docker inspect -f '{{index .Volumes "/var/jenkins_home"}}' jenkins-data
/var/lib/docker/vfs/dir/5a6f7b306b96af38723fc4d31def1cc515a0d75c785f3462482f60b730533b1a

The above example may be a little difficult to understand, but that's okay, let's first understand the basic usage of Go templates.

Template directive

The {{ }} syntax is used to process template directives, and any characters outside the curly braces will be output directly.

context

"." means "current context". In most cases the entire data structure of the container metadata is represented, but in some cases the context can be redefined, such as using the  with  function:

$ docker inspect -f '{{.State.Pid}}' jenkins
6331
$ docker inspect -f '{{with .State}} {{.Pid}} {{end}}' jenkins
6331

You can use  $  to get the root context, for example:

$ docker inspect -f '{{with .State}} {{$.Name}} has pid {{.Pid}} {{end}}' jenkins
 /jenkins has pid 6331

Note that using "." by itself is fine, and will output the full metadata unformatted:

$ docker inspect -f '{{.}}' jenkins
...

type of data

The inspect data can consist of floats, strings, and booleans, and can be compared using Go template built-in functions. Although Go templates support integers, currently the numeric types in inspect data are floats, and integers should be more convenient for most scenarios (see this  Issue for details  ). Double quotes can be used when working with strings.

Values ​​that do not exist in the data cannot be compared:

$ docker inspect -f '{{.ExecIDs}}' jenkins
<no value>
$ docker inspect -f '{{eq .ExecIDs .ExecIDs}}' jenkins
FATA[0000] template: :1:2: executing "" at <eq .ExecIDs .ExecIDs>: error calling eq: invalid type for comparison

data structure

The inspect data is stored using maps and arrays. The map structure is very simple. As we have shown earlier, the internal data of the map can be accessed through the chain of .:

$ docker inspect -f '{{.State.ExitCode}}' jenkins
0

不过有些情况(比如 map 的键不是字符串)是不能直接使用 . 方式来获取 map 值的,此时我们可以使用 index 函数,前面卷的例子可以这样写:

docker inspect -f '{{index .Volumes "/var/jenkins_home"}}' jenkins-data
/var/lib/docker/vfs/dir/5a6f7b306b96af38723fc4d31def1cc515a0d75c785f3462482f60b730533b1a

我们也可以使用  index 来获取指定下标的数组值:

$ docker inspect -f '{{.HostConfig.Binds}}' jenkins
[/var/run/docker.sock:/var/run/docker.sock /usr/bin/docker:/usr/bin/docker]
$ docker inspect -f '{{index .HostConfig.Binds 1}}' jenkins
/usr/bin/docker:/usr/bin/docker

函数

除了 index 函数,其他很多函数也很常用。比如逻辑函数 and 、 or 可以返回布尔结果。注意,函数是不能放在中间:

$ docker inspect -f '{{and true true}}' jenkins
true

而不是:

$ docker inspect -f '{{true and true}}' jenkins
FATA[0000] template: :1:2: executing "" at <true>: can't give argument to non-function true

下面是一些常用的比较函数:

  • eq (等于)
  • ne (不等于)
  • lt (小于)
  • le (小于等于)
  • gt (大于)
  • ge (大于等于)

我们可以用这些函数来比较字符串、浮点数或整数:

$ docker inspect -f '{{eq "abc" "abc"}}' jenkins
true
$ docker inspect -f '{{ge 1 -1}}' jenkins
true
$ docker inspect -f '{{lt 4.5 4.6}}' jenkins
true
$ docker inspect -f '{{ne 4.5 4.5}}' jenkins
false

要注意的是操作数类型必须匹配,数字比较时使用浮点数:

$ docker inspect -f '{{eq "4.5" 4.5}}' jenkins
FATA[0000] template: :1:2: executing "" at <eq "4.5" 4.5>: error calling eq: incompatible types for comparison
$ docker inspect -f '{{gt .State.Pid 1}}' jenkins
FATA[0000] template: :1:2: executing "" at <gt .State.Pid 1>: error calling gt: incompatible types for comparison 
$ docker inspect -f '{{gt .State.Pid 1.0}}' jenkins
true

另外,可以使用 json 函数来生成 JSON 输出:

$ docker inspect -f '{{json .NetworkSettings.Ports}}' jenkins
{"50000/tcp":null,"8080/tcp":[{"HostIp":"0.0.0.0","HostPort":"8080"}]}

我们也可以使用 jq 工具来组合结果:

$ docker inspect -f '{{json .State}}' jenkins-data | jq '.StartedAt'
"2015-03-15T20:26:30.526796706Z"

当然, docker inspect 的默认输出结果就是 JSON,所以下面这样也可以:

$ docker inspect jenkins-data | jq '.[] | .State.StartedAt'
"2015-03-15T20:26:30.526796706Z"

更多函数请参考 Go 官方文档 ,不过很奇怪的是官方文档中并没有描述 json 函数(我是从 Nathan LeClaire’s blog 中学到的),你如果知道其中原因,记得告诉我!

If 语句

条件语句 if 可以和前面的比较函数一起使用:

$ docker inspect -f '{{if eq .State.ExitCode 0.0}} 
Normal Exit
{{else if eq .State.ExitCode 1.0}} 
Not a Normal Exit 
{{else}} 
Still Not a Normal Exit 
{{end}}' jenkins

Normal Exit

注意, {{end}} 语句必须有, else if 和 else 按需使用。

结论

我想本文应该涵盖了 docker inspect -f 使用模版时的大部分内容,不过另外还有一些很常用的特性,比如使用  range 来迭代数据、自定义函数、使用管道等需要你来自己摸索实践。

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326561648&siteId=291194637