[Project] Multi-Tenant K8s Cluster on ARM64 - (6) CNI 설정 - Calico 사용

developowl·2026년 3월 6일
post-thumbnail

이전 포스팅에서 Network Policy 적용을 위해 Calico를 설치하는 과정 중, 기존에 사용하던 Flannel 과 충돌하여 파드 생성에 실패하는 오류가 발생했습니다.
이번 포스팅에서는 CNI의 개념을 다시 한 번 짚어보고, 구체적인 문제 원인 파악과 함께 Calico 로의 마이그레이션 과정을 다시 한 번 정리해보겠습니다..(ㅜ…)


📌 쿠버네티스 네트워크의 심장, CNI(Container Network Interface)

CNI란?

  • 쿠버네티스는 자체적으로 파드 간의 네트워크를 구축하는 기능을 가지고 있지 않음
  • 대신 CNI 라는 표준 규격을 만들어 놓고, 네트워크 구현은 플러그인에게 맡김
  • 핵심 역할 : 파드가 생성될 때 가상 네트워크 인터페이스를 할당하고, 고유한 IP를 부여하며, 파드 간 통신 경로(Router)를 생성

⚠️ Flannel 에서 에러가 발생한 이유

Warning  FailedCreatePodSandBox  49m                    kubelet            Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "7a46363082ddde997807d803e54195e8a5b6d3fc96eab219318c78e6bb6aa93c": plugin type="flannel" failed (add): failed to load flannel 'subnet.env' file: open /run/flannel/subnet.env: no such file or directory. Check the flannel pod log for this node.
  • /run/flannel/subnet.env 파일이 없다는 에러 발생…!

상태 불일치

  • Flannel 설정 파일은 노드에 남아있는데, 정작 네트워크 일꾼 역할을 하는 Flannel Pod는 클러스터에 배포되지 않았거나 삭제된 상태
  • Kubelet 관점) CNI 설정 파일은 존재하기 때문에 Flannel을 호출하지만, 정작 일을 해야 할 Flannel 프로세스가 없어 발생하는 MissMatch 상황..!

Sandbox 생성 실패

  • 쿠버네티스는 파드를 만들기 전 Sandbox를 먼저 만드는데, CNI가 응답하지 않으니 파드 생성 자체가 멈춘 상황

격리 기능의 한계

  • Flannel은 단순 통신에는 강하지만, 현재 작업 중인 Network Policy(특정 네임스페이스 차단) 기능을 지원하지 않음.
    • 설계 자체가 통로만 뚫어주는 구조이기 때문

CNI 도구 비교: Flannel vs Calico vs Cilium

FlannelCalicoCilium
핵심 기술VXLAN (터널링)IPTables / BGPeBPF
보안 정책불가능 (차단 안 됨)강력함 (L3/L4 격리)매우 강력함 (L7/API 격리 가능)
복잡도매우 낮음중간높음
적절한 상황단순 학습용멀티 테넌시/엔터프라이즈고성능/대규모/관제 중심

현재 프로젝트에서는 Calico를 사용해보겠습니다.

Calico CNI 설치 및 전환

  • 기존의 꼬인 설정(Flannel 관련)을 삭제하고 새롭게 네트워크를 구축하는 과정

1. 구형 Flannel 설정 제거

# 모든 노드(Master, Worker)에서 실행
sudo rm /etc/cni/net.d/10-flannel.conflist

2. Calico Operator

  • Operator는 Calico의 컴포넌트들을 자동으로 관리해주는 네트워크 관리자 파드
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml

3. 클러스터 맞춤형 자원(CR) 배포

  • 클러스터의 Pod CIDR(주소 대역) 에 맞춰 설정을 주입해야 함.
  • 현재 라즈베리파이 홈랩에서는 10.244.0.0/16 을 사용
cat <<EOF | kubectl apply -f -
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  calicoNetwork:
    ipPools:
    - blockSize: 26
      cidr: 10.244.0.0/16
      encapsulation: VXLANCrossSubnet
      natOutgoing: Enabled
      nodeSelector: all()
EOF

📌 Calico 인데 VXLAN을 사용하는 이유?

Calico 는 기본적으로 BGP 라우팅을 권장하지만, 네트워크 환경에 따라 VXLAN 터널링 모드도 완벽하게 지원한다고 합니다.

설정의 편의성과 범용성을 고려하여 VXLAN 모드를 채택했습니다. VXLAN 방식을 사용하더라도, Calico를 사용하는 가장 큰 목적인 ‘L3/L4 Network Policy’ 기능은 그대로 활용할 수 있기에 적용해보았습니다.

(VXLAN, BGP, eBPF 에 대한 자세한 내용은 학습 후 정리해봐야겠습니다…. 넘 어렵습니다…ㅜ)

Zero-Trust 네트워크 격리 테스트

  • 허가받은 내부 통신은 허용하고, 허가받지 않은 외부 접근은 차단하는지 검증

1. 테스트 환경 준비

  • 네트워크 교체(Calico) 과정에서 파드 재시작이 되었을 수 있으니 현재 타겟 파드의 IP를 변수에 저장
TARGET_IP=$(kubectl get pod limit-test-pod -n tenant-alpha -o jsonpath='{.status.podIP}')

# 확인
echo "Target Pod IP: $TARGET_IP"

2. [Case 1] 내부 통신 테스트 (Intra-Namespace)

  • 시나리오: 같은 네임스페이스(현재 tenant-alpha)에 속한 파드끼리는 통신이 가능해야 함
kubectl exec local-tester -n tenant-alpha -- wget -qO- --timeout=2 $TARGET_IP
  • 결과

  • 이전에 작성해둔 Nginx 의 Welcome HTML 소스코드가 출력됨 (→ 정상 작동)
  • NetworkPolicyfrom.podSelector: {} 규칙이 동일 네임스페이스 내의 트래픽을 화이트리스트로 승인

3. [Case 2] 외부 침입 테스트 (Inter-Namespace)

  • 시나리오: 다른 네임스페이스(default)에서 tenant-alpha 로의 접근은 차단되어야 함
kubectl run intruder -n default --image=busybox --restart=Never -it --rm -- wget -qO- --timeout=5 $TARGET_IP
  • 결과

  • wget: download timed out (→ 정상 작동)
  • 정책에 정의되지 않은 외부 네임스페이스의 패킷을 Calico가 생성한 iptables 규칙에 의해 패킷이 커널 레벨에서 Drop 됨

.

.

.

→ Calico 설치 완료! 😋

profile
Don’t get mad at the computer.

0개의 댓글