Troubleshooting 2026.10.28 6 min read

Calico IPPool 조회 오류를 고치고 Pod 통신과 NetworkPolicy를 검증했다

첫 단계부터 조회 명령이 실패했다. IPPool을 확인하려고 사용한 명령에 대해 해당 리소스가 없다는 응답이 나왔다. 설치가 실패했다고 보기 전에, 내가 조회한 API 그룹이 실제 클러스터의 리소스와 맞는지 확인했다.

클러스터 구성을 마친 뒤에는 실제 트래픽을 흘려 보고 싶었다. 노드가 Ready이고 CNI Pod가 실행 중이어도, 내가 사용할 Pod 통신과 Service 경로가 동작하는지는 따로 확인해야 했다. 서로 다른 Worker에 테스트 Pod를 배치하고 Pod IP, DNS, Service와 정책을 차례로 검증하기로 했다.

첫 단계부터 조회 명령이 실패했다. IPPool을 확인하려고 사용한 명령에 대해 해당 리소스가 없다는 응답이 나왔다. 설치가 실패했다고 보기 전에, 내가 조회한 API 그룹이 실제 클러스터의 리소스와 맞는지 확인했다.

IPPool 이름보다 API 그룹을 먼저 확인했다

처음 사용한 조회 대상은 ippools.crd.projectcalico.org였다. 하지만 이 환경에서는 그 이름으로 조회되지 않았다. 다음처럼 API 리소스 목록에서 실제 제공되는 이름과 그룹을 찾는 흐름으로 바꿨다.

kubectl api-resources | grep -i ippool
kubectl get ippools.projectcalico.org -o yaml
kubectl get installation.operator.tigera.io default -o yaml

설치한 Native v3 API 그룹에 맞춰 조회하는 문제였다. 명령에서 리소스를 찾지 못한 사실과 CNI 전체가 동작하지 않는 상황을 바로 연결하면 점검 범위가 불필요하게 커질 수 있었다. 실제 API 목록을 보고 그 환경이 제공하는 이름으로 확인했다.

당시 설정 의도는 Iptables dataplane에 VXLAN 캡슐화를 사용하고 BGP는 비활성화하는 것이었다. 노드 주소는 Kubernetes NodeInternalIP를 기준으로 감지하도록 했다. IPPool과 Installation을 함께 확인하면서 내가 의도한 설정과 조회 결과를 대조하는 범위를 잡았다.

Calico IPPool의 VXLAN 설정과 BGP 비활성화
Calico IPPool의 VXLAN 설정과 BGP 비활성화.

두 Worker에 Pod를 나눠 배치했다

다음은 통신 시험이었다. 테스트 전용 namespace를 만들고 web Pod는 두 번째 Worker, client Pod는 첫 번째 Worker에 배치했다. 두 Pod가 우연히 같은 노드에 올라가면 노드 사이 통신을 확인하려던 의도가 흐려질 수 있어 배치 대상을 명시했다.

web에는 Nginx를, client에는 요청을 보낼 수 있는 BusyBox를 사용했다. 먼저 두 Pod의 Ready를 기다리고 wide 출력으로 실제 노드가 나뉘었는지 확인하는 순서였다. 이후 client에서 web의 Pod IP로 직접 HTTP 요청을 보내 Nginx HTML을 확인하도록 했다.

이 검사는 서로 다른 Worker의 Pod가 통신하는지를 확인하는 범위였다. 여기에 IPPool의 VXLAN 설정을 함께 확인했다. 패킷 캡처로 실제 VXLAN 프레임을 분석한 시험까지 한 것은 아니므로 두 결과를 합쳐 설명하는 데도 경계를 뒀다.

Pod 상태가 Ready라는 것과 요청이 상대 Pod까지 도달하는 것은 서로 다른 관측이었다. 배치 노드, Pod IP와 HTTP 응답을 함께 봐야 시험 결과를 구체적으로 설명할 수 있었다.

DNS와 Service를 분리해서 확인했다

web Pod 앞에는 ClusterIP Service를 뒀다. client에서 Service의 전체 이름을 해석하고, 그 이름으로 HTTP 요청도 보냈다. 확인하려던 것은 이름 해석 결과와 Service를 통과한 실제 응답이었다.

kubectl -n net-check exec client -- nslookup web.net-check.svc.cluster.local
kubectl -n net-check exec client -- wget -qO- -T 5 http://web.net-check.svc.cluster.local

직접 Pod IP로 접속한 결과와 Service 이름으로 접속한 결과를 따로 확인했다. 이름 해석은 되지만 HTTP 요청이 실패할 수도 있고, Pod IP 접근만 성공할 수도 있기 때문이다. 한 번의 요청으로 DNS와 Service 양쪽을 모두 확인했다고 처리하지 않았다.

이 단계에서 완료 기준은 Nginx HTML 응답, Service 이름 해석과 ClusterIP 경로의 응답이었다. 노드 상태 화면에서 출발해 실제 애플리케이션 요청으로 내려오면서 클러스터 네트워크의 확인 범위를 넓혔다.

차단을 먼저 만든 뒤 필요한 client만 허용했다

통신이 되는 상태를 확인한 뒤에는 NetworkPolicy를 적용했다. 첫 정책은 web Pod를 선택하고 ingress 허용 규칙을 두지 않는 형태였다. 적용 후 같은 client의 요청이 timeout 또는 연결 실패로 바뀌는지를 확인하도록 했다.

그다음에는 client의 label을 기준으로 web의 TCP 80 접근을 허용하는 정책을 추가했다. 기존 차단 정책을 지워야 허용되는 방식으로 이해하지 않았다. 두 정책이 함께 있을 때 해당 Pod에 적용되는 허용 규칙이 합산된다는 점을 요청 결과와 연결했다.

시험은 통신 성공, 차단, 특정 client 허용이라는 순서로 진행했다. 계속 성공하는지만 보는 것보다 정책이 실제로 요청을 막는지도 확인해야 설정 의도를 검증할 수 있었다. 제한 시간을 둔 요청을 같은 경로에 반복해 변화가 드러나도록 했다.

전체 네트워크 시험을 마친 뒤에는 시험 결과를 남기고 전용 namespace를 정리하는 흐름으로 끝냈다. 이 결과가 모든 트래픽과 모든 정책 조합을 보장하는 것은 아니었다. 내가 다음 서비스 배포에 사용할 노드 간 Pod 통신, 이름 해석, Service와 기본 ingress 정책 경로를 확인한 것이다. 조회 오류를 바로 설치 실패로 확대하지 않고, 작은 요청으로 확인 범위를 쌓은 과정이 이후 장애 점검에도 도움이 됐다.

작은 통신 시험의 결과는 당시 완료 기록에 의존한다. 2026년 10월 19일의 재조회에서는 Calico IPPool의 VXLAN 설정과 현재 NetworkPolicy 구성을 확인했다. 과거 차단 전후 응답을 이 시점에 새로 시험한 것은 아니다.

SEARCH JOURNAL

기록 검색

글 제목, 요약, 태그에서 찾습니다.

검색을 준비하고 있어요.

검색어를 입력해 주세요.

    Ctrl/⌘ K 검색 Esc 닫기 ↑ ↓ 결과 이동