凯发网娱乐下载-凯发网站-凯发体育下载
当前位置:主页 > 联系我们 >

kubespy 用bash实现的k8s动态调试工具

发表日期:2020-01-01 13:34文章编辑:admin浏览次数: 标签:    

Kubernetes调试的最大痛点是精简过的容器镜像里没有日常的调试东西。背面的原因是精简容器镜像自身便是容器技能的最佳实践之一。nginx的容器镜像乃至不包括ps和curl这种最根底的东西。这种彻底服务于出产环境的战略无异于过早优化,但受制于immutable infrastructure的基本思想和CI/CD实际操作的两层限制,你无法在出产环境发布一个和开发环境不同的容器镜像。这使得这一过早优化的成果愈加灾祸化。处理这个问题的要害在于,能否在不侵入式的修正容器镜像的情况下,向方针容器里加载需求的调试东西。例如,类似于istio之类的处理计划能够向方针pod刺进一个sidecar容器。当然这儿的权限要求是高于sidecar容器的,由于pod中的各个容器尽管同享network,但pid和ipc是不同享的。此外,sidecar容器是无法被参加一个现已创立出来的pod,而咱们期望东西容器能够在运行时被动态刺进,由于问题的发生是随机的,你不能彻底猜测需求加载哪些东西。

Kubernetes社区很早有相关的issue和proposal但并没有终究终究被upstream承受。

现在官方给出最接近的计划是Ephemeral Containers和shareProcessNamespace。前者答应你在运行时在一个pod里刺进一个短生命周期的容器,而后者答应你同享方针pod内容器的network,pid,ipc等cgroups namespace乃至修正其间的环境。现在Ephemeral Containers还在v1.17 alpha阶段。并且shareProcessNamespace这个spec要求在创立pod的时分就必须显式启用,不然运行时无法修正。

kubespy 是一个彻底用bash完成的Kubernetes调试东西,它不光完美的处理了上面说到的如安在运行时向方针容器加载东西的问题,并且并不依靠任何最新版别的Kubernetes的特性。这篇文章稍后会介绍怎么运用kubespy来动态调试,以及kubespy是怎么经过kubectl,docker以及chrootl来构建这条调试链的,终究会简略剖析一下要害的代码完成。

你能够直接从代码装置,由于kubespy是彻底bash完成的,所以能够直接复制文件来履行。

$ curl -so kubectl-spy https://raw.githubusercontent. ... bespy

$ sudo install kubectl-spy /usr/local/bin/

你也能够从krew来装置。krew是一个kubernetes-sigs孵化中的kubectl插件包管理东西,带有准官方性质。

$ kubectl krew install spy

装置往后,kubespy能够成为一个kubectl的子指令被履行。你能够指定方针pod为参数。假如方针pod有多个容器,你能够经过-c指定详细的容器。你也能够指定加载的东西容器的镜像,默许是busybox:latest

$ kubectl spy POD [-c CONTAINER] [--spy-image SPY_IMAGE]

你能够经过以下这个demo来快速体会怎么调试一个镜像为nginx的pod。nginx镜像不包括ps或许任何网络东西。而加载的东西容器的镜像为busybox,不光能够拜访原容器的文件体系和进程树,乃至能够杀进程,修正文件。当然发http恳求更是没有问题。

kubespy的作业原理大致能够用以下这个流程图来展现。

local machine: kubectl spy [1]
master node: kube-apiserver [2]
worker node: kubelet [3]
 spy pod  [4]
 | 
 docker runtime [5]
 | 
 spy container [6]
 | 
 application pod  [7]

概要的看,kubespy是经过以下这些过程构建调试连的,上图的过程数字能够与下文对应

[1] `kubespy`作为`kubectl`的插件被履行,能够向`master node`上的`kube-apiserver`宣布api恳求,会先取得方针容器的要害信息,如其地点的`worker node`和pid/net/ipc 等cgroups namespace
[2] `kube-apiserver`将详细的指令分发给方针容器地点的`worker node`上的agent`kubelet`履行
[3] `kubelet`创立一个`busybox`作为`spy pod`
[4] `spy pod`mount了`worker node`的根目录,并经过`chroot`取得了worker node的操控权
[5] `spy pod`操控了docker cli创立了东西容器
[6] 东西容器被参加方针容器的pid/net/ipc等cgroups namespace
[7] 用户经过`kubectl`被attach到东西容器的tty里,能够对方针容器进行调试乃至是修正

要害代码

怎么取得方针容器的pid/net/ipc等cgroups namespace

if [[ ${co} == ]]; then
cid=$
cid=$].containerID}' | sed 's/docker:\/\///')

依据kubectl的convention,假如用户未指定容器,咱们默许以方针pod的第一个容器作为方针容器。kubelet在为kubernetes集群创立容器时,会相应的创立以containerID命名的pid/net/ipc等cgroups namespace。cgroups namespace是docker完成user space阻隔的根底原理,能够参阅 https://docs.docker.com/engine ... paces 进行了解。

怎么取得方针容器地点worker node以及其docker cli的操控权

 volumes : [
 name : node ,
 hostPath : {
 path : / 

spy pod会将worker node的根目录作为volume来mount在/host

{
 name : spy ,
 image : busybox ,
 command : [ /bin/chroot , /host ],
 args : [
 docker ,
 run ,
 -it ,
 --network=container:' ${cid} ' ,
 --pid=container:' ${cid} ' ,
 --ipc=container:' ${cid} ' ,
 ' ${ep} ' 
 stdin : true,
 stdinOnce : true,
 tty : true,
 volumeMounts : [
 mountPath : /host ,
 name : node 

}

然后在经过busybox里的chroot,将worker node的根目录作为自己的根目录。而docker cli也将被直接露出出来。

在获取了方针容器的pid/net/ipc等cgroups namespace之后,即可直接创立东西容器同享方针容器的cgroups namespace。此刻,方针容器和方针容器在进程树,网络空间,内部进程通讯等,都是没有任何阻隔的。

怎么将用户的terminal带入方针容器中

kubectl run -it,chroot和docker run -it都是能够attach到方针的tty中的,这些指令链接起来,像一系列跳板,把用户的terminal一层层带入下一个,终究带入方针容器中。

kubespy 用bash完成对kubernetes集群中的pod经过动态加载东西容器来调试,弥补了现在kubernetes版别上功用的缺失,并展现了一些对kubernetes自身有深度的技巧。

原文坐落

相关新闻