티스토리 뷰

Calico는 가상머신이나 컨테이너들을 위한 네트워킹, IP관리, 접근제어, 모니터링 등

다양한 네트워크 관련 기능을 제공하는 오픈소스 프로젝트로 주로 Tigera의 주도로 개발되고 있습니다.

다수의 K8s의 네트워크 서비스를 위한 CNI 플러그인들 중에서 현재 기준으로 가장 대중적인 선택지로 활용되고 있으며,

오픈스택이나 베어메탈, Windows 환경에서도 활용가능한 다재다능한 네트워크 솔루션입니다.

 

Calico는 k8s의 Pod들에게 네트워크 기능을 제공하기 위해, 개별 Node에 다수의 컴포넌트를 설치합니다.

설치된 컴포넌트들은 Calico에서 제공하는 다양한 기능들에 대한 역할을 담당하며,

사용자의 설치 환경과 사용 목적에 따라 다양한 조합으로 이루어질 수 있습니다.

이 중 k8s에서 Pod간의 네트워크를 위한 핵심 역할을 담당하는 것이 바로 Felix와 BIRD입니다.

 

  1) Felix

인터페이스 관리, 라우팅 정보 관리, ACL 관리, 상태 체크 등 다양한 역할을 담당하고 있습니다.

Calico 데이터베이스(typha, etcd)로부터 가져온 설정 정보를 기반으로 개별 Node의 정보를 갱신하고 적용합니다.

 

  2) BIRD

오픈소스 소프트웨어로 BGP 관련 컴포넌트로써, BGP Peer에게 라우팅 정보를 전달하고 수신합니다.

기본적으로 Full-Mesh 토플로지로 동작하나, 다수의 Peer가 존재할 경우 Route Reflector로 구성하는 것을 권장합니다.

 

K8s 환경에서 Calico를 설치한 후 제공되는 네트워킹 구성은 사용자 환경에 맞추어 선택이 가능합니다.

먼저 Direct 방식과 Overlay 방식 중 어떤 방식으로 네트워크 서비스를 제공할지 선택해야 하며,

두 방식 모두 Node간의 네트워크 구성을 기반으로 Pod간의 네트워크 서비스를 제공합니다.

 

  1) Direct 방식

Pod의 네트워크 정보를 Node의 위치와 상관없이 그대로 물리적인 네트워크 인터페이스로 전송합니다.

최종적으로 네트워크에 대한 처리는 물리적인 네트워크 장비에 의해 처리되기 때문에 성능적으로 가장 우수합니다.

MTU 역시 물리적 네트워크의 구성에 따라 확장 가능하며, 큰 MTU의 경우 대용량 파일 전송등에 있어 유리합니다.

하나의 통일된 네트워크를 쓰거나, 구조가 단순하여 네트워크 변경이 없는 경우

또는 네트워크 장비 구성에 대한 자동화를 통해 Pod 네트워크에 대한 자동 업데이트가 가능한 경우에 사용됩니다.

필요할 경우 Node간 통신을 암호화를 할 수 있으며, 이 경우 최대 MTU 사이즈에서 60Byte만큼 줄여야 합니다.

 

  2) Overlay 방식

Pod의 네트워크 정보를 Node에서 다시한번 Encapsulation 과정을 거쳐 목적지 Node로 전달합니다.

즉 IP 기반의 일종의 터널링 방식으로 Node간의 터널링 구간을 통해 Pod의 패킷이 전달됩니다.

각 Node에서 패킷에 대한 Encapsulation과 Decapsulation 과정이 필요하여 네트워크 성능저하가 발생할 수 있습니다.

물리적인 네트워크 구간의 최대 MTU에서 Encapsulation 되는 프로토콜에 따라 MTU 사이즈의 일부 축소가 필요하며,

감소되는 크기는 IPIP 모드의 경우 20Byte, VxLAN 모드일 경우 50Byte로 overlay 헤더에 의해 사용되는 사이즈입니다.

 

  3) CrossSubnet 방식

Direct 방식과 Overlay 방식이 혼합되어 있는 hybrid 형태입니다.

기본적으로 Node 간 같은 네트워크 대역일 경우에는 Direct 방식으로, 

Node간 다른 네트워크 대역일 경우에는 Overlay 방식의 IPIP 모드로 동작합니다.

동일한 네트워크 기반의 일정 규모의 Node까지는 Direct 방식으로 빠르게 처리합니다.

 

이 중 Overlay 방식의 경우 두가지 방식으로 한번 더 나뉘어 지며, 사용자 선택에 따라 사용할 수 있습니다.

 

  1. IPIP mode

 

일반적으로 IP-in-IP라고 불리우는 Overlay 방식으로, Calico 네트워킹의 기본 모드입니다.

IP-in-IP는 RFC1853과 RFC2003으로 표준화 되어 있으며, IP 기반의 Overlay 기능을 제공합니다.

다만 Azure 같은 일부 퍼블릭클라우드에서는 사용이 제한되어 있습니다.

IP-in-IP는 Pod의 네트워크 패킷의 기존 IP 헤더 앞에 IP 헤더를 하나 더 덧붙여 통신하는 방식입니다.

이를 통해 출발지 Pod의 네트워크 패킷 헤더에 출발지 Node의 네트워크 정보가 추가되고,

최종 Node에 도착하면 다시 도착지 Node의 헤더가 제거되고 도착지 Pod로 전달되는 방식입니다.

이때 출발지 Node에서는 BGP 라우팅을 통해 얻은 정보를 기반으로 도착지 Node에 대한 정보를 알고 있으며,

해당 정보를 기반으로 Node간 통신을 위한 헤더를 덧붙여 물리 네트워크를 통해 처리되도록 합니다.

 

IP-in-IP는 Overlay에서 발생하는 추가적인 헤더의 오버헤드가 상대적으로 적지만, 

데이터센터의 Fabric 관점에서 보자면, ECMP를 통한 대역폭과 경로 확장이 지원되지 못하는 확장의 단점이 존재합니다.

 

이제 실제 k8s 환경에서 구성을 확인해 보겠습니다.

기본적으로는 Virtualbox 위에 1대의 Control Plane(k8s-m)과 3대의 Node(k8s-w0/w1/w2)가 있는 테스트 환경입니다.

# kubectl get node -o wide

 

Calico의 현재 모드는 IPIPMODE가 Always인 상태 입니다.

#calicoctl get ippool -o wide

 

동작중인 프로세스를 확인해보면 Calico의 핵심 컴포넌트인 Felix와 BIRD를 확인할 수 있습니다.

#ps axf

 

Calico의 IPIP mode는 각 Node간에 BGP를 통해 서로의 정보를 학습합니다.

이 경우 각 Node는 동일한 네트워크일 필요는 없으며, 물리적으로 통신이 가능한 Node여야 합니다.

#calicoctl node status 

 

각 Node별도 개별 Pod를 구동한 환경입니다.

#kubectl get pod -o wide

 

Calico의 라우팅 테이블을 살펴보면, 오버레이를 통한 터널링 인터페이스가 tunl0로 나타나고 있습니다.

예를 들어 172.16.158.0으로 가기 위해서는 192.168.10.101으로 가야하며 tunl0 인터페이스를 통해야합니다.

# route -n | egrep 'Destination|tunl0)'

 

즉, pod1에서 pod3으로 통신이 발생한다면,

pod1에서 출발한 패킷은 출발지와 목적지의 IP 주소가 모두 Pod의 정보이겠지만,

Node에서 Tunl0를 거치면서 물리적 경로가 가진 인터페이스의 정보로 출발지와 목적지 주소가 모두 추가됩니다.

이후 물리적인 네트워크 구간을 지나 목적지 Node에서 추가된 Node의 출발지와 목적지 주소를 제거한 후,

목적지 Pod로 전달해주면, 목적지 Pod는 출발지와 목적지의 IP 주소가 모두 Pod의 정보인 패킷을 받게됩니다.

 

실제 물리적 구간의 패킷을 잡아보면 IP 헤더(ICMP) 앞에 하나의 IP 헤더(IPIP)가 더 있음을 확인할 수 있습니다.

calico-ipip.pcap
0.00MB

 

2. VxLAN 모드

 

VxLAN은 RFC7348에 의해 정의된 표준 오버레이 프로토콜로 UDP 기반의 터널링을 지원합니다.

기본적으로 패킷에 24bit의 VNI를 통해 약 1,600만개의 테넌트 네트워크를 구분할 수 있으며,

테넌트간의 네트워크 격리를 목적으로 클라우드 환경에서 주로 사용됩니다.

VxLAN은 네트워크 패킷앞에 VNI를 붙이고 VTEP의 정보를 기반으로 헤더를 하나 더 덧붙여 통신하는 방식입니다.

여기서 VTEP은 패킷의 Encapsulation과 Decapsulation이 발생하는 위치입니다.

이를 통해 출발지 Pod의 네트워크 정보 헤더에 VNI 및 출발지 Node의 네트워크 정보가 추가되고,

최종 Node에 도착하면 다시 도착지 Node의 헤더가 제거되고 VNI를 확인하여 도착지 Pod로 전달되는 방식입니다.

이때 출발지 Node에서는 FELIX를 통해 미리 etcd에서 네트워크 정보를 가져다가 라우팅 테이블을 업데이트 합니다.

그렇기 때문에 잦은 BGP 업데이트로 인한 시스템 부하를 줄일 수 있습니다.

또한, UDP를 사용함으로 IP-in-IP를 사용할 수 없는 Azure에서도 사용할 수 있습니다.

 

데이터센터 Fabric 관점에서 보면, VxLAN은 ECMP를 지원할 수 있습니다.

따라서 대역폭과 경로의 확장에 있어 유연함을 가져갈 수 있으며,

하드웨어 NIC을 통한 Offload 기능도 지원하고 있어 성능상의 장점을 가져갈 수도 있습니다.

 

다시 실제 k8s 환경에서 구성을 확인해 보겠습니다.

IP-in-IP에서 사용한 구성을 그대로 사용하였음으로,

동일하게 Virtualbox 위에 1대의 Control Plane(k8s-m)과 3대의 Node(k8s-w0/w1/w2)가 있는 테스트 환경입니다.

# kubectl get node -o wide

 

Calico의 현재 모드는 VXLANMODE가 Always인 상태 입니다.

#calicoctl get ippool -o wide

 

동작중인 프로세스를 확인해보면 BIRD는 보이지 않고 Felix만 확인됩니다.

그렇기 때문에, etcd에서 네트워크 정보가 변경이 발생할때마다 FELIX를 통해 가져와 라우팅 테이블을 업데이트 합니다.

#ps axf

 

Calico의 VXLAN mode에서는 BGP를 사용하지 않으며, BIRD가 동작하지 않습니다.

만약 외부의 BGP 라우터와 서로간의 네트워크 정보 교환이 필요할 경우라면, 별도의 설정이 필요합니다.

#calicoctl node status 

 

VxLAN 모드에서의 Peer를 확인해보면, BGP 없이도 서로간의 정보를 가지고 있습니다.

아래 두가지 정보를 동일한 MAC 기준으로 조합해보면,

192.168.10.102 Node에 172.16.184.2 VTEP이 위치하고 있음을 알 수 있습니다.

# bridge fdb show | grep vxlan
# ip neighbor show | grep vxlan

 

Pod 역시 기존 IP-in-IP 모드의 구성을 그대로 사용합니다.

각 Node별도 개별 Pod를 구동한 환경입니다.

#kubectl get pod -o wide

 

Calico의 라우팅 테이블을 살펴보면, 오버레이를 통한 터널링 인터페이스가 vxlan.calico로 나타나고 있습니다.

예를 들어 172.16.158.0으로 가기 위해서는 172.16.158.2로 가야하며 vxaln.calico인터페이스를 통해야합니다.

vxlan.calico는 패킷의 encapsulation과 decapsulation을 처리하는 VTEP의 역할을 담당합니다.

# route -n | egrep 'Destination|vxlan)'

 

즉, pod1에서 pod3으로 통신이 발생한다면,

pod1에서 출발한 패킷은 출발지와 목적지의 IP 주소가 모두 Pod의 정보이겠지만,

Node에서 vxaln.calico를 거치면서 기존 패킷 앞에 VNI 값과 VTEP의 가진 정보를 기반으로

Node의 물리적 경로가 가진 인터페이스의 IP 정보로 출발지와 목적지 주소가 모두 추가됩니다.

이후 물리적인 네트워크 구간을 지나 목적지 Node에서 추가된 VNI값과 VTEP의 출발지와 목적지 주소를 제거한 후,

Pod로 전달해주면, 목적지 Pod는 출발지와 목적지의 IP 주소가 모두 Pod의 정보인 패킷을 받게됩니다.

 

실제 물리적 구간의 패킷을 잡아보면 IP 헤더(IP) 앞에 VNI 정보가 추가되어 있으며,

그 앞에 하나의 IP 헤더(VxLAN)가 더 있음을 확인할 수 있습니다.

calico-vxlan.pcap
0.00MB

 

-----------------------------------------------------------------------------------------------

이 내용은 NDKS(Networking : Docker & K8s Study)의 졸업 과제로써 작성되었습니다.

NDKS는 '가시다'님이 속한 CloudNet@에서 진행하는 네트워크 엔지니어들을 위한 K8s 네트워킹 스터디입니다.

매주 일요일마다 소중한 정보를 퍼주셨던 '가시다'님께 무한 감사 드립니다.

https://www.notion.so/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863

댓글
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함
최근에 올라온 글
Total
Today
Yesterday
링크