K8s Network
Calico CNI는 Kubernetes에서 네트워크 통신 시, 4가지 통신 제어 모드를 제공합니다.
각각 IPIP, Direct, VXLAN, Pod Packet 암호화이며, Default로 IPIP 모드로 설정됩니다.
아래는 Calico의 4가지 모드를 도식화하고, 통신 흐름을 빨간 선으로 표시한 것입니다.
IPIP 터널링 모드는 다른 노드간 Pod 통신 시, Pod 정보에 IP해더를 추가하는 방식입니다. 이때, tunl0 인터페이스를 통해 IP Header를 en/decapsulation가 진행되며, 원본 IP패킷은 Calico에 의해(IPIP프로토콜) Outer IP Header가 덧붙여집니다.
encapsultation이 진행된, Outer IP Header가 덧붙여진 모습은 아래와 같습니다.
VXLAN (Virtual eXtensible LAN) 은 L2 네트워크를 L3 위에서 확장하기 위한 오버레이 터널링 프로토콜입니다. 즉, 물리적으로 분리된 네트워크를 마치 동일한 L2 네트워크에 있는 것처럼 통신하게 해주는 기술입니다.
Calico는 Pod간 트래픽을 UDP 프로토콜을 사용하여, 캡슐화하여 전송합니다.
Felix가 라우팅 정보를 얻는 방식
라우팅 정보를 활용하는 방식
1. VXLAN 모드 전환 & bird 컴포넌트 비활성화
Calico 설치 시, 기본적으로 IPIP모드로 설정되어 있기에, VXLAN 모드로 전환이 필요합니다.
VXLAN 전환 전에, bird 컴포넌트 비활성화가 필요합니다.
kubectl apply -f https://raw.githubusercontent.com/gasida/KANS/main/3/calico-vxlan-kans.yaml
#bird 컴포넌트 비활성화 calico.yaml 파일 적용
calicoctl get ippool default-ipv4-ippool -o yaml > vxlan_mode.yaml
# vxlan 모드 활성화
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
cidr: 192.168.0.0/16
ipipMode: Never
vxlanMode: Always
natOutgoing: true
disabled: false
nodeSelector: all()
calicoctl apply -f vxlan_mode.yaml #vxlan 모드 적용
calicoctl get ippool default-ipv4-ippool -o wide #vxlan 활성화 확인
calicoctl apply -f vxlan_mode.yaml - vxlan 모드 적용
calicoctl get ippool default-ipv4-ippool -o wide - vxlan 활성화 확인
kubectl delete pod -n kube-system -l k8s-app=calico-node #calico pod 재실행 하여, 변경 사항 적용
라우팅 테이블 확인 시 vxlan.calico 인터페이스가 추가되어, vxlan 모드가 적용됨을 확인 가능합니다.
2. BGP 프로토콜 비활성화
vxlan 모드는 BGP 프로토콜을 활용하지 않기에, Control Plane을 포함한 전체 노드에서 비활성화가 필요합니다.
# bgp.yaml
apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:
name: default
spec:
logSeverityScreen: Info
nodeToNodeMeshEnabled: false
calicoctl apply -f bgp.yaml
calicoctl get bgpconfiguration default -o yaml #비활성화 확인
간단한 Pod를 3개 생성합니다.
Pod간 통신을 위해서는 아래와 같이 vxlan.calico 인터페이스에 대한 라우팅 테이블이 동적으로 생성되어 있어야 합니다.
Pod1 -> Pod3 (다른 노드 통신)
Pod 통신 시, worker1 -> worker2로 통신되기 위해서는 노드 외부로 나가야 하며, vxlan.calico 인터페이스를 통해 통신됩니다.
worker1의 eth0에 tcpdump를 걸어 확인합니다.
tcpdump -i eth0 udp port 4789 #Cloud 환경일 경우 반드시 보안 그룹에서 UDP로 해당 Port 오픈
kubectl exec -it pod1 – ping <pod3 IP>
WIrdGurad 모드는 Pod Packet을 암호화하여 통신합니다. 해당 모드 사용 시, wiregurad 인터페이스가 생성되며, 해당 인터페이스가 패킷을 암호화/복호화합니다.
다른 모드에 비해 암호화/복호화가 과정이 추가되기에, 네트워크 속도 저하의 단점이 있습니다.
apt install wireguard -y #전체 노드에 wireGurad 설치
calicoctl patch felixconfiguration default --type='merge' -p '{"spec":{"wireguardEnabled":true}}' #Control Plane에서 Calico Wireguard 모드 활성화
ot@-control:~# calicoctl get felixconfiguration default -o yaml | grep wireguardEnabled wireguardEnabled: true #활성화 확인
ip -c -d addr show wireguard.cali #활성화 시, wireguard 인터페이스 자동 생성됨
wg showconf wireguard.cali #패킷 암호화를 위한 공개키/개인키 정보 확인
vxlan 모드에서와 동일하게 pod1(worker1) -> pod3(worker2) 방향으로진행합니다.
tcpdump에 잡힌 패킷 확인 시, 51820 Port 및 UDP 프로토콜 통신이 확인됩니다.
해당 tcpdump 내용을 pcap 파일로 저장하여, 와이어샤크로 확인하면 데이터가 암호화되어 있음을 확인 가능합니다.