클라우드 리소스 프로비저닝
이 섹션에서는 carts에서 사용 중인 인메모리 데이터베이스를 DynamoDB로 교체하겠습니다. 기본 WebApplication 템플릿을 기반으로 구축하는 WebApplicationDynamoDB ResourceGraphDefinition을 구성하여 이를 수행하겠습니다.
먼저 이전 섹션에서 생성한 kro 인스턴스를 삭제하겠 습니다:
webapplication.kro.run "carts" deleted
이렇게 하면 관련된 모든 리소스가 정리됩니다:
No resources found in carts namespace.
이제 재사용 가능한 WebApplicationDynamoDB API를 정의하는 ResourceGraphDefinition 템플릿을 살펴보겠습니다:
전체 RGD 매니페스트 확장
apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
name: web-application-ddb
spec:
schema:
apiVersion: v1alpha1
kind: WebApplicationDynamoDB
spec:
appName: string | required=true description="Web Application Name"
replicas: integer | default=1 minimum=1 maximum=100
image: string | default=nginx
port: integer | default=8080
dynamodb:
tableName: string | required=true description="DynamoDB Table Name"
healthcheck:
readinessPath: string | default="/actuator/health/readiness"
readinessPort: integer | default=8080
livenessPath: string | default="/actuator/health/liveness"
livenessPort: integer | default=8080
service:
enabled: boolean | default=true
aws:
accountID: integer | required=true
region: string | default="us-west-2"
env: map[string]string | default={}
ingress:
enabled: boolean | default=false
path: string | default="/"
healthcheckPath: string | default="/health"
groupname: string | default="eks-workshop"
resources:
- id: podIdentityAssociation
template:
apiVersion: eks.services.k8s.aws/v1alpha1
kind: PodIdentityAssociation
metadata:
name: ${schema.spec.appName}
namespace: ${schema.spec.appName}
spec:
clusterName: "eks-workshop"
namespace: ${schema.spec.appName}
serviceAccount: ${schema.spec.appName}
roleARN: ${itemsTableIAMRole.status.ackResourceMetadata.arn}
- id: webApplication
template:
apiVersion: kro.run/v1alpha1
kind: WebApplication
metadata:
name: ${schema.spec.appName}
namespace: ${schema.spec.appName}
spec:
appName: ${schema.spec.appName}
replicas: 1
image: ${schema.spec.image}
port: 8080
healthcheck:
readinessPath: ${schema.spec.healthcheck.readinessPath}
readinessPort: ${schema.spec.healthcheck.readinessPort}
livenessPath: ${schema.spec.healthcheck.livenessPath}
livenessPort: ${schema.spec.healthcheck.livenessPort}
service:
enabled: ${schema.spec.service.enabled}
iamRole: ${podIdentityAssociation.status.ackResourceMetadata.arn}
env: ${schema.spec.env}
ingress:
enabled: ${schema.spec.ingress.enabled}
path: ${schema.spec.ingress.path}
healthcheckPath: ${schema.spec.ingress.healthcheckPath}
groupname: ${schema.spec.ingress.groupname}
- id: serviceDDB
template:
apiVersion: v1
kind: Service
metadata:
name: carts-dynamodb
labels:
app.kubernetes.io/created-by: eks-workshop
spec:
type: ClusterIP
ports:
- port: 8000
targetPort: dynamodb
protocol: TCP
name: dynamodb
selector:
app.kubernetes.io/name: ${schema.spec.appName}
app.kubernetes.io/instance: ${schema.spec.appName}
app.kubernetes.io/component: dynamodb
- id: itemsTable
template:
apiVersion: dynamodb.services.k8s.aws/v1alpha1
kind: Table
metadata:
name: items
namespace: ${schema.spec.appName}
spec:
keySchema:
- attributeName: id
keyType: HASH
attributeDefinitions:
- attributeName: id
attributeType: "S"
- attributeName: customerId
attributeType: "S"
billingMode: PAY_PER_REQUEST
tableName: ${schema.spec.dynamodb.tableName}
globalSecondaryIndexes:
- indexName: idx_global_customerId
keySchema:
- attributeName: customerId
keyType: HASH
- attributeName: id
keyType: RANGE
projection:
projectionType: "ALL"
- id: itemsTableIamPolicy
template:
apiVersion: iam.services.k8s.aws/v1alpha1
kind: Policy
metadata:
name: ${itemsTable.spec.tableName}-iam-policy
spec:
name: ${itemsTable.spec.tableName}-iam-policy
description: "EKS Workshop Carts DynamoDB Policy"
policyDocument: >
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllAPIActionsOnCart",
"Effect": "Allow",
"Action": "dynamodb:*",
"Resource": [
"arn:aws:dynamodb:${schema.spec.aws.region}:${schema.spec.aws.accountID}:table/${itemsTable.spec.tableName}",
"arn:aws:dynamodb:${schema.spec.aws.region}:${schema.spec.aws.accountID}:table/${itemsTable.spec.tableName}/index/*"
]
}
]
}
- id: itemsTableIAMRole
template:
apiVersion: iam.services.k8s.aws/v1alpha1
kind: Role
metadata:
name: ${itemsTable.spec.tableName}-iam-role
namespace: ${schema.spec.appName}
spec:
name: ${itemsTable.spec.tableName}-iam-role
description: "EKS Workshop Carts DynamoDB Role"
maxSessionDuration: 3600
policies:
- ${itemsTableIamPolicy.status.ackResourceMetadata.arn}
assumeRolePolicyDocument: >
{
"Version":"2012-10-17",
"Statement": [{
"Effect":"Allow",
"Principal": {"Service": "pods.eks.amazonaws.com"},
"Action": [
"sts:TagSession",
"sts:AssumeRole"
]
}]
}
이 ResourceGraphDefinition은:
- WebApplication RGD를 구성하는 사용자 정의
WebApplicationDynamoDBAPI를 생성합니다 - ACK를 사용하여 DynamoDB 테이블을 프로비저닝합니다
- DynamoDB 액세스를 위한 IAM 역할 및 정책을 생성합니다
- 애플리케이션 Pod에서 안전한 액세스를 위해 EKS Pod Identity를 구성합니다
EKS Pod Identity에 대해 자세히 알아보려면 공식 문서를 참조하세요.
이 RGD가 리소스 섹션에 WebApplication RGD를 포함하고 있는 것을 주목하세요. webApplication을 참조함으로써 이 템플릿은 기본 WebApplication RGD에 정의된 모든 Kubernetes 리소스를 재사용하면서 DynamoDB, IAM 및 Pod Identity 리소스를 추가합니다.
ResourceGraphDefinition을 적용하여 WebApplicationDynamoDB API를 등록하겠습니다:
resourcegraphdefinition.kro.run/web-application-ddb created
이렇게 하면 WebApplicationDynamoDB API가 등록됩니다. Custom Resource Definition (CRD)을 확인하세요:
NAME CREATED AT
webapplicationdynamodbs.kro.run 2024-01-15T10:35:00Z
이제 WebApplicationDynamoDB API를 사용하여 Carts 컴포넌트의 인스턴스를 생성할 carts-ddb.yaml 파일을 살펴보겠습니다:
apiVersion: kro.run/v1alpha1
kind: WebApplicationDynamoDB
metadata:
name: carts
namespace: carts
spec:
# Basic types
appName: carts
replicas: 1
image: "public.ecr.aws/aws-containers/retail-store-sample-cart:1.2.1"
port: 8080
dynamodb:
tableName: "eks-workshop-carts-kro"
env:
RETAIL_CART_PERSISTENCE_PROVIDER: "dynamodb"
RETAIL_CART_PERSISTENCE_DYNAMODB_TABLE_NAME: "eks-workshop-carts-kro"
aws:
accountID: ${AWS_ACCOUNT_ID}
region: ${AWS_REGION}
RGD에서 생성한 사용자 정의 WebApplicationDynamoDB API를 사용합니다
carts 네임스페이스에 carts라는 이름의 리소스를 생성합니다
리소스 이름 지정을 위한 애플리케이션 이름을 지정합니다
단일 레플리카를 설정합니다
소매점 장바구니 서비스 컨테이너 이미지를 사용합니다
포트 8080에 애플리케이션을 노출합니다
DynamoDB 테이블 이름을 지정합니다
DynamoDB 지속성 모드를 활성화하기 위한 환경 변수를 설정합니다
IAM 및 Pod Identity 구성을 위한 AWS 계정 ID와 리전을 제공합니다
다음으로 carts-ddb.yaml 파일을 활용하여 업데이트된 컴포넌트를 배포하겠습니다:
webapplicationdynamodb.kro.run/carts created
kro는 이 사용자 정의 리소스를 처리하고 DynamoDB 테이블을 포함한 모든 기본 리소스를 생성합니다. 사용자 정의 리소스가 생성되었는지 확인하겠습니다:
NAME STATE SYNCED AGE
carts IN_PROGRESS False 16s
이제 인스턴스가 "synced" 상태에 도달할 때까지 기다릴 수 있습니다:
DynamoDB 테이블이 생성되었는지 확인하기 위해 생성된 ACK 리소스를 확인할 수 있습니다:
table.dynamodb.services.k8s.aws/items condition met
ACTIVE
AWS CLI를 사용하여 테이블이 생성되었는지 확인하겠습니다:
{"TableNames": [
"eks-workshop-carts-kro"
]
}
kro의 구성 가능한 접근 방식을 사용하여 DynamoDB 테이블과 컴포넌트가 성공적으로 생성되었습니다.
컴포넌트가 새 DynamoDB 테이블과 함께 작동하는지 확인하기 위해 브라우저를 통해 상호 작용할 수 있습니다. 테스트를 위해 샘플 애플리케이션을 노출하는 NLB가 생성되었습니다:
http://k8s-ui-ui-a9797f0f61.elb.us-west-2.amazonaws.com
새로운 Network Load Balancer 엔드포인트가 프로비저닝되므로 이 명령을 실행할 때 실제 엔드포인트는 다를 것입니다.
로드 밸런서 프로비저닝이 완료되었는지 확인하려면 다음 명령을 실행할 수 있습니다:
로드 밸런서가 프로비저닝되면 웹 브라우저에 URL을 붙여넣어 액세스할 수 있습니다. 웹 스토어의 UI가 표시되며 사용자로서 사이트를 탐색할 수 있습니다.

Carts 모듈이 방금 프로비저닝한 DynamoDB 테이블을 실제로 사용하고 있는지 확인하려면 장바구니에 몇 가지 항목을 추가해 보세요.
이러한 항목이 DynamoDB 테이블에도 있는지 확인하려면 다음을 실행하세요:
축하합니다! 기본 WebApplication 템플릿을 기반으로 구축하여 DynamoDB 스토리지를 추가함으로써 kro의 구성 가능성을 성공적으로 시연했습니다.