[Kubernetes] Calico CNI 동작원리 이해하기

Jade·2022년 2월 1일
5

Kubernetes Advanced Networking Study(KANS)의 3주차 내용을 학습하며 정리한 내용입니다.

Calico 기본 통신 이해

Calico CNI 알아보기

소개(링크)

  • Calico란, 컨테이너, 가상 머신 및 기본 호스트 기반 워크로드를 위한 오픈 소스 네트워킹 및 네트워크 보안 솔루션이다.
  • Kubernetes, OpenShift, Mirantis Kubernetes Engine(MKE), OpenStack 및 베어메탈 서비스를 포함한 광범위한 플랫폼 지원한다.
  • Calico의 eBPF 데이터 플레인을 사용하든 Linux의 표준 네트워킹 파이프라인을 사용하든 Calico는 진정한 클라우드 네이티브 확장성과 함께 놀랍도록 빠른 성능을 제공한다.
  • Calico는 공용 클라우드나 온프레미스, 단일 노드 또는 수천 개의 노드 클러스터에서 실행되는지 여부에 관계없이 개발자와 클러스터 운영자에게 일관된 경험과 기능 세트를 제공한다.

구성 요소 아키텍처(링크)

  • 여러가지 구성 요소가 많지만, 일단 눈여겨 볼 내용은 Calico가 사용하는 Datastore[1]와 마스터 노드를 포함한 모든 노드들에 존재하는 Calico Pods[2]

    • Felix (필릭스) : 인터페이스 관리, 라우팅 정보 관리, ACL 관리, 상태 체크
    • BIRD (버드): BGP Peer 에 라우팅 정보 전파 및 수신, BGP RR(Route Reflector)
    • Confd : calico global 설정과 BGP 설정 변경 시(트리거) BIRD 에 적용해줌
    • Datastore plugin : calico 설정 정보를 저장하는 곳 - k8s API datastore(kdd) 혹은 etcd 중 선택
    • Calico IPAM plugin : 클러스터 내에서 파드에 할당할 IP 대역
    • calico-kube-controllers : calico 동작 관련 감시(watch)
    • calicoctl : calico 오브젝트를 CRUD 할 수 있다, 즉 datastore 접근 가능
    • BGP(Border Gateway Protocol): AS 사이에서 이용되는 라우팅 프로토콜. 대규모 네트워크(수천만의 경로 수)에 대응하도록 설계됐다. 그래서 BGP로 동작하는 라우터는 비교적 고가인 제품이 많다.
    • AS(Autonomous System): 하나의 정책을 바탕으로 관리되는 네트워크(자율 시스템)를 말한다. ISP, 엔터프라이즈 기업, 공공기관 같은 조직이 이에 해당하며 인터넷은 이러한 자율 시스템의 집합체이다.

구성 요소 확인하기

  • 데몬셋으로 각 노드에 calico-node 파드가 동작하여, 해당 파드에 bird, felix, confd 등이 동작 + Calico 컨트롤러 파드디플로이먼트로 생성
    • Calico의 특징은 BGP를 이용해 각 노드에 할당된 Pod 대역의 정보를 전달한다. 즉, 쿠버네티스 서버뿐만 아니라 물리적인 라우터와도 연동이 가능 하다는 뜻이다. (Flannel의 경우 해당 구성 불가)
    • Calico Pod 안에서 Bird라고 하는 오픈소스 라우팅 데몬 프로그램이 프로세스로 동작하여 각 Node의 Pod 정보가 전파되는 것이다.
    • 이후 Felix라는 컴포넌트가 리눅스 라우터의 라우팅 테이블 및 iptables rule에 전달 받은 정보를 주입하는 형태이다.
    • confd는 변경되는 값을 계속 반영할 수 있도록 트리거 하는 역할이다.

Calico 기본 통신 과정 확인하기

calicoctl 설치

  • 리소스 관리를 위해 Calico CLI를 설치 및 구성

마스터 노드 확인

  • Calico CNI 설치시, 데몬셋이므로 모든 노드에 칼리코 파드가 하나씩 존재하게 된다. (calico-node-*)

  • 칼리코 컨트롤러가 하나 존재하는 것을 확인할 수 있다.

  • calicoctl ipm show 명령어를 통해, IAPM 정보를 확인할 수 있다. 아래 스크린샷에서는 172.16.0.0/16 대역을 해당 쿠버네티스 클러스터에서 사용할 수 있다는 내용을 알 수 있다.

    • IPAM(IP Address Management): 풍부한 사용자 환경을 통해 IP 주소 인프라의 엔드 투 엔드 계획, 배포, 관리 및 모니터링을 지원하는 통합 도구 모음이다.
      IPAM은 네트워크상의 IP 주소 인프라 서버 및 DNS(도메인 이름 시스템) 서버를 자동으로 검색하여 중앙 인터페이스에서 이들 서버를 관리할 수 있다.
    • 옵션을 통해 아래와 같이 특정한 노드에 할당 가능한 대역대를 확인할 수도 있음(Block는 각 노드에 할당된 Pod CIDR 정보를 나타냄)
  • calicoctl node 정보 확인

  • ippool 정보 확인

  • 파드와 서비스 사용 네트워크 대역 정보 확인

실습 1.

동일 노드 내 파드 간 통신

  • 결론: 동일 노드 내의 파드 간 통신은 내부에서 직접 통신됨

파드 생성 전 노드(k8s-w1)의 기본 상태

노드(k8s-w1)에 파드 2개 생성

  • 아래 내용으로 node1-pod2.yaml 파일 작성 후 파드 생성
  • 파드 생성 전후의 변화를 관찰하기 위해 터미널 하단 추가 탭에watch calicoctl get workloadEndpoint 명령어를 사용하여 모니터링
    • calicoctl 명령어로 endpoint 확인: veth 정보도 확인할 수 있음

생성된 파드 정보 확인

네트워크 인터페이스 정보 확인(k8s-w1)

  • calice#~ 두개 추가된 것을 확인할 수 있음
  • 각각 net ns 0,1로 호스트와 구별되는 것을 확인할 수 있음

네트워크 네임스페이스 확인

  • 아래 2개 PAUSE 컨테이너가 각각 파드별로 생성된 것을 확인할 수 있음
  • 바로 위 스크린샷인 link-netnsid 0, link-netnsid 1과 매칭됨

라우팅 테이블 확인

  • 파드의 IP/32bit 호스트 라우팅 대역이 라우팅 테이블에 추가된 것을 확인할 수 있음

파드간 통신 실행 이해

  • (위) 마스터 노드에서 Pod1 Shell에 접근하여 Pod2로 Ping 테스트
  • (아래) 워커 노드(k8s-w1)에서 iptables 필터 테이블에 FORWARD 리스트 중 cali-FORWARD 룰 정보를 필터링해서 watch로 확인
  • 테스트 결과 아래 이미지와 같이 Host iptables에서 FOWRARD라는 테이블의 허용 조건에 따라 정상적으로 통신이 가능한 것을 확인할 수 있다.

파드에서 외부(인터넷)로의 통신

  • 결론: 파드에서 외부(인터넷) 통신 시에는 해당 노드의 네트워크 인터페이스 IP 주소로 MASQUERADE(출발지 IP가 변경) 되어서 외부에 연결됨

파드 배포 전 calico 설정 정보 확인 & 노드에 iptables 확인

  • 마스터 노드에서 아래 내용 확인: natOutgoing의 기본값이 true로 설정되어 있는 것을 확인 할 수 있다. 즉 이 노드에서 외부로 통신할 때 NAT의 MASQUERADE를 사용하겠다는 의미이다.

    NAT - MASQUERADE : 조건에 일치하는 패킷의 출발지 주소를 변환하는 것. 내부에서 전달되는 요청의 출발지 주소를 조건에 지정된 인터페이스의 IP로 변환한다.

  • 워커 노드(k8s-w1)에서도 외부로 통신시 MASQUERADE 동작 Rule이 존재하는 것을 확인할 수 있다.

마스터 노드에서 워커 노드(k8s-w1)에 아래 내용의 파드 1개 생성

외부 통신 가능 여부 확인

  • 통신 전, 워커 노드(k8s-w1)에 iptables NAT MASQUERADE 모니터링을 활성화 하면 외부 통신시 pkts값이 증가하는지 확인할 수 있다.
  • (위) 마스터 노드에서 Pod1 Shell 실행 후, 8.8.8.8로의 통신 성공
  • (아래) pkts 값이 이전 이미지와 다르게 증가한 것을 확인할 수 있다.

다른 노드에서 파드 간 통신

  • 결론: 다른 노드 환경에서 파드 간 통신시에는 IPIP터널(기본값) 모드를 통해서 이루어진다.
    • 각 노드에 파드 네트워크 대역은 Bird에 의해서 BGP로 광고 전파/전달 되며, Felix에 의해서 호스트의 라우팅 테이블에 자동으로 추가/삭제 된다.
    • 다른 노드 간의 파드 통신은 tunl0 인터페이스를 통해 IP 헤더에 감싸져서 상대측 노드로 도달 후 tunl0 인터페이스에서 Outer 헤더를 제거하고 내부 파드와 통신한다.

파드 배포 전, 노드에서 BGP에 의해 전달 받은 정보가 호스트 라우팅 테이블에 존재하는지 확인

  • 아래 명령어를 통해 나머지 노드들의 파드 대역을 자신의 호스트 라우팅 테이블에 가지고 있고, 해당 경로는 tunl0 인터페이스로 보내게 된다는 사실을 알 수 있다.

워커 노드(k8s-w1, w2)의 tunl0 정보 확인

  • 터널 인터페이스가 IP에 할당되어 있음
  • MTU는 1480 (칼리코 사용 시 파드의 인터페이스도 기본 MTU 1480 사용)
  • 현재 TX/RX 카운트는 0 --> 잠시 후, 오버레이 통신시 카운트 값이 증가할 것

마스터 노드에서 워커 노드(k8s-w1, w2) 대상으로 각각 파드 1개씩 생성

  • calicoctl 명령어를 이용하여 생성된 파드의 엔드포인트 확인

각 노드에서 파드 간 통신을 처리하는 라우팅 정보 확인

  • k8s-w1(172.16.158.4/32) 노드에서 w2(172.16.184.0) 노드 대역에 통신하려면 192.168.10.102를 거쳐야 한다는 것을 확인할 수 있다.
  • 반대로 w2(172.16.184.1/32) 노드에서 w1(172.16.158.0) 노드 대역에 통신하려면 192.168.10.101를 거쳐야 한다.

다른 노드 파드 간 통신이 어떻게 실행되는지 확인 ⇒ IPIP

  • (상) Pod2가 속한 노드(k8s-w2)에 tunl0 인터페이스 TX/RX 패킷 카운트 모니터링 세팅

  • (중) 마스터 노드에서 Pod1 Shell 접속 후, Pod2로 Ping 통신 테스트 준비

  • (하) Pod1이 속한 노드(k8s-w1)에서 패킷 덤프 세팅: tunl0 - 터널 인터페이스에 파드간 IP 패킷 정보를 확인할 수 있음

  • 결과

    • (중) Pod1 --> Pod2로 정상 통신 확인
    • (상) tunl0 인터페이스의 TX/RX 패킷 카운트가 각각 10개로 증가
    • (하) 실제 통신을 하게 되는 파드 간 IP 패킷 정보 확인
  • 실제로 오버레이 통신을 하고 있는지 확인하기 위해 패킷덤프 명령어를 아래와 같이 수정하여 Ping 통신을 다시 하였고, 결과적으로 IP Outer(파란색 박스) 헤더 정보 안쪽에 Inner(빨간색 박스) 헤더가 1개 더 있음을 확인할 수 있다.

Calico 네트워크 모드

Calico Mode 요약

  • 칼리코는 다양한 네트워크 통신 방법을 제공한다.

IPIP 모드

  • 파드 간 통신이 노드와 노드 구간에서는 IPIP 인캡슐레이션을 통해 이루어진다.
  • 단, Azure 네트워크에서는 IPIP 통신이 불가능하기 때문에 대신 VXLAN 모드를 사용한다고 한다.

Direct 모드

  • 파드 통신 패킷이 출발지 노드의 라우팅 정보를 보고 목적지 노드로 원본 패킷 그대로 전달된다.
  • 단, 클라우드 사업자 네트워크 사용 시, NIC에 매칭되지 않는 IP 패킷은 차단되니 NIC의 Source/Destination Check 기능을 Disable해야 정상 통신 가능 (AWS 문서 링크)

BGP 연동

  • Kubernetes 클러스터 내부 네트워크와 IDC 내부망 네트워크 간 직접 라우팅도 가능

VXLAN 모드

  • 파드 간 통신이 노드와 노드 구간에서는 VXLAN 인캡슐레이션을 통해서 이루어진다.
  • 다른 노드 간의 파드 통신은 vxlan 인터페이스를 통해 L2 프레임이 UDP - VXLAN에 감싸져 상대 노드로 도달 후 vxlan 인터페이스에서 Outer헤더를 제거하고 내부의 파드와 통신하게 된다.
  • BGP 미사용, VXLAN L3 라우팅을 통해서 동작한다.
  • UDP를 사용하므로 Azure 네트워크에서도 사용 가능하다.

Pod 패킷 암호화(네트워크 레벨)

  • Calico의 다양한 네트워크 모드 환경 위에서 WireGuard 터널을 자동 생성 및 파드 트래픽을 암호화하여 노드 간 전달한다.
  • Yaml 파일에 간단하게 추가하는 것만으로도 네트워크 레벨의 패킷 암호화를 설정할 수 있다.
  • WireGuard는 구닥다리 IPsec 및 OpenVPN의 대항마로 등장한 open source VPN project이며 작년, Linux 5.6 커널에 WireGuard 1.0.0 기본 패키지로 탑재되었다.
  • 정말 간결한 코드 구조빠른 성능 (모든 것이 kernel에서 동작하고, 주요 암호 알고리즘에 대해서 병렬처리하므로써 빠른 속도를 자랑함)

실습 2. WireGuard

WireGuard 설정

  • 모든 노드에 WireGuard를 설치(apt install wireguard -y)하고, Enabled 설정
  • 현재 노드에 존재하는 Wireguard 퍼블릭 키 확인
  • wireguard.cali 인터페이스 정보 확인
  • wg로 시작하는 명령어를 사용하여 wireguard.cali 설정 확인: 노드 별로 각각의 상대방 Peer의 IP와 퍼블릭 키를 확인할 수 있음

동작 확인

  • 아래 내용으로 파드 생성
  • (상) 파드가 생성된 노드의 eth0(enp0s8)에서 패킷 덤프 모니터링 세팅
  • (하) 생성한 파드 Shell 접속 후 Ping 통신 준비
  • (하) Pod2 IP 확인
  • (중) Pod1 --> Pod2 Ping 정상 통신
  • (상) 51820 포트 패킷 덤프 내용 확인
profile
우당탕탕 좌충우돌 인프라 여행기

2개의 댓글

comment-user-thumbnail
2022년 2월 3일

내용이 이해하기 쉽게 정리 잘 하셨네요!

내용 중간에 '마스터 노드에 WireGuard를 설치' -> '모든 노드에...' 로 변경해주시면 될것 같습니다.

그럼 나머지 기간도 잘 부탁드리겠습니다!

1개의 답글