본문 바로가기

OS,Network,Container

[Kubernetes] Flannel CNI & PAUSE 컨테이너 알아보기

반응형

- 가시다님 주관 Kubernetes network 스터디를 진행하면서 Vagrant와 VirtualBox를 활용하여 Kubernetes 실습 환경을 구성하고 있으며, Flannel CNI 및 Pause 컨테이너에 대해서 알아보기 위한 실습을 진행하고자 합니다.

 

- 본 글에서는 Kubernetes 기초 개념 및 아키텍처 등에 대한 자세한 설명은 진행하지 않음

 

- 선 요약

 

1. Flannel은 L2 Layer 스위치이며, L3 계층의 가상 스위치를 만든 뒤 VXLAN Encapsulation 이 후 다른 Worker Node들과 브로드캐스팅을 한다.

=> 이로 인해 다른 워커 노드에 있는 Pod 와도 통신이 가능하게 된다.

 

2. Pause 컨테이너는 IPC, Network Namespace를 동일 Pod 내의 Container들과 공유한다.

=> 이로 인해 Application을 구동하고 있는 Container가 갑자기 죽어도 동일한 네트워크 설정값을 유지할 수 있다.


 

Empty 디렉터리에 Vagrantfile 1EA를 생성한 뒤 vagrant up 명령어를 통해 실습 환경을 구성하였다.

1. Vagrant로 실습 환경 구성

vagrant로 배포를 하게 되면 .vagrant 폴더에 내역이 남게 된다.

각 Machine들의 Alias 별로 폴더가 생성되며,

action_provision

action_set_name

box_meta

creator_uid

id

index_uuid

private_key

synced_folders

vagrant_cwd

등의 파일이 생성된다.

 

(배포 중 Timeout 발생으로 k8s-w2가 생성이 진행되지 않았다.)

 

설치 중 직면한 에러

1. Timeout

default: SSH auth method: private key 
    Timed out while waiting for the machine to boot. This means that Vagrant was unable to communicate with the guest machine within the configured ("config.vm.boot_timeout" value) time period.

    If you look above, you should be able to see the error(s) that Vagrant had when attempting to connect to the machine. These errors are usually good hints as to what may be wrong.

    If you're using a custom box, make sure that networking is properly working and you're able to connect to the machine. It is a common problem that networking isn't setup properly in these boxes. Verify that authentication configurations are also setup properly, as well.

    If the box appears to be booting properly, you may want to increase the timeout ("config.vm.boot_timeout") value.

 

=> 구글링을 해보면 여러가지 해결 방안이 나온다. 초기 부팅 시 BIOS Intel 가상화 기능을 활성화하거나 로그에 나와있는 대로 config.vm.boot_timeout 값을 증가시키든가 하는 방안이 나온다.

 

=> Vagrant로 서버를 구성할 때 초기 세팅 시간이 오래 걸리는 것으로 보아 후자가 맞아 보이지만 값을 증가시키지 않고 vagrant.exe up 을 여러번 수행하여 해결하였다.

 

2. vagrant.exe up을 여러번 하다보니, vagrant는 이미 Shell Provisioner를 수행한 줄 알고 있었다.

=> Master Node에 대한 Shell script가 수행이 제대로 되어 있지 않아 직접 서버 내에 들어가서 수행해주었다.

 

 

3. /var/lib/kubelet/config.yaml 파일이 존재하지 않는 에러

=> Worker node에서 /var/log/syslog를 Tail 해본 결과 config 파일이 존재하지 않았음

=> Systemd 데몬은 kubelet 프로세스를 기동시키고 싶지만 kubelet 컨피그 파일이 존재하지 않아 실행을 못 시키는중

 

⇒ kubeadm init이나 join을 한 뒤에 /var/lib/kubelet/config.yaml 파일이 생성되는 것이었다..

 

 

설치 완료된 모습

  1. kube-flannel 파드는 각 Node에 1개씩 배포된 것을 확인할 수 있다. (DaemonSet)
  2. kube-proxy 또한 각 Node에 1개씩 배포된 것을 확인할 수 있다. (DaemonSet)
  3. kube-scheduler, apiserver, controller-manager, etcd 등은 master node에 배치되었다.

 

Dashboard 생성

 

2. Flannel

참고한 블로그 : https://ikcoo.tistory.com/101

 

CNI : Container Network Interface (컨테이너 간 네트워킹을 제어할 수 있는 플러그인을 만들기 위한 표준)

(서로 다른 Node에 있는 Pod 간 통신을 하기 위해서는 관련 기능을 제공하는 CNI가 필요하다.)

종류로는 Flannel, Calico, Cilium, Multus, Weave Net, .. 등이 있다.

 

Flannel 또한 CNI의 종류 중 하나이며, 가볍게 사용할 수 있다는 장점이 있다.

 

1) Flannel 이란?

오버레이 네트워크(Overlay Network)로 L3 네트워크를 구성하는 가장 간단하고 쉬운 방법을 제공한다.

(flanneld : Small, single binary agent // 모든 노드에 flanneld가 동작)

 

2) Flannel이 왜 필요할까?

Worker Node 1과 Worker Node 2의 각각 Pod로 통신할 때 IP가 같을 경우 문제가 발생할 수 있는데,

Flannel CNI를 사용하여 Worker Node 간 Pod의 IP를 동일하지 않게 세팅한 뒤 라우터를 거쳐서 Pod 간 통신이 가능하게 된다.

 

 

각 Node에서 ifconfig 명령어를 쳤을 때 Flannel 관련 인터페이스는 어떤 것들이 나올까?

= > 위의 그림에서 볼 수 있는 것처럼 cni0와 flannel.1이 나온다.

>> Node 마다 flannel.1 생성 : VXLAN VTEP 역할
>> Node 마다 cni0 생성 : bridge 역할

 

3) Flannel 관련 정보

>> 컨피그맵

 

flannel 정보 확인 : 대역

 

각 노드마다 할당된 Subnet (POD CIDR) 확인

 

ip 기본 정보 확인

 

iptables 정보 확인

 

4) 다른 Node 간의 Pod 끼리 통신 테스트 (Flannel CNI를 사용할 시)

 

Pod 2개 생성

 

Pod Shell 접속 후 확인 (Pod-1)

 

Pod-1에서 Pod-2로 Ping을 치게 되면 Packet 흐름이 어떻게 될까?

 

Pod 네트워크는 veth 장치를 통해서 패킷이 나가고 이 트래픽을 cni0라고 하는 Bridge가 받는다.

그리고 Flannel은 이 트래픽을 flannel.1 인터페이스로 보내게 된다.

 

=> Flannel은 L2 Layer 스위치이며, 각 노드당 서브넷 단위로 네트워크를 분리하게 된다. 이 때 동일한 서브넷 내(노드 내)에서는 ARP 라우팅만으로 서로 통신이 가능하지만 호스트가 다를 경우 ARP 라우팅만으로는 찾을 수 없다.

 

=> 이로 인해 Flannel은 L3 Layer 계층의 가상 스위치 장비를 생성하고 이렇게 만들어진 각 호스트의 가상의 스위치를 하나로 연결하는데 이것이 바로 VXLAN 이다. (가상의 스위치를 flannel.1 이라고 생각하면 된다.)

 

=> cni0로부터 전달 받은 데이터는 L2 계층에서 만든 프레임으로 이것을 UDP 패킷 형태로 IP를 붙여서 캡슐화(Encapsulation)한다. 

 

=> flannel.1 NIC는 다른 호스트와 연결된 또 다른 flannel.1 인터페이스로 Broadcasting을 하게 된다.

위에서 봤던 그림을 자세히 보면

 

Container는 Pause 컨테이너에 의해 Network namespace를 공유 받게 되고, 독립적인 eth0 이란 인터페이스를 할당받는다.

 

이는 veth0 (virtual eth0) 인터페이스와 연결되어 있으며, 다른 Node의 Pod와 통신하기 위해 Flannel CNI를 통해 트래픽을 주고 받게 된다.

 

cni0를 거친 뒤 flannel.1을 거친 다음에 ensxx (Node의 물리 인터페이스)를 거치게 될 것이다.

 

3. PAUSE 컨테이너

PAUSE 컨테이너는 왜 존재할까?

 

Pod 내에는 여러 개의 Container가 존재할 수 있다.

⇒ App 컨테이너와 Logging 컨테이너 혹은 App 컨테이너와 Monitoring 컨테이너, ..

동일한 IP를 공유하고, 컨테이너끼리는 Localhost 통신을 하여 Port를 구분하여 통신하게 될 것이다.

 

이럴 때 PAUSE 컨테이너가 Network namespace를 만들어준 뒤, 나머지 컨테이너들은 PAUSE 컨테이너의 Network namespace를 공유받아 동일한 IP를 사용하게 되는 것이다.

1) 사이드카 & PAUSE 컨테이너 실습

파드 배포

 

Worker 노드에 접속한 뒤 docker ps로 확인

 

=> PAUSE 컨테이너, nginx 컨테이너, netshoot 컨테이너 3개가 하나의 파드에 존재하는 것을 확인할 수 있다.

 

파드의 각각 컨테이너 IP가 동일하다.

한 파드 내의 각 컨테이너 네임스페이스 정보를 확인

1) cgroup, user : 별도로 네임스페이스를 격리하지 않는다.
2) ipc, net : 파드 내의 컨테이너 간 네임스페이스를 공유한다.

 

[목적]
>>> PAUSE 컨테이너가 ipc, network 네임스페이스를 생성하고 유지한 뒤에 각 컨테이너끼리 공유할 수 있도록 한다.
>>> 특정 컨테이너가 비정상적으로 종료되어도 PAUSE 컨테이너에 의해 문제가 발생되는 것이 방지된다.

 

Worker 노드에서 Docker 컨테이너를 조회하였을 때 각 컨테이너의 NetworkMode가 PAUSE Container의 Cotaniner ID를 바라보고 있음을 확인할 수 있다.

 

 

 

 

 

 

 

 

Ref : https://linux.systemv.pe.kr/docker-kubernetes-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC/

 

Docker, Kubernetes 네트워크 - Voyager of Linux

쿠버네티스 네트워크에 대해서 간단하게 알아 봅니다. 먼저, Docker 네트워크를 간단하게 알아보고, 쿠버네티스 Flannel 의 네트워크에 대해서 알아 봅니다.

linux.systemv.pe.kr

https://ikcoo.tistory.com/101

 

40. Flannel CNI Networking 분석

Flannel CNI Networking CNI 란? CNI : Container Network Interface 컨테이너 간의 네트워킹을 제어할 수 있는 플러그인을 만들기 위한 표준. Kubernetes Cluster 내부는 Master Node 에 의해 여러 컨테이너가 생..

ikcoo.tistory.com

 

반응형