尾巴Kubernetes与船尾

编者注:今天的帖子是Wercker的软件工程师Antti Kupila撰写的,内容涉及在Kubernetes上构建可拖尾多个Pod和容器的工具。

我们在这里喜欢Kubernetes 维尔克 并在此基础上构建我们的所有基础架构。部署任何东西时,您需要对正在发生的事情有良好的可见性,并且日志是您应用程序内部工作的第一个视图。好的老尾巴-f已经存在了很长时间,Kubernetes也已经将其内置到 Kubectl .

我应该说,tail绝不是用于调试问题的工具,而是应该将日志输入到更持久的位置,例如 弹性搜索。但是,仍然有很多地方需要您快速调试某些内容,或者您​​尚未设置持久日志记录(例如,在 迷你库 )。

多个豆荚

Kubernetes 的概念是 复制控制器 确保n个Pod同时运行。这允许滚动更新和冗余。考虑到它们的设置非常简单,因此没有理由不这样做。

但是,现在有多个吊舱正在运行,并且它们都有唯一的ID。这里的一个问题是,您需要知道确切的Pod ID(kubectl获取Pod),但是每次创建Pod时都会更改,因此您每次都需要这样做。另一个考虑因素是,Kubernetes对流量进行负载平衡,因此您将不知道请求最终到达哪个吊舱。如果您要拖曳Pod A,但交通最终停在Pod B,您将错过发生的一切。

假设我们有一个名为service的Pod,带有3个副本。如下所示:

$  Kubectl  get pods                         # get pods to find pod ids

$  Kubectl  log -f service-1786497219-2rbt1  # pod 1

$  Kubectl  log -f service-1786497219-8kfbp  # pod 2

$  Kubectl  log -f service-1786497219-lttxd  # pod 3

多个容器

我们是重度用户 gRPC 内部服务,并使用REST通过REST公开gRPC端点 gRPC 网关。通常,我们将服务器和网关作为两个容器放在同一个容器中(通过cli标志设置模式的相同二进制文件)。网关在同一个Pod中与服务器对话,两个端口都暴露给Kubernetes。对于内部服务,我们的网站可以使用标准REST与网关进行通信,而我们可以直接与gRPC端点进行对话。

但是,这带来了问题。现在,我们不仅有多个吊舱,而且吊舱内还有多个容器。在这种情况下,kubectl的内置日志记录要求您指定要从中记录日志的容器。

If we have 3 replicas of a pod and 2 containers in the pod you'll need 6 Kubectl log -f <pod id> <container id>. We work with big monitors but this quickly gets out of hand…

如果我们的服务舱有一个服务器和网关容器,我们将查看以下内容:

$  Kubectl  get pods                                 # get pods to find pod ids

$  Kubectl  describe pod service-1786497219-2rbt1    # get containers in pod

$  Kubectl  log -f service-1786497219-2rbt1 server   # pod 1

$  Kubectl  log -f service-1786497219-2rbt1 gateway  # pod 1

$  Kubectl  log -f service-1786497219-8kfbp server   # pod 2

$  Kubectl  log -f service-1786497219-8kfbp gateway  # pod 2

$  Kubectl  log -f service-1786497219-lttxd server   # pod 3

$  Kubectl  log -f service-1786497219-lttxd gateway  # pod 3

船尾

为了解决这个问题,我们建立了 船尾 。这是一个非常简单的实用程序,可让您将Pod ID和容器ID都指定为正则表达式。将进行任何匹配,并将输出多路复用在一起,并以pod和容器ID为前缀,并使用颜色编码以供人类使用(如果通过管道传输到文件,则会去除颜色)。

服务示例如下所示:

$ stern service

这将匹配任何包含单词service的pod并监听其中的所有容器。如果只想查看到服务器容器的流量,可以执行stern --container服务器服务,它将从3个容器中流式传输所有服务器容器的日志。

输出看起来像这样:

$ stern service

+ service-1786497219-2rbt1 › server

+ service-1786497219-2rbt1 › gateway

+ service-1786497219-8kfbp › server

+ service-1786497219-8kfbp › gateway

+ service-1786497219-lttxd › server

+ service-1786497219-lttxd › gateway

+ service-1786497219-8kfbp server Log message from server

+ service-1786497219-2rbt1 gateway Log message from gateway

+ service-1786497219-8kfbp gateway Log message from gateway

+ service-1786497219-lttxd gateway Log message from gateway

+ service-1786497219-lttxd server Log message from server

+ service-1786497219-2rbt1 server Log message from server

此外,如果在部署过程中某个Pod被杀死并重新创建,则Stern将停止监听旧Pod,并自动挂接到新Pod。不再需要弄清楚新创建的Pod的ID是什么。

配置选项

船尾 故意设计为最小,所以没有太多。但是,仍有几个配置选项可以在此处重点介绍。它们与内置在kubectl中的非常相似,因此,如果您熟悉它,便会感到宾至如归。

  • 时间戳将时间戳添加到每行
  • 因为显示了自某个时间以来的日志条目(例如-自15分钟起)
  • kube-config允许您指定另一个Kubernetes配置。默认为〜/ .kube / config
  • 名称空间允许您仅将搜索限制为某个名称空间对所有选项运行stern --help。

例子

在登台时在envvars pod内尾部运行的网关容器尾部

 + stern --context staging --container gateway envvars

通过时间戳显示15分钟前的身份验证活动

+ stern -t --since 15m auth

跟随minikube中一些新功能的发展

+ stern --context minikube some-new-feature

查看另一个命名空间中的Pod

+ stern --namespace kube-system kubernetes-dashboard

严厉

船尾 是开源的, 在GitHub上可用,我们很乐意您的贡献或想法。如果您不想从源代码构建,也可以从以下位置下载预编译的二进制文件: GitHub版本.