2주차 [3] - Flannel CNI
k8s 에서 정의하는 CNI란 무엇인지 이해한다.
Flannel CNI 동작과 통신흐름을 이해한다.
1. CNI 네트워크 모델 요구사항

1.1 네트워크 모델 요구사항 4가지
쿠버네티스 네트워크 모델은 4가지 요구사항이 있습니다.
pod와 pod간 통신시 NAT 없이 통신한다.
Kubelet 은 pod와 통신이 가능하다.
호스트 네트워크를 사용하는 pod 는 NAT 없이 POD와 통신한다.
서비스 클러스터 IP 대역과 POD가 사용하는 IP 대역은 중복되지 않아야한다.
1.2 네트워크 동작 4가지

파드내 컨테이너는 루프백을 통한 통신을 할 수 있어야한다.
파드간 통신을 할 수 있어야한다.
클러스터 내부에서 서비스를 통한 통신을 할 수 있어야한다.
클러스터 외부에서 서비스를 통한 통신을 할 수 있어야한다.
1.3 노드의 파드들간 통신을 위한 VXLAN 네트워크 환경
VXLAN
네트워크 오버레이 기술을 구현해주는 방법
논리적인 가상의 네트워크 환경을 만들어준다.
터널링 기법으로, 파드의 패킷을 감싸서 노드에서 빠져나가고, 목적지 노드에 도착해서 패킷에 감싸진 부분을 제거하고 목적지 파드에 전달하게 됩니다.
이 제거하는 부분을 VTEP이라고 하고, FLANNEL 1 네트워크 인터페이스가 해당 역할을 합니다.
UDP 8472 포트를 사용합니다.

파드의 eth0 네트워크 인터페이스는 호스트 네트워크 네임스페이스의 vethY 인터페이스와 페어로 연결된다.
vethY 인터페이스는 cniO 네트워크 브릿지로 연결 된다.
동일 노드 내에서 파드들간 통신은 cni0 네트워크 브리지를 통해서 통신이 가능하다.
2. Flannel 이란?
Flannel은 K8S의 CNI로 모든 노드에 flannelld라는 에이전트를 생성합니다.
2.1 kind 와 Flannel 배포
#
cat <<EOF> kind-cni.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
labels:
mynode: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
- containerPort: 30001
hostPort: 30001
- containerPort: 30002
hostPort: 30002
kubeadmConfigPatches:
- |
kind: ClusterConfiguration
controllerManager:
extraArgs:
bind-address: 0.0.0.0
etcd:
local:
extraArgs:
listen-metrics-urls: http://0.0.0.0:2381
scheduler:
extraArgs:
bind-address: 0.0.0.0
- |
kind: KubeProxyConfiguration
metricsBindAddress: 0.0.0.0
- role: worker
labels:
mynode: worker
- role: worker
labels:
mynode: worker2
networking:
disableDefaultCNI: true
EOF
kind create cluster --config kind-cni.yaml --name myk8s --image kindest/node:v1.30.4
# 배포 확인
kind get nodes --name myk8s
(⎈|kind-myk8s:N/A) root@kind:~# kind get nodes --name myk8s
myk8s-worker2
myk8s-worker
myk8s-control-plane
# 네트워크 확인
kubectl cluster-info dump | grep -m 2 -E "cluster-cidr|service-cluster-ip-range"
(⎈|N/A:N/A) root@kind:~# kubectl cluster-info dump | grep -m 2 -E "cluster-cidr|service-cluster-ip-range"
"--service-cluster-ip-range=10.96.0.0/16",
"--cluster-cidr=10.244.0.0/16",
# flannel 설치 및 namespace 확인
(⎈|kind-myk8s:N/A) root@kind:~# kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
namespace/kube-flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get ns --show-labels
NAME STATUS AGE LABELS
default Active 9m24s kubernetes.io/metadata.name=default
kube-flannel Active 9s k8s-app=flannel,kubernetes.io/metadata.name=kube-flannel,pod-security.kubernetes.io/enforce=privileged
kube-node-lease Active 9m24s kubernetes.io/metadata.name=kube-node-lease
kube-public Active 9m24s kubernetes.io/metadata.name=kube-public
kube-system Active 9m24s kubernetes.io/metadata.name=kube-system
local-path-storage Active 7m16s kubernetes.io/metadata.name=local-path-storage
# kubectl describe pod -n kube-system -l k8s-app=kube-dns
# 브릿지 파일이 없어 오류가 생기고 있는것을 확인 할 수 있습니다!
Warning FailedCreatePodSandBox 25s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "8ac0f67e7c8ac0b705f5f98b5678db797daf95b8c14223144df9c397d1c37df9": plugin type="flannel" failed (add): failed to delegate add: failed to find plugin "bridge" in path [/opt/cni/bin]
Normal SandboxChanged 21s (x12 over 32s) kubelet Pod sandbox changed, it will be killed and re-created.
Warning FailedCreatePodSandBox 20s (x4 over 24s) kubelet (combined from similar events): Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "25498fd6b78c74571f99295f7e4dd378f89e69f253196c51c02eb81f99876faf": plugin type="flannel" failed (add): failed to delegate add: failed to find plugin "bridge" in path [/opt/cni/bin]
(⎈|kind-myk8s:N/A) root@kind:~# kubectl get pod -A -owide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-flannel kube-flannel-ds-8tqt6 1/1 Running 0 3m23s 172.18.0.3 myk8s-control-plane <none> <none>
kube-flannel kube-flannel-ds-9ftxz 1/1 Running 0 3m23s 172.18.0.2 myk8s-worker2 <none> <none>
kube-flannel kube-flannel-ds-lzw85 1/1 Running 0 3m23s 172.18.0.4 myk8s-worker <none> <none>
kube-system coredns-7db6d8ff4d-g8n75 1/1 Running 0 10m 10.244.0.3 myk8s-control-plane <none> <none>
kube-system coredns-7db6d8ff4d-jwnn6 1/1 Running 0 10m 10.244.0.2 myk8s-control-plane <none> <none>
kube-system etcd-myk8s-control-plane 1/1 Running 0 12m 172.18.0.3 myk8s-control-plane <none> <none>
kube-system kube-apiserver-myk8s-control-plane 1/1 Running 0 12m 172.18.0.3 myk8s-control-plane <none> <none>
kube-system kube-controller-manager-myk8s-control-plane 1/1 Running 0 12m 172.18.0.3 myk8s-control-plane <none> <none>
kube-system kube-proxy-744r7 1/1 Running 0 10m 172.18.0.3 myk8s-control-plane <none> <none>
kube-system kube-proxy-cmphm 1/1 Running 0 10m 172.18.0.2 myk8s-worker2 <none> <none>
kube-system kube-proxy-nbdg2 1/1 Running 0 10m 172.18.0.4 myk8s-worker <none> <none>
kube-system kube-scheduler-myk8s-control-plane 1/1 Running 0 12m 172.18.0.3 myk8s-control-plane <none> <none>
local-path-storage local-path-provisioner-7d4d9bdcc5-8zsrx 1/1 Running 0 10m 10.244.0.4 myk8s-control-plane <none> <none>
2.2 통신 흐름 확인하기

동일 노드간 통신을 확인합니다.

통신이 되고있는데, UDP 라서, POD 간 통신은 잡히지 않음

외부 통신을 확인합니다.

다른 노드의 파드에 통신을 확인합니다.
2.3 파드에 어떻게 IP를 할당하게 될까요?

pod 생성
kubelet이 CRI Plugin 에게 pod 생성하라고 요청
CRI Plugin이 pod sandbox 생성 및 pod network namespace 생성한다. 그리고 cni에 요청한다.
CNI Plugin이 네트워크를 구성합니다.
flannel cni
bridge cni plugin
host local IPAM CNI Plugin
IP를 POD에 할당합니다.
Pause 컨테이너를 생성하고 network namspace에 할당합니다.
Kubelet이 CRI에 컨테이너 이미지를 요청합니다.
컨테이너 이미지를 containerd를 이용하여 가져옵니다.
kubelet이 CRI Plugin에게 컨테이너를 시작하라고 요청합니다.
CRI Plugin은 containerd를 사용하여, 파드의 컨테이너의 cgroup과 namespace를 할당하고 시작합니다.
2.4 Flannel 은 모든 파드 위치와 IP 주소를 어떻게 알게 될까요?
각 노드에서 Flannel DL은 ETCD의 IP 주소 할당을 동기화합니다.
ARP 테이블을 각각 ROOT NETNS에서 업데이트해줘서 어느 노드가 어떤 Pod의 IP를 가지고 있는지 알 수 있습니다. -> ARP 테이블의 최대크기를 넘어갈 수 있지 않을까?
Last updated