我们知道,kubectl是封装curl操作的命令行工具,kubernetes
通过Api-Server
向外暴露Restful接口,当我们执行命令kubectl exec
命令时,实际在执行什么,和docker exec
有什么关联?
下面我们来一探究竟。
我们的default命令空间下有Pod:
MacBook-Pro-WRJ:~ wrj$ kubectl get po
NAME READY STATUS RESTARTS AGE
prometheus-operator-6f6b75f46f-h4gl4 1/1 Running 0 20d
MacBook-Pro-WRJ:~ wrj$ kubectl exec prometheus-operator-6f6b75f46f-h4gl4 ping baidu.com
执行exec命令,打印详细日志:
MacBook-Pro-WRJ:~ wrj$ kubectl -v=7 exec prometheus-operator-6f6b75f46f-h4gl4 ls
I0818 20:15:57.037226 11518 loader.go:375] Config loaded from file: /Users/wrj/.kube/config
I0818 20:15:57.054763 11518 round_trippers.go:420] GET https://10.172.58.142:6443/api/v1/namespaces/default/pods/prometheus-operator-6f6b75f46f-h4gl4
I0818 20:15:57.054799 11518 round_trippers.go:427] Request Headers:
I0818 20:15:57.054805 11518 round_trippers.go:431] Accept: application/json, */*
I0818 20:15:57.054810 11518 round_trippers.go:431] User-Agent: kubectl/v1.16.3 (darwin/amd64) kubernetes/b3cbbae
I0818 20:15:57.093926 11518 round_trippers.go:446] Response Status: 200 OK in 39 milliseconds
I0818 20:15:57.106419 11518 round_trippers.go:420] POST https://10.172.58.142:6443/api/v1/namespaces/default/pods/prometheus-operator-6f6b75f46f-h4gl4/exec?command=ls&container=prometheus-operator&stderr=true&stdout=true
I0818 20:15:57.106459 11518 round_trippers.go:427] Request Headers:
I0818 20:15:57.106466 11518 round_trippers.go:431] X-Stream-Protocol-Version: v4.channel.k8s.io
I0818 20:15:57.106473 11518 round_trippers.go:431] X-Stream-Protocol-Version: v3.channel.k8s.io
I0818 20:15:57.106480 11518 round_trippers.go:431] X-Stream-Protocol-Version: v2.channel.k8s.io
I0818 20:15:57.106484 11518 round_trippers.go:431] X-Stream-Protocol-Version: channel.k8s.io
I0818 20:15:57.106488 11518 round_trippers.go:431] User-Agent: kubectl/v1.16.3 (darwin/amd64) kubernetes/b3cbbae
I0818 20:15:57.187518 11518 round_trippers.go:446] Response Status: 101 Switching Protocols in 81 milliseconds
bin
dev
etc
home
lib
proc
root
sys
tmp
usr
var
重点1:exec请求相当于向Api-server
发起路径为/api/v1/namespaces/default/pods/prometheus-operator-6f6b75f46f-h4gl4/exec?command=ls&container=prometheus-operator&stderr=true&stdout=true
的请求
重点2:日志里这一行:Response Status: 101 Switching Protocols in 81 milliseconds。表示最后 API Server 返回了 101 Ugrade 响应,向客户端表示已切换到 SPDY 协议
SPDY 允许在单个 TCP 连接上复用独立的 stdin/stdout/stderr/spdy-error 流
我们知道,Pod对应的是某个Node节点运行的docker容器,所以大致流程是:
kubectl exec -> Api-server -> kubelet(pod所在的宿主机) -> docker container
涉及到kubelet注册exec处理器、kubelet与docker运行时接口之间的交互以及请求的转发,用下面一张图可以更好的说明:
具体原理还需要弄清楚以下问题:
- Kubelet 是如何注册 exec 处理器的?
- Kubelet 与 Docker API 如何交互?
这块涉及代码层的理解,笔者目前理解不够深入,还需要加强源码阅读
本文参考自:https://fuckcloudnative.io/posts/how-it-works-kubectl-exec/ 。 源码级的分析在此文中有介绍,可以点击进入阅读。