曾几何时,咱们将本人的利用运行在 Kubernetes 上,每当呈现容器异样解体时,咱们往往都是一边重启容器,一边面对解体的容器无从下手。通常在业务研发本人 build 的镜像内蕴含了 shell,咱们还能通过在 command 中嵌入一个 ["sleep", "3600"]
命令来阻塞容器内服务启动,不过也有时候会呈现不晓得从哪里冒出来一个 distroless
镜像,这时可能最先解体的就是运维了。那是一种运维这个职业自诞生以来,第一次感触到不知所措并脱离掌控的无助感
。于是在 k8s 环境下无奈 debug 容器的梗开始在坊间广为吐槽。
第一个突破魔咒的是 kubectl-debug,它蕴含了 agent 和debug-tools两个局部。也是目前全网内搜到文档最全的解决方案。不过目前它的开发仿佛曾经进行,上一次提交还是在 8 个月之前,而最近一次 Release 版本也停留在两年前。更难以承受的是,以后它无奈被集成在容器运行时为 Containerd 的 k8s 集群。
只管 kubectl-debug 已经的确是一款十分好用的容器调试工具,但现在 Kubernetes 曾经有了更好的容器调试解决方案,Ephemeral Containers
。
Ephemeral Containers
Ephemeral Containers 字如其名,它就是一个长期容器。这是一个自 Kubernetes v1.16 中作为 alpha 引入的新性能,尽管以后它还没有 GA,不过自从在 Kubernetes v1.18 之后,在 kubectl 内曾经集成了 debug 客户端,咱们简直能够残缺的应用并体验它的新个性。
长期容器的指标是为 Kubernetes 用户提供一个故障诊断工具,同时具备满足以下需要:
- 作为一个开箱即用的平台化工具
- 不依赖于曾经蕴含在容器镜像中的工具
- 不须要间接登陆计算节点(能够通过 Kubernetes API 的治理拜访 Node)
不过也有货色是长期容器不打算反对的,比方对 windows 上启用长期容器就不太敌对。
启用长期容器的个性也非常简单,在 kubernetes v1.16 之后的版本中将启动参数 --feature-gates=EphemeralContainers=true
配置到 kube-api 和 kubelet 服务上重启即可。
在 1.20 之前,kubectl debug 工具被放在 alpha 中,留神不同版本的命令操作差异
这里举荐应用客户端为 1.20+ 的版本体验会更好
那么咱们有了 Ephemeral Containers 能做哪些事件呢?
1. POD Troubleshooting
如上文所说,咱们能够间接通过 kubectl debug 命令进行容器调试。最间接简略的对一个 pod 进行调试命令如下:
kubectl debug mypod -it --image=busybox
默认状况下用户不指定长期容器名称的话,debug 容器名称就由 kubectl 主动生成一个惟一 id 的名称。如果用户须要本人指定容器名称则应用
kubectl debug mypod -c debugger --image=busybox
有了长期容器除了日常 debug 性能外,咱们能够扩大出很多新花样的玩法。比方批量跑某个命名空间下的平安扫描的脚本而不必烦扰原容器。
for pod in $(kubectl get -o name pod);
do
kubectl debug --image security/pod_scanner -p $pod /sanner.sh
done
2. POD Troubleshooting by Copy
对于没有开启 Ephemeral Containers 个性的集群,咱们就只能通过复制模式来调试容器。它的原理是复制一个指定 pod 的新容器,并将 debug 作为 sidecar 追随新容器一起启动。通过这种形式也能达到曲线救国的目标。此种形式的几个参数还是挺有意思:
--copy-to 指定新 pod 的名称
--replace=true 是否删除原容器
--same-node=true 是否调度到和原容器一样的 node 上
--share-processes=true 是否共享容器 pid 空间
例如咱们就能够启动一个跟须要调试 pod 一样配置的 debug 容器如下:
kubectl debug mypod -it \
--container=debug \
--image=busybox \
--copy-to=my-debugger \
--same-node=true \
--share-processes=true
3. Node Troubleshooting
对!你没看错!利用 Ephemeral Containers 还能对 Worker 节点进行调试。当以节点为指标调用时,kubectl debug 将创立一个带有 node 名称的 pod,并且调度到该节点。同时该容器还具备了 hostIPC
、hostNetwork
和hostPID
这些特权模式。不堪设想的是Worker 节点的根文件系统还被 mount 到了 debug 容器下的 /host 目录下
。
间接执行这个命令就能 debug 主机。
kubectl debug node/mynode -it --image=busybox
Debug 镜像
工欲善其事,必先利其器。不管怎样咱们都须要一套工具欠缺的 debug 镜像,在解决问题时可能得心应手。尽管网上也有不少 debug 镜像,不过都还是不如本人构建来的畅快。
这里小白分享一个 Debug 镜像的 Dockerfile,大家能够依据本人条件批改即可。
FROM golang:alpine as grpcurl
RUN apk update \
&& apk add --virtual build-dependencies git \
&& apk add bash curl jq \
&& go get -u github.com/fullstorydev/grpcurl \
&& go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
FROM alpine:latest
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories && \
apk update && \
apk add --no-cache vim bash tcpdump curl wget strace mysql-client iproute2 redis jq iftop tzdata tar nmap bind-tools htop && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN wget -O /usr/bin/httpstat https://github.com/davecheney/httpstat/releases/download/v1.0.0/httpstat-linux-amd64-v1.0.0 && \
chmod +x /usr/bin/httpstat
COPY --from=grpcurl /go/bin/grpcurl /usr/bin/grpcurl
ENV TZ=Asia/Shanghai LC_ALL=C.UTF-8 LANG=C.UTF-8 LANGUAGE=C.UTF-8
ENTRYPOINT ["/bin/bash"]
debug 镜像内反对的工具包如下图
总结
本文次要讲述了 kubernetes 在 v1.18 版本之后被提上 alpha 的 Ephemeral Containers
个性,通过长期容器咱们能够 debug 容器,甚至还能够 debug 主机。它的确是一个十分不便和足以代替 kubectl-debug 的解决方案。不过,目前长期容器对于用户权限这块并没有特地的阐明,特地是用特权模式调试主机的时候,心愿前面可能借助 PSP(Pod Security Policy)做一个额定的补充。
关注公众号【云原生小白】,回复「入群」退出 Loki 学习群