Kubernetes 이야기

Pod에서 tcpdump 패킷 캡처 본문

Kubernetes/일반

Pod에서 tcpdump 패킷 캡처

kmaster 2022. 8. 28. 11:36
반응형

네트워크 패킷을 관찰하기 가장 좋은 방법 중 하나는 tcpdump이다. 포드에서 TCP 트래픽 캡처를 수행하고 캡처를 조회할 수 있는 방법을 살펴보자.

 

Pod에 Tcpdump 툴 설치하는 방법

 

연결 문제가 있는 포드에 접속해 보자. 

# k exec -it -n test sampleapp-6c65c5cdb7-mplj4 -- /bin/bash

다음과 같이 tcpdump 를 설치한다.

# apt-get update && apt-get install tcpdump

Alpine Linux인 경우에는 다음의 명령을 수행한다.

# apk add tcpdump

 

캡처

# tcpdump -s 0 -vvv -w /capture.cap
# tcpdump -s 0 -vvv -w /capture.cap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
Got 0
20 packets captured
20 packets received by filter
0 packets dropped by kernel

 

캡처받은 파일을 현재 디렉토리에 저장한다.

# kubectl cp -n test sampleapp-6c65c5cdb7-mplj4:/capture.cap capture.cap

 

Ksniff 를 이용하는 방법

Kubernetes 통합 패킷 스니퍼인 Ksniff 를 사용하여 패킷을 분석할 수도 있다.

(
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)
export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

다음의 명령을 사용하여 sniff 를 설치한다.

# kubectl krew install sniff

설치가 완료되면 명령어를 살펴보자.

# kubectl sniff
Usage:
  sniff pod [-n namespace] [-c container] [-f filter] [-o output-file] [-l local-tcpdump-path] [-r remote-tcpdump-path] [flags]

Examples:
kubectl sniff hello-minikube-7c77b68cff-qbvsd -c hello-minikube

Flags:
  -c, --container string                container (optional)
  -x, --context string                  kubectl context to work on (optional)
  -f, --filter string                   tcpdump filter (optional)
  -h, --help                            help for sniff
      --image string                    the privileged container image (optional)
  -i, --interface string                pod interface to packet capture (optional) (default "any")
  -l, --local-tcpdump-path string       local static tcpdump binary path (optional)
  -n, --namespace string                namespace (optional)
  -o, --output-file string              output file path, tcpdump output will be redirect to this file instead of wireshark (optional) ('-' stdout)
      --pod-creation-timeout duration   the length of time to wait for privileged pod to be created (e.g. 20s, 2m, 1h). A value of zero means the creation never times out. (default 1m0s)
  -p, --privileged                      if specified, ksniff will deploy another pod that have privileges to attach target pod network namespace
  -r, --remote-tcpdump-path string      remote static tcpdump binary path (optional) (default "/tmp/static-tcpdump")
      --socket string                   the container runtime socket path (optional)
      --tcpdump-image string            the tcpdump container image (optional)
  -v, --verbose                         if specified, ksniff output will include debug information (optional)
Error: not enough arguments

사용법

# kubectl sniff  <your-apache-pod-name> -p -o s.cap

예)

# kubectl sniff -n test sampleapp-6c65c5cdb7-d6lrq  -p
INFO[0000] no container specified, taking first container we found in pod.
INFO[0000] selected container: 'sampleapp'
INFO[0000] sniffing method: privileged pod
INFO[0000] sniffing on pod: 'sampleapp-6c65c5cdb7-d6lrq' [namespace: 'test', container: 'sampleapp', filter: '', interface: 'any']
INFO[0000] creating privileged pod on node: 'kind-control-plane'
INFO[0000] pod: 'ksniff-r7r2t' created successfully in namespace: 'test'
INFO[0000] waiting for pod successful startup

 

Ephemeral Containers를 이용하는 방법

간단히 tcpdump를 받을 수 있지만, 인터넷이 되지 않는 환경인 경우나 방화벽 문제로 Pod 에 설치할 수 없는 경우에는 tcpdump를 사용하지 못 할 수 있다. 또한 Pod가 root로 실행되지 않는 경우에는 apk-get 등으로 설치가 불가능하다.

 

이 경우에는 Ephemeral Containers를 사용하여 진행할 수 있다. ( tcpdump 이미지는 별도로 내부 registry에 가져다 놓으면 오프라인 환경에서도 tcpdump가 가능하다. )

# kubectl debug -it sampleapp-6c65c5cdb7-d6lrq -n test --image=10.10.20.10:5000/tcpdump --target=sampleapp -- /bin/sh
Targeting container "sampleapp". If you don't see processes from this container it may be because the container runtime doesn't support this feature.
Defaulting debug container name to debugger-phbrs.
If you don't see a command prompt, try pressing enter.

tcpdump 명령어로 패킷을 조회할 수 있다.

/ # tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
02:33:41.378181 IP 10-244-0-7.ingress-nginx-controller.ingress-nginx.svc.cluster.local.58826 > sampleapp-6c65c5cdb7-d6lrq.80: Flags [S], seq 3471741613, win 29200, options [mss 1460,sackOK,TS val 396323759 ecr 0,nop,wscale 7], length 0
02:33:41.378216 IP sampleapp-6c65c5cdb7-d6lrq.80 > 10-244-0-7.ingress-nginx-controller.ingress-nginx.svc.cluster.local.58826: Flags [S.], seq 3340565320, ack 3471741614, win 28960, options [mss 1460,sackOK,TS val 396323759 ecr 396323759,nop,wscale 7], length 0
02:33:41.378236 IP 10-244-0-7.ingress-nginx-controller.ingress-nginx.svc.cluster.local.58826 > sampleapp-6c65c5cdb7-d6lrq.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 396323759 ecr 396323759], length 0
02:33:41.378273 IP 10-244-0-7.ingress-nginx-controller.ingress-nginx.svc.cluster.local.58826 > sampleapp-6c65c5cdb7-d6lrq.80: Flags [P.], seq 1:336, ack 1, win 229, options [nop,nop,TS val 396323759 ecr 396323759], length 335: HTTP: GET / HTTP/1.1
02:33:41.378279 IP sampleapp-6c65c5cdb7-d6lrq.80 > 10-244-0-7.ingress-nginx-controller.ingress-nginx.svc.cluster.local.58826: Flags [.], ack 336, win 235, options [nop,nop,TS val 396323759 ecr 396323759], length 0
02:33:41.378418 IP sampleapp-6c65c5cdb7-d6lrq.58712 > kube-dns.kube-system.svc.cluster.local.53: 35745+ PTR? 7.0.244.10.in-addr.arpa. (41)
02:33:41.378737 IP kube-dns.kube-system.svc.cluster.local.53 > sampleapp-6c65c5cdb7-d6lrq.58712: 35745*- 2/0/0 PTR 10-244-0-7.ingress-nginx-controller-admission.ingress-nginx.svc.cluster.local., PTR 10-244-0-7.ingress-nginx-controller.ingress-nginx.svc.cluster.local. (259)
02:33:41.379467 IP sampleapp-6c65c5cdb7-d6lrq.58907 > kube-dns.kube-system.svc.cluster.local.53: 52231+ PTR? 10.0.96.10.in-addr.arpa. (41)
02:33:41.379627 IP kube-dns.kube-system.svc.cluster.local.53 > sampleapp-6c65c5cdb7-d6lrq.58907: 52231*- 1/0/0 PTR kube-dns.kube-system.svc.cluster.local. (116)
^C
9 packets captured
15 packets received by filter
6 packets dropped by kernel

 

이 방법외에도 container가 수행중인 노드에서 nsenter를 사용하여 tcpdump 를 사용하는 방법도 있다.

반응형
Comments