メインコンテンツまでスキップ

クラウドリソースのプロビジョニング

このセクションでは、カートが使用しているインメモリデータベースをDynamoDBに置き換えます。WebApplicationのベーステンプレートを拡張してWebApplicationDynamoDB ResourceGraphDefinitionを構成することで実現します。

まず、前のセクションで作成したkroインスタンスを削除しましょう:

~$kubectl delete webapplication.kro.run/carts -n carts
webapplication.kro.run "carts" deleted

これにより、関連するすべてのリソースがクリーンアップされます:

~$kubectl get all -n carts
No resources found in carts namespace.

次に、再利用可能なWebApplicationDynamoDB APIを定義するResourceGraphDefinitionテンプレートを確認しましょう:

RGDマニフェストの全文を展開
~/environment/eks-workshop/modules/automation/controlplanes/kro/rgds/webapp-dynamodb-rgd.yaml
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は以下を行います:

  1. WebApplication RGDを構成するカスタムWebApplicationDynamoDB APIを作成
  2. ACKを使用してDynamoDBテーブルをプロビジョニング
  3. DynamoDBアクセス用のIAMロールとポリシーを作成
  4. アプリケーションPodからの安全なアクセスのためにEKS Pod Identityを設定

EKS Pod Identityの詳細については、公式ドキュメントを参照してください。

備考

このRGDのresourceセクションにWebApplication RGDが含まれていることに注目してください。webApplicationを参照することで、このテンプレートはベースのWebApplication RGDで定義されたすべてのKubernetesリソースを再利用し、DynamoDB、IAM、およびPod Identityリソースを追加します。

ResourceGraphDefinitionを適用してWebApplicationDynamoDB APIを登録しましょう:

~$kubectl apply -f ~/environment/eks-workshop/modules/automation/controlplanes/kro/rgds/webapp-dynamodb-rgd.yaml
resourcegraphdefinition.kro.run/web-application-ddb created

これによりWebApplicationDynamoDB APIが登録されます。Custom Resource Definition (CRD)を確認しましょう:

~$kubectl get crd webapplicationdynamodbs.kro.run
NAME                               CREATED AT
webapplicationdynamodbs.kro.run    2024-01-15T10:35:00Z

次に、WebApplicationDynamoDB APIを使用してCartsコンポーネントのインスタンスを作成するcarts-ddb.yamlファイルを確認しましょう:

~/environment/eks-workshop/modules/automation/controlplanes/kro/app/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}
A

RGDで作成されたカスタムWebApplicationDynamoDB APIを使用

B

carts名前空間にcartsという名前のリソースを作成

C

リソース命名のためのアプリケーション名を指定

D

1レプリカを設定

E

小売店のカートサービスコンテナイメージを使用

F

ポート8080でアプリケーションを公開

G

DynamoDBテーブル名を指定

H

DynamoDB永続モードを有効にする環境変数を設定

I

IAMとPod Identityの設定のためにAWSアカウントIDとリージョンを提供

次に、carts-ddb.yamlファイルを活用して更新されたコンポーネントをデプロイしましょう:

~$kubectl kustomize ~/environment/eks-workshop/modules/automation/controlplanes/kro/app \
| envsubst | kubectl apply -f-
webapplicationdynamodb.kro.run/carts created

kroはこのカスタムリソースを処理し、DynamoDBテーブルを含むすべての基盤となるリソースを作成します。カスタムリソースが作成されたことを確認しましょう:

~$kubectl get webapplicationdynamodb -n carts
NAME    STATE         SYNCED   AGE
carts   IN_PROGRESS   False    16s

インスタンスが「同期された」状態に達するまで待機できます:

~$kubectl wait -o yaml webapplicationdynamodb/carts -n carts \
--for=condition=InstanceSynced=True --timeout=120s

DynamoDBテーブルが作成されたことを確認するために、生成されたACKリソースをチェックできます:

~$kubectl wait table.dynamodb.services.k8s.aws items -n carts --for=condition=ACK.ResourceSynced --timeout=15m
table.dynamodb.services.k8s.aws/items condition met
~$kubectl get table.dynamodb.services.k8s.aws items -n carts -ojson | yq '.status."tableStatus"'
ACTIVE

AWS CLIを使用してテーブルが作成されたことを確認しましょう:

~$aws dynamodb list-tables
 
{
    "TableNames": [
        "eks-workshop-carts-kro"
    ]
}

kroの組み合わせ可能なアプローチを使用して、DynamoDBテーブルとコンポーネントが正常に作成されました。

コンポーネントが新しいDynamoDBテーブルで正常に動作していることを確認するために、ブラウザを通じて操作することができます。テスト用にサンプルアプリケーションを公開するためのNLBが作成されています:

~$ADDRESS=$(kubectl get ingress -n ui ui -o jsonpath="{.status.loadBalancer.ingress[*].hostname}")
~$echo "http://${ADDRESS}"
http://k8s-ui-ui-a9797f0f61.elb.us-west-2.amazonaws.com
備考

このコマンドを実行すると、新しいNetwork Load Balancerエンドポイントがプロビジョニングされるため、実際のエンドポイントは異なります。

ロードバランサーがプロビジョニングを完了したことを確認するには、次のコマンドを実行できます:

ロードバランサーがプロビジョニングされたら、ウェブブラウザにURLを貼り付けてアクセスできます。ウェブストアのUIが表示され、ユーザーとしてサイト内を移動できるようになります。

http://k8s-ui-ui-a9797f0f61.elb.us-west-2.amazonaws.com/

Cartsモジュールが実際に先ほどプロビジョニングしたDynamoDBテーブルを使用していることを確認するために、カートにいくつかの商品を追加してみましょう。

これらの商品がDynamoDBテーブルにも存在することを確認するために、次のコマンドを実行します:

~$aws dynamodb scan --table-name "${EKS_CLUSTER_NAME}-carts-kro"

おめでとうございます!ベースのWebApplicationテンプレートを拡張してDynamoDBストレージを追加することで、kroの組み合わせ可能性を実証することに成功しました。