In previous blog posts, we focused on how to use TCPdump in a specific container
While researching some other things recently, I came across a comment suggesting a quick fix for another issue like this …
$ kubectl run -it --rm debug --restart=Never --image=ubuntu --overrides='{"kind":"Pod", "apiVersion":"v1", "spec": {"hostNetwork":true}}'
This is pretty similar as described in a previous blog posts …
docker run -it --net=host ubuntu
… but in the kubectl case, we do not need SSH access to a node or access to the docker client, nor do we need to re-deploy the deployment (aka restart of the pods)
So let’s try this ... Create a small K8S cluster and deploy a simple nginx service (I used the managed K8S service from Digitalocean and tested as well on an Azure environment)
$ kubectl get no
NAME STATUS ROLES AGE VERSION
demo-pool1-lyg2 Ready <none> 2m3s v1.16.2
demo-pool1-lygl Ready <none> 2m12s v1.16.2
demo-pool1-lygt Ready <none> 2m14s v1.16.2$ kubectl get svc -n radarhack
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-radarhack-clusterip ClusterIP 10.245.94.156 <none> 80/TCP 100s$ kubectl get po -n radarhack -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
radarhack-deployment-655b776bd-6v6dl 1/1 Running 0 22m 10.244.0.232 demo-pool1-lygt <none> <none>
radarhack-deployment-655b776bd-wmqv9 1/1 Running 0 22m 10.244.1.87 demo-pool1-lygl <none> <none>
radarhack-deployment-655b776bd-zrxdd 1/1 Running 0 22m 10.244.2.223 demo-pool1-lyg2 <none> <none>
So lets deploy an ubuntu pod like described before …
$ kubectl run -it --rm debug --restart=Never --image=ubuntu --overrides='{"kind":"Pod", "apiVersion":"v1", "spec": {"hostNetwork":true}}'
If you don't see a command prompt, try pressing enter.
… inside the pod, install following packages …
root@demo-pool1-lygt:/# apt-get update && apt-get install -y net-tools && apt-get install -y tcpdump
Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Get:2 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
Get:3 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
...
Setting up tcpdump (4.9.2-3) ...
Processing triggers for libc-bin (2.27-3ubuntu1) ...
… and now we can list all the interfaces of the host inside the pod !
root@demo-pool1-lygt:/# ifconfig
cilium_host: flags=4291<UP,BROADCAST,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.244.0.191 netmask 255.255.255.255 broadcast 0.0.0.0
inet6 fe80::44ca:4aff:fee7:ddba prefixlen 64 scopeid 0x20<link>
ether 46:ca:4a:e7:dd:ba txqueuelen 1000 (Ethernet)
RX packets 445 bytes 46829 (46.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 133 bytes 6790 (6.7 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
cilium_net: flags=4291<UP,BROADCAST,RUNNING,NOARP,MULTICAST> mtu 1500
inet6 fe80::144b:40ff:fee3:892d prefixlen 64 scopeid 0x20<link>
ether 16:4b:40:e3:89:2d txqueuelen 1000 (Ethernet)
RX packets 133 bytes 6790 (6.7 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 445 bytes 46829 (46.8 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
cilium_vxlan: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::4e9:f7ff:fe9e:8a5a prefixlen 64 scopeid 0x20<link>
ether 06:e9:f7:9e:8a:5a txqueuelen 1000 (Ethernet)
RX packets 248 bytes 23105 (23.1 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 250 bytes 29122 (29.1 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:b9:15:7e:44 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 188.166.35.94 netmask 255.255.192.0 broadcast 188.166.63.255
inet6 fe80::7421:6bff:fed4:7a97 prefixlen 64 scopeid 0x20<link>
ether 76:21:6b:d4:7a:97 txqueuelen 1000 (Ethernet)
RX packets 35107 bytes 184254131 (184.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8237 bytes 637679 (637.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.18.0.9 netmask 255.255.0.0 broadcast 10.18.255.255
ether 76:21:6b:d4:7a:97 txqueuelen 1000 (Ethernet)
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.133.91.245 netmask 255.255.0.0 broadcast 10.133.255.255
inet6 fe80::407:2eff:fee7:7135 prefixlen 64 scopeid 0x20<link>
ether 06:07:2e:e7:71:35 txqueuelen 1000 (Ethernet)
RX packets 3320 bytes 1297431 (1.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3327 bytes 486607 (486.6 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 1933 bytes 123132 (123.1 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1933 bytes 123132 (123.1 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
...
We can now attach TCPdump to any of the interfaces and record the traffic.
root@demo-pool1-lygt:/# tcpdump -i eth0 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
12:29:40.285086 IP 178.62.231.175.443 > 188.166.35.94.56492: Flags [P.], seq 3344525609:3344526062, ack 3498904092, win 249, options [nop,nop,TS val 1350708887 ecr 1279555160], length 453
...root@demo-pool1-lygt:/# tcpdump -i any -n port 80
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
12:44:22.727590 IP 10.244.1.42.36658 > 10.244.0.232.80: Flags [S], seq 790184700, win 28200, options [mss 1410,sackOK,TS val 4002115421 ecr 0,nop,wscale 7], length 0
12:44:22.727695 IP 10.244.1.42.36658 > 10.244.0.232.80: Flags [S], seq 790184700, win 28200, options [mss 1410,sackOK,TS val 4002115421 ecr 0,nop,wscale 7], length 0
12:44:22.727738 IP 10.244.0.232.80 > 10.244.1.42.36658: Flags [S.], seq 2931529117, ack 790184701, win 27960, options [mss 1410,sackOK,TS val 3120146425 ecr 4002115421,nop,wscale 7], length 0
12:44:22.727751 IP 10.244.0.232.80 > 10.244.1.42.36658: Flags [S.], seq 2931529117, ack 790184701, win 27960, options [mss 1410,sackOK,TS val 3120146425 ecr 4002115421,nop,wscale 7], length 0
12:44:22.728424 IP 10.244.1.42.36658 > 10.244.0.232.80: Flags [.], ack 1, win 221, options [nop,nop,TS val 4002115422 ecr 3120146425], length 0
12:44:22.728460 IP 10.244.1.42.36658 > 10.244.0.232.80: Flags [.], ack 1, win 221, options [nop,nop,TS val 4002115422 ecr 3120146425], length 0
Remark: The traffic being displayed in the second example in address space 10.244.0.0/16 is inter-pod traffic.
It is even possible to intercept the traffic in/out the kube-system pods ;-)
I hope this article provides an easy way to capture traffic and learn more on the inner workings of our K8S cluster. Thanks for reading, Philippe Bogaerts !!!
Comments