Kubernetes/Architecture

Cluster Networking

Operation CWAL 2021. 1. 22. 22:45

시작하며...

Kubernetes 클러스터를 직접 구축하는 경우, CNI 플러그인 설치를 요구받게 된다. 현재 시장에는 수십개 이상의 CNI 플러그인이 존재하며, 한번 설치하고나면 운영 중 다른 플러그인으로 교체는 결코 쉽지 않은 작업이 되므로 신중하게 선택해야 한다.

각 플러그인마다 수행방식이나 네트워크 모델이 제각각이며 장단점 또한 다르기 때문에 우리의 선택엔 확실한 근거와 기준이 필요하다. 이를 위해 Container와 Container, Container와 Host 사이에 어떻게 네트워크가 구성되는지 알아보도록 하자.

 

우선 Kubernetes의 Network Model은 아래와 같이 단순하지만 확고한 요구사항 3개를 명시해 놓았다.

K8s Network Requirements

  • Pod은 NAT을 사용하지 않고 다른 Node의 모든 Pod과 통신할 수 있다
  • 동일한 Node 내 Agent(ex: kubelet)와 Pod은 통신이 가능하다
  • Host Network를 사용하는 Pod은 NAT을 사용하지 않고 다른 Node의 모든 Pod과 통신할 수 있다
    • Linux에서만 적용된다

Container Networking Model

Kubernetes에서 Pod to Pod Communication을 위해 Network를 구성하는 방식은 여러가지가 있다. 대표적으로 Tunneling(vxlan, ipip)을 통한 Overlay Network와 Routing 프로토콜(BGP)을 사용하는 Non-overlay Network를 예로 들 수 있다.

쉬운 이해를 위해 아래와 같이 4개의 단계로 나누어서 설명하도록 한다.

  1. Single network namespace
  2. Single node, 2 network namespaces
  3. Multiple nodes, same L2 network
  4. Multiple nodes, overlay network

1. Single network namespace

Host와 Container 간 Communication

Host Namespace와 Pod Namespace 사이 veth pair를 통해 연결된 경우이다. Pod에서 발생하는 모든 트래픽은 eth0를 통해 나가도록 Routing Rule이 설정되며, 여기서 다음 2개의 케이스를 생각할 수 있다.

Destination IP가 Host IP(10.0.0.1)인 경우

veth pair를 통해 Host와 Pod 사이에 직접 Communication이 이루어진다. Host는 Pod IP(172.16.0.1)에 대해 veth0로 패킷을 보내도록 Routing Rule이 설정되어있으며, NAT은 개입하지 않는다.

Destination IP가 Host IP가 아닌 경우

Host 외부(다른 Node 또는 Public IP)가 Destination인 경우로, Host는 해당 패킷을 SNAT한 후, enp0s8을 통해 외부로 내보낸다. 상대방으로부터 패킷이 돌아오면 CONNTRACK 기능을 통해 Host IP가 다시 Pod IP로 NAT되며, Routing Rule을 통해 veth0로 전송된다.

 

2. Single Node, 2 Namespaces

동일 Host 상의 Container 간 Communication

Pod A가 Pod B로 패킷을 보내기 위해선 우선 Host Namespace에 위치한 Bridge(172.16.0.1)로 Routing된다. Destination IP가 Pod CIDR(172.16.0.0/24)에 속한 경우, 해당 Pod으로 패킷을 포워딩하며 그 외는 'Single network namespace'에서 설명한 방식과 동작이 동일하다. Docker의 Bridge Network가 이와 같은 방식으로 구성된다.

3. Multiple Nodes, Same L2 Network

동일 Subnet에 속한 Container 간의 Communication

동일 Switch 또는 Subnet에 속한 Node로 구성된 클러스터에서 서로 다른 Node에 속한 Container 간의 네트워크 모델로 Node가 가상의 Router(vRouter)처럼 동작하는 것이 핵심이다. 

'Single Node, 2 Namespace' 모델에서 Pod에서 Host로 라우팅된 패킷의 Destination IP가 다른 Node에 속했다면 이를 해당 Node로 전달한다. 이 패킷을 받은 Node는 Destination IP가 자신의 Bridge와 연결된 Pod 있음을 알고 있기 때문에 추가적인 작업없이 패킷을 목적지까지 전송할 수 있다.

CNI 플러그인 중 Calico(Non-overlay 모드)가 대표적이며, BGP 라우팅 프로토콜을 통해 Pod CIDR와 Node간의 Routing Rule을 계속해서 업데이트하는 방식을 사용하고 있다.

다만, Node가 서로 다른 Subnet에 속해있고 중간에 외부 Router를 거쳐야 하는 경우엔 이 방식을 적용할 수 없다. 외부 Router 입장에선 Pod IP만으로는 Next Hop을 결정할 수 없기 때문이다.

4. Multiple Nodes, Overlay Network

서로 다른 Subnet에 속한 Container 간의 Communication

우리는 서로 다른 Node가 동일한 L2 Network가 위치하지 않는 케이스를 생각해볼 필요가 있다. 만약에 Multi AZ로 K8s 클러스터를 구성하는 경우, Node들은 서로 다른 subnet에 속하게 된다. 3번에서 설명한 L3 Routing 방식 적용시, Pod IP만으로는 외부 Router에서 Next Hop을 찾을 수 없기 때문에 문제가 발생한다. 이를 해결하기 위해 적용된 기술이 Tunneling이다.

우선 Pod에서 Host로 라우팅된 패킷 중 Destination IP가 Pod CIDR에 속한 경우, tun0를 통해 터널링 디바이스 또는 네트워크 Agent로 전달된다. Agent는 Destination IP가 어떤 Node에 위치하는지 알고 있기 때문에, 해당 패킷을  Encapsulation 후 Host Network Stack을 통해 전달한다. 이때 패킷의 Outer Header의 Src와 Dst는 각 Node로 지정된다.

패킷을 전달받은 Node는 Decapsulation 과정에서 해당 패킷이 자신이 갖고 있는 Pod으로 전송된 것임을 알 수 있고, 이를 통해 해당 Destination IP를 가지고 있는 Pod으로 전달된다.

CNI 플러그인 중 Flannel, Weave 그리고 Calico(Overlay 모드)가 대표적이며, VXLAN 또는 IPinIP 프로토콜을 통해 Packet Encapsualtion을 수행한다.

결론

Non-overlay 네트워크는 Overlay 네트워크보다 더 높은 성능(response time 등)을 보여주며, 이는 CNI 플러그인 Agent의 Packet Encapsulation/Decapsulation 과정 유무에 달려있다. 따라서 Cluster의 모든 Node가 같은 Subnet에 존재하는 경우, Non-overlay 네트워크를 구성하는 것이 바람직하다. 다만 High Availability를 위해 여러 Subnet에 Node가 배치된 경우, Overlay 네트워크를 사용할 수 밖에 없다(On-premise 환경에서 Router를 제어할 수 있다면 이 경우에도 Non-overlay 네트워크를 구성할 수도 있다).

 

BGP 모드
ipip 모드
vxlan 모드

환경에 따라 다소 차이가 있을 순 있지만, Direct로 패킷을 전송하는 BGP 모드의 응답속도(<1ms)가 제일 빠르고, 터널링 방식의 ipip와 vxlan은 상대적으로 느린 점(~40ms)을 확인할 수 있다. 여기서 알 수 있는 것은, Packet Encapsulation/Decapsulation 과정에서 적지 않은 시간 또한 소요된다는 점이다.

 

수많은 CNI 플러그인 중에서 Calico는 CrossSubnet 모드를 지원한다. 이 모드 적용시, 동일 Subnet 안에서 Non-overlay/다른 Subnet 사이에선 Overlay 방식으로 동작하는 매우 유용한 기능이다.

참고
Cluster Networking - kubernetes
Container Networking From Scratch - Kristen Jacobs, Oracle
Calico - Overlay Networking#crossSubnet
 

Overlay networking

Configure Calico to use IP in IP or VXLAN overlay networking so the underlying network doesn’t need to understand pod addresses.

docs.projectcalico.org

 

'Kubernetes > Architecture' 카테고리의 다른 글

Pod Lifecycle  (0) 2021.03.07
Calico Components  (0) 2021.02.11
Linux Namespaces  (0) 2021.02.02
CNI - Spec  (0) 2021.01.24
Scheduler  (0) 2021.01.15