Kubernetes 서비스 메시 워크로드 시나리오
Kubernetes 서비스 메시 워크로드 시나리오
이 문서에서는 여러 시나리오(멀티포트 배포 포함)에서 Kubernetes의 워크로드를 Consul 서비스 메시에 등록하는 예제 워크플로를 설명해 드려요. 각 시나리오는 특정 Kubernetes 워크로드 유형과 함께 Consul 서비스 메시를 사용하는 방법을 보여주는 예제 Kubernetes 매니페스트를 제공합니다.
참고: Consul 서비스 메시에 서비스를 등록하려면 Kubernetes Service가 필요해요. Consul은 서비스 객체를 사용해 Kubernetes Service와 그 서비스 인스턴스의 수명 주기를 모니터링합니다. 또한 Kubernetes 서비스는 Consul 카탈로그에서 서비스를 등록하고 등록 해제하는 데 사용됩니다.
출처: 문서
본문
Deployment로 실행되는 Kubernetes Pod
다음 예시는 static-server 서비스에 대해 서비스 메시 연결을 구체적으로 활성화하는 Kubernetes 구성을 보여줘요. Consul은 기본적으로 20000 포트에서 리슨하고 유효한 인바운드 연결을 8080 포트로 프록시하는 사이드카를 시작하고 등록합니다.
static-server.yaml
apiVersion: v1
kind: Service
metadata:
# This name will be the service name in Consul.
name: static-server
spec:
selector:
app: static-server
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: static-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: static-server
spec:
replicas: 1
selector:
matchLabels:
app: static-server
template:
metadata:
name: static-server
labels:
app: static-server
annotations:
'consul.hashicorp.com/connect-inject': 'true'
spec:
containers:
- name: static-server
image: hashicorp/http-echo:latest
args:
- -text="hello world"
- -listen=:8080
ports:
- containerPort: 8080
name: http
# If ACLs are enabled, the serviceAccountName must match the Consul service name.
serviceAccountName: static-server
서비스 메시를 사용하여 업스트림 Pod에 연결하려면 클라이언트가 메시 프록시를 통해 업스트림 워크로드에 연결해야 해요. 클라이언트 메시 프록시는 Consul 서비스 디스커버리를 사용해 모든 가용 업스트림 프록시와 그 공개 포트를 찾습니다.
메시 활성화 서비스에 연결하기
아래의 예제 Deployment 사양은 이전 예시인 "static-server" 서비스에 연결할 수 있는 Deployment를 구성해요. 이 정적 텍스트 서비스로의 연결은 서비스 메시를 통해 권한 부여되고 암호화된 연결로 이루어집니다.
static-client.yaml
apiVersion: v1
kind: Service
metadata:
# This name will be the service name in Consul.
name: static-client
spec:
selector:
app: static-client
ports:
- port: 80
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: static-client
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: static-client
spec:
replicas: 1
selector:
matchLabels:
app: static-client
template:
metadata:
name: static-client
labels:
app: static-client
annotations:
'consul.hashicorp.com/connect-inject': 'true'
spec:
containers:
- name: static-client
image: curlimages/curl:latest
# Just spin & wait forever, we'll use `kubectl exec` to demo
command: ['/bin/sh', '-c', '--']
args: ['while true; do sleep 30; done;']
# If ACLs are enabled, the serviceAccountName must match the Consul service name.
serviceAccountName: static-client
기본적으로 ACL이 활성화되어 있거나 ACL 기본 정책이 allow일 때, Consul은 동일한 데이터센터의 모든 업스트림으로 프록시를 자동으로 구성해요. ACL이 default deny 정책으로 활성화되어 있다면, 통신해야 하는 업스트림을 Consul에 알려 주는 인텐션(intention)을 제공해야 합니다.
업스트림이 consul.hashicorp.com/connect-service-upstreams 어노테이션으로 명시적으로 지정되면, 인젝터는 정의된 각 업스트림에 대해 파드의 모든 컨테이너에 <NAME>_CONNECT_SERVICE_HOST 및 <NAME>_CONNECT_SERVICE_PORT 환경 변수도 설정해요. 이는 표준 Kubernetes 서비스 환경 변수와 유사하지만, 서비스 메시를 통한 연결을 수립하기 위해 올바른 로컬 프록시 포트를 가리킵니다.
업스트림 어노테이션에 점(dot)이 포함되어 있으면 자동 생성된 환경 변수를 참조할 수 없어요. 이는 Consul이 환경 변수를 점을 포함하도록 렌더링하기 때문입니다. 예를 들어 static-server.svc:8080에 대해 생성된 변수를 Consul이 STATIC-SERVER.SVC_CONNECT_SERVICE_HOST와 STATIC_SERVER.SVC_CONNECT_SERVICE_PORT로 렌더링하여, 해당 변수를 사용할 수 없게 됩니다.
kubectl exec를 사용해 정적 텍스트 서버에 접근할 수 있는지 확인할 수 있어요. 트랜스패런트 프록시가 기본으로 활성화되어 있으므로 Kubernetes DNS를 사용해 원하는 업스트림에 연결하세요.
$ kubectl exec deploy/static-client -- curl --silent http://static-server/
"hello world"
인텐션을 사용하여 서버에 대한 접근을 제어할 수 있어요. Consul UI 또는 CLI를 사용해 "static-client"와 "static-server" 간의 통신을 거부하면, 실행 중인 파드를 갱신하지 않고도 연결이 즉시 거부됩니다. 그런 다음 이 인텐션을 제거하여 다시 연결을 허용할 수 있어요.
$ kubectl exec deploy/static-client -- curl --silent http://static-server/
command terminated with exit code 52
Kubernetes Jobs
Kubernetes Jobs는 메시의 서비스에 아웃바운드 요청만 하고 완료되면 성공적으로 종료되는 파드를 실행해요. Kubernetes Job을 메시에 등록하려면 consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds 어노테이션에 정수 값을 제공해야 합니다. 그런 다음 Job이 완료된 후 Kubernetes가 consul-dataplane 사이드카를 정상적으로 종료하도록 http://127.0.0.1:20600/graceful_shutdown API 엔드포인트에 요청을 보내세요.
아래는 Job을 올바르게 배포하는 예제 Kubernetes 매니페스트예요.
test-job.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: test-job
namespace: default
---
apiVersion: v1
kind: Service
metadata:
name: test-job
namespace: default
spec:
selector:
app: test-job
ports:
- port: 80
---
apiVersion: batch/v1
kind: Job
metadata:
name: test-job
namespace: default
labels:
app: test-job
spec:
template:
metadata:
annotations:
'consul.hashicorp.com/connect-inject': 'true'
'consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds': '5'
labels:
app: test-job
spec:
containers:
- name: test-job
image: alpine/curl:3.14
ports:
- containerPort: 80
command:
- /bin/sh
- -c
- |
echo "Started test job"
sleep 10
echo "Killing proxy"
curl --max-time 2 -s -f -X POST http://127.0.0.1:20600/graceful_shutdown
sleep 10
echo "Ended test job"
serviceAccountName: test-job
restartPolicy: Never
Job을 완료한 후 파드 내의 모든 컨테이너가 종료되었는지 확인할 수 있어요.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
test-job-49st7 0/2 Completed 0 3m55s
$ kubectl get job
NAME COMPLETIONS DURATION AGE
test-job 1/1 30s 4m31s
또한 파드가 출력한 로그를 기반으로 Job이 완료되기 전에 프록시가 종료되었는지 확인할 수 있어요.
$ kubectl logs test-job-49st7 -c test-job
Started test job
Killing proxy
Ended test job
여러 포트를 가진 Kubernetes Pod
여러 포트를 가진 Pod를 서비스 메시에 추가하려면, 명명된 포트를 노출하는 단일 Kubernetes Service를 만들고 하나의 서비스 어카운트로 등록하세요. Consul은 Pod를 각 명명된 포트로 메시 트래픽을 라우팅하는 단일 멀티포트 서비스로 등록해요. 멀티포트 서비스 등록에는 Consul Enterprise가 필요합니다. Enterprise
단계별 지침, 예제 매니페스트, 그리고 트랜스패런트 프록시 활성화/비활성화 상태의 연결 예시는 Kubernetes에서 멀티포트 서비스 구성 문서를 참고하세요. 모든 플랫폼에 적용되는 일반적인 멀티포트 개념과 한계는 멀티포트 서비스 문서를 참고해 주세요.