Intro
Pod가 클러스터 내부 서비스, Pod로 연결이 안되는 통신 문제가 있었다.
네트워크 상 큰 문제는 보이지 않았고, tcpdump를 떠보니 retransmission이 계속해서 발생하고 있었다.
따로 firewall도 없고 sg, route table, nat 등 네트워크 구성에도 문제가 없었다.
커널레벨에서 동작을 봐야하는것일까..?
pwru (Packet, Where Are You?)
https://github.com/cilium/pwru
cilium에서 개발한 리눅스 커널에서 ebpf 네트워크 패킷 트레이싱 도구이다.
내부 동작에 이해하기 위해서는 BTP와 krpobes를 잘 알아야한다.
BTF(BPF Type Format)은 리눅스 커널에서 제공해주는 정보로 커널에서 사용되는 네트워크 패킷의 구조체나 타입등을 알려준다. pwru는 BTF를 통해 네트워크 함수 인수들을 해석할 수 있게된다.
pwru에서는 BTF 정보를 vmlinux 파일에서 가져오는데, 커널에서 실행중인 모든 구조체에 대한 정보를 담고있다. 요걸 Go로 binding해서 커널 메모리에 어떻게 해당 패킷이 올라가있는지 확인하게 된다.
그리고 이러한 기능은 pwru가 kprobe를 붙여서 커널 네트워크 함수를 후킹하면서 동적으로, 실시간으로 확인할 수 있게 된다.
Installation and Usage
직접 노드에 binary를 실행할 수 있지만, 아래와 같이 hostNetwork를 통해 pod로 쉽게 설치할 수 있다.
#!/usr/bin/env bash
NODE=<hostname>
PWRU_ARGS="--output-tuple 'host 1.1.1.1'"
trap " kubectl delete --wait=false pod pwru " EXIT
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pwru
spec:
nodeSelector:
kubernetes.io/hostname: ${NODE}
containers:
- image: docker.io/cilium/pwru:latest
name: pwru
volumeMounts:
- mountPath: /sys/kernel/debug
name: sys-kernel-debug
securityContext:
privileged: true
command: ["/bin/sh"]
args: ["-c", "pwru ${PWRU_ARGS}"]
volumes:
- name: sys-kernel-debug
hostPath:
path: /sys/kernel/debug
type: DirectoryOrCreate
hostNetwork: true
hostPID: true
EOF
kubectl wait pod pwru --for condition=Ready --timeout=90s
kubectl logs -f pwru
PWRU_ARGS 의 경우 tcpdump를 사용하는 것과 비슷하게 쓸 수 있다. 다만 host == src로 이해하면 쉽다.
‘host [source-pod-ip]’ 나는 이렇게 작성했다.
그리고 생성한뒤 kubectl logs pwru -f 명령어로 로그를 살펴보면 된다.
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) __netif_rx
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) netif_rx_internal
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) enqueue_to_backlog
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) __netif_receive_skb
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) __netif_receive_skb_one_core
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) ip_rcv
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) ip_rcv_core
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) kfree_skb_reason(SKB_DROP_REASON_OTHERHOST)
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) skb_release_head_state
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) tcp_wfree
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) skb_release_data
0xffff8b58c09694e8 1 nc:580185 4026531840 0 ~i3e26d660904:21 0x0800 9001 60 10.1.165.64:37099→10.1.165.65:22(tcp) kfree_skbmem 이번 문제의 경우 SKB_DROP_REASON_OTHERHOST 오류를 확인할 수 있었다. 다음 문서[1]를 보면 다음과 같이 설명되어있다.
// @SKB_DROP_REASON_OTHERHOST: packet don't belong to current host
SKB_DROP_REASON_OTHERHOST,
host랑 맞지않는다..? pwru의 contributer는 MAC 주소가 잘못된 경우 나타난다고 한다.[2]
amazon-vpc-cni design proposal을 보면[3] pod 레벨에서 default gateway에 대한 static ARP 엔트리를 구성하게 되어있다.
ip netns exec ns1 arp -i veth-1c -s 169.254.1.1 <veth-1's mac> /* add static ARP entry for default gateway */
[3]에 참고된 이미지도 함께보자.

해당 문제는 네트워크 설정인 /etc/systemd/network/99-default.link 에MACAddressPolicy=Persistent 로 설정된 경우 MAC주소가 변경되어서 문제가 되는 것이다.
arp 보내기 위해 mac주소를 고정적으로 사용하는 static arp를 구성했는데, 바뀌어 버려서 커널단에서 패킷이 잘못들어온 것으로 판단하고 DROP된 것이다.
나의 경우 모든 패키지를 업데이트 해버려 systemd-udev 도 업그레이드가 됐고 systemd-udev 기본 MACAddressPolicy 설정이 Persistent로 바뀌면서 문제가 됐다. [4]
해당 문제는 EKS 팀에서 인지하고 빠르게 수정했다. [5]
참고자료
[1] https://codebrowser.dev/linux/linux/include/net/dropreason-core.h.html
[2] https://github.com/cilium/cilium/issues/28433#issuecomment-1754901244
[3] https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md
[4] https://fedoraproject.org/wiki/Changes/MAC_Address_Policy_none