kubernetes
ksniff 로 kubernetes 컨테이너 패킷 캡쳐
misankim
2024. 4. 6. 20:19
일반적으로 파드 내부의 컨테이너로 들어오고 나가는 네트워크 패킷은 확인할 일은 많지 않지만,
간혹 트러블 슈팅 목적으로 HTTP 헤더 등 패킷 상의 Raw 데이터를 직접 확인하고자 하는 경우
컨테이너 안에서 패킷 캡쳐를 하고 싶을 때가 있습니다.
ksniff 는 kubectl CLI의 플러그인 중 하나로, 파드 내부에 tcpdump 를 실행하여 로컬 랩탑의 wireshark 로 패킷 덤프를 전달해줍니다.
root 로 실행되는 컨테이너는 바로 파드 내부에서 tcpdump 를 실행하며, 일반 사용자로 실행되는 컨테이너는 -p 옵션을 부여하여 별도의 파드가 실행되어 대상 컨테이너의 패킷을 전달해줍니다.
(아래 커맨드는 Mac OS를 기준으로 작성되었습니다.)
# ksniff 설치
kubectl krew install sniff
# wireshark 설치
참고. https://formulae.brew.sh/formula/wireshark
brew install --cask wireshark
# 특정 파드의 패킷 캡쳐
# 특정 컨테이너의 패킷을 캡쳐하려면 -c 옵션으로 컨테이너 지정
# 일반 사용자로 실행되는 컨테이너는 -p 옵션 필요
# 특정 인터페이스를 지정하려면 -i 옵션으로 인터페이스 지정
1. 가장 기본적인 캡쳐 방식
kubectl sniff my-flask-app-6cd76fccb8-5fxrh
2. 80 포트로 필터 지정
kubectl sniff my-flask-app-6cd76fccb8-5fxrh -f 'port 80'
3. istio-proxy 컨테이너의 loopback 인터페이스 지정
kubectl sniff my-flask-app-6cd76fccb8-7r6s7 -p -c istio-proxy -f 'port 80' -i lo
4. 특정 tcp flag 를 기준으로 필터 지정
kubectl sniff my-flask-app-6cd76fccb8-7r6s7 -p -c istio-proxy -f 'tcp[tcpflags] & (tcp-syn|tcp-fin|tcp-rst) != 0' -i lo
# 패킷 캡쳐하여 터미널 상의 표준 출력으로 전송
컨테이너의 패킷을 캡쳐하여 wireshark 로 전송하는 것이 아닌 터미널 상의 표준 출력으로 표시해줍니다.
kubectl sniff my-flask-app-6cd76fccb8-5fxrh -i eth0 -p -o - | tshark -xnV -r -
# 패킷 캡쳐 파일(.pcapng) 분할하기
wireshark 로 전송된 패킷 덤프 데이터는 로컬 PC에 .pcapng 파일로 저장할 수 있는데 때로는 캡쳐된 패킷의 양이 너무 많기에 이 패킷 덤프 파일을 시간이나 패킷의 수 단위로 나누어 분할하고 싶을 때가 있습니다. 이 때 아래 커맨드로 .pcapng 파일을 분할합니다.
# output 파일명 뒤에 자동으로 _00000_패킷_시작_시간, _00001_패킷_시작_시간, _00002_패킷_시작_시간... 와 파일명 접미사가 붙어서 분할됨
시간 기준으로 분할(600초 단위로 파일 분할)
editcap -i 600 origin.pcapng origin_split_by_time.pcapng
패킷 갯수 기준으로 분할(패킷 100만개 단위로 파일 분할)
editcap -c 1000000 origin.pcapng origin_split_by_count.pcapng