【实践原创】docker inspect --format 详解:Go 模板在 Docker 中的应用

Docker 的 inspect 命令用于查看容器、镜像、网络、卷等 Docker 对象的低级详细信息。默认输出为 JSON 格式,但通过 --format(或 -f)选项,可以使用 Go 模板(text/template)自定义输出格式。这使得我们能够精确提取所需字段、格式化输出,甚至进行条件判断和循环处理。

Go 模板的核心语法是 {``{ }},其中可以放置变量、函数、控制结构等。Docker 在标准 Go 模板基础上添加了一些自定义函数(如 jsonjoinsplit 等),以便更好地处理 JSON 数据。

1. 什么是模板?

模板的概念源于 MVC(Model-View-Controller)框架:Model 处理数据,View 负责展示,Controller 协调两者。

在 Docker 中,inspect 返回的 JSON 数据相当于 Model,而 --format 允许我们定义 View:将静态文本与动态数据结合,生成自定义输出。

例如,容器列表的表头(如 "CONTAINER ID"、"NAMES")是固定的,而具体值是动态的。通过模板,我们可以复用静态部分,只提取需要的动态字段,提高效率和可读性。

参考官方文档:Go 的 text/template 包提供了详细语法,Docker 在此基础上扩展。

2. Go 模板基本语法

  • 注释{``{/* 注释内容 */}}

    bash 复制代码
    docker network inspect --format='{{/* 查看容器的默认网关 */}}{{range .IPAM.Config}}{{.Gateway}}{{end}}' <network_id>
  • 当前对象.(点号)表示当前上下文对象,类似于 Java 中的 this

    bash 复制代码
    docker inspect --format '{{.State.Status}}' <container_id>  # 输出 running/exited 等

3. 变量

3.1 系统变量(. 和级联)

  • 使用 .Field 访问字段,支持级联:.Parent.Child.Grandchild

  • 如果字段名包含点号(.)或以数字开头,不能直接用 .Field,会解析错误。

    bash 复制代码
    # 错误示例
    docker inspect --format '{{.Options.com.docker.network.driver.mtu}}' bridge
    
    # 正确:使用 index 函数
    docker inspect --format '{{index .Options "com.docker.network.bridge.name"}}' bridge

示例:

bash 复制代码
docker inspect -f '{{.Id}}' <container>                  # 完整 ID
docker inspect -f '{{.State.Status}}' <container>        # 状态:running
docker inspect -f '{{"status:"}}{{.State.Status}}' <container>  # status:running

3.2 自定义变量

使用 $var := value 定义变量,可在后续使用。

bash 复制代码
docker inspect --format '已绑定端口列表:{{println}}{{range $p, $conf := .NetworkSettings.Ports}}{{$p}} -> {{(index $conf 0).HostPort}}{{println}}{{end}}' <container>

输出示例:

复制代码
已绑定端口列表:
80/tcp -> 32770
8081/tcp -> 8081

4. 遍历(range)

用于迭代数组、切片、map 或 channel。

bash 复制代码
{{range pipeline}} ... {{.}} {{end}}
{{range pipeline}} ... {{else}} ... {{end}}  # 无数据时执行 else

示例:

bash 复制代码
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container>  # 输出所有 IP
docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}}{{$p}} -> {{(index $conf 0).HostPort}}{{end}}' <container>
# 输出:9090/tcp -> 9090

5. index 函数

用于访问 map、slice、array 或 string 的元素(索引从 0 开始)。

bash 复制代码
docker inspect --format='{{(index (index .NetworkSettings.Ports "9090/tcp") 0).HostPort}}' <container>

6. 判断(if-else)

bash 复制代码
{{if pipeline}} ... {{end}}
{{if pipeline}} ... {{else}} ... {{end}}
{{if pipeline}} ... {{else if pipeline}} ... {{end}}

内置逻辑函数:

  • not:否定
  • and / or:逻辑与/或(or 返回第一个非空值)
  • 比较:eq(等于,支持多参数)、neltlegtge

示例:

bash 复制代码
docker inspect --format '{{if not .State.Restarting}}容器没有配置重启策略{{end}}' <container>
docker inspect --format '{{if ne 0 .State.ExitCode}}{{.Name}}{{else}}该容器还在运行{{end}}' $(docker ps -aq)

7. 打印函数

  • print:默认输出,多个参数间加空格
  • println:类似 print,但末尾换行(或直接 {``{println}} 换行)
  • printf:格式化输出,支持 %d%s 等占位符
bash 复制代码
docker inspect --format '{{printf "Pid:%d ExitCode:%d" .State.Pid .State.ExitCode}}' <container>
# 输出:Pid:24039 ExitCode:0

8. 管道(pipeline)和 Docker 扩展函数

管道类似于 shell 的 |,可链式调用函数。

Docker 扩展函数(官方文档:https://docs.docker.com/config/formatting/):

  • json:将结构体输出为 JSON(默认是 Go 风格 dump)

    bash 复制代码
    docker inspect --format '{{json .State}}' <container> | jq
  • join:连接切片元素

    bash 复制代码
    docker inspect --format '{{join .Config.Env "\n"}}' <container>
  • split:拆分字符串

  • upper / lower / title:大小写转换

  • truncate:截断字符串

  • pad:填充空格

其他命令如 docker ps 支持 table 指令打印表头:

bash 复制代码
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}\t{{.Status}}"

9. 高级示例

  • 输出容器所有环境变量:

    bash 复制代码
    docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' <container>
  • 自定义 JSON 输出(非标准,但可组合):

    bash 复制代码
    docker inspect --format "{ID:'{{.ID}}',Names:'{{.Names}}',Status:'{{.Status}}'}"
  • 查看可用字段:先用 {``{json .}} 输出完整结构

    bash 复制代码
    docker ps --format '{{json .}}'  # 查看 docker ps 的字段
    docker inspect --format '{{json .}}' <container>  # 查看 inspect 字段

总结

--format 是 Docker CLI 的强大工具,结合 Go 模板,能实现从简单字段提取到复杂格式化的各种需求。建议先用 {``{json .}} 探索数据结构,再逐步构建模板。

更多函数和示例参考 Docker 官方格式化文档:https://docs.docker.com/config/formatting/ 和 Go 模板文档。

通过这些技巧,你可以让 Docker 输出更简洁、更易脚本处理!

相关推荐
❀͜͡傀儡师2 小时前
基于docker一键部署 x86的cpu_mem_hog 用于生成CPU和内存负载,用于服务器cpu和内存使用不达标的
java·服务器·docker
qq_381454992 小时前
Go vs Java:极简主义与全能生态的终极对决
golang
星环处相逢2 小时前
Docker 场景化作业:生产环境容器操作实训
运维·docker·容器
bybitq2 小时前
Go-Package-Module-functions
开发语言·后端·golang
bs_1012 小时前
k8s工作运维中常用命令
运维·容器·kubernetes
Fortune_yangyang2 小时前
Docker 生产环境容器化
运维·docker·容器
虫小宝2 小时前
电商返利APP容器编排实践:K8s在多环境部署中的资源调度优化
云原生·容器·kubernetes
youxiao_902 小时前
Docker 容器(二)
运维·docker·容器
爱宇阳2 小时前
使用 Docker 容器备份 GitLab 实例教程
docker·容器·gitlab