如何在kubernetes pod种进行网络分析

背景

我们通常在 kubernetes 部署业务会选择最小化的基础镜像,这样做的好处有两个

  1. 镜像大小较小,节约带宽资源并提高传输效率
  2. 镜像更加纯净,避免因为引入非业务软件带来的潜在风险

但是缺点也很明显,一旦线上出现网络问题或者需要进行网络分析就变得很困难,如果是 kvm 或者宿主机部署,只需要在本地安装 tcpdump之类的工具即可,对业务也没有侵入,但是线上 pod里没有这些工具软件,势必需要修改镜像重启 pod 对业务造成影响。

sidercar使用

参考 istio 使用 sidercar 来实现服务网格的思路,我们也可以考虑自己封装一个带有 tcpdump 等工具的镜像来作为 sidercar注入到pod 中,因为 pod 种的容器是共享网络网络命名空间的,所以 sidercar 中的 tcpdump 就可以监听到业务容器中流量。这里其实我们也不需要自己封装这样的一个 sidercar 镜像了,netshoot 内置了丰富的网络工具包。

工具包概览如下:

Untitled

apache2-utils \
bash \
bind-tools \
bird \
bridge-utils \
busybox-extras \
conntrack-tools \
curl \
dhcping \
drill \
ethtool \
file\
fping \
grpcurl \
iftop \
iperf \
iperf3 \
iproute2 \
ipset \
iptables \
iptraf-ng \
iputils \
ipvsadm \
jq \
libc6-compat \
liboping \
ltrace \
mtr \
net-snmp-tools \
netcat-openbsd \
nftables \
ngrep \
nmap \
nmap-nping \
nmap-scripts \
openssl \
py3-pip \
py3-setuptools \
scapy \
socat \
speedtest-cli \
openssh \
strace \
tcpdump \
tcptraceroute \
tshark \
util-linux \
vim \
git \
zsh \
websocat \
swaks \
perl-crypt-ssleay \
perl-net-ssleay

netshoot使用

yaml准备

在 kubernetes 中将 netshoot作为 sidercar 使用,这里主容器以 nginx为例 示例如下:

[root@master1 ~]# cat netshoot-sidercar.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-netshoot
  labels:
    app: nginx-netshoot
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-netshoot
  template:
    metadata:
      labels:
        app: nginx-netshoot
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
      - name: netshoot
        image: nicolaka/netshoot
        command: ["sleep", "infinity"]

Deployment创建

[root@master1 ~]# kubectl apply -f netshoot-sidercar.yaml 
deployment.apps/nginx-netshoot created

pod状态查看

[root@master1 ~]# kubectl get pods 
NAME                              READY   STATUS    RESTARTS   AGE
nginx-netshoot-558f499f76-rfpgc   2/2     Running   0          2m22s

进入netshoot 容器

[root@master1 ~]# kubectl exec -it nginx-netshoot-558f499f76-rfpgc -c netshoot -- /bin/zsh
                    dP            dP                           dP   
                    88            88                           88   
88d888b. .d8888b. d8888P .d8888b. 88d888b. .d8888b. .d8888b. d8888P 
88'  88 88ooood8   88   Y8ooooo. 88'  88 88'  88 88'  88   88   
88    88 88.  ...   88         88 88    88 88.  .88 88.  .88   88   
dP    dP 88888P'   dP   88888P' dP    dP 88888P' 88888P'   dP   

Welcome to Netshoot! (github.com/nicolaka/netshoot)

 nginx-netshoot-558f499f76-rfpgc  ~ 

tcpdump测试

在 netshoot 内使用 tcpdump监听 nginx 的 流量,这里为了方便图形化展示,会把流量保存到文件里,后续使用 wireshark 打开分析,当然你也可以直接打印在终端输出上

nginx-netshoot-558f499f76-rfpgc  ~  tcpdump -i any -nn dst port 80 -w network.pcap

这个时候 nginx 是没有流量进来的,需要模拟请求一下,首先得获取到容器所在 pod 的 ip,我们新开一个shell窗口,查看pod的ip

[root@master1 ~]# kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
nginx-netshoot-558f499f76-rfpgc   2/2     Running   0          6m16s   10.244.2.6   node2   

请求pod ip

[root@master1 ~]# curl 10.244.2.6



Welcome to nginx!Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

还回到原来的 shell窗口ctrl+c中断监听并退出 netshoot 容器

nginx-netshoot-558f499f76-rfpgc  ~  exit

接着需要把 pod 中的 network.pcap拷贝到宿主机

kubectl cp  nginx-netshoot-558f499f76-rfpgc:network.pcap -c netshoot  network.pcap

在宿主机可以通过 scp 等方式把network.pcap拷贝到自己机器然后使用 wireshark 打开就可以分析了

Untitled

参考

  1. https://github.com/nicolaka/netshoot
  2. https://developer.aliyun.com/article/788714
  3. https://medium.com/@rakhitharr/debug-network-traffic-in-kubernetes-using-a-sidecar-fd1671d8a35b

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据