Kubernetes의 네트워크 CNI
Kubernetes의 CNI는 여러 프로젝트가 진행되고 있지만, 프로젝트의 확장과 사용이 용이한 Calico를 Playce Kube에서는 사용하고 있습니다. 그럼 CNI란 무엇인지 알아야 하는데요, CNI(Container Network Ingerface)는 컨테이너간의 네트워크를 제어할 수 있는 플러그인을 뜻합니다.
요약하자면, 물리 환경의 네트워크를 기반으로 하여, Container Runtime에서 Container간의 네트워크를 사용하게 도와주는 인터페이스 입니다.
CNI는 여러 플러그인들이 존재 하며, 주로 Container의 네트워크 연결과 Container삭제에 따른 리소스제거가 주요 기능으로 뚜렷하고 확실한 목표가 있어, 광범위한 지원을 제공하고 요구사항을 구현하기가 간단합니다. 우리가 알고있는 네트워크를 생각한다면, L2인지 L3인지 그리고 TCP/UDP를 지원하고 Inbound/Outbound를 제어해주는 것으로 보면 되겠습니다.
Calico CNI Architecture
Calico는 Kubernetes의 환경에서 운영되기 때문에 사용에 대한 여러 표준이 준비되어 있습니다. 네트워크 플러그인, 서비스,로드벨런싱 그리고 네트워킹 등에서 자세히 지정하고 사용하게 되어있습니다. 물론 Calico는 Kubernetes의 네트워크 정책을 완벽히 지원한다고 합니다. 그럼 Calico만 잘 알면 Playce Kube의 네트워크 환경을 잘 이해 할 수 있겠네요.
위의 구조도는 Calico 홈페이지에서 제공해주는 Architecture지만, 상세 설명이나 정확히 어떻게 움직이는지는 보이지 않네요. 물론 Calico를 이미 통달하신 분은 이 한장의 구조도를 보고 '충분하다'라고 생각할 수 있겠죠? 제가 보기엔 인터페이스 Archtecture같지만 한번 눈에 익힌다고 생각하고 넘어가겠습니다.
Calico 구성 정보 확인
Playce Kube에서 구축된 내역을 확인해 보겠습니다. Control-Plane의 1, 2, 3 어디에서도 확인이 가능합니다.
### 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
위에서 본 정보로 우리가 확인이 가능한 것이 생각보다 많은데요. Opensource이다 보니 Version은 항상 호환성을 위해서라도 기억해두는 것이 좋습니다. 설치된 Calico는 3.20.3 버전이네요. 노드 스테이터스는 총 4개의 PEER ADDRESS가 보이는데 검색을 한 서버는 보이지 않는것 같습니다. 그리고 BGP를 사하는것으로 보아 IP in IP 모드를 사용하는것으로 보입니다. IP Pool 은 10.233.64.0의 18비트 (subnet 255.255.192.0, 16384 hosts)를 사용하고 있습니다.
IP Pool의 설정을 yaml 형태로 본다면 더 정확히 보입니다. default-pool 이라는 이름으로 10.233.64/18과 ipipMode항목이 Always라고 명시되어 있네요. IP in IP 모드는 Pod간의 통신을 IP Address 기반의 터널링 방식으로사용한다는 것이고, Pod 네트워크 패킷의 기존 IP헤더 앞에 IP헤더를 하나 더 붙여서 통신하게 됩니다. 즉 1500MTU를 다 사용하지 못한다는 것이죠. 이 부분은 뒤에서 더 보도록 하겠습니다.
그럼 정보를 더 보도록 하겠습니다.
### Calico Pod 정보
# kubectl -n kube-system get all | grep cali채
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별 설정이므로 실제 설정들을 확인해 보겠습니다.
### 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
}
}
]
}
/etc/kubernetes 의 경로에 있는 파일들을 본다면, calico-config의 config map 내용과 calico-config.yml 이 같고, calico-node 파드와 calico-node.yml 이 같으며, calico-kube-controllers 파드와 calico-kube-controllers.yml이 같습니다. 그렇다면, 이들 yml 파일들을 이용해 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의 경로에 다 있네요.
다른 경로로 /etc/cni 의 경로가 있는데요. 여기는 Container Runtime이 구성될때 사용하게 되는 calico 설정이라고 보시면 됩니다. 인증서와 Template가 있고, 이를 이용해 10-calico.conflist 를 작성하여 사용하게 됩니다.
### 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)의 사용량을 확인 할 수 있습니다. 한 노드당 24bit를 사용할 수 있다면, System에서 사용 할 수 있는 2, 3개의 IP Address를 빼고, Service등의 여유를 제외한다면, 약 200개 정도의 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 가 생성됩니다. 여기에 ippam에 대한 로그가 생성됩니다.
Calico는 봐야할 정보가 정말 많은 것 같습니다. 설정은 간단하지만 작용이 매우 복잡하기 때문이겠죠. 그렇다면 container에서 기동 된 이후에 어떻게 작동 하는지 확인해 보겠습니다.
### 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가 있는 서버에서 확인한다면, 네트워크상의 이상 유무를 바로 알 수 있겠습니다.
구성된 Calico를 본다면 아래의 그림처럼 구성됩니다.
'kubernetes' 카테고리의 다른 글
Playce Kube - 설치 확인 (0) | 2023.05.13 |
---|---|
Playce Kube - 서버 준비 (0) | 2023.02.21 |
Playce Kube - System Design (0) | 2023.01.14 |
Playce Kube - 설치 (0) | 2023.01.14 |
Playce Kube - 구조 (0) | 2022.08.29 |