Search

VPC Lattice

Amazon VPC Lattice란 VPC와 관련된 네트워크, 보안, 모니터링의 틀을 제공하는 완전 관리형 애플리케이션 네트워킹 서비스로, 네트워크에 대해 잘 모르더라도 쉽게 네트워크를 구성할 수 있게 도와주는 서비스입니다.

VPC Lattice가 제공하는 기능

서비스 검색
연결
Observability
보안

서비스 검색

서비스 네트워크와 연결된 VPC의 모든 클라이언트 및 서비스는 동일한 서비스 네트워크 내의 다른 서비스와 통신할 수 있다.
VPC Lattice 엔드포인트를 통해 DNS는 Client-Service 및 Service-Service 트래픽을 전달한다.
클라이언트가 서비스에 요청을 보내려고 할 때 서비스의 DNS 이름을 사용하며, Route 53 Resolver는 트래픽을 VPC Lattice로 전송하고 VPC Lattice는 대상 서비스를 식별한다.

연결성

VPC를 서비스 네트워크와 연결하면 VPC 내의 모든 클라이언트는 서비스 네트워크의 서비스와 연결할 수 있다.
단, 필요한 액세스 권한이 있어야 한다.

Observability

서비스 네트워크를 통과하는 각 요청 및 응답에 대한 지표와 로그를 생성하여 애플리케이션을 모니터링한다.
서비스 소유자는 서비스를 요청하는 모든 클라이언트에 대한 로그를 받는다.

보안

네트워크의 여러 계층에서 방어 전략을 구현하는 데 사용할 수 있는 프레임워크를 제공한다.

사용방법

VPC Lattice를 사용하면 서비스 네트워크라는 논리적 애플리케이션 계층 네트워크가 생성되며, 이 서비스 네트워크에 여러 서비스를 연결할 수 있다.
여기서 서비스란 특정 작업이나 기능을 제공하는 소프트웨어의 독립적으로 배포 가능한 단위를 말한다.
VPC Lattice에서 서비스는 VPC나 계정 내에서 실행할 수 있는 논리적 구성 요소이며, 결합된 컴퓨팅 유형(가상 머신, 컨테이너, 서버리스 함수)에서 실행할 수 있다.
서비스 구성
서비스에서 트래픽이 통과할 것으로 예측하는 포트와 프로토콜을 정의하는 리스너 1~2개
리스너에는 우선 순위, 규칙을 적용할 시점을 정의하는 1개 이상의 조건, 대상 그룹으로 트래픽을 포워딩하는 작업으로 구성된 규칙이 있다. 각 리스너는 추가적인 규칙이 구성되지 않았거나 조건이 충족되지 않을 때 적용되는 기본 규칙이 있다.
대상 그룹은 대상 즉, 라우팅하려는 특정 워크로드를 실행 중인 컴퓨팅 리소스의 모음입니다. 대상은 Amazon EC2 인스턴스, IP 주소, Lambda 함수가 될 수 있다. Kubernetes 워크로드의 경우, VPC Lattice는 AWS Gateway Controller for Kubernetes를 통해 서비스와 포드를 대상으로 지정할 수 있다.
사용순서 정리
대상 그룹 등록
VPC Lattice 서비스 만들기
서비스 네트워크 만들기

VPC Lattice 생성

ENV

EKS_CLUSTER_NAME="<CLUSTER_NAME>" REGION_CORD="ap-northeast-2"
Shell
복사

eks-pod-identity-agent addon 생성

aws eks create-addon --cluster-name $EKS_CLUSTER_NAME --addon-name eks-pod-identity-agent --addon-version v1.0.0-eksbuild.1
Shell
복사

ENV

export CLUSTER_SG=$(aws eks describe-cluster --name $EKS_CLUSTER_NAME --query "cluster.resourcesVpcConfig.clusterSecurityGroupId" --output text) PREFIX_LIST_ID=$(aws ec2 describe-managed-prefix-lists --query "PrefixLists[?PrefixListName=='com.amazonaws.$REGION_CODE.vpc-lattice'].PrefixListId" --output text) PREFIX_LIST_ID_IPV6=$(aws ec2 describe-managed-prefix-lists --query "PrefixLists[?PrefixListName=='com.amazonaws.$REGION_CODE.ipv6.vpc-lattice'].PrefixListId" --output text)
Shell
복사

보안그룹 인바운드 수정

aws ec2 authorize-security-group-ingress --group-id $CLUSTER_SG --ip-permissions "PrefixListIds=[{PrefixListId=${PREFIX_LIST_ID}}],IpProtocol=-1" > /dev/null aws ec2 authorize-security-group-ingress --group-id $CLUSTER_SG --ip-permissions "PrefixListIds=[{PrefixListId=${PREFIX_LIST_ID_IPV6}}],IpProtocol=-1" > /dev/null
Shell
복사

IAM 정책 생성

curl https://raw.githubusercontent.com/aws/aws-application-networking-k8s/main/files/controller-installation/recommended-inline-policy.json -o recommended-inline-policy.json
Shell
복사
aws iam create-policy \ --policy-name VPCLatticeControllerIAMPolicy \ --policy-document file://recommended-inline-policy.json
Shell
복사

ENV

export VPCLatticeControllerIAMPolicyArn=$(aws iam list-policies --query 'Policies[?PolicyName==`VPCLatticeControllerIAMPolicy`].Arn' --output text)
Shell
복사

IAM 정책 생성

kubectl apply -f https://raw.githubusercontent.com/aws/aws-application-networking-k8s/main/files/controller-installation/deploy-namesystem.yaml
Shell
복사
cat >trust-relationship.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowEksAuthToAssumeRoleForPodIdentity", "Effect": "Allow", "Principal": { "Service": "pods.eks.amazonaws.com" }, "Action": [ "sts:AssumeRole", "sts:TagSession" ] } ] } EOF
Shell
복사

IAM 역할 생성

aws iam create-role --role-name VPCLatticeControllerIAMRole --assume-role-policy-document file://trust-relationship.json
Shell
복사

IAM 역할 연결

aws iam attach-role-policy --role-name VPCLatticeControllerIAMRole --policy-arn=$VPCLatticeControllerIAMPolicyArn
Shell
복사

OIDC

eksctl utils associate-iam-oidc-provider --cluster $EKS_CLUSTER_NAME --approve --region $REGION_CODE
Shell
복사

SA 생성

eksctl create iamserviceaccount \ --cluster=$EKS_CLUSTER_NAME \ --namespace=aws-application-networking-system \ --name=gateway-api-controller \ --attach-policy-arn=$VPCLatticeControllerIAMPolicyArn \ --override-existing-serviceaccounts \ --region $REGION_CODE \ --approve
Shell
복사

Deploy 파일 가져오기

wget https://raw.githubusercontent.com/aws/aws-application-networking-k8s/main/files/controller-installation/deploy-v1.0.6.yaml
Shell
복사

sed 명령어로 특정 줄 삭제

sed -i '8222,8227d' deploy-v1.0.6.yaml
Shell
복사

Deploy 생성

kubectl apply -f deploy-v1.0.6.yaml
Shell
복사

Gateway 파일 가져오기

kubectl apply -f https://raw.githubusercontent.com/aws/aws-application-networking-k8s/main/files/controller-installation/gatewayclass.yaml
Shell
복사

VPC Lattice Service Network 생성

aws vpc-lattice create-service-network --name lattice-svc-net
Shell
복사

ENV

SERVICE_NETWORK_ID=$(aws vpc-lattice list-service-networks --query "items[?name=='lattice-svc-net'].id" --output text) VPC_ID=$(aws ec2 describe-vpcs --filter Name=tag:Name,Values=<VPC Name> --query "Vpcs[].VpcId" --output text)
Shell
복사

VPC Lattice Service Network VPC 연결

aws vpc-lattice create-service-network-vpc-association --service-network-identifier $SERVICE_NETWORK_ID --vpc-identifier $VPC_ID
Shell
복사

Gateway 생성 (서비스 네트워크와 VPC 간의 트래픽을 라우팅)

apiVersion: gateway.networking.k8s.io/v1beta1 kind: Gateway metadata: name: lattice-svc-net namespace: default annotations: application-networking.k8s.aws/lattice-vpc-association: "true" spec: gatewayClassName: amazon-vpc-lattice listeners: - name: http protocol: HTTP port: 80
YAML
복사
kubectl apply -f gateway.yaml
Shell
복사
kubectl get gateway -n default
Shell
복사
gateway가 정상적으로 동작 시 PROGRAMMEND가 True로 뜹니다.

TargetGroupPolicy 생성 (타겟 그룹에 대한 접근 제어와 트래픽 라우팅 규칙을 정의)

apiVersion: application-networking.k8s.aws/v1alpha1 kind: TargetGroupPolicy metadata: name: policy namespace: default spec: targetRef: group: "" kind: Service name: skills-svc protocol: HTTP protocolVersion: HTTP1 healthCheck: enabled: true intervalSeconds: 10 timeoutSeconds: 1 healthyThresholdCount: 3 unhealthyThresholdCount: 2 path: "/healthcheck" port: 8080 protocol: HTTP protocolVersion: HTTP1 statusMatch: "200"
YAML
복사
kubectl apply -f targetgrouppolicy.yaml
Shell
복사

IAMAuthPolicy 생성 (서비스 네트워크와 VPC 간의 통신에 대한 인증 및 권한 부여)

apiVersion: application-networking.k8s.aws/v1alpha1 kind: IAMAuthPolicy metadata: name: iam-auth-policy namespace: default spec: targetRef: group: "gateway.networking.k8s.io" kind: HTTPRoute name: lattice-svc namespace: default policy: | { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "*", "Resource": "*", "Condition": { "IpAddress": { "aws:SourceIp": "BASTION/32" } } } ] }
YAML
복사

ENV

BASTION_IP=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=bastion-ec2" --query "Reservations[0].Instances[0].PrivateIpAddress" --output text)
Shell
복사

sed 명령어로 취환

sed -i "s|BASTION|$BASTION_IP|g" iamauthpolicy.yaml
Shell
복사
kubectl apply -f iamauthpolicy.yaml
Shell
복사

HTTP Route 생성 (HTTP 트래픽을 특정 경로와 조건에 따라 라우팅)

apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: lattice-svc namespace: default spec: parentRefs: - name: lattice-svc-net sectionName: http rules: - backendRefs: - name: skills-svc kind: Service port: 8080 matches: - path: type: PathPrefix value: /healthcheck
YAML
복사
kubectl apply -f httproute.yaml
Shell
복사

테스트

kubectl wait -n default --timeout=3m \ --for=jsonpath='{.status.parents[-1:].conditions[-1:].reason}'=ResolvedRefs httproute/lattice-svc
Shell
복사
deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: skills-deployment namespace: default spec: replicas: 2 selector: matchLabels: app: skills-app template: metadata: labels: app: skills-app spec: containers: - name: skills-app image: 362708816803.dkr.ecr.ap-northeast-2.amazonaws.com/skills-app ports: - containerPort: 8080
YAML
복사
service.yaml
apiVersion: v1 kind: Service metadata: name: skills-svc namespace: default spec: selector: app: skills-app ports: - protocol: TCP port: 8080 targetPort: 8080
YAML
복사
ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: skills-ingress namespace: default annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/load-balancer-name: skills-alb alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]' alb.ingress.kubernetes.io/healthcheck-path: "/healthcheck" alb.ingress.kubernetes.io/subnets: subnet-03c547d8a0e9b9ce3, subnet-06346b286b8f1dcc8 alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/group.name: alb spec: ingressClassName: alb rules: - http: paths: - path: /v1/dummy pathType: Prefix backend: service: name: skills-svc port: number: 8080 - path: /healthcheck pathType: Exact backend: service: name: skills-svc port: number: 8080
YAML
복사