안녕하세요. Playce Cloud팀 이성림입니다.
쿠버네티스 파드 네트워크에 이은 두 번째 칼리코입니다.
칼리코 소개
쿠버네티스 네트워크는 CNI(Container Network Interface) 표준을 지키는 네트워크 플러그인이 필요합니다. CNI 표준을 지키는 솔루션은 Calico 이외에도 다양한 선택지가 있지만 저희 팀에서 설계/제안 할 때 주로 선택하는 것이 Calico이기 때문에 주제로 선정하였습니다. 네트워크 플러그인에서 지원하는 항목이나 특성, 성능에 따라서 다른 플러그인을 선택하여 사용할 수 있습니다.
CNI 참고 사이트)
https://kubernetes.io/ko/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/
https://github.com/containernetworking/cni
쿠버네티스 네트워크 플러그인은 표준 CNI를 따라야 한다고 하는데 아래와 같은 요구사항이 있다고 합니다. 쿠버네티스를 경험해 보신 분이라면 당연히 되어야 할 기능으로 생각되지 않으신가요?
1. veth 페어 생성 및 컨테이너 네트워크 인터페이스와 연결
2. Pod 네트워크 대역 확인 후 IP 설정
3. CNI 설정 파일 작성
4. IP 설정 및 관리
5. 컨테이너 내 기본 라우팅 정보 삽입 (default route rule)
6. 동료 노드들에게 IP 라우팅 정보 전달(advertising the routes)
7. 호스트 서버에 라우팅 정보 삽입
8. 네트워크 정책에 따라 트래픽 처리
...
출처 - https://coffeewhale.com/packet-network2
칼리코 개발 회사인 Tigera 홈페이지에서 칼리코 아키텍처를 확인할 수 있습니다.
네트워크 플러그인은 노드/파드 통신을 원할하게 해주는 역할을 하기 때문에 쿠버네티스 노드에 네트워크 화살표만 그려져 있는 것을 볼 수 있습니다. 간단한 그림이 실제로는 어떻게 구성이 되어져 있는지 확인해보도록 하겠습니다.
설명에 설명하는 쿠버네티스에서 사용하는 칼리코 버전은 v3.21.2입니다.
root@sung-ubuntu01:~/tmp# calicoctl version
Client Version: v3.21.2
Git commit: 17461419
Cluster Version: v3.21.2
Cluster Type: kubespray,bgp,kubeadm,kdd,k8s
calicoctl 명령어로 모든 노드가 메쉬 형태로 연결되어 있는 것을 확인 할 수 있습니다.
root@sung-ubuntu01:~/tmp# calicoctl node status
Calico process is running.
IPv4 BGP status
+-----------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+-----------------+-------------------+-------+----------+-------------+
| 192.168.110.101 | node-to-node mesh | up | 02:45:04 | Established |
| 192.168.110.103 | node-to-node mesh | up | 02:40:50 | Established |
| 192.168.110.104 | node-to-node mesh | up | 02:41:00 | Established |
| 192.168.110.102 | node-to-node mesh | up | 02:44:42 | Established |
+-----------------+-------------------+-------+----------+-------------+
root@sung-ubuntu04:~# calicoctl node status
Calico process is running.
IPv4 BGP status
+-----------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+-----------------+-------------------+-------+----------+-------------+
| 192.168.110.100 | node-to-node mesh | up | 02:40:49 | Established |
| 192.168.110.101 | node-to-node mesh | up | 02:45:02 | Established |
| 192.168.110.104 | node-to-node mesh | up | 02:40:59 | Established |
| 192.168.110.102 | node-to-node mesh | up | 02:44:42 | Established |
+-----------------+-------------------+-------+----------+-------------+
마스터 노드에서 wokrloadEndpoint를 조회하면, 생성된 파드 정보와 노드 위치, 인터페이스까지 확인 할 수 있습니다.
*master 서버에서만 출력
# 생성된 파드에 대한 위치, 정보 확인
root@sung-ubuntu01:~/tmp# calicoctl get workloadEndpoint
WORKLOAD NODE NETWORKS INTERFACE
multi-container sung-ubuntu05 10.233.78.3/32 calib4cfe5eb958
multi-container2 sung-ubuntu04 10.233.99.2/32 calia85a668c715
ubuntu-test sung-ubuntu04 10.233.99.1/32 calie3df4d89b13
BGP 피어링은 179번 포트를 사용하며, 아래 BGP 그림을 참고하시면 이해하기가 쉽습니다.
root@k8s-master01:~# netstat -antlp | grep 179
tcp 0 0 0.0.0.0:179 0.0.0.0:* LISTEN 831313/bird
tcp 0 0 192.168.110.111:179 192.168.110.115:54063 ESTABLISHED 831313/bird
tcp 0 0 192.168.110.111:179 192.168.110.112:40507 ESTABLISHED 831313/bird
tcp 0 0 192.168.110.111:179 192.168.110.113:52189 ESTABLISHED 831313/bird
tcp 0 0 192.168.110.111:179 192.168.110.114:51323 ESTABLISHED 831313/bird
Q. 위 상태에서 multi-container2 파드를 삭제하면 sung-ubuntu04 노드의 인터페이스는 어떻게 변할까요?
-> 칼리코 workloadEndpoint에서도 삭제 되겠지만 노드에서 생성된 해당 파드와 연결된 인터페이스도 삭제 됩니다. ifconfig 명령어로 확인 시 calib4cfe5eb958 인터페이스가 삭제되게 됩니다.
BGP(Border Gateway Protocol)
BGP는 기업의 사내망과 인터넷, 국가 간 통신 방법에 비유 할 수 있습니다. AS(Autonomous System)은 각 Zone을 의미하며, 쿠버네티스에서는 해당 내용을 각 노드 내 파드 통신과 노드 간의 통신으로 적용하여 설명 할 수 있습니다.
AS 간 통신은 eBGP라고 하며, AS 내 통신은 iBGP라고 합니다.
칼리코 구성확인 및 Data-Path 확인
💡 리눅스 네임스페이스
1. 리눅스 시스템은 초기 구동 시 하나의 단일 네임스페이스를 갖는다.
2. 파일 시스템, 프로세스ID, 사용자ID, 네트워크 인터페이스 등과 같은 모든 시스템 자원은 단일 네임스페이스에 속한다.
3. 네임스페이스를 추가로 만들고 리소스를 구성할 수 있다.
4. 프로세스를 실행하면 프로세스는 네임스페이스 중 하나에서만 실행되며 동일 네임스페이스 내 리소스만 볼수 있다.
5. 여러 종류의 네임스페이스가 존재하므로 프로세스는 하나의 네임스페이스에만 속하지 않고 각 종류의 네임스페이스에 속한다.
6. 네임스페이스는 마운트(mnt), 프로세스(pid), 네트워크(net), 프로세스간 통신(ipc), UTS, 사용자ID(user)가 있다.
Q. 컨테이너가 리눅스의 네임스페이스 격리 기술을 활용 한다던데.. 어떻게 확인할 수 있을까요?
#네트워크 네임스페이스 확인
root@sung-ubuntu04:~# lsns -t net
NS TYPE NPROCS PID USER NETNSID NSFS COMMAND
4026531992 net 160 1 root unassigned /run/docker/netns/default /sbin/init
4026532314 net 3 313510 root 0 /run/docker/netns/6c1ef9da93ed /pause
4026532393 net 7 474316 root 1 /run/docker/netns/6698a621349f /pause
*컨테이너는 네트워크 네임스페이스로 네트워크를 분리하기 때문에 2개의 파드가 서로 다른 네트워크 네임스페이스(0,1)을 가지는 것을 확인할 수 있습니다.
#Pause Container가 부모 프로세스입니다.
root@sung-ubuntu04:~# ps -ef | grep 313510
root 313510 313479 0 12:35 ? 00:00:00 /pause
칼리코 인터페이스 dump를 통해 실제 트래픽이 이동하는 것을 확인해 보겠습니다.
#4번 노드에서 cali 인터페이스 확인
root@sung-ubuntu04:~# ifconfig -a
calia85a668c715: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1480
inet6 fe80::ecee:eeff:feee:eeee prefixlen 64 scopeid 0x20<link>
ether ee:ee:ee:ee:ee:ee txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5 bytes 446 (446.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
calie3df4d89b13: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1480
inet6 fe80::ecee:eeff:feee:eeee prefixlen 64 scopeid 0x20<link>
ether ee:ee:ee:ee:ee:ee txqueuelen 0 (Ethernet)
RX packets 3747 bytes 254298 (254.2 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5769 bytes 24076756 (24.0 MB)
#calia85a668c715 인터페이스 tcpdump 확인
root@sung-ubuntu04:~# VETH1=calia85a668c715
root@sung-ubuntu04:~# tcpdump -i $VETH1 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on calia85a668c715, link-type EN10MB (Ethernet), capture size 262144 bytes
..대기중
#마스터 노드에서 4번 노드 POD에 ping 테스트(다른 세션)
root@sung-ubuntu01:~/tmp# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
multi-container 2/2 Running 0 164m 10.233.78.3 sung-ubuntu05 <none> <none>
multi-container2 2/2 Running 0 69m 10.233.99.2 sung-ubuntu04 <none> <none>
ubuntu-test 1/1 Running 0 3h16m 10.233.99.1 sung-ubuntu04 <none> <none>
#ping
root@sung-ubuntu01:~/tmp# ping 10.233.99.2
PING 10.233.99.2 (10.233.99.2) 56(84) bytes of data.
64 bytes from 10.233.99.2: icmp_seq=1 ttl=63 time=1.38 ms
#calia85a668c715 인터페이스 tcpdump 확인
root@sung-ubuntu04:~# tcpdump -i $VETH1 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on calia85a668c715, link-type EN10MB (Ethernet), capture size 262144 bytes
16:05:46.144509 IP 10.233.95.0 > 10.233.99.2: ICMP echo request, id 2, seq 1, length 64
16:05:46.145001 IP 10.233.99.2 > 10.233.95.0: ICMP echo reply, id 2, seq 1, length 64
#sung-ubuntu01(10.233.95.0) -> sung-ubuntu04(10.233.99.2)로 ICMP echo request 확인
---
#sung-ubuntu05 노드의 파드에서 ping 테스트
root@sung-ubuntu01:~/tmp# kubectl exec -it multi-container -c ubuntu -- bash
root@multi-container:/# ping 10.233.99.2
root@sung-ubuntu04:~# tcpdump -i $VETH1 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on calia85a668c715, link-type EN10MB (Ethernet), capture size 262144 bytes
16:13:18.856132 IP 10.233.78.3 > 10.233.99.2: ICMP echo request, id 341, seq 1, length 64
16:13:18.856660 IP 10.233.99.2 > 10.233.78.3: ICMP echo reply, id 341, seq 1, length 64
16:13:23.952285 ARP, Request who-has 10.233.99.2 tell 192.168.110.103, length 28
16:13:23.952244 ARP, Request who-has 169.254.1.1 tell 10.233.99.2, length 28
16:13:23.952792 ARP, Reply 169.254.1.1 is-at ee:ee:ee:ee:ee:ee, length 28
16:13:23.952809 ARP, Reply 10.233.99.2 is-at f6:8b:49:61:d0:02, length 28
* 169.254.1.1(link-local address)
169.254.1.1는 IP 주소 관리 대행사가 예약한 예약 IP 주소이며 공용 또는 개인 IP로 할당되지 않습니다.
예약된 IP는 일반적으로 소프트웨어, 개인 네트워크, 호스트, 서브넷, 문서, 변환, 멀티 캐스트, 브로드 캐스트, 로컬 통신, 루프백, 릴레이, 링크, 매핑, 테스트 및 향후 사용과 같은 특수 목적으로 사용됩니다.
출처 - https://ko.ipshu.com/ipv4/169.254.1.1
쿠버네티스에서 사용하는 칼리코 Pool과 해당 Pool이 어떤 모드를 사용하는지도 확인 할 수 있습니다.
구축 후 모드 변경이 가능하며, calico 홈페이지에서 자세한 방법을 확인 할 수 있습니다.
#Calico NAT 정책 확인 (true)
root@sung-ubuntu01:~/tmp# calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-pool 10.233.64.0/18 true Always Never false false all()
#워커 노드에서 iptables nat 확인
root@sung-ubuntu04:~# iptables -n -t nat --list cali-nat-outgoing
Chain cali-nat-outgoing (1 references)
target prot opt source destination
MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0 /* cali:flqWnvo8yq4ULQLa */ match-set cali40masq-ipam-pools src ! match-set cali40all-ipam-pools dst random-fully
=> cali-nat-outgoing 정책으로 외부로 나가는 패킷은 모두 MASQUERADE하여 처리됨 (=외부로 나가는 트래픽은 MASQURADE 정책을 통해 나갈 수 있음)
*IP Masquerade
- NAT 기술 안에 속한 기술로 가면이라는 의미
- NAT와 다르게 주소변환만 하는 것이 아닌 포트번호까지 포트포워딩 시켜주는 기능을 가지고 있음
- SNAT(Source NAT)와 같다고 함.
칼리코 모드
칼리코 네트워크 방식은 Overlay 방식과 Overlay를 사용하지 않는 방식(Direct)로 구분 할 수 있으며, 쿠버네티스 배포 툴인 kubespray release-2.19 부터 기본 옵션이 ipip에서 vxlan으로 변경되었습니다.
1. Direct 방식
- Pod 통신 패킷이 출발지 라우팅 정보를 보고 목적지 노드로 원본 패킷 그대로 전달
- 성능적으로 가장 우수
2. Overlay 방식 (터널링)
- Pod의 네트워크 정보를 노드에서 Encapsulation(캡슐화)하여 목적지 노드로 전달
- IP 기반의 터널링 방식으로 파드의 패킷 전달
- 각 노드 패킷에 대한 Encapsulation / Decapsulation 과정 실행
2.1. IPIP 모드
→ IP-in-IP라고 불리우는 Overlay 방식으로, Calico의 기본 모드
→ Pod의 네트워크 패킷의 기존 IP헤더 앞에 IP헤더를 하나 더 덧붙여 통신하는 방식
→ 다른 노드간 Pod 통신은 tunl0 인터페이스를 통해 IP 헤더에 감싸져서 상대 노드로 도달 후 tunl0 인터페이스에서 Outer 헤더를 제거하고 내부의 파드와 통신
2.2 VXLAN 모드
→ POD간 통신이 노드 구간에 VXLAN Encapsultation을 통해 이루어 짐
Q. 노드의 칼리코 인터페이스의 mtu는 몇으로 설정되어 있나요?
칼리코 구성요소
Calico 모듈과 그 기능들에 대해서 정리해 보겠습니다.
아래 표는 calico 홈페이지에 정리된 내용을 일부 번역/정리하였습니다.
💡 Calico 구성요소
- The `calico/node` container is deployed to every node (on Kubernetes, by a DaemonSet), and runs three internal daemons:
Felix(필릭스)
- the Calico daemon that runs on every node and provides endpoints.
- calico-node 파드 안에 위치하며, 모든 노드의 endpoint 제공
- K8s ETCD 정보를 읽음
- 라우팅 테이블 생성
- kube-proxy가 iptables 모드인 경우, iptables 컨트롤
- kube-proxy가 ipvs 모드인 경우, ipvs 컨트롤 |
BIRD(버드)
- the BGP daemon that distributes routing information to other nodes.
- 다른 노드에 있는 BGP 데몬들과 라우팅 정보 교환.
- TCP 179를 이용해서 mesh 형태로 연
confd
- a daemon that watches the Calico datastore for config changes and updates
BIRD’s config files.
- Calico 데이터 저장소의 구성 변경을 감시하고 BIRD의 구성 파일을 업데이트하는 데몬
출처 - [https://projectcalico.docs.tigera.io/reference/node/configuration]
실제로 칼리코는 쿠버네티스에서 어떻게 배포되어 사용되고 있을까요?
#calino-node는 daemonset으로 배포되어있습니다.
root@sung-ubuntu01:/var/lib/cni# kubectl -n kube-system get all | grep cali
pod/calico-kube-controllers-6bc8445c8-kptbp 1/1 Running 48 2d23h
pod/calico-node-ckvhb 1/1 Running 4 (2d23h ago) 2d23h
pod/calico-node-d2pr7 1/1 Running 5 (2d23h ago) 2d23h
pod/calico-node-fnmg9 1/1 Running 5 (2d23h ago) 2d23h
pod/calico-node-gqr27 1/1 Running 9 (2d23h ago) 2d23h
pod/calico-node-gzrt9 1/1 Running 8 (2d23h ago) 2d23h
daemonset.apps/calico-node 5 5 5 5 5 kubernetes.io/os=linux 2d23h
deployment.apps/calico-kube-controllers 1/1 1 1 2d23h
replicaset.apps/calico-kube-controllers-6bc8445c8 1 1 1 2d23h
calico-node 파드를 살펴보겠습니다. 어떤 컨테이너들로 구성되어 있는지, Probe는 어떻게 체크하는지, 기본 리소스는 어떻게 설정되어 있는지 확인해보세요. 시스템에 규모/사용량에 따라서 리소스를 수정해야하는 경우가 있습니다.
root@sung-ubuntu01:~# kubectl -n kube-system describe pod calico-node-ckvhb
Name: calico-node-ckvhb
Namespace: kube-system
Priority: 2000001000
Priority Class Name: system-node-critical
Node: sung-ubuntu01/192.168.110.100
Start Time: Fri, 26 Aug 2022 11:33:59 +0900
Labels: controller-revision-hash=bc4df5999
k8s-app=calico-node
pod-template-generation=1
Annotations: <none>
Status: Running
IP: 192.168.110.100
IPs:
IP: 192.168.110.100
Controlled By: DaemonSet/calico-node
Init Containers:
upgrade-ipam:
Container ID: docker://5c0d79f72455a568d8df8242131c7c997200ad6a0612819e76ed731a599f5d18
Image: quay.io/calico/cni:v3.21.2
Image ID: docker-pullable://quay.io/calico/cni@sha256:7aa6c97fc5f6a6959f8b06bacc12e6f593c68e6e0839e1f454ba0b9523255a79
Port: <none>
Host Port: <none>
Command:
/opt/cni/bin/calico-ipam
-upgrade
State: Terminated
Reason: Completed
Exit Code: 0
Started: Fri, 26 Aug 2022 11:34:42 +0900
Finished: Fri, 26 Aug 2022 11:34:42 +0900
Ready: True
Restart Count: 0
Environment Variables from:
kubernetes-services-endpoint ConfigMap Optional: true
Environment:
KUBERNETES_NODE_NAME: (v1:spec.nodeName)
CALICO_NETWORKING_BACKEND: <set to the key 'calico_backend' of config map 'calico-config'> Optional: false
Mounts:
/host/opt/cni/bin from cni-bin-dir (rw)
/var/lib/cni/networks from host-local-net-dir (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-bhp9z (ro)
install-cni:
Container ID: docker://deaf5d827119ae09e88b6f2dd816e4e7d7b04b5bbe39c67daaf70b268af3f2cd
Image: quay.io/calico/cni:v3.21.2
Image ID: docker-pullable://quay.io/calico/cni@sha256:7aa6c97fc5f6a6959f8b06bacc12e6f593c68e6e0839e1f454ba0b9523255a79
Port: <none>
Host Port: <none>
Command:
/opt/cni/bin/install
State: Terminated
Reason: Completed
Exit Code: 0
Started: Fri, 26 Aug 2022 11:35:33 +0900
Finished: Fri, 26 Aug 2022 11:36:19 +0900
Ready: True
Restart Count: 0
Environment Variables from:
kubernetes-services-endpoint ConfigMap Optional: true
Environment:
CNI_CONF_NAME: 10-calico.conflist
UPDATE_CNI_BINARIES: true
CNI_NETWORK_CONFIG_FILE: /host/etc/cni/net.d/calico.conflist.template
SLEEP: false
KUBERNETES_NODE_NAME: (v1:spec.nodeName)
Mounts:
/host/etc/cni/net.d from cni-net-dir (rw)
/host/opt/cni/bin from cni-bin-dir (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-bhp9z (ro)
flexvol-driver:
Container ID: docker://af898ab3c87a361deb668e39cccbcbaa8e8b7cc2bc3779bffcddb25d8b298d23
Image: quay.io/calico/pod2daemon-flexvol:v3.21.2
Image ID: docker-pullable://quay.io/calico/pod2daemon-flexvol@sha256:2397cea01382233f942edeecc2c205e241aa0a292e2624449df9b6c9381fa1a5
Port: <none>
Host Port: <none>
State: Terminated
Reason: Completed
Exit Code: 0
Started: Fri, 26 Aug 2022 11:36:45 +0900
Finished: Fri, 26 Aug 2022 11:36:45 +0900
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/host/driver from flexvol-driver-host (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-bhp9z (ro)
Containers:
calico-node:
Container ID: docker://8f6b34864db9b809b59a8da7e9149979d91bdac10c5477edcd70ebbf593e14d0
Image: quay.io/calico/node:v3.21.2
Image ID: docker-pullable://quay.io/calico/node@sha256:895a10b9d68d8f724f72e0bd002d435862ce997c85658ce7d4c6407c34bc65ab
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 26 Aug 2022 11:40:30 +0900
Last State: Terminated
Reason: Error
Exit Code: 1
Started: Fri, 26 Aug 2022 11:39:13 +0900
Finished: Fri, 26 Aug 2022 11:39:31 +0900
Ready: True
Restart Count: 4
Limits:
cpu: 300m
memory: 500M
Requests:
cpu: 150m
memory: 64M
Liveness: exec [/bin/calico-node -felix-live -bird-live] delay=10s timeout=10s period=10s #success=1 #failure=6
Readiness: exec [/bin/calico-node -bird-ready -felix-ready] delay=0s timeout=10s period=10s #success=1 #failure=6
Environment Variables from:
kubernetes-services-endpoint ConfigMap Optional: true
Environment:
DATASTORE_TYPE: kubernetes
WAIT_FOR_DATASTORE: true
CALICO_NETWORKING_BACKEND: <set to the key 'calico_backend' of config map 'calico-config'> Optional: false
CLUSTER_TYPE: <set to the key 'cluster_type' of config map 'calico-config'> Optional: false
CALICO_K8S_NODE_REF: (v1:spec.nodeName)
CALICO_DISABLE_FILE_LOGGING: true
FELIX_DEFAULTENDPOINTTOHOSTACTION: RETURN
FELIX_HEALTHHOST: localhost
FELIX_IPTABLESBACKEND: Legacy
FELIX_IPTABLESLOCKTIMEOUTSECS: 10
CALICO_IPV4POOL_IPIP: Off
FELIX_IPV6SUPPORT: False
FELIX_LOGSEVERITYSCREEN: info
CALICO_STARTUP_LOGLEVEL: error
FELIX_USAGEREPORTINGENABLED: False
FELIX_CHAININSERTMODE: Insert
FELIX_PROMETHEUSMETRICSENABLED: False
FELIX_PROMETHEUSMETRICSPORT: 9091
FELIX_PROMETHEUSGOMETRICSENABLED: True
FELIX_PROMETHEUSPROCESSMETRICSENABLED: True
NODEIP: (v1:status.hostIP)
IP_AUTODETECTION_METHOD: can-reach=$(NODEIP)
IP: autodetect
NODENAME: (v1:spec.nodeName)
FELIX_HEALTHENABLED: true
FELIX_IGNORELOOSERPF: False
CALICO_MANAGE_CNI: true
Mounts:
/host/etc/cni/net.d from cni-net-dir (rw)
/lib/modules from lib-modules (ro)
/run/xtables.lock from xtables-lock (rw)
/var/lib/calico from var-lib-calico (rw)
/var/log/calico/cni from cni-log-dir (ro)
/var/run/calico from var-run-calico (rw)
/var/run/nodeagent from policysync (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-bhp9z (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
lib-modules:
Type: HostPath (bare host directory volume)
Path: /lib/modules
HostPathType:
var-run-calico:
Type: HostPath (bare host directory volume)
Path: /var/run/calico
HostPathType:
var-lib-calico:
Type: HostPath (bare host directory volume)
Path: /var/lib/calico
HostPathType:
cni-net-dir:
Type: HostPath (bare host directory volume)
Path: /etc/cni/net.d
HostPathType:
cni-bin-dir:
Type: HostPath (bare host directory volume)
Path: /opt/cni/bin
HostPathType:
xtables-lock:
Type: HostPath (bare host directory volume)
Path: /run/xtables.lock
HostPathType: FileOrCreate
host-local-net-dir:
Type: HostPath (bare host directory volume)
Path: /var/lib/cni/networks
HostPathType:
cni-log-dir:
Type: HostPath (bare host directory volume)
Path: /var/log/calico/cni
HostPathType:
policysync:
Type: HostPath (bare host directory volume)
Path: /var/run/nodeagent
HostPathType: DirectoryOrCreate
flexvol-driver-host:
Type: HostPath (bare host directory volume)
Path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec/nodeagent~uds
HostPathType: DirectoryOrCreate
kube-api-access-bhp9z:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Burstable
Node-Selectors: kubernetes.io/os=linux
Tolerations: op=Exists
node.kubernetes.io/disk-pressure:NoSchedule op=Exists
node.kubernetes.io/memory-pressure:NoSchedule op=Exists
node.kubernetes.io/network-unavailable:NoSchedule op=Exists
node.kubernetes.io/not-ready:NoExecute op=Exists
node.kubernetes.io/pid-pressure:NoSchedule op=Exists
node.kubernetes.io/unreachable:NoExecute op=Exists
node.kubernetes.io/unschedulable:NoSchedule op=Exists
Events: <none>
위 calico-node 설정에서 설정 파일을 찾으셨나요? 해당 파일을 찾아보면 실제로 칼리코의 설정을 확인 할 수 있습니다.
root@sung-ubuntu01:/etc/cni/net.d# ll
total 20
drwxr-xr-x 2 kube root 4096 Aug 26 11:36 ./
drwxr-xr-x 3 kube root 4096 Aug 26 11:08 ../
-rw-r--r-- 1 root root 713 Aug 26 11:36 10-calico.conflist
-rw------- 1 root root 2850 Aug 29 11:59 calico-kubeconfig
-rw-r--r-- 1 root root 715 Aug 26 11:32 calico.conflist.template
root@sung-ubuntu01:/etc/cni/net.d# cat 10-calico.conflist
{
"name": "cni0",
"cniVersion":"0.3.1",
"plugins":[
{
"datastore_type": "kubernetes",
"nodename": "sung-ubuntu01",
"type": "calico",
"log_level": "info",
"log_file_path": "/var/log/calico/cni/cni.log",
"ipam": {
"type": "calico-ipam",
"assign_ipv4": "true",
"ipv4_pools": ["10.233.64.0/18"]
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type":"portmap",
"capabilities": {
"portMappings": true
}
},
{
"type":"bandwidth",
"capabilities": {
"bandwidth": true
}
}
]
}
칼리코 노드/파드 인터페이스 이해
칼리코 인터페이스 설명 부분에서 169.254.1.1 아이피가 기억나시나요? 해당 아이피를 특수 목적으로 사용하는 예약 IP 주소라고 설명을 했습니다. 해당 아이피를 link-local address라고 하며, 쿠버네티스 노드 인터페이스와 파드 안의 인터페이스를 이어주는 역할을 합니다.
###
#sung-ubuntu05 노드의 파드에서 ping 테스트
root@sung-ubuntu01:~/tmp# kubectl exec -it multi-container -c ubuntu -- bash
root@multi-container:/# ping 10.233.99.2
root@sung-ubuntu04:~# tcpdump -i $VETH1 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on calia85a668c715, link-type EN10MB (Ethernet), capture size 262144 bytes
16:13:18.856132 IP 10.233.78.3 > 10.233.99.2: ICMP echo request, id 341, seq 1, length 64
16:13:18.856660 IP 10.233.99.2 > 10.233.78.3: ICMP echo reply, id 341, seq 1, length 64
16:13:23.952285 ARP, Request who-has 10.233.99.2 tell 192.168.110.103, length 28
16:13:23.952244 ARP, Request who-has 169.254.1.1 tell 10.233.99.2, length 28
16:13:23.952792 ARP, Reply 169.254.1.1 is-at ee:ee:ee:ee:ee:ee, length 28
16:13:23.952809 ARP, Reply 10.233.99.2 is-at f6:8b:49:61:d0:02, length 28
###
TCP dump 상에서 보였던 낯선 IP 169.254.1.1는 예약 IP 주소이며, link-local address
💡 link-local address
- 직접 연결된 동일 링크 및 subnet에서 사용하는 주소
- 링크 로컬 주소는 FE80::/10의 고정된 대역과 interface의 EUI-64 ID의 결합으로 이루어짐
- 169.254.1.0 ~ 169.254.254.255(IPv4) 범위의 예약된 네트워크 주소
다시 노드의 네트워크 인터페이스를 확인해 보겠습니다. 노드 인터페이스가 파드 인터페이스와 어떻게 연결이 되어있는지 dump내용과 비교해보세요.
root@sung-ubuntu04:~# ifconfig
calia85a668c715: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1480
inet6 fe80::ecee:eeff:feee:eeee prefixlen 64 scopeid 0x20<link>
ether ee:ee:ee:ee:ee:ee txqueuelen 0 (Ethernet)
RX packets 75 bytes 6790 (6.7 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 80 bytes 7236 (7.2 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
calie3df4d89b13: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1480
inet6 fe80::ecee:eeff:feee:eeee prefixlen 64 scopeid 0x20<link>
ether ee:ee:ee:ee:ee:ee txqueuelen 0 (Ethernet)
RX packets 3747 bytes 254298 (254.2 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5769 bytes 24076756 (24.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
...
#ubuntu 컨테이너 접속
root@sung-ubuntu01:~/tmp# kubectl exec -it multi-container -c ubuntu -- bash
root@multi-container:/# apt install iproute2 -y
root@multi-container:/# ip route
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link
=> 169.254.1.1는 파드의 IPv4 link-local Address
마지막으로 공식 홈페이지에서 설명하는 칼리코 데이터흐름을 확인해보세요.
길게 설명한 내용이 한 페이지에 정리가 되어있으며, 모든 것이 칼리코에서 자동으로 이루어지기 때문에 흐름만 익히면 문제가 생겼을 경우 해결이 수월 할 것입니다!
https://projectcalico.docs.tigera.io/reference/architecture/data-path