mcpField
S
Stern

Stern

官方Agent-ready
github.com云与 DevOps4.9kstern3 天前更新
代码仓库访问官网

关于 Stern

Stern 是用于 Kubernetes 的日志查看命令行工具,命令为 stern。可按名称筛选并同时输出多个 Pod 的日志,适合放进脚本和重复执行的运维流程。

主要功能

  1. 01用 stern api 跟踪名称匹配的 Pod 日志
  2. 02用 --since 10m 限定查看最近十分钟
  3. 03命令便于自动化调用
  4. 04可重复执行的运维工作流

适用场景

  1. 01排查服务故障时同时查看多个副本的日志
  2. 02发布后查看最近一段时间的输出
  3. 03编码 Agent 在脚本中自动收集集群日志

安装

选择你的系统或包管理器,复制命令到终端运行。

$
brew install stern

安装完成后运行stern --version确认安装成功。

命令示例

常用命令按使用顺序排列。

01
stern api
02
stern api --since 10m

详细介绍

Build

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。

命令行标志
flagdefaultpurpose
--all-namespaces, -Afalse如果指定,则跨所有命名空间跟踪日志。即使指定了 --namespace,也会忽略特定命名空间。
--burst0对 Kubernetes API 服务端进行限流时允许的最大突发请求数。默认为 0(使用 client-go 默认值)。当 --qps=-1 时忽略。
--colorauto强制设置彩色输出。'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.yamlstern 配置文件的路径
--container, -c.*Pod 中有多个容器时使用的容器名称。(正则表达式)
--container-colors指定用于突出显示容器名称的颜色。使用与 --pod-colors 相同的格式。若省略,则默认为 --pod-colors 的值,且长度必须与其一致。
--container-stateall跟踪状态为 running、waiting、terminated 或 all 的容器。'all' 匹配所有容器状态。要指定多个状态,请重复此选项或设置逗号分隔的值。
--context要使用的 kubeconfig 上下文名称
--diff-container, -dfalse为不同容器显示不同颜色。
--ephemeral-containerstrue包含或排除临时容器。
--exclude, -e[]要排除的日志行。(正则表达式)
--exclude-container, -E[]Pod 中有多个容器时要排除的容器名称。(正则表达式)
--exclude-pod[]要排除的 Pod 名称。(正则表达式)
--field-selector要筛选的选择器(字段查询)。如果指定,则 pod-query 默认为 ".*"。
--highlight, -H[]要突出显示的日志行。(正则表达式)
--include, -i[]要包含的日志行。(正则表达式)
--init-containerstrue包含或排除初始化容器。
--kubeconfigCLI 请求所用 kubeconfig 文件的路径。
--max-log-requests-1要请求的最大并发日志数。默认为 50;指定 --no-follow 时为 5
--namespace, -n要使用的 Kubernetes 命名空间。默认为 Kubernetes 上下文中配置的命名空间。要指定多个命名空间,请重复此选项或设置逗号分隔的值。
--no-followfalse显示完所有日志后退出。
--node要筛选的节点名称。
--only-log-linesfalse仅打印日志行
--output, -odefault指定预定义模板。目前支持:[default, raw, json, extjson, ppextjson]
--pager将 stern 的输出通过管道传递给的命令(例如 'less')。仅当标准输出是终端时使用;不指定 --color=always 也会保留颜色。
--pod-colors指定用于突出显示 Pod 名称的颜色。使用逗号分隔的列表提供颜色,格式为 SGR(选择图形再现)序列,例如 "91,92,93,94,95,96"。
--prompt, -pfalse切换用于选择 'app.kubernetes.io/instance' 标签值的交互式提示。
--qps0Kubernetes API 服务端允许的最大 QPS。默认为 0(使用 client-go 默认值)。使用 -1 可禁用客户端限流。
--selector, -l要筛选的选择器(标签查询)。如果指定,则 pod-query 默认为 ".*"。
--show-hidden-optionsfalse打印隐藏选项列表。
--since, -s48h0m0s返回相对时长以内的较新日志,例如 5s、2m 或 3h。
--stdinfalse从 stdin 解析日志。启用后会忽略所有与 Kubernetes 相关的标志。
--tail-1要显示的日志末尾行数。默认为 -1,即显示所有日志。
--template用于日志行的模板;留空则使用 --output 标志。
--template-file, -T用于日志行的模板文件路径;留空则使用 --output 标志。此选项会覆盖 --template 选项。
--timestamps, -t按指定格式打印时间戳。格式可以是 'default' 或 'short',形式为 '--timestamps=format'(不能省略 '=')。如果指定但未提供值,则使用 'default'。
--timezoneLocal将时间戳设置为指定时区。
--verbosity0日志级别的详细程度
--version, -vfalse打印版本并退出。
详情请参阅 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 模板将接收以下结构体:

属性类型说明
Messagestring日志消息本身
Timestampstring按 --timestamps/--timezone 格式化的日志时间戳;除非设置了 --timestamps,否则为空
NodeNamestringPod 所调度到的节点名称
NamespacestringPod 的命名空间
PodNamestringPod 的名称
ContainerNamestring容器的名称
Labelsmap[string]stringPod 的标签
Annotationsmap[string]stringPod 的注解

模板中还提供以下函数(内置函数除外):

funcargumentsdescription
jsonobject将对象编组并以 JSON 文本形式输出
colorcolor.Color, string为文本添加颜色(提供了 .ContainerColor 和 .PodColor)
parseJSONstring将字符串解析为 JSON
tryParseJSONstring尝试将字符串解析为 JSON,失败时返回 nil
extractJSONPartsstring, ...string将字符串解析为 JSON,并拼接指定的键。键可以使用点号表示法(例如 python.levelname)访问嵌套字段。
tryExtractJSONPartsstring, ...string尝试将字符串解析为 JSON,并拼接指定的键(点号表示法可访问嵌套字段);失败时返回文本。
prettyJSONany解析输入并将其格式化为易读的 JSON 输出;如果解析失败,则按原样输出字符串。
toRFC3339Nanoobject解析时间戳(字符串、整数、json.Number),并按 RFC3339Nano 格式输出
toUTCobject解析时间戳(字符串、整数、json.Number),并将其作为 UTC time.Time 返回
toTimestampobject, string [, string]解析时间戳(字符串、整数、json.Number),并按给定布局输出,使用可选指定的时区(默认为 UTC)。
levelColorstring使用适当的颜色打印日志级别
bunyanLevelColorstring使用适当的颜色打印 bunyan 数字日志级别
colorBlackstring使用黑色打印文本
colorRedstring使用红色打印文本
colorGreenstring使用绿色打印文本
colorYellowstring使用黄色打印文本
colorBluestring使用蓝色打印文本
colorMagentastring使用洋红色打印文本
colorCyanstring使用青色打印文本
colorWhitestring使用白色打印文本
colorCustomstring, 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。

评论

支持 Markdown