개요
2024.05.22-[K8s] 네트워크 유형 - Pod와 Service 간 통신에서는 Service의 개념과 동작 방식에 대해서 알아보았다. 다만 Service는 기본적으로 ClusterIP 유형으로 생성되어 클러스터 내부에서만 통신이 가능하도록 되어있다. 그렇다면 외부와 통신을 주고받아야 할 때는 어떻게 해야 할까?
쿠버네티스에서는 NodePort 유형의 Service, Load Balancer 유형의 Service 그리고 Ingress를 통해 외부와의 통신을 가능하게 한다.
각각에 대해서 정리해 둔다.
NodePort
NodePort 유형의 Service는 기본적으로 Cluster IP 유형과 비슷하지만, Node 네트워크의 IP를 통한 접근을 허용하는 등의 몇 가지 기능을 더 갖고 있다. 즉, NodePort 유형의 서비스를 사용하여 Node의 IP를 통한 접근과 Cluster IP를 통한 접근 모두 가능하다.
왜냐하면 쿠버네티스가 NodePort 유형의 서비스를 생성하면 kube-proxy가 각 노드의 eth0 인터페이스에 30000-32767번 사이의 임의 포트를 할당하고, 할당된 포트로 요청이 오면 이를 매핑되어 있는 ClusterIP로 전달하기 때문이다.
위의 그림에서 클라이언트가 로드 밸런서 IP로 연결하면, 로드 밸런서는 node를 선택하여 32213 Port로 패킷을 전달한다. kube-proxy는 받은 패킷을 Cluster IP(10.3.241.152:80)으로 전달한다. 이후 netfilter에 의해 service IP를 실제 Pod (10.0.2.2:8080)으로 변환하여 전달한다.
다만 NodePort 유형의 서비스는 한정된 자원이고, 로드 밸런서를 거치지 않는다면 non-standard 포트를 열어주어야 하는 등의 문제가 있다.
즉, NodePort 유형의 Service는 외부 트래픽이 쿠버네티스 환경으로 들어오는 기초적인 방법이지만, 대부분의 경우 로드 밸런서를 요구한다.
LoadBalancer
LoadBalancer 유형의 Service는 NodePort 유형의 Service에 로드 밸런서를 통한 접근을 추가한 기능이다. GCP, AWS처럼 API를 통해 로드 밸런서를 생성할 수 있는 클라우드 환경에서 사용하는 것을 가정하고 개발되었다. 즉, Service 생성 시 spec.type을 LoadBalancer로 지정하면 클라우드 환경에 LoadBalancer 인프라가 생성된다!
클라우드 환경이 아니라면 Metal LB를 설치하여 사용할 수도 있다.
LoadBalancer 유형의 Service에는 TLS termination 설정 불가, virtual host 불가, path-base routing 불가 등의 몇 가지 제약사항이 존재한다. 따라서 하나의 로드 밸런서로 여러 서비스에 연결하는 것은 불가능하다.
(참고 : https://passwd.tistory.com/entry/Services)
Ingress
참고 : https://passwd.tistory.com/entry/Ingress-Networking
Ingress는 LoadBalancer 타입의 Service와 달리 하나의 로드 밸런서를 통해 여러 Service에 접근할 수 있도록 구성할 수 있다.
Ingress는 Ingress라는 리소스와 리소스를 관리하는 컨트롤러로 구성된다. Ingress-controller은 들어오는 요청을 적절한 서비스로 전달하는 역할을 담당하며, 요청받을 서비스를 NodePort 유형의 서비스로 설정하고 Ingress -controller로 요청을 어떻게 노드에 전달할지 파악하게 한다.
주의해야 할 점은 LoadBalancer 유형의 Service와 Ingress을 혼용해서 사용하면 이슈가 발생할 수도 있다는 것이다. 대부분은 이상 없이 동작하지만 일반적인 경우에는 Ingress만 사용하는 것을 권한다.
참고 문서
https://coffeewhale.com/k8s/network/2019/05/30/k8s-network-03/