페더레이션 서비스 구성
여러 클러스터에 걸쳐 서비스를 발견(discovery)할 수 있도록 로컬 클러스터를 구성하는 방법을 설명해요. 클러스터 메시(cluster mesh)와 페더레이션 서비스 디스커버리를 활용해 클러스터 경계를 넘어 서비스 엔드포인트를 공유하는 패턴을 익혀 보세요.
출처: 문서
본문
큰 그림(Big picture)
여러 클러스터에 걸쳐 서비스를 발견하도록 로컬 클러스터를 구성해요.
가치(Value)
클러스터 메시(cluster mesh)와 페더레이션 서비스 디스커버리를 페더레이션 엔드포인트 아이덴티티와 함께 사용해 엔드포인트 공유를 확장하고 자동화해요. (자체 서비스 디스커버리 메커니즘을 이미 갖추고 있다면 선택 사항이에요.)
개념(Concepts)
페더레이션 서비스(Federated services)
페더레이션 서비스(federated service, 백킹 서비스(backing service)라고도 불려요)는 엔드포인트가 통합된 서비스들의 집합이에요. Calico Cloud는 클러스터 메시 전체(로컬 클러스터와 원격 클러스터 모두)에서 서비스를 발견하고, 개별 서비스들을 모두 포괄하는 "페더레이션 서비스"를 로컬 클러스터에 만들어요.
페더레이션 서비스는 Tigera Federated Service Controller가 관리하며, 이 컨트롤러는 로컬에서 페더레이션된 각 서비스의 엔드포인트를 모니터링하고 유지해요. 컨트롤러는 원격 클러스터의 구성을 변경하지 않아요.
페더레이션 서비스는 일반적인 Kubernetes 서비스와 비슷하게 보이지만, pod 셀렉터 대신 어노테이션(annotation)을 사용해요. 예를 들면 다음과 같아요:
apiVersion: v1
kind: Service
metadata:
name: my-app-federated
namespace: default
annotations:
federation.tigera.io/serviceSelector: run == "my-app"
spec:
ports:
- name: my-app-ui
port: 8080
protocol: TCP
type: ClusterIP
| 어노테이션 | 설명 |
|---|---|
federation.tigera.io/serviceSelector |
페더레이션 서비스에 사용할 서비스를 지정하는 필수 필드예요. 형식은 표준 Calico Cloud 셀렉터(즉, Calico Cloud 정책 리소스와 동일)이며, 서비스의 레이블을 기준으로 서비스를 선택해요. 이 셀렉터 어노테이션은 pod이 아니라 서비스를 선택해요. 페더레이션 서비스와 같은 네임스페이스에 있는 서비스만 포함돼요. 이는 클러스터 간에 네임스페이스 이름이 연결되어 있어야 한다는 뜻이에요(페더레이션 엔드포인트 아이덴티티의 기본 전제예요). 값이 잘못 지정되면 해당 서비스는 페더레이션되지 않고 서비스에서 엔드포인트 데이터가 제거돼요. 이 값을 처리하는 데 문제가 있으면 컨트롤러의 경고 로그를 확인하세요. |
문법과 규칙(Syntax and rules)
- 페더레이션 서비스에 지정하는 서비스는 반드시 같은 네임스페이스에 있어야 하며, 그렇지 않으면 무시돼요. 페더레이션 엔드포인트 아이덴티티의 기본 가정은 클러스터 간에 네임스페이스 이름이 연결되어 있다는 거예요.
- 페더레이션 서비스에
spec.Selector를 지정하면 해당 서비스는 페더레이션되지 않아요. - 다른 페더레이션 서비스를 페더레이션할 수는 없어요. 서비스에 페더레이션 서비스 어노테이션이 있으면 다른 페더레이션 서비스의 백킹 서비스로 포함되지 않아요.
- 페더레이션 서비스 포트의 target 포트 번호는 사용되지 않아요.
레이블로 서비스 매칭하기(Match services using a label)
레이블을 사용해 서비스를 매칭할 수도 있어요. 이 레이블은 각 서비스에 암묵적으로 추가되지만, 서비스를 조회할 때 kubectl에는 나타나지 않아요.
| 레이블 | 설명 |
|---|---|
federation.tigera.io/remoteClusterName |
원격 클러스터의 Remote Cluster Configuration 이름에 해당하는 모든 원격 서비스에 추가되는 레이블이에요. 이 레이블을 사용해 서비스가 선택할 클러스터를 제한할 수 있어요. 참고: 로컬 클러스터의 서비스에는 이 레이블이 추가되지 않아요. |
엔드포인트 정보(About endpoints)
- 엔드포인트 리소스는 수동으로 만들거나 관리하지 마세요. Tigera 컨트롤러가 모든 작업을 처리하게 두세요. 사용자가 엔드포인트 리소스를 수정하면 무시돼요.
- 엔드포인트는 페더레이션 서비스의 서비스 포트 이름과 프로토콜이 백킹 서비스의 포트 이름과 프로토콜과 일치할 때만 선택돼요.
- 페더레이션 서비스에 구성된 엔드포인트 데이터는 백킹 서비스의 원본 데이터에서 약간 수정된 형태예요. 원격 클러스터의 백킹 서비스의 경우, 페더레이션 서비스의
targetRef.name필드에<원본 이름>이 추가돼요. 예를 들어<Remote Cluster Configuration 이름>/<원본 이름>처럼 돼요.
시작하기 전에(Before you begin)
필수 사항
방법(How to)
서비스 리소스 만들기(Create service resources)
메시 내에서 특정 서비스를 제공하는 각 클러스터에서, 다음 요구 사항에 따라 평소처럼 서비스 리소스를 만들어요:
- 서비스는 모두 같은 네임스페이스에 있어야 해요.
- 클러스터 전반에 걸친 공통 서비스 집합을 식별할 수 있도록 각 서비스에 공통 레이블 키와 값을 구성하세요 (예:
run=my-app).
Kubernetes는 서비스 스펙에 구성된 셀렉터와 일치하는 pod들로 서비스 엔드포인트를 채워 서비스를 관리해요.
페더레이션 서비스 구성(Configure a federated service)
- 애플리케이션을 실행하는 페더레이션 pod 집합에 접근해야 하는 클러스터에서,
spec selector를 비워 둔 채로 해당 클러스터에 서비스를 만들어요. federation.tigera.io/serviceSelector어노테이션을, 이전에 구성한 서비스들을 매칭 레이블 조건(예:run == "my-app")으로 선택하는 Calico Cloud 셀렉터로 설정하세요.
Federated Services Controller가 이 서비스를 관리하며, 어노테이션에 구성된 서비스 셀렉터와 일치하는 모든 서비스들로 서비스 엔드포인트를 채워요.
페더레이션 서비스 접근하기(Access a federated service)
어떤 애플리케이션이든 해당 서비스의 로컬 DNS 이름을 사용해 페더레이션 서비스에 접근할 수 있어요. 페더레이션 서비스에 접근하는 가장 간단한 방법은 그에 대응하는 DNS 이름을 이용하는 거예요.
기본적으로 Kubernetes는 로컬에서 서비스에 접근하기 위한 DNS 엔트리를 추가해요. 네임스페이스 my-namespace의 my-svc라는 서비스의 경우, 로컬 클러스터 내에서 서비스에 접근하기 위해 다음 DNS 엔트리가 추가돼요:
my-svc.my-namespace.svc.cluster.local
이 이름에 대한 DNS 조회는 페더레이션 서비스에 할당된 고정 ClusterIP 주소를 반환해요. 이 ClusterIP는 iptables에서 페더레이션 서비스 엔드포인트 IP 중 하나로 변환되고, 모든 엔드포인트에 걸쳐 로드 밸런싱돼요.
튜토리얼(Tutorial)
서비스 만들기(Create a service)
다음 예에서 원격 클러스터는 아래와 같은 서비스를 정의해요.
apiVersion: v1
kind: Service
metadata:
labels:
run: my-app
name: my-app
namespace: default
spec:
selector:
run: my-app
ports:
- name: my-app-ui
port: 80
protocol: TCP
targetPort: 9000
- name: my-app-console
port: 81
protocol: TCP
targetPort: 9001
type: ClusterIP
이 서비스 정의는 애플리케이션 my-app을 위해 두 개의 포트를 노출해요. 하나는 UI에 접근하기 위한 포트이고, 다른 하나는 관리 콘솔에 접근하기 위한 포트예요. 이 서비스는 Kubernetes 셀렉터를 지정하고 있어서, 이 서비스의 엔드포인트는 서비스 자신의 클러스터 내에서 일치하는 pod들로 Kubernetes가 자동으로 채워요.
페더레이션 서비스 만들기(Create a federated service)
로컬과 원격 서비스 모두의 웹 접근 포트를 페더레이션하는 페더레이션 서비스를 로컬 클러스터에 만들려면, 로컬 클러스터에 다음과 같이 서비스 리소스를 만들면 돼요:
apiVersion: v1
kind: Service
metadata:
name: my-app-federated
namespace: default
annotations:
federation.tigera.io/serviceSelector: run == "my-app"
spec:
ports:
- name: my-app-ui
port: 8080
protocol: TCP
type: ClusterIP
spec.selector가 지정되지 않았으므로 Kubernetes가 관리하지 않아요. 대신 federation.tigera.io/selector 어노테이션을 사용해, 이것이 Federated Services Controller가 관리하는 페더레이션 서비스임을 나타내요.
컨트롤러는 로컬과 원격 클러스터 양쪽에서 my-app 서비스들(run 레이블과 일치)을 매칭하고, 그 두 서비스의 my-app-ui TCP 포트에 대한 엔드포인트를 통합해요. 페더레이션 서비스가 my-app-console 포트를 지정하지 않았기 때문에, 컨트롤러는 이 포트의 엔드포인트를 페더레이션 서비스에 포함하지 않아요.
페더레이션 서비스의 엔드포인트 데이터는 다음과 비슷해요. targetRef.name에 원격 클러스터의 이름이 포함된 점에 주목하세요.
apiVersion: v1
kind: Endpoints
metadata:
creationTimestamp: 2018-07-03T19:41:38Z
annotations:
federation.tigera.io/serviceSelector: run == "my-app"
name: my-app-federated
namespace: default
resourceVersion: '701812'
selfLink: /api/v1/namespaces/default/endpoints/my-app-federated
uid: 1a0427e8-7ef9-11e8-a24c-0259d75c6290
subsets:
- addresses:
- ip: 192.168.93.12
nodeName: node1.localcluster.tigera.io
targetRef:
kind: Pod
name: my-app-59cf48cdc7-frf2t
namespace: default
resourceVersion: '701655'
uid: 19f5e914-7ef9-11e8-a24c-0259d75c6290
ports:
- name: my-app-ui
port: 80
protocol: TCP
- addresses:
- ip: 192.168.0.28
nodeName: node1.remotecluster.tigera.io
targetRef:
kind: Pod
name: remotecluster/my-app-7b6f758bd5-ctgbh
namespace: default
resourceVersion: '701648'
uid: 19e2c841-7ef9-11e8-a24c-0259d75c6290
ports:
- name: my-app-ui
port: 80
protocol: TCP
추가 리소스(Additional resources)
더 알아보기 (Learn more)
페더레이션 서비스를 구성하기 전에 반드시 페더레이션 엔드포인트 아이덴티티(kubeconfig 교환)를 먼저 세팅해야 해요. 클러스터 간 네임스페이스 이름 연결이 이 패턴의 핵심 전제라는 점을 꼭 기억하세요.