Kubernetes Advanced Networking Study(KANS)의 2주차 내용을 학습하며 정리한 내용입니다.
K8S Network 작동 방식
- 쿠버네티스는 CNI 규격을 사용하여 네트워크와 연결한다.
- CNI 플러그인: 쿠버네티스는 별도 오버레이 네트워크를 구축하는 소프트웨어와 사용해야 한다. 쿠버네티스 클러스터는 여러 쿠버네티스 노드로 구성되어 있다. 여러 쿠버네티스 노드는 파드 간 통신을 확보하기 위해 클러스터 내에 분산된 파드가 서로 통신이 가능하도록 네트워크를 구성해야 한다. 이 부분을 담당하는 것이 바로 CNI(Container Network Interface) 플러그인이다.
- CNI의 역할은 단순히 파드 간 연결을 용이하게 만드는 것으로 이해하면 된다. 예를 들어 컨테이너 런타임(예: Docker)은 CNI 플러그인 실행 파일(예: Calico)을 호출하여 컨테이너 네트워킹 Namespace에 인터페이스를 추가하거나 제거한다. 이를 샌드박스 인터페이스라고도 한다.
- 대표 CNI 플러그인인 플라넬은 VXLAN을 사용하여 가상 오버레이 네트워크를 구축한다. 플라넬 외에도 쿠버네티스가 표준으로 지원하는 CNI 플러그인은 Open vSwitch, Calico, Cillium, Weave Net 등이 있다.
- 오버레이 네트워크(Overlay Network): 실제 물리 Network 위에서 가상 Network를 구축하는 기법을 의미한다. 각 가상 Network는 서로 완전히 격리되어 관리 된다.
- VXLAN (Virtual Extensible LAN): Overlay Network 구축을 위한 Network Protocol 중 하나다. 가상 Network안에서 발생한 Packet은 Encapsulation되어 물리 Network를 통과하고 다시 Decapsulation되어 가상 Network로 전달된다.
Flannel
- 코어 OS 주도의 프로젝트이며 쿠버네티스용으로 설계된 3계층 오버레이 네트워크를 구성하기 쉬운 방법이다. 패킷은 VXLAN 및 다양한 메커니즘을 사용하여 전달된다.
Flannel의 필요성
- Kubernetes Default Network 구조 사용시, 아래 그림과 같이 Worker Node가 2개 생생되면 Pod에 부여되는 IP가 동일하여 Worker Node 1의 Pod에서 Work Node 2 Pod로의 통신이 불가하다.
- Flannel 사용시, 아래 그림과 같이 다른 Worker Node간 Pod IP가 동일하지 않으므로 라우터를 거쳐 Pod간 통신이 가능해진다.
- 노드마다 VXLAN VTEP 역할을 하는 flannel.1과 bridge 역할을 하는 cni0이 생성된다.
- 실제 실습 환경 구성시, 기본 네트워크 정보를 확인하면 아래 스크린샷과 같이 flannel.1과 cni0을 확인할 수 있었다.
- flannel.1의 자세한 정보를 확인하면 아래와 같이 vxlan을 사용한다는 것 또한 확인할 수 있었다.
- 전체 노드 정보 중 flannel 관련 정보 확인하면 아래 스크린샷과 같이 각 노드의 Backend-type이 vxlan 사용되는 것을 확인할 수 있었다.
실습 환경 구성
- [아래 이미지 출처: 스터디 멤버 라임님이 제출하신 구성도] 실습 환경 구동되는 Host(PC)포함한 실습 랩 환경
- 워커 노드마다 할당된 dedicated subnet (pod CIDR) 확인
실습 1. 플라넬 CNI는 Pod 생성을 통해 'cni0'이라고 하는 브릿지에 파드에 연결된 veth 페어 인터페이스가 실제로 추가되는지 확인하기
-
현재 cni0가 존재하지 않는 w-1, w-2번 워커 노드에 모니터링 명령어를 걸어두었다.
-
마스터 노드에서 파드 2개를 생성 해보았다.
-
파드가 생성됨과 동시에 cni0에 연결된 veth인터페이스가 각 노드마다 생성되는 것을 확인할 수 있다.
PAUSE
파드 네트워킹 이해하기
- 하나의 파드에 속한 컨테이너들은 아래 그림과 같이 veth0 하나를 공유한다. 그래서 같은 파드에 속한 컨테이너들은 모두 같은 IP를 갖게 되며, 각 컨테이너마다 서로 다른 포트를 사용해야 통신이 가능하다.
- 그렇다면 쿠버네티스는 어떻게 가상 네트워크 인터페이스를 공유할까? 정답은 pause 컨테이너의 존재 때문이다. 파드의 veth0은 pause컨테이너 네트워크 네임스페이스에 속한 장치로써, 같은 파드 안 다른 컨테이너들은 해당 pause 컨테이너 네트워크 네임스페이스를 공유해 사용한다.
- 즉 파드가 실행될 때 pause라는 이름의 컨테이너가 자동으로 먼저 실행되고, 이 pause 컨테이너의 리눅스 네임스페이스를 파드 내부의 모든 컨테이너들이 공유해서 사용한다. 이 컨테이너는 단순히 네임스페이스를 공유하기 위한 컨테이너이며, SIGINT나 SIGTERM 시그널을 받기 전까지 아무 동작도 하지 않고 Sleep 상태로 대기한다.
실습 환경 구성
- 마스터 노드에서 아래 스크린샷과 같이 nginx와 netshoot 컨테이너 2개가 포함된 파드 생성
- 생성된 파드 확인(k8s-w2 노드에 배포되었음)
실습 2. 사용자가 생성한 컨테이너가 pause 컨테이너의 네트워크 네임스페이스를 공유해서 사용하는지 확인하기
- 배포된 워커 노드에서 docker ps로 내용을 확인해보면 내가 yaml 파일에 명시하지 않은 pause 컨테이너가 자동으로 생성된 것이 보인다.
- kubectl describe pod myweb2 명령어를 통해 해당 Pod의 상세 정보를 확인해봐도 두 개의 컨테이너 정보만 확인할 수 있다.
- 해당 Pod의 각 컨테이너 IP를 확인해보면 netshhot, nginx 컨테이너의 IP가 동일하다는 것을 알 수 있다.
- 각 프로세스를 NGINXPID, NETSHPID 변수에 넣고 각 컨테이너의 네임스페이스 정보도 확인해보았다.
- 아래 스크린샷으로 확인할 수 있는 내용은 다음과 같다.
- cgroup, user 네임스페이스는 따로 격리하지 않는다.
- ipc, net 네임스페이스는 파드 내의 컨테이너 간 공유한다.
- mnt, uts, pid 네임스페이스는 컨테이너별로 격리한다.
- pause 컨테이너는 IPC, Network 네임스페이스를 생성하고 유지한다. → 나머지 컨테이너는 해당 네임스페이스를 공유하여 사용한다.
- 유저가 실행한 특정 컨테이너가 비정상적으로 종료되어 컨테이너 전체에서 공유되는 네임스페이스에 문제가 발생하는 것을 방지한다.
참고