Kubernetes 서비스와 Consul 서비스 동기화
Kubernetes 서비스와 Consul 서비스 동기화 (Sync Kubernetes and Consul services)
Kubernetes와 Consul의 서비스를 자동으로 동기화하여 Kubernetes 서비스가 Consul 에이전트에 제공되고 Consul의 서비스를 일급 Kubernetes 서비스로 사용할 수 있어요. 이 기능은 consul-k8s 프로젝트에서 제공하며 Consul K8s Helm 차트를 사용해 자동으로 설치하고 구성할 수 있어요.
출처: 문서
본문
Kubernetes와 Consul의 서비스를 자동으로 동기화하여 Kubernetes 서비스가 Consul 에이전트에 제공되고 Consul의 서비스를 일급 Kubernetes 서비스로 사용할 수 있습니다. 이 기능은 consul-k8s 프로젝트에서 제공하며 Consul K8s Helm 차트를 사용해 자동으로 설치하고 구성할 수 있습니다.
Kubernetes 서비스를 Consul로 동기화하는 이유는 무엇인가요? Consul 카탈로그로 동기화된 Kubernetes 서비스는 다른 별도의 Kubernetes 클러스터를 포함한 Consul 클러스터의 일부인 모든 노드에서 Kubernetes 서비스에 액세스할 수 있게 합니다. Kubernetes가 아닌 노드의 경우 표준 Consul DNS 또는 HTTP API를 사용해 서비스에 액세스할 수 있습니다.
Consul 서비스를 Kubernetes로 동기화하는 이유는 무엇인가요? Consul 서비스를 Kubernetes 서비스로 동기화하면 Kubernetes가 아닌 서비스를 kube-dns 및 Kubernetes 고유 환경 변수를 사용해 액세스할 수 있게 됩니다. 이 통합을 통해 데이터베이스 같은 호스팅 서비스를 포함한 외부 서비스 검색을 매우 쉽게 자동화할 수 있습니다.
설치 및 구성 (Installation and configuration)
동일한 Kubernetes 서비스에서 Service Mesh와 Service Sync를 모두 활성화하는 것은 지원되지 않습니다. Service Mesh도 Kubernetes 서비스 인스턴스를 Consul에 등록하기 때문입니다. Sync Enable/Disable에서 설명한 대로 Service Sync가 Service Mesh용 Consul 사이드카로 주입되지 않는 네임스페이스와 서비스에만 활성화되도록 하세요.
서비스 동기화 기능은 Kubernetes 클러스터 내부 또는 외부에서 실행할 수 있는 장기 실행 프로세스를 배포합니다. 그러나 이 프로세스를 Kubernetes 클러스터 내에서 실행하는 것이 일반적으로 더 쉽습니다. Helm 차트를 사용해 자동화되기 때문입니다.
Consul 서버 클러스터는 Kubernetes 클러스터 내부 또는 외부에서 실행할 수 있습니다. Consul 서버 클러스터가 동기화 프로세스와 같은 머신 또는 같은 플랫폼에서 실행될 필요는 없습니다. 동기화 프로세스에는 Consul 에이전트의 주소와 ACL 토큰 같은 추가 액세스 정보를 구성해야 합니다.
동기화 프로세스를 설치하려면 Helm 값을 사용해 카탈로그 동기화 기능을 활성화하고, 기존 설치에는 helm upgrade를, 새 설치에는 helm install을 사용해 설치를 업그레이드하세요.
syncCatalog:
enabled: true
이 값은 양방향으로 서비스 동기화를 활성화합니다. 또한 한 방향을 비활성화하여 Kubernetes 서비스만 Consul로 동기화하거나 Consul 서비스만 Kubernetes로 동기화할 수도 있습니다.
Consul 서비스를 Kubernetes로만 동기화하려면 다음 구성을 사용하세요:
syncCatalog:
enabled: true
toConsul: false
toK8S: true
Kubernetes 서비스를 Consul로만 동기화하려면 다음을 사용하세요:
syncCatalog:
enabled: true
toConsul: true
toK8S: false
자세한 내용은 Helm 구성을 참조하세요.
인증 (Authentication)
동기화 프로세스는 서비스를 읽고 쓰기 위해 Kubernetes와 Consul 양쪽에 인증해야 합니다.
Helm 차트를 사용해 consul-k8s를 실행하는 경우 이 인증은 알아서 처리됩니다.
Kubernetes 외부에서 consul-k8s를 실행하는 경우 클러스터 및 인증 정보가 포함된 유효한 kubeconfig 파일을 제공해야 합니다. 동기화 프로세스는 클러스터 내부 및 외부 인증 모두에 대해 기본 위치를 확인합니다. kubectl이 작동한다면 동기화 프로그램도 작동해야 합니다.
Consul 클러스터에 ACL이 구성된 경우 Consul ACL 토큰을 제공해야 합니다. 이 토큰을 만들 때 ACL 규칙을 검토하여 필요한 권한만 허용하도록 하세요. 카탈로그 동기화 프로세스는 CONSUL_HTTP_TOKEN 환경 변수를 사용해 이 토큰을 허용합니다. 이 토큰은 Kubernetes 시크릿으로 설정하고 Helm 차트에서 참조해야 합니다.
Kubernetes에서 Consul로 (Kubernetes to Consul)
이 동기화는 Kubernetes 서비스를 Consul 카탈로그에 자동으로 등록합니다.
이 동기화를 통해 DNS나 HTTP 같은 기본 Consul 서비스 검색 프로토콜을 사용해 Kubernetes 서비스를 검색하고 연결할 수 있습니다. 이는 특히 Kubernetes가 아닌 노드에 유용합니다. 또한 검색 가능한 모든 서비스가 Consul의 중앙 서비스 카탈로그의 일부가 되어 다른 Kubernetes 클러스터나 다른 플랫폼으로 추가 동기화할 수 있게 합니다.
각 동기화된 서비스는 k8s-sync라는 Consul 노드에 등록됩니다. 이 노드는 실제 노드가 아닙니다. 대신 카탈로그 동기화 프로세스가 Kubernetes를 모니터링하고 서비스를 Consul로 동기화합니다.
Kubernetes 서비스 유형 (Kubernetes service types)
모든 Kubernetes 서비스가 외부에서 액세스 가능한 것은 아닙니다. 동기화 프로그램은 기본적으로 다음 유형 또는 구성을 가진 서비스만 동기화합니다. 서비스 유형이 아래에 나열되지 않으면 동기화 프로그램은 해당 서비스 유형을 무시합니다.
NodePort
NodePort 서비스는 K8S 클러스터의 모든 노드가 수신하는 정적 포트를 등록합니다.
NodePort 서비스의 경우 대표 포드가 실행 중인 각 노드에 대해 Consul 서비스 인스턴스가 생성됩니다. Kubernetes가 클러스터의 모든 노드에 정적 포트를 구성하지만 이는 서비스 인스턴스 수를 대상 포드를 실행하는 노드 수와 동일하도록 제한합니다. 기본적으로 노드의 외부 IP를 사용하지만 nodePortSyncType helm 옵션으로 구성할 수 있습니다.
서비스 인스턴스의 포트는 consul.hashicorp.com/service-port 어노테이션에서 특별히 설정하지 않는 한 서비스의 첫 번째 정의된 노드 포트로 설정됩니다. 자세한 내용은 서비스 포트를 참조하세요.
LoadBalancer
LoadBalancer 서비스의 경우 생성된 로드 밸런서의 외부 IP로 단일 서비스 인스턴스가 등록됩니다. 이미 로드 밸런서이므로 개별 포드 엔드포인트를 각각 등록하는 대신 단일 서비스 인스턴스만 Consul에 등록됩니다.
서비스 인스턴스의 포트는 consul.hashicorp.com/service-port 어노테이션에서 특별히 설정하지 않는 한 서비스의 첫 번째 정의된 포트로 설정됩니다. 자세한 내용은 서비스 포트를 참조하세요.
외부 IP (External IPs)
모든 서비스 유형은 "외부 IP" 구성을 지정할 수 있습니다. 외부 IP는 다른 시스템으로 구성해야 하지만 모든 서비스 검색은 가상 IP 대신 이 IP 주소 집합으로 해석됩니다.
외부 IP 목록이 있으면 각 외부 IP에 대해 Consul에 서비스 인스턴스가 생성됩니다. 외부 IP가 있으면 라우팅 가능하고 다른 시스템에서 구성된 것으로 간주합니다.
서비스 인스턴스의 포트는 consul.hashicorp.com/service-port 어노테이션으로 특별히 설정하지 않는 한 서비스의 첫 번째 정의된 포트로 설정됩니다. 자세한 내용은 서비스 포트를 참조하세요.
ClusterIP
ClusterIP 서비스는 consul-k8s 버전 0.3.0부터 기본적으로 동기화됩니다. 서비스의 엔드포인트인 각 포드는 IP가 포드 IP로, 포트가 targetPort로 설정된 Consul 서비스 인스턴스로 동기화됩니다.
서비스 인스턴스의 포트는 consul.hashicorp.com/service-port 어노테이션으로 재정의할 수 있습니다. 자세한 내용은 서비스 포트를 참조하세요.
포드 IP가 클러스터 외부에서 액세스할 수 없는 Kubernetes 클러스터에서는 Consul에 등록된 서비스가 라우팅되지 않을 수 있습니다. ClusterIP 서비스 동기화를 건너뛰려면 Helm 차트 값 파일에서 syncClusterIPServices를 false로 설정하세요.
동기화 활성화 및 비활성화 (Enable and disable sync)
기본적으로 kube-system과 kube-public을 제외한 모든 Kubernetes 네임스페이스의 모든 유효한 서비스 유형이 동기화됩니다.
특정 서비스만 동기화하려면 먼저 어노테이션을 수정하여 기본값을 false로 설정하세요:
syncCatalog:
enabled: true
default: false
그런 다음 consul.hashicorp.com/service-sync 어노테이션으로 특정 서비스의 동기화를 명시적으로 활성화하세요:
kind: Service
apiVersion: v1
metadata:
name: my-service
annotations:
'consul.hashicorp.com/service-sync': 'true'
참고: 기본 동기화가 true일 때 어노테이션이 false로 설정되면 서비스는 동기화되지 않습니다.
k8sAllowNamespaces와 k8sDenyNamespaces 키를 설정하여 특정 Kubernetes 네임스페이스에서의 동기화를 허용하거나 거부할 수 있습니다:
syncCatalog:
enabled: true
default: true
k8sAllowNamespaces: ['*']
k8sDenyNamespaces: ['kube-system', 'kube-public']
기본 구성에서는 kube-system과 kube-public을 제외한 모든 네임스페이스의 서비스가 동기화됩니다.
특정 네임스페이스에서만 동기화하려면 해당 네임스페이스만 k8sAllowNamespaces 키에 나열할 수 있습니다:
syncCatalog:
enabled: true
default: true
k8sAllowNamespaces: ['my-ns-1', 'my-ns-2']
k8sDenyNamespaces: []
특정 네임스페이스를 제외한 모든 네임스페이스에서 동기화하려면 허용 목록에 *를 사용하고 비동기화 네임스페이스를 거부 목록에 지정하세요:
syncCatalog:
enabled: true
default: true
k8sAllowNamespaces: ['*']
k8sDenyNamespaces: ['no-sync-ns-1', 'no-sync-ns-2']
참고: 거부 목록이 허용 목록보다 우선합니다. 네임스페이스가 두 목록 모두에 있으면 동기화되지 않습니다.
서비스 이름 (Service name)
Kubernetes 서비스가 Consul로 동기화되면 Consul의 서비스 이름은 기본적으로 해당 Kubernetes 서비스의 name 메타데이터 값입니다. 이렇게 하면 서비스 동기화가 구성 변경 없이 작동하도록 합니다. 이 설정은 어노테이션을 사용해 Consul 서비스 이름을 지정하여 재정의할 수 있습니다:
kind: Service
apiVersion: v1
metadata:
name: my-service
annotations:
'consul.hashicorp.com/service-name': my-consul-service
Consul에 충돌하는 서비스 이름이 있는 경우 동기화 프로그램은 해당 동일한 서비스에 추가 인스턴스를 등록합니다. 따라서 Kubernetes 내부와 외부의 서비스는 어느 한쪽이 잠재적으로 연결되도록 하지 않는 한 서로 다른 이름을 가져야 합니다. 이 기본 동작은 또한 Kubernetes 내부와 외부 배포 간에 서비스를 우아하게 전환할 수 있게 합니다.
서비스 포트 (Service ports)
서비스 검색 기능을 사용할 때 Consul은 카탈로그를 Kubernetes 서비스 카탈로그와 자동으로 동기화합니다. 단일 및 다중 포트 서비스가 모두 지원됩니다. Kubernetes 서비스에 여러 포트가 있으면 consul.hashicorp.com/service-port 어노테이션으로 기본값을 지정하지 않는 한 Consul은 계열의 첫 번째 포트를 서비스의 기본값으로 등록합니다.
Consul 서비스 메시의 경우 카탈로그가 단일 포트에 서비스를 등록해야 합니다. Consul은 서비스 메시 작업에 서비스의 기본 포트를 사용합니다.
다음 예제는 consul.hashicorp.com/service-port 어노테이션으로 기본 서비스 포트를 재정의하는 방법을 보여줍니다. my-service 서비스의 기본 포트를 http로 설정합니다.
kind: Service
apiVersion: v1
metadata:
name: my-service
annotations:
'consul.hashicorp.com/service-port': 'http'
어노테이션 값은 포트의 이름 또는 정확한 포트 값일 수 있습니다. 고유한 이름의 포트를 사용할 것을 권장합니다.
서비스 태그 (Service tags)
Kubernetes에서 Consul에 등록된 서비스에는 항상 "k8s" 태그가 추가됩니다. 추가 태그는 쉼표로 구분된 어노테이션 값으로 지정할 수 있습니다. 이러한 사용자 정의 태그에는 자동으로 "k8s" 태그가 포함되며 비활성화할 수 없습니다. 값을 지정할 때 공백 없이 쉼표를 사용하세요.
kind: Service
apiVersion: v1
metadata:
name: my-service
annotations:
'consul.hashicorp.com/service-tags': 'primary,foo'
서비스 메타 (Service meta)
Kubernetes에서 Consul에 등록된 서비스는 external-source 키를 kubernetes로 설정합니다. 이는 API, CLI, UI에서 k8s에 설정된 서비스 인스턴스를 필터링하는 데 사용할 수 있습니다. Consul UI는 Kubernetes에서 외부 등록된 모든 서비스 옆에 Kubernetes 아이콘을 표시합니다.
추가 메타데이터는 어노테이션을 사용해 지정할 수 있습니다. 아래 "KEY"는 어떤 키로도 설정할 수 있습니다. 이를 통해 여러 메타 값을 설정할 수 있습니다.
kind: Service
apiVersion: v1
metadata:
name: my-service
annotations:
'consul.hashicorp.com/service-meta-KEY': 'value'
Consul Enterprise 네임스페이스 (Consul Enterprise Namespaces)
Consul Enterprise는 Consul 네임스페이스를 지원합니다. 이는 Kubernetes에서 Consul로 동기화할 때 사용할 수 있습니다. 그러나 Consul에서 Kubernetes로 동기화할 때는 네임스페이스가 지원되지 않습니다.
세 가지 옵션이 있습니다:
-
단일 대상 네임스페이스 (Single Destination Namespace) - 네임스페이스에 관계없이 모든 Kubernetes 서비스를 동일한 Consul 네임스페이스로 동기화합니다.
global: enableConsulNamespaces: true syncCatalog: enabled: true consulNamespaces: consulDestinationNamespace: 'my-consul-ns' -
네임스페이스 미러링 (Mirror Namespaces) - 각 Kubernetes 서비스는 해당 Kubernetes 네임스페이스와 같은 이름의 Consul 네임스페이스로 동기화됩니다.
예를 들어 Kubernetes 네임스페이스 ns-1의 서비스 foo는 Consul 네임스페이스 ns-1로 동기화됩니다. 미러링된 네임스페이스가 Consul에 없으면 자동으로 생성됩니다.
global:
enableConsulNamespaces: true
syncCatalog:
enabled: true
consulNamespaces:
mirroringK8S: true
addK8SNamespaceSuffix: false
-
접두사가 있는 네임스페이스 미러링 (Mirror Namespaces With Prefix) - 각 Kubernetes 서비스는 접두사가 있는 해당 Kubernetes 네임스페이스와 같은 이름의 Consul 네임스페이스로 동기화됩니다. 예를 들어 접두사
k8s-가 주어지면 Kubernetes 네임스페이스ns-1의 서비스foo는 Consul 네임스페이스k8s-ns-1로 동기화됩니다.global: enableConsulNamespaces: true syncCatalog: enabled: true consulNamespaces: mirroringK8S: true mirroringK8SPrefix: 'k8s-' addK8SNamespaceSuffix: false
두 미러링 예제 모두에서 addK8SNamespaceSuffix가 false로 설정됩니다. 기본값인 true로 설정하면 Kubernetes 네임스페이스가 각 Consul 서비스 이름에 접미사로 추가됩니다. 예를 들어 네임스페이스 k8s-ns의 Kubernetes 서비스 foo는 foo-k8s-ns라는 이름으로 Consul에 등록됩니다. 이는 여러 Kubernetes 네임스페이스에서 단일 Consul 네임스페이스로 동기화할 때 유용합니다. 그러나 네임스페이스를 미러링할 때는 서비스가 다른 네임스페이스의 서비스와 겹치지 않도록 이 동작을 비활성화하고 싶을 수 있습니다.
Consul에서 Kubernetes로 (Consul to Kubernetes)
이 동기화는 Consul 서비스를 일급 Kubernetes 서비스로 동기화합니다. 동기화는 각 Consul 서비스에 대해 ExternalName을 생성합니다. "외부 이름"은 Consul DNS 이름입니다.
예를 들어 Consul 서비스 foo가 주어지면:
apiVersion: v1
kind: Service
metadata:
name: foo
...
spec:
externalName: foo.service.consul
type: ExternalName
Consul-to-Kubernetes 동기화가 활성화된 상태에서 <consul-service-name> 형식의 DNS 요청은 Consul DNS로 처리됩니다. Consul이 배포된 위치와 다른 Kubernetes 네임스페이스에서 DNS 요청하려면 <consul-service-name>.<consul-namespace> 형식이어야 합니다.
참고: Kubernetes에서 Consul DNS를 활성화했다면 Consul-to-Kubernetes 동기화는 필요하지 않습니다. <consul-service-name>.service.consul 형식으로 서비스를 주소 지정하기만 하면 되므로 Kubernetes Service 객체를 만들 필요가 없습니다.
Kubernetes의 CoreDNS를 통한 Consul DNS 필요: 이 기능은 Kubernetes 내에 Consul DNS가 구성되어 있어야 합니다. 또한 사용자 정의 도메인을 가리키는 externalName 서비스 해석 문제를 해결하려면 kube-dns 대신 CoreDNS가 필요합니다.
동기화 활성화 및 비활성화 (Enable and disable sync)
주어진 ACL 토큰을 기준으로 동기화 프로세스에 표시되는 모든 Consul 서비스가 Kubernetes로 동기화됩니다.
이 동작을 서비스별로 변경할 수는 없습니다. 반대 동기화 방향(Kubernetes에서 Consul로)에서는 Kubernetes 어노테이션을 사용해 서비스별 동기화를 비활성화할 수 있습니다. 이는 현재 Consul-to-Kubernetes 동기화에서는 불가능하며 ACL 토큰을 사용해 어떤 서비스가 동기화되는지 제한해야 합니다.
향후에는 서비스별 구성을 지원할 예정입니다.
서비스 이름 (Service Name)
Consul 서비스가 Kubernetes로 동기화되면 Kubernetes 서비스의 이름은 Consul 서비스의 이름과 정확히 일치합니다.
이 기본 정확 일치 동작을 변경하려면 -k8s-service-prefix 플래그를 사용해 Kubernetes 내 서비스 이름에 추가할 접두사를 지정할 수 있습니다. 이는 Helm 구성에서도 지정할 수 있습니다.
충돌하는 서비스가 발견된 경우: 서비스는 동기화되지 않습니다. 이는 Kubernetes-to-Consul 동작과는 다릅니다. 그러나 현재 구현에서는 Kubernetes가 CNAME 기반 서비스와 Endpoint 기반 서비스를 혼합할 수 없기 때문에 이렇게 해야 합니다.
Kubernetes 서비스 라벨 및 어노테이션 (Kubernetes service labels and annotations)
Kubernetes로 동기화된 모든 Consul 서비스에는 라벨과 어노테이션이 지정됩니다. 이 서비스가 Consul에서 온 동기화된 서비스임을 나타내기 위해 consul.hashicorp.com/synced 어노테이션이 true로 설정됩니다.
추가로 consul=true 라벨이 지정되어 kubectl 및 기타 도구에서 라벨 선택기를 사용해 모든 Consul 동기화 서비스를 쉽게 필터링할 수 있습니다.