서버에 네트워크 카드를 한 장 더 꽂았거나, 하드웨어 교체 후 인터페이스 이름이 eth0 에서 ens192 같은 형태로 바뀐 뒤에 일부 파드가 올라오지 않는다. 노드 자체는 Ready 이고 노드 IP 도 그대로인데, 특정 파드의 readiness probe 가 connection refused 로 실패하거나 다른 파드에서 그 서비스로 접근이 안 된다.
원인은 대개 CNI 가 노드 IP 를 자동 감지하는 방식에 있다. Calico 계열(Calico · Canal)은 IP_AUTODETECTION_METHOD 로 어느 인터페이스의 주소를 노드 IP 로 삼을지 정하는데, 기본값 first-found 는 이름 순으로 처음 발견한 인터페이스를 고른다. NIC 이 늘거나 이름이 바뀌면 고르는 대상이 바뀐다.
# Calico
kubectl -n kube-system get ds calico-node \
-o jsonpath='{.spec.template.spec.containers[0].env}' | tr ',' '\n' | grep -i AUTODETECT
# Canal (내부에 calico-node 컨테이너가 있다)
kubectl -n kube-system get ds canal \
-o jsonpath='{.spec.template.spec.containers[?(@.name=="calico-node")].env}' | tr ',' '\n'
# 실제로 어떤 주소가 노드 IP 로 등록됐는지
kubectl get nodes -o wide
kubectl get node <node> -o jsonpath='{.metadata.annotations.projectcalico\.org/IPv4Address}'
노드의 InternalIP 와 Calico 가 등록한 IPv4Address 가 다르면 그것이 원인이다.
first-found 를 벗어나 명시적인 방법으로 바꾼다.
| 값 | 동작 |
|---|---|
first-found |
이름 순으로 처음 발견한 인터페이스. NIC 변경에 취약 |
interface=ens192 |
정규식으로 인터페이스 이름 지정 |
can-reach=10.0.0.1 |
지정한 주소로 나가는 경로의 인터페이스를 선택 |
kubernetes-internal-ip |
노드의 InternalIP 를 그대로 사용 |
인터페이스 이름은 서버마다 다를 수 있으므로, 클러스터 전체에 하나를 적용해야 한다면 can-reach 나 kubernetes-internal-ip 가 안전하다.
kubectl -n kube-system set env ds/calico-node \
IP_AUTODETECTION_METHOD=kubernetes-internal-ip
Canal 이나 배포판이 관리하는 매니페스트(RKE2 의 /var/lib/rancher/rke2/server/manifests/)라면 데몬셋을 직접 고쳐도 배포판이 되돌린다. 해당 HelmChartConfig 나 매니페스트 원본을 고쳐야 한다.
CNI 말고도 인터페이스 이름을 직접 쓰는 곳이 있다.
# 워크로드 스펙에서 인터페이스 이름 참조 찾기
kubectl get deploy,ds,sts -A -o yaml | grep -nE 'eth0|ens[0-9]+|interface='
# kube-proxy 의 바인딩 주소
kubectl -n kube-system get cm kube-proxy -o yaml | grep -i bindAddress
# 노드에서 실제 인터페이스와 라우팅
ip -br addr
ip route get 8.8.8.8
kube-proxy 가 --bind-address 나 --nodeport-addresses 로 특정 주소를 잡고 있으면 NodePort 가 새 NIC 쪽에만 열리거나, 반대로 안 열린다. netstat -nltp | grep <포트> 로 어느 주소에 바인딩됐는지 확인한다.
설정을 바꿨으면 재기동 순서를 지킨다. CNI 가 먼저 정상화돼야 그 위의 파드가 제대로 뜬다.
kubectl -n kube-system rollout restart ds/calico-node
kubectl -n kube-system rollout status ds/calico-node
# CNI 가 정상화된 뒤 영향받은 워크로드 재기동
kubectl -n <ns> rollout restart deploy/<name>
노드 IP 자체가 바뀐 것이 아니라 인터페이스 이름만 바뀐 경우, 클러스터 전체를 재기동할 필요는 없다. 다만 kubelet 이 --node-ip 를 명시하고 있었다면 그 값도 함께 확인한다.
원본 대화에서는 위 확인을 모두 거쳤음에도 특정 파드(TCP ingress controller)의 readiness probe 실패가 끝내 해소되지 않았다. 기록에 남은 단서는 이렇다.
describe 에는 Readiness probe failed: dial tcp ...: connect: connection refused 와 Deployment does not have minimum availability 만 나온다.netstat -nltp | grep 8000 을 보면 프로세스가 추가된 NIC 의 주소에 바인딩돼 있었다.read udp <corednsIP>:53: connection refused 와 i/o timeout 이 대량으로 찍히고 있었다.애플리케이션이 시작 시점에 자기가 바인딩할 주소를 자동 선택하는 구현이라면, 추가된 NIC 를 잡는 순간 probe 가 바라보는 파드 IP 와 어긋난다. 이런 경우 해법은 CNI 설정이 아니라 애플리케이션의 바인딩 주소를 0.0.0.0 으로 고정하거나 추가 NIC 을 내리는 쪽이다. 추가 NIC 이 당장 필요 없다면 ip link set <iface> down 으로 내려 두고 증상이 사라지는지부터 확인하면 원인을 빠르게 가를 수 있다.
network plugin is not ready 계열 증상.