Traffic Flow in K8s

Dongmin Lee·2023년 7월 11일
0

Kubernetes

목록 보기
3/10

온프레미스 쿠버네티스 클러스터에 트래픽이 들어왔을 때 어떻게 흘러가는지 살펴보자.

0. Assumption

아래의 기술들을 쓴다고 가정해보자.

  • 외부 DNS 서비스: AWS Route 53
  • 내부 ingress controller: Nginx

1. Traffic Arrival

외부 클라이언트가 웹 브라우저에서 www.example.com을 입력하여 어플리케이션에 접근 요청을 보냈다. 요청을 하게 되면 외부 DNS 서비스(e.g., AWS Route 53 CNAME 레코드 사용)를 통해 www.example.com이 어떤 IP 주소를 가리키게 되고, 그 IP 주소는 클러스터 내에 있는 load balancer 중 하나인 nginx ingress controller의 external IP이다.

2. Ingress

Nginx ingress controller는 접근 요청을 수신한다. 그리고 생성되어있는 ingress resource를 참조하여 정의된 라우팅 규칙(e.g., 호스트 이름, 경로, 서비스 이름, 서비스 포트) 에 따라 외부에서 들어온 트래픽을 전달해야 하는 서비스를 결정한다.

3. CoreDNS

Ingress controller는 호스트 이름으로 트래픽을 전달하기 위해 해당 서비스의 이름을 사용한다. 이 때 클러스터 내부에서 CoreDNS는 호스트 이름을 해당 서비스의 내부 ClusterIP로 변환한다. 이 과정을 통해 트래픽은 서비스의 ClusterIP로 라우팅된다. 참고로 클러스터 내부에서 사용되는 호스트 이름(e.g., <service_name>.<namespace_name>.svc.cluster.local)을 해당 서비스의 ClusterIP로 변환한다.

여기까지 ingress controller의 역할은 종료된다.

4. Kube-Proxy

  1. 서비스 IP 주소 관리
  2. 트래픽 라우팅
  3. 트래픽 로드 밸런싱

Kube-proxy는 클러스터 내에서 트래픽 라우팅을 담당한다. 서비스의 ClusterIP로 라우팅된 트래픽은 kube-proxy에 의해 처리된다.

Kube-proxy는 해당 서비스의 IP 주소와 서비스에 연결된 Pod들의 IP 주소를 관리한다. 이때, 서비스의 label selector를 사용하여 해당 label과 일치하는 Pod들을 식별한다.

이후 kube-proxy는 기본적으로 사용되는 Round Robin 로드 밸런싱 전략에 따라 여러 Pod 중 하나로 트래픽을 전달한다. 즉, 트래픽은 모든 Pod에 균등하게 분산하게 된다.

이 과정에서 kube-proxy는 NAT를 사용하여 서비스로부터 받은 요청을 해당 Pod의 IP 주소로 변환하여 트래픽을 보낸다. 변환할 때에는 일반적으로 리눅스 네트워크 방법 중 하나인 IP tables를 이용한다.

4.1 (참고) Services in Kube-Proxy

이 부분은 흐름도와 관계 없이 각 서비스에 대한 내용이다.

ClusterIP

Kubernetes의 기본 서비스 유형이다. 서비스가 생성되면 kube-proxy에 의해 해당 서비스에 가상 IP(ClusterIP)가 할당된다. 이 IP는 클러스터 내에서 트래픽을 Pod로 라우팅하는 데 사용된다. 기본적으로 kube-proxy는 서비스와 연결된 Pod의 IP와 port를 추적하고 라우팅을 관리한다.

NodePort

NodePort는 내부 ClusterIP 외에 각 Node에 port가 할당된다. 이렇게 하면 클러스터 외부에서 서비스에 접근할 수 있다. NodePort에 도달하는 모든 트래픽은 kube-proxy에 의해 인터셉트되며, kube-proxy는 서비스의 ClusterIP를 통해 서비스의 label selector를 확인하고, 일치하는 label을 가진 Pod 중 하나를 선택하여 트래픽을 전달한다.

LoadBalancer

LoadBalancer는 NodePort 서비스와 ClusterIP 서비스를 포함한 확장된 서비스이다. 일반적으로 클러스터 외부에서 오는 트래픽은 LoadBalancer에 도달한 다음 NodePort로 전달되어 클러스터 내부의 적절한 Node의 port로 라우팅된다. 마지막으로 kube-proxy는 앞서 NodePort에서 살펴본 것처럼 서비스의 ClusterIP를 통해 Pod로 트래픽을 load balancing한다.

모든 서비스에서 kube-proxy는 서비스의 IP(ClusterIP, NodePort, LoadBalancer)에서 해당 서비스에 매핑된 Pod로 트래픽을 라우팅하는 역할을 한다.

5. Container Network Interface (CNI)

  1. 네트워크 인터페이스 설정
  2. IP 주소 할당
  3. 파드 간 네트워크 설정
  4. Network Policy 적용

CNI는 Pod가 통신할 수 있는 네트워크 환경을 구축한다. Pod가 시작할 때마다 각 Pod에 네트워크 인터페이스를 제공하여 동적으로 IP 주소를 할당하는 역할을 하고, 종료될 때마다 네트워크 인터페이스를 제거하는 표준화된 방식을 제공한다.

또한 Pod 간의 통신을 가능하게 한다. 하지만 Pod의 IP가 동적으로 할당되기 때문에 Pod 간의 통신을 직접적으로 하는 것이 어렵다. 그래서 서비스를 통해 Pod 간의 label selector를 이용하여 통신한다.

CNI는 트래픽이 들어왔을 때 실행되는 것은 아니며, 이미 어플리케이션이 실행되었기 때문에 Pod에 네트워크 인터페이스가 제공되었을 것이며, 동적으로 IP 주소를 할당했을 것이다.

6. CoreDNS vs Kube-Proxy

CoreDNS

  • 역할
    • CoreDNS는 클러스터 내 DNS 서버로, 도메인 이름을 IP 주소로 변환하는 역할을 한다.
  • 기능
    • 서비스 이름 해석: CoreDNS는 클러스터 내부에서 호스트 이름(e.g., <service_name>.<namespace_name>.svc.cluster.local)을 해당 서비스의 ClusterIP로 변환한다. 이를 통해 클러스터 내부의 다른 컴포넌트나 Pod들이 서비스 이름을 사용하여 서로 통신할 수 있도록 해준다.
    • 외부 DNS 쿼리 포워딩: 클러스터 외부의 도메인 이름에 대한 쿼리를 받으면, 이를 클러스터 외부의 DNS 서버로 전달하여 해석한다.
  • 적용 범위
    • 주로 클러스터 내부 통신에 사용되며, 클러스터 내의 서비스나 리소스 간의 이름 해석에 중점을 둔다.

Kube-Proxy

  • 역할
    • Kube-proxy는 클러스터 내에서 트래픽을 Pod에 전달하는 네트워크 프록시이다.
  • 기능
    • 서비스로의 트래픽 라우팅: kube-proxy는 서비스의 ClusterIP, NodePort, LoadBalancer 등을 관리하고, 이러한 서비스로 들어오는 트래픽을 적절한 Pod로 라우팅한다.
    • 로드 밸런싱과 NAT: kube-proxy는 트래픽을 여러 Pod에 분산하는 로드 밸런싱을 담당한다. 이 과정에서 NAT를 사용하여 서비스의 IP 주소를 Pod의 실제 IP 주소로 변환한다.
    • Label Selector 사용: 서비스 정의에 포함된 label selector를 이용하여 해당하는 label을 가진 Pod들을 식별하고, 그 중 하나로 트래픽을 전달한다.
  • 적용 범위
    • 주로 서비스와 Pod 간의 네트워크 트래픽 라우팅에 중점을 둔다.

차이점 요약

  • CoreDNS는 이름 해석에 집중하여 클러스터 내에서 호스트 이름을 IP 주소로 변환한다. 이는 클러스터 내부의 통신을 위해 주로 사용된다.
  • Kube-proxy는 실제 트래픽 라우팅과 로드 밸런싱을 담당한다. 서비스로 들어오는 트래픽을 적절한 Pod로 전달하는 역할을 하며, 이 과정에서 NAT와 IP tables를 사용한다.

0개의 댓글