토폴로지 인지 힌트

토폴로지 인지 힌트 는 트래픽이 발생한 존 내에서 네트워크 트래픽을 유지하도록 처리하는 메커니즘을 제공한다. 클러스터의 파드간 동일한 존의 트래픽을 선호하는 것은 안전성, 성능(네트워크 지연 및 처리량) 혹은 비용 측면에 도움이 될 수 있다.
기능 상태: Kubernetes v1.23 [beta]

토폴로지 인지 힌트(Topology Aware Hints) 는 클라이언트가 엔드포인트(endpoint)를 어떻게 사용해야 하는지에 대한 제안을 포함시킴으로써 토폴로지 인지 라우팅을 가능하게 한다. 이러한 접근은 엔드포인트슬라이스(EndpointSlice) 또는 엔드포인트(Endpoints) 오브젝트의 소비자(consumer)가 이용할 수 있는 메타데이터를 추가하며, 이를 통해 해당 네트워크 엔드포인트로의 트래픽이 근원지에 더 가깝게 라우트될 수 있다.

예를 들어, 비용을 줄이거나 네트워크 성능을 높이기 위해, 인접성을 고려하여 트래픽을 라우트할 수 있다.

동기(motivation)

쿠버네티스 클러스터가 멀티-존(multi-zone) 환경에 배포되는 일이 점점 많아지고 있다. 토폴로지 인지 힌트 는 트래픽이 발생한 존 내에서 트래픽을 유지하도록 처리하는 메커니즘을 제공한다. 이러한 개념은 보통 "토폴로지 인지 라우팅"이라고 부른다. 서비스의 엔드포인트를 계산할 때, 엔드포인트슬라이스 컨트롤러는 각 엔드포인트의 토폴로지(지역(region) 및 존)를 고려하여, 엔드포인트가 특정 존에 할당되도록 힌트 필드를 채운다. 그러면 kube-proxy와 같은 클러스터 구성 요소는 해당 힌트를 인식하고, (토폴로지 상 가까운 엔드포인트를 사용하도록) 트래픽 라우팅 구성에 활용한다.

토폴로지 인지 힌트 사용하기

service.kubernetes.io/topology-aware-hints 어노테이션을 auto로 설정하여 서비스에 대한 토폴로지 인지 힌트를 활성화할 수 있다. 이는 엔드포인트슬라이스 컨트롤러가 안전하다고 판단되는 경우 토폴로지 힌트를 설정하도록 지시하는 것이다. 명심할 점은, 이를 수행한다고 해서 힌트가 항상 설정되는 것은 아니라는 것이다.

동작 방법

이 기능을 동작시키는 요소는 엔드포인트슬라이스 컨트롤러와 kube-proxy 두 구성요소로 나눠져 있다. 이 섹션에서는 각 구성요소가 어떻게 이 기능을 동작시키는지에 대한 고차원 개요를 제공한다.

엔드포인트슬라이스 컨트롤러

엔드포인트슬라이스 컨트롤러는 이 기능이 활성화되어 있을 때 엔드포인트슬라이스에 힌트를 설정하는 일을 담당한다. 컨트롤러는 각 존에 일정 비율의 엔드포인트를 할당한다. 이 비율은 해당 존에 있는 노드의 할당 가능한(allocatable) CPU 코어에 의해 결정된다. 예를 들어, 한 존에 2 CPU 코어가 있고 다른 존에 1 CPU 코어만 있는 경우, 컨트롤러는 2 CPU 코어가 있는 존에 엔드포인트를 2배 할당할 것이다.

다음 예시는 엔드포인트슬라이스에 힌트가 채워졌을 때에 대한 예시이다.

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: example-hints
  labels:
    kubernetes.io/service-name: example-svc
addressType: IPv4
ports:
  - name: http
    protocol: TCP
    port: 80
endpoints:
  - addresses:
      - "10.1.2.3"
    conditions:
      ready: true
    hostname: pod-1
    zone: zone-a
    hints:
      forZones:
        - name: "zone-a"

kube-proxy

kube-proxy 구성요소는 엔드포인트슬라이스 컨트롤러가 설정한 힌트를 기반으로 자신이 라우팅하는 엔드포인트를 필터링한다. 대부분의 경우, 이는 kube-proxy가 동일 존 내에서 트래픽을 엔드포인트로 라우팅할 수 있음을 뜻한다. 때때로 컨트롤러는 존 사이에 보다 균등한 엔드포인트 분배를 위해 다른 존으로부터 엔드포인트를 할당하기도 한다. 이러한 경우 일부 트래픽은 다른 존으로 라우팅될 것이다.

보호 규칙

쿠버네티스 컨트롤 플레인과 각 노드의 kube-proxy는 토폴로지 인지 힌트를 사용하기 전에 몇 가지 보호 규칙을 적용한다. 이들이 만족되지 않으면, kube-proxy는 존에 상관없이 클러스터의 모든 곳으로부터 엔드포인트를 선택한다.

  1. 엔드포인트 수가 충분하지 않음: 존의 숫자보다 엔드포인트의 숫자가 적으면, 컨트롤러는 어떤 힌트도 할당하지 않을 것이다.

  2. 균형잡힌 할당이 불가능함: 일부 경우에, 존 간 균형잡힌 엔드포인트 할당이 불가능할 수 있다. 예를 들어, zone-a가 zone-b보다 2배 큰 상황에서, 엔드포인트가 2개 뿐이라면, zone-a에 할당된 엔드포인트는 zone-b에 할당된 엔드포인트보다 2배의 트래픽을 수신할 것이다. 컨트롤러는 이 "예상 과부하" 값을 각 존에 대해 허용 가능한 임계값보다 작게 낮출 수 없는 경우에는 힌트를 할당하지 않는다. 명심할 점은, 이것이 실시간 피드백 기반이 아니라는 것이다. 개별 엔드포인트가 과부하 상태로 바뀔 가능성도 여전히 있다.

  3. 하나 이상의 노드에 대한 정보가 불충분함: topology.kubernetes.io/zone 레이블이 없는 노드가 있거나 할당 가능한 CPU 값을 보고하지 않는 노드가 있으면, 컨트롤 플레인은 토폴로지 인지 엔드포인트를 설정하지 않으며 이로 인해 kube-proxy는 존 별로 엔드포인트를 필터링하지 않는다.

  4. 하나 이상의 엔드포인트에 존 힌트가 없음: 이러한 상황이 발생하면, kube-proxy는 토폴로지 인지 힌트로부터의 또는 토폴로지 인지 힌트로의 전환이 진행 중이라고 가정한다. 이 상태에서 서비스의 엔드포인트를 필터링하는 것은 위험할 수 있으므로 kube-proxy는 모든 엔드포인트를 사용하는 모드로 전환된다.

  5. 힌트에 존이 기재되지 않음: kube-proxy가 실행되고 있는 존을 향하는 힌트를 갖는 엔드포인트를 하나도 찾지 못했다면, 모든 존에서 오는 엔드포인트를 사용하는 모드로 전환된다. 이러한 경우는 기존에 있던 클러스터에 새로운 존을 추가하는 경우에 발생할 가능성이 가장 높다.

제약사항

  • 토폴로지 인지 힌트는 서비스의 externalTrafficPolicy 또는 internalTrafficPolicyLocal로 설정된 경우에는 사용되지 않는다. 동일 클러스터의 서로 다른 서비스들에 대해 두 기능 중 하나를 사용하는 것은 가능하며, 하나의 서비스에 두 기능 모두를 사용하는 것은 불가능하다.

  • 이러한 접근 방법은 존의 일부분에서 많은 트래픽이 발생하는 서비스에는 잘 작동하지 않을 것이다. 대신, 들어오는 트래픽이 각 존 내 노드 용량에 대략 비례한다고 가정한다.

  • 엔드포인트슬라이스 컨트롤러는 각 존 내의 비율을 계산할 때 준비되지 않은(unready) 노드는 무시한다. 이 때문에 많은 노드가 준비되지 않은 상태에서는 의도하지 않은 결과가 나타날 수도 있다.

  • 엔드포인트슬라이스 컨트롤러는 각 존 내의 비율을 배포하거나 계산할 때 톨러레이션은 고려하지 않는다. 서비스를 구성하는 파드가 클러스터의 일부 노드에만 배치되어 있는 경우, 이러한 상황은 고려되지 않을 것이다.

  • 오토스케일링 기능과는 잘 동작하지 않을 수 있다. 예를 들어, 하나의 존에서 많은 트래픽이 발생하는 경우, 해당 존에 할당된 엔드포인트만 트래픽을 처리하고 있을 것이다. 이로 인해 Horizontal Pod Autoscaler가 이 이벤트를 감지하지 못하거나, 또는 새롭게 추가되는 파드가 다른 존에 추가될 수 있다.

다음 내용