关于 Stern
Stern 是用于 Kubernetes 的日志查看命令行工具,命令为 stern。可按名称筛选并同时输出多个 Pod 的日志,适合放进脚本和重复执行的运维流程。
主要功能
- 01用 stern api 跟踪名称匹配的 Pod 日志
- 02用 --since 10m 限定查看最近十分钟
- 03命令便于自动化调用
- 04可重复执行的运维工作流
适用场景
- 01排查服务故障时同时查看多个副本的日志
- 02发布后查看最近一段时间的输出
- 03编码 Agent 在脚本中自动收集集群日志
安装
选择你的系统或包管理器,复制命令到终端运行。
安装完成后运行stern --version确认安装成功。
命令示例
常用命令按使用顺序排列。
详细介绍
stern
已停止维护的 wercker/stern 的分支
Stern 可让你在 Kubernetes 上同时 tail 多个 Pod,以及 Pod 中的多个容器。每个结果都会以不同颜色显示,便于快速调试。
查询可以是正则表达式,也可以是 <resource>/<name> 格式的 Kubernetes 资源,这样可以轻松筛选 Pod 名称,而无需指定确切的 ID(例如可以省略 deployment ID)。如果某个 Pod 被删除,它会从 tail 中移除;如果新增 Pod,它会自动开始 tail。
当一个 Pod 包含多个容器时,Stern 也可以同时 tail 所有容器,无需逐个手动操作。只需指定 container 标志即可限制要显示的容器。默认情况下会监听所有容器。
安装
下载二进制文件
下载二进制发行版
从源代码构建
go install github.com/stern/stern@latest
asdf(Linux/macOS)
如果你使用 asdf,可以按如下方式安装:
asdf plugin add stern
asdf install stern latest
Homebrew(Linux/macOS)
如果你使用 Homebrew,可以按如下方式安装:
brew install stern
Krew(Linux/macOS/Windows)
如果你使用 Krew(kubectl 插件的包管理器),可以按如下方式安装:
kubectl krew install stern
WinGet(Windows)
如果你在 Windows 上运行,通常最好使用 WinGet 安装。它是 Windows 内置的包管理器,可以按如下方式安装:
winget install stern.stern
用法
stern pod-query [flags]
pod-query 可以是正则表达式,也可以是 <resource>/<name> 格式的 Kubernetes 资源。
如果查询不是 Kubernetes 资源,则会被视为正则表达式,因此你可以提供 "web-\w",以 tail web-backend 和 web-frontend Pod,但不匹配 web-123。
如果查询采用 <resource>/<name> 格式(精确匹配),则可以选择属于指定 Kubernetes 资源的所有 Pod,例如 deployment/nginx。
支持的 Kubernetes 资源包括 pod、replicationcontroller、service、daemonset、deployment、replicaset、statefulset 和 job。
命令行标志
| flag | default | purpose |
|---|---|---|
--all-namespaces, -A | false | 如果指定,则跨所有命名空间跟踪日志。即使指定了 --namespace,也会忽略特定命名空间。 |
--burst | 0 | 对 Kubernetes API 服务端进行限流时允许的最大突发请求数。默认为 0(使用 client-go 默认值)。当 --qps=-1 时忽略。 |
--color | auto | 强制设置彩色输出。'auto':连接到 tty 时使用颜色;'always':始终使用颜色;'never':从不使用颜色。 |
--completion | 输出指定 shell 的 stern 命令行补全代码。可以是 'bash'、'zsh' 或 'fish'。 | |
--condition | 要筛选的条件:[condition-name[=condition-value]。默认 condition-value 为 true。匹配时不区分大小写。目前仅支持与 --tail=0 或 --no-follow 一起使用。 | |
--config | ~/.config/stern/config.yaml | stern 配置文件的路径 |
--container, -c | .* | Pod 中有多个容器时使用的容器名称。(正则表达式) |
--container-colors | 指定用于突出显示容器名称的颜色。使用与 --pod-colors 相同的格式。若省略,则默认为 --pod-colors 的值,且长度必须与其一致。 | |
--container-state | all | 跟踪状态为 running、waiting、terminated 或 all 的容器。'all' 匹配所有容器状态。要指定多个状态,请重复此选项或设置逗号分隔的值。 |
--context | 要使用的 kubeconfig 上下文名称 | |
--diff-container, -d | false | 为不同容器显示不同颜色。 |
--ephemeral-containers | true | 包含或排除临时容器。 |
--exclude, -e | [] | 要排除的日志行。(正则表达式) |
--exclude-container, -E | [] | Pod 中有多个容器时要排除的容器名称。(正则表达式) |
--exclude-pod | [] | 要排除的 Pod 名称。(正则表达式) |
--field-selector | 要筛选的选择器(字段查询)。如果指定,则 pod-query 默认为 ".*"。 | |
--highlight, -H | [] | 要突出显示的日志行。(正则表达式) |
--include, -i | [] | 要包含的日志行。(正则表达式) |
--init-containers | true | 包含或排除初始化容器。 |
--kubeconfig | CLI 请求所用 kubeconfig 文件的路径。 | |
--max-log-requests | -1 | 要请求的最大并发日志数。默认为 50;指定 --no-follow 时为 5 |
--namespace, -n | 要使用的 Kubernetes 命名空间。默认为 Kubernetes 上下文中配置的命名空间。要指定多个命名空间,请重复此选项或设置逗号分隔的值。 | |
--no-follow | false | 显示完所有日志后退出。 |
--node | 要筛选的节点名称。 | |
--only-log-lines | false | 仅打印日志行 |
--output, -o | default | 指定预定义模板。目前支持:[default, raw, json, extjson, ppextjson] |
--pager | 将 stern 的输出通过管道传递给的命令(例如 'less')。仅当标准输出是终端时使用;不指定 --color=always 也会保留颜色。 | |
--pod-colors | 指定用于突出显示 Pod 名称的颜色。使用逗号分隔的列表提供颜色,格式为 SGR(选择图形再现)序列,例如 "91,92,93,94,95,96"。 | |
--prompt, -p | false | 切换用于选择 'app.kubernetes.io/instance' 标签值的交互式提示。 |
--qps | 0 | Kubernetes API 服务端允许的最大 QPS。默认为 0(使用 client-go 默认值)。使用 -1 可禁用客户端限流。 |
--selector, -l | 要筛选的选择器(标签查询)。如果指定,则 pod-query 默认为 ".*"。 | |
--show-hidden-options | false | 打印隐藏选项列表。 |
--since, -s | 48h0m0s | 返回相对时长以内的较新日志,例如 5s、2m 或 3h。 |
--stdin | false | 从 stdin 解析日志。启用后会忽略所有与 Kubernetes 相关的标志。 |
--tail | -1 | 要显示的日志末尾行数。默认为 -1,即显示所有日志。 |
--template | 用于日志行的模板;留空则使用 --output 标志。 | |
--template-file, -T | 用于日志行的模板文件路径;留空则使用 --output 标志。此选项会覆盖 --template 选项。 | |
--timestamps, -t | 按指定格式打印时间戳。格式可以是 'default' 或 'short',形式为 '--timestamps=format'(不能省略 '=')。如果指定但未提供值,则使用 'default'。 | |
--timezone | Local | 将时间戳设置为指定时区。 |
--verbosity | 0 | 日志级别的详细程度 |
--version, -v | false | 打印版本并退出。 |
详情请参阅 stern --help |
如果设置了 $KUBECONFIG 环境变量,Stern 将使用该变量。如果同时传入环境变量和 --kubeconfig 标志,则会使用命令行标志。
配置文件
你可以使用配置文件更改 stern 选项的默认值。默认配置文件路径为 ~/.config/stern/config.yaml。
# <flag name>: <value>
tail: 10
max-log-requests: 999
timestamps: short
你可以通过 --config 标志或 STERNCONFIG 环境变量更改配置文件路径。
模板
stern 支持输出自定义日志消息。你可以通过指定 --output 标志使用几个预定义模板:
| 输出 | 说明 |
|---|---|
default | 显示命名空间、Pod 和容器,并根据 --color 为其添加颜色 |
raw | 仅输出日志消息本身;当日志为 json 且你想将其传递给 jq 时很有用 |
json | 将日志结构体编组为 json。适用于编程用途 |
extjson | 输出扩展 JSON,并为 Pod/容器名称添加颜色 |
ppextjson | 美化输出扩展 JSON,并为 Pod/容器名称添加颜色 |
它接受通过 --template 标志传入的自定义模板,并将其编译为 Go 模板,然后用于每条日志消息。此 Go 模板将接收以下结构体:
| 属性 | 类型 | 说明 |
|---|---|---|
Message | string | 日志消息本身 |
Timestamp | string | 按 --timestamps/--timezone 格式化的日志时间戳;除非设置了 --timestamps,否则为空 |
NodeName | string | Pod 所调度到的节点名称 |
Namespace | string | Pod 的命名空间 |
PodName | string | Pod 的名称 |
ContainerName | string | 容器的名称 |
Labels | map[string]string | Pod 的标签 |
Annotations | map[string]string | Pod 的注解 |
模板中还提供以下函数(内置函数除外):
| func | arguments | description |
|---|---|---|
json | object | 将对象编组并以 JSON 文本形式输出 |
color | color.Color, string | 为文本添加颜色(提供了 .ContainerColor 和 .PodColor) |
parseJSON | string | 将字符串解析为 JSON |
tryParseJSON | string | 尝试将字符串解析为 JSON,失败时返回 nil |
extractJSONParts | string, ...string | 将字符串解析为 JSON,并拼接指定的键。键可以使用点号表示法(例如 python.levelname)访问嵌套字段。 |
tryExtractJSONParts | string, ...string | 尝试将字符串解析为 JSON,并拼接指定的键(点号表示法可访问嵌套字段);失败时返回文本。 |
prettyJSON | any | 解析输入并将其格式化为易读的 JSON 输出;如果解析失败,则按原样输出字符串。 |
toRFC3339Nano | object | 解析时间戳(字符串、整数、json.Number),并按 RFC3339Nano 格式输出 |
toUTC | object | 解析时间戳(字符串、整数、json.Number),并将其作为 UTC time.Time 返回 |
toTimestamp | object, string [, string] | 解析时间戳(字符串、整数、json.Number),并按给定布局输出,使用可选指定的时区(默认为 UTC)。 |
levelColor | string | 使用适当的颜色打印日志级别 |
bunyanLevelColor | string | 使用适当的颜色打印 bunyan 数字日志级别 |
colorBlack | string | 使用黑色打印文本 |
colorRed | string | 使用红色打印文本 |
colorGreen | string | 使用绿色打印文本 |
colorYellow | string | 使用黄色打印文本 |
colorBlue | string | 使用蓝色打印文本 |
colorMagenta | string | 使用洋红色打印文本 |
colorCyan | string | 使用青色打印文本 |
colorWhite | string | 使用白色打印文本 |
colorCustom | string, int [, int] | 使用自定义颜色打印文本,例如,{{colorCustom "Hi" 3 96}} 会将 "Hi" 以斜体和青色打印 |
日志级别详细程度
你可以通过 --verbosity 标志配置日志级别的详细程度。
排查问题时,如果想了解 stern 与 Kubernetes API 服务器的交互情况,这会很有帮助。
提高详细程度会增加日志数量。建议从 --verbosity 6 开始。
最大日志请求数
Stern 限制并发日志请求数,以防止对集群造成意外负载。
可以通过 --max-log-requests 标志配置此数量。
根据是否指定 --no-follow 标志,行为和默认值会有所不同。
--no-follow | 默认值 | 行为 |
|---|---|---|
| 已指定 | 5 | 限制并发日志请求数 |
| 未指定 | 50 | 达到并发上限时退出并报错 |
如果想按顺序显示日志,将 --max-log-requests 1 与 --no-follow 组合使用会很有帮助。
自定义高亮颜色
你可以在配置文件中使用逗号分隔的 SGR(选择图形再现)序列配置 Pod 和容器的高亮颜色,如下所示。如果省略 container-colors,容器也会使用 Pod 的颜色。
只要列表中还有未使用的颜色,stern 就会从列表中选取颜色,使同一工作负载(例如 Deployment 或 StatefulSet 的副本)创建的 Pod 使用不同的颜色。
# Green, Yellow, Blue, Magenta, Cyan, White
pod-colors: "32,33,34,35,36,37"
# Colors with underline (4)
# If empty, the pod colors will be used as container colors
container-colors: "32;4,33;4,34;4,35;4,36;4,37;4"
如果你的终端支持,这种格式还可以使用各种属性,例如下划线、背景色、8 位颜色和 24 位颜色。
也可以使用对应的标志 --pod-colors 和 --container-colors。以下命令通过 --pod-colors 标志应用 24 位颜色。
# Monokai theme
podColors="38;2;255;97;136,38;2;169;220;118,38;2;255;216;102,38;2;120;220;232,38;2;171;157;242"
stern --pod-colors "$podColors" deploy/app
使用分页器
你可以通过 --pager 标志将 stern 的输出传递给分页器。与在 Shell 中使用管道(stern --color=always backend | less -R)不同,无需额外标志即可保留颜色,并且退出分页器时 stern 会停止追踪日志。
stern --pager less backend
只有标准输出是终端时才会使用分页器。如果你始终想使用分页器,请在配置文件中进行设置:
pager: less
除非已设置 LESS=FRX 和 LV=-c 环境变量,否则 stern 会在运行分页器时设置这些变量,以便 less 和 lv 开箱即用地显示颜色。
示例:
跟踪所有命名空间中的所有日志
stern . --all-namespaces
跟踪 kube-system 命名空间,不打印之前的任何日志
stern . -n kube-system --tail 0
跟踪 staging 上 envvars Pod 内运行的 gateway 容器
stern envvars --context staging --container gateway
跟踪 staging 命名空间,但排除 istio-proxy 容器的日志
stern -n staging --exclude-container istio-proxy .
跟踪 kube-system 命名空间,但排除 kube-apiserver Pod
stern -n kube-system --exclude-pod kube-apiserver .
显示 15 分钟前的身份验证活动,并附带时间戳
stern auth -t --since 15m
按时间显示最近 5 分钟的所有日志,并按时间排序
stern --since=5m --no-follow --only-log-lines -A -t . | sort -k4
显示身份验证活动,并附带指定时区的时间戳(默认为本地时区)
stern auth -t --timezone Asia/Tokyo
在 minikube 中跟进 some-new-feature 的开发
stern some-new-feature --context minikube
查看另一个命名空间中的 Pod
stern kubernetes-dashboard --namespace kube-system
在所有命名空间中跟踪由 run=nginx 标签选择器筛选出的 Pod
stern --all-namespaces -l run=nginx
跟踪 canary 发布中的 frontend Pod
stern frontend --selector release=canary
在所有命名空间中跟踪 kind-control-plane 节点上的 Pod
stern --all-namespaces --field-selector spec.nodeName=kind-control-plane
跟踪由 deployment/nginx 创建的 Pod
stern deployment/nginx
将日志消息传递给 jq:
stern backend -o json | jq .
仅输出日志消息本身:
stern backend -o raw
使用自定义模板输出:
stern --template '{{printf "%s (%s/%s/%s/%s)\n" .Message .NodeName .Namespace .PodName .ContainerName}}' backend
使用 stern 提供的颜色和自定义模板输出:
stern --template '{{.Message}} ({{.Namespace}}/{{color .PodColor .PodName}}/{{color .ContainerColor .ContainerName}}){{"\n"}}' backend
使用带有 parseJSON 的自定义模板输出:
stern --template='{{.PodName}}/{{.ContainerName}} {{with $d := .Message | parseJSON}}[{{$d.level}}] {{$d.message}}{{end}}{{"\n"}}' backend
使用尝试解析 JSON、否则回退到原始格式的自定义模板输出:
stern --template='{{.PodName}}/{{.ContainerName}} {{ with $msg := .Message | tryParseJSON }}[{{ colorGreen (toRFC3339Nano $msg.ts) }}] {{ levelColor $msg.level }} ({{ colorCyan $msg.caller }}) {{ $msg.msg }}{{ else }} {{ .Message }} {{ end }}{{"\n"}}' backend
美化输出 JSON(如果日志为 JSON):
# Will try to parse .Message as JSON and pretty print it, if not json will output as is
stern --template='{{ .Message | prettyJSON }}{{"\n"}}' backend
# Or with parsed json, will drop non-json logs because of `with`
stern --template='{{ with $msg := .Message | tryParseJSON }}{{ prettyJSON $msg }}{{"\n"}}{{end}}' backend
提取 JSON 字段,包括通过点号表示法提取嵌套字段:
# Given a message like {"python": {"levelname": "INFO", "module": "router"}}
stern --template='{{ levelColor (extractJSONParts .Message "python.levelname") }} {{ extractJSONParts .Message "python.module" }}{{"\n"}}' backend
从文件加载自定义模板:
stern --template-file=~/.stern.tpl backend
触发交互式提示,选择一个 'app.kubernetes.io/instance' 标签值:
stern -p
仅输出日志行:
stern . --only-log-lines
从标准输入读取:
stern --stdin < service.log
仅显示未就绪 Pod 的日志:
stern . --condition=ready=false --tail=0
自动补全
Stern 支持 bash、zsh 或 fish 的命令行自动补全。stern --completion=(bash|zsh|fish) 会输出 shell 补全代码;将其在指定 shell 的
.bashrc 等文件中求值即可生效。此外,Stern
还支持对 --namespace、--context、--node、形式为 <resource>/<name> 的资源查询,以及具有预定义选项的标志进行动态补全。
如果使用 bash,stern 的 bash 补全代码依赖于 bash-completion。在 macOS 上,可以 通过 homebrew 按如下方式安装:
# If running Bash 3.2
brew install bash-completion
# or, if running Bash 4.1+
brew install bash-completion@2
请注意,必须先在 .bashrc 中加载 bash-completion,再加载 stern 的 bash
补全代码。
source "$(brew --prefix)/etc/profile.d/bash_completion.sh"
source <(stern --completion=bash)
如果通过 Krew 安装,请使用:
source <(kubectl stern --completion bash)
complete -o default -F __start_stern kubectl stern
如果使用 zsh,只需在 .zshrc 中加载 stern 的 zsh 补全代码。
source <(stern --completion=zsh)
如果使用 fish shell,只需加载 stern 的 fish 补全代码。
stern --completion=fish | source
# To load completions for each session, execute once:
stern --completion=fish >~/.config/fish/completions/stern.fish
使用容器运行
你也可以通过容器使用 stern:
docker run ghcr.io/stern/stern --version
如果使用 minikube 集群,需要按如下方式运行容器:
docker run --rm -v "$HOME/.minikube:$HOME/.minikube" -v "$HOME/.kube:/$HOME/.kube" -e KUBECONFIG="$HOME/.kube/config" ghcr.io/stern/stern .
你可以在 https://github.com/orgs/stern/packages/container/package/stern 查找镜像标签。
在 Kubernetes Pod 中运行
如果要在 Kubernetes Pod 中使用 stern,需要创建以下 ClusterRole,并将其绑定到 ServiceAccount。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: stern
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "watch", "list"]
为此仓库贡献代码
详情请参阅 CONTRIBUTING。