안녕하세요. 저는 클라우드 및 애자일·협업 전문 기업 오픈소스컨설팅의 이건웅이라고 합니다. 우리 회사는 클라우드, 데브옵스(DevOps), 컨테이너 아키텍처 등 인프라 관련 최신 기술 전문성을 보유, 이를 토대로 오픈스택 및 쿠버네티스 커뮤니티 오픈소스 패키지인 ‘플레이스 클라우드(Playce Cloud)’를 개발 및 공급하고 있습니다.
우리 팀은 지속적으로 CNCF의 공개 버전을 이용하여 크고 작은 사이트들에 설계, 구축 및 유지보수 업무를 진행 하고 있는데요. 이때 생기는 알찬 노하우를 공유하고자 합니다. 많은 분들이 오픈소스를 쉽게 접할 수는 있지만 실제 환경에 적용해서 사용하기에는 많은 시행 착오와 경험이 필요한데요. 누군가가 구현 가능하고 바로 사용 가능한 아키텍처를 보여준다면 너무 좋겠죠. 그래서 준비 했습니다.
구현 가능하고 적절한 사용이 가능한 Kubernetes 구축과 운영 포인트를 저와 같이 확인해 주시면 감사하겠습니다.
목표
Kubernetes를 사용함에 있어, 관리하게 되는 Kube-APIServer, Kube-Controller, Kube-Scheduler, etcd, kubelet, kube-proxy, CNI, CSI, nginx-ingress, service, Pod, Object 등의 상당히 많은 요소들을 알고, 학습해야 할 필요가 있습니다.
Kubernetes를 일반 개발자, 혹은 사업관리자들은 Container Orchstration으로 자동 배포, 자동 수평확장, 자동 복구가 되는 시스템으로만 알고 있지만 이러한 것들은 아무런 댓가 없이 이루어지지는 않습니다.
Kubernetes를 잘 이해하는 엔지니어가 사용방법과 운영방법을 어드바이스하고 지속적인 확인과 점검을 할 필요가 있지요.
그러기 위해서 엔지니어들은 Kubernetes의 요소들을 잘 숙지하고, 365일 24시간 주 7일의 안정적인 운영에 최선의 노력을 경주해야 겠지요. 그렇다면, 문제없는 관리를 위해 Kubernetes의 구성요소들을 살펴보겠습니다.
Playce Kube에서 제공하는 CNI(Calico)의 구성 형태와 확인 방법을 통해 Pod 간 통신을 확인하고, Pod 네트워크를 이해 할 수 있도록 하겠습니다.
CNI 란?
Kubernetes의 CNI는 여러 프로젝트가 진행되고 있지만, 프로젝트의 확장과 사용이 용이한 Calico를 Playce Kube에서는 사용하고 있습니다. 그럼 CNI(Container Network Interface)란 무엇인지 알아야 하는데요, CNI는 컨테이너간의 네트워크를 제어할 수 있는 플러그인을 뜻합니다.
요약하자면, 물리 환경의 네트워크를 기반으로 하여, Container Runtime에서 Container간의 네트워크를 사용하게 도와주는 인터페이스 입니다.
CNI는 여러 플러그인들이 존재 하며, 주로 Container의 네트워크 연결과 Container삭제에 따른 리소스제거가 주요 기능으로 뚜렷하고 확실한 목표가 있어, 광범위한 지원을 제공하고 요구사항을 구현하기가 간단합니다. 우리가 알고있는 네트워크를 생각한다면, L2인지 L3인지 그리고 TCP/UDP를 지원하고 Inbound/Outbound를 제어해주는 것으로 보면 되겠습니다.
Calico 란?
Calico CNI Architecture
Calico는 다양한 환경에서 운영이 가능하지만, Playce Kube에서 제공되는 Kubernetes의 환경을 중점으로 보겠습니다. Calico는 다양한 환경에서 운영이 가능한 만큼 다양한 설정이 준비되어 있습니다. Kubernetes와 관련을 뽑자면 네트워크 플러그인, 서비스, 로드벨런싱 그리고 네트워킹 등에서 자세히 지정하고 사용하게 되어있습니다.
당연히 Calico는 Kubernetes가 요구하는 네트워크 정책을 완벽히 지원한다고 합니다. 그렇다면 우리는 Calico만 잘 이해하면, Playce Kube의 네트워크 환경을 잘 이해 할 수 있겠네요.
위의 구조도는 Calico 홈페이지에서 설명하는 Architecture지만, 상세 설명이나 정확히 어떻게 움직이는지는 보이지 않네요. 물론 Calico를 이미 통달하신 분은 이 한장의 구조도를 보고 ‘충분하다’라고 생각할 수 있을 것입니다. 그러나 단번에 알아보기는 쉽지 않아보입니다.
각 Node별로 네트워크에 필요한 프로그램들과 호스트별로 Pod구성을 칼리코가 관리 하면서, Calico는 Control-Plane Node와 통신하며 작동 하는 것으로 보입니다.
구성된 Calico를 Playce kube의 Control-Plane에서 좀더 상세하게 확인 해보도록 하겠습니다.
Calico 구성 정보 확인
Playce Kube에서 구축된 내역을 확인해 보겠습니다. Control-Plane의 1, 2, 3 어디에서도 확인이 가능합니다. (Worker에서는 확인이 되지 않습니다.)
### Calico CNI 정보 확인
# calicoctl version
Client Version: v3.20.3
Git commit: dcb4b76a
Cluster Version: v3.20.3
Cluster Type: kubespray,bgp,kubeadm,kdd,k8s
### Node 상태 확인
# calicoctl node status
Calico process is running.
IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+-------------------+-------+----------+-------------+
| 10.0.0.22 | node-to-node mesh | up | 14:28:46 | Established |
| 10.0.0.23 | node-to-node mesh | up | 14:30:06 | Established |
| 10.0.0.31 | node-to-node mesh | up | 14:30:45 | Established |
| 10.0.0.32 | node-to-node mesh | up | 14:28:54 | Established |
+--------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
### ip pool 정보 확인
# 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()
### calico 설정 Yaml 형태로 확인
# calicoctl get ippool default-pool -o yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
creationTimestamp: "2023-05-10T15:12:42Z"
name: default-pool
resourceVersion: "1162"
uid: c84e11a9-3621-4880-8d66-f8e988ea255b
spec:
blockSize: 24
cidr: 10.233.64.0/18
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
### 생성된 파드에 대한 위치, 정보 확인
# calicoctl get workloadEndpoint
WORKLOAD NODE NETWORKS INTERFACE
nginx-deployment-84cd76b964-jnt76 playcekube-worker02 10.233.106.12/32 cali382bc0c1cbe
nginx-volume-deployment-69c9474d89-dbgm4 playcekube-worker02 10.233.106.14/32 calif31b03684db
nginx-volume-deployment-69c9474d89-hh48q playcekube-worker01 10.233.99.10/32 cali146ae769172
nginx-volume-deployment-69c9474d89-jjxfr playcekube-worker01 10.233.99.9/32 cali6d8b6ed7fbf
nginx-volume-deployment-69c9474d89-mlwgc playcekube-worker02 10.233.106.13/32 cali37dd35672f6
nginx-volume-deployment-69c9474d89-v6zdm playcekube-worker01 10.233.99.11/32 cali7d09eb87bd4
Calico의 버전부터 Node의 상태, 그리고 할당 가능한 Pod IP Address의 범위 등등 Calico는 간단한 명령어를 통해 확인이 가능한 것이 생각보다 많습니다.
확인한 내역들은 위에서부터 간단하게 설명하자면, Version은 항상 호환성을 위해서라도 확인하는 것이 좋습니다. OpenSource들은 최신 버전의 생성과 생명주기가 제품별로 다를 수 있기때문에 항상 확인하는 습관이 있어야 하겠습니다. 설치된 Calico는 3.20.3 버전이네요.
노드 스테이터스는 총 4개의 PEER ADDRESS가 보이는데 검색을 한 서버는 보이지 않는것 같습니다. 특이한 점이네요.
그리고 BGP를 사용하고, IP Pool 은 10.233.64.0의 18비트 (subnet 255.255.192.0, 16384 hosts)를 사용하고 있습니다. ( Kubernetes 기본 설정 )
IP Pool의 설정을 yaml 형태로 본다면 더 정확히 보입니다. default-pool 이라는 이름으로 10.233.64/18과 ipipMode항목이 Always라고 명시되어 있네요. IP in IP 모드는 Pod간의 통신을 IP Address 기반의 터널링 방식으로 사용 한다는 것이고, 터널링을 사용하게 될 경우에는 Pod 네트워크 패킷의 기존 IP헤더 앞에 IP헤더를 하나 더 붙여서 통신하게 됩니다. 즉 MTU(Maximum Transmission Unit) 1500byte를 다 사용하지 못한다는 것이죠. 이 부분은 뒤에서 더 보도록 하겠습니다.
그럼 정보를 더 보도록 하겠습니다.
Calico Pod 정보 확인
### Calico Pod 정보
# kubectl -n kube-system get all | grep calico
pod/calico-kube-controllers-b8d4d8984-82xn7 1/1 Running 79 (30m ago) 46d
pod/calico-node-8qf8n 1/1 Running 1 (30m ago) 46d
pod/calico-node-92vqx 1/1 Running 1 (31m ago) 46d
pod/calico-node-l42l9 1/1 Running 1 (32m ago) 46d
pod/calico-node-sn89s 1/1 Running 1 (29m ago) 46d
pod/calico-node-zx9z6 1/1 Running 1 (31m ago) 46d
daemonset.apps/calico-node 5 5 5 5 5 kubernetes.io/os=linux 46d
deployment.apps/calico-kube-controllers 1/1 1 1 46d
replicaset.apps/calico-kube-controllers-b8d4d8984 1 1 1 46d
## Calico Node의 Pod(calico-node-8qf8n) 상세 정보
# kubectl -n kube-system describe pod calico-node-8qf8n
ame: calico-node-8qf8n
Namespace: kube-system
Priority: 2000001000
Priority Class Name: system-node-critical
Node: playcekube-master03/10.0.0.13
Start Time: Thu, 11 May 2023 00:13:00 +0900
Labels: controller-revision-hash=96f798dc5
k8s-app=calico-node
pod-template-generation=1
Annotations: <none>
Status: Running
IP: 10.0.0.13
IPs:
IP: 10.0.0.13
Controlled By: DaemonSet/calico-node
Init Containers:
upgrade-ipam:
Container ID: containerd://697ee3795ce25ea231d6e942a21f872ff8448493931f78ba4b04cd3d3ffbccec
Image: registry.local.cloud:5000/calico/cni:v3.20.3
Image ID: sha256:e9a8982d9e894ca1030928298cee1d8064f6e082e174e99fe359b728de5e92a9
Port: <none>
Host Port: <none>
Command:
/opt/cni/bin/calico-ipam
-upgrade
State: Terminated
Reason: Completed
Exit Code: 0
Started: Mon, 26 Jun 2023 23:29:35 +0900
Finished: Mon, 26 Jun 2023 23:29:37 +0900
Ready: True
Restart Count: 1
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-twqbd (ro)
install-cni:
Container ID: containerd://9c154e8b8a742a8dd826fa9e480f317b79c2e6408e1857884cd5dff0efb903bf
Image: registry.local.cloud:5000/calico/cni:v3.20.3
Image ID: sha256:e9a8982d9e894ca1030928298cee1d8064f6e082e174e99fe359b728de5e92a9
Port: <none>
Host Port: <none>
Command:
/opt/cni/bin/install
State: Terminated
Reason: Completed
Exit Code: 0
Started: Mon, 26 Jun 2023 23:29:45 +0900
Finished: Mon, 26 Jun 2023 23:29:52 +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-twqbd (ro)
flexvol-driver:
Container ID: containerd://da7937ee27926d01e7ec9b198711a05926c87f5f50d7504016713cd88bfc1b72
Image: registry.local.cloud:5000/calico/pod2daemon-flexvol:v3.20.3
Image ID: sha256:0631af1a04ae8074a3a0ceb5aeec688f19aa71627c9118b60391dd1158e37eb9
Port: <none>
Host Port: <none>
State: Terminated
Reason: Completed
Exit Code: 0
Started: Mon, 26 Jun 2023 23:29:54 +0900
Finished: Mon, 26 Jun 2023 23:29:54 +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-twqbd (ro)
Containers:
calico-node:
Container ID: containerd://1ab8efb046edf5e10247a9daf394e2a9ec5f536e7309abf947ebc94338ceae36
Image: registry.local.cloud:5000/calico/node:v3.20.3
Image ID: sha256:6570786a0fd3b9950d85ee3b26046fa07930eb4599023603b9e33809f0d51f43
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 26 Jun 2023 23:29:55 +0900
Last State: Terminated
Reason: Unknown
Exit Code: 255
Started: Thu, 11 May 2023 00:13:25 +0900
Finished: Mon, 26 Jun 2023 23:29:08 +0900
Ready: True
Restart Count: 1
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-twqbd (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-twqbd:
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 Controller의 Pod(calico-kube-controllers-b8d4d8984-82xn7) 상세 정보
# kubectl -n kube-system describe pod calico-kube-controllers-b8d4d8984-82xn7
Name: calico-kube-controllers-b8d4d8984-82xn7
Namespace: kube-system
Priority: 2000000000
Priority Class Name: system-cluster-critical
Node: playcekube-worker02/10.0.0.21
Start Time: Thu, 11 May 2023 00:14:04 +0900
Labels: k8s-app=calico-kube-controllers
pod-template-hash=b8d4d8984
Annotations: <none>
Status: Running
IP: 10.0.0.21
IPs:
IP: 10.0.0.21
Controlled By: ReplicaSet/calico-kube-controllers-b8d4d8984
Containers:
calico-kube-controllers:
Container ID: containerd://e76406836d05657e20361e436984100ab18a9c4707c44f0f21150be77a3518d3
Image: registry.local.cloud:5000/calico/kube-controllers:v3.20.3
Image ID: sha256:fcd3512f2a7c5b023f9e6997545b9b0d71504e574fc77e2146524ad5b96a4204
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 26 Jun 2023 23:28:44 +0900
Last State: Terminated
Reason: Error
Exit Code: 1
Started: Mon, 26 Jun 2023 23:28:24 +0900
Finished: Mon, 26 Jun 2023 23:28:28 +0900
Ready: True
Restart Count: 79
Limits:
cpu: 1
memory: 256M
Requests:
cpu: 30m
memory: 64M
Liveness: exec [/usr/bin/check-status -l] delay=10s timeout=1s period=10s #success=1 #failure=6
Readiness: exec [/usr/bin/check-status -r] delay=0s timeout=1s period=10s #success=1 #failure=3
Environment:
ENABLED_CONTROLLERS: node
DATASTORE_TYPE: kubernetes
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-lf7sd (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-lf7sd:
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: node-role.kubernetes.io/control-plane:NoSchedule
node-role.kubernetes.io/master:NoSchedule
node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
이번에는 Pod의 정보입니다. 생각보다 많은 정보가 있어서 놀랄 수 있는데요. 우리가 간단히 사용 할 수 있게 되어 있다고 해도 역시 내부에서는 많은 정보를 갖고, 많은 작용이 이루어 지고 있는것으로 보입니다. 한줄씩 다 보면 좋겠지만 상당한 시간이 필요해 보이네요. 이중 중요해 보이는 부분만 집고 넘어가겠습니다.
Calico는 크게 1개의 Deployment와 이를 통해 생성되는 Replicaset이 있고 Replicaset은 calico-kube-controllers를 생성하고, 1개의 Daemonset은 모든 Node에 calico-node를 생성하고 있습니다. 두 파드 모두 성능부분이 지정되어 있고, Liveness와 Readiness가 있어 라이프사이클이 관리 됨을 알 수 있습니다.
Controller의 경우 특별한 설정이 보이지 않지만 실제로 일하게 되는 calico-node는 상당히 긴 정보가 표시되는데요. 이중에 enviroment와 mount를 보면 설정과 옵션들이 있습니다.
mount는 주로 로그와 실행파일 그리고 lock등의 경로에 관련이 있어 보입니다. 그럼 Environment를 보겠습니다. 이 중에서 큰 이름들을 본다면, Felix, Calico등이 있네요. 크게 두가지의 설정들을 지정한 것 같습니다. Calico는 글로벌한 설정으로 보이고, Felix는 상세 값을 가진 설정으로 보입니다. 아마 실제 Calico안에서 직접적으로 작동을 하는것으로 보입니다.
아직은 정확한 설정을 알 수 없네요. Pod별 설정이므로 실제 설정들을 확인해 보겠습니다.
Calico 설정 정보 확인
### Config Map 확인
# kubectl get cm -n kube-system | grep cali
calico-config 2 47d
# kubectl get cm -n kube-system calico-config -o yaml
apiVersion: v1
data:
calico_backend: bird
cluster_type: kubespray,bgp
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"calico_backend":"bird","cluster_type":"kubespray,bgp"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"calico-config","namespace":"kube-system"}}
creationTimestamp: "2023-05-10T15:12:55Z"
name: calico-config
namespace: kube-system
resourceVersion: "1210"
uid: 4b685c6f-08d7-4a00-881c-a2c15262524b
# 노드 설정 파일 확인
# pwd
/etc/kubernetes
# ls -alhtr cali*
-rw-r--r-- 1 root root 151 May 11 00:12 calico-config.yml
-rw-r--r-- 1 root root 11K May 11 00:12 calico-node.yml
-rw-r--r-- 1 root root 95 May 11 00:12 calico-node-sa.yml
-rw-r--r-- 1 root root 3.4K May 11 00:12 calico-cr.yml
-rw-r--r-- 1 root root 265 May 11 00:12 calico-crb.yml
-rw-r--r-- 1 root root 1.6K May 11 00:13 calico-kube-controllers.yml
-rw-r--r-- 1 root root 107 May 11 00:13 calico-kube-sa.yml
-rw-r--r-- 1 root root 1.6K May 11 00:13 calico-kube-cr.yml
-rw-r--r-- 1 root root 301 May 11 00:14 calico-kube-crb.yml
# cat calico-config.yml
kind: ConfigMap
apiVersion: v1
metadata:
name: calico-config
namespace: kube-system
data:
cluster_type: "kubespray,bgp"
calico_backend: "bird"
# cat calico-node.yml
---
# This manifest installs the calico/node container, as well
# as the Calico CNI plugins and network config on
# each master and worker node in a Kubernetes cluster.
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: calico-node
namespace: kube-system
labels:
k8s-app: calico-node
spec:
selector:
matchLabels:
k8s-app: calico-node
template:
metadata:
labels:
k8s-app: calico-node
annotations:
spec:
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-node-critical
hostNetwork: true
serviceAccountName: calico-node
tolerations:
- operator: Exists
# Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force
# deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods.
terminationGracePeriodSeconds: 0
initContainers:
# This container performs upgrade from host-local IPAM to calico-ipam.
# It can be deleted if this is a fresh installation, or if you have already
# upgraded to use calico-ipam.
- name: upgrade-ipam
image: registry.local.cloud:5000/calico/cni:v3.20.3
command: ["/opt/cni/bin/calico-ipam", "-upgrade"]
envFrom:
- configMapRef:
# Allow KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT to be overridden for eBPF mode.
name: kubernetes-services-endpoint
optional: true
env:
- name: KUBERNETES_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: CALICO_NETWORKING_BACKEND
valueFrom:
configMapKeyRef:
name: calico-config
key: calico_backend
volumeMounts:
- mountPath: /var/lib/cni/networks
name: host-local-net-dir
- mountPath: /host/opt/cni/bin
name: cni-bin-dir
securityContext:
privileged: true
# This container installs the Calico CNI binaries
# and CNI network config file on each node.
- name: install-cni
image: registry.local.cloud:5000/calico/cni:v3.20.3
command: ["/opt/cni/bin/install"]
envFrom:
- configMapRef:
# Allow KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT to be overridden for eBPF mode.
name: kubernetes-services-endpoint
optional: true
env:
# Name of the CNI config file to create.
- name: CNI_CONF_NAME
value: "10-calico.conflist"
# Install CNI binaries
- name: UPDATE_CNI_BINARIES
value: "true"
# The CNI network config to install on each node.
- name: CNI_NETWORK_CONFIG_FILE
value: "/host/etc/cni/net.d/calico.conflist.template"
# Prevents the container from sleeping forever.
- name: SLEEP
value: "false"
# Set the hostname based on the k8s node name.
- name: KUBERNETES_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- mountPath: /host/etc/cni/net.d
name: cni-net-dir
- mountPath: /host/opt/cni/bin
name: cni-bin-dir
securityContext:
privileged: true
# Adds a Flex Volume Driver that creates a per-pod Unix Domain Socket to allow Dikastes
# to communicate with Felix over the Policy Sync API.
- name: flexvol-driver
image: registry.local.cloud:5000/calico/pod2daemon-flexvol:v3.20.3
volumeMounts:
- name: flexvol-driver-host
mountPath: /host/driver
securityContext:
privileged: true
containers:
# Runs calico/node container on each Kubernetes node. This
# container programs network policy and routes on each
# host.
- name: calico-node
image: registry.local.cloud:5000/calico/node:v3.20.3
envFrom:
- configMapRef:
# Allow KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT to be overridden for eBPF mode.
name: kubernetes-services-endpoint
optional: true
env:
# The location of the Calico etcd cluster.
# Use Kubernetes API as the backing datastore.
- name: DATASTORE_TYPE
value: "kubernetes"
# Wait for the datastore.
- name: WAIT_FOR_DATASTORE
value: "true"
# Choose the backend to use.
- name: CALICO_NETWORKING_BACKEND
valueFrom:
configMapKeyRef:
name: calico-config
key: calico_backend
# Cluster type to identify the deployment type
- name: CLUSTER_TYPE
valueFrom:
configMapKeyRef:
name: calico-config
key: cluster_type
# Set noderef for node controller.
- name: CALICO_K8S_NODE_REF
valueFrom:
fieldRef:
fieldPath: spec.nodeName
# Disable file logging so `kubectl logs` works.
- name: CALICO_DISABLE_FILE_LOGGING
value: "true"
# Set Felix endpoint to host default action to ACCEPT.
- name: FELIX_DEFAULTENDPOINTTOHOSTACTION
value: "RETURN"
- name: FELIX_HEALTHHOST
value: "localhost"
- name: FELIX_IPTABLESBACKEND
value: "Legacy"
- name: FELIX_IPTABLESLOCKTIMEOUTSECS
value: "10"
# should be set in etcd before deployment
# # Configure the IP Pool from which Pod IPs will be chosen.
# - name: CALICO_IPV4POOL_CIDR
# value: "10.233.64.0/18"
- name: CALICO_IPV4POOL_IPIP
value: "Off"
- name: FELIX_IPV6SUPPORT
value: "False"
# Set Felix logging to "info"
- name: FELIX_LOGSEVERITYSCREEN
value: "info"
# Set Calico startup logging to "error"
- name: CALICO_STARTUP_LOGLEVEL
value: "error"
# Enable or disable usage report
- name: FELIX_USAGEREPORTINGENABLED
value: "False"
# Set MTU for tunnel device used if ipip is enabled
- name: FELIX_CHAININSERTMODE
value: "Insert"
- name: FELIX_PROMETHEUSMETRICSENABLED
value: "False"
- name: FELIX_PROMETHEUSMETRICSPORT
value: "9091"
- name: FELIX_PROMETHEUSGOMETRICSENABLED
value: "True"
- name: FELIX_PROMETHEUSPROCESSMETRICSENABLED
value: "True"
- name: NODEIP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: IP_AUTODETECTION_METHOD
value: "can-reach=$(NODEIP)"
- name: IP
value: "autodetect"
- name: NODENAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: FELIX_HEALTHENABLED
value: "true"
- name: FELIX_IGNORELOOSERPF
value: "False"
- name: CALICO_MANAGE_CNI
value: "true"
securityContext:
privileged: true
resources:
limits:
cpu: 300m
memory: 500M
requests:
cpu: 150m
memory: 64M
livenessProbe:
exec:
command:
- /bin/calico-node
- -felix-live
- -bird-live
periodSeconds: 10
initialDelaySeconds: 10
timeoutSeconds: 10
failureThreshold: 6
readinessProbe:
exec:
command:
- /bin/calico-node
- -bird-ready
- -felix-ready
periodSeconds: 10
timeoutSeconds: 10
failureThreshold: 6
volumeMounts:
- mountPath: /lib/modules
name: lib-modules
readOnly: true
- mountPath: /var/run/calico
name: var-run-calico
readOnly: false
- mountPath: /var/lib/calico
name: var-lib-calico
readOnly: false
- name: xtables-lock
mountPath: /run/xtables.lock
readOnly: false
# For maintaining CNI plugin API credentials.
- mountPath: /host/etc/cni/net.d
name: cni-net-dir
readOnly: false
- name: policysync
mountPath: /var/run/nodeagent
- name: cni-log-dir
mountPath: /var/log/calico/cni
readOnly: true
volumes:
# Used by calico/node.
- name: lib-modules
hostPath:
path: /lib/modules
- name: var-run-calico
hostPath:
path: /var/run/calico
- name: var-lib-calico
hostPath:
path: /var/lib/calico
# Used to install CNI.
- name: cni-net-dir
hostPath:
path: /etc/cni/net.d
- name: cni-bin-dir
hostPath:
path: /opt/cni/bin
# Mount the global iptables lock file, used by calico/node
- name: xtables-lock
hostPath:
path: /run/xtables.lock
type: FileOrCreate
# Mount in the directory for host-local IPAM allocations. This is
# used when upgrading from host-local to calico-ipam, and can be removed
# if not using the upgrade-ipam init container.
- name: host-local-net-dir
hostPath:
path: /var/lib/cni/networks
# Used to access CNI logs.
- name: cni-log-dir
hostPath:
path: /var/log/calico/cni
# Used to create per-pod Unix Domain Sockets
- name: policysync
hostPath:
type: DirectoryOrCreate
path: /var/run/nodeagent
# Used to install Flex Volume Driver
- name: flexvol-driver-host
hostPath:
type: DirectoryOrCreate
path: "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/nodeagent~uds"
updateStrategy:
rollingUpdate:
maxUnavailable: 20%
type: RollingUpdate
# cat calico-kube-controllers.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: calico-kube-controllers
namespace: kube-system
labels:
k8s-app: calico-kube-controllers
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
k8s-app: calico-kube-controllers
template:
metadata:
name: calico-kube-controllers
namespace: kube-system
labels:
k8s-app: calico-kube-controllers
spec:
nodeSelector:
kubernetes.io/os: linux
hostNetwork: true
serviceAccountName: calico-kube-controllers
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
priorityClassName: system-cluster-critical
containers:
- name: calico-kube-controllers
image: registry.local.cloud:5000/calico/kube-controllers:v3.20.3
imagePullPolicy: IfNotPresent
resources:
limits:
cpu: 1000m
memory: 256M
requests:
cpu: 30m
memory: 64M
livenessProbe:
exec:
command:
- /usr/bin/check-status
- -l
periodSeconds: 10
initialDelaySeconds: 10
failureThreshold: 6
readinessProbe:
exec:
command:
- /usr/bin/check-status
- -r
periodSeconds: 10
env:
- name: ENABLED_CONTROLLERS
value: node
- name: DATASTORE_TYPE
value: kubernetes
## cni 설정 정보 확인
# ls -al /etc/cni/net.d
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
# cat 10-calico.conflist
{
"name": "cni0",
"cniVersion":"0.3.1",
"plugins":[
{
"datastore_type": "kubernetes",
"nodename": "playcekube-worker01",
"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
}
}
]
}
Control-Plane Node의 /etc/kubernetes 의 경로에 있는 파일들을 확인해보면, calico-config의 config map 내용과 calico-config.yml 이 같고, calico-node 파드와 calico-node.yml 이 같으며, calico-kube-controllers 파드와 calico-kube-controllers.yml이 같다는 것을 알 수 있습니다. yaml 파일들을 이용해 calico가 구성 되는 것으로 보이는군요.
나머지 calico-cr.yml, calico-crb.yml, calico-kube-cr.yml, calico-kube-crb.yml 는 Calico에서 사용되는 ClusterRole과 ClusterRoleBinding 입니다. calico-kube-sa.yml, calico-node-sa.yml는 ServiceAccount입니다. Calico 에서 사용하는 모든 설정파일이 Control-plane의 /etc/kubernetes의 경로에 다 있네요.
Node에서 확인 가능한 다른 경로로는 /etc/cni 의 경로가 있는데요. 여기는 Container Runtime이 구성될때 사용하게 되는 calico 설정이라고 보시면 됩니다. 인증서와 Template가 있고, 이를 이용해 10-calico.conflist 를 작성하여 사용하게 됩니다.
Calico 운영 정보 확인
### ipam 에 할당된 IP Address 정보 확인
# calicoctl ipam show --show-blocks
+----------+-----------------+-----------+------------+--------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+-----------------+-----------+------------+--------------+
| IP Pool | 10.233.64.0/18 | 16384 | 25 (0%) | 16359 (100%) |
| Block | 10.233.106.0/24 | 256 | 9 (4%) | 247 (96%) |
| Block | 10.233.113.0/24 | 256 | 2 (1%) | 254 (99%) |
| Block | 10.233.77.0/24 | 256 | 2 (1%) | 254 (99%) |
| Block | 10.233.88.0/24 | 256 | 3 (1%) | 253 (99%) |
| Block | 10.233.99.0/24 | 256 | 9 (4%) | 247 (96%) |
+----------+-----------------+-----------+------------+--------------+
설정 등을 확인하고, Calico가 IP Address를 정상적으로 사용중 인지 확인하기 위해서는 ipam 정보를 확인 해보면 되겠습니다. 10.233.64.0/18 에서 각 노드별로 자동 할당된 24bit(subnet 255.255.255.0, 256 hosts)의 네트워크와 IP Address의 사용량을 확인 할 수 있습니다.
한 노드당 24bit를 사용할 수 있다면, kube-system에서 사용하거나, Service등의 여유를 제외한다면, 150에서 200개의 IP Address를 Pod에서 사용 할 수 있게 됩니다. (kubelet에 설정되어있는 기본 Pod수는 110개)
Log는 ‘/var/log/calico/cni’의 경로와 ‘/var/log/pods/kube-system_calico-node*’ 의 경로에 cni로그와 calico-node, flexvol-driver, install-cni, upgrade-ipam의 로그가 적제되고 있습니다. 로그의 종류가 상당히 다양합니다.
왜 이렇게 많은 로그의 종류가 있을까요. 우선 Control-plane과 Calico-node 크게 두 부분으로 나뉘게 될거고, Calico-node의 image를 보게 된다면, cni, pod2daemon-flexvol, node 가 생성됩니다. 여기에 ipam에 대한 로그가 생성됩니다.
Calico는 봐야할 정보가 정말 많은 것 같습니다. 설정은 간단하지만 작용이 매우 복잡하기 때문이겠죠. 그렇다면 container에서 기동 된 이후에 어떻게 작동 하는지 확인해 보겠습니다.
Calico Node 정보 확인
### Felix 확인
# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.233.0.1:443 rr
-> 10.222.0.84:6443 Masq 1 2 0
-> 10.222.0.158:6443 Masq 1 0 0
-> 10.222.0.165:6443 Masq 1 2 0
TCP 10.233.0.3:53 rr
-> 10.233.88.4:53 Masq 1 0 0
-> 10.233.113.2:53 Masq 1 0 0
TCP 10.233.0.3:9153 rr
-> 10.233.88.4:9153 Masq 1 0 0
-> 10.233.113.2:9153 Masq 1 0 0
TCP 10.233.2.41:80 rr
-> 10.233.99.12:80 Masq 1 0 0
-> 10.233.106.23:80 Masq 1 0 0
TCP 10.233.2.41:443 rr
-> 10.233.99.12:444 Masq 1 0 0
-> 10.233.106.23:444 Masq 1 0 0
TCP 10.233.6.194:443 rr
-> 10.233.99.15:10250 Masq 1 0 0
TCP 10.233.8.79:6379 rr
-> 10.233.99.13:6379 Masq 1 0 0
-> 10.233.106.16:6379 Masq 1 0 0
-> 10.233.106.17:6379 Masq 1 0 0
TCP 10.233.9.197:80 rr
-> 10.233.106.21:3000 Masq 1 0 0
TCP 10.233.17.208:80 rr
-> 10.233.106.20:4180 Masq 1 0 0
TCP 10.233.17.208:44180 rr
-> 10.233.106.20:44180 Masq 1 0 0
TCP 10.233.18.86:9090 rr
-> 10.233.106.22:9090 Masq 1 0 0
TCP 10.233.22.239:443 rr
-> 10.233.77.2:4443 Masq 1 2 0
TCP 10.233.25.169:80 rr
-> 10.233.99.18:8080 Masq 1 0 0
TCP 10.233.25.169:443 rr
-> 10.233.99.18:8443 Masq 1 0 0
TCP 10.233.31.233:9100 rr
-> 10.222.0.15:9100 Masq 1 0 0
-> 10.222.0.84:9100 Masq 1 0 0
-> 10.222.0.123:9100 Masq 1 0 0
-> 10.222.0.158:9100 Masq 1 0 0
-> 10.222.0.165:9100 Masq 1 0 0
TCP 10.233.37.77:6379 rr
-> 10.233.106.18:6379 Masq 1 0 0
TCP 10.233.48.81:5432 rr
-> 10.233.99.14:5432 Masq 1 0 0
TCP 10.233.55.99:8080 rr
-> 10.233.99.17:8080 Masq 1 0 0
TCP 10.233.60.245:9093 rr
-> 10.233.99.16:9093 Masq 1 0 0
TCP 10.233.63.123:443 rr
-> 10.233.99.19:8443 Masq 1 0 0
-> 10.233.106.19:8443 Masq 1 0 0
UDP 10.233.0.3:53 rr
-> 10.233.88.4:53 Masq 1 0 0
-> 10.233.113.2:53 Masq 1 0 0
# ip r
default via 10.0.0.1 dev ens4 proto dhcp src 10.0.0.11 metric 100
default via 10.1.1.254 dev ens3 proto dhcp src 10.1.1.11 metric 100
10.0.0.0/16 dev ens4 proto kernel scope link src 10.0.0.11 metric 100
10.0.0.1 dev ens4 proto dhcp scope link src 10.0.0.11 metric 100
10.0.0.10 dev ens4 proto dhcp scope link src 10.0.0.11 metric 100
blackhole 10.233.77.0/24 proto bird
10.233.77.2 dev calie347534bfe4 scope link
10.233.88.0/24 via 10.0.0.12 dev tunl0 proto bird onlink
10.233.99.0/24 via 10.0.0.21 dev tunl0 proto bird onlink
10.233.106.0/24 via 10.0.0.22 dev tunl0 proto bird onlink
10.233.113.0/24 via 10.0.0.12 dev tunl0 proto bird onlink
169.254.169.254 via 10.0.0.10 dev ens4 proto dhcp src 10.0.0.11 metric 100
169.254.169.254 via 10.1.1.110 dev ens3 proto dhcp src 10.1.1.11 metric 100
10.1.1.0/16 dev ens3 proto kernel scope link src 10.1.1.11 metric 100
10.1.1.1 dev ens3 proto dhcp scope link src 10.1.1.11 metric 100
10.1.1.10 dev ens3 proto dhcp scope link src 10.1.1.11 metric 100
10.1.1.110 dev ens3 proto dhcp scope link src 10.1.1.11 metric 100
# ip -c route | grep bird
blackhole 10.233.77.0/24 proto bird
10.233.88.0/24 via 10.0.0.13 dev tunl0 proto bird onlink
10.233.99.0/24 via 10.0.0.21 dev tunl0 proto bird onlink
10.233.106.0/24 via 10.0.0.22 dev tunl0 proto bird onlink
10.233.113.0/24 via 10.0.0.12 dev tunl0 proto bird onlink
# ip -c route | grep cali
10.233.99.12 dev cali529aed0cdfd scope link
10.233.99.13 dev calia1a4ce1fd14 scope link
10.233.99.14 dev cali0bf64d8a013 scope link
10.233.99.15 dev cali1b77e6bb67a scope link
10.233.99.16 dev cali7c21de47b2f scope link
10.233.99.17 dev calie8b6d9446c8 scope link
10.233.99.18 dev cali8442edcb221 scope link
10.233.99.19 dev cali7029cbd2dfb scope link
10.233.99.20 dev cali6b516219e5f scope link
10.233.99.21 dev cali3a199d39f75 scope link
10.233.99.22 dev cali39d0067cf12 scope link
## calico interface 확인
# calicoctl get workloadendpoints -a | grep cali529aed0cdfd
cattle-system cattle-cluster-agent-679697c475-9l4p6 playcekube-worker01 10.233.99.12/32 cali529aed0cdfd
## calico interface 네트워크 확인
# tcpdump -i cali529aed0cdfd -nn
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on cali529aed0cdfd, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:20:59.286266 IP 10.233.0.1.443 > 10.233.99.12.36640: Flags [P.], seq 2348022798:2348023587, ack 3076275329, win 9683, options [nop,nop,TS val 2811409034 ecr 611887874], length 789
15:20:59.286300 IP 10.233.99.12.36640 > 10.233.0.1.443: Flags [.], ack 789, win 10245, options [nop,nop,TS val 611888182 ecr 2811409034], length 0
15:20:59.286350 IP 10.233.0.1.443 > 10.233.99.12.36640: Flags [P.], seq 789:1352, ack 1, win 9683, options [nop,nop,TS val 2811409034 ecr 611887874], length 563
15:20:59.286378 IP 10.233.99.12.36640 > 10.233.0.1.443: Flags [.], ack 1352, win 10241, options [nop,nop,TS val 611888182 ecr 2811409034], length 0
:
:
확인 부분이 조금 길어지네요. bird는 BGP를 생성하여 Routing Table을 생성하고 있습니다.
Felix는 모든 노드의 endpoint 와 etcd의 정보를 읽고 쓰고, iptables/ipvsadm 등을 컨트롤합니다.
confd는 etcd에 bird의 구성을 업데이트 하거나 변경을 감시합니다.
ipvsadm으로는 Service를 통해서 Pod까지의 경로를 알 수 있습니다. ip route로는 현재 노드에서 타 노드로 가는 라우팅과 현재 노드에서 구성되어 있는 Pod의 endpoint IP Address를 알 수 있습니다.
현재 노드에 할당된 내부 IP Address 대역은 ip -c route | grep bird 로 확인이 가능합니다. calico가 연동되는 calico interface 를 확인 하려면 p -c route | grep calico 로 확인이 가능합니다.
이때 보이는 dev 이름 cali* 를 이용해서 Pod를 확인하려면 calicoctl get workloadendpoints -a | grep cali* 로 확인이 가능합니다. 그리고 tcpdump -i cali* 를 이용한다면 Pod의 네트워크 사용량을 확인 할 수 있습니다. Pod가 있는 서버에서 확인한다면, 네트워크상의 이상 유무를 바로 알 수 있겠습니다.
해당 정보는 모든 Node가 동일하게 구성됩니다. 만약 1개의 Node가 구성이 다르다면, Calico구성 혹은 Node의 네트워크에 단절이 생긴 것으로 판단해도 되겠습니다.
Calico Architecture
Calico를 최초의 아키텍처에서 우리가 확인한 정보들을 확인하면서 본다면 아래의 그림처럼 구성됩니다.
component | Describe |
Felix | calico-node 파드 안에 위치하며, 모든 노드의 endpoint 제공 K8s ETCD 정보를 읽음 라우팅 테이블 생성 kube-proxy가 iptables 모드인 경우, iptables 컨트롤 kube-proxy가 ipvs 모드인 경우, ipvs 컨트롤 |
Bird | 다른 노드에 있는 BGP 데몬들과 라우팅 정보 교환. TCP 179를 이용해서 mesh 형태로 연결 |
Confd | Calico 데이터 저장소의 구성 변경을 감시하고 BIRD의 구성 파일을 업데이트하는 데몬 |
결론
Playce Kube의 구축시 생성되는 CNI(calico network)를 확인 하는 방법과 서비스 흐름을 찾는 방법을 알아보았습니다.
Kubernetes 에서 구축되는 Pod 네트워크는 상당히 중요합니다. 각 Node에 산발되어 있는 모든 Pod를 각 Node에 할당된 24bit 내의 가상 네트워크를 모든 서버에 등록해야 하고, 라우팅을 해야 합니다.
여기에 각 Pod의 생성과 제거에 따른 IP Address의 관리, 그리고 생성된 Pod에 외부에서 오는 서비스 흐름을 생성해 추가로 라우팅을 해줘야하는 매우 복잡한 형태 입니다.
단순한 서버 네트워크로는 운영하기에 너무나도 어려운 부분으로 보입니다만, Playce Kube에서 사용하는 Calico Network는 구축과 구성을 운영자의 부담없이 운영될 수 있게 구축 되어있습니다.
하지만 가상네트워크를 다루는 만큼 실제 운영 구조는 복잡하게 되어있죠. Kubernetes의 구성에 중요하지 않은 부분은 없겠지만, 어느 일정 이상의 서비스를 운영하게 된다면 네트워크 상태를 알지 못하면 낭패를 당할 수 있습니다.
Node에서 Pod를 찾아가거나 서비스를 추적하면서 많이 연습하고 구조를 OSI 7 Layer에 맞추어 생각한다면 조금더 친근한 Interface가 될 것 같습니다.
Kubernetes란 무엇인가를 시작으로, 고객의 니즈와 서비스 형태를 바탕으로 완성한 쿠버네티스 시스템을 분석하여 블로깅 하고 있습니다.
우리 모두 오픈소스컨설팅의 미션 처럼 기술을 나누고, 모두 함께 성장했으면 좋겠습니다.