Kubernetes 서비스
Kubernetes 서비스가 무엇인지, 세 가지 주요 서비스 타입이 어떻게 다른지, 서비스와 네트워크 정책이 어떻게 상호작용하는지 알아봐요. 서비스 처리를 최적화하는 옵션도 함께 소개해요. Calico 운영에서 자주 마주치는 서비스·정책 상호작용 개념을 잡는 데 유용한 문서예요.
출처: 문서
본문
참고: 이 가이드는 Calico에 특화되지 않은 교육용 자료를 제공해요.
이 가이드에서 다음을 배울 수 있어요.
- Kubernetes 서비스란 무엇인가?
- 세 가지 주요 서비스 타입의 차이와 각각의 용도는 무엇인가?
- 서비스와 네트워크 정책은 어떻게 상호작용하는가?
- 서비스 처리를 최적화하는 몇 가지 옵션은 무엇인가?
Kubernetes 서비스란 무엇인가요?
Kubernetes 서비스는 파드 그룹에 대한 접근을 네트워크 서비스로 추상화하는 방법을 제공해요. 각 서비스를 지원하는 파드 그룹은 보통 레이블 셀렉터로 정의해요.
클라이언트가 Kubernetes 서비스에 연결하면 그 연결은 서비스를 지원하는 파드 중 하나로 로드 밸런싱돼요. 다음 개념 다이어그램처럼 동작해요.
Kubernetes 서비스의 주요 타입은 세 가지예요.
- Cluster IP - 클러스터 내부에서 서비스에 접근하는 일반적인 방법
- Node port - 클러스터 외부에서 서비스에 접근하는 가장 기본적인 방법
- Load balancer - 외부 로드 밸런서를 사용해 클러스터 외부에서 서비스에 접근하는 좀 더 정교한 방법
Cluster IP 서비스
기본 서비스 타입은 ClusterIP예요. 이 타입은 서비스 Cluster IP라고 하는 가상 IP 주소를 통해 클러스터 내부에서 서비스에 접근할 수 있게 해 줘요. 서비스의 Cluster IP는 Kubernetes DNS를 통해 알 수 있어요. 예를 들어 my-svc.my-namespace.svc.cluster-domain.example 같은 식이에요. DNS 이름과 Cluster IP 주소는 서비스의 수명 동안 변하지 않아요. 서비스를 지원하는 파드가 만들어지거나 삭제되고, 파드 수가 시간에 따라 바뀌더라도 그래요.
일반적인 Kubernetes 배포에서는 kube-proxy가 모든 노드에서 실행되며, Cluster IP 주소로 들어오는 연결을 가로채 서비스를 지원하는 파드 그룹 전반에 로드 밸런싱하는 역할을 맡아요. 이 과정에서 DNAT가 사용되어 목적지 IP 주소가 Cluster IP에서 선택된 백엔드 파드로 매핑돼요. 연결의 응답 패킷은 되돌아가는 길에 NAT 역변환을 거쳐 연결을 시작한 파드로 돌아가요.
중요한 점은 네트워크 정책이 서비스 Cluster IP가 아니라 파드 기준으로 적용된다는 거예요. (즉, egress 네트워크 정책은 DNAT가 연결의 목적지 IP를 선택된 서비스 백엔드 파드로 바꾼 후에 클라이언트 파드에 적용돼요. 그리고 연결의 목적지 IP만 바뀌기 때문에, 백엔드 파드의 ingress 네트워크 정책은 원래 클라이언트 파드를 연결의 출발지로 봐요.)
Node port 서비스
클러스터 외부에서 서비스에 접근하는 가장 기본적인 방법은 NodePort 타입의 서비스를 사용하는 거예요. Node Port는 클러스터의 각 노드에서 예약된 포트로, 이 포트를 통해 서비스에 접근할 수 있어요. 일반적인 Kubernetes 배포에서 kube-proxy가 Node Port로 들어오는 연결을 가로채 서비스를 지원하는 파드 전반에 로드 밸런싱하는 역할을 맡아요.
이 과정에서 NAT가 사용되어 목적지 IP 주소와 포트가 노드 IP와 Node Port에서 선택된 백엔드 파드와 서비스 포트로 매핑돼요. 또한 소스 IP 주소가 클라이언트 IP에서 노드 IP로 매핑되어, 연결의 응답 패킷이 원래 노드로 돌아올 수 있고 그 노드에서 NAT 역변환이 일어나요. (NAT를 수행한 노드가 NAT를 되돌리는 데 필요한 커넥션 트래킹 상태를 갖고 있거든요.)
연결의 소스 IP 주소가 노드 IP 주소로 SNAT되기 때문에, 서비스 백엔드 파드의 ingress 네트워크 정책은 원래 클라이언트 IP 주소를 볼 수 없다는 점에 주의하세요. 보통 이는 그런 정책이 목적지 프로토콜과 포트를 제한하는 데에 한정되고, 클라이언트/소스 IP 기반 제한은 불가능하다는 뜻이에요. 이 제한은 일부 시나리오에서 externalTrafficPolicy를 사용하거나, 소스 IP 주소를 보존하는 Calico의 eBPF 데이터 플레인 네이티브 서비스 처리(kube-proxy 대신)를 사용해 우회할 수 있어요.
Load balancer 서비스
LoadBalancer 타입의 서비스는 외부 네트워크 로드 밸런서(NLB)를 통해 서비스를 노출해요. 어떤 종류의 네트워크 로드 밸런서가 쓰이는지는 클러스터와 통합된 퍼블릭 클라우드 공급자가 무엇인지, 온프레미스라면 어떤 하드웨어 로드 밸런서 통합을 쓰는지에 따라 달라져요.
서비스는 네트워크 로드 밸런서의 특정 IP 주소를 통해 클러스터 외부에서 접근할 수 있고, 기본적으로 서비스 노드 포트를 사용해 노드 전반에 고르게 로드 밸런싱해요.
대부분의 네트워크 로드 밸런서는 클라이언트 소스 IP 주소를 보존하지만, 서비스 트래픽이 노드 포트를 거치기 때문에 백엔드 파드 자체는 클라이언트 IP를 볼 수 없고, 네트워크 정책에도 같은 영향이 생겨요. Node port와 마찬가지로 이 제한은 일부 시나리오에서 externalTrafficPolicy를 사용하거나, 소스 IP 주소를 보존하는 Calico의 eBPF 데이터 플레인 네이티브 서비스 처리(kube-proxy 대신)를 사용해 우회할 수 있어요.
서비스 IP 광고하기
노드 포트나 네트워크 로드 밸런서를 쓰는 대안 중 하나는 서비스 IP 주소를 BGP로 광고하는 거예요. 클러스터가 BGP를 지원하는 기반 네트워크 위에서 실행되어야 하고, 보통 표준 top-of-rack 라우터를 갖춘 온프레미스 배포를 의미해요.
Calico는 서비스 Cluster IP와, External IP가 구성된 서비스의 External IP 광고를 지원해요. Calico를 네트워크 플러그인으로 사용하지 않는다면 MetalLB가 다양한 네트워크 플러그인과 동작하는 유사한 기능을 제공해요.
externalTrafficPolicy:local
기본적으로 NodePort나 LoadBalancer 서비스 타입을 쓰든, 서비스 IP 주소를 BGP로 광고하든, 클러스터 외부에서 서비스에 접근하면 파드가 어느 노드에 있든 상관없이 서비스를 지원하는 모든 파드에 고르게 로드 밸런싱돼요. 이 동작은 서비스를 externalTrafficPolicy:local로 구성해 바꿀 수 있어요. 이 설정은 연결이 로컬 노드에 있는 서비스 백엔드 파드로만 로드 밸런싱되어야 함을 지정해요.
LoadBalancer 타입의 서비스와 결합하거나 Calico 서비스 IP 주소 광고와 결합하면, 트래픽이 서비스를 지원하는 파드를 최소 하나 이상 호스팅하는 노드로만 향해요. 노드 사이의 잠재적인 추가 네트워크 홉을 줄여 주고, 더 중요하게는 소스 IP 주소를 파드까지 끝까지 유지해 주기 때문에, 원한다면 네트워크 정책으로 특정 외부 클라이언트를 제한할 수 있어요.
LoadBalancer 타입의 서비스의 경우 이 모드를 지원하지 않는 로드 밸런서도 있다는 점에 유의하세요. 그리고 서비스 IP 광고의 경우 로드 밸런싱의 균등성이 토폴로지에 따라 달라져요. 이 경우 파드 안티 어피니티 규칙을 사용해 백엔드 파드가 토폴로지 전반에 고르게 분포하도록 보장할 수 있지만, 서비스 배포에 약간의 복잡성이 더해져요.
Calico eBPF 네이티브 서비스 처리
Kubernetes 표준 kube-proxy를 쓰는 대안으로, Calico의 eBPF 데이터 플레인은 네이티브 서비스 처리를 지원해요. 소스 IP를 보존해 네트워크 정책을 단순하게 만들어 주고, 반환 트래픽의 네트워크 홉 수를 줄이는 DSR(Direct Server Return)을 제공하며, kube-proxy보다 낮은 CPU와 지연 시간으로 토폴로지와 무관하게 균등한 로드 밸런싱을 제공해요.
추가 리소스
더 알아보기 (Learn more)
서비스 타입에 따라 소스 IP 보존 여부가 달라지고, 이것이 네트워크 정책의 세밀함을 결정해요. 외부 트래픽에 정교한 정책이 필요하다면 externalTrafficPolicy: Local이나 eBPF 네이티브 서비스 처리를 검토해 보세요.