Terminating Gateway로 외부 서비스 등록
Terminating Gateway로 외부 서비스 등록
Consul terminating gateway는 서비스 메시 외부의 애플리케이션과 서비스와 안전하게 통신할 수 있는 능력을 서비스에 제공해요. Amazon RDS 같은 관리형 서비스, 지원되지 않는 OS에서 실행되는 레거시 서비스, 서비스 메시로 전환 중이며 통합 테스트가 필요하거나 다른 레거시 시스템과의 호환성을 유지해야 하는 하이브리드 애플리케이션 등이 일반적인 사용 사례예요.
출처: 문서
본문
Consul terminating gateway는 서비스 메시 외부의 애플리케이션과 서비스와 안전하게 통신할 수 있는 능력을 서비스에 제공합니다. 일반적인 사용 사례에는 관리형 서비스(예: Amazon RDS), 지원되지 않는 OS에서 실행되는 레거시 서비스, 서비스 메시로 전환 중이며 통합 테스트가 필요하거나 다른 레거시 시스템과의 호환성을 유지해야 하는 하이브리드 애플리케이션이 있습니다. 이것은 모든 런타임, 클라우드 또는 온프레미스 환경에서 애플리케이션을 Consul로 안전하게 연결하는 능력을 확장합니다.
Terminating gateway는 그렇지 않으면 대체 보안 및 정책 시행 메커니즘이 필요할 이러한 시나리오에 서비스 메시 확장성을 제공합니다. 이들은 서비스 메시 mTLS 연결을 종료하고, 의도를 시행하며, 요청을 적절한 대상으로 전달합니다.
이 튜토리얼에서는 관리형 AWS RDS 인스턴스와의 안전한 통신을 제공하는 Consul terminating gateway를 배포합니다. HashiCups 데모 애플리케이션의 프런트엔드를 AWS RDS의 HashiCups 백엔드 데이터베이스에 연결합니다. 이 과정에서 이 기능이 서비스 메시 외부 서비스와의 단순하고 안전한 통신을 어떻게 제공하는지 보게 됩니다.
시나리오 개요 (Scenario overview)
HashiCups는 커피숍 데모 애플리케이션입니다. 마이크로서비스 아키텍처를 가지며 Consul 서비스 메시를 사용해 서비스를 안전하게 연결합니다. 이 튜토리얼 시작 부분에서 Terraform을 사용해 HashiCups 마이크로서비스, AWS EKS의 자체 관리 Consul 클러스터, HashiCups 데이터베이스를 포함한 관리형 AWS RDS 인스턴스를 배포합니다.
이 튜토리얼에서 다음을 수행합니다.
- Terraform으로 다음 리소스 배포:
- Elastic Kubernetes Service (EKS) 클러스터
- EKS의 자체 관리 Consul 데이터센터
- 관리형 AWS RDS 인스턴스
- EKS의 HashiCups 데모 애플리케이션
- 다음 Consul 절차 수행:
- 데모 애플리케이션 탐색(중단된 상태)
- terminating gateway 기능 검토 및 활성화
- AWS RDS 인스턴스를 Consul 서비스로 등록
- AWS RDS 서비스를 terminating gateway에 구성하고 연결
- AWS RDS와 통신하도록 서비스 메시 애플리케이션 업데이트
- 데모 애플리케이션 탐색(작동하는 상태)
사전 요구 사항 (Prerequisites)
튜토리얼은 Consul과 그 핵심 기능에 익숙하다고 가정합니다. Consul이 처음이라면 Consul Getting Started tutorials collection을 참조하세요.
이 튜토리얼에는 다음이 필요합니다.
- Terraform과 함께 사용하도록 구성된 AWS 계정
- terraform >= 1.0
- consul >= 1.17.0
- consul-k8s >= 1.2.1
- helm >= 3.0
- git >= 2.0
- kubectl > 1.24
GitHub 리포지토리 클론
구성 파일과 리소스를 포함하는 GitHub 리포지토리를 클론하세요.
$ git clone https://github.com/hashicorp-education/learn-consul-terminating-gateways.git
이 튜토리얼의 완전한 구성 파일이 포함된 디렉터리로 들어갑니다.
$ cd learn-consul-terminating-gateways/self-managed/eks
리포지토리 내용 검토
이 리포지토리는 초기 인프라를 시작하기 위한 Terraform 구성과 Consul, 데모 애플리케이션, 관찰성 제품군 리소스를 배포하기 위한 모든 파일을 포함합니다.
eks 디렉터리에는 다음 Terraform 구성 파일이 포함됩니다.
aws-vpc.tf는 AWS VPC 리소스를 정의합니다.aws-lambda.tf는 AWS Lambda 리소스를 정의합니다.aws-rds.tf는 AWS RDS 리소스를 정의합니다.eks-cluster.tf는 Amazon EKS 클러스터 배포 리소스를 정의합니다.eks-consul.tf는 자체 관리 Consul 배포를 정의합니다.eks-hashicups-with-consul.tf는 HashiCups 리소스를 정의합니다.providers.tf는 Terraform용 AWS 및 Kubernetes 공급자 정의를 정의합니다.variables.tf는 튜토리얼을 사용자 지정하는 데 사용할 수 있는 변수를 정의합니다.
또한 디렉터리에는 다음 하위 디렉터리가 포함됩니다.
api-gw는 Consul API 게이트웨이의 Kubernetes 구성 파일을 포함합니다.hashicups는 HashiCups의 Kubernetes 구성 파일을 포함합니다.config는 사용자 지정 Consul ACL 구성 파일, AWS Lambda 데이터베이스 초기화 함수, terminating gateway 구성 파일을 포함합니다.helm은 Consul의 Helm chart를 포함합니다.
인프라 및 데모 애플리케이션 배포
이러한 Terraform 구성 파일로 인프라를 배포할 준비가 되었습니다. 필요한 공급자와 모듈을 다운로드하려면 Terraform 구성을 초기화하세요.
$ terraform init
Initializing the backend...
Initializing provider plugins...
## ...
Terraform has been successfully initialized!
## …
그런 다음 리소스를 배포합니다. yes를 입력해 실행을 확인합니다.
$ terraform apply
## ...
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
## ...
Apply complete! Resources: 103 added, 0 changed, 0 destroyed.
Terraform 배포는 완료하는 데 최대 15분이 걸릴 수 있습니다.
인프라에 연결
Kubernetes 클러스터를 배포했으므로 kubectl이 상호작용하도록 구성하세요.
$ aws eks --region $(terraform output -raw region) update-kubeconfig --name $(terraform output -raw kubernetes_cluster_id)
Consul 데이터센터와 상호작용하도록 CLI 구성
이 섹션에서는 Consul CLI가 Consul 데이터센터와 상호작용할 수 있도록 터미널에서 환경 변수를 설정합니다. Consul CLI는 이러한 환경 변수를 기본 동작으로 읽으며, consul 명령을 실행할 때 이 값을 참조합니다.
Consul 대상 주소를 설정하세요.
$ export CONSUL_HTTP_ADDR=https://$(kubectl get services/consul-ui --namespace consul -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
해당 Kubernetes 시크릿에서 ACL 부트스트랩 토큰을 검색하고 환경 변수로 설정하세요.
$ export CONSUL_HTTP_TOKEN=$(kubectl get --namespace consul secrets/consul-bootstrap-acl-token --template={{.data.token}} | base64 -d)
Consul과의 TLS 통신에 사용할 Consul CA 인증서를 내보냅니다.
$ kubectl get --namespace consul secrets/consul-ca-cert -o json | jq -r '.data."tls.crt"' | base64 -d > ca.crt && \
export CONSUL_CACERT=ca.crt
TLS로 Consul에 연결할 때 SNI 호스트로 사용할 서버 이름을 설정합니다.
$ export CONSUL_TLS_SERVER_NAME=server.dc1.consul
Consul 카탈로그의 모든 알려진 서비스를 인쇄하려면 consul catalog services CLI 명령을 실행하세요.
$ consul catalog services
api-gateway
consul
frontend
frontend-sidecar-proxy
nginx
nginx-sidecar-proxy
payments
payments-sidecar-proxy
product-api
product-api-sidecar-proxy
public-api
public-api-sidecar-proxy
데모 애플리케이션 탐색 (중단된 상태)
이 섹션에서는 데모 애플리케이션을 방문해 HashiCups UI를 탐색합니다.
Consul API 게이트웨이 공용 DNS 주소를 검색합니다.
$ export CONSUL_APIGW_ADDR=http://$(kubectl get svc/api-gateway -o json | jq -r '.status.loadBalancer.ingress[0].hostname') && echo $CONSUL_APIGW_ADDR
http://a4cc3e77d86854fe4bbcc9c62b8d381d-221509817.us-west-2.elb.amazonaws.com
브라우저에서 Consul API 게이트웨이의 URL을 열고 HashiCups UI를 탐색하세요. HashiCups가 중단된 상태이며 백엔드 제품 데이터베이스에서 커피를 검색하지 못하는 것을 확인하세요. 이 동작은 예상된 것입니다. Consul 서비스 메시 내의 HashiCups 프런트엔드 서비스가 기본적으로 외부 백엔드 제품 데이터베이스(AWS RDS)와 안전하게 통신할 수 없기 때문입니다.
Consul terminating gateway 활성화
Consul terminating gateway는 mTLS 연결을 종료하고, Consul 의도를 시행하며, 요청을 적절한 대상 서비스로 전달하여 서비스 메시 애플리케이션에 외부 대상으로의 연결을 제공하는 이그레스 프록시입니다.
이 섹션에서는 이 기능을 활성화하는 매개변수를 검토하고 새 구성을 적용하도록 Consul 설치를 업데이트합니다.
Consul values 파일 검토
아래 values 파일에서 강조된 줄을 검토하여 terminating gateway를 활성화하는 매개변수를 확인하세요.
helm/consul-v2-terminating-gw.yaml
## …
## ...
# Configures and installs the Consul terminating gateway.
terminatingGateways:
# Enable terminating gateway deployment. Requires `connectInject.enabled=true`.
enabled: true
메트릭 구성 옵션과 세부 정보에 대해 알아보려면 Consul metrics for Kubernetes documentation과 공식 Helm chart values를 참조하세요.
terminating gateway를 배포하려면 Consul K8S CLI로 Kubernetes 클러스터의 Consul을 업데이트하세요. y를 입력해 실행을 확인합니다.
$ consul-k8s upgrade -config-file=helm/consul-v2-terminating-gw.yaml
추가 설정에 대해 알아보려면 Consul K8S CLI documentation을 참조하세요.
Consul 업데이트는 완료하는 데 최대 5분이 걸릴 수 있습니다.
이 설정에 대해 더 알아보려면 공식 Helm chart values을 검토하세요.
Consul terminating gateway가 환경에 성공적으로 배포되었는지 확인하세요.
$ kubectl get pods --namespace consul
NAME READY STATUS RESTARTS AGE
consul-connect-injector-7869cf6f69-sqqb4 1/1 Running 0 7m58s
consul-server-0 1/1 Running 0 5m40s
consul-server-1 1/1 Running 0 6m41s
consul-server-2 1/1 Running 0 7m56s
consul-terminating-gateway-d6bfbf5fd-4km4x 1/1 Running 0 7m57s
consul-webhook-cert-manager-7646f7456d-l2z8w 1/1 Running 0 7m57s
AWS RDS 인스턴스를 Consul 서비스로 등록
Consul terminating gateway를 통해 외부 서비스에 도달하려면 외부 서비스를 Consul 카탈로그에 등록해야 합니다.
이 섹션에서는 AWS RDS 인스턴스에 대한 Consul 서비스 구성 파일을 만들고 managed-aws-rds라는 이름으로 Consul 카탈로그에 등록합니다. AWS RDS 사설 DNS 주소를 검색하고 환경 변수로 설정하세요.
$ export AWS_RDS_ENDPOINT=$(terraform output -raw aws_rds_endpoint) && \
echo $AWS_RDS_ENDPOINT
envsubst로 managed-aws-rds에 대한 사용자 지정 Consul 서비스 구성 파일을 만듭니다. 이는 모든 자리 표시자를 고유한 AWS RDS 사설 DNS 주소로 채웁니다.
$ envsubst < config/external-service.template > config/external-service.json
고유한 Consul 서비스 구성 파일을 검토하세요.
config/external-service.json
{
"Node": "AWS RDS",
"Address": "learn-consul-4yyx.cvjehh8zzfhg.us-west-2.rds.amazonaws.com",
"NodeMeta": {
"external-node": "true",
"external-probe": "true"
},
"Service": {
"ID": "managed-aws-rds",
"Service": "managed-aws-rds",
"Tags": ["external", "postgres"],
"Port": 5432
}
}
Consul 서비스 구성 옵션과 세부 정보에 대해 알아보려면 Consul services configuration documentation을 참조하세요.
managed-aws-rds를 Consul의 서비스로 등록합니다.
$ curl -k \
--request PUT \
--data @config/external-service.json \
--header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \
$CONSUL_HTTP_ADDR/v1/catalog/register
외부 managed-aws-rds서비스에 대한 Consul 서비스 기본값을 적용합니다. service-defaults.yaml의 구성은 서비스 메시 내의 서비스가 Consul DNS를 사용해 외부 서비스와 통신할 수 있게 하는 virtual service를 Consul에 생성합니다.
$ kubectl apply --filename config/service-defaults.yaml
Consul이 외부 서비스를 성공적으로 해석하는지 확인합니다.
$ kubectl exec -it svc/consul-server --namespace consul -- /bin/sh -c "nslookup -port=8600 managed-aws-rds.virtual.consul 127.0.0.1"
Defaulted container "consul" out of: consul, locality-init (init)
Server: 127.0.0.1
Address: 127.0.0.1:8600
Name: managed-aws-rds.virtual.consul
Address: 240.0.0.6
Name: managed-aws-rds.virtual.consul
Address: 240.0.0.6
managed-aws-rds.virtual.consul이 멀티캐스트 IP 주소로 해석되며, 이는 managed-aws-rds Consul 서비스의 모든 인스턴스에 대해 일대다 통신을 용이하게 합니다.
AWS RDS 서비스를 terminating gateway에 구성하고 연결
외부 서비스로 트래픽 라우팅을 시작하려면 Consul 보안 시스템을 구성하고 외부 서비스를 terminating gateway에 연결해야 합니다.
이 섹션에서는 메시 내 서비스, terminating gateway, 외부 managed-aws-rds 서비스 사이의 안전한 통신을 허용하도록 Consul ACL과 의도를 구성합니다. 그런 다음 외부 managed-aws-rds 서비스를 terminating gateway에 연결합니다.
먼저 terminating gateway가 managed-aws-rds 서비스와 통신할 수 있게 하는 사용자 지정 ACL 정책을 만듭니다.
$ consul acl policy create -name "managed-aws-rds-write-policy" \
-datacenter "dc1" \
-rules @config/write-acl-policy.hcl
예시 출력:
ID: 56cd0458-2115-3722-22a5-aee974a4edb8
Name: managed-aws-rds-write-policy
Description:
Datacenters:
Rules:
# Set write access for external managed-aws-rds service
service "managed-aws-rds" {
policy = "write"
intentions = "read"
}
자세한 내용은 Consul ACL Policies 문서를 참조하세요.
terminating gateway ACL 역할 ID를 검색하고 환경 변수로 설정합니다.
$ export TGW_ACL_ROLE_ID=$(consul acl role list -format=json | jq --raw-output '[.[] | select(.Name | endswith("-terminating-gateway-acl-role"))] | if (. | length) == 1 then (. | first | .ID) else "Unable to determine the role ID because there are multiple roles matching this name.\n" | halt_error end')
사용자 지정 ACL 정책을 terminating gateway 역할에 연결합니다.
$ consul acl role update -id $TGW_ACL_ROLE_ID \
-datacenter "dc1" \
-policy-name managed-aws-rds-write-policy
예시 출력:
ID: af87a7bb-660b-8d7b-39ea-e909c13779e7
Name: consul-terminating-gateway-acl-role
Description: ACL Role for consul-terminating-gateway
Policies:
054eccc4-e379-6aa7-a36d-ebf0fd0ce02f - terminating-gateway-policy
56cd0458-2115-3722-22a5-aee974a4edb8 - managed-aws-rds-write-policy
product-api 서비스에서 managed-aws-rds 서비스로의 통신을 허용하는 의도를 만듭니다. 이 의도는 HashiCups 프런트엔드 서비스에서 HashiCups 백엔드 데이터베이스 서비스로 트래픽이 흐를 수 있게 합니다.
$ kubectl apply --filename config/service-intentions.yaml
serviceintentions.consul.hashicorp.com/managed-aws-rds created
terminating-gateway.yaml CRD를 클러스터에 적용해 managed-aws-rds용 terminating gateway를 배포합니다.
$ kubectl apply --filename config/terminating-gateway.yaml
terminatinggateway.consul.hashicorp.com/terminating-gateway created
서비스 메시 애플리케이션을 외부 서비스와 통신하도록 업데이트
서비스 메시 애플리케이션을 구성하려면 해당 Consul 가상 주소를 관련 애플리케이션 연결 매개변수에 구성해야 합니다.
이 섹션에서는 product-api 서비스 메시 애플리케이션을 배포하여 외부 managed-aws-rds 가상 서비스와 통신하도록 합니다.
config/products-api 배포 구성 파일을 열고 배포의 ConfigMap 섹션을 검토하세요.
config/product-api.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: db-configmap
namespace: default
data:
config: |
{
"db_connection": "host=managed-aws-rds.virtual.consul port=5432 user=postgres password=password dbname=products sslmode=disable",
"bind_address": ":9090",
"metrics_address": ":9103"
}
##..
이 HashiCups 서비스의 데이터베이스 연결 문자열이 managed-aws-rds.virtual.consul Consul DNS 주소를 포함하는 방법을 확인하세요.
참고
외부 서비스의 가상 주소 배치는 애플리케이션 고유합니다. 이 시나리오는 HashiCups 데이터베이스로 PostgreSQL을 사용합니다.
product-api 서비스를 배포합니다.
$ kubectl apply -f config/product-api.yaml
configmap/db-configmap created
service/product-api created
serviceaccount/product-api created
servicedefaults.consul.hashicorp.com/product-api created
deployment.apps/product-api created
데모 애플리케이션 탐색 (작동하는 상태)
브라우저에서 HashiCup의 URL을 열고 HashiCups UI를 새로고침하세요.
$ echo $CONSUL_APIGW_ADDR
http://a4cc3e77d86854fe4bbcc9c62b8d381d-221509817.us-west-2.elb.amazonaws.com
HashiCups UI가 올바르게 작동하는 것을 확인하세요. Consul terminating gateway를 사용하여 HashiCups 프런트엔드를 AWS RDS의 외부 HashiCups 백엔드 데이터베이스에 성공적으로 연결했습니다.
리소스 정리
환경을 정리하기 위해 Terraform 리소스를 파괴합니다. yes를 입력해 파괴 작업을 확인합니다.
$ terraform destroy
## ...
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
## ...
Destroy complete! Resources: 0 added, 0 changed, 103 destroyed.
참고
이 튜토리얼의 클라우드 리소스의 경합 조건 때문에 모든 리소스를 제거하려면 destroy 작업을 두 번 실행해야 할 수 있습니다.
다음 단계 (Next steps)
이 튜토리얼에서는 Consul terminating gateway를 배포하고 구성하여 Consul 서비스 메시 외부의 서비스로 보안 통신을 확장했습니다. 이 통합은 네트워크, 보안, 정책의 균일성에 대한 더 큰 단순성을 제공합니다. 또한 운영 오버헤드 감소와 레거시 서비스 채택 용이성을 제공합니다.
튜토리얼에서 다룬 주제에 대한 자세한 내용은 다음 리소스를 참조하세요.