Calico 네트워크 모드 알아보기
Calico 네트워크 모드 알아보기
💡 KANS 스터디
CloudNet에서 주관하는 KANS(Kubernetes Advanced Networking Study)으로 쿠버네티스 네트워킹 스터디입니다. 아래의 글은 스터디의 내용을 기반으로 작성했습니다.스터디에 관심이 있으신 분은 CloudNet Blog를 참고해주세요.
요약
Calico에서 지원하는 네트워크 모드가 있다. (다른 노드에 위치한 파드 통신에서 사용)
- IPIP: 기본값(ip 패킷을 하나 더 쌓아 터널링)
- Direct: 터널링 없이 전송
- VXLAN: Flannel에서 default로 사용하며, IP위에 VXLAN을 쌓아 터널링
여기서는 Direct 방법에 대해 자세히 살펴본다.
Direct 모드
- 장점: 터널링이 없다. 오버헤드가 없으니 빠르다.
- 단점: 라우터와 연동이 필요하다 (기업의 경우 네트워크 팀과 협업 필요)
Direct 모드를 사용하려면, NIC SRC/DST check 모드를 해제(disables)해야 한다. 우리는 CloudFormation으로 배포할 때 설정되어있어 별도의 작업이 필요없다.
현재 상태를 확인한다. IPIP 모드인 것을 확인할 수 있다.
아래의 명령어를 통해 ipip모드를 끈다. (direct mode)
1
2
root@k8s-m:~# calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/ipipMode: Always/ipipMode: Never/" | calicoctl apply -f -
Successfully applied 1 'IPPool' resource(s)
라우팅 테이블 정보가 달라진 것을 확인할 수 있다.
위에 사진에서는 다른 노드에 위치한 파드 대역이면 tunl0 인터페이스로 라우팅됐지만, 지금은 호스트 이더넷 인터페이스로 라우팅된다.
** 하지만, 통신을 진행하면 같은 서브넷에 위치한 파드끼리는 (정확히는 같은 서브넷에 위치한 노드에 있는 파드)통신이 가능하나 다른 서브넷에 위치한 파드는 통신이 안된다. Direct 모드를 지원하지위해선 Router 연동이 필요하나, AWS는 내부 라우터를 사용하기에 이를 현재 테스트할 순 없다. 아쉬운대로 아래의 Cross Subnet 방식을 사용해본다.
Cross Subnet
BPG(Router) 연동을 하지 않으면, 다른 네트워크 대역에 있는 노드와 통신하기 어렵다. 이럴땐 CrossSubnet 모드를 사용한다. 이때는 네트워크 대역에 존재하는 노드는 Direct, 아닌 노드는 IPIP 터널링으로 통신된다.
아래 명령어를 통해 설정을 진행한다.
1
calicoctl patch ippool default-ipv4-ippool -p '{"spec":{"ipipMode":"CrossSubnet"}}'
- 설정 확인
1
2
3
calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv4-ippool 172.16.0.0/16 true CrossSubnet Never false false all()
라우팅 정보를 확인하면 다른 서브넷의 경우 tunl0으로, 같은 서브넷의 경우 이더넷으로 라우팅된다.
실습 진행
아래의 파드를 배포하고, 정상적으로 통신되는지 확인한다.
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
31
32
33
34
35
36
37
38
39
cat node3-pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
nodeName: k8s-w1
containers:
- name: pod1
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
name: pod2
spec:
nodeName: k8s-w2
containers:
- name: pod2
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
name: pod3
spec:
nodeName: k8s-w0
containers:
- name: pod3
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
다른 서브넷에 위치한 파드끼리 통신을 진행한다. (pod1 ↔ pod3)
1
2
3
4
5
(⎈|HomeLab:N/A) root@k8s-m:~# k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 45s 172.16.158.3 k8s-w1 <none> <none>
pod2 1/1 Running 0 45s 172.16.184.4 k8s-w2 <none> <none>
pod3 1/1 Running 0 44s 172.16.34.1 k8s-w0 <none> <none>
아래와 같이 정상적으로 통신되는 것을 확인할 수 있다.
워커노드1에서 tunl0 인터페이스를 tcpdump한 모습이다. tunl0 인터페이스를 사용한다는 것을 눈으로 확인할 수 있다.