쿠버네티스는 만져보는 시간이 길어질 수록 점점 공부할 것이 많아집니다.
항상 정리하고 싶었지만 그동안 업무에서 다뤄보지 않았다는 이유로 공부를 미루고 있었습니다.
그러다가 최근 이직 후 데브옵스 엔지니어로써 업무를 시작하는 과정에서 쿠버네티스를 제대로 이해해보려고 합니다.
경험이 부족한 엔지니어가 머리를 굴려가며 쿠버네티스를 이해해보는 시리즈라고 편하게 봐주셨으면 좋겠습니다.
그래서 전반적으로 이해하려고 노력했던 사고 흔적들을 말로 풀어서 적어볼까합니다.
포스팅 맨 밑에는 참고했던 링크를 적어둡니다. (제대로된 글을 보시려면 해당 링크들을 먼저보시는 걸 권고드립니다)
노드 네트워크
우선 노드라는 것을 단순하게 호스트(=물리서버) 한대 라고 가정하고 접근하겠습니다.
AWS나 Azure와 같은 퍼블릭 클라우드에서 호스트(=인스턴스)를 생성해보셨다면
호스트에는 하나의 사설IP 가 할당되는 것을 알 수 있습니다.
여기서는 172.20.10.54 IP를 할당받았다고 해보겠습니다.
호스트의 네트워크를 확인해보면 ens3이라는 인터페이스에 해당 IP가 할당된 것을 확인 가능합니다.
해당 인터페이스는 노드의 물리 인터페이스로 아래와 같은 구조로 볼 수 있습니다.
ens3는 172.20.10.0/24 네트워크에 속하는 IP (172.20.10.54)를 가지고 있고
route -n 으로 확인해보면 172.20.10.1 게이트웨이를 통해 외부 통신이 가능한 것을 확인할 수 있습니다.
노드의 네트워크를 확인했으니 이제 파드 네트워크를 확인해보겠습니다.
파드 네트워크
쿠버네티스에서 여러 과정을 거쳐 파드를 생성하고 나면 아래와 같은 과정이 진행됩니다.
1. 퍼즈 컨테이너는 네트워크 네임스페이스를 통해 파드를 격리
2. CNI는 파드의 eth0 인터페이스를 생성 파드와 네트워크 연결을 위해 veth 쌍을 생성
3. CNI는 브릿지-veth-eth0 연결과 파드의 네트워크를 설정
4. CNI는 iptables와 네트워크 정책을 설정
퍼즈컨테이너? CNI? 용어를 알기 전에 우선 파드 자원격리가 어떻게 진행되는지 이해해야합니다.
네트워크 네임스페이스
네임스페이스는 전체 리소스로 부터 개별 프로세스를 격리해주는 기술입니다.
mount, IPC, PID, UTS 등의 다양한 네임스페이스가 컨테이너 격리 기술에서 사용됩니다.
우리는 네트워크를 이해중이므로 네트워크 네임스페이스를 실습을 통해 이해해보겠습니다.
(실습은 하단 커피고래님의 패킷의 삶 포스팅을 참고하였습니다)
리눅스에서 제공하는 ip 기능을 통해 네트워크 네임스페이스를 생성합니다.
ip netns add pod
네트워크 네임스페이스(pod) 를 bridge에 연결하기 위해 bridge를 생성합니다.
ip link add bridge-pod type bridge
bidge와 pod 네티워크 네임스페이스 연결을 위해 veth 쌍페어를 생성합니다.
veth는 양끝단을 연결하는 케이블로 이해하시면 좋습니다.
ip link add pod-veth type veth peer name pod-veth-br
생성한 veth를 네임스페이스와 bridge에 연결합니다.
ip link set pod-veth netns pod
ip link set pod-veth-br master bridge-pod
이제 인터페이스들을 기동해줍니다
ip link set bridge-pod up
ip link set pod-veth-br up
### netns pod 내 veth 활성화
ip netns exec pod ip link set pod-veth up
### netns pod 내 ip 할당
ip netns exec pod ip addr add 172.30.1.11/24 dev pod-veth
### bridge 임의 ip 할당
ip addr add 172.30.1.5/24 dev bridge-pod
이제 pod 네트워크 네임스페이스 에서 bridge ip (172.30.1.5)로 ping 이 전달되는지 확인해봅니다.
네임스페이스에서 브릿지로 정상적으로 ping 전달되는 것을 확인할 수 있습니다.
현재 이러한 구조로 볼 수 있겠습니다.
pod 라는 이름으로 생성된 네트워크 네임스페이스가 호스트 내 생성된 브릿지와 연결되어 있고
pod-veth 라는 가상 네트워크 인터페이스가 연결을 담당합니다.
pod 네트워크 네임스페이스는 호스트의 ens3 인터페이스까지 통신할 수 있을까요?
언뜻봐서는 가능할 거 같습니다. 한번 테스트해보겠습니다.
Network is unreachable이 발생하면서 통신이 실패합니다.
네트워크 네임스페이스 내부 route 테이블을 확인해봅니다.
route 테이블을 보니 172.30.1.0/24 대역으로 나가는 통신에 대해서만 경로가 잡혀있습니다.
default 라우팅 정보를 입력합니다.
ip netns exec pod ip route add default via 172.30.1.1
이제 default 경로에 대한 통신도 브릿지를 향하게 되었습니다.
다시 시도해보겠습니다.
ip netns exec pod ping 172.20.10.54
정상적으로 통신이 되는 것이 확인됩니다.
그렇다면 외부 8.8.8.8 통신도 가능할까요?
ip netns exec pod ping 8.8.8.8
통신이 되지않습니다. 이유가 뭘까요?
여기서 iptables 개념이 등장합니다.
172.30.1.5/24 대역은 내부 사설 IP 대역입니다. 해당 IP는 공인망 (인터넷) 으로 나가려면 패킷은 NAT 변환이 필요합니다.
iptables에 정책을 추가하면서 NAT 변환을 할 수 있습니다.
172.30.1.0/24 대역을 NAT하여 ens3 인터페이스에서 변환되는 정책을 추가합니다.
iptables -t nat -A POSTROUTING -s 172.30.1.0/24 -o ens3 -j MASQUERADE
외부 통신이 가능한 것을 확인할 수 있었습니다.
iptables는 리눅스 커널 단에서 동작하면서 네트워크 패킷의 필터링, NAT 및 방화벽 등의 패킷 조작을 담당합니다.
여러 CNI 플러그인에서 iptables 를 활용하여 파드 간 통신에서 패킷을 제어합니다.
(네트워크 패킷제어를 iptables 대신 eBFP 를 사용하는 CNI plugin, cilium도 있습니다)
시간이 꽤 걸렸지만 네트워크 네임스페이스를 간단하게 생성해보았고
veth 쌍페어로 bridge 와 연결하여 브릿지, 호스트, 외부 까지의 통신을 테스트 해보았습니다.
또한 iptables를 통해 내부 네트워크를 외부로 전달하는 NAT 정책도 추가해보았습니다.
CNI plugin은 위와 비슷한 방식으로 동작합니다.
loopback, eth0 인터페이스를 만들고 IP를 컨테이너에게 할당하는 작업을 담당합니다.
CNI
Container Network Interface
즉 CNI는 리눅스 컨테이너의 네트워크 인터페이스를 설정을 돕는 명세와 라이브러리로 구성됩니다.
앞으로 몇가지 CNI를 살펴보고 테스트해보겠습니다.
파드 네트워크에서는 CNI가 위에서 직접 수행했던
컨테이너 네트워크 네임스페이스에 네트워크 인터페이스(eth0) 을 삽입,
veth 페어를 호스트의 bridge에 연결,
네트워크 인터페이스에 IP 할당, 라우팅 정보 설정 등의 역할을 수행합니다.
pause 컨테이너
1. 퍼즈 컨테이너는 네트워크 네임스페이스를 통해 파드를 격리
여기서 그러면 퍼즈 컨테이너는 무엇일까요?
퍼즈 컨테이너는 인스라스트럭처 컨테이너로 불리며,
퍼즈 컨테이너는 파드의 모든 컨테이너를 함께 담고 있는 컨테이너로
파드가 생성될 때 네트워크 네임스페이스를 생성하고, 파드를 격리하는 역할을 담당합니다.
즉, 퍼즈 컨테이너가 먼저 기동되어 파드의 격리를 담당하고,
이때 CNI가 등장해서 노드와 파드 간의 네트워크 구성을 진행하게 됩니다.
노드 내 파드 간 통신
노드 내 파드 간 통신은 아래와 같습니다.
각 파드 내 네트워크 네임스페이스는 veth 쌍페어를 통해 브릿지와 연결되며, 동일한 네트워크 대역을 할당받습니다.
bridge는 가상 스위치와 같은 역할을 하므로 10.1.1.1의 파드는 브릿지를 통해
같은 네트워크 대역인 10.1.1.2 파드와 통신할 수 있게 됩니다.
정리
1. 퍼즈 컨테이너는 네트워크 네임스페이스를 통해 파드를 격리
2. CNI는 파드의 eth0 인터페이스를 생성 파드와 네트워크 연결을 위해 veth 쌍을 생성
3. CNI는 브릿지-veth-eth0 연결과 파드의 네트워크를 설정
4. CNI는 iptables와 네트워크 정책을 설정
참고자료
https://coffeewhale.com/packet-network1
[번역]쿠버네티스 패킷의 삶 - #1
쿠버네티스 네트워킹은 언제나 맘 한구석의 숙제 같은 녀석입니다. 제대로 공부해야지 하면서도 그 방대한 양과 내용에 쉽게 시작하질 못합니다. 이번 번역 포스트는 예전 글, 쿠버네티스 네트
coffeewhale.com
[Container] Container Network Interface (CNI) 간단 정리
CNI(Container Network Interface)는 Linux 컨테이너에서 네트워크 인터페이스를 구성하는데 사용되는 플러그인을 작성하기 위한 사양 및 라이브러리로 구성된다.
velog.io
+ 쿠버네티스 인 액션
매일 업데이트하는 식으로 포스팅합니다.
'tech > k8s' 카테고리의 다른 글
쿠버네티스 이해해보기 [kube-proxy] (0) | 2025.03.27 |
---|---|
[쿠버네티스 인 액션] 파드 메타데이터와 그 외 리소스 접근하기 (0) | 2025.03.27 |
쿠버네티스 이해해보기 [CNI와 containerd] (0) | 2025.03.25 |