验证使用 pod 副本调试正在运行中的 pod 时是否会被k8s接入流量

- 云计算

打算使用 kubectl debug 创建个 pod 副本运行额外的调试工具时突然想到一个问题,这个 pod 副本是基于现在运行中 pod 创建的那 k8s 会不会把流量也转发到这个 副本 pod上 ?测试一下吧。


默认业务 pod 无 netstat 命令

[root@imzcy ~]# kubectl get pods -n test |grep "NAME\|signinapp"
NAME                                                    READY   STATUS    RESTARTS           AGE
deployment-express-signinapp-v62-fcb5b8fc8-p5nfj        1/1     Running   0                  37h
[root@imzcy ~]#
[root@imzcy ~]# kubectl -n test exec -it deployment-express-signinapp-v62-fcb5b8fc8-p5nfj -- /bin/bash
[zcy@deployment-express-signinapp-v62-fcb5b8fc8-p5nfj dyapp]$ netstat -antp
bash: netstat: command not found
[zcy@deployment-express-signinapp-v62-fcb5b8fc8-p5nfj dyapp]$
[zcy@deployment-express-signinapp-v62-fcb5b8fc8-p5nfj dyapp]$ exit
exit
[root@imzcy ~]#




创建 pod 副本引入 busybox 镜像附加容器

使用 kubectl debug 命令创建pod副本使用busybox镜像作为附加容器,进入容器后执行 netstat 命令正常。

[root@imzcy ~]# kubectl debug -n test deployment-express-signinapp-v62-fcb5b8fc8-p5nfj -it --image=busybox:1.28 --share-processes --copy-to=signinapp-debug
Defaulting debug container name to debugger-wlkgk.
If you don't see a command prompt, try pressing enter.
/ # id
uid=0(root) gid=0(root) groups=10(wheel)
/ #

/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 /pause
    9 1009      0:03 dotnet SignInApp.Api.dll urls=http://*:5000
   32 root      0:00 sh
   41 root      0:00 ps
/ # netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 192.18.23.81:47606      192.18.0.6:7080         ESTABLISHED -
tcp        0      0 192.18.23.81:35296      192.18.0.26:10003       ESTABLISHED -
tcp        0      0 192.18.23.81:47602      192.18.0.6:7080         ESTABLISHED -
tcp        0      0 192.18.23.81:47608      192.18.0.6:7080         ESTABLISHED -
tcp        0      0 192.18.23.81:47588      192.18.0.6:7080         ESTABLISHED -
tcp        0      0 192.18.23.81:47604      192.18.0.6:7080         ESTABLISHED -
tcp        0      0 192.18.23.81:47586      192.18.0.6:7080         ESTABLISHED -
tcp        0      0 :::5000                 :::*                    LISTEN      -
tcp        0      0 ::ffff:192.18.23.81:5000 ::ffff:192.18.31.8:40264 TIME_WAIT   -
tcp        0      0 ::ffff:192.18.23.81:5000 ::ffff:192.18.31.8:40160 TIME_WAIT   -
/ #




确认业务pod和副本pod情况

可以看到原本的业务pod中值运行了一个容器,但是副本pod中运行了两个容器(多一个busybox容器)。

[root@imzcy ~]# kubectl -n test get pods -o wide  |grep "NAME\|signinapp"
NAME                                                    READY   STATUS    RESTARTS         AGE     IP              NODE           NOMINATED NODE   READINESS GATES
deployment-express-signinapp-v62-fcb5b8fc8-p5nfj        1/1     Running   0                40h     192.18.23.138   192.18.31.8    <none>           <none>
signinapp-debug                                         2/2     Running   0                3h12m   192.18.23.81    192.18.31.8    <none>           <none>
[root@imzcy ~]#




确认 service 资源情况

过滤 signinapp 查询服务名

[root@imzcy ~]# kubectl -n test get svc |grep "NAME\|signinapp"
NAME                                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)           AGE
svc-express-signinapp-v62            ClusterIP   10.6.1.158   <none>        80/TCP            3d22h
[root@imzcy ~]#

查看服务详细信息,可以看到当前 Endpoints 的列表里只有原来业务 pod 的IP,没有副本 pod 的IP。 这样的话就不会把流量转发给副本pod了。 因为 service 是根据 labels 去匹配 pod 的,难道副本pod的label特殊?

[root@imzcy ~]# kubectl -n test describe svc svc-express-signinapp-v62
Name:              svc-express-signinapp-v62
Namespace:         test
Labels:            <none>
Annotations:       <none>
Selector:          dyapp=signinapp,dyitem=express,dyversion=v62
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.6.1.158
IPs:               10.6.1.158
Port:              <unset>  80/TCP
TargetPort:        5000/TCP
Endpoints:         192.18.23.138:5000
Session Affinity:  None
Events:            <none>
[root@imzcy ~]#




确认副本 pod 的 label

查看副本 pod 的详细信息,发现 labels 的值竟然是空的,好吧。

[root@imzcy ~]# kubectl -n test describe pod signinapp-debug |head
Name:         signinapp-debug
Namespace:    test
Priority:     0
Node:         192.18.31.8/192.18.31.8
Start Time:   Mon, 11 Dec 2023 14:13:04 +0800
Labels:       <none>
Annotations:  tke.cloud.tencent.com/networks-status:
                [{
                    "name": "tke-route-eni",
                    "interface": "eth0",
[root@imzcy ~]#

对比业务 pod 的label 。

[root@imzcy ~]# kubectl -n test describe pod deployment-express-signinapp-v62-fcb5b8fc8-p5nfj |head
Name:         deployment-express-signinapp-v62-fcb5b8fc8-p5nfj
Namespace:    test
Priority:     0
Node:         192.18.31.8/192.18.31.8
Start Time:   Sun, 10 Dec 2023 00:48:12 +0800
Labels:       dyapp=signinapp
              dyitem=express
              dyversion=v62
              pod-template-hash=fcb5b8fc8
Annotations:  tke.cloud.tencent.com/networks-status:
[root@imzcy ~]#




结论

使用 kubectl debug 创建 pod 副本去排查问题的时候,k8s 默认是不会将流量转发到这个副本 pod 上的。因为默认将它的 label 值设为空了,所以不会被 service 匹配到,流量自然也不会转发过来。

不过这个情况也只使用于服务本身是只会被调用的 api 服务的时候,如果要创建副本pod的业务pod本身跑的是 task 应用之类的,那只要pod里的应用起来就会开始处理数据了。这点要注意一下。