본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

eBPF 모드 문제 해결

원문 보기 위키 갱신

eBPF 데이터플레인을 위한 일반적인 문제 해결 가이드를 소개해요. eBPF 모드 활성화 확인부터 서비스 접근 진단, BPF 맵 조회, calico-node NotReady, 성능 저하, CPU 사용량 급증 같은 자주 만나는 장애 상황을 하나씩 다뤄요. 문제가 생겼을 때 어디부터 확인하면 좋은지 순서대로 따라가 보세요.

출처: 문서

본문

이 문서는 eBPF 데이터플레인을 위한 일반적인 문제 해결 안내를 다뤄요.

기본 개념을 이해하려면 Tigera 엔지니어들의 다음 영상을 추천해요: Opening the Black Box: Understanding and troubleshooting Calico's eBPF Data Plane.

서비스 접근 문제 해결

  • eBPF 모드가 올바르게 활성화되어 있는지 확인해요

    calico-node 컨테이너의 로그를 살펴봐요. eBPF 모드가 지원되지 않는 아주 드문 경우에 다음 내용의 ERROR 로그가 남아요.

    BPF data plane mode enabled but not supported by the kernel. Disabling BPF mode.
    

    BPF 모드가 올바르게 활성화되었다면 다음 내용의 INFO 로그가 보여야 해요.

    BPF enabled, starting BPF endpoint manager and map manager.
    
  • eBPF 모드에서는 외부 클라이언트가 서비스(보통 NodePort)에 접근하는 트래픽을 노드에서 노드로 전달할 때 VXLAN 캡슐화를 사용해요. 백엔드 파드가 다른 노드에 있을 때 NodePort 연결이 타임아웃된다면, 하부 네트워크 패브릭이 노드 간 VXLAN 트래픽을 허용하는지 확인해요. VXLAN은 UDP 프로토콜이고, 기본 포트는 4789예요.

    이 VXLAN 트래픽은 파드 간 트래픽을 위해 사용 중일 수 있는 오버레이 네트워크와는 별개라는 점에 유의하세요.

  • DSR 모드에서는 Calico가 한 노드가 다른 노드를 대신해 응답할 수 있도록 하부 네트워크 패브릭이 허용해야 해요.

    • AWS에서는 이를 허용하려면 노드 NIC에서 Source/Dest check를 비활성화해야 해요. 다만 DSR은 AWS 내부에서만 동작하고, 로드 밸런서를 통과하는 외부 트래픽과는 호환되지 않아요. 로드 밸런서는 트래픽이 같은 호스트로 돌아오기를 기대하기 때문이에요.

    • GCP에서는 "Allow forwarding" 옵션을 활성화해야 해요. AWS와 마찬가지로 로드 밸런서를 통과하는 트래픽은 DSR과 올바르게 동작하지 않아요. 백엔드 노드에서 돌아오는 경로에서는 로드 밸런서가 관여하지 않기 때문이에요.

calico-node -bpf 도구

Calico의 내부 데이터 구조를 살펴보려면 calico-node -bpf 도구를 사용할 수 있어요. 이 도구는 calico/node 컨테이너 이미지에 내장되어 있고, calico-node 파드 안에서만 eBPF 데이터플레인 정보를 표시해요. kubectl get pod -o wide -n calico-system으로 calico-node 파드 이름을 찾은 뒤, 아래 명령에서 <calico-node-name> 대신 그 이름을 사용하세요.

도구를 실행하려면 다음을 사용해요.

kubectl exec -n calico-system <calico-node-name> -- calico-node -bpf <args>

예를 들어 도구의 도움말을 보려면:

kubectl exec -n calico-system <calico-node-name> -- calico-node -bpf help

  Available Commands:
    arp          Manipulates arp
    cleanup      Removes all calico-bpf programs and maps
    completion   Generate the autocompletion script for the specified shell
    connect-time Manipulates connect-time load balancing programs
    conntrack    Manipulates connection tracking
    counters     Show and reset counters
    help         Help about any command
    ifstate      Manipulates ifstate
    ipsets       Manipulates ipsets
    nat          Manipulates network address translation (nat)
    policy       Dump policy attached to interface
    profiling    Show and reset profiling data
    routes       Manipulates routes
    version      Prints the version and exits

(Since the tool is embedded in the main `calico-node` binary the `--help` option is not available, but running
`calico-node -bpf help` does work.)

예를 들어 BPF conntrack 테이블을 덤프하려면:

kubectl exec -n calico-system <calico-node-name> -- calico-node -bpf conntrack dump
...

서비스 접근 디버깅

서비스가 올바르게 프로그래밍되었는지 확인하려면 BPF NAT 테이블을 살펴봐요. BPF NAT 테이블을 덤프하려면:

kubectl exec -n calico-system <calico-node-name> -- calico-node -bpf nat dump

10.96.0.10 port 53 proto 6 id 4 count 2 local 0
    4:0	 192.168.129.66:53
    4:1	 192.168.129.68:53
10.96.0.10 port 53 proto 17 id 6 count 2 local 0
    6:0	 192.168.129.66:53
    6:1	 192.168.129.68:53
10.96.0.10 port 9153 proto 6 id 5 count 2 local 0
    5:0	 192.168.129.66:9153
    5:1	 192.168.129.68:9153
10.105.77.92 port 5473 proto 6 id 0 count 2 local 0
    0:0	 10.128.1.192:5473
    0:1	 10.128.1.195:5473
10.105.187.231 port 8081 proto 6 id 2 count 1 local 0
    2:0	 192.168.105.131:8081
10.109.136.88 port 7443 proto 6 id 1 count 1 local 0
    1:0	 192.168.129.72:7443
10.109.139.39 port 443 proto 6 id 7 count 2 local 0
    7:0	 192.168.129.67:5443
    7:1	 192.168.129.69:5443
10.96.0.1 port 443 proto 6 id 3 count 1 local 0
    3:0	 10.128.0.255:6443

연결이 추적되고 있는지 확인하려면 BPF conntrack 테이블을 살펴봐요. BPF conntrack 테이블을 덤프하려면:

kubectl exec -n calico-system <calico-node-name> -- calico-node -bpf conntrack dump

TCP 192.168.58.7:49178 -> 10.111.57.87:80 -> 192.168.105.136:80  Active ago 4.486606371s CLOSED              <--- example of connection to service with per-packet NAT
TCP 10.128.1.194:41513 -> 10.128.1.192:179  Active ago 26.442759238s ESTABLISHED                             <--- example of connection without NAT or with connect-time NAT
TCP 192.168.58.7:42818 -> 10.111.57.87:80 -> 192.168.105.136:80  Active ago 1m15.987585857s CLOSED
TCP 10.128.1.192:58208 -> 10.109.136.88:7443 -> 192.168.58.5:7443  Active ago 4.935017508s ESTABLISHED
UDP 162.142.125.240:30603 -> 10.128.1.192:18989  Active ago 1m0.816678617s
UDP 127.0.0.1:48611 -> 127.0.0.53:53  Active ago 17.789851961s

클러스터 안에서 시작된 트래픽은 connect-time 로드 밸런싱을 사용해요. 기본적으로 connect-time 로드 밸런싱은 TCP 트래픽에만 활성화되어 있어요. connect-time 로드 밸런싱을 사용하면 NAT 처리가 애플리케이션이 connect()를 호출하는 시점에 일어나기 때문에 conntrack 테이블에 NAT 결과가 표시되지 않아요.

Calico가 패킷을 드롭하는지 확인

Calico가 패킷을 드롭한다고 의심되면 calico-node -bpf 도구로 BPF 카운터를 확인할 수 있어요. eBPF 데이터플레인은 인터페이스에 붙은 프로그램들로 나뉘어 있기 때문에, 관련 인터페이스의 카운터를 확인해야 해요. 모든 인터페이스의 카운터를 덤프하거나 --iface=<interface name>으로 특정 인터페이스의 카운터를 덤프할 수 있어요.

Dropped by policy 카운터가 늘어난다면 Calico가 정책 때문에 패킷을 드롭하고 있는 것이니 정책 설정을 확인해야 해요.

kubectl exec -n calico-system <calico-node-name> -- calico-node -bpf counters dump --iface=eth0
+----------+--------------------------------+---------+--------+-----+
| CATEGORY |              TYPE              | INGRESS | EGRESS | XDP |
+----------+--------------------------------+---------+--------+-----+
| Accepted | by another program             |       0 |      0 | N/A |
|          | by failsafe                    |       0 |      0 | N/A |
|          | by policy                      |       0 |      4 | N/A |
| Dropped  | NAT source collision           |       0 |      0 | N/A |
|          | resolution failed              |         |        |     |
|          | QoS control limit              |       0 |      0 | N/A |
|          | by policy                      |       0 |     11 | N/A |
|          | failed decapsulation           |       0 |      0 | N/A |
|          | failed encapsulation           |       0 |      0 | N/A |
|          | failed to create conntrack     |       0 |      0 | N/A |
|          | fragment of yet incomplete     |       0 |      0 | N/A |
|          | packet                         |         |        |     |
|          | fragment out of order within   |       0 |      0 | N/A |
|          | host                           |         |        |     |
|          | fragments not supported        |       0 |      0 | N/A |
|          | incorrect checksum             |       0 |      0 | N/A |
|          | malformed IP packets           |       0 |      0 | N/A |
|          | packets hitting blackhole      |       0 |      0 | N/A |
|          | route                          |         |        |     |
|          | packets with unknown route     |       0 |      0 | N/A |
|          | packets with unknown source    |       0 |      0 | N/A |
|          | packets with unsupported IP    |       0 |      0 | N/A |
|          | options                        |         |        |     |
|          | too short packets              |       0 |      0 | N/A |
| Other    | packets hitting NAT source     |       0 |      0 | N/A |
|          | collision                      |         |        |     |
| Redirect | neigh                          |       0 |      0 | N/A |
|          | peer                           |       0 |      0 | N/A |
|          | plain                          |      20 |      0 | N/A |
| Total    | packets                        |      34 |     22 | N/A |
+----------+--------------------------------+---------+--------+-----+

eBPF 프로그램 디버그 로그

때로는 eBPF 프로그램 자체가 내보내는 로그를 살펴봐야 할 때가 있어요. 로그가 매우 장황할 수 있지만(프로그램이 모든 패킷을 로그로 남기기 때문에) eBPF 프로그램 문제를 진단할 때 매우 유용해요. 로그를 활성화하려면 Felix 구성 설정 bpfLogLevel을 Debug로 설정해요.

경고: 이렇게 로그를 활성화하면 eBPF 프로그램 성능에 큰 영향을 줘요.

프로덕션 클러스터에서 성능 영향을 줄이려면 bpfLogFilters Felix 구성 설정으로 특정 트래픽이나 특정 인터페이스에 로깅을 좁힐 수 있어요. 필터는 pcap 표현식이에요.

필터는 NAT나 캡슐화가 적용되기 전의 원래 패킷에 적용된다는 점에 유의하세요. 따라서 서비스로 향하는 패킷이 여러 디바이스를 거쳐 가는 상황에서 그 패킷을 로그로 남기려면 서비스 IP와 포트, 그리고 백엔드 파드 IP와 포트 둘 다로 필터링해야 해요.

로그는 커널 trace 버퍼로 내보내지고, 다음 명령으로 확인할 수 있어요:

kubectl exec -n calico-system <calico-node-name> -- bpftool prog tracelog

로그 형식은 다음과 같아요:

     <...>-84582 [000] .Ns1  6851.690474: 0: ens192---E: Final result=ALLOW (-1). Program execution time: 7366ns

로그의 각 부분은 다음과 같이 설명할 수 있어요:

  • <...>-84582는 어떤 프로그램(또는 커널 프로세스)이 패킷을 처리했는지 알려주는 단서예요. 전송 중인 패킷이라면 보통 실제로 패킷을 보내는 프로그램의 이름과 PID예요. 수신되는 패킷이라면 보통 커널 프로세스이거나, 우연히 처리를 촉발한 무관한 프로그램이에요.

  • 6851.690474는 로그 타임스탬프예요.

  • ens192---E는 Calico 로그 태그예요. 인터페이스에 붙은 프로그램이라면 첫 부분에 인터페이스 이름의 앞 몇 글자가 들어가요. 접미사는 "Ingress" 또는 "Egress"를 뜻하는 -I 또는 -E예요. "Ingress"와 "Egress"는 정책에서와 같은 의미예요:

    • 워크로드 ingress 프로그램은 호스트 네트워크 네임스페이스에서 워크로드로 가는 경로에서 실행돼요.
    • 워크로드 egress 프로그램은 워크로드에서 호스트로 가는 경로에서 실행돼요.
    • 호스트 엔드포인트 ingress 프로그램은 외부 노드에서 호스트로 가는 경로에서 실행돼요.
    • 호스트 엔드포인트 egress 프로그램은 호스트에서 외부 호스트로 가는 경로에서 실행돼요.
  • ens192---X도 볼 수 있는데, 이는 XDP 프로그램을 뜻해요. Calico는 XDP 프로그램을 호스트 디바이스에 한해서 doNotTrack 정책을 구현하는 데 사용해요.

  • Final result=ALLOW (-1). Program execution time: 7366ns는 메시지예요. 여기서는 프로그램의 최종 결과를 로그로 남긴 경우예요. 이 타임스탬프는 로깅에 소요된 시간 때문에 크게 왜곡된다는 점에 유의하세요.

정책 문제 디버깅

Calico가 정책 때문에 패킷을 드롭한다고 의심되면 calico-node -bpf 도구로 특정 인터페이스에 붙은 정책을 덤프할 수 있어요.

kubectl exec -n calico-system <calico-node-name> -- calico-node -bpf policy dump <interface> <type> [--asm]

여기서:

  • <interface>는 인터페이스 이름이에요. 예를 들어 eth0 또는 caliXXXXXX예요.
  • <type>은 정책의 위치를 나타내요. ingress, egress, xdp 또는 all 중 하나예요.

ingress 정책 덤프 예시예요. 파드의 ingress 정책은 caliX veth 쌍의 호스트 쪽 tc/tcx egress 훅에 붙고, 호스트 엔드포인트의 ingress 정책은 호스트 인터페이스의 tc/tcx ingress 훅에 붙는 점에 유의하세요. egress 정책도 마찬가지예요.

IfaceName: calic31b4f7fc58
Hook: tc egress
Error:
Policy Info:
// Start of tier default
// Start of policy default/knp.default.allow-nginx-from-ubuntu
// Start of rule action:"allow"  protocol:{name:"tcp"}  dst_ports:{first:80  last:80}  src_ip_set_ids:"s:nzE8vwTu69FSscx2FDKjb20D9dZxEyVxsWFqwA"  original_src_selector:"projectcalico.org/orchestrator == 'k8s' && app == 'ubuntu-client'"  rule_id:"29vMYcPWr7reSxxN"
// IPSets src_ip_set_ids:<0x303904ae5eae5418>
// count = 9
// End of rule 29vMYcPWr7reSxxN
// End of policy default/knp.default.allow-nginx-from-ubuntu
// End of tier default: deny
// Start of rule action:"allow"  rule_id:"aBMQCbsUMESPKGRp"
// count = 0
// End of rule aBMQCbsUMESPKGRp

셀렉터를 사용하는 규칙은 IP 셋을 참조해요. ipsets 명령으로 IP 셋 내용을 덤프하고, 해당 IP 셋에 기대한 멤버가 들어 있는지 확인할 수 있어요:

kubectl exec -n calico-system <calico-node-name> -- calico-node -bpf ipsets dump

각 규칙에 매칭된 패킷 수를 볼 수 있어요. 이 예시에서는 9개 패킷이 규칙 29vMYcPWr7reSxxN에 매칭되었고, 0개 패킷이 규칙 aBMQCbsUMESPKGRp에 매칭되었어요.

--asm을 추가하면 프로그램의 eBPF 어셈블리 코드도 함께 보여요.

kubectl exec -n calico-system <calico-node-name> -- calico-node -bpf ipsets dump

IP set 0x303904ae5eae5418
   192.168.58.5/32

IP set 0xffef9f925a8a4ca4
   192.168.129.66/32
   192.168.129.68/32

calico-node NotReady 디버깅

calico-node 파드가 준비되지 않았다고 보이면 로그에서 오류를 확인해요. eBPF 모드에서 calico-node가 준비되지 않는 가장 유력한 원인은 Calico가 인터페이스에 붙은 프로그램을 갱신하지 못하는 것이에요. 다음 유형의 경고를 찾아보세요:

2025-09-22 22:39:59.801 [WARNING][10374] felix/bpf_ep_mgr.go 2107: Failed to apply policy to endpoint, leaving it dirty

이런 오류의 한 가지 원인은 calico/node 이미지에 포함된 eBPF 프로그램이 여러분 커널의 verifier와 호환되지 않는 것이에요. 각 커널은 자신이 적재하는 eBPF 프로그램이 안전하게 실행됨을 보장해야 해요. 그런데 verifier의 능력은 커널 버전마다 달라요. 우리는 다양한 커널로 eBPF 프로그램을 테스트하지만, 모든 커널을 테스트하는 것은 불가능해요. verifier가 프로그램을 거부하면 다음과 같은 오류를 볼 수 있어요:

265: (79) r1 = *(u64 *)(r10 -72)      ; R1_w=ctx(off=0,imm=0) R10=fp0
266: (79) r2 = *(u64 *)(r10 -128)     ; R2_w=scalar(umin=14,umax=74,var_off=(0x2; 0x7c)) R10=fp0
267: (b7) r5 = 0                      ; R5_w=0
268: (85) call bpf_skb_store_bytes#9
invalid access to map value, value_size=1512 off=8 size=0
R3 min value is outside of the allowed memory range
processed 1102 insns (limit 1000000) max_states_per_insn 2 total_states 38 peak_states 38 mark_read 27
-- END PROG LOAD LOG --
libbpf: prog 'calico_tc_skb_ipv4_frag': failed to load: -13
libbpf: failed to load object '/usr/lib/calico/bpf/to_wep_no_log.o'
2025-07-31 17:36:15.708 [WARNING][45] felix/bpf_ep_mgr.go 2124: Failed to apply policy to endpoint, leaving it dirty error=attaching program to wep: loading generic v4 tc hook program: error loading program: error loading object permission denied
attaching program to wep: loading generic v4 tc hook program: error loading program: error loading object permission denied name="enif327a56b833" wepID=&types.WorkloadEndpointID{OrchestratorId:"k8s", WorkloadId:"calico-system/csi-node-driver-tggmr", EndpointId:"eth0"}
2025-07-31 17:36:15.708 [WARNING][45] felix/bpf_ep_mgr.go 2124: Failed to apply policy to endpoint, leaving it dirty error=attaching program to wep: loading generic v4 tc hook program: error loading program: error loading object permission denied

이런 유형의 오류가 보이면 커널 버전과 배포판 정보를 포함해 Calico GitHub 저장소에 이슈를 열어 주세요.

성능 저하

여러 가지 문제가 eBPF 데이터플레인의 성능을 떨어뜨릴 수 있어요.

  • 클러스터에 가장 적합한 네트워킹 모드를 사용하고 있는지 확인해요. 가능하면 오버레이 네트워크 사용을 피하세요. 오버레이가 없는 라우티드 네트워크가 훨씬 빨라요. Calico의 오버레이 모드를 써야 한다면 IPIP가 아니라 VXLAN을 사용하세요. 커널 제약 때문에 IPIP는 eBPF 모드에서 성능이 좋지 않아요.

  • 오버레이를 사용하지 않는다면 Felix 구성 파라미터인 ipInIpEnabled와 vxlanEnabled가 false로 설정되어 있는지 확인해요. 이 파라미터는 오버레이를 사용하는 IP 풀이 없더라도 Felix가 IPIP나 VXLAN을 허용하도록 자기 자신을 구성할지 제어해요. 이 파라미터들은 IPIP 및 VXLAN과의 호환성을 위해 특정 eBPF 모드 최적화도 비활성화해요.

    구성을 확인하려면:

    kubectl get felixconfiguration -o yaml
    
    apiVersion: projectcalico.org/v3
    items:
    - apiVersion: projectcalico.org/v3
      kind: FelixConfiguration
      metadata:
        creationTimestamp: "2020-10-05T13:41:20Z"
        name: default
        resourceVersion: "767873"
        uid: 8df8d751-7449-4b19-a4f9-e33a3d6ccbc0
      spec:
        ...
        ipipEnabled: false
        ...
        vxlanEnabled: false
    kind: FelixConfigurationList
    metadata:
      resourceVersion: "803999"
    
  • AWS 같은 클라우드에서 클러스터를 운영한다면 클라우드 제공자가 클러스터 내 노드 간 대역폭을 제한할 수 있어요. 예를 들어 대부분의 AWS 노드는 연결당 5GBit으로 제한돼요.

런타임 프로파일링

bpfProfiling을 Enabled로 설정하면 eBPF 프로그램의 런타임 프로파일링 데이터 수집이 활성화돼요. 각 인터페이스에 붙은 각 eBPF 프로그램의 평균 실행 시간과 실행 횟수를 수집해요. 프로파일링 데이터는 calico-node -bpf profiling e2e 명령으로 확인할 수 있어요. 이 명령은 덤프 후 프로파일링 데이터를 초기화해요.

----------------+-------------+-----+-------------+-------+-------------+-------+-------------+-------+
|     IFACE      | INGRESS NEW |  #  | INGRESS EST |   #   | EGRESS NEW  |   #   | EGRESS ETS  |   #   |
+----------------+-------------+-----+-------------+-------+-------------+-------+-------------+-------+
| lo             | ---         | --- | ---         | ---   | 142.263 ns  | 10272 | ---         | ---   |
| eth0           | 2492.344 ns |  32 | 1535.443 ns | 16114 | 6296.421 ns |   749 | 1503.339 ns | 10982 |
| eni76136be4c77 | 5031.436 ns | 149 | 1194.923 ns |  1421 | 4950.196 ns |   138 | 1437.015 ns |  1432 |
| eni80d5c04bc95 | 7773.459 ns |  74 | 1508.973 ns |   641 | 4907.333 ns |    69 | 1715.848 ns |   646 |
| eth1           | 136.250 ns  |  24 | ---         | ---   | 75.320 ns   |    25 | ---         | ---   |
| eni5f8ab1cfc29 | 107.250 ns  |  36 | 1068.596 ns |  1514 | 189.528 ns  |    36 | 1104.335 ns |  1658 |
| bpfout.cali    | 440.000 ns  |   1 | ---         | ---   | 206.000 ns  |     1 | ---         | ---   |
+----------------+-------------+-----+-------------+-------+-------------+-------+-------------+-------+

MKE: VXLAN 디바이스 DOWN

MKE 클러스터에서는 eBPF 모드를 활성화한 뒤 vxlan.calico 디바이스가 DOWN 상태로 남고 Felix 로그에 다음이 표시될 수 있어요:

Failed to set tunnel device up error=address already in use

이는 MKE의 Docker Swarm 오버레이 네트워킹이 Docker 네트워크 네임스페이스(/run/docker/netns/) 안에서 UDP 포트 4789로 VXLAN 디바이스를 만들기 때문이에요. eBPF 모드에서 노드에 BTF가 있으면(보통 커널 v5.8+) Felix는 flow 모드(external)의 vxlan.calico를 만드는데, 이 디바이스는 자신의 UDP 포트에서 catch-all 역할을 해요. Docker Swarm의 VXLAN 디바이스가 이미 포트 4789를 점유하고 있어서 커널이 이를 거부해요.

iptables 모드에서는 이 충돌이 생기지 않아요. Calico의 VXLAN 디바이스가 특정 VNI(4096)로 바인딩되기 때문에 같은 포트에서 Docker Swarm의 VXLAN과 공존할 수 있어요.

진단:

# Confirm the VXLAN device is DOWN
kubectl exec -n calico-system <calico-node-pod> -- ip -d link show vxlan.calico

# Check what holds port 4789 (shows a kernel-owned socket with no process name)
kubectl exec -n calico-system <calico-node-pod> -- ss -ulnp sport = :4789

# Find Docker Swarm VXLAN devices in Docker network namespaces (run on the node via SSH)
for ns in /run/docker/netns/*; do
  echo "=== $(basename "$ns") ==="
  nsenter --net="$ns" ip -d link show type vxlan 2>/dev/null
done

해결: Calico의 VXLAN 포트를 바꿔 충돌을 피하세요:

kubectl patch felixconfiguration default --type merge -p '{"spec":{"vxlanPort":4790}}'

Felix가 몇 초 안에 새 포트로 vxlan.calico를 다시 만들어요. 각 노드에서 확인해요:

kubectl exec -n calico-system <calico-node-pod> -- ip -d link show vxlan.calico
# Should show: vxlan external ... dstport 4790 ... state UP

선택한 UDP 포트가 모든 노드 사이 하부 네트워크에서 허용되는지 확인하세요.

성공 팁: MKE 클러스터에서는 중단을 피하려면 eBPF 모드를 활성화하기 전에 VXLAN 포트를 설정하세요.

높은 CPU 사용량 디버깅

calico-node가 높은 CPU를 사용한다고 보이면:

  • kube-proxy가 아직 실행 중인지 확인해요. kube-proxy가 아직 실행 중이라면 kube-proxy를 비활성화하거나 Felix 구성 설정 bpfKubeProxyIptablesCleanupEnabled가 false로 설정되어 있는지 확인해야 해요. 이 설정이 true(기본값)이면 Felix가 kube-proxy의 iptables 규칙을 제거하려고 시도해요. kube-proxy가 아직 실행 중이라면 Felix가 계속 규칙을 제거하려 하고, 이로 인해 CPU 사용량이 높아질 수 있어요.
  • 클러스터가 매우 크거나 워크로드에 서비스 변동(churn)이 많다면 bpfKubeProxyMinSyncPeriod 설정 값을 늘려 Felix가 서비스 데이터플레인을 갱신하는 주기를 늘릴 수 있어요. 기본값은 1초예요. 값을 늘리면 서비스 갱신이 더 느리게 반영되는 트레이드오프가 있어요.
  • Calico는 kube-proxy와 마찬가지로 엔드포인트 슬라이스를 지원해요. Kubernetes 클러스터가 엔드포인트 슬라이스를 지원하고 활성화되어 있다면 bpfKubeProxyEndpointSlicesEnabled 구성 플래그로 Calico에서도 엔드포인트 슬라이스 지원을 켤 수 있어요.

더 알아보기 (Learn more)

eBPF 모드 문제 해결은 대체로 로그 확인 → BPF 맵 덤프 → 카운터·정책 확인 순서로 진행돼요. 서비스 접근 문제는 NAT 테이블과 conntrack 테이블부터 살펴보면 원인을 빨리 좁힐 수 있어요. calico-node NotReady가 반복되면 커널 verifier 호환성 여부도 꼭 의심해 보세요.