Amazon Web Services ブログ

AWS Controllers for Kubernetes (ACK) と Amazon EKS Blueprints を利用したマイクロサービスのデプロイメント

この記事は Microservices development using AWS controllers for Kubernetes (ACK) and Amazon EKS blueprints (記事公開日: 2022 年 11 月 25 日) を翻訳したものです。

はじめに

マイクロサービスアーキテクチャはアプリケーションのスケールを容易にし開発を高速化することで、イノベーションを可能にし新機能の市場投入までの時間を短縮します。複数のクライアント (Web、モバイル、デスクトップ、スマートデバイス) を持つビジネスアプリケーションでは、集中制御とセキュリティを追加するために、アプリケーションプログラミングインターフェース (API) ゲートウェイマイクロサービスデザインパターンが役に立ちます。コンテナとサーバーレスは、マイクロサービスアプリケーションの開発を可能にする 2 つの主要な技術です。サーバーレスアプリケーションを構築するために、開発者は一般的に AWS Serverless Application Model (AWS SAM) のようなソリューションを使用して、API、データベース、およびイベントソースマッピングを定義してきました。

マイクロサービスアプリケーションを構築するために Kubernetes が人気を集めている中、Amazon API Gateway、Amazon Simple Storage Service (Amazon S3) バケット、Amazon Relational Database Service (Amazon RDS) インスタンスなどの AWS リソースを Kubernetes API と設定言語を使ってプロビジョニングや設定を行いたいお客様もいます。 この記事では、このニーズを満たすために AWS Controllers for Kubernetes (ACK) と共に AWS Load Balancer Controller を使用しています。ACK を使用すると、Kubernetes の Deployment や Service を作成および構成を行うのと同じ方法で、API Gateway リソースと DynamoDB テーブルを作成および構成できます。AWS Load Balancer Controller は Application Load Balancer (ALB) の作成、Amazon EKS Blueprints for Terraform はリソースのプロビジョニングを自動化するために使用されます。

ソリューションの概要

ACK コントローラーで API ゲートウェイマイクロサービス設計の実装する

ACK は、Kubernetes から直接 AWS サービスのリソースを定義して利用することができます。ACK を使えば、クラスターの外でリソースを定義したり、クラスター内でサポート機能 (データベースやメッセージキューなど) を提供するサービスを実行する必要がなく、Kubernetes アプリケーションのために AWS マネージドサービスを利用することができるのです。ACK プロジェクトには、一連のサービスコントローラーが含まれており、AWS の各サービス API に対応したものが用意されています。

この記事では、ACK コントローラーと AWS Load Balancer Controllerを使用して、Amazon Elastic Kubernetes Service (Amazon EKS) クラスターを作成します。サンプルアプリケーションをデプロイし、内部 ALB を使用して公開します。サンプルアプリケーションはストレージとして DynamoDB テーブルを使用しており、ACK DynamoDB コントローラーによってプロビジョニングされています。そして、ACK API Gateway コントローラーを使用して、 VPC リンクを介してサンプルアプリケーションに紐付けられたルートを持つ API Gateway HTTP API を作成します。

ソリューションのアーキテクチャを下記の図に示します。

この記事では ACK API Gateway コントローラーと ACK DynamoDB コントローラーのみを使用していますが、他の ACK コントローラーを使用する場合でも、アーキテクチャは同じです。その他の例については、こちらのリンクをご確認ください。

AWS EKS Blueprints for Terraform を使って Amazon EKS クラスターをプロビジョニングし、ACK コントローラーをインストールする

前提条件

以下のツールがローカルにインストールされていることを確認してください。

  1. Amazon コマンドラインインターフェース (AWS CLI)
  2. kubectl
  3. Terraform
  4. Docker

ウォークスルー

ACK サービスコントローラーごとに、AWS リソースを管理するための異なる AWS Identify and Access Management (AWS IAM) ロールが必要なので、必要なサービスコントローラーをインストールするには、自動化ツールを使用した方がよいでしょう。我々は、Amazon EKS Blueprints for Terraform を使用して、以下のコンポーネントをプロビジョニングすることを選択します。

  • 3つのプライベートサブネットと3つのパブリックサブネットを持つ新しい仮想プライベートクラウド (VPC)
  • パブリックサブネット用のインターネットゲートウェイとプライベートサブネット用の NAT ゲートウェイ
  • 1 つのマネージドノードグループを持つ Amazon EKS クラスターコントロールプレーン
  • Amazon EKS アドオン: VPC CNI、CoreDNS、およびkube-proxy
  • AWS Load Balancer Controller と ACK コントローラー
  • API Gateway と VPC リンク
  • サンプル API アプリケーションのための DynamoDB 読み書き用 IAM ロール

まずはコードリポジトリをローカルにクローンしてみましょう。main.tf にあるモジュール eks_ack_addons は ACK コントローラーをインストールするためのものです。

ACK コントローラーは、Amazon ECR Public Galley の Helm チャートを利用してインストールします。Terraform スクリプトを実行する前に、ログインしておく必要があります。

cd terraform-aws-eks-ack-addons/examples/complete
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
terraform init
terraform plan
terraform apply -auto-approve -var aws_region=<aws_region> #defaults to us-west-2

完了すると、以下の図のような出力が得られます。次のステップで、これらの出力値でデプロイメント用の YAML ファイルを修正する必要があります。

kubeconfig を設定する

Terraform の出力から configure_kubectl を使用して、ワークステーションから kubectl にアクセスできるように設定します。

region=<your region> # set region variable for following commands
aws eks --region $region update-kubeconfig --name ack-eks-complete

クラスターのアクセスの検証する

kubectl のアクセスが正しく設定されていることを確認します。

kubectl get nodes

サンプルアプリケーションをデプロイする

サンプルアプリケーションは、2 つの API メソッドを持つシンプルな NodeJS の API アプリケーションです。/rows/add に対する POST メソッドは、入力されたペイロードを受け取り、DynamoDB に保存します。/rows/all に対する GET メソッドは、DynamoDB のテーブルからすべてのデータを取得し、フロントエンドに返します。サンプルアプリケーションは、上記の Amazon EKS Blueprints で作成した IAM ロールを使用して DynamoDB にアクセスします。

デプロイ前に app.yaml を修正します。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-api-dynamodb
  namespace: ack-demo
....

    env:
    - name: aws_region
        value: "<same region as your eks cluster>" # replace with your region 
kubectl apply -f sample-app/app.yaml

デプロイが成功したことを確認します。

kubectl get pods -n ack-demo

デプロイスクリプトは、内部 ALB を介して API アプリケーションを公開します。以下のスクリプトを使用して、ALB リスナーの ARN を取得します。

aws elbv2 describe-listeners \
  --region $region \
  --load-balancer-arn $(aws elbv2 describe-load-balancers \
  --region $region \
  --query “LoadBalancers[?contains(DNSName, ‘$(kubectl get ingress ingress-api-dynamodb -n ack-demo -o=jsonpath=”{.status.loadBalancer.ingress[].hostname}”)’)].LoadBalancerArn” \
  --output text) \
  --query “Listeners[0].ListenerArn” \
  --output text

API Gateway リソースをデプロイする

API Gateway 用の ACK コントローラーと、API Gateway を内部 ALB に接続するために必要な VPC リンクが、Amazon EKS Blueprints によって作成されています。

デプロイ前に apigwv2-httpapi.yaml を更新します。

apiVersion: apigatewayv2.services.k8s.aws/v1alpha1
kind: Integration
metadata:
  name: "vpc-integration"
spec:
  apiRef:
    from:
      name: "ack-api"
  integrationType: HTTP_PROXY
  integrationURI: "<your ALB listener arn>" # replace
  integrationMethod: ANY
  payloadFormatVersion: "1.0"
  connectionID: "<your vpclink id>" # api_gatewayv2_vpc_link_id in terraform output
  connectionType: "VPC_LINK"
kubectl apply -f sample-app/apigwv2-httpapi.yaml

AWS CLI で API Gateway がデプロイされていることを確認します。

aws apigatewayv2 get-apis --region $region

次に、ALB との連携が正常に作成されたことを確認しましょう。

aws apigatewayv2 get-integrations --api-id <insert-api-id> --region $region

DynamoDB テーブルをデプロイする

DynamoDB テーブルをデプロイし、正常に作成されたことを確認します。

kubectl apply -f sample-app/dynamodb-table.yaml
aws dynamodb list-tables --region $region

API メソッドをテストする

これで、API メソッドに必要なすべてのコンポーネントをデプロイすることができました。以下のスクリプトを使って、API Gateway のエンドポイントを取得し、テストしてみましょう。

URL=$(kubectl get -n ack-demo api ack-api -o jsonpath="{.status.apiEndpoint}") 

まず、curl を使った POST メソッドをテストしてみます。

curl -X POST $URL/rows/add -H 'Content-Type: application/json' -d '{"name": "external"}'

Response: 
{"success":true}

次に、<your api gateway endpoint>/rows/all に対する GET メソッドをテストします。1 つのレコードしか投稿していないので、今のところ 1 つのレコードが返されるだけです。

curl $URL/rows/all

Response:
["external"]

クリーンアップ

kubectl delete -f sample-app/.
### Please wait a couple of minutes for ACK deleting resources before running code below
terraform destroy -target="module.eks_ack_addons" -target="module.eks_blueprints_kubernetes_addons" -auto-approve -var aws_region=$region
terraform destroy -target="module.eks_blueprints" -auto-approve -var aws_region=$region
terraform destroy -auto-approve -var aws_region=$region

まとめ

この記事では、Kubernetes の API とコマンドのみを使用して、Amazon EKS クラスターにマイクロサービス API アプリケーションをデプロイする方法を紹介しました。AWS Controller for Kubernetes を使うと、Kubernetes のリソース (Pod、Deployment、Service、Ingress など) と同じように Amazon API Gateway と DynamoDB を管理することができます。Amazon EKS Blueprints は、Amazon EKS クラスターのプロビジョニングと ACK コントローラーのインストールを自動化します。

ACK を使用すると、Amazon RDS、Amazon S3、AWS Lambda などのより多くの AWS サービスを Amazon EKS クラスターから作成および管理できます。 サポートされているサービス一覧は、こちらのリンクを参照してください。Amazon EKS Blueprints for Terraform は、他の多くの Kubernetes アドオンをプロビジョニングするために使用することができます。アドオンのリストはこちらのリンクを参照してください。

翻訳はプロフェッショナルサービスの藤村が担当しました。原文はこちらです。