콘텐츠로 이동






MetalLB적용 이슈

ESXi VMXNET3 환경에서 MetalLB webhook timeout 해결하기

Kubernetes에 MetalLB를 설치한 뒤 IPAddressPool을 생성하는 과정에서 admission webhook timeout이 발생했다. 처음에는 MetalLB 설정 문제를 의심했지만, 패킷 캡처와 커널 통계를 통해 Calico VXLAN 패킷의 수신 checksum 오류를 확인했다. Offload 설정 변경으로 checksum 오류는 개선됐지만 timeout은 계속 발생했다. 이후 가상 NIC를 VMXNET3에서 E1000E로 변경하자 webhook이 정상적으로 응답했고, 그동안 확인되지 않았던 IP Pool 설정 오류가 반환됐다. 이 글에서는 발생 현상, 진단 과정, 조치 방법, 관련 VMware 이슈, 가상 NIC별 차이를 정리한다.

이번 사례에서 확인된 사실과 추정 원인은 구분한다. NIC 변경 후 통신이 복구됐지만, 특정 ESXi 또는 VMXNET3 버그로 확정한 것은 아니다.

1. 환경과 발생 현상

구성 환경

항목 구성
가상화 플랫폼 VMware ESXi
Kubernetes 구성 Control-plane 1대, worker 1대
Control-plane k8s-m1, 192.168.100.11, k8s-m2, 192.168.100.12,k8s-m3, 192.168.100.13
Worker k8s-w1, 192.168.0.21, k8s-w2, 192.168.0.22, k8s-w3, 192.168.0.23, k8s-w4, 192.168.0.24
Linux 커널 5.14.0-687.54.1.el9_8.x86_64
변경 전 가상 NIC VMXNET3
변경 후 가상 NIC E1000E
변경 전 NIC 드라이버 vmxnet3
드라이버 버전 1.9.0.0-k-NAPI
CNI Calico
Pod CIDR 10.233.64.0/18
캡슐화 모드 VXLAN Always
VXLAN 포트 UDP 4789
VXLAN VNI 4096
VXLAN MTU 1450
MetalLB 버전 v0.16.1
MetalLB 설치 방식 Helm
MetalLB 네임스페이스 metallb
MetalLB 광고 방식 L2

ESXi 버전과 빌드, NSX 사용 여부, Calico 버전은 분석 당시 확보하지 못했다. 따라서 공식 이슈와 증상을 비교할 수는 있지만, 특정 버그의 적용 여부까지 확정하지는 않았다.

최초 오류

MetalLB 설치 후 Pool 설정을 적용했다.

kubectl apply -f pool.yml

다음과 같은 오류가 발생했다.

Error from server (InternalError):
error when creating "pool.yml":
Internal error occurred:
failed calling webhook "ipaddresspoolvalidationwebhook.metallb.io":
failed to call webhook:
Post "[https://metallb-webhook-service.metallb.svc:443/validate-metallb-io-v1beta1-ipaddresspool?timeout=10s](https://metallb-webhook-service.metallb.svc:443/validate-metallb-io-v1beta1-ipaddresspool?timeout=10s)":
context deadline exceeded

L2Advertisement에서도 동일한 유형의 오류가 발생했다.

failed calling webhook "l2advertisementvalidationwebhook.metallb.io"
context deadline exceeded

이 오류는 Pool 주소가 잘못됐다는 검증 결과가 아니다.

API Server가 MetalLB admission webhook을 호출했지만 제한 시간 안에 응답을 받지 못했다는 의미다.

다른 Ingress와 Service는 정상인데 왜 실패했을까?

일반 애플리케이션 접속과 admission webhook 호출은 서로 다른 경로를 사용할 수 있다.

애플리케이션 Pod가 worker에 모여 있다면 다음 요청은 같은 노드 내부에서 처리될 수 있다.

클라이언트
  → worker의 Ingress controller
  → 같은 worker의 backend Pod

반면 MetalLB Pool 생성은 API Server에서 시작하는 요청이다.

kubectl apply
  → master의 kube-apiserver
  → MetalLB webhook Service
  → worker의 MetalLB controller Pod

따라서 다음 두 가지는 별도로 검증해야 한다.

  • Ingress와 Service를 통한 애플리케이션 접속
  • API Server에서 admission webhook으로의 접속

이번 환경에서는 worker 로컬 접속은 정상이고, master에서 worker Pod로 향하는 접속이 실패했다.

2. 진단 과정

Service와 Endpoint 확인

먼저 MetalLB Pod와 webhook Service를 확인했다.

kubectl -n metallb get pods -o wide

kubectl -n metallb get svc metallb-webhook-service -o yaml

kubectl -n metallb get endpointslices \
  -l kubernetes.io/service-name=metallb-webhook-service \
  -o yaml

확인 결과는 다음과 같았다.

항목 결과
Controller 상태 1/1 Running
Controller 재시작 없음
Controller 실행 노드 k8s-w1
Controller Pod IP 10.233.103.150
Webhook Service IP 10.233.37.54
Service 포트 TCP 443
Endpoint 포트 TCP 9443
Endpoint 상태 ready: true, serving: true

Service의 포트 설정은 다음과 같았다.

spec:
  clusterIP: 10.233.37.54
  ports:
    - port: 443
      protocol: TCP
      targetPort: 9443

실제 경로는 다음과 같다.

metallb-webhook-service
10.233.37.54:443
  → controller Pod
    10.233.103.150:9443

Service selector와 Endpoint 연결에는 누락이 보이지 않았다.

Controller 로그 확인

kubectl -n metallb logs \
  metallb-controller-75f6b7f996-nrjqs \
  --tail=100

로그에는 다음 내용이 있었다.

certs are ready in /tmp/k8s-webhook-server/serving-certs
CA certs are injected to webhooks
webhooks enabled
Starting webhook server
Serving webhook server ... port: 9443

검증 경로도 등록됐다.

/validate-metallb-io-v1beta1-ipaddresspool
/validate-metallb-io-v1beta1-l2advertisement

초기화 중 Secret 갱신 충돌과 ConfigurationState 생성 전 오류가 있었지만, 이후 인증서 준비와 webhook 기동이 완료됐다.

따라서 초기 오류 로그만 보고 인증서 Secret을 삭제하거나 MetalLB를 재설치하지 않았다.

Master에서 접속 테스트

Pod IP에 직접 접근했다.

curl -vk --noproxy '*' \
  --connect-timeout 3 --max-time 5 \
  [https://10.233.103.150:9443/](https://10.233.103.150:9443/)

결과:

Trying 10.233.103.150:9443...
Connection timed out after 3001 milliseconds

Service IP 경유도 확인했다.

curl -vk --noproxy '*' \
  --connect-timeout 3 --max-time 5 \
  [https://10.233.37.54:443/](https://10.233.37.54:443/)

이 요청도 TCP 연결 단계에서 timeout이 발생했다.

Worker에서 접속 테스트

동일한 Pod IP에 worker에서 접근했다.

curl -vk --noproxy '*' \
  --connect-timeout 3 --max-time 5 \
  [https://10.233.103.150:9443/](https://10.233.103.150:9443/)

결과:

Connected to 10.233.103.150 port 9443
SSL connection using TLSv1.3
HTTP/1.1 404 Not Found

루트 경로 /의 404는 이 테스트에서 연결 실패를 의미하지 않는다.

TCP 연결, TLS handshake, HTTP 응답까지 진행됐으므로 webhook 프로세스가 응답한다는 근거다.

다만 curl -k는 인증서 검증을 생략한다. 따라서 이 테스트는 연결 확인용이며, API Server가 사용하는 CA 신뢰 검증까지 확인한 것은 아니다.

Calico 캡슐화 설정 확인

kubectl get ippools.crd.projectcalico.org -o yaml
spec:
  cidr: 10.233.64.0/18
  ipipMode: Never
  vxlanMode: Always
  natOutgoing: true

Calico는 IPIP가 아닌 VXLAN Always 모드였다.

라우팅과 터널 매핑 확인

두 노드에서 다음을 조회했다.

ip route get 10.233.103.150
ip -d link show vxlan.calico
ip neigh show dev vxlan.calico
bridge fdb show dev vxlan.calico

Master의 목적지 경로:

10.233.103.150 via 10.233.103.128 dev vxlan.calico
src 10.233.106.128

Worker의 목적지 경로:

10.233.103.150 dev cali5fb4ce83675
src 192.168.0.22

터널 매핑은 다음과 같았다.

방향 상대 터널 IP 상대 MAC 상대 외부 IP
Master → worker 10.233.103.128 aa:bb:cc 192.168.0.22
Worker → master 10.233.106.128 a1:b2:c3 192.168.100.11

양쪽 VXLAN 인터페이스는 VNI 4096, UDP 4789, MTU 1450으로 설정돼 있었다.

라우트와 Neighbor/FDB가 존재한다는 사실은 설정 확인일 뿐, 실제 패킷 전달 성공을 보장하지는 않는다.

패킷 캡처

Worker에서 외부 VXLAN과 내부 TCP를 함께 확인했다.

sudo tcpdump -lni any -nn -vv \
  '(host 192.168.100.11 and udp port 4789) or
   (host 10.233.103.150 and tcp port 9443)'

Master에서 curl을 실행하자 다음 패킷이 관찰됐다.

eth0 In
192.168.100.11 → 192.168.0.22:4789
[bad udp cksum]

내부 TCP:
10.233.106.128 → 10.233.103.150:9443
Flags [S], incorrect checksum

SYN 재전송은 있었지만 SYN-ACK은 보이지 않았다.

초기에는 내부 TCP가 vxlan.calico에서도 관찰되지 않았다.

송신 캡처의 bad checksum은 offload 때문에 표시될 수 있다. 따라서 tcpdump 출력만으로 실제 checksum 오류를 확정하면 안 된다.

UDP 수신 오류 카운터 확인

Worker에서 요청 전후 통계를 비교했다.

nstat -az | grep -E 'UdpInErrors|UdpInCsumErrors'
ip -s link show vxlan.calico
항목 요청 전 요청 후
UdpInErrors 1608 1610
UdpInCsumErrors 1608 1610
VXLAN RX packets 12 12

수신 캡처의 checksum 오류와 함께 실제 커널의 UDP checksum 오류 카운터가 증가했다.

카운터는 호스트 전체 통계지만, 요청 시점의 SYN 재전송과 증가량이 일치했다.

이 단계에서 실제 수신 checksum 오류가 발생한다는 강한 근거를 확보했다.

다른 차단 요인 확인

조회한 정책은 모두 없었다.

kubectl get networkpolicy -A
kubectl get networkpolicies.crd.projectcalico.org -A
kubectl get globalnetworkpolicies.crd.projectcalico.org
kubectl get hostendpoints.crd.projectcalico.org
No resources found

또한 해당 환경에서는 방화벽과 SELinux를 사용하지 않았다.

Worker의 forwarding은 활성화돼 있었다.

net.ipv4.ip_forward = 1
vxlan.calico forwarding = 1

역방향 검사 설정과 통계는 다음과 같았다.

all rp_filter = 0
vxlan.calico rp_filter = 1
TcpExtIPReversePathFilter = 0

rp_filter=1이라는 사실만으로 원인이라고 판단하지 않았다. 확인된 통계에는 역방향 검사 드롭 증가가 없었다.

3. 원인과 관련 이슈

확인된 사실과 추정 원인

이번 장애는 한 단계의 문제로만 설명하기 어렵다.

단계 관찰 판단
초기 UDP checksum 오류 증가 실제 수신 checksum 문제 확인
Offload 변경 후 오류 증가 중단, VXLAN RX 증가 초기 checksum 단계 개선
이후 VXLAN 내부 SYN 수신, Pod 방향 전달 미관찰 추가 전달 문제 존재
NIC 변경 후 Webhook 검증 응답 반환 NIC 변경 후 통신 복구

가장 타당한 추정 원인은 VMXNET3·ESXi·Calico VXLAN 사이의 checksum/offload 또는 패킷 전달 경로 문제다.

하지만 checksum 개선 후 남은 전달 실패의 정확한 드롭 지점은 확인하지 못했다.

또한 NIC 변경에는 재부팅과 네트워크 재초기화가 동반될 수 있으므로, 전체 장애를 특정 VMXNET3 버그 하나로 확정하지는 않았다.

VMware KB 324199

관련 문서:

VM VXLAN traffic fails on a host prepared for NSX

Linux VM이 생성한 VXLAN 트래픽과 VMware tunnel offload 처리 관련 이슈다.

공식 문서의 주요 내용:

  • 표준 VXLAN 포트 관련 문제는 ESXi 6.7 패치 ESXi670-202111001과 ESXi 7 Update 3에서 수정됐다.
  • 비표준 VXLAN 포트는 Linux VMXNET3 드라이버 수정과 관련된다.
  • 우회책으로 게스트 tunnel offload 비활성화를 제시한다.
sudo ethtool -K eth0 \
  tx-udp_tnl-segmentation off \
  tx-udp_tnl-csum-segmentation off

다만 이 KB는 NSX가 준비된 호스트라는 조건이 있다. 현재 환경의 NSX 여부를 확인하지 않았으므로 동일 버그라고 단정할 수 없다.

VMware KB 440703

관련 문서:

Intermittent packet drops for dual VXLAN and Geneve encapsulated packets

게스트 VXLAN 위에 NSX Geneve가 추가되는 이중 캡슐화 환경의 checksum 문제다.

발생 과정:

게스트에서 checksum 계산을 offload에 위임
  → VXLAN 패킷 생성
  → NSX에서 Geneve 캡슐화 추가
  → 가장 안쪽 TCP checksum 처리 누락
  → 수신 게스트에서 패킷 드롭

문서에는 VMXNET3에서 발생하고 E1000에서는 발생하지 않는다고 설명돼 있다.

현재 사례와 비교할 때 다음 차이를 고려해야 한다.

  • 공식 사례는 NSX의 이중 캡슐화 환경이다.
  • 공식 사례의 E1000과 이번에 사용한 E1000E는 서로 다른 NIC다.
  • 공식 사례는 내부 TCP checksum을 설명한다.
  • 이번 초기 증상은 수신 UDP checksum 오류였다.

따라서 관련 처리 문제의 근거로 참고할 수 있지만, 현재 장애와 동일한 버그라고 확정할 수는 없다.

Kubespray Issue 8992

관련 문서:

VXLAN: bad UDP checksums

Kubespray와 Calico VXLAN 환경에서 노드 간 통신이 실패한 사례다.

다음 설정이 우회책으로 제시됐다.

sudo ethtool -K vxlan.calico tx-checksum-ip-generic off

이러한 우회책은 커널, Calico 버전, NIC와 하이퍼바이저 조합에 따라 효과가 달라질 수 있다.

검증 없이 모든 환경에 영구 적용하지 않는 것이 좋다.

4. 조치와 정상화 검증

기존 offload 상태 저장

변경 전에 실제 설정을 저장했다.

sudo ethtool -k eth0 \
  > /tmp/eth0-offload-before.txt

sudo ethtool -k vxlan.calico \
  > /tmp/vxlan-offload-before.txt

진단 과정에서는 설정을 하나씩 변경하고 결과를 비교하는 것이 좋다.

여러 기능을 동시에 변경하면 어느 기능이 영향을 줬는지 판단하기 어렵다.

Offload 비활성화

테스트 과정에서 다음 기능을 비활성화했다.

sudo ethtool -K eth0 \
  tx-udp_tnl-segmentation off \
  tx-udp_tnl-csum-segmentation off

sudo ethtool -K eth0 \
  tx-checksum-ip-generic off

sudo ethtool -K vxlan.calico \
  tx-checksum-ip-generic off

변경 후 상태를 즉시 확인했다.

sudo ethtool -k eth0 | grep -E \
  'tx-checksum-ip-generic|tx-udp_tnl'

sudo ethtool -k vxlan.calico | grep \
  tx-checksum-ip-generic

실제 off 상태에서 테스트해야 한다. 명령을 실행했다는 사실만으로 설정 적용을 가정하면 안 된다.

Offload 변경 결과

Checksum 오류 카운터는 더 이상 증가하지 않았다.

항목 요청 전 요청 후
UdpInErrors 1610 1610
UdpInCsumErrors 1610 1610
VXLAN RX packets 23 25
VXLAN RX bytes 8693 8813

내부 SYN도 VXLAN 인터페이스에서 관찰됐다.

vxlan.calico In
10.233.106.128 → 10.233.103.150:9443
Flags [S]

그러나 Pod 방향 인터페이스로 전달되는 패킷은 관찰되지 않았고 curl timeout도 지속됐다.

따라서 결과는 다음처럼 해석했다.

Offload 변경으로 checksum 드롭은 개선됐다. 하지만 webhook 연결을 방해하는 추가 전달 문제가 남아 있었다.

NIC를 E1000E로 변경

이후 가상 NIC를 VMXNET3에서 E1000E로 변경했다.

NIC 변경 시에는 다음을 준비한다.

  1. vSphere 콘솔 접근을 확보한다.
  2. 기존 NIC의 MAC, Port Group, IP, 라우팅을 기록한다.
  3. NetworkManager 프로파일을 기록한다.
  4. 중단 가능한 시간에 VM을 정상 종료한다.
  5. NIC 변경 후 올바른 Port Group 연결을 확인한다.
  6. 부팅 후 인터페이스 이름과 프로파일 연결을 확인한다.
  7. 노드 IP와 Kubernetes 상태를 검증한다.

변경 전 기록:

ip -br addr
ip route
nmcli -f NAME,UUID,DEVICE connection show

변경 후 확인:

ip -br addr
ip route

sudo ethtool -i <실제-인터페이스>

kubectl get nodes -o wide
kubectl -n kube-system get pods -o wide
kubectl -n metallb get pods -o wide

NIC 변경 후 MAC이나 인터페이스 이름이 달라질 수 있다. Worker가 한 대뿐이면 해당 노드의 애플리케이션도 중단될 수 있으므로 작업 시간을 확보한다.

Pod 재생성 후에는 controller Pod IP가 변경될 수 있다. 기존 IP로 테스트하지 말고 현재 주소를 다시 확인한다.

NIC 변경 후 오류 변화

Pool 설정을 다시 적용하자 다음 결과가 반환됐다.

l2advertisement.metallb.io/vip-l2 created

admission webhook "ipaddresspoolvalidationwebhook.metallb.io"
denied the request:

parsing address pool vip-pool:
invalid CIDR "192.168.0.100"

이것은 기존 timeout과 다른 오류다.

변경 전 변경 후
Webhook 호출 자체가 timeout Webhook이 요청을 수신하고 검증 결과 반환
통신 문제 Pool 주소 형식 문제

Pool 생성은 아직 실패했지만 API Server와 webhook 사이의 왕복 통신은 복구됐음을 확인했다.

Pool 주소 형식 수정

MetalLB Pool은 CIDR 또는 IP 범위 형식을 사용한다.

목적 설정
단일 IPv4 주소 "192.168.0.100/32"
IP 범위 "192.168.0.100-192.168.0.110"
CIDR 대역 "192.168.0.96/28"

단일 주소를 192.168.0.100처럼 입력하면 CIDR 형식 오류가 발생할 수 있다.

이번에는 다음처럼 범위를 지정했다.

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: vip-pool
  namespace: metallb
spec:
  addresses:
    - "192.168.0.100-192.168.0.110"
  autoAssign: true
***
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: vip-l2
  namespace: metallb
spec:
  ipAddressPools:
    - vip-pool
kubectl apply -f pool.yml

kubectl -n metallb get \
  ipaddresspool,l2advertisement

MetalLB 리소스의 네임스페이스는 설치 네임스페이스와 일치시킨다.

VIP로 사용할 주소는 DHCP 범위와 다른 장비의 고정 IP에서 제외해 예약한다.

설치 절차 정리

MetalLB 설치는 다음 순서로 정리할 수 있다.

kube-proxy 모드 확인
  → IPVS라면 strictARP 설정
  → MetalLB Helm 설치
  → Controller / speaker 준비 확인
  → Webhook 통신 확인
  → IPAddressPool 생성
  → L2Advertisement 생성
  → Ingress controller Service를 LoadBalancer로 변경
  → VIP 할당 및 서비스 접속 확인

IPVS를 사용할 때는 kube-proxy 설정의 strictARP를 활성화한다.

mode: ipvs
ipvs:
  strictARP: true
kubectl -n kube-system edit cm kube-proxy

kubectl -n kube-system rollout restart \
  daemonset kube-proxy

kubectl -n kube-system rollout status \
  daemonset kube-proxy \
  --timeout=120s

strictARP는 IPVS의 ARP 동작을 위한 설정이다. Admission webhook timeout의 직접적인 해결책은 아니다.

로컬 MetalLB Helm chart 설치 예시:

helm install metallb ./ \
  -f values.yaml \
  -n metallb \
  --create-namespace \
  --wait \
  --timeout 5m

이미 release가 존재하면 helm install을 반복하지 말고 현재 release와 values를 확인한 뒤 upgrade한다.

HAProxy Technologies의 Kubernetes Ingress 차트를 사용한다면 values를 다음처럼 설정한다.

controller:
  service:
    type: LoadBalancer

변경 대상은 HAProxy ingress controller를 외부에 노출하는 Service다. Backend 애플리케이션의 Service를 모두 LoadBalancer로 변경하는 것은 아니다.

5. NIC 차이와 운영 판단

VMXNET3와 E1000E 비교

항목 VMXNET3 E1000E
구현 방식 VMware 준가상화 NIC Intel 82574 NIC 에뮬레이션
Linux 드라이버 vmxnet3 e1000e
설계 목적 가상 환경 성능과 효율 최적화 실제 NIC와 유사한 장치 인터페이스
CPU 효율 일반적으로 유리 에뮬레이션 오버헤드 발생
병렬 처리 RSS와 멀티큐 지원 고성능 병렬 처리 측면에서 상대적으로 불리
Offload 다양한 checksum·segmentation 기능 기능 범위와 처리 방식이 다름
일반적 사용 고성능 서버 VM 호환성 확보와 장애 비교 테스트

VMXNET3는 가상화 환경에 최적화된 NIC다.

반면 E1000E는 실제 Intel 장치의 동작을 에뮬레이션한다. 따라서 높은 패킷 처리량이나 CPU 효율이 필요한 환경에서는 VMXNET3가 일반적으로 유리하다.

E1000E에도 offload 기능이 있을 수 있다. 따라서 다음 설명은 정확하지 않다.

E1000E는 offload가 없어서 문제가 해결됐다.

이번 사례에서는 다음처럼 이해하는 것이 적절하다.

E1000E는 다른 드라이버와 가상 장치 처리 경로를 사용한다.
그 결과 문제가 발생하던 조합을 우회했을 가능성이 있다.

NIC 비교 자료:

Choosing a network adapter for a virtual machine

RSS and multiqueue support in Linux driver for VMXNET3

운영 환경에서의 선택

소규모 테스트 환경이라면 정상 동작하는 E1000E를 유지할 수 있다.

하지만 트래픽이 많은 Kubernetes 운영 환경에서는 다음을 검증한 뒤 영구 사용 여부를 결정한다.

  • 양방향 노드 간 Pod 통신
  • DNS 조회
  • Admission webhook 호출
  • ClusterIP, NodePort, LoadBalancer 접속
  • TCP 처리량과 재전송
  • 노드 CPU 사용률
  • ESXi 버전과 빌드
  • NSX 사용 여부
  • VMXNET3 드라이버와 커널 수정 여부

VMXNET3로 되돌려 재현 비교를 한다면 중단 가능한 테스트 환경에서 수행한다.

NIC를 바꾼 결과만으로 정확한 버그를 확정하면 안 된다. 재부팅과 Calico 재초기화가 함께 영향을 줬을 가능성도 남아 있다.

임시 offload 설정 관리

ethtool -K로 변경한 설정은 재부팅이나 인터페이스 재생성 뒤 유지되지 않을 수 있다.

영구 조치 전에 실제 적용 상태를 다시 확인한다.

sudo ethtool -k <실제-인터페이스>
sudo ethtool -k vxlan.calico

원복할 때는 모든 기능을 일괄적으로 켜지 않는다. 변경 전 기록한 값에 맞춰 복원한다.

NIC가 변경됐다면 이전 VMXNET3 설정을 E1000E에 그대로 적용하지 말고, 새 드라이버의 기능 목록을 확인한다.

장애 기록

이번 사례는 다음처럼 기록할 수 있다.

ESXi VMXNET3 환경의 Calico VXLAN 통신에서 수신 UDP checksum 오류와 MetalLB admission webhook timeout이 발생했다.

게스트 offload 비활성화로 checksum 오류는 개선됐으나 webhook timeout은 지속됐다. 이후 가상 NIC를 E1000E로 변경한 뒤 webhook 응답이 복구됐다.

VMXNET3·ESXi·Calico VXLAN 처리 경로의 호환 문제로 추정한다. 정확한 버그 식별과 checksum 개선 후 남았던 전달 실패 원인의 확정에는 ESXi/NSX 구성 확인 및 동일 조건의 재현 비교가 필요하다.

이번 분석에서 중요한 점은 오류를 다음 세 단계로 구분한 것이다.

1. Webhook timeout
   → API Server에서 webhook으로의 통신 실패

2. UDP checksum 오류
   → VXLAN 수신 처리 단계의 패킷 드롭

3. invalid CIDR
   → 통신 복구 후 확인된 Pool 설정 오류

동일한 kubectl apply 실패라도 원인은 서로 다를 수 있다. 오류 메시지의 변화, 패킷 경로, 커널 카운터를 함께 확인해야 불필요한 재설치나 설정 변경을 줄일 수 있다.