[AEWS3기-12주차] AWS VPC Lattice For Multi Cluster secure communication
이 포스팅은 https://devops-james.tistory.com/535해당 포스팅에서 알아본 VPC Lattice 서비스를
다중 클러스터 환경에서 학습해보는 포스팅입니다.
[AEWS3기-12주차] Amazon VPC Lattice for Amazon EKS
이 포스팅은 가시다님의 AEWS 3기 스터디 포스팅내용입니다.해당 글에서는 Service Discovery에서 Service Mesh까지의 변천사를 알아보고,AWS 내에서 EKS 클러스터의 Gateway API를 어떻게 Lattice 서비스와 연결
devops-james.tistory.com
앞서 VPC Lattice 서비스는 무엇인지, 그리고 어떻게 EKS GatewayAPI와 소통되는지 확인해보았습니다.
이제 좀 더 복잡한, 좀 더 실전적인 다중 클러스터 환경에서 사용하는 법을 알아보겠습니다.
해당 포스팅은 https://aws-ia.github.io/terraform-aws-eks-blueprints/patterns/network/cross-cluster-pod-communication/ 해당 워크샵 내용을 기반으로 합니다.
Cross VPC and EKS clusters secure Communication - Amazon EKS Blueprints for Terraform
Amazon VPC Lattice - Multi-cluster secure communication This pattern showcases secure multi-cluster communication between two EKS clusters in different VPCs using VPC Lattice with IAM authorization. It illustrates service discovery and highlights how VPC L
aws-ia.github.io
인프라 구성 소개
이 구성에서는 다음과 같은 특이점을 가지고 있습니다.
다중 VPC의 다중 EKS 클러스터
- VPC Lattice를 통해 서로 다른 VPC에 각각 존재하는 EKS 클러스터 통신을 가능하게 합니다.
VPC Lattice로 서비스 디스커버리
- 두 VPC 간에는 Transitgateway나 vpc peering이 없이 VPC Lattice를 통해 service Discovery를 진행합니다.
Private CA를 통해 TLS 암호화
- 클러스터간 통신은 ACM에서 발급한 Private CA를 통해 TLS 암호화가 가능하도록 했고, Amazon Route53 Private Hosted Zone을 사용하여 Amazon VPC Lattice를 통해 설정하였습니다.
Kyverno 사용
- Kyverno를 사용하여 Envoy SigV4 proxy 컨테이너를 Pod에 추가하여 PCA를 주입해 TLS 인증을 시킵니다.
테라폼 코드 구성
git clone https://github.com/aws-ia/terraform-aws-eks-blueprints.git
cd terraform-aws-eks-blueprints/patterns/vpc-lattice/cross-cluster-pod-communication
인프라 구성 확인
코드가 매우 많으므로 학습에 불필요한 부분은 생성한 내용을 콘솔로 확인하도록 하겠습니다.
- 두 개의 VPC: VPC cluster 1과 VPC cluster 2가 독립적으로 구성
- 두 개의 EKS 클러스터: 각 VPC에 EKS Cluster 1과 EKS Cluster 2 배포
참고로 EKS 보안그룹에서는 VPC Lattice의 ipv4 주소 범위를 허용해주어야 합니다.
################################################################################
# Update cluster security group to allow access from VPC Lattice
################################################################################
data "aws_ec2_managed_prefix_list" "vpc_lattice_ipv4" {
name = "com.amazonaws.${local.region}.vpc-lattice"
}
resource "aws_vpc_security_group_ingress_rule" "cluster_sg_ingress" {
security_group_id = module.eks.node_security_group_id
prefix_list_id = data.aws_ec2_managed_prefix_list.vpc_lattice_ipv4.id
ip_protocol = "-1"
}
- VPC Lattice: 두 VPC 간의 서비스 통신을 위한 중앙 관리형 연결 서비스
서비스 네트워크를 살펴보면 각 vpc에 잘연결되어있습니다.
VPC Lattice 대상그룹에 해당 application이 등록됩니다.
예를들어 대상 pod의 ip또 한 잘 Discovery 되는 것을 확인할 수 있습니다.
애플리케이션 구성
- EKS Cluster 1 애플리케이션:
- App1 Service가 Pod로 배포됨
- Envoy sidecar 프록시를 통한 서비스 메시 구성
- HTTP Route를 통한 외부 트래픽 라우팅
- EKS Cluster 2 애플리케이션:
- App2 Service가 Pod로 배포됨
- 마찬가지로 Envoy sidecar 프록시와 HTTP Route 구성
Kubernetes의 라우팅 설정
1. GatewayClass
VPC Lattice와 연결하기 위해서 EKS에서도 GatewayClass, Gateway 를 배포합니다.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
name: amazon-vpc-lattice
spec:
controllerName: application-networking.k8s.aws/gateway-api-controller
2. Gateway
TLS 통신이 들어가 있으므로 443 포트도 라우팅되는 것을 확인할 수 있으며 HTTPRoute 임을 확인했습니다.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: {{ .Release.Namespace }}
namespace: {{ .Release.Namespace }}
spec:
gatewayClassName: amazon-vpc-lattice
listeners:
- name: http-listener
port: 80
protocol: HTTP
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Selector
selector:
matchLabels:
allow-attachment-to-infra-gw: "true"
- name: https-listener-with-default-domain
port: 443
protocol: HTTPS
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Selector
selector:
matchLabels:
allow-attachment-to-infra-gw: "true"
- name: https-listener-with-custom-domain
port: 443
protocol: HTTPS
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Selector
selector:
matchLabels:
allow-attachment-to-infra-gw: "true"
tls:
mode: Terminate
options:
application-networking.k8s.aws/certificate-arn: {{ .Values.certificateArn }}
---
#https://github.com/aws/aws-application-networking-k8s/blob/main/docs/api-types/iam-auth-policy.md?plain=1
apiVersion: application-networking.k8s.aws/v1alpha1
kind: IAMAuthPolicy
metadata:
name: {{ .Release.Namespace }}-iam-auth-policy
namespace: {{ .Release.Namespace }}
spec:
targetRef:
group: "gateway.networking.k8s.io"
kind: Gateway
name: {{ .Release.Namespace }}
policy: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "vpc-lattice-svcs:Invoke",
"Resource": "*",
"Condition": {
"StringNotEqualsIgnoreCase": {
"aws:PrincipalType": "anonymous"
}
}
}
]
}
해당 서비스 네트워크를 살펴보면 lattice-gateway 라는 이름으로 각 서비스가 묶여 있습니다.
3. HTTP Route
HTTP Route 설정은 다음과 같습니다.
Gateway에서 http-listener와 https-listener-with-custom-domain을 각각 엔드포인트로 두고, IAM AuthPolicy를 통해서 호출에 대한 접근제어를 진행합니다.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
spec:
hostnames:
- {{ .Release.Name }}.{{ .Values.customDomain }}
parentRefs:
- kind: Gateway
name: lattice-gateway
namespace: lattice-gateway
sectionName: http-listener
- kind: Gateway
name: lattice-gateway
namespace: lattice-gateway
sectionName: https-listener-with-custom-domain
rules:
- backendRefs:
- name: {{ .Release.Name }}-{{ .Values.version }}
kind: Service
port: 80
matches:
- path:
type: PathPrefix
value: /
실제 두 개의 클러스터 내에서의 HTTPRoute 설정부터 보도록하겠습니다.
annotation 정보에 vpc lattice 주소가 있으며 hostname이 각각 example.com 도메인과 연동됨을 확인할 수 있습니다.
콘솔에서도 Lattice 내의 서비스로 각 클러스터의 애플리케이션이 연동됨을 확인할 수 있습니다.
정책 및 보안
Kyverno
이번 실습에서는 Kyverno의 ClusterPolicy를 사용하여 데모 애플리케이션 Pod에 iptables 규칙과 envoy 사이드카 프록시를 주입합니다.
- iptables 규칙은 애플리케이션에서 envoy 프록시로 트래픽을 라우팅합니다(소스 프로세스 gid가 0인 경우 규칙이 적용되지 않으므로 애플리케이션에 다른 gid를 제공합니다: runAsGroup: 1000).
- envoy 프록시는 시작 시 Private CA 인증서를 검색하여 시작 스크립트를 통해 VPC lattice 서비스를 신뢰하도록 설치합니다.
envoy 프록시 컨테이너가 뜰 때 launch_envoy.sh를 실행합니다. 해당 명령어를 통해서 스크립트문을 확인해봅시다.
kubectl --context eks-cluster1 \
exec -it deploy/demo-cluster1-v1 -c envoy-sigv4 -n apps \
-- cat /usr/local/bin/launch_envoy.sh
다음 내용은 launch_envoy.sh에 대한 내용인데 envoy.yaml 스크립트를 참조합니다.
#!/bin/sh
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
cat /etc/envoy/envoy.yaml.in | envsubst \$AWS_REGION,\$JWT_AUDIENCE,\$JWT_JWKS,\$JWT_ISSUER,\$JWKS_HOST,\$APP_DOMAIN > /etc/envoy/envoy.yaml
aws acm-pca get-certificate-authority-certificate --certificate-authority-arn $CA_ARN --region $AWS_REGION --output text > /etc/pki/ca-trust/source/anchors/internal.pem
update-ca-trust extract
cat /etc/envoy/envoy.yaml
/usr/local/bin/envoy --base-id 1 -l trace -c /etc/envoy/envoy.yaml
envoy.yaml의 내용을 요약하면 다음과 같습니다.
- 8080 포트에서 HTTP 요청 수신
- 모든 요청을 동적 DNS 조회를 통해 해당 서비스로 전달
- AWS VPC Lattice로 가는 요청에 SigV4 인증 서명 적용
- TLS를 사용하여 안전한 통신 보장
또한 envoy는 컨테이너 내에 포함된 상태로 애플리케이션에 배포되는데, envoy에 대한 라우팅 룰 설정을 kyverno를 통해 관리합니다.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: inject-sidecar
annotations:
policies.kyverno.io/title: Inject Sidecar Container
spec:
rules:
- name: inject-sidecar-envoy
match:
any:
- resources:
kinds:
- Deployment
mutate:
patchStrategicMerge:
spec:
template:
metadata:
annotations:
(vpc-lattices-svcs.amazonaws.com/agent-inject): "true"
spec:
initContainers: # IPtables 규칙은 init container에서 업데이트됩니다. (링크 : init container란?)
- image: public.ecr.aws/seb-demo/iptables:v1
name: iptables-init
securityContext:
capabilities:
add:
- NET_ADMIN
command: # Envoy 프록시 자체의 트래픽이 리디렉션되는 것을 방지하기위한 코드를 작성합니다.(무한 루프 방지)
- /bin/sh
- -c
- >
iptables -t nat -N EGRESS_PROXY;
iptables -t nat -A OUTPUT -p tcp -d 169.254.171.0/24 -j EGRESS_PROXY;
iptables -t nat -A EGRESS_PROXY -m owner --gid-owner 0 -j RETURN;
iptables -t nat -A EGRESS_PROXY -p tcp -j REDIRECT --to-ports 8080;
iptables -t nat -L -n -v;
containers:
- name: envoy-sigv4
image: public.ecr.aws/seb-demo/envoy-sigv4:v0.5
securityContext:
runAsGroup: 0
env:
- name: APP_DOMAIN
value: "example.com"
- name: CA_ARN
value: "{{ .Values.acmpCAArn }}"
args: ["-l", "info"]
ports:
- containerPort: 8080
name: proxy
protocol: TCP
앞서 kyverno에서 command 명령을 보시면 다음과 같이 iptables 명령이 들어있습니다.
해당 내역은 다음과 같은 내용입니다.
# EGRESS_PROXY라는 새로운 체인(체인은 규칙 그룹)을 만듭니다.
iptables -t nat -N EGRESS_PROXY;
# 목적지 IP가 169.254.171.0/24 대역인 모든 TCP 패킷을 EGRESS_PROXY 체인으로 보냅니다. (169.254.171.0/24 - VPC Lattice 링크 로컬 주소 범위)
iptables -t nat -A OUTPUT -p tcp -d 169.254.171.0/24 -j EGRESS_PROXY;
# EGRESS_PROXY 체인에서 그룹 ID가 0인 사용자(root 사용자)의 패킷은 규칙을 거치지 않고 통과시킵니다.
iptables -t nat -A EGRESS_PROXY -m owner --gid-owner 0 -j RETURN;
# EGRESS_PROXY 체인에서 나머지 TCP 패킷은 8080 포트로 리다이렉트됩니다. (envoy-sigv4 컨테이너로 리다이렉트)
iptables -t nat -A EGRESS_PROXY -p tcp -j REDIRECT --to-ports 8080;
# 현재 설정된 NAT 테이블 규칙을 자세히 출력합니다.
iptables -t nat -L -n -v
각 클러스터 내의 정보를 보면 먼저 init container를 통해 envoy-sigv4 컨테이너를 위한 IPTables 세팅이 수행되었습니다.
그리고 envoy-sigv4 컨테이너와 데모 애플리케이션 컨테이너가 잘 배포되어 있습니다.
다음과 같이 pod 목록에서도 controller 정보도 확인할 수 있습니다.
IAM Auth Policy
VPC Lattice의 Service Network 또는 Service에 첨부되는 IAM Policy 문서로, 주체(principal)가 첨부된 Service Network의 Service 또는 특정 첨부된 Service에 접근하는 권한을 제어합니다. 쉽게말해 IAM Auth Policy로두 클러스터 간의 인증 및 권한 정책을 설정합니다.
실제 해당 내용 적용 확인은 아래 호출실습 2를 참고하시기 바랍니다.
apiVersion: application-networking.k8s.aws/v1alpha1
kind: IAMAuthPolicy
metadata:
name: {{ .Release.Name }}-iam-auth-policy
namespace: {{ .Release.Namespace }}
spec:
targetRef:
group: "gateway.networking.k8s.io"
kind: HTTPRoute
namespace: {{ .Release.Namespace }}
name: {{ .Release.Name }}
policy: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::{{ .Values.awsAccountID }}:root"
},
"Action": "vpc-lattice-svcs:Invoke",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:PrincipalTag/eks-cluster-name": "{{ .Values.allowedCluster }}",
"aws:PrincipalTag/kubernetes-namespace": "{{ .Values.allowedNamespace }}"
}
}
}
]
}
Private Host와 CA 설정
정책 및 보안에서 중앙 인증서 관리를 위해 Private Certificate Authority(PCA)와 인증서 관리를 위해 Certificate Manager를 사용합니다.
1. Private Host Zone 생성
먼저 Private 영역의 HostZone을 만들기 위해서 다음과 같이 Host Zone을 생성합니다.
Private Host Zone은 VPC랑 연결을 지어주어야 합니다. 따라서 해당 VPC 내에서만 Host Zone에 접근할 수 있게됩니다.
#-------------------------------
# Create Private Hosted Zone
#-------------------------------
resource "aws_route53_zone" "private_zone" {
name = local.domain
vpc {
vpc_id = aws_vpc.example.id
}
#we will add vpc association in other terraform stack, prevent this one to revert this
lifecycle {
ignore_changes = [
vpc,
]
}
force_destroy = true
tags = local.tags
}
#dummy VPC that will not be used, but needed to create private hosted zone
resource "aws_vpc" "example" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "Example VPC"
}
}
2. Private CA 설정
생성한 Private HostZone에서 통신할 때 TLS 인증을 받기 위해서 인증서를 별도로 발급합니다.
이게 근데 참고로.. 유지비가 $50/월 입니다. 참고하시기 바랍니다. (최초 리전당 1개는 발급비용 및 사용이 30일간은 무료같습니다.)
#-------------------------------
# Associates a certificate with an AWS Certificate Manager Private Certificate Authority (ACM PCA Certificate Authority).
# An ACM PCA Certificate Authority is unable to issue certificates until it has a certificate associated with it.
# A root level ACM PCA Certificate Authority is able to self-sign its own root certificate.
#-------------------------------
# # https://docs.aws.amazon.com/acm-pca/latest/userguide/pca-rbp.html
resource "aws_acmpca_certificate_authority" "this" {
enabled = true
type = "ROOT"
certificate_authority_configuration {
key_algorithm = "RSA_4096"
signing_algorithm = "SHA512WITHRSA"
subject {
common_name = var.custom_domain_name
organization = var.organization
}
}
permanent_deletion_time_in_days = 7
tags = local.tags
}
resource "aws_acmpca_certificate" "this" {
certificate_authority_arn = aws_acmpca_certificate_authority.this.arn
certificate_signing_request = aws_acmpca_certificate_authority.this.certificate_signing_request
signing_algorithm = "SHA512WITHRSA"
template_arn = "arn:aws:acm-pca:::template/RootCACertificate/V1"
validity {
type = "YEARS"
value = 10
}
}
resource "aws_acmpca_certificate_authority_certificate" "this" {
certificate_authority_arn = aws_acmpca_certificate_authority.this.arn
certificate = aws_acmpca_certificate.this.certificate
certificate_chain = aws_acmpca_certificate.this.certificate_chain
}
#-------------------------------
# Create certificate in AWS Certificate Manager
#-------------------------------
resource "aws_acm_certificate" "private_domain_cert" {
domain_name = var.custom_domain_name
#validation_method = "DNS"
subject_alternative_names = [
"*.${var.custom_domain_name}"
]
options {
certificate_transparency_logging_preference = "DISABLED"
}
certificate_authority_arn = aws_acmpca_certificate_authority.this.arn
tags = local.tags
}
Route53 의 private host zone 정보입니다. 두 도메인이 각각 lattice 서비스와 연동됨을 확인할 수 있습니다.
CA도 arn 정보와 함께 확인해봅니다.
네트워킹
AWS Gateway API Controller로 각 클러스터의 API 트래픽 제어하고, Route53으로 도메인관리를 진행하면서 ExternalDNS를 통해서 연동합니다.
먼저, 인증서관리는 Pod identity Associations 정보를 확인해보겠습니다.
cluster1의 설정입니다.
cluster2의 설정입니다.
해당 역할을 통해사용하고 있습니다. 해당 IAM 역할은 EKS 내 default 라는 service account와 IRSA 구성을 이루고 있습니다.
이 IAM role은 ACM의 PCA에 대한 여러 액세스 권한과 VPC Lattice Service에 대한 invoke 권한이 설정되어 있습니다.
관리형 역할이므로 text로 표시하겠습니다.
AWSCertificateManagerPrivateCAReadOnly
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": [
"acm-pca:DescribeCertificateAuthority",
"acm-pca:DescribeCertificateAuthorityAuditReport",
"acm-pca:ListCertificateAuthorities",
"acm-pca:GetCertificateAuthorityCsr",
"acm-pca:GetCertificateAuthorityCertificate",
"acm-pca:GetCertificate",
"acm-pca:GetPolicy",
"acm-pca:ListPermissions",
"acm-pca:ListTags"
],
"Resource": "*"
}
}
VPCLatticeServicesInvokeAccess
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"vpc-lattice-svcs:Invoke"
],
"Resource": "*"
}
]
}
호출 실습 1 - 두 클러스터 간 단순 도메인 호출 테스트
두 클러스터 간의 연결성 확인을 위해 cluster1에서 다음 내용을 호출해 보겠습니다.
eks-cluster1에서 demo-cluster1-v1을 접속한뒤 demo-cluster2.example.com을 호출하는 예시입니다.
kubectl --context eks-cluster1 \
exec -ti -n apps deployments/demo-cluster1-v1 -c demo-cluster1-v1 \
-- curl demo-cluster2.example.com
cluster1에서는 응답이 다음과 같이 돌아옵니다.
Requsting to Pod(demo-cluster2-v1-55d69b6dc6-k72xf): Hello from demo-cluster2-v1
보기 좀 불편하긴 하지만 cluster2에서도 다음과 같이 로그가 식별되는 모습입니다.
demo-cluster2-v1 2025/04/22 06:54:01 Receiving %!(EXTRA *http.Request=&{GET / HTTP/1.1 1 1 map[Accept:[*/*] User-A
│ gent:[curl/8.3.0] X-Amz-Content-Sha256:[UNSIGNED-PAYLOAD] X-Amzn-Lattice-Identity:[Principal=arn:aws:sts::16088933
│ 2534:assumed-role/vpc-lattice-sigv4-client/eks-eks-cluste-demo-clust-824fb29d-0882-4581-af1a-86c368cbe455; Princip
│ alOrgID=o-z3k7i465it; SessionName=eks-eks-cluste-demo-clust-824fb29d-0882-4581-af1a-86c368cbe455; Type=AWS_IAM] X-
│ Amzn-Lattice-Network:[SourceVpcArn=arn:aws:ec2:ap-northeast-2:160889332534:vpc/vpc-0c4bab466c9680098] X-Amzn-Latti
│ ce-Target:[ServiceArn=arn:aws:vpc-lattice:ap-northeast-2:160889332534:service/svc-0b7970c34ac15f76a; ServiceNetwor
│ kArn=arn:aws:vpc-lattice:ap-northeast-2:160889332534:servicenetwork/sn-0f806be2c26d936e5; TargetGroupArn=arn:aws:v
│ pc-lattice:ap-northeast-2:160889332534:targetgroup/tg-0a92050da2be8a5c2] X-Amzn-Source-Vpc:[vpc-0c4bab466c9680098]
│ X-Amzn-Tls-Cipher-Suite:[ECDHE-RSA-AES128-GCM-SHA256] X-Amzn-Tls-Version:[TLSv1.2] X-Envoy-Expected-Rq-Timeout-Ms
│ :[15000] X-Forwarded-For:[10.0.2.152] X-Request-Id:[1b245173-4659-4c83-83f0-f2fd269554f9]] {} <nil> 0 [] false dem
│ o-cluster2.example.com map[] map[] <nil> map[] 169.254.171.195:7230 / <nil> <nil> <nil> 0xc00005cc40})
해당 호출이 가능한 이유는 HTTPRoute로 라우팅 되는 대상이 demo-cluster1-v1 이라는 Service임을 알 수 있습니다.
해당 서비스 정보는 모두 VPC Lattice에 대상그룹으로 등록되어 있습니다.
결국 해당 도메인으로 호출하게 되면 해당 서비스까지 도달할 수 있는 것입니다. 다음과 같이 콘솔에서 확인이 가능합니다.
호출 실습 2 - IAMAuthPolicy 적용 여부 확인 (자기 자신 호출)
이번에는 eks-cluster1에서 eks-cluster1인 자기자신의 도메인을 호출해보겠습니다.
kubectl --context eks-cluster1 \
exec -ti -n apps deployments/demo-cluster1-v1 -c demo-cluster1-v1 \
-- curl demo-cluster1.example.com
그럼 다음과 같은 에러가 보입니다.
AccessDeniedException: User: arn:aws:sts::12341234:assumed-role/vpc-lattice-sigv4-client/eks-eks-cluste-demo-clust-824fb29d-0882-4581-af1a-86c368cbe455 is not authorized to perform: vpc-lattice-svcs:Invoke on resource: arn:aws:vpc-lattice:ap-northeast-2:1234234534:service/svc-05b69e17f83655902/ because no service-based policy allows the vpc-lattice-svcs:Invoke action%
이렇게 에러가 발생하는 이유는, eks-cluster1의 IAMAuthPolicy에서 eks-cluster2 으로만 호출 가능하도록 했기 때문입니다.
구체적인 설정을 살펴보기위해서 다음 내용을 조회합니다.
kubectl --context eks-cluster1 \
get IAMAuthPolicy -n apps demo-cluster1-iam-auth-policy \
-o json | jq ".spec.policy | fromjson"
다음과 같이 cluster2에대해서만 허용하고 있습니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::12345678910:root"
},
"Action": "vpc-lattice-svcs:Invoke",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:PrincipalTag/eks-cluster-name": "eks-cluster2",
"aws:PrincipalTag/kubernetes-namespace": "apps"
}
}
}
]
}
위의 정책 내용을 해석하면 아래와 같습니다.
VPC Lattice Serivce를 invoke하는 액션 중에서 클러스터 명(eks-cluster-name)이 eks-cluster2 여야하고, 네임스페이스가 apps일 때에만 Invoke를 허용한다.
클러스터 2개를 같이 보면 다음과 같이 각각 설정되어 있습니다.
해당 IAMAuthPolicy의 적용 대상(Target Ref)이 demo-cluster1 라는 이름을 가진, apps 네임스페이스의 HTTPRoute 리소스임을 확인할 수 있습니다.
결과적으로 이 데모 애플리케이션 Pod가 IAMAuthPolicy의 규칙을 적용받고 있음을 확인할 수 있습니다.
이렇게 IAMAuthPolicy를 사용하면 멀티 클러스터 간에 각 애플리케이션에 대한 액세스 제어를 쉽게 구성할 수 있습니다.
이를 통해서 멀티 클러스터 환경에서도 VPC Lattice와 EKS를 연결하여 상호 호출하는 방법을 확인하였고, 추가적으로 TLS 설정과 iptables 설정을 위한 kyverno와 트래픽 통제를 위한 IAMAuthPolicy 등을 학습할 수 있었습니다.