Kubernetes v1.17
alpha
서비스 토폴로지 를 활성화 하면 서비스는 클러스터의 노드 토폴로지를 기반으로 트래픽을 라우팅한다. 예를 들어, 서비스는 트래픽을 클라이언트와 동일한 노드이거나 동일한 가용성 영역에 있는 엔드포인트로 우선적으로 라우팅되도록 지정할 수 있다.
기본적으로 ClusterIP
또는 NodePort
서비스로 전송된 트래픽은 서비스의
모든 백엔드 주소로 라우팅 될 수 있다. 쿠버네티스 1.7부터는 “외부(external)”
트래픽을 수신한 노드에서 실행중인 파드로 라우팅할 수 있었지만,
ClusterIP
서비스에서는 지원되지 않으며 더 복잡한
토폴로지 — 영역별 라우팅과 같은 — 에서는 불가능 했다.
서비스 토폴로지 기능은 서비스 생성자가 발신 노드와 수신 노드에 대해서
노드 레이블에 기반한 트래픽 라우팅 정책을 정의할 수 있도록
함으로써 이 문제를 해결한다.
소스와 목적지의 노드 레이블 일치를 사용하여 운영자는 운영자의 요구 사항에 적합한 메트릭에 대해서 서로 “근접(closer)” 하거나 “먼(farther)” 노드 그룹을 지정할 수 있다. 공용 클라우드의 많은 운영자들이 서비스 트래픽을 동일한 영역에서 유지하는 것을 선호하는 것을 필요성의 예제로 볼 수 있다. 그 이유는 지역간의 트래픽에는 관련 비용이 발생하지만 지역 내의 트래픽은 발생하지 않기 때문이다. 다른 일반적인 필요성으로는 DaemonSet이 관리하는 로컬 파드로 트래픽을 라우팅 하거나, 대기시간을 최소화하기 위해 동일한 랙 상단(top-of-rack) 스위치에 연결된 노드로 트래픽을 유지하는 것이 있다.
만약 클러스터에서 서비스 토폴로지가 활성화된 경우, 서비스 사양에서
topologyKeys
필드를 지정해서 서비스 트래픽 라우팅을 제어할 수 있다. 이 필드는
이 서비스에 접근할 때 엔드포인트를 정렬하는데 사용되는 노드
레이블의 우선 순위 목록이다. 트래픽은 첫 번째 레이블 값이 해당 레이블의
발신 노드 값과 일치하는 노드로 보내진다. 만약 노드에 서비스와 일치하는
백엔드가 없는 경우, 두 번째 레이블을 그리고 더 이상의
레이블이 남지 않을 때까지 고려한다.
만약 일치하는 것을 못찾는 경우에는, 서비스에 대한 백엔드가 없었던 것처럼
트래픽이 거부될 것이다. 즉, 엔드포인트는 사용 가능한 백엔드가 있는 첫 번째
토폴로지 키를 기반으로 선택된다. 만약 이 필드가 지정되고 모든 항목에
클라이언트의 토폴로지와 일치하는 백엔드가 없는 경우, 서비스에는 해당 클라이언트에
대한 백엔드가 없기에 연결에 실패해야 한다. 특수한 값인 "*"
은 “모든 토폴로지”를
의미하는데 사용될 수 있다. 이 캐치 올(catch-all) 값을 사용하는 경우
목록의 마지막 값으로만 타당하다.
만약 topologyKeys
가 지정되지 않거나 비어있는 경우 토폴로지 제약 조건이 적용되지 않는다.
호스트 이름, 영역 이름 그리고 지역 이름으로 레이블이 지정된 노드가 있는
클러스터가 있다고 생각해 보자. 그러고 나면, 서비스의 topologyKeys
값을 설정해서 다음과 같이 트래픽을
전달할 수 있다.
["kubernetes.io/hostname"]
.["kubernetes.io/hostname",
"topology.kubernetes.io/zone", "topology.kubernetes.io/region"]
.
예를 들어 데이터 위치가 중요한 경우에 유용할 수 있다.["topology.kubernetes.io/zone", "*"]
.서비스 토폴로지는 externalTrafficPolicy=Local
와 호환되지 않으므로
서비스는 이 두 가지 기능을 함께 사용할 수 없다. 동일한 서비스가 아닌
같은 클러스터의 다른 서비스라면 이 기능을 함께 사용할
수 있다.
유효한 토폴로지 키는 현재 kubernetes.io/hostname
,
topology.kubernetes.io/zone
그리고 topology.kubernetes.io/region
로
제한되어있지만, 앞으로 다른 노드 레이블로 일반화 될 것이다.
토폴로지 키는 유효한 레이블 키이어야 하며 최대 16개의 키를 지정할 수 있다.
만약 캐치 올(catch-all) 값인 "*"
를 사용한다면 토폴로지 키들의 마지막 값이어야
한다.
다음은 서비스 토폴로지 기능을 사용하는 일반적인 예시이다.
노드 로컬 엔드포인트로만 라우팅하는 서비스이다. 만약 노드에 엔드포인트가 없으면 트레픽이 드롭된다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
topologyKeys:
- "kubernetes.io/hostname"
노드 로컬 엔드포인트를 선호하지만, 노드 로컬 엔드포인트가 없는 경우 클러스터 전체 엔드포인트로 폴백 하는 서비스이다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
topologyKeys:
- "kubernetes.io/hostname"
- "*"
영역보다는 지리적 엔드포인트를 선호하는 서비스이다. 만약 엔드포인트가 없다면, 트래픽은 드롭된다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
topologyKeys:
- "topology.kubernetes.io/zone"
- "topology.kubernetes.io/region"
노드 로컬, 영역 및 지역 엔드포인트를 선호하지만, 클러스터 전체 엔드포인트로 폴백하는 서비스이다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
topologyKeys:
- "kubernetes.io/hostname"
- "topology.kubernetes.io/zone"
- "topology.kubernetes.io/region"
- "*"
이 페이지가 도움이 되었나요?
피드백 감사합니다. 쿠버네티스 사용 방법에 대해서 구체적이고 답변 가능한 질문이 있다면, 다음 링크에서 질문하십시오. Stack Overflow. 원한다면 GitHub 리포지터리에 이슈를 열어서 문제 리포트 또는 개선 제안이 가능합니다..