ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 쿠버네티스 네트워킹 : 서비스 네트워킹(kubernetes service networking)
    Kubernetes 2018. 8. 27. 09:00
    쿠버네티스에서 포드간에 어떻게 통신하는지는 알아봤습니다. 하지만 쿠버네티스에서 실제로 서비스용으로 앱을 올려서 사용한다면 단순히 포드와 포드사이의 통신만 하는 일은 사실 잘 없습니다. 단일 포드보다는 여러개의 포드를 띄우게 되고 그 포드들의 앞에 서비스를 두고 사용하는 것이 일반적인 구성입니다. 그래서 실제로 클러스터 내부에서 통신을 할때는 서비스의 IP를 바라보도록 되어 있습니다. clusterIP나 NodePort로 구성했을때 어떻게 서비스를 거쳐서 실제 포드까지 패킷이 가게 되는지 알아보겠습니다.
    쿠버네티스에서는 포드용 CIDR과 서비스용 CIDR을 별도로 지정하게 되어 있습니다. 포드용 CIDR은 마스터용 프로세스들을 실행할 때 --cluster-cidr 옵션을 이용해서 지정해 줍니다. 서비스용 CIDR은 --service-cluster-ip-range 옵션을 이용해서 지정합니다. 이렇게 2개의 옵션이 다른 만큼 서로 포드와 서비스는 서로 다른 IP대역을 사용합니다. 그런데 포드 네트워크를 구성할 때 살펴봤던 구성에서는 각각의 이더넷 디바이스나 라우터등의 장치에서 서비스용 IP대역에 대한 정보는 없었습니다. 이건 어디서 처리되는 걸까요? 다음 그림을 보도록 하겠습니다. 


    프론트와 벡엔드로 나뉘어져 있는 앱이라고 가정하겠습니다. 실제로 서비스를 한다면 프론트와 벡엔드에 각각 여러개의 포드들이 있겠지만 편의상 여기서는 각 포드가 1개씩만 있는걸 가정했습니다. 호스트 01에 있는 프론트용 포드(192.168.20.2)에서 벡엔드에 있는 포드에 접근하기 위해서 벡엔드용 서비스인 192.168.100.3으로 접근을 시도하려고 한다고 했을때 어떤 경로를 따라서 접근하게 될까요? 각 네트워크 디바이스인 veth0, eth0, 라우터/게이트웨이는 서비스용 IP인 192.168.100.x에 대한 라우팅 정보가 없습니다. 하지만 실제로 쿠버네티스 상에서 서비스 IP인 192.168.100.3으로 접근하면 통신이 잘 됩니다. 비밀은 그림에 표현된 NAT(Network Address Translation)쪽에 있습니다. cbr0와 eth0사이에서 실제로 존재하지 않는 ip인 192.168.100.x 대역에 대한 정보가 들어오면 NAT 영역에서 이 IP에 대한 요청을 적절한 곳으로 라우팅 되도록 변경을 해주게 됩니다. NAT 영역에서 패킷에 있는 출발지/목적지의 IP 정보를 실제 포드의 IP정보로 변경해 주는 역할을 합니다. 그렇기 때문에 별도 디바이스가 없더라도 서비스를 통해서 실제 포드로 접근이 가능하게 되는 것입니다. 이 NAT영역의 설정은 kube-proxy가 해주고 있습니다. kube-proxy가 apiserver를 지켜보고 있다가 포드의 변경사항이 발생하면 설정된 각 서비스(프론트, 벡엔드)에 해당하는 NAT 규칙을 업데이트 해줍니다. 이를 위해 쿠버네티스 클러스터내의 모든 노드에 kube-proxy가 설치되어 있습니다.
    쿠버네티스 초기에는 kube-proxy가 직접 패킷을 받아서 ip변환을 하는 역할을 했기 때문에 성능에 이슈가 있었습니다. 그래서 현재는 넷필터(netfilter)를 이용하도록 iptables를 이용하는게 기본 옵션입니다. kube-proxy가 직접 패킷을 변환하는게 아니라 iptables에 규칙만 업데이트 해주는 역할을 하고 있습니다. 하지만 이것 마저도 포드와 서비스가 많아져서 iptables에 규칙이 수천개 단위가 되면 성능에 이슈가 있다고 해서 요즘에는 ipvs를 사용하도록 하는 기능이 나왔습니다.

    댓글

Designed by Tistory.