Ssoon

[3주차] Calico CNI 설치 본문

쿠버네티스 네트워크 스터디 3기

[3주차] Calico CNI 설치

구구달스 2024. 9. 13. 10:50
CloudNet@ 가시다님이 진행하는 쿠버네티스 네트워크 스터디 3기

 CNI 없이 K8S CloudFormation 스택 배포

🧿 CNI (Container Network Interface) 문제:

  • CoreDNS는 클러스터 내의 DNS 서비스로, 네트워크 연결이 필요합니다. CNI 플러그인이 제대로 설치되지 않았거나 설정에 문제가 있을 경우, 네트워크가 구성되지 않아 파드가 Pending 상태가 될 수 있습니다.
  • CNI 플러그인이 올바르게 설치되지 않았으면 네트워크 문제로 인해 파드가 스케줄링되지 않고 Pending 상태로 남을 수 있습니다.
(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl cluster-info
Kubernetes control plane is running at https://192.168.10.10:6443
CoreDNS is running at https://192.168.10.10:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl get node -owide
NAME     STATUS     ROLES           AGE     VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION   CONTAINER-RUNTIME
k8s-m    NotReady   control-plane   6m25s   v1.30.5   192.168.10.10    <none>        Ubuntu 22.04.4 LTS   6.5.0-1024-aws   containerd://1.7.22
k8s-w0   NotReady   <none>          6m7s    v1.30.5   192.168.20.100   <none>        Ubuntu 22.04.4 LTS   6.5.0-1024-aws   containerd://1.7.22
k8s-w1   NotReady   <none>          6m3s    v1.30.5   192.168.10.101   <none>        Ubuntu 22.04.4 LTS   6.5.0-1024-aws   containerd://1.7.22
k8s-w2   NotReady   <none>          6m6s    v1.30.5   192.168.10.102   <none>        Ubuntu 22.04.4 LTS   6.5.0-1024-aws   containerd://1.7.22

(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl get service,ep
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.200.1.1   <none>        443/TCP   6m31s

NAME                   ENDPOINTS            AGE
endpoints/kubernetes   192.168.10.10:6443   6m31s

(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl get pod -A -owide
NAMESPACE     NAME                            READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
kube-system   coredns-55cb58b774-knjds        0/1     Pending   0          6m21s   <none>           <none>   <none>           <none>
kube-system   coredns-55cb58b774-wmbz2        0/1     Pending   0          6m21s   <none>           <none>   <none>           <none>
kube-system   etcd-k8s-m                      1/1     Running   0          6m35s   192.168.10.10    k8s-m    <none>           <none>
kube-system   kube-apiserver-k8s-m            1/1     Running   0          6m36s   192.168.10.10    k8s-m    <none>           <none>
kube-system   kube-controller-manager-k8s-m   1/1     Running   0          6m35s   192.168.10.10    k8s-m    <none>           <none>
kube-system   kube-proxy-658jh                1/1     Running   0          6m19s   192.168.10.102   k8s-w2   <none>           <none>
kube-system   kube-proxy-hcngb                1/1     Running   0          6m20s   192.168.20.100   k8s-w0   <none>           <none>
kube-system   kube-proxy-t8qlb                1/1     Running   0          6m16s   192.168.10.101   k8s-w1   <none>           <none>
kube-system   kube-proxy-vdsgw                1/1     Running   0          6m21s   192.168.10.10    k8s-m    <none>           <none>
kube-system   kube-scheduler-k8s-m            1/1     Running   0          6m35s   192.168.10.10    k8s-m    <none>           <none>

 

  • /etc/cni/net.d/ 디렉토리의 내용을 보면, 네트워크 설정 파일이 전혀 없는 상태입니다. .kubernetes-cni-keep라는 빈 파일만 존재하며, 실제 네트워크 설정에 사용되지 않습니다. 이 디렉토리에는 CNI 플러그인들의 네트워크 설정 파일들이 있어야 합니다. 이 파일이 없다는 것은 네트워크가 올바르게 구성되지 않았다는 의미이며, 이는 노드가 NotReady 상태에 있고 CoreDNS 파드가 Pending 상태로 남아 있는 주요 원인입니다.
(⎈|SsoonLab:N/A) root@k8s-m:/etc/cni/net.d# ls -al
total 8
drwxrwxr-x 2 root root 4096 Sep 13 09:46 .
drwxrwxr-x 3 root root 4096 Sep 13 09:46 ..
-rw-r--r-- 1 root root    0 Jan 11  2024 .kubernetes-cni-keep
  • 로그에 따르면, kubelet이 CNI 플러그인이 초기화되지 않았음을 나타내고 있습니다. 즉, 네트워크 플러그인이 설정되지 않았기 때문에 Kubernetes가 컨테이너의 네트워크를 제대로 구성하지 못하고 있습니다. 이는 모든 노드가 NotReady 상태에 있는 이유이며, CoreDNS 파드가 Pending 상태로 남아 있는 원인입니다.
(⎈|SsoonLab:N/A) root@k8s-m:/etc/cni/net.d# journalctl -u kubelet | grep -i cni
Sep 13 09:49:05 k8s-m kubelet[2773]: E0913 09:49:05.637875    2773 kubelet.go:2920] "Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized"
Sep 13 09:49:10 k8s-m kubelet[2773]: E0913 09:49:10.638909    2773 kubelet.go:2920] "Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized"
Sep 13 09:49:15 k8s-m kubelet[2773]: E0913 09:49:15.640722    2773 kubelet.go:2920] "Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized"
  • default : 이 컴퓨터가 어떤 목적지에 네트워크 패킷을 보내야 하는데, 해당 목적지에 대한 특정 경로가 없다면 패킷을 기본적으로 이 경로(게이트웨이)로 보냅니다.
  • via :192.168.10.1: 패킷을 192.168.10.1로 보내라는 의미입니다
  • dev ens5 : 패킷을 ens5라는 네트워크 인터페이스(이더넷 카드)를 통해 보냅니다. 
  • proto dhcp : DHCP 프로토콜을 통해 자동으로 설정되었습니다.
  • scope link : 같은 네트워크에 있는 장치들로만 트래픽을 보내겠다는 뜻입니다. 라우터를 경유할 필요 없이 직접 통신합니다.
    • 네트워크 패킷을 보내야 할 때 기본적으로 192.168.10.1이라는 게이트웨이를 통해 ens5 네트워크 인터페이스를 사용하여 보냅니다.
    • 192.168.0.2로 가는 네트워크 트래픽은 192.168.10.1을 경유하고, ens5 네트워크 인터페이스를 사용합니다.
    • 192.168.10.0/24 대역의 IP로 가는 모든 트래픽은 라우터를 경유하지 않고, ens5 네트워크 인터페이스를 통해 직접 전송됩니다
    • 192.168.10.1로의 트래픽은 ens5 네트워크 인터페이스를 통해 직접 보내집니다.
(⎈|SsoonLab:N/A) root@k8s-m:~# ip -c route
default via 192.168.10.1 dev ens5 proto dhcp src 192.168.10.10 metric 100
192.168.0.2 via 192.168.10.1 dev ens5 proto dhcp src 192.168.10.10 metric 100
192.168.10.0/24 dev ens5 proto kernel scope link src 192.168.10.10 metric 100
192.168.10.1 dev ens5 proto dhcp scope link src 192.168.10.10 metric 100

(⎈|SsoonLab:N/A) root@k8s-m:~# ip -c addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
    link/ether 02:cf:72:b0:2e:65 brd ff:ff:ff:ff:ff:ff
    altname enp0s5
    inet 192.168.10.10/24 metric 100 brd 192.168.10.255 scope global dynamic ens5
       valid_lft 2328sec preferred_lft 2328sec
    inet6 fe80::cf:72ff:feb0:2e65/64 scope link
       valid_lft forever preferred_lft forever

 

 Calico CNI v3.28.1 설치

(⎈|SsoonLab:N/A) root@k8s-m:~# curl -O https://raw.githubusercontent.com/gasida/KANS/main/kans3/calico-kans.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  248k  100  248k    0     0   295k      0 --:--:-- --:--:-- --:--:--  295k

(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl apply -f calico-kans.yaml
poddisruptionbudget.policy/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
serviceaccount/calico-node created
serviceaccount/calico-cni-plugin created
configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgpfilters.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrole.rbac.authorization.k8s.io/calico-cni-plugin created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-cni-plugin created
daemonset.apps/calico-node created
deployment.apps/calico-kube-controllers created

🧿 추가 설정

  • Calico가 Kubernetes 클러스터에서 네트워크를 관리할 때, IP 주소 풀을 256개의 IP 주소가 들어있는 블록으로 나누겠다는 뜻입니다.
    • 이를 통해 IP 주소가 클러스터의 노드와 Pod에 할당될 때 IPv4 블록 크기 /24로 지정됩니다.
4927             # Block size to use for the IPv4 POOL created at startup. Block size for IPv4 should be in the range 20-32. default 24
4928             - name: CALICO_IPV4POOL_BLOCK_SIZE
4929               value: "24"

 Calico 네트워크 플러그인이 설정한 경로

  • 172.16.34.0/24 via 192.168.20.100 dev tunl0 proto bird onlink
    • 172.16.34.0/24로 가는 트래픽은 192.168.20.100을 통해 보내집니다.
    • tunl0는 터널 인터페이스로, 패킷을 물리적으로 연결되지 않은 다른 네트워크로 전달하는 가상 네트워크 인터페이스입니다.
    • proto bird는 BIRD 라우팅 프로토콜이 경로를 관리한다는 의미입니다.
  • blackhole 172.16.116.0/24 proto bird
    • 블랙홀 라우트는 172.16.116.0/24로 가는 모든 트래픽을 차단하는 역할을 합니다. 이 경로로 보내진 데이터는 더 이상 전송되지 않고 폐기됩니다.
  • 172.16.158.0/24 via 192.168.10.101 dev tunl0 proto bird onlink
    • 172.16.158.0/24로 가는 트래픽은 192.168.10.101을 통해 전달됩니다. tunl0를 통해 라우팅됩니다.
  • 172.16.184.0/24 via 192.168.10.102 dev tunl0 proto bird onlink
    • 172.16.184.0/24로 가는 트래픽은 192.168.10.102를 통해 전달되며,  tunl0 터널 인터페이스를 사용합니다.
(⎈|SsoonLab:N/A) root@k8s-m:~# ip -c route
...
172.16.34.0/24 via 192.168.20.100 dev tunl0 proto bird onlink
blackhole 172.16.116.0/24 proto bird
172.16.158.0/24 via 192.168.10.101 dev tunl0 proto bird onlink
172.16.184.0/24 via 192.168.10.102 dev tunl0 proto bird onlink
...

 

  • @NONE : 인터페이스가 물리적 연결이 없고, 가상 인터페이스임을 나타냅니다.
  • NOARP: ARP (Address Resolution Protocol)를 사용하지 않습니다. 터널 인터페이스는 이를 필요로 하지 않습니다.
  • link/ipip 0.0.0.0 brd 0.0.0.0 : IP-over-IP 터널링을 위해 사용되며, 링크 레벨 주소가 0.0.0.0으로 설정되어 있습니다.
    • link/ipip :
      • **ipip**는 IP-over-IP 터널링을 의미합니다. 이 기술은 IP 패킷을 다른 IP 패킷 안에 캡슐화하여 전송하는 방식입니다. 따라서, link/ipip는 이 인터페이스가 IP 패킷을 IP 패킷으로 터널링하는 역할을 한다는 의미입니다.
    • 0.0.0.0 :
      • 링크 레벨 주소가 0.0.0.0으로 설정되어 있습니다. 이는 실제로는 네트워크 장비의 물리적 MAC 주소나 다른 링크 레벨 식별자가 없다는 것을 의미합니다. 터널링 인터페이스는 물리적인 장비가 아니기 때문에 실제 링크 레벨 주소가 없습니다.
    • brd 0.0.0.0 :
      • 브로드캐스트 주소가 0.0.0.0으로 설정되어 있습니다. 브로드캐스트 주소는 네트워크 내의 모든 장비에 패킷을 전송할 때 사용되는 주소입니다. 0.0.0.0은 브로드캐스트를 지원하지 않음을 의미합니다. IP-over-IP 터널링에서는 브로드캐스트가 필요하지 않기 때문에 이렇게 설정됩니다.
(⎈|SsoonLab:N/A) root@k8s-m:~# ip -c addr
...
3: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 8981 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
    inet 172.16.116.0/32 scope global tunl0
       valid_lft forever preferred_lft forever

 calicoctl 설치

  • calicoctl : Calico를 설정하고 관리하는 데 사용하는 명령줄 도구
(⎈|SsoonLab:N/A) root@k8s-m:~# curl -L https://github.com/projectcalico/calico/releases/download/v3.28.1/calicoctl-linux-amd64 -o calicoctl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 64.4M  100 64.4M    0     0  35.8M      0  0:00:01  0:00:01 --:--:-- 49.2M
(⎈|SsoonLab:N/A) root@k8s-m:~# chmod +x calicoctl && mv calicoctl /usr/bin
(⎈|SsoonLab:N/A) root@k8s-m:~# calicoctl version
Client Version:    v3.28.1
Git commit:        601856343
Cluster Version:   v3.28.1
Cluster Type:      k8s,bgp,kubeadm,kdd
  • calico CNI 설치 후 node 및 pod 정상 확인
(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl get nodes
NAME     STATUS   ROLES           AGE   VERSION
k8s-m    Ready    control-plane   65m   v1.30.5
k8s-w0   Ready    <none>          65m   v1.30.5
k8s-w1   Ready    <none>          65m   v1.30.5
k8s-w2   Ready    <none>          65m   v1.30.5

(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl get pod -A -o wide
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
kube-system   calico-kube-controllers-77d59654f4-7n4v4   1/1     Running   0          23m   172.16.158.2     k8s-w1   <none>           <none>
kube-system   calico-node-9v798                          1/1     Running   0          23m   192.168.20.100   k8s-w0   <none>           <none>
kube-system   calico-node-dqbpn                          1/1     Running   0          23m   192.168.10.102   k8s-w2   <none>           <none>
kube-system   calico-node-h224r                          1/1     Running   0          23m   192.168.10.10    k8s-m    <none>           <none>
kube-system   calico-node-lcpzb                          1/1     Running   0          23m   192.168.10.101   k8s-w1   <none>           <none>
kube-system   coredns-55cb58b774-knjds                   1/1     Running   0          65m   172.16.158.1     k8s-w1   <none>           <none>
kube-system   coredns-55cb58b774-wmbz2                   1/1     Running   0          65m   172.16.158.3     k8s-w1   <none>           <none>
kube-system   etcd-k8s-m                                 1/1     Running   0          65m   192.168.10.10    k8s-m    <none>           <none>
kube-system   kube-apiserver-k8s-m                       1/1     Running   0          65m   192.168.10.10    k8s-m    <none>           <none>
kube-system   kube-controller-manager-k8s-m              1/1     Running   0          65m   192.168.10.10    k8s-m    <none>           <none>
kube-system   kube-proxy-658jh                           1/1     Running   0          65m   192.168.10.102   k8s-w2   <none>           <none>
kube-system   kube-proxy-hcngb                           1/1     Running   0          65m   192.168.20.100   k8s-w0   <none>           <none>
kube-system   kube-proxy-t8qlb                           1/1     Running   0          65m   192.168.10.101   k8s-w1   <none>           <none>
kube-system   kube-proxy-vdsgw                           1/1     Running   0          65m   192.168.10.10    k8s-m    <none>           <none>
kube-system   kube-scheduler-k8s-m                       1/1     Running   0          65m   192.168.10.10    k8s-m    <none>           <none>

 

calico-kube-controllers

Calico의 컨트롤러로, Kubernetes 클러스터의 상태를 모니터링하고 필요한 조치를 수행하는 역할을 합니다.

주요 역할:

  • IPAM (IP Address Management, IP 주소 관리): Kubernetes는 각 Pod에 고유한 IP 주소를 할당합니다. calico-kube-controllers는 이러한 IP 주소를 적절히 관리하고, 중복되지 않게 할당될 수 있도록 돕습니다.
  • Garbage Collection (쓰레기 수집): Kubernetes 리소스(예: Pod, 노드 등)가 삭제되면 그와 관련된 IP 주소나 리소스도 정리해야 합니다. calico-kube-controllers는 이러한 리소스를 자동으로 정리하는 역할을 합니다.
  • 정책 관리: Calico는 네트워크 정책(Network Policy)을 통해 Pod 간의 트래픽을 제어합니다. calico-kube-controllers는 이러한 정책들이 제대로 적용되고 있는지 모니터링하고 관리합니다.

calico-kube-controllers는 클러스터의 네트워크 상태를 관리하고, IP 주소를 할당하거나 정리 작업을 수행하는 관리자 역할을 합니다. Kubernetes 환경에서 Calico의 네트워크 동작을 전반적으로 조정하는 백그라운드 프로세스라고 할 수 있습니다.

 

calico-node

calico-node는 각 Kubernetes 노드에서 실행되는 Calico의 주요 네트워크 컴포넌트입니다. 노드(Node)는 Kubernetes에서 Pod가 실제로 실행되는 서버 또는 가상 머신을 뜻하는데, calico-node는 각 노드에서 실제 네트워크 작업을 수행합니다.

주요 역할:

  • 네트워크 라우팅: calico-node는 Pod들이 서로 통신할 수 있도록 네트워크 경로를 설정합니다. 예를 들어, 하나의 Pod가 다른 노드에 있는 Pod와 통신할 때, 네트워크 경로를 통해 데이터를 안전하게 전달할 수 있게 만듭니다.
  • BGP (Border Gateway Protocol) 사용: Calico는 BGP를 이용하여 클러스터 내에서 네트워크 라우팅을 설정할 수 있습니다. BGP는 인터넷에서 사용하는 프로토콜이지만, Calico는 이를 사용해 클러스터 내부 네트워크 경로도 설정할 수 있습니다.
  • 네트워크 정책 적용: Calico의 강력한 기능 중 하나인 **네트워크 정책(Network Policy)**을 각 노드에서 적용하는 역할을 합니다. 이를 통해, 네트워크 트래픽이 특정 규칙에 맞춰 허용되거나 차단됩니다.
  • IP 주소 관리: 각 노드에서 Pod에 IP 주소를 할당하고, 이 주소가 클러스터 내에서 유효하게 유지되도록 관리합니다.

calico-node는 각 노드에서 실제 네트워크 작업을 처리하는 작업자 역할을 합니다. Pod 간의 통신이 가능하도록 네트워크를 구성하고, 네트워크 트래픽이 규칙에 따라 잘 작동하는지 확인하며, IP 주소 관리도 수행합니다.

 

 

 

 

Comments