Docker偷偷藏了个宝藏:Go模板引擎。这玩意儿比你想象的强大多了

image.png

所谓的良知,是被动一方的说辞。掌握主动权的一方,通常是不以良知而行动的。 ——摘自当年威尼斯外交官的报告”

Docker偷偷藏了个宝藏:Go模板引擎。这玩意儿比你想象的强大多了

介绍

如果您使用 Docker 已有一段时间,您可能已经输入过无数次 docker ps。但您知道这个简单的命令隐藏着许多高级功能,可以改变您查看和管理容器的方式吗?

在本指南中,我们将深入探讨 Docker 的格式化能力,探索 Go 模板语法,并发现实用技巧,使您成为 Docker 命令行的高手。

默认 docker ps 的问题

老实说,默认的 docker ps 输出可能会让人感到不知所措:

  • 列太多:大多数情况下,您并不需要所有信息
  • 数据被截断:重要细节被切掉
  • 可读性差:信息难以快速扫描
  • 缺乏自定义:一刀切的解决方案并不适合所有用例

但如果我告诉您,docker ps 可以完全自定义,以显示您所需的内容,正如您想要的那样呢?

理解 Go 模板语法

Docker 使用 Go 的强大模板引擎来格式化输出。以下是语法解析:

基本结构

docker ps --format "{{.FieldName}}"

结构解析:

  • {{}} - 模板分隔符
  • . - 指当前对象(容器)
  • FieldName - 您想要显示的属性

可用字段

Docker 容器暴露以下模板字段:

字段 描述 示例
{{.ID}} 容器 ID a1b2c3d4e5f6
{{.Names}} 容器名称 my-web-app
{{.Image}} Docker 镜像 nginx:latest
{{.Status}} 当前状态 运行中 2 小时
{{.Ports}} 端口映射 0.0.0.0:80->80/tcp
{{.Command}} 容器命令 nginx -g daemon off;
{{.CreatedAt}} 创建时间戳 2024-01-15 10:30:00
{{.RunningFor}} 运行时长 2 小时前
{{.Size}} 容器大小 1.2MB
{{.Labels}} 容器标签 version=1.0
{{.Mounts}} 卷挂载 my-volume

基本格式化技巧

1. 简单自定义列

只想要容器名称和状态?很简单:

docker ps --format "table {{.Names}}\t{{.Status}}"

输出:

NAMES                STATUS
web-server           运行中 2 小时
database             运行中 2 小时(健康)
redis-cache          运行中 1 小时

2. 添加表头

table 关键字会自动添加表头和适当的对齐:

docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"

为什么使用 table

  • 自动列头
  • 适当的文本对齐
  • 专业外观
  • 制表符分隔的列

3. 自定义分隔符

跳过表格格式以获得自定义布局:

docker ps --format "{{.Names}} -> {{.Status}} ({{.Image}})"

输出:

web-server -> 运行中 2 小时 (nginx:latest)
database -> 运行中 2 小时 (postgres:13)
redis-cache -> 运行中 1 小时 (redis:alpine)

强大的过滤选项

Docker 的过滤能力非常强大:

基于状态的过滤

# 仅运行中的容器
docker ps -f "status=running"

# 仅已停止的容器
docker ps -f "status=exited"

# 仅暂停的容器
docker ps -f "status=paused"

名称和镜像过滤

# 名称中包含 "web" 的容器
docker ps -f "name=web"

# 来自 nginx 镜像的容器
docker ps -f "ancestor=nginx"

# 暴露端口 80 的容器
docker ps -f "expose=80"

高级多过滤组合

# 名称中包含 "api" 的运行中容器,显示自定义格式
docker ps -f "status=running" -f "name=api" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"

# 来自特定镜像的所有容器,使用自定义输出
docker ps -a -f "ancestor=postgres" --format "{{.Names}} | 创建时间: {{.CreatedAt}}"

用于脚本的 JSON 输出

对于自动化和脚本,JSON 格式非常有价值:

docker ps --format json | jq '.[] | {name: .Names, status: .Status}'

这将输出干净的 JSON,可以通过 jqpython 或任何 JSON 解析器进行处理。

命令行标志深入分析

基本标志

标志 描述 示例
-a, --all 显示所有容器 docker ps -a
-q, --quiet 仅容器 ID docker ps -q
-s, --size 包括文件大小 docker ps -s
-n, --last 显示最后 N 个容器 docker ps -n 5
-l, --latest 显示最新容器 docker ps -l
--no-trunc 不截断输出 docker ps --no-trunc

实用标志组合

# 获取所有运行中容器的 ID
docker ps -q

# 使用自定义格式显示文件大小
docker ps -s --format "table {{.Names}}\t{{.Size}}\t{{.Status}}"

# 显示最后 3 个容器的完整详细信息
docker ps -n 3 --no-trunc

真实世界的用例

1. 容器健康仪表板

创建健康监控视图:

docker ps --format "table {{.Names}}\t{{.Status}}\t{{if .Ports}}{{.Ports}}{{else}}内部{{end}}" | grep -E "(健康|不健康|启动中)"

2. 端口映射概览

快速检查端口映射:

docker ps --format "table {{.Names}}\t{{.Ports}}" | grep -v "^NAMES"

3. 资源使用摘要

监控容器大小:

docker ps -s --format "table {{.Names}}\t{{.Size}}\t{{.Status}}"

4. 开发环境状态

非常适合检查您的开发栈:

docker ps -f "name=dev-" --format "{{.Names}} | {{.Status}} | {{if .Ports}}✅ 可访问{{else}}❌ 内部{{end}}"

Shell 集成和别名

将这些命令作为您日常工作流的一部分:

Bash/Zsh 别名

添加到您的 ~/.bashrc~/.zshrc

# 基本别名
alias dps='docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"'
alias dpsa='docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"'
alias dpsq='docker ps -q'
alias dpsh='docker ps --format "table {{.Names}}\t{{.Status}}" | grep 健康'

# 高级别名
alias docker-health='docker ps --format "table {{.Names}}\t{{.Status}}" | grep -E "(健康|不健康)"'
alias docker-ports='docker ps --format "table {{.Names}}\t{{.Ports}}" | grep -v "^NAMES"'
alias docker-sizes='docker ps -s --format "table {{.Names}}\t{{.Size}}\t{{.Status}}"'

Shell 函数

用于更复杂的操作:

# 按镜像显示容器的函数
docker-by-image() {
    docker ps -f "ancestor=$1" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
}

# 显示容器资源使用情况的函数
docker-resources() {
    docker ps -s --format "table {{.Names}}\t{{.Size}}\t{{.Status}}" | head -${1:-10}
}

故障排除和提示

常见模板错误

  1. 缺少点:始终使用 .FieldName,而不是 FieldName
  2. 区分大小写:字段名称区分大小写({{.Names}},而不是 {{.names}}
  3. 转义引号:在模板中使用 \" 表示字面引号
  4. 制表符:使用 \t 进行适当的列分隔

性能考虑

  • 当您只需要容器 ID 时,使用 -q 标志
  • 组合过滤器以减少输出处理
  • 在容器数量较多的系统上谨慎使用 --no-trunc

跨平台兼容性

这些格式化技术在以下平台上工作相同:

  • Linux
  • macOS
  • Windows(使用 Docker Desktop)
  • WSL2

超越 Docker PS

相同的格式化技术也适用于其他 Docker 命令:

# 使用自定义格式的 Docker 镜像
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"

# Docker 网络
docker network ls --format "table {{.Name}}\t{{.Driver}}\t{{.Scope}}"

# Docker 卷
docker volume ls --format "table {{.Name}}\t{{.Driver}}\t{{.Mountpoint}}"

结论

掌握 docker ps 格式化将一个基本的列出命令转变为一个强大的容器管理工具。通过 Go 模板,您可以:

  • 自定义输出,显示您所需的内容
  • 精确过滤容器
  • 创建可重用的别名,用于常见操作
  • 与 shell 脚本和自动化无缝集成

本指南中涵盖的技术将为您节省时间,减少认知负担,使您的 Docker 工作流程更加高效。从简单的自定义格式开始,逐渐将高级功能纳入您的工作中,直到您对语法感到舒适。

记住:目标不是记住每个模板函数,而是理解模式,以便您可以为每种情况制作完美的视图。

快速参考卡

# 基本格式
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
docker ps --format "{{.Names}}: {{.Status}}"
docker ps --format json

# 有用的过滤器
docker ps -f "status=running"
docker ps -f "name=web"
docker ps -f "ancestor=nginx"

# 实用标志
docker ps -q              # 仅 ID
docker ps -a              # 所有容器
docker ps -s              # 包括大小
docker ps --no-trunc      # 完整输出

今天就开始尝试这些技术,看看您的 Docker 生产力如何提升!


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容