트러블슈팅
트러블슈팅 (Troubleshooting)
이 문서는 다양한 배포 모드에서 Cilium을 트러블슈팅하는 방법을 안내해요. 데이터센터나 퍼블릭 클라우드에서 Cilium을 완전히 배포한 환경에 초점을 맞춥니다. 간단히 실험해보고 싶다면 Getting Started 가이드를 먼저 추천해요.
출처: Troubleshooting
본문
이 가이드는 모든 컴포넌트와 개념을 설명하는 Networking Concepts와 Securing Networks with Cilium을 읽었다고 가정해요.
우리는 GitHub 이슈로 Cilium 자주 묻는 질문(FAQ) 목록을 유지해요. 질문이 이미 다뤄졌는지도 확인해볼 수 있어요.
컴포넌트 및 클러스터 상태 (Component & Cluster Health)
Kubernetes
모든 파드의 상태가 Running인지 확인하기 위해 파드 목록을 조회하면 Cilium의 초기 개요를 확인할 수 있어요:
$ kubectl -n kube-system get pods -l k8s-app=cilium
NAME READY STATUS RESTARTS AGE
cilium-2hq5z 1/1 Running 0 4d
cilium-6kbtz 1/1 Running 0 4d
cilium-klj4b 1/1 Running 0 4d
cilium-zmjj9 1/1 Running 0 4d
Cilium이 복구할 수 없는 문제를 만나면 cilium-dbg status를 통해 실패 상태를 자동으로 보고하는데, 이 상태는 Kubernetes liveness 프로브가 정기적으로 조회해 Cilium 파드를 자동 재시작해요. Cilium 파드가 CrashLoopBackoff 상태라면 영구적 실패 시나리오를 나타내요.
상세 상태 (Detailed Status)
특정 Cilium 파드가 Running 상태가 아니라면, 해당 파드의 컨텍스트에서 cilium-dbg status를 실행해 그 노드의 에이전트 상태와 상태 정보를 얻을 수 있어요:
$ kubectl -n kube-system exec cilium-2hq5z -- cilium-dbg status
KVStore: Ok etcd: 1/1 connected: http://demo-etcd-lab--a.etcd.tgraf.test1.lab.corp.isovalent.link:2379 - 3.2.5 (Leader)
Kubernetes: Ok OK
Kubernetes APIs: ["cilium/v2::CiliumNetworkPolicy", "networking.k8s.io/v1::NetworkPolicy", "core/v1::Service", "core/v1::Endpoint", "core/v1::Node", "CustomResourceDefinition"]
Cilium: Ok OK
NodeMonitor: Disabled
Cilium health daemon: Ok
Controller Status: 14/14 healthy
Proxy Status: OK, ip 10.2.0.172, port-range 10000-20000
Cluster health: 4/4 reachable (2018-06-16T09:49:58Z)
또는 k8s-cilium-exec.sh 스크립트를 사용해 모든 노드에서 cilium-dbg status를 실행할 수 있어요. 이는 클러스터의 모든 노드에 대한 상세 상태와 상태 정보를 제공해요:
curl -sLO https://raw.githubusercontent.com/cilium/cilium/main/contrib/k8s/k8s-cilium-exec.sh
chmod +x ./k8s-cilium-exec.sh
… 그리고 모든 노드에서 cilium-dbg status를 실행하세요:
$ ./k8s-cilium-exec.sh cilium-dbg status
KVStore: Ok Etcd: http://127.0.0.1:2379 - (Leader) 3.1.10
Kubernetes: Ok OK
Kubernetes APIs: ["networking.k8s.io/v1beta1::Ingress", "core/v1::Node", "CustomResourceDefinition", "cilium/v2::CiliumNetworkPolicy", "networking.k8s.io/v1::NetworkPolicy", "core/v1::Service", "core/v1::Endpoint"]
Cilium: Ok OK
NodeMonitor: Listening for events on 2 CPUs with 64x4096 of shared memory
Cilium health daemon: Ok
Controller Status: 7/7 healthy
Proxy Status: OK, ip 10.15.28.238, 0 redirects, port-range 10000-20000
Cluster health: 1/1 reachable (2018-02-27T00:24:34Z)
Cilium 상태에 대한 상세 정보는 cilium-dbg status --verbose 명령으로 확인할 수 있어요. 상세 출력에는 자세한 IPAM 상태(할당된 주소), Cilium 컨트롤러 상태, Proxy 상태의 세부 정보가 포함돼요.
로그 (Logs)
cilium 파드의 로그 파일을 가져오려면 (다음에서 cilium-1234를 kubectl -n kube-system get pods -l k8s-app=cilium으로 반환된 파드 이름으로 바꿔서) 실행하세요:
kubectl -n kube-system logs --timestamps cilium-1234
문제 발생 후 liveness 문제로 cilium 파드가 이미 재시작됐다면, 마지막 재시작 전 파드의 로그를 가져오는 것도 유용할 수 있어요:
kubectl -n kube-system logs --timestamps -p cilium-1234
일반 (Generic)
Cilium이 실행 중인 호스트에 로그인하면 cilium CLI를 직접 호출할 수 있어요:
$ cilium-dbg status
KVStore: Ok etcd: 1/1 connected: https://192.168.60.11:2379 - 3.2.7 (Leader)
Kubernetes: Ok OK
Kubernetes APIs: ["core/v1::Endpoint", "networking.k8s.io/v1beta1::Ingress", "core/v1::Node", "CustomResourceDefinition", "cilium/v2::CiliumNetworkPolicy", "networking.k8s.io/v1::NetworkPolicy", "core/v1::Service"]
Cilium: Ok OK
NodeMonitor: Listening for events on 2 CPUs with 64x4096 of shared memory
Cilium health daemon: Ok
IPv4 address pool: 261/65535 allocated
IPv6 address pool: 4/4294967295 allocated
Controller Status: 20/20 healthy
Proxy Status: OK, ip 10.0.28.238, port-range 10000-20000
Hubble: Ok Current/Max Flows: 2542/4096 (62.06%), Flows/s: 164.21 Metrics: Disabled
Cluster health: 2/2 reachable (2018-04-11T15:41:01Z)
Hubble로 흐름 관찰하기 (Observing Flows with Hubble)
Hubble은 Cilium이 관리하는 모든 엔드포인트의 최근 흐름 이벤트를 검사할 수 있게 해주는 내장 관찰 도구예요.
Hubble이 올바르게 실행 중인지 확인
Hubble 클라이언트가 Cilium 내부에서 실행 중인 Hubble 서버에 연결할 수 있는지 확인하려면 Cilium 파드 안에서 hubble status 명령을 사용할 수 있어요:
$ hubble status
Healthcheck (via unix:///var/run/cilium/hubble.sock): Ok
Current/Max Flows: 4095/4095 (100.00%)
Flows/s: 164.21
Hubble 서버가 활성화되려면 cilium-agent가 --enable-hubble 옵션(기본값)으로 실행 중이어야 해요. Helm으로 Cilium을 배포할 때는 hubble.enabled=true 값을 설정해야 해요.
배포에서 Hubble이 활성화됐는지 확인하려면 cilium-dbg status에서 다음 출력을 찾을 수 있어요:
$ cilium status
...
Hubble: Ok Current/Max Flows: 4095/4095 (100.00%), Flows/s: 164.21 Metrics: Disabled
...
참고
파드가 Hubble로 관찰되려면 Cilium이 관리해야 해요. 파드가 Cilium에 관리되는지 확인하는 방법을 참고하세요.
특정 파드의 흐름 관찰하기
특정 파드의 트래픽을 관찰하려면 먼저 그 파드를 관리하는 cilium 인스턴스의 이름을 가져와야 해요. Hubble CLI는 Cilium 컨테이너 이미지의 일부이며 kubectl exec로 접근할 수 있어요. 예를 들어 다음 조회는 지난 3분 동안 default/tiefighter 파드에서 시작되거나 끝난 모든 흐름 관련 이벤트를 보여줘요:
$ kubectl exec -n kube-system cilium-77lk6 -- hubble observe --since 3m --pod default/tiefighter
May 4 12:47:08.811: default/tiefighter:53875 -> kube-system/coredns-74ff55c5b-66f4n:53 to-endpoint FORWARDED (UDP)
May 4 12:47:08.811: default/tiefighter:53875 -> kube-system/coredns-74ff55c5b-66f4n:53 to-endpoint FORWARDED (UDP)
May 4 12:47:08.811: default/tiefighter:53875 <- kube-system/coredns-74ff55c5b-66f4n:53 to-endpoint FORWARDED (UDP)
May 4 12:47:08.811: default/tiefighter:53875 <- kube-system/coredns-74ff55c5b-66f4n:53 to-endpoint FORWARDED (UDP)
May 4 12:47:08.811: default/tiefighter:50214 <> default/deathstar-c74d84667-cx5kp:80 to-overlay FORWARDED (TCP Flags: SYN)
May 4 12:47:08.812: default/tiefighter:50214 <- default/deathstar-c74d84667-cx5kp:80 to-endpoint FORWARDED (TCP Flags: SYN, ACK)
May 4 12:47:08.812: default/tiefighter:50214 <> default/deathstar-c74d84667-cx5kp:80 to-overlay FORWARDED (TCP Flags: ACK)
May 4 12:47:08.812: default/tiefighter:50214 <> default/deathstar-c74d84667-cx5kp:80 to-overlay FORWARDED (TCP Flags: ACK, PSH)
May 4 12:47:08.812: default/tiefighter:50214 <- default/deathstar-c74d84667-cx5kp:80 to-endpoint FORWARDED (TCP Flags: ACK, PSH)
May 4 12:47:08.812: default/tiefighter:50214 <> default/deathstar-c74d84667-cx5kp:80 to-overlay FORWARDED (TCP Flags: ACK, FIN)
May 4 12:47:08.812: default/tiefighter:50214 <- default/deathstar-c74d84667-cx5kp:80 to-endpoint FORWARDED (TCP Flags: ACK, FIN)
May 4 12:47:08.812: default/tiefighter:50214 <> default/deathstar-c74d84667-cx5kp:80 to-overlay FORWARDED (TCP Flags: ACK)
각 흐름 이벤트에 대한 더 자세한 정보를 얻으려면 -o json을 사용할 수도 있어요.
참고
Hubble Relay를 사용하면 특정 노드를 먼저 수동으로 지정하지 않고도 여러 Hubble 인스턴스를 동시에 조회할 수 있어요. Hubble Relay로 흐름 관찰하기를 참고하세요.
Hubble Relay로 흐름 관찰하기 (Observing flows with Hubble Relay)
Hubble Relay는 여러 Hubble 인스턴스를 동시에 조회하고 결과를 집계하는 서비스예요. 아직 활성화되지 않았다면 Hubble 관측성 설정을 참고해 Hubble Relay를 활성화하고 로컬 머신에 Hubble CLI를 설치하세요.
참고
아래 명령은
-P(--port-forward) 플래그를 사용해 로컬 머신의 포트4245로 Hubble Relay 서비스를 자동으로 포트 포워딩해요.
플래그를 생략하고 Cilium CLI로 수동으로 포트 포워딩을 만들 수도 있어요:
$ cilium hubble port-forward
ℹ️ Hubble Relay is available at 127.0.0.1:4245
또는 kubectl로:
$ kubectl -n kube-system port-forward service/hubble-relay 4245:80
Forwarding from 127.0.0.1:4245 -> 4245
Forwarding from [::1]:4245 -> 4245
이 방법에 대한 자세한 내용은 클러스터의 애플리케이션에 접근하기 위한 포트 포워딩 사용을 참고하세요.
Hubble Relay에 연결할 수 있는지 확인하려면 Hubble CLI를 사용해 로컬 머신에서 다음 명령을 실행하세요:
hubble status -P
이 명령은 다음과 유사한 출력을 반환해야 해요:
Healthcheck (via 127.0.0.1:4245): Ok
Current/Max Flows: 16380/16380 (100.00%)
Flows/s: 46.19
Connected Nodes: 4/4
Hubble Relay가 연결된 노드에 대한 세부 정보는 다음 명령을 실행해 볼 수 있어요:
$ hubble list nodes -P
NAME STATUS AGE FLOWS/S CURRENT/MAX-FLOWS
cluster/node-cp Connected 2m30s 13.94 2227/4095 ( 54.38%)
cluster/node-w1 Connected 2m31s 51.37 5108/9840 ( 51.91%)
Hubble Relay는 개별 Hubble 인스턴스와 같은 API를 공유하므로 Hubble로 흐름 관찰하기 섹션을 따르되, 개별 Hubble 인스턴스에서 볼 수 있는 것에 대한 제한은 더 이상 적용되지 않는다는 점을 기억하세요.
연결성 문제 (Connectivity Problems)
Cilium 연결성 테스트 (Cilium connectivity tests)
Cilium 연결성 테스트는 다양한 연결 경로를 사용해 서로 연결하는 일련의 서비스, deployment, CiliumNetworkPolicy를 배포해요. 연결 경로에는 서비스 로드밸런싱 유무와 다양한 네트워크 정책 조합이 포함돼요.
참고
연결성 테스트는 다른 파드나 네트워크 정책이 적용되지 않은 네임스페이스에서만 동작해요. Cilium Clusterwide Network Policy가 활성화되어 있다면 이 연결성 검사가 깨질 수도 있어요.
연결성 테스트를 실행하려면 cilium-test라는 격리된 테스트 네임스페이스를 만들어 테스트를 배포하세요:
kubectl create ns cilium-test
kubectl apply --namespace=cilium-test -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/connectivity-check/connectivity-check.yaml
테스트는 시스템의 다양한 기능을 다뤄요. 아래에서 각 테스트 유형을 설명해요. 테스트가 통과하면 해당 서브시스템의 기능이 정상이라는 것을 시사해요.
| Pod-to-pod (intra-host) | Pod-to-pod (inter-host) | Pod-to-service (intra-host) | Pod-to-service (inter-host) | Pod-to-external resource | | eBPF routing is functional | Data plane, routing, network | eBPF service map lookup | VXLAN overlay port if used | Egress, CiliumNetworkPolicy, masquerade |
파드 이름이 연결성 변형을 나타내고, readiness·liveness 게이트가 테스트의 성공·실패를 나타내요:
$ kubectl get pods -n cilium-test
NAME READY STATUS RESTARTS AGE
echo-a-6788c799fd-42qxx 1/1 Running 0 69s
echo-b-59757679d4-pjtdl 1/1 Running 0 69s
echo-b-host-f86bd784d-wnh4v 1/1 Running 0 68s
host-to-b-multi-node-clusterip-585db65b4d-x74nz 1/1 Running 0 68s
host-to-b-multi-node-headless-77c64bc7d8-kgf8p 1/1 Running 0 67s
pod-to-a-allowed-cnp-87b5895c8-bfw4x 1/1 Running 0 68s
pod-to-a-b76ddb6b4-2v4kb 1/1 Running 0 68s
pod-to-a-denied-cnp-677d9f567b-kkjp4 1/1 Running 0 68s
pod-to-b-intra-node-nodeport-8484fb6d89-bwj8q 1/1 Running 0 68s
pod-to-b-multi-node-clusterip-f7655dbc8-h5bwk 1/1 Running 0 68s
pod-to-b-multi-node-headless-5fd98b9648-5bjj8 1/1 Running 0 68s
pod-to-b-multi-node-nodeport-74bd8d7bd5-kmfmm 1/1 Running 0 68s
pod-to-external-1111-7489c7c46d-jhtkr 1/1 Running 0 68s
pod-to-external-fqdn-allow-google-cnp-b7b6bcdcb-97p75 1/1 Running 0 68s
테스트 실패에 대한 정보는 실패한 테스트 파드를 describe해 알 수 있어요:
$ kubectl describe pod pod-to-b-intra-node-hostport
Warning Unhealthy 6s (x6 over 56s) kubelet, agent1 Readiness probe failed: curl: (7) Failed to connect to echo-b-host-headless port 40000: Connection refused
Warning Unhealthy 2s (x3 over 52s) kubelet, agent1 Liveness probe failed: curl: (7) Failed to connect to echo-b-host-headless port 40000: Connection refused
클러스터 연결성 상태 확인 (Checking cluster connectivity health)
Cilium은 연결성 문제를 트러블슈팅할 때 모든 클러스터 노드와 각 노드에서 실행되는 시뮬레이션된 워크로드 사이에 신뢰할 수 있는 상태·지연 프로브를 제공해 네트워크 패브릭 관련 문제를 배제할 수 있어요.
기본적으로 Cilium을 실행하면 클러스터의 전체 연결성 상태를 파악하기 위해 백그라운드에서 cilium-health 인스턴스를 실행해요. 이 도구는 각 경로와 프로토콜의 상태를 결정하기 위해 클러스터를 통과하는 여러 경로와 각 노드를 통해 여러 프로토콜로 주기적으로 양방향 트래픽을 보내요. 언제든지 cilium-health에 마지막 프로브의 연결성 상태를 조회할 수 있어요.
$ kubectl -n kube-system exec -ti cilium-2hq5z -- cilium-health status --verbose
Probe time: 2018-06-16T09:51:58Z
Nodes:
ip-172-0-52-116.us-west-2.compute.internal (localhost):
Host connectivity to 172.0.52.116:
ICMP to stack: OK, RTT=315.254µs
HTTP to agent: OK, RTT=368.579µs
Endpoint connectivity to 10.2.0.183:
ICMP to stack: OK, RTT=190.658µs
HTTP to agent: OK, RTT=536.665µs
ip-172-0-117-198.us-west-2.compute.internal:
Host connectivity to 172.0.117.198:
ICMP to stack: OK, RTT=1.009679ms
HTTP to agent: OK, RTT=1.808628ms
Endpoint connectivity to 10.2.1.234:
ICMP to stack: OK, RTT=1.016365ms
HTTP to agent: OK, RTT=2.29877ms
각 노드에 대해 노드 자체와 그 노드의 엔드포인트 모두에 대해 각 프로토콜·경로의 연결성이 표시돼요. 지정된 지연은 보통 분당 한 번 실행되는 프로브의 마지막 스냅샷이에요. ICMP 연결성 행은 네트워킹 스택에 대한 Layer 3 연결성을 나타내고, HTTP 연결성 행은 호스트나 엔드포인트로 실행되는 cilium-health 에이전트 인스턴스에 대한 연결을 나타내요.
데이터패스 상태 모니터링 (Monitoring Datapath State)
때로는 연결성이 끊길 수 있으며, 이는 여러 다른 원인이 있을 수 있어요. 주요 원인 중 하나는 네트워킹 수준에서 원치 않는 패킷 드롭이에요. cilium-dbg monitor 도구로 패킷 드롭이 발생하는지 어디서 발생하는지 빠르게 검사할 수 있어요. 다음은 예시 출력이에요(Kubernetes로 실행 중이면 이전 예시처럼 kubectl exec 사용):
$ kubectl -n kube-system exec -ti cilium-2hq5z -- cilium-dbg monitor --type drop
Listening for events on 2 CPUs with 64x4096 of shared memory
Press Ctrl-C to quit
xx drop (Policy denied) to endpoint 25729, identity 261->264: fd02::c0a8:210b:0:bf00 -> fd02::c0a8:210b:0:6481 EchoRequest
xx drop (Policy denied) to endpoint 25729, identity 261->264: fd02::c0a8:210b:0:bf00 -> fd02::c0a8:210b:0:6481 EchoRequest
xx drop (Policy denied) to endpoint 25729, identity 261->264: 10.11.13.37 -> 10.11.101.61 EchoRequest
xx drop (Policy denied) to endpoint 25729, identity 261->264: 10.11.13.37 -> 10.11.101.61 EchoRequest
xx drop (Invalid destination mac) to endpoint 0, identity 0->0: fe80::5c25:ddff:fe8e:78d8 -> ff02::2 RouterSolicitation
위는 엔드포인트 ID 25729로 가는 패킷이 Layer 3 정책 위반으로 드롭됐다는 것을 나타내요.
드롭 처리 (CT: Map insertion failed)
연결이 실패하고 cilium-dbg monitor --type drop이 xx drop (CT: Map insertion failed)를 보여주면, 연결 추적 테이블이 가득 차서 가비지 컬렉터 간격의 자동 조정이 부족한 것일 가능성이 높아요.
--conntrack-gc-interval을 현재 값보다 낮게 설정하면 도움이 될 수 있어요. 이는 두 가비지 컬렉션 실행 사이의 시간 간격을 제어해요.
기본적으로 --conntrack-gc-interval은 0으로 설정되어 동적 간격을 사용함을 의미해요. 이 경우 간격은 가비지 컬렉션된 항목 수에 따라 각 가비지 컬렉션 실행 후 업데이트돼요. 컬렉션된 항목이 거의 없거나 없으면 간격이 늘어나고, 많이 컬렉션되면 줄어들어요. 현재 간격 값은 Cilium 에이전트 로그에 보고돼요.
대안으로 bpf-ct-global-any-max와 bpf-ct-global-tcp-max 값을 늘릴 수도 있어요. 이 두 옵션을 모두 설정하면 conntrack-gc-interval의 CPU와 bpf-ct-global-any-max·bpf-ct-global-tcp-max의 메모리 사용량이 트레이드오프돼요. datapath_conntrack_gc_runs_total, datapath_conntrack_gc_entries 같은 conntrack 가비지 컬렉션 관련 메트릭을 추적해 가비지 컬렉션 실행에 대한 가시성을 얻을 수 있어요. 자세한 내용은 Monitoring & Metrics을 참고하세요.
데이터패스 디버그 메시지 활성화
기본적으로 데이터패스 디버그 메시지는 비활성화되어 cilium-dbg monitor -v 출력에 표시되지 않아요. 활성화하려면 debug-verbose 옵션에 "datapath"를 추가하세요.
정책 트러블슈팅 (Policy Troubleshooting)
파드가 Cilium에 관리되는지 확인 (Ensure pod is managed by Cilium)
정책 적용이 예상대로 작동하지 않는 잠재적 원인은 정책이 선택한 파드의 네트워킹이 Cilium에 의해 관리되지 않는 경우예요. 다음 상황은 관리되지 않는 파드를 초래해요:
- 파드가 host 네트워킹에서 실행되어 호스트의 IP 주소를 직접 사용하는 경우. 이러한 파드는 전체 네트워크 연결이 있지만 Cilium은 기본적으로 그러한 파드에 대한 보안 정책 적용을 제공하지 않아요. 이 파드들에 정책을 적용하려면
hostNetwork를 false로 설정하거나 Host Policies을 사용하세요. - 파드가 Cilium 배포 전에 시작된 경우. Cilium은 Cilium 자체가 시작된 후 배포된 파드만 관리해요. Cilium은 그러한 파드에 대한 보안 정책 적용을 제공하지 않아요. Cilium이 보안 정책 적용을 제공할 수 있도록 이러한 파드를 재시작해야 해요.
파드 네트워킹이 Cilium에 의해 관리되지 않으면 해당 파드를 선택하는 ingress·egress 정책 규칙이 적용되지 않아요. 자세한 내용은 네트워크 정책 개요 섹션을 참고하세요.
Cilium이 관리하지 않는 파드가 있는지 빠르게 평가하려면 Cilium CLI가 관리되는 파드 수를 출력해요. 모든 파드가 Cilium에 관리된다고 출력되면 문제가 없는 거예요:
$ cilium status
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Hubble: OK
\__/¯¯\__/ ClusterMesh: disabled
\__/
Deployment cilium-operator Desired: 2, Ready: 2/2, Available: 2/2
Deployment hubble-relay Desired: 1, Ready: 1/1, Available: 1/1
Deployment hubble-ui Desired: 1, Ready: 1/1, Available: 1/1
DaemonSet cilium Desired: 2, Ready: 2/2, Available: 2/2
Containers: cilium-operator Running: 2
hubble-relay Running: 1
hubble-ui Running: 1
cilium Running: 2
Cluster Pods: 5/5 managed by Cilium
...
다음 스크립트를 실행해 Cilium이 관리하지 않는 파드를 나열할 수 있어요:
$ curl -sLO https://raw.githubusercontent.com/cilium/cilium/main/contrib/k8s/k8s-unmanaged.sh
$ chmod +x k8s-unmanaged.sh
$ ./k8s-unmanaged.sh
kube-system/cilium-hqpk7
kube-system/kube-addon-manager-minikube
kube-system/kube-dns-54cccfbdf8-zmv2c
kube-system/kubernetes-dashboard-77d8b98585-g52k5
kube-system/storage-provisioner
정책 렌더링 이해하기 (Understand the rendering of your policy)
문제에 접근하는 방법은 항상 여러 가지예요. Cilium은 제공된 집계 정책의 렌더링을 보여줄 수 있어 모든 정책을 검색(그리고 잠재적으로 놓치)하지 않고 실제 정책이 무엇이어야 하는지와 비교하기만 하면 돼요. 엔드포인트의 매우 큰 덤프를 읽는 비용을 치르지만, 이는 종종 Kubernetes API에서 잘못된 정책 요청을 발견하는 더 빠른 경로예요.
먼저 다음 목록에서 디버깅할 엔드포인트를 찾으세요. 이 목록에는 IP 주소와 파드 라벨을 포함한 여러 교차 참조가 있어요:
kubectl -n kube-system exec -ti cilium-q8wvt -- cilium-dbg endpoint list
올바른 엔드포인트를 찾으면 각 행의 첫 번째 열이 엔드포인트 ID예요. 그것으로 전체 엔드포인트 정보를 덤프하세요:
kubectl -n kube-system exec -ti cilium-q8wvt -- cilium-dbg endpoint get 59084

이 덤프를 JSON 친화적인 편집기로 가져오면 정보를 탐색하는 데 도움이 돼요. 덤프의 최상위에는 주목할 두 노드가 있어요:
spec: 엔드포인트의 원하는 상태status: 엔드포인트의 현재 상태
이것은 표준 Kubernetes 컨트롤 루프 패턴이에요. 여기서 Cilium이 컨트롤러이며 status를 spec과 일치시키기 위해 반복적으로 작업해요.
status를 열면 policy.realized.l4로 내려갈 수 있어요. ingress와 egress 규칙이 예상과 일치하나요? 그렇지 않으면 잘못된 규칙에 대한 참조를 derived-from-rules 노드에서 찾을 수 있어요.
Policymap 압박 및 오버플로 (Policymap pressure and overflow)
policymap 압박을 디버깅하는 가장 중요한 단계는 영향을 받는 노드를 찾는 것이에요.
cilium_bpf_map_pressure{map_name="cilium_policy_v3_*"} 메트릭은 엔드포인트의 BPF policymap 압박을 모니터링해요. 이 메트릭은 노드의 최대 BPF 맵 압박을 노출하며, 즉 특정 노드에서 가장 큰 압박을 받는 policymap을 의미해요.
노드를 알게 되면 트러블슈팅 단계는 다음과 같아요:
- 문제가 있는 policymap 압박이 있는 노드에서 Cilium 파드를 찾고
kubectl exec로 셸을 얻으세요. cilium policy selectors를 사용해 많은 identity를 선택하는 셀렉터 개요를 얻으세요.- 셀렉터 유형이 어떤 종류의 정책 규칙이 영향을 미칠 수 있는지 알려줘요. 기존 세 가지 셀렉터 유형은 아래에 설명되며, 셀렉터에 따라 특정 단계가 있어요. 셀렉터 유형에 해당하는 아래 단계를 참고하세요.
- 최후의 수단으로 policymap 크기를 늘리는 것을 고려하세요. 다만 다음 의미를 염두에 두세요:
- 각 policymap의 메모리 소비 증가.
- 일반적으로 클러스터의 identity가 늘어날수록 Cilium이 수행하는 작업이 많아져요.
- 더 넓은 의미에서, 정책 자세가 모두 또는 거의 모든 identity를 선택하도록 되어 있으면 그 자세가 너무 허용적임을 시사해요.
| 셀렉터 유형 | cilium policy selectors 출력에서의 형태 |
| CIDR | &LabelSelector{MatchLabels:map[string]string{cidr.1.1.1.1/32: ,} |
| FQDN | MatchName: , MatchPattern: * |
| Label | &LabelSelector{MatchLabels:map[string]string{any.name: curl,k8s.io.kubernetes.pod.namespace: default,} |
cilium policy selectors의 예시 출력:
root@kind-worker:/home/cilium# cilium policy selectors
SELECTOR LABELS USERS IDENTITIES
&LabelSelector{MatchLabels:map[string]string{k8s.io.kubernetes.pod.namespace: kube-system,k8s.k8s-app: kube-dns,},MatchExpressions:[]LabelSelectorRequirement{},} default/tofqdn-dns-visibility 1 16500
&LabelSelector{MatchLabels:map[string]string{reserved.none: ,},MatchExpressions:[]LabelSelectorRequirement{},} default/tofqdn-dns-visibility 1
MatchName: , MatchPattern: * default/tofqdn-dns-visibility 1 16777231
16777232
16777233
16860295
...
&LabelSelector{MatchLabels:map[string]string{any.name: netperf,k8s.io.kubernetes.pod.namespace: default,},MatchExpressions:[]LabelSelectorRequirement{},} default/tofqdn-dns-visibility 1
&LabelSelector{MatchLabels:map[string]string{cidr.1.1.1.1/32: ,},MatchExpressions:[]LabelSelectorRequirement{},} default/tofqdn-dns-visibility 1 16860329
&LabelSelector{MatchLabels:map[string]string{cidr.1.1.1.2/32: ,},MatchExpressions:[]LabelSelectorRequirement{},} default/tofqdn-dns-visibility 1 16860330
&LabelSelector{MatchLabels:map[string]string{cidr.1.1.1.3/32: ,},MatchExpressions:[]LabelSelectorRequirement{},} default/tofqdn-dns-visibility 1 16860331
위 출력에서 세 셀렉터 모두 사용 중임을 볼 수 있어요. 여기서 중요한 행동은 어떤 셀렉터가 가장 많은 identity를 선택하는지 결정하는 것이며, 해당 셀렉터를 포함한 정책이 policymap 압박의 가능한 원인이기 때문이에요.
Label
identity 관련 라벨 섹션을 참고하세요.
또 다른 고려할 측면은 정책의 허용 정도와 그것을 줄일 수 있는지 여부예요.
CIDR
CIDR 셀렉터가 선택하는 identity 수를 줄이는 한 가지 방법은 가능하면 CIDR 범위를 넓히는 거예요. 예를 들어 위 예시 출력에서 정책은 CIDR마다 /30 같은 넓은 범위 대신 /32 규칙을 사용해요. 이 규칙으로 정책을 업데이트하면 /30 내 모든 IP를 나타내는 identity가 생성되므로 셀렉터가 1개의 identity만 선택하면 돼요.
FQDN
identity와 정책 관련 toFQDNs 문제의 소스 격리 섹션을 참고하세요.
etcd (kvstore)
소개 (Introduction)
Cilium은 CRD 모드와 kvstore/etcd 모드로 운영할 수 있어요. cilium이 kvstore/etcd 모드로 실행될 때 kvstore는 여러 작업에 사용 가능해야 하므로 전체 클러스터 상태의 중요한 컴포넌트가 돼요.
etcd 모드로 실행할 때 kvstore가 엄격히 필요한 작업:
- 새 워크로드 스케줄링: — 워크로드/엔드포인트를 스케줄링하는 과정의 일부로 에이전트가 kvstore와의 상호작용이 필요한 보안 identity 할당을 수행해요. 알려진 보안 identity를 재사용해 워크로드를 스케줄링할 수 있다면, 엔드포인트 세부 정보의 다른 노드로의 상태 전파는 여전히 kvstore에 의존하므로 클러스터의 다른 노드가 새 워크로드를 알지 못해 정책 적용으로 인한 패킷 드롭이 관찰될 수 있어요.
- Multi cluster: — 클러스터 간의 모든 상태 전파는 kvstore에 의존해요.
- 노드 발견: — 새 노드는 kvstore에 스스로 등록해야 해요.
- 에이전트 부트스트랩: — Cilium 에이전트는 부트스트랩 시점에 kvstore에 연결할 수 없으면 결국 실패하지만, kvstore가 나타나기를 기다리는 동안 가능한 모든 작업을 계속 수행해요.
kvstore 가용성이 필요하지 않은 작업:
- 모든 데이터패스 작업: — 기존 워크로드/엔드포인트에 대한 모든 데이터패스 포워딩, 정책 적용, 가시성 기능은 kvstore에 의존하지 않아요. 패킷은 계속 포워딩되고 네트워크 정책 규칙은 계속 적용돼요.
다만 Recovery behavior의 일부로 에이전트를 재시작해야 한다면 다음에 지연이 있을 수 있어요:
-
흐름 이벤트와 메트릭 처리
-
레이어 7 프록시의 짧은 비가용성
-
NetworkPolicy 업데이트: — 네트워크 정책 업데이트는 계속 처리·적용돼요.
-
Services 업데이트: — 서비스에 대한 모든 업데이트가 처리·적용돼요.
etcd 상태 이해하기 (Understanding etcd status)
etcd 상태는 cilium-dbg status를 실행할 때 보고돼요. 다음 줄은 etcd의 상태를 나타내요:
KVStore: Ok etcd: 1/1 connected, lease-ID=29c6732d5d580cb5, lock lease-ID=29c6732d5d580cb7, has-quorum=true: https://192.168.60.11:2379 - 3.4.9 (Leader)
- OK: — 전체 상태.
OK또는Failure. - 1/1 connected: — 전체 etcd 엔드포인트 수와 그중 연결 가능한 수.
- lease-ID: — 이 에이전트가 소유한 모든 키에 사용되는 lease의 UUID.
- lock lease-ID: — 이 에이전트가 획득한 잠금에 사용되는 lease의 UUID.
- has-quorum: — etcd 쿼럼 상태.
true또는 오류로 설정됨. - consecutive-errors: — 연속 쿼럼 오류 수. 오류가 있을 때만 출력됨.
- https://192.168.60.11:2379 - 3.4.9 (Leader): — etcd 버전과 특정 엔드포인트가 현재 선출된 리더인지 여부를 명시한 모든 etcd 엔드포인트 목록. etcd 엔드포인트에 연결할 수 없으면 오류가 표시돼요.
복구 동작 (Recovery behavior)
etcd 엔드포인트가 비정상이 되면 etcd는 새 리더를 선출하고 정상 etcd 엔드포인트로 장애 조치하여 자동으로 해결해야 해요. 쿼럼이 보존되는 한 etcd 클러스터는 계속 기능해요.
또한 Cilium은 etcd 상태를 파악하고 잠재적으로 조치를 취하기 위해 간격으로 백그라운드 검사를 수행해요. 간격은 전체 클러스터 크기에 따라 달라요. 클러스터가 클수록 간격이 길어져요:
- 연결할 수 있는 etcd 엔드포인트가 없으면 Cilium이
cilium-dbg status에서 실패를 보고해요. 이로 인해 Kubernetes의 liveness·readiness 프로브가 실패하고 Cilium이 재시작돼요.- 쿼럼이 필요한 쓰기 연산을 테스트하기 위해 잠금을 획득·해제해요. 이 연산이 실패하면 쿼럼 손실이 보고돼요. 쿼럼이 세 번 이상 연속으로 실패하면 Cilium이 비정상으로 선언돼요.
- Cilium operator는 heartbeat 키(
cilium/.heartbeat)에 지속적으로 기록해요. 모든 Cilium 에이전트는 이 heartbeat 키의 업데이트를 감시해요. 이는 에이전트가 etcd에서 키 업데이트를 받을 수 있는 능력을 검증해요. heartbeat 키가 제때 업데이트되지 않으면 쿼럼 검사가 실패한 것으로 선언되고, 3회 이상 연속 실패 후 Cilium이 비정상으로 선언돼요.
아직 임계값에 도달하지 않은 쿼럼 실패가 있는 상태의 예:
KVStore: Ok etcd: 1/1 connected, lease-ID=29c6732d5d580cb5, lock lease-ID=29c6732d5d580cb7, has-quorum=2m2.778966915s since last heartbeat update has been received, consecutive-errors=1: https://192.168.60.11:2379 - 3.4.9 (Leader)
쿼럼 실패 수가 임계값을 초과한 상태의 예:
KVStore: Failure Err: quorum check failed 8 times in a row: 4m28.446600949s since last heartbeat update has been received
Cluster Mesh 트러블슈팅
Cilium CLI 설치
최신 버전의 Cilium CLI를 설치하세요. Cilium CLI는 Cilium 설치, Cilium 설치 상태 점검, 다양한 기능(예: clustermesh, Hubble) 활성화/비활성화에 사용할 수 있어요.
Linux:
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
macOS:
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "arm64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-darwin-${CLI_ARCH}.tar.gz{,.sha256sum}
shasum -a 256 -c cilium-darwin-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-darwin-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-darwin-${CLI_ARCH}.tar.gz{,.sha256sum}
전체 릴리스 페이지도 참고하세요.
자동 검증 (Automatic Verification)
- Cilium 파드가 정상이고 준비 상태인지 확인하세요:
cilium status
- Cluster Mesh가 활성화되고 정상 작동하는지 확인하세요:
cilium clustermesh status
- 오류가 있으면 troubleshoot 명령을 실행해 원격 클러스터의 ClusterMesh 컨트롤 플레인에 대한 Cilium 에이전트 연결 문제를 자동으로 조사하세요:
kubectl exec -it -n kube-system ds/cilium -c cilium-agent -- cilium-dbg troubleshoot clustermesh
troubleshoot 명령은 DNS 해석, 네트워크 연결성, TLS 인증, etcd 권한 부여 등을 검증하는 일련의 자동 검사를 수행하고 사용자 친화적인 형식으로 출력을 보고해요. KVStoreMesh가 활성화되면 troubleshoot 명령의 출력은 에이전트에서 로컬 캐시로의 연결을 의미하며, 연결된 모든 클러스터에 대해 동일할 것으로 예상돼요. 원격 클러스터의 ClusterMesh 컨트롤 플레인에 대한 KVStoreMesh 연결 문제를 조사하려면 clustermesh-apiserver 내부에서 troubleshoot 명령을 실행하세요:
kubectl exec -it -n kube-system deploy/clustermesh-apiserver -c kvstoremesh -- \
clustermesh-apiserver kvstoremesh-dbg troubleshoot
팁
troubleshoot 명령의 파라미터로 하나 이상의 클러스터 이름을 지정해 원격 클러스터의 하위 집합에 대해서만 검사를 실행할 수 있어요.
수동 검증 (Manual Verification)
이전 섹션에서 제시된 도구를 활용하는 대안으로 다음 단계를 수행해 ClusterMesh 문제를 트러블슈팅할 수도 있어요.
- 각 클러스터가 고유한 사람이 읽을 수 있는 이름과 숫자 클러스터 ID(1-255)를 할당받았는지 확인하세요.
- 각 클러스터에 대해 clustermesh-apiserver가 올바르게 초기화됐는지 확인하세요:
$ kubectl logs -n kube-system deployment/clustermesh-apiserver -c apiserver
...
level=info msg="Connecting to etcd server..." config=/var/lib/cilium/etcd-config.yaml endpoints="[https://127.0.0.1:2379]" subsys=kvstore
level=info msg="Got lock lease ID 7c0281854b945c07" subsys=kvstore
level=info msg="Initial etcd session established" config=/var/lib/cilium/etcd-config.yaml endpoints="[https://127.0.0.1:2379]" subsys=kvstore
level=info msg="Successfully verified version of etcd endpoint" config=/var/lib/cilium/etcd-config.yaml endpoints="[https://127.0.0.1:2379]" etcdEndpoint="https://127.0.0.1:2379" subsys=kvstore version=3.4.13
- 각 Cilium 에이전트 내부에서
cilium-dbg status --all-clusters를 실행해 ClusterMesh가 정상인지 확인하세요:
ClusterMesh: 1/1 remote clusters ready
k8s-c2: ready, 3 nodes, 25 endpoints, 8 identities, 10 services, 0 endpoint slices, 0 MCS-API service exports, 0 reconnections (last: never)
└ etcd: 1/1 connected, leases=0, lock lease-ID=7c028201b53de662, has-quorum=true: https://k8s-c2.mesh.cilium.io:2379 - 3.5.4 (Leader)
└ remote configuration: expected=true, retrieved=true, cluster-id=3, kvstoremesh=false, sync-canaries=true, service-exports=disabled, endpoint-slice-export-mode=services-only
└ synchronization status: nodes=true, endpoints=true, identities=true, services=true
KVStoreMesh가 활성화되면 그 상태를 추가로 확인하고 모든 원격 클러스터에 올바르게 연결됐는지 검증하세요:
$ kubectl --context $CLUSTER1 exec -it -n kube-system deploy/clustermesh-apiserver \
-c kvstoremesh -- clustermesh-apiserver kvstoremesh-dbg status --verbose
- TLS 관련 수동 검사는 TLS 인증서 트러블슈팅을 참고하세요.
- 원격 클러스터 구성을 올바르게 가져왔는지 확인하세요. 각 원격 클러스터에 대해
cilium-agent로그에 원격 클러스터 이름과 함께New remote cluster configuration정보 로그 메시지가 기록되어야 해요. 구성이 발견되지 않으면 다음을 확인하세요:cilium-clustermeshKubernetes 시크릿이 존재하고 Cilium 에이전트 파드가 올바르게 마운트했는지.- 시크릿이 각 원격 클러스터에 대해
--cluster-name인자 또는cluster-nameConfigMap 옵션으로 제공된 원격 클러스터 이름과 일치하는 파일명으로 파일을 포함하는지. - 원격 클러스터 이름을 딴 각 파일이 원격 etcd 클러스터에 도달할 엔드포인트와 그 etcd 클러스터에 인증할 인증서·개인 키 경로로 구성된 유효한 etcd 구성을 포함하는지. 인증서와 개인 키 자체를 제공하기 위해 시크릿에 추가 파일이 포함될 수 있어요.
- Cilium 에이전트 파드 내부의
/var/lib/cilium/clustermesh디렉터리가cilium-clustermesh시크릿에서 마운트된 파일을 포함하는지. 다음으로 존재하는 파일을 나열할 수 있어요.kubectl exec -ti -n kube-system ds/cilium -c cilium-agent -- ls /var/lib/cilium/clustermesh
- 원격 클러스터에 연결이 설정됐는지 확인하세요. 각 원격 클러스터에 대해
cilium-agent로그에 이런 로그 메시지가 보일 거예요:
level=info msg="Connection to remote cluster established"
연결이 실패하면 이런 경고가 보일 거예요:
level=warning msg="Unable to establish etcd connection to remote cluster"
연결이 실패하면 다음을 확인하세요:
- KVStoreMesh가 비활성화되면 Cilium DaemonSet의
hostAliases섹션이 각 원격 클러스터를 원격 컨트롤 플레인을 제공하는 LoadBalancer의 IP로 매핑하는지 확인하고, KVStoreMesh가 활성화되면 clustermesh-apiserver Deployment의hostAliases섹션을 확인하세요. - 소스 클러스터의 로컬 노드가
hostAliases섹션에 지정된 IP에 도달할 수 있는지 확인하세요. KVStoreMesh가 비활성화되면cilium-clustermesh시크릿이 각 원격 클러스터에 대한 구성 파일을 포함하며, 원격 클러스터를 나타내는 논리적 이름을 가리켜요; KVStoreMesh가 활성화되면cilium-kvstoremesh시크릿에 존재해요.
endpoints:
- https://cluster1.mesh.cilium.io:2379
이 이름은 Cilium 에이전트 파드 밖에서 DNS로 해석되지 않아요. 이 이름은 hostAliases를 사용해 IP에 매핑돼요. KVStoreMesh가 비활성화되면 kubectl -n kube-system get daemonset cilium -o yaml을 실행하거나, 활성화되면 kubectl -n kube-system get deployment clustermesh-apiserver -o yaml을 실행하고 FQDN을 grep해 구성된 IP를 가져오세요. 그런 다음 curl로 포트에 도달 가능한지 확인하세요.
- 로컬 클러스터와 원격 클러스터 사이의 방화벽이 컨트롤 플레인 연결을 드롭할 수 있어요. 포트 2379/TCP가 허용되는지 확인하세요.
상태 전파 (State Propagation)
- Cilium 파드 중 하나에서
cilium-dbg node list를 실행하고 로컬 노드와 원격 클러스터의 노드를 모두 나열하는지 확인하세요. 원격 노드가 없으면 Cilium 에이전트(또는 활성화된 경우 KVStoreMesh)가 주어진 원격 클러스터에 올바르게 연결됐는지 확인하세요. 또한 모든 클러스터의 초기 노드 동기화가 완료됐는지 확인하세요. - 아무 Cilium 파드 안에서
cilium-health status를 실행해 클러스터 간 연결성 상태 매트릭스를 확인하세요. 각 원격 노드에 대한 연결성 상태 검사 상태를 나열해요. 실패하면 방화벽 규칙 섹션에 지정된 대로 네트워크가 상태 검사 트래픽을 허용하는지 확인하세요. - Cilium 파드 중 하나에서
cilium-dbg identity list를 실행해 identity가 올바르게 동기화됐는지 확인하세요. 모든 클러스터의 identity를 나열해야 해요.io.cilium.k8s.policy.cluster라벨을 보고 identity가 속한 클러스터를 판단할 수 있어요. 원격 identity가 없으면 Cilium 에이전트(또는 활성화된 경우 KVStoreMesh)가 주어진 원격 클러스터에 올바르게 연결됐는지 확인하세요. 또한 모든 클러스터의 초기 identity 동기화가 완료됐는지 확인하세요. cilium-dbg bpf ipcache list또는cilium-dbg map get cilium_ipcache를 실행해 IP 캐시가 올바르게 동기화됐는지 확인하세요. 출력에는 로컬과 원격 클러스터의 파드 IP가 포함되어야 해요. 원격 IP 주소가 없으면 Cilium 에이전트(또는 활성화된 경우 KVStoreMesh)가 주어진 원격 클러스터에 올바르게 연결됐는지 확인하세요. 또한 모든 클러스터의 초기 IP 동기화가 완료됐는지 확인하세요.- 전역 서비스를 사용할 때 전역 서비스가 모든 클러스터의 엔드포인트로 구성됐는지 확인하세요. 아무 Cilium 파드에서
cilium-dbg shell -- db/show backends(또는cilium-dbg service list)를 실행하고 백엔드 IP가 관련 백엔드를 실행하는 모든 클러스터의 파드 IP로 구성됐는지 확인하세요.cilium-dbg bpf lb list를 실행해 eBPF 맵 상태를 검사함으로써 올바른 데이터패스 배선을 추가로 검증할 수 있어요.
TLS 인증서 트러블슈팅
Cluster Mesh TLS를 활성화한 후 문제가 발생하면 다음 지침으로 문제를 진단하세요. 먼저 자동 검증을 참고하고 troubleshoot 명령을 실행하세요. 이들은 TLS 인증을 검증하고 사람이 읽을 수 있는 형식으로 인증서 정보를 표시해요.
인증서 관리 방법과 관계없이 적용되는 검사:
- 인증서가 만료되지 않았고 CN과 SAN이 예상 값과 일치하는지 확인하세요.
- 각 클라이언트가 서버 인증서에 서명한 CA를 신뢰하는지 확인하세요.
- 기본적으로 다음 TLS 시크릿이 Cilium이 설치된 네임스페이스에서 사용 가능해야 해요:
clustermesh-apiserver-server-cert: clustermesh-apiserver deployment의 etcd 컨테이너가 사용. 외부 etcd 클러스터를 사용하면 적용되지 않아요.clustermesh-apiserver-admin-cert: sideca etcd 인스턴스에 인증하기 위해 clustermesh-apiserver deployment의 apiserver/kvstoremesh 컨테이너가 사용. 외부 etcd 클러스터를 사용하면 적용되지 않아요.clustermesh-apiserver-remote-cert: 원격 etcd 인스턴스에 인증하기 위해 Cilium 에이전트 또는(KVStoreMesh 활성화 시) clustermesh-apiserver deployment의 kvstoremesh 컨테이너가 사용.clustermesh-apiserver-local-cert: 로컬 etcd 인스턴스에 인증하기 위해 Cilium 에이전트가 사용. KVStoreMesh가 활성화된 경우에만 적용돼요.
다음 검사는 인증서를 프로비저닝하는 데 사용한 특정 방법에 따라 달라져요.
cert-manager / Helm / 사용자 제공 인증서
Cilium이나 cert-manager를 설치하는 동안 다음 오류가 발생할 수 있어요:
Error: Internal error occurred: failed calling webhook "webhook.cert-manager.io": Post "https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s": dial tcp x.x.x.x:443: connect: connection refused
이것은 cert-manager의 webhook(Certificate CRD 리소스를 검증하는 데 사용)을 사용할 수 없을 때 발생해요. 이 문제를 해결하는 방법은 여러 가지예요. 다음 옵션 중 하나를 선택하세요.
CRD를 먼저 설치 — Cilium과 cert-manager 전에 cert-manager CRD를 설치하세요(kubectl로 CRD 설치에 대한 cert-manager 문서 참고):
$ kubectl create -f cert-manager.crds.yaml
그런 다음 cert-manager를 설치하고 issuer를 구성한 뒤 Cilium을 설치하세요.
Cilium 업그레이드 — Cluster Mesh를 비활성화한 상태로 Cilium을 설치하세요:
$ helm install cilium cilium/cilium \
--set clustermesh.useAPIServer=false \
--set clustermesh.config.enabled=false \
...
그런 다음 cert-manager를 설치하고 issuer를 구성한 뒤 Cluster Mesh를 활성화하세요.
웹훅 비활성화 — cert-manager 검증을 비활성화하세요(Cilium이 kube-system 네임스페이스에 설치됐다고 가정):
$ kubectl label namespace kube-system cert-manager.io/disable-validation=true
그런 다음 Cilium, cert-manager를 설치하고 issuer를 구성하세요.
호스트 네트워크 웹훅 — cert-manager가 호스트 네트워크 네임스페이스 내에서 webhook을 노출하도록 구성하세요:
$ helm install cert-manager jetstack/cert-manager \
--set webhook.hostNetwork=true \
--set 'webhook.tolerations[0].operator=Exists'
그런 다음 issuer를 구성하고 Cilium을 설치하세요.
Helm 사용 시 인증서는 자동으로 갱신되지 않아요. 만료된 인증서 문제가 발생하면 helm upgrade를 실행해 인증서를 갱신할 수 있어요.
인증서에 문제가 발생하면 디코딩해 확인할 수 있어요:
$ kubectl -n kube-system get secret clustermesh-apiserver-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -text -noout
$ kubectl -n kube-system get secret clustermesh-apiserver-server-cert -o jsonpath='{.data.tls\.key}' | base64 -d | openssl pkey -text -noout
$ kubectl -n kube-system get secret clustermesh-apiserver-server-cert -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -text -noout
같은 명령을 다른 시크릿에도 사용할 수 있어요.
Service Mesh 트러블슈팅
이 섹션은 Cilium Service Mesh(주로 Ingress 컨트롤러와 CiliumEnvoyConfig)와 관련된 트러블슈팅입니다. 자세한 절차는 전용 문서인 Service Mesh 트러블슈팅을 참고하세요.
Cilium CLI 설치 — Cilium CLI를 설치하세요 (Linux/macOS 지침은 Cluster Mesh 섹션의 Cilium CLI 설치 참고).
일반 — ds/cilium 및 deployment/cilium-operator 파드가 정상이고 준비 상태인지 확인하세요:
$ cilium status
설치 수동 검증 — kubeProxyReplacement가 true인지, enable-envoy-config와 enable-ingress-controller 값이 true인지 확인하세요. 고객이 CiliumEnvoyConfig 또는 CiliumClusterwideEnvoyConfig CRD만 사용하는 경우 ingress controller 플래그는 선택사항이에요.
$ kubectl exec -n kube-system ds/cilium -- cilium-dbg status
...
KubeProxyReplacement: True
...
$ kubectl -n kube-system get cm cilium-config -o json | egrep "enable-ingress-controller|enable-envoy-config"
"enable-envoy-config": "true",
"enable-ingress-controller": "true",
Ingress 트러블슈팅 — 내부적으로 Cilium Ingress 컨트롤러는 각 Ingress 리소스마다 하나의 Load Balancer 서비스, 하나의 CiliumEnvoyConfig, 하나의 더미 Endpoint 리소스를 생성해요. Load Balancer 서비스에 외부 IP 또는 FQDN이 할당됐는지, Cilium이 CiliumEnvoyConfig를 프로비저닝하는 동안 경고·오류가 없는지 확인하세요. 자세한 명령과 참고 사항은 Service Mesh 트러블슈팅 페이지를 참고하세요.
증상 라이브러리 (Symptom Library)
노드 간 트래픽이 드롭됨 (Node to node traffic is being dropped)
증상 (Symptom)
단일 노드에서 엔드포인트 간 통신은 성공하지만 여러 노드에 걸친 엔드포인트 간 통신은 실패해요.
트러블슈팅 단계
- 소스·대상 엔드포인트의 노드에서
cilium-health status --verbose를 실행하세요. 이는 그 노드에서 클러스터의 다른 노드로, 그리고 다른 각 노드의 시뮬레이션된 엔드포인트로의 연결성을 설명해야 해요. 클러스터에서 서로 통신할 수 없는 지점을 식별하세요. 명령이 다른 노드의 상태를 설명하지 않으면 KV-Store에 문제가 있을 수 있어요. - 소스·대상 엔드포인트의 노드에서
cilium-dbg monitor를 실행하세요. 패킷 드롭을 찾으세요.
캡슐화(Encapsulation) 모드로 실행 중:
- 노드가 올바르게 채워지면 각 노드에서
tcpdump -n -i cilium_vxlan을 실행해 노드 간 트래픽이 올바르게 전달되는지 확인하세요. 패킷이 드롭되면:cilium-dbg bpf ipcache list에 나열된 노드 IP가 서로 도달할 수 있는지 확인하세요.- 각 노드의 방화벽이 UDP 포트 8472를 허용하는지 확인하세요.
Native-Routing 모드로 실행 중:
ip route를 실행하거나 클라우드 제공업체 라우터를 확인해 모든 노드 간에 엔드포인트 프리픽스를 라우팅할 경로가 설치됐는지 확인하세요.- 각 노드의 방화벽이 엔드포인트 IP를 라우팅하는 것을 허용하는지 확인하세요.
유용한 스크립트 (Useful Scripts)
특정 파드를 관리하는 Cilium 파드 가져오기
네임스페이스에서 특정 파드를 관리하는 Cilium 파드를 식별해요:
k8s-get-cilium-pod.sh <pod> <namespace>
예시:
$ curl -sLO https://raw.githubusercontent.com/cilium/cilium/main/contrib/k8s/k8s-get-cilium-pod.sh
$ chmod +x k8s-get-cilium-pod.sh
$ ./k8s-get-cilium-pod.sh luke-pod default
cilium-zmjj9
cilium-node-init-v7r9p
cilium-operator-f576f7977-s5gpq
모든 Kubernetes Cilium 파드에서 명령 실행
클러스터의 모든 Cilium 파드 내에서 명령을 실행해요:
k8s-cilium-exec.sh <command>
예시:
$ curl -sLO https://raw.githubusercontent.com/cilium/cilium/main/contrib/k8s/k8s-cilium-exec.sh
$ chmod +x k8s-cilium-exec.sh
$ ./k8s-cilium-exec.sh uptime
10:15:16 up 6 days, 7:37, 0 users, load average: 0.00, 0.02, 0.00
10:15:16 up 6 days, 7:32, 0 users, load average: 0.00, 0.03, 0.04
10:15:16 up 6 days, 7:30, 0 users, load average: 0.75, 0.27, 0.15
10:15:16 up 6 days, 7:28, 0 users, load average: 0.14, 0.04, 0.01
관리되지 않는 Kubernetes 파드 나열
Cilium이 네트워킹을 제공하지 않는 클러스터의 모든 Kubernetes 파드를 나열해요. 여기에는 host-네트워킹 모드로 실행 중인 파드와 Cilium 배포 전에 시작된 파드가 포함돼요.
k8s-unmanaged.sh
예시:
$ curl -sLO https://raw.githubusercontent.com/cilium/cilium/main/contrib/k8s/k8s-unmanaged.sh
$ chmod +x k8s-unmanaged.sh
$ ./k8s-unmanaged.sh
kube-system/cilium-hqpk7
kube-system/kube-addon-manager-minikube
kube-system/kube-dns-54cccfbdf8-zmv2c
kube-system/kubernetes-dashboard-77d8b98585-g52k5
kube-system/storage-provisioner
문제 보고하기 (Reporting a problem)
문제를 보고하기 전에 실패 상태가 사라지기 전에 클러스터에서 필요한 정보를 가져와야 해요.
자동 로그 및 상태 수집 (Automatic log & state collection)
최신 버전의 Cilium CLI를 설치하세요. Cilium CLI는 Cilium 설치, Cilium 설치 상태 점검, 다양한 기능(예: clustermesh, Hubble) 활성화/비활성화에 사용할 수 있어요.
Linux:
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
macOS:
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "arm64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-darwin-${CLI_ARCH}.tar.gz{,.sha256sum}
shasum -a 256 -c cilium-darwin-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-darwin-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-darwin-${CLI_ARCH}.tar.gz{,.sha256sum}
전체 릴리스 페이지도 참고하세요.
그런 다음 cilium sysdump 명령을 실행해 Kubernetes 클러스터에서 트러블슈팅 정보를 수집하세요:
cilium sysdump
기본적으로 cilium sysdump는 클러스터의 모든 노드에 대해 가능한 한 많은 로그를 수집하려 시도해요. 클러스터 크기가 20개 노드를 넘으면 다음 옵션을 설정해 sysdump의 크기를 제한하는 것을 고려하세요. 필수는 아니지만 대역폭이나 업로드 크기에 제약이 있는 사용자에게 유용해요.
--node-list옵션을 설정해 노드가 많은 경우 일부 노드만 선택하세요.--logs-since-time옵션을 설정해 문제가 시작된 시점으로 돌아가세요.--logs-limit-bytes옵션을 설정해 로그 파일 크기를 제한하세요(참고:kubectl logs에 전달됨; 전체 수집 아카이브에는 적용되지 않아요). 이상적으로는 모든 노드의 짧은 기록보다 선택된 노드의 전체 기록이 있는 sysdump를 선호해요(--node-list사용). 두 번째 권장 방법은 문제가 시작된 시점을 좁힐 수 있다면--logs-since-time을 사용하는 거예요. 마지막으로 Cilium 에이전트와 Operator 로그가 너무 크면--logs-limit-bytes를 고려하세요.
--help로 더 많은 옵션을 확인하세요:
cilium sysdump --help
단일 노드 Bugtool
Kubernetes를 실행하지 않는다면 단일 노드 범위로 버그 수집 도구를 수동으로 실행할 수도 있어요:
cilium-bugtool은 디버깅을 위해 환경에 대한 잠재적으로 유용한 정보를 수집해요. 이 도구는 단일 Cilium 에이전트 노드를 디버깅하기 위한 것이에요. Kubernetes의 경우 Cilium 파드가 여러 개 있으면 도구가 모두에서 디버깅 정보를 가져올 수 있어요. 도구는 여러 곳에서 명령 출력과 파일 모음을 아카이브해 작동해요. 기본적으로 tmp 디렉터리에 기록해요.
명령은 Cilium 파드/컨테이너 내부에서 실행해야 한다는 점에 유의하세요.
cilium-bugtool
위처럼 옵션 없이 실행하면 파일 몇 개를 복사하고 명령 몇 개를 실행하려 시도해요. kubectl이 감지되면 Cilium 파드를 검색해요. 기본 라벨은 k8s-app=cilium이며, 이것과 네임스페이스는 각각 k8s-namespace와 k8s-label로 변경할 수 있어요.
Kubernetes 파드에서 아카이브를 캡처하려면 프로세스가 조금 달라요:
$ # First we need to get the Cilium pod
$ kubectl get pods --namespace kube-system
NAME READY STATUS RESTARTS AGE
cilium-kg8lv 1/1 Running 0 13m
kube-addon-manager-minikube 1/1 Running 0 1h
kube-dns-6fc954457d-sf2nk 3/3 Running 0 1h
kubernetes-dashboard-6xvc7 1/1 Running 0 1h
$ # Run the bugtool from this pod
$ kubectl -n kube-system exec cilium-kg8lv -- cilium-bugtool
[...]
$ # Copy the archive from the pod
$ kubectl cp kube-system/cilium-kg8lv:/tmp/cilium-bugtool-20180411-155146.166+0000-UTC-266836983.tar /tmp/cilium-bugtool-20180411-155146.166+0000-UTC-266836983.tar
[...]
참고
아카이브에서 민감한 정보를 확인하고 우리와 공유하기 전에 제거하세요.
아래는 아카이브에 포함된 정보의 대략적인 목록이에요.
- Cilium status
- Cilium version
- Kernel configuration
- Resolve configuration
- Cilium endpoint state
- Cilium logs
- Docker logs
dmesgethtoolip aip linkip riptables-savekubectl -n kube-system get podskubectl get pods,svc for all namespacesunameuptimecilium-dbg bpf * listcilium-dbg endpoint get for each endpointcilium-dbg endpoint listhostnamecilium-dbg policy getcilium-dbg service list
디버깅 정보 (Debugging information)
Kubernetes를 실행하지 않는다면 cilium-dbg debuginfo 명령으로 유용한 디버깅 정보를 가져올 수 있어요. Kubernetes를 실행한다면 이 명령은 system dump의 일부로 자동 실행돼요.
cilium-dbg debuginfo는 Cilium API에서 유용한 출력을 출력할 수 있어요. 출력 형식은 Markdown이라 이슈 트래커에 버그를 보고할 때 사용할 수 있어요. 인자 없이 실행하면 표준 출력으로 출력하지만, 다음과 같이 파일로 리다이렉트할 수도 있어요:
cilium-dbg debuginfo -f debuginfo.md
참고
debuginfo 파일에서 민감한 정보를 확인하고 우리와 공유하기 전에 제거하세요.
Slack 도움 (Slack assistance)
Cilium Slack 커뮤니티는 문제 트러블슈팅이나 문제 해결 방법 논의를 위한 유용한 첫 번째 도움 지점이에요. 커뮤니티는 누구에게나 열려 있어요.
GitHub로 이슈 보고 (Report an issue via GitHub)
Cilium에서 이슈를 발견했다고 생각되면 GitHub 이슈를 보고하고 위에서 설명한 대로 system dump를 첨부해 개발자가 이슈를 재현할 가장 좋은 기회를 갖도록 하세요.