kubernetes

Playce Kube - CNI(Calico)

Tech Studio 2023. 6. 26. 23:46

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 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를 본다면 아래의 그림처럼 구성됩니다. 

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