<aside> ⏰ 本文我们将剖析 kubectl exec 命令的实现原理
</aside>
我们经常会有切换到 Pod 容器下面去调试应用的需求,我们可以通过使用 kubectl exec
命令来完成,本文我们将来了解该命令是如何工作的,了解了原理后我们就可以将该功能集成到我们自己开发的管理系统中去了。
首先我们先简单部署一个 Pod,然后在该 Pod 中来执行一条命令,这里我们直接使用 kubectl run
命令即可:
$ kubectl run nginx --image=nginx --port=80
pod/nginx created
$ kubectl get pods nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 21s
创建完成后通过使用 kubectl exec
命令在上面的 Pod 中执行下面的命令:
$ kubectl exec nginx -- date
Mon Aug 16 07:58:07 UTC 2021
$ kubectl exec -it nginx -- /bin/bash
root@nginx:/#
这里我们执行了两个命令,第一个是在容器内执行的 date
命令,第二个通过使用 -i
和 -t
两个参数进入容器的交互式 shell 中进行操作。
要想了解这个操作是如何发生的,一个比较好的办法是在执行 kubectl exec
的时候加 -v=7
的参数来调整日志等级,可以查看 kubectl exec
命令执行的过程:
$ kubectl exec -v=7 -it nginx -- /bin/bash
I0816 16:15:54.439180 73436 loader.go:375] Config loaded from file: /var/folders/x3/wjy_1z155pdf8jg_jgpmf6kc0000gn/T/kubeconfig-cbb18dcb67afc330852f5058cf700669
I0816 16:15:54.446329 73436 round_trippers.go:421] GET <http://127.0.0.1:53296/cbb18dcb67afc330852f5058cf700669/api/v1/namespaces/default/pods/nginx>
I0816 16:15:54.446353 73436 round_trippers.go:428] Request Headers:
I0816 16:15:54.446362 73436 round_trippers.go:432] User-Agent: kubectl/v1.18.15 (darwin/amd64) kubernetes/73dd5c8
I0816 16:15:54.446370 73436 round_trippers.go:432] Accept: application/json, */*
I0816 16:15:54.469502 73436 round_trippers.go:447] Response Status: 200 OK in 23 milliseconds
I0816 16:15:54.484801 73436 round_trippers.go:421] POST <http://127.0.0.1:53296/cbb18dcb67afc330852f5058cf700669/api/v1/namespaces/default/pods/nginx/exec?command=%2Fbin%2Fbash&container=nginx&stdin=true&stdout=true&tty=true>
I0816 16:15:54.484830 73436 round_trippers.go:428] Request Headers:
I0816 16:15:54.484839 73436 round_trippers.go:432] X-Stream-Protocol-Version: v4.channel.k8s.io
I0816 16:15:54.484856 73436 round_trippers.go:432] X-Stream-Protocol-Version: v3.channel.k8s.io
I0816 16:15:54.484863 73436 round_trippers.go:432] X-Stream-Protocol-Version: v2.channel.k8s.io
I0816 16:15:54.484870 73436 round_trippers.go:432] X-Stream-Protocol-Version: channel.k8s.io
I0816 16:15:54.484897 73436 round_trippers.go:432] User-Agent: kubectl/v1.18.15 (darwin/amd64) kubernetes/73dd5c8
I0816 16:15:54.595597 73436 round_trippers.go:447] Response Status: 101 Switching Protocols in 110 milliseconds
root@nginx:/#
我们可以清楚的看到上面的命令执行过程包含两个 HTTP 请求:
GET 请求用来获取 Pod 信息,路径 /api/v1/namespaces/default/pods/nginx
POST 请求调用 Pod 的 exec 子资源在容器内执行命令,路径 /api/v1/namespaces/default/pods/nginx/exec?command=%2Fbin%2Fbash&container=nginx&stdin=true&stdout=true&tty=true
最后是请求过后 APIServer 返回了一个 101 Switching Protocols
,用来表示请求已经升级为 SPDY
协议。
SPDY 允许在单个 TCP 连接上复用独立的
stdin/stdout/stderr/spdy-error
流。