Kubernetes CRD로 구성 항목 관리
Kubernetes CRD로 구성 항목 관리
Kubernetes 커스텀 리소스(Custom Resource)로 Consul 구성 항목(configuration entries)을 관리하는 방법을 설명하는 문서예요. 구성 항목은 서비스 메시에 대한 클러스터 전체 기본값을 제공해요.
출처: 문서
본문
이 주제는 Kubernetes 커스텀 리소스로 Consul 구성 항목을 관리하는 방법을 설명해요. 구성 항목은 서비스 메시에 클러스터 전체 기본값을 제공해요.
지원되는 구성 항목 (Supported configuration entries)
kind 필드에 다음 값을 지정할 수 있어요:
MeshExportedServicesPeeringAcceptorPeeringDialerProxyDefaultsRegistrationSamenessGroupServiceDefaultsServiceSplitterServiceRouterServiceResolverServiceIntentionsIngressGatewayTerminatingGateway
설치 (Installation)
Helm 차트의 최소 버전(0.28.0)을 설치했는지 확인하세요.
$ Helm search repo hashicorp/consul
NAME CHART VERSION APP VERSION DESCRIPTION
hashicorp/consul 0.28.0 1.9.1 Official HashiCorp Consul Chart
필요하다면 Helm 리포지토리 캐시를 업데이트해요.
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "hashicorp" chart repository
Update Complete. ⎈Happy Helming!⎈
추가 설치 지침은 Helm 차트로 설치를 참고하세요.
참고: 구성 항목은 connectInject가 활성화되어 있어야 하는데, 이는 공식 Helm 차트의 기본 동작이에요. 이 설정을 비활성화했다면 CRD를 사용하려면 다시 활성화해야 해요.
사용법 (Usage)
설치 후 kubectl을 사용해 Consul의 구성 항목을 만들고 관리해요.
생성 (Create)
kubectl apply로 구성 항목을 만들어요.
$ cat <<EOF | kubectl apply --filename -
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: foo
spec:
protocol: "http"
EOF
servicedefaults.consul.hashicorp.com/foo created
상세 스키마 문서는 구성 항목을 참고하세요.
조회 (Get)
kubectl get [kind] [name]을 사용해 구성 항목의 상태를 가져와요.
$ kubectl get servicedefaults foo
NAME SYNCED
foo True
SYNCED 상태는 구성 항목이 Consul에 성공적으로 생성되었는지 여부를 보여줘요.
상세 조회 (Describe)
kubectl describe [kind] [name]을 사용해 구성 항목의 상태를 조사해요. SYNCED가 false라면 상태에 그 이유가 포함돼요.
$ kubectl describe servicedefaults foo
Status:
Conditions:
Last Transition Time: 2020-10-09T21:15:50Z
Status: True
Type: Synced
편집 (Edit)
kubectl edit [kind] [name]을 사용해 구성 항목을 편집해요.
$ kubectl edit servicedefaults foo
# change protocol: http => protocol: tcp
servicedefaults.consul.hashicorp.com/foo edited
그런 다음 kubectl get을 사용해 변경 사항이 Consul에 동기화되었는지 확인할 수 있어요.
$ kubectl get servicedefaults foo
NAME SYNCED
foo True
삭제 (Delete)
kubectl delete [kind] [name]을 사용해 구성 항목을 삭제해요.
$ kubectl delete servicedefaults foo
servicedefaults.consul.hashicorp.com "foo" deleted
kubectl get을 사용해 구성 항목이 삭제되었는지 확인해요.
$ kubectl get servicedefaults foo
Error from server (NotFound): servicedefaults.consul.hashicorp.com "foo" not found
삭제가 멈추는 경우 (Delete hanging)
kubectl delete를 실행했는데 종료되지 않고 멈추면, 대상 구성 항목의 삭제를 막는 종속 구성 항목이 Consul에 등록되어 있을 수 있어요. 예를 들어 ServiceDefaults에서 서비스의 프로토콜을 http로 설정한 다음 ServiceSplitter를 만들면 ServiceDefaults를 삭제할 수 없어요. ServiceDefaults 구성을 삭제하면 프로토콜이 기본값인 tcp로 돌아가기 때문이에요. ServiceSplitter는 서비스가 http 프로토콜을 가질 것을 요구하므로, ServiceDefaults를 삭제하면 Consul이 깨진 상태가 되기 때문에 Consul이 이를 허용하지 않아요.
ServiceDefaults 구성을 삭제하려면 먼저 ServiceSplitter를 삭제해야 해요.
Kubernetes 네임스페이스 (Kubernetes namespaces)
Consul CE
Consul Community Edition(Consul CE)은 Kubernetes 네임스페이스를 무시하고 이름에 따라 모든 서비스를 동일한 전역 Consul 레지스트리에 등록해요. 예를 들어 Kubernetes 네임스페이스 web-ns의 서비스 web과 Kubernetes 네임스페이스 admin-ns의 서비스 admin은 Kubernetes 소스 네임스페이스가 무시된 채 web과 admin으로 Consul에 등록돼요.
이 서비스들을 구성하는 커스텀 리소스를 만들 때 커스텀 리소스의 네임스페이스도 무시돼요. 예를 들어 web 서비스가 실제로 web-ns 네임스페이스에서 실행되고 있더라도(비록 권장되지는 않지만) Kubernetes 네임스페이스 admin-ns에 서비스 web에 대한 ServiceDefaults 커스텀 리소스를 만들 수 있어요:
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: web
namespace: admin-ns
spec:
protocol: http
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: web-ns
spec: ...
참고 서로 다른 Kubernetes 네임스페이스에 동일한
kind와name값을 가진 커스텀 리소스 두 개를 만들면, 나중에 만든 쪽은 동기화할 수 없어요.
ServiceIntentions 특수 사례 (ServiceIntentions special case)
ServiceIntentions는 리소스의 이름이 중요하지 않다는 점에서 다른 커스텀 리소스와 달라요. 다른 리소스의 경우 리소스 이름이 어떤 서비스를 구성하는지 결정해요. 예를 들어 이 리소스는 서비스 web을 구성해요:
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: web
spec:
protocol: http
ServiceIntentions의 경우 와일드카드 인텐션(예: foo => * (allow)는 foo가 어떤 서비스와도 통신할 수 있다는 뜻)을 만들 수 있는 능력을 지원해야 하고, *는 유효한 Kubernetes 리소스 이름이 아니기 때문에, 대신 spec.destination.name 필드를 사용해 인텐션의 대상 서비스를 구성해요:
# foo => * (allow)
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
name: name-does-not-matter
spec:
destination:
name: '*'
sources:
- name: foo
action: allow
---
# foo => web (allow)
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
name: name-does-not-matter
spec:
destination:
name: web
sources:
- name: foo
action: allow
두 개의 ServiceIntentions 리소스가 동일한 spec.destination.name을 설정하면, 나중에 만든 리소스는 동기화되지 않아요.
Consul Enterprise
Consul Enterprise는 Kubernetes 네임스페이스가 Consul 네임스페이스로 매핑되는 방식을 여러 가지로 구성할 수 있어요. 커스텀 리소스가 등록되는 Consul 네임스페이스는 사용 중인 구성에 따라 달라지지만, 일반적으로 커스텀 리소스는 그것이 구성하는 서비스와 동일한 Kubernetes 네임스페이스에 만들어야 해요.
각 구성에 대한 세부 사항은 다음과 같아요:
- 미러링 (Mirroring) - Kubernetes 네임스페이스가 Consul로 미러링돼요. 예를 들어 Kubernetes 네임스페이스
web-ns의 서비스web은 Consul 네임스페이스web-ns의 서비스web으로 등록돼요. 마찬가지로 Kubernetes 네임스페이스web-ns의 이름web을 가진ServiceDefaults커스텀 리소스가 동일한 서비스를 구성해요. 이는connectInject.consulNamespaces로 구성돼요:
global:
name: consul
enableConsulNamespaces: true
image: hashicorp/consul-enterprise:<tag>-ent
connectInject:
consulNamespaces:
mirroringK8S: true
- 접두사가 있는 미러링 (Mirroring with prefix) - Kubernetes 네임스페이스가 Consul 네임스페이스에 접두사가 추가된 채로 미러링돼요. 예를 들어 접두사가
k8s-라면 Kubernetes 네임스페이스web-ns의 서비스web은 Consul 네임스페이스k8s-web-ns의 서비스web으로 등록돼요. 마찬가지로 Kubernetes 네임스페이스web-ns의 이름web을 가진ServiceDefaults커스텀 리소스가 동일한 서비스를 구성해요. 이는connectInject.consulNamespaces로 구성돼요:
global:
name: consul
enableConsulNamespaces: true
image: hashicorp/consul-enterprise:<tag>-ent
connectInject:
consulNamespaces:
mirroringK8S: true
mirroringK8SPrefix: k8s-
- 단일 대상 네임스페이스 (Single destination namespace) - Kubernetes 네임스페이스가 무시되고 모든 서비스가 동일한 Consul 네임스페이스에 등록돼요. 예를 들어 대상 Consul 네임스페이스가
my-ns라면 Kubernetes 네임스페이스web-ns의 서비스web은 Consul 네임스페이스my-ns의 서비스web으로 등록돼요. 이 구성에서는 커스텀 리소스의 Kubernetes 네임스페이스가 무시돼요. 예를 들어 Kubernetes 네임스페이스admin-ns의 이름web을 가진ServiceDefaults커스텀 리소스는, 그 서비스가 Kubernetes 네임스페이스web-ns에서 실행 중이더라도 이름web인 서비스를 구성해요. 왜냐하면ServiceDefaults리소스가 결국 동일한 Consul 네임스페이스my-ns에 등록되기 때문이에요. 이는connectInject.consulNamespaces로 구성돼요:
global:
name: consul
enableConsulNamespaces: true
image: hashicorp/consul-enterprise:<tag>-ent
connectInject:
consulNamespaces:
consulDestinationNamespace: 'my-ns'
참고: 이 구성에서는 두 Kubernetes 네임스페이스에 동일한 name과 kind 값을 가진 커스텀 리소스 두 개를 만들면, 나중에 만든 리소스는 동기화되지 않아요.
ServiceIntentions 특수 사례 (엔터프라이즈) (ServiceIntentions Special Case)
ServiceIntentions는 리소스의 이름이 중요하지 않다는 점에서 다른 커스텀 리소스와 달라요. 다른 리소스의 경우 리소스 이름이 어떤 서비스를 구성하는지 결정해요. 예를 들어 이 리소스는 서비스 web을 구성해요:
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: web
spec:
protocol: http
ServiceIntentions의 경우 와일드카드 인텐션(예: foo => * (allow)는 foo가 어떤 서비스와도 통신할 수 있다는 뜻)을 만들 수 있는 능력을 지원해야 하고, *는 유효한 Kubernetes 리소스 이름이 아니기 때문에, 대신 spec.destination.name 필드를 사용해 인텐션의 대상 서비스를 구성해요:
# foo => * (allow)
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
name: name-does-not-matter
spec:
destination:
name: '*'
sources:
- name: foo
action: allow
---
# foo => web (allow)
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
name: name-does-not-matter
spec:
destination:
name: web
sources:
- name: foo
action: allow
또한 대상 서비스의 Consul 네임스페이스를 구성하기 위해 spec.destination.namespace 필드를 지원해요. spec.destination.namespace가 비어 있으면 위에 설명된 다른 구성 항목과 동일한 Consul 네임스페이스가 사용돼요.