Calico CNI(Container Network Interface)
벌써 3번째 시간입니다. 이번 시간에는 CNI 심화편으로 calico를 활용하는 방법을 배웠습니다. 네트워크 엔지니어가 아닌 분들은 이해하기 어렵다고 했는데, 쉽지는 않았습니다. 하나씩 따라해 보겠습니다.
Calico란?
-
Calico는 컨테이너, 가상 머신 및 기본 호스트 기반 워크로드를 위한 오픈 소스 네트워킹 및 네트워크 보안 솔루션입니다. Calico는 Kubernetes, OpenShift, Mirantis Kubernetes Engine(MKE), OpenStack 및 베어메탈 서비스를 포함한 광범위한 플랫폼을 지원합니다.
-
Calico의 eBPF 데이터 플레인을 사용하든 Linux의 표준 네트워킹 파이프라인을 사용하든 Calico는 진정한 클라우드 네이티브 확장성과 함께 놀랍도록 빠른 성능을 제공합니다. Calico는 공용 클라우드나 온프레미스, 단일 노드 또는 수천 개의 노드 클러스터에서 실행되는지 여부에 관계없이 개발자와 클러스터 운영자에게 일관된 경험과 기능 세트를 제공합니다.
Component architecture
Calico components
- Felix (필릭스) : 인터페이스 관리, 라우팅 정보 관리, ACL 관리, 상태 체크
- Programs routes and ACLs, and anything else required on the host to provide desired connectivity for the endpoints on that host. Runs on each machine that hosts endpoints. Runs as an agent daemon.
- BIRD (버드): BGP Peer 에 라우팅 정보 전파 및 수신, BGP RR(Route Reflector)
- Gets routes from Felix and distributes to BGP peers on the network for inter-host routing. Runs on each node that hosts a Felix agent. Open source, internet routing daemon.
- Confd : calico global 설정과 BGP 설정 변경 시(트리거) BIRD 에 적용
- Monitors Calico datastore for changes to BGP configuration and global defaults such as AS number, logging levels, and IPAM information. Open source, lightweight configuration management tool.
- Dikasted : Enforces network policy for Istio service mesh. Runs on a cluster as a sidecar proxy to Istio Envoy.
- Calico CNI Plugin : k8s 에 calico 네트워킹 환경을 제공
- Provides Calico networking for Kubernetes clusters
- Datastore plugin : calico 설정 정보를 저장하는 곳 - k8s API datastore(kdd) 혹은 etcd 중 선택
- Increases scale by reducing each node’s impact on the datastore
- Calico IPAM plugin : 클러스터 내에서 파드에 할당할 IP 대역
- Uses Calico’s IP pool resource to control how IP addresses are allocated to pods within the cluster
- calico-kube-controllers : calico 동작 관련 감시(watch)
- Typha : Datastore 와 felix, confd 다수간 연결하지 않고 Datastore 는 단일 Typha(중계자 역할) 로 연결, Typha 는 상태 캐시 및 이벤트 중복 제거 등으로 대규모 환경에서 부하를 감소 할 수 있음, 기본적으로 설치는 되지만 설정 구성되어 있지 않음
- Increases scale by reducing each node’s impact on the datastore. Runs as a daemon between the datastore and instances of Felix. Installed by default, but not configured.
- calicoctl : calico 오브젝트를 CRUD 할 수 있음, 즉 datastore 접근 가능
- Command line interface to create, read, update, and delete Calico objects. calicoctl command line is available on any host with network access to the Calico datastore as either a binary or a container
Calico 구성요소 확인
POD 내 Calico 구성요소
- 각 Node는 Calico POD 존재
Brid
를 통해 BGP로 변경된 POD 대역 정보 전파- 변경된 정보는
Felix
를 통해Route table
과Iptables
에 추가/삭제 처리
Calico 실습을 위한 K8S 배포
실습 환경은 K8S v1.22.6, 노드 OS(Ubuntu 20.04.3 LTS) , CNI(Calico v3.21.4, IPIP, NAT enable) , IPTABLES proxy mode / 회사 내부 라우터는 Quagga 로 구성되어 있습니다.
- 2개의 네트워크 대역이 존재 : 서로 다른 네트워크끼리 통신은
k8s-rtr
리눅스에서 라우팅 처리
10.0.2.0/24 대역은 enp0s3 에서 사용하는 대역으로 10.1.1.0/24 와 10.1.2.0/24 대역과는 다릅니다!
# K8S 배포에 사용할 폴더(디렉터리)를 생성 후 사용해주세요
# vagrant 파일 다운로드
$ curl -O https://raw.githubusercontent.com/gasida/KANS/main/3/Vagrantfile
# 배포 >> 윈도우(25분 소요), 맥(15분 소요)
$ vagrant up
# 배포 확인
$ vagrant status
# Linux Router(k8s-rtr) 접속
$ vagrant ssh k8s-rtr
# 마스터노드 접속
$ vagrant ssh k8s-m
# (워커)노드 접속
$ vagrant ssh k8s-w0
$ vagrant ssh k8s-w1
$ vagrant ssh k8s-w2
Calico 설치
Calico는 기본설치가 되어 있지 않습니다. 아래 명령어를 Main 노드에서 실행해야 합니다.
# 모니터링
$ watch -d 'kubectl get pod -n kube-system;echo;route -n'
# calico install : kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml - 서브넷 24bit 추가 - 링크
$ kubectl apply -f https://raw.githubusercontent.com/gasida/KANS/main/3/calico-kans.yaml
# calicoctl install
$ curl -L https://github.com/projectcalico/calico/releases/download/v3.21.4/calicoctl-linux-amd64 -o calicoctl
$ chmod +x calicoctl && mv calicoctl /usr/bin
Calico 정보 확인
# CNI 설치 후 파드 상태 확인
$ kubectl get pod -n kube-system -l k8s-app=calico-node -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
calico-node-b2qx2 1/1 Running 0 44m 192.168.10.101 k8s-w1 <none> <none>
calico-node-fbtkg 1/1 Running 0 83m 192.168.10.10 k8s-m <none> <none>
calico-node-s87fs 1/1 Running 0 5m26s 192.168.10.102 k8s-w2 <none> <none>
calico-node-wj9qq 1/1 Running 0 58m 192.168.20.100 k8s-w0 <none> <none>
# Calico 버젼 확인
$ calicoctl version
Client Version: v3.21.4
Git commit: 220d04c94
Cluster Version: v3.21.4
Cluster Type: k8s,bgp,kubeadm,kdd
# IPAM 정보 확인 - https://projectcalico.docs.tigera.io/reference/calicoctl/ipam/show
$ calicoctl ipam show
+----------+---------------+-----------+------------+--------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+---------------+-----------+------------+--------------+
| IP Pool | 172.16.0.0/16 | 65536 | 7 (0%) | 65529 (100%) |
+----------+---------------+-----------+------------+--------------+
# Block 는 각 노드에 할당된 podCIDR 정보
$ calicoctl ipam show --show-blocks
+----------+-----------------+-----------+------------+--------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+-----------------+-----------+------------+--------------+
| IP Pool | 172.16.0.0/16 | 65536 | 7 (0%) | 65529 (100%) |
| Block | 172.16.116.0/24 | 256 | 4 (2%) | 252 (98%) |
| Block | 172.16.158.0/24 | 256 | 1 (0%) | 255 (100%) |
| Block | 172.16.184.0/24 | 256 | 1 (0%) | 255 (100%) |
| Block | 172.16.34.0/24 | 256 | 1 (0%) | 255 (100%) |
+----------+-----------------+-----------+------------+--------------+
# 워커 노드마다 할당된 dedicated subnet (podCIDR) 확인
$ kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}' ;echo
172.16.0.0/24 172.16.1.0/24 172.16.2.0/24 172.16.3.0/24
# CNI Plugin 정보 확인 - 링크
$ tree /etc/cni/net.d/
/etc/cni/net.d/
├── 10-calico.conflist
└── calico-kubeconfig
0 directories, 2 files
$ cat /etc/cni/net.d/10-calico.conflist
{
"name": "k8s-pod-network",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "calico",
"log_level": "info",
"log_file_path": "/var/log/calico/cni/cni.log",
"datastore_type": "kubernetes",
"nodename": "k8s-m",
"mtu": 0,
"ipam": {
"type": "calico-ipam" // ipam 이 calico ipam을 사용
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "portmap",
"snat": true,
"capabilities": {"portMappings": true}
},
{
"type": "bandwidth",
"capabilities": {"bandwidth": true}
}
]
}
# calicoctl node 정보 확인 : Bird 데몬(BGP)을 통한 BGP 네이버 연결 정보(bgp peer 는 노드의 IP로 연결) - https://projectcalico.docs.tigera.io/reference/calicoctl/node/overview
$ calicoctl node status
Calico process is running.
IPv4 BGP status
+----------------+-------------------+-------+----------+--------------------------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+----------------+-------------------+-------+----------+--------------------------------+
| 192.168.20.100 | node-to-node mesh | start | 15:01:48 | Passive BGP Error: Hold timer |
| | | | | expired |
| 192.168.10.101 | node-to-node mesh | up | 14:49:09 | Established |
| 192.168.10.102 | node-to-node mesh | up | 15:16:18 | Established |
+----------------+-------------------+-------+----------+--------------------------------+
IPv6 BGP status
No IPv6 peers found.
# ippool 정보 확인
$ calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv4-ippool 172.16.0.0/16 true Always Never false false all()
# 파드와 서비스 사용 네트워크 대역 정보 확인
$ kubectl cluster-info dump | grep -m 2 -E "cluster-cidr|service-cluster-ip-range"
"--service-cluster-ip-range=10.96.0.0/12",
"--cluster-cidr=172.16.0.0/16",
$ kubectl get cm -n kube-system kubeadm-config -oyaml | grep -i subnet
podSubnet: 172.16.0.0/16
serviceSubnet: 10.96.0.0/12
# calico endpoint (파드)의 정보 확인
$ calicoctl get workloadEndpoint -o wide -A
NAMESPACE NAME WORKLOAD NODE NETWORKS INTERFACE PROFILES NATS
kube-system k8s--m-k8s-calico--kube--controllers--76c5bc74--x6zm9-eth0 calico-kube-controllers-76c5bc74-x6zm9 k8s-m 172.16.116.3/32 cali964dde55aa0 kns.kube-system,ksa.kube-system.calico-kube-controllers
kube-system k8s--m-k8s-coredns--78fcd69978--8pdx2-eth0 coredns-78fcd69978-8pdx2 k8s-m 172.16.116.1/32 cali4b946a19c49 kns.kube-system,ksa.kube-system.coredns
kube-system k8s--m-k8s-coredns--78fcd69978--pj5j2-eth0 coredns-78fcd69978-pj5j2 k8s-m 172.16.116.2/32 calib52ae62e057 kns.kube-system,ksa.kube-system.coredns
Calico Mode 요약
IPIP 모드
파드 간 통신이 노드와 노드 구간에서는
IPIP 인캡슐레이션
을 통해서 이루어 집니다
- 다른 노드 간의 파드 통신은 tunl0 인터페이스를 통해 IP 헤더에 감싸져서 상대측 노드로 도달 후 tunl0 인터페이스에서 Outer 헤더를 제거하고 내부의 파드와 통신
- 다른 노드의 파드 대역은 BGP로 전달 받아 호스트 라우팅 테이블에 업데이트됨
- Azure 네트워크에서는 IPIP 통신이 불가능하여 IPIP 모드 대신 VXLAN 모드 사용
실습
# 파드 생성
$ curl -s -O https://raw.githubusercontent.com/gasida/NDKS/main/5/node3-pod3.yaml
$ kubectl apply -f node3-pod3.yaml
# 파드 IP 정보 확인
$ kubectl get pod -o wide
# 파드 Shell 접속(zsh)
$ kubectl exec -it pod1 -- zsh
## 파드 Shell 에서 아래 입력
$ ping <pod2 혹은 pod3 IP>
# 파드가 동작하는 워커노드1의 eth0(예시)에서 IPIP 패킷(proto 4) 덤프
$ tcpdump -i enp0s8 -nn proto 4
# 혹은 아래 처럼 파일로 저장 후 해당 파일을 다운받아서 확인(wireshark 등 사용)
$ tcpdump -i enp0s8 proto 4 -w /tmp/calico-ipip.pcap
# 파드 삭제
$ kubectl delete -f node3-pod3.yaml
Direct 모드
파드 통신 패킷이 출발지 노드의 라우팅 정보를 보고 목적지 노드로
원본 패킷 그대로 전달
합니다.
실습
클라우드 사업자 네트워크의 경우 NIC 에 매칭되지 않는 IP 패킷은 차단되니, NIC에 Source/Destination Check 기능을 Disable 해야 합니다. AWS - 원본/대상 확인 비활성화
# AWS CLI 로 특정 인스턴스의 Source/Destination Check 기능을 Disable 하기
$ aws ec2 modify-instance-attribute --instance-id <INSTANCE_ID> --source-dest-check "{\"Value\": false}"
calico Direct 모드로 변경 처리
# calico 설정
$ calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/ipipMode: Always/ipipMode: Never/" | calicoctl apply -f -
Successfully applied 1 'IPPool' resource(s)
$ calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv4-ippool 172.16.0.0/16 true Never Never false false all()
# BGP 로 전달 받은 파드 네트워크 대역이 호스트 라우팅 테이블에 적용되었는지 확인 : Iface 가 tunl0 에서 enp0s8 로 변경!
$ route -n | egrep '(Destination|UG)'
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.2.2 0.0.0.0 UG 100 0 0 enp0s3
172.16.158.0 192.168.10.101 255.255.255.0 UG 0 0 0 enp0s8
172.16.184.0 192.168.10.102 255.255.255.0 UG 0 0 0 enp0s8
192.168.20.0 192.168.10.254 255.255.255.0 UG 0 0 0 enp0s8
동작 확인
# 파드 생성
$ curl -s -O https://raw.githubusercontent.com/gasida/NDKS/main/5/node3-pod3.yaml
$ kubectl apply -f node3-pod3.yaml
# 파드 IP 정보 확인
$ kubectl get pod -o wide
$ calicoctl get wep
# 파드 Shell 접속(zsh)
$ kubectl exec -it pod1 -- zsh
## 파드 Shell 에서 아래 입력
pod1 $> ping <pod2 혹은 pod3 IP>
# 파드가 동작하는 노드의 eth0(예시)에서 패킷 덤프
$ tcpdump -i enp0s8 -nn icmp
# 혹은 아래 처럼 파일로 저장 후 해당 파일을 다운받아서 확인(wireshark 등 사용)
$ tcpdump -i enp0s8 icmp -w /tmp/calico-direct.pcap
같은 IP 대역의 pod끼리는 통신이 가능하지만, 다른 IP 대역의 POD와는 통신이 불가능합니다. 이는 Overlay 네트워크 기법이 필요한 이유입니다.
CrossSubnet 모드
노드 간 같은 네트워크 대역(Direct 모드로 동작) , 노드 간 다른 네트워크 대역(IPIP 모드로 동작)
# CrossSubnet 모드 설정
$ calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/ipipMode: Never/ipipMode: CrossSubnet/" | calicoctl apply -f -
Successfully applied 1 'IPPool' resource(s)
# 모드 확인
$ 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()
# 파드 생성
$ kubectl apply -f node3-pod3.yaml
$ calicoctl get wep
# 호스트 라우팅 정보 확인
$ route -n | grep UG
100.105.79.128 172.20.61.184 255.255.255.192 UG 0 0 0 ens5 # 노드간 같은 네트워크 대역 - Direct 모드
100.125.78.64 172.20.59.153 255.255.255.192 UG 0 0 0 ens5 # 노드간 같은 네트워크 대역 - Direct 모드
100.127.64.128 172.20.64.181 255.255.255.192 UG 0 0 0 tunl0 # 노드간 다른 네트워크 대역 - IPIP 모드
# 파드 Shell 접속(zsh)
$ kubectl exec -it pod1 -- zsh
## 파드 Shell 에서 아래 입력
$ ping <pod2 혹은 pod3 IP>
# 파드 삭제
$ kubectl delete -f node3-pod3.yaml
VXLAN 모드
파드 간 통신이 노드와 노드 구간에서는
VXLAN 인캡슐레이션
을 통해서 이루어 집니다.
- 다른 노드 간의 파드 통신은 vxlan 인터페이스를 통해 L2 프레임이 UDP - VXLAN에 감싸져서 상대측 노드로 도달 후 vxlan 인터페이스에서 Outer 헤더를 제거하고 내부의 파드와 통신
- BGP 미사용, VXLAN L3 라우팅을 통해서 동작
- UDP 사용으로 Azure 네트워크에서도 사용 가능
VXLAN 모드
# VXLAN 설정 적용
$ kubectl apply -f https://raw.githubusercontent.com/gasida/KANS/main/3/calico-vxlan-kans.yaml
# 모드 설정 변경 : VXLAN 모드 사용 시, ipipMode 와 BGP(Bird)는 반드시 Never 비활성화 되어야 합니다
# ipipMode 현재 모드(Always, CrossSubnet)를 확인하고, 해당 모드를 Never 로 변경합니다
$ calicoctl get ippool default-ipv4-ippool -o wide
$ calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/ipipMode: CrossSubnet/ipipMode: Never/" | calicoctl apply -f -
#calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/ipipMode: Always/ipipMode: Never/" | calicoctl apply -f -
$ calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/vxlanMode: Never/vxlanMode: Always/" | calicoctl apply -f -
$ calicoctl get ippool default-ipv4-ippool -o wide
# 변경 설정 적용을 위해서 calico 파드 삭제 후 재생성
$ kubectl delete pod -n kube-system -l k8s-app=calico-node
# 모든 노드에서 enp0s8 down 후 up (라우팅 테이블 갱신을 위함)
$ route -n && echo && ip link set enp0s8 down && sleep 1 && ip link set enp0s8 up && route -n
동작 확인
# 파드 생성
$ kubectl apply -f node3-pod3.yaml
# 파드 Shell 접속(zsh)
$ kubectl exec -it pod1 -- zsh
## 파드 Shell 에서 아래 입력
$ ping <pod2 혹은 pod3 IP>
# 파드가 동작하는 노드의 eth0(예시)에서 패킷 덤프
# tcpdump -i <eth0> -nn udp port 4789
$ tcpdump -i enp0s8 -nn udp port 4789
# 혹은 아래 처럼 파일로 저장 후 해당 파일을 다운받아서 확인(wireshark 등 사용)
# tcpdump -i <eth0> udp port 4789 -w /tmp/calico-vxlan.pcap
$ tcpdump -i enp0s8 udp port 4789 -w /tmp/calico-vxlan.pcap
# (참고) BGP 를 사용하지 않기 때문에, 기존의 BGP 라우터와 네트워크 정보 교환을 하지 못한다. 별도 설정이 없으면 통신 불가!
# 파드 삭제
$ kubectl delete -f node3-pod3.yaml
Pod 패킷 암호화
Calico 의 다양한 네크워크 모드 환경 위에서 WireGuard
터널을 자동 생성
및 파드트래픽을 암호화
하여 노드간 전달
WireGuard 소개
- WireGuard는 구닥다리 IPsec 및 OpenVPN의 대항마로 등장한 open source VPN project 이며 작년, Linux 5.6 커널에 WireGuard 1.0.0 기본 패키지로 탑재되었다.
- 간결한 코드 구조와 빠른 성능
- 모든 것이 kernel에서 동작하고, 주요 암호 알고리즘에 대해서 병렬처리하므로써 빠른 속도를 자랑
- WireGuard는 보시다시피 경쟁자들인 IPsec, SoftEther VPN, OpenVPN 등과 비교할 때, 코드 size(Line of Codes)가 현격하게 작다.
- 코드량이 많지 않아 그만큼 철저히 검증될 가능성이 높고, 예상치 못한 곳에서의 버그로 인한 취약점이 발생할 가능성이 상대적으로 적다
- WireGuard는 Noise Protocol Framework을 기초로하여 상호 인증 및 키 교환(ECDH의 변형된 형태로 보면 됨 - Curve25519 ECC 공개키 암호 알고리즘 사용)이 이루어지고 있으며, ChaCha20(Stream Cipher 알고리즘), Poly1305(무결성 검사 알고리즘), BLAKE2s, SipHash24, HKDF 등 가장 빠르고 최신의 암호 및 해쉬 알고리즘을 사용한다.
- wireguard는 망 변경으로 peer의 ip 주소가 변경되더라도 tunnel이 유지되는 특징이 있다. 이것이 가능한 이유는 index 기반으로 peer hash table이 운용되기 때문이다.
- Receiver index가 message format에 있었다는 사실을 상기해 보라. 이 Receiver index가 index hash table에서 사용되는 index 값이다.
- 사용 예로 달리는 기차 위에서 안정적으로 사내망에 접속하고 싶을 때 : Public key를 기반으로 peer를 인식하기 때문에 LTE 기지국이 바뀌더라도 tunnel이 끊기지 않고 안정적으로 유지
- 참고 링크 : WG VPN 해부 - 링크 & 개발 계획서 - 링크 & 데브시스터즈 WG 로 VPN 서버 구축하기 - 링크1 링크2 & WG 대시보드 - 링크
WireGuard 설정
# 설치
$ apt install wireguard -y
# WireGuard 버전 확인
$ wg version
wireguard-tools v1.0.20200513 - https://git.zx2c4.com/wireguard-tools/
# 설정
$ calicoctl patch felixconfiguration default --type='merge' -p '{"spec":{"wireguardEnabled":true}}'
# 확인
$ calicoctl get felixconfiguration default -o yaml | grep wireguardEnabled
wireguardEnabled: true
calicoctl get node -o yaml | grep wireguardPublicKey
calicoctl get node <노드 Name> -o yaml | grep wireguardPublicKey
root@k8s-m:~/yaml# calicoctl get node k8s-w1 -o yaml | grep wireguardPublicKey
wireguardPublicKey: BToK9bLEhMaPUJsuKy3KdrxVOpklyo0qlGRdMN6lHWc=
# wireguard.cali 인터페이스 확인
$ ip -c -d addr show wireguard.cali
12: wireguard.cali: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default qlen 1000
link/none promiscuity 0 minmtu 0 maxmtu 2147483552
wireguard numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
inet 172.16.228.74/32 scope global wireguard.cali
valid_lft forever preferred_lft forever
$ ifconfig wireguard.cali
wireguard.cali: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1440
inet 172.16.228.69 netmask 255.255.255.255 destination 172.16.228.69
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC)
# wireguard.cali 설정 확인 : 통신 포트, Peer/Endpoint 정보, 패킷 암호화를 위한 공개키/사설키 정보
$ wg showconf wireguard.cali
[Interface]
ListenPort = 51820
FwMark = 0x100000
PrivateKey = AIgTihI2p4icwVMR4sIvuVaSqwKlkxMImQp4A/Gm+Gg=
[Peer]
PublicKey = BToK9bLEhMaPUJsuKy3KdrxVOpklyo0qlGRdMN6lHWc=
AllowedIPs = 172.16.228.64/26, 172.16.228.69/32, 172.16.228.67/32
Endpoint = 192.168.100.101:51820
[Peer]
PublicKey = 9TCD8hG6SLutZSOZSzQeqj6O0icJAxA3RPIipcBKBxs=
AllowedIPs = 172.16.197.0/26, 172.16.197.3/32, 172.16.197.5/32
Endpoint = 192.168.100.103:51820
[Peer]
PublicKey = Ercb/0pNZ+I1ELOkiXlWbZA9J0Fjt7XqsstDH4GhNmI=
AllowedIPs = 172.16.46.3/32, 172.16.46.0/26, 172.16.46.5/32
Endpoint = 192.168.100.102:51820
# Peer 의 정보(고유한 index)
$ wg show
interface: wireguard.cali
public key: 8TNaYyzzc1N4SHfqE+Y5b4rMBKX/lqPe0tWO/h8sOB4=
private key: (hidden)
listening port: 51820
fwmark: 0x100000
peer: 6WtZqEKSmoSKiFp20fhk/jyTcrTqf9qshyZI1HvE9Qk=
endpoint: 192.168.10.102:51820
allowed ips: 172.16.184.0/32, 172.16.184.0/24, 172.16.184.1/32
peer: +fOEOJgFxueIbrp709iB4F4gFRb2ny4lWKbxCNNfczM=
endpoint: 192.168.20.100:51820
allowed ips: 172.16.34.0/32, 172.16.34.0/24, 172.16.34.1/32
peer: d2LgXvRo4DwsyhiLXUn9TEt6D3l4pFIVlCD7KESR/m0=
endpoint: 192.168.10.101:51820
allowed ips: 172.16.158.0/32, 172.16.158.0/24, 172.16.158.1/32
# 키 정보 확인
$ wg show all public-key
wireguard.cali 8TNaYyzzc1N4SHfqE+Y5b4rMBKX/lqPe0tWO/h8sOB4=
$ wg show all private-key
wireguard.cali kJbrfATGFP2v4sl+Wqg1Gv8zwFpIXshYFFD3udMDd3k=
$ wg show all preshared-keys
wireguard.cali 6WtZqEKSmoSKiFp20fhk/jyTcrTqf9qshyZI1HvE9Qk= (none)
wireguard.cali +fOEOJgFxueIbrp709iB4F4gFRb2ny4lWKbxCNNfczM= (none)
wireguard.cali d2LgXvRo4DwsyhiLXUn9TEt6D3l4pFIVlCD7KESR/m0= (none)
# 그외 키타 정보
$ wg show all dump
$ wg show all endpoints
$ wg show all peers
$ wg show all transfer
$ wg show all persistent-keepalive
동작 확인
# 파드 생성
$ kubectl apply -f node3-pod3.yaml
# 파드 Shell 접속(zsh)
$ kubectl exec -it pod1 -- zsh
## 파드 Shell 에서 아래 입력
$ ping <pod2 혹은 pod3 IP>
# 파드가 동작하는 노드의 eth0(예시)에서 패킷 덤프
# tcpdump -i <eth0> -nn udp port 51820
$ tcpdump -i enp0s8 -nn udp port 51820
# 혹은 아래 처럼 파일로 저장 후 해당 파일을 다운받아서 확인(wireshark 등 사용)
# tcpdump -i <eth0> udp port 51820 -w /tmp/calico-wireguard.pcap
$ tcpdump -i enp0s8 udp port 51820 -w /tmp/calico-wireguard.pcap
# 현재 모든 워커 노드에 tcpdump 후 ping curl 테스트 시 모든 노드에서 트래픽이 발생한다 >> 이유는 VirtualBox 에 nic2 에 "무작위 모드 : 모두 허용" 상태여서, 모든 노드로 패킷이 전달됨
# VirtualBox 에 nic2 에 "무작위 모드 : 거부"로 설정 후 테스트 하게 되면 정확하게, 출발지와 목적지의 VM에서만 패킷이 확인된다!
# 모드워커노드)
$ tcpdump -i enp0s8 -nn udp port 51820
# 파드 삭제
$ kubectl delete -f node3-pod3.yaml
3주를 마치며
이번 스터디를 따라가며, 가장 큰 문제는 내 노트북이 테스트 환경을 시작하기 위해서 1시간이 걸리고 잦은 오류가 발생해서 실습을 따라하기 너무 어려웠습니다. 작년에 산 노트북인데, 다시 구매해야하나 잠시 고민까지 되네요.
내용이 어렵지만 구성과 동작을 이해에 집중하였습니다.
참고자료
- Calico Docs - Install / requirements / Configure Networking / Release notes / Network Policy / Visualizing Grafana
- Calico Docs (IPAM) - IPAM / another / Change IP size / Restrict ip range
- Calico Docs (Design)- Calico over Ethernet Fabrics & Calico over IP fabrics / BGP peering
- Calico - Youtube Github
- [심화] Calico 무료 교육(tigera) - Calico Operator Level 1 - 링크
- [심화] Tracing the path of network traffic in Kubernetes - 링크