Amazon Web Services ブログ
Amazon API Gateway を Amazon EKS における Ingress として利用する
2023/09/13 追記 : この記事で紹介している Amazon API Gateway Ingress Controller プロジェクトは、現在メンテナンスされていません。そのため、Amazon EKS と Amazon API Gateway の連携については、代わりに AWS Controller for Kubernetes (ACK) プロジェクトの利用を検討してください。連携方法の詳細は、Integrate Amazon API Gateway with Amazon EKS でご確認いただけます。
チームが Amazon EKS にマイクロサービスをデプロイすると、通常、フロントエンドおよびサードパーティーアプリケーションで使用する REST API を公開します。ベストプラクティスは、これらの API を API Gateway で管理することです。
これにより、API の一意のエントリポイントが提供され、各マイクロサービスのセキュリティ、キャッシュ、スロットル、監視などの API 固有のコードを実装する必要もなくなります。このパターンは、ALB Ingress Controller と Amazon API Gateway を使用して実装できます。Amazon API Gateway は、あらゆる規模でセキュアな API を管理するための完全マネージドサービスです。このアプローチは機能しますが、いくつかの構成ファイルを作成する必要があります。このタスクをどのように自動化できますか?
この記事では、オープンソースソリューション API Gateway Ingress Controller の使用方法を示します。これは、Amazon API Gateway の HTTP プロキシモードを活用して Amazon EKS で実行する API をすばやく設定することで、手動手順を削減します。API Gateway Ingress Controller は、リバースプロキシポッドの前に Network Load Balancer を構成します。これは、パスベースのルーティングを処理し、HTTP リクエストをポッドにルーティングします。次の図は、この記事で説明した高レベルのアーキテクチャを示しています。
Kubernetes Ingress と Amazon API Gateway Ingress Controller の連携方法
次の図は、ユーザーが Ingress リソースを作成するときに Amazon API Gateway Ingress Controller によって作成される AWS コンポーネントの詳細を示しています。Ingress リソースは、API Gateway VPC リンクを介してプライベート Network Load Balancer を使用して、API Gateway から Kubernetes クラスターに Ingress トラフィックをルーティングします。
Ingress の作成
上の図で青い丸の番号付き手順通りに実行します。
- API Gateway Ingress Controller は、API サーバーからの Ingress イベントを監視します。要件を満たす Ingress リソースを見つけると、AWS リソースの作成を開始します。
- API Gateway API が作成され、Ingress アノテーションで説明されている指定済みの API Gateway ステージが作成されます。
- Ingress リソース用にプライベート Network Load Balancer が作成され、パス構成で指定されたすべてのポートに対してリスナーが作成されます。
- API Gateway がプライベート Network Load Balancer と通信するために、プライベート API Gateway VPC リンクが作成されます。
- ターゲットグループは、Ingress リソースで指定されたリバースプロキシ用に作成されます。
- API Gateway Ingress Controller は NGINX をリバースプロキシとしてデプロイし、Ingress リソースで指定された各パスに対してリバースプロキシのルールが作成されます。これにより、特定のパスへのトラフィックが正しいポッドにルーティングされるようになります。
手順 1:AWS Cloud9 IDE を作成する
このブログの指示を作成するために使用された AWS Cloud9 IDE を使用することをお勧めします。
AWS Cloud9 環境を作成する
この deep-link 通りに、オレゴンリージョンで作成してください
- [eksworkshop] という名前を付けて、[次へ] をクリックします。
- インスタンスタイプに [t2.small] を選択し、すべてのデフォルト値を取得して、[環境を作成] をクリックします
- 起動したら、[ようこそ] タブと下の作業領域を閉じて、メインの作業領域で新しい [ターミナル] タブを開いて、環境をカスタマイズします。
WorkSpace の IAM ロールを作成します
- この deep-link 通りに、AdministratorAccess で IAM ロールを作成します。
- AWS サービスと EC2 が選択されていることを確認し、[次へ] をクリックして権限を表示します。
- AdministratorAccess がチェックされていることを確認し、[次へ: タグ] をクリックしてタグを割り当てます。
- デフォルトを使用し、[次へ: レビュー] をクリックしてレビューします。
- 名前に [eksworkshop-admin] と入力し、[ロールを作成] をクリックします。
IAM ロールを WorkSpace にアタッチします
- この deep-link 通りに、AWS Cloud9 EC2 インスタンスを見つけてください
- インスタンスを選択し、[アクション] / [インスタンス設定] / [IAM ロールをアタッチ/置換] を選択します
- IAM ロールのドロップダウンから eksworkshop-admin を選択し、[適用] を選択します
WorkSpace の IAM 設定を更新する
- WorkSpaces の右上隅にある clog をクリックします
- AWS 設定を選択
- AWS マネージドの一時認証情報をオフにする
- [設定] タブを閉じます
一時的な認証情報がまだ設定されていないことを確認するために、既存の認証情報ファイルも削除します。
rm -vf ${HOME}/.aws/credentials
GetCallerIdentity CLI コマンドを使用して、AWS Cloud9 IDE が正しい IAM ロールを使用していることを検証します。
aws sts get-caller-identity
#The output assumed-role name should contain
eksworkshop-admin
kubectl およびその他のツールをインストールする
kubectl インストールの詳細については、kubectl のインストールを参照してください。
sudo curl --silent --location -o /usr/local/bin/kubectl \
https://amazon-eks.s3-us-west-2.amazonaws.com/1.14.6/2019-08-22/bin/linux/amd64/kubectl
sudo chmod +x /usr/local/bin/kubectl
jq、envsubst (GNU gettext ユーティリティから)、および bash-completion をインストールします
sudo yum -y install jq gettext bash-completion
eksctl バイナリをダウンロードしてインストールします
curl --silent --location \
"https://github.com/weaveworks/eksctl/releases/download/latest_release/eksctl_$(uname -s)_amd64.tar.gz" \
| tar xz -C /tmp
sudo mv -v /tmp/eksctl /usr/local/bin
eksctl コマンドが機能することを確認します
eksctl version
ブログの GitHub プロジェクトを複製します。このブログに必要なすべての YAML ファイルが含まれています。
cd ~/environment/
git clone https://github.com/aws-samples/amazon-apigateway-ingress-controller-blog.git
手順 2: Amazon EKS クラスターを作成する
eksctl を使用して、Amazon EKS クラスターとノードを起動して構成します。
eksctl create cluster --name=eksworkshop-blog --nodes=3 --region=us-west-2
Amazon EKS クラスターの作成には最大 15 分かかります。クラスターが実行されたら、次のコマンドを実行してクラスターにアクセスできます。
kubectl get nodes
# 3 つのノードが表示された場合、正しく認証されたことがわかり、クラスターが起動されます
手順 3:kube2iam ロールを設定する
Amazon API Gateway Ingress Controller には、AWS リソースを作成するための 4 つのポリシー (AutoScallingFullAccess、AmazonAPIGatewayAdministrator、AmazonVPCFullAccess、および AWSCloudFormationFullAccess) が必要です。1 つのオプションは、これらのポリシーをノードのインスタンスロールに追加することですが、推奨しません。 サービスアカウントの IAM ロールが最適なオプションです。現在、API Gateway Ingress Controller はこのオプションをサポートしていません。プロジェクトの予定リストにあります。Ingress Controller ポッドにロールを割り当てるために kube2iam をセットアップします。このロールを作成しましょう。
ノードのロールを取得する
クラスターのノードにロール名を付けるには、次の 3 つのコマンドが必要です。
STACK_NAME=$(eksctl get nodegroup --cluster eksworkshop-blog -o json | jq -r '.[].StackName')
ROLE_NAME=$(aws cloudformation describe-stack-resources --stack-name $STACK_NAME | jq -r '.StackResources[] | select(.ResourceType=="AWS::IAM::Role") | .PhysicalResourceId')
aws iam get-role --role-name $ROLE_NAME | jq -r .Role.Arn
# ノードのロール Arn を表示し、コピーします
~/environment/apigw-ingress-controller-blog/kube2iam-ingress-trust-policy.yml を編集し、ロール ARN を置き換えます。
.....
"Principal": {
"AWS": "arn:aws:iam::xx:role/eksctl-eksworkshop-blog-nodegroup-NodeInstanceRole-xxxxxx"
},
......
Kube2Iam ロールを作成する
kub2iam-ingress-role という名前のロールを作成します。名前は ~/environment/apigw-ingress-controller-blog/AmazonAPIGWHelmChart/template/statefulset.yaml
で設定されているため重要です。
cd ~/environment/apigw-ingress-controller-blog
aws iam create-role --role-name kube2iam-ingress-role \
--assume-role-policy-document file://kube2iam-ingress-trust-policy.yml
4 つのポリシーを kub2iam-ingress-role に追加する必要があります。Amazon API Gateway Ingress Controller はこれを使用して AWS リソースを作成します。
aws iam attach-role-policy --role-name kube2iam-ingress-role --policy-arn \
arn:aws:iam::aws:policy/AutoScalingFullAccess
aws iam attach-role-policy --role-name kube2iam-ingress-role --policy-arn \
arn:aws:iam::aws:policy/AmazonAPIGatewayAdministrator
aws iam attach-role-policy --role-name kube2iam-ingress-role --policy-arn \
arn:aws:iam::aws:policy/AmazonVPCFullAccess
aws iam attach-role-policy --role-name kube2iam-ingress-role --policy-arn \
arn:aws:iam::aws:policy/AWSCloudFormationFullAccess
aws iam attach-role-policy --role-name kube2iam-ingress-role --policy-arn \
arn:aws:iam::aws:policy/ElasticLoadBalancingFullAccess
手順 4:Helm をセットアップしてチャートをデプロイする
現在、API Gateway Ingress Controller は Helm チャートとして利用できます。以下の手順通りに、Helm をインストールします。
Helm CLI をインストールする
cd ~/environment
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
chmod +x get_helm.sh
./get_helm.sh
RBAC を使用して Helm アクセスを構成する
cd ~/environment/apigw-ingress-controller-blog
kubectl apply -f helm-rbac.yml
helm init --service-account tiller
kube2iam チャートをデプロイする
kube2iam Helm チャートをインストールします。
helm install \
--set rbac.create=true \
--set host.iptables=true \
--set host.interface=eni+ \
--set=extraArgs.auto-discover-base-arn= \
stable/kube2iam
kube2iam ポッドがインストールされ、実行されていることを確認します。
kubectl get pods
# 名前に kube2iam を含む 3 つのポッドが表示されます
# ポッドの 1 つのログを表示し、ポッド名を置き換えます
kubectl logs xxxx-kube2iam-xxx
# ログには「ベース ARN 自動検出」が含まれている必要があります
time="2019-12-27T23:08:26Z" level=info msg="base ARN autodetected, arn:aws:iam::xx:role/"
API Gateway Ingress Controller チャートをデプロイ
API Ingress Controller Helm チャートをインストールします。
cd ~/environment/apigw-ingress-controller-blog/AmazonAPIGWHelmChart
helm install --debug ./amazon-apigateway-ingress-controller \
--set image.repository="karthikk296d/aws-apigw-ingress-controller"
API Gateway Ingress Controller がインストールされていることを確認し、次のコマンドを実行します。
kubectl get pods
# apigw イングレスコントローラのポッドが 1 つ表示されます
NAME READY STATUS RESTARTS AGE
virtuous-markhor-amzn-apigw-ingress-controller-0 1/1 Running 0 22s 26s
手順 5:サンプル REST API をデプロイする
書籍と著者をデプロイする: このブログのサンプルマイクロサービスです。
cd ~/environment/apigw-ingress-controller-blog
kubectl apply -f book-deployment.yml
kubectl apply -f book-service.yml
kubectl apply -f author-deployment.yml
kubectl apply -f author-service.yml
本と著者はどのタイプのサービスですか? book-service.yml を覗いてみましょう。書籍サービスと著者サービスは、どちらも ClusterIP タイプです。ClusterIP は、Amazon EKS クラスター内からのみ呼び出すことができます。
......
name: bookservice
spec:
type: ClusterIP
selector:
app: books
....
これで、クラスターで次のポッドが実行されていることがわかります。
kubectl get pods
# 実行中の著者と書籍ポッドが表示されます
NAME READY STATUS RESTARTS AGE
author-deployment-658d67f7dc-9z4r6 1/1 Running 0 14m
book-deployment-577b7577ff-pn5ng
また、次のサービスが実行されていることがわかります。
kubectl get svc
# authorservice と booksservice が実行されます
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
authorservice ClusterIP 10.100.10.144 <none> 80/TCP 15m
bookservice ClusterIP 10.100.128.1 <none> 80/TCP 15m
手順 6:API Gateway Ingress Controller リソースをデプロイする
API Gateway Ingress は現在、IAM 認証を使用して REST API を保護しています。サンプル REST API を呼び出すために使用するユーザーを作成しましょう。
aws iam create-user --user-name apigw-user
# apigw-user という名前のユーザーが作成されます
~/environment/apigw-ingress-controller-blog/api_ingress.yml の apigateway.ingress.kubernetes.io/client-arns デフォルトユーザー ARN をapigw-user の Arn に置き換えます。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
*# arn::foo,arn::bar を apigw-user の Arn に置き換えます*
apigateway.ingress.kubernetes.io/client-arns: arn:aws:iam::xxxxx:user/apigw-user
apigateway.ingress.kubernetes.io/stage-name: prod
kubernetes.io/ingress.class: apigateway
name: api-95d8427d
namespace: default
spec:
rules:
- http:
paths:
- backend:
serviceName: bookservice
servicePort: 80
path: /api/book
- backend:
serviceName: authorservice
servicePort: 80
path: /api/author
api_ingress.yml ファイルを編集したら、次のコマンドを実行してデプロイします。
cd ~/environment/apigw-ingress-controller-blog/
kubectl apply -f api_ingress.yml
Ingress が稼働していることを確認します。
kubectl get ingress
# api-95d8427d という名前の 1 つのイングレスがデプロイされます
リバースプロキシのデプロイを確認します。
kubectl get pods
# 3 つのリバースプロキシポッドが実行されています
NAME READY STATUS RESTARTS AGE
api-95d8427d-reverse-proxy-5fc845fc67-bx7t2 1/1 Running 0 4s
api-95d8427d-reverse-proxy-5fc845fc67-d7gxf 1/1 Running 0 4s
api-95d8427d-reverse-proxy-5fc845fc67-mttkm 1/1 Running 0 4s
Ingress リソース作成の進行状況を確認するには、xxxx-amzn-apigw-ingress-controller ポッドのログを表示します。AWS マネジメントコンソール CloudFormation を使用して進行状況を表示することもできます。
kubectl logs xxxx-markhor-amzn-apigw-ingress-controller-0 -f
# 作成中、メッセージが表示されます
"Not complete, requeuing","status":"CREATE_IN_PROGRESS"}
# すべてのリソースは約 15 分で作成されます
{"level":"info",........,"msg":"Stack Create/Update Complete"}
手順 7: デプロイをテストする
API Gateway コンソールで api-95d8427d の作成を確認します。
api-95d8427d をクリックして、構成を確認しましょう。
左側のメニューでリソース VPC リンクをクリックします。これは、Amazon API Gateway Ingress Controller によって作成されました。Amazon Virtual Private Cloud (VPC) 内の HTTP リソースへのアクセスを、パブリックインターネットに直接公開することなく提供します。
リソースポリシーの左メニューをクリックし、リソースポリシーを使用して、Amazon API Gateway Ingress Controller がこのプライベート API へのアクセス制御を設定しました。
左側にあるメニューのステージリンクをクリックすると、prod ステージが表示されます。/api/author をクリックしてから、メソッド取得をクリックします。API の呼び出し URL が表示されたら、コピーします。
apigw-user のアクセスキーとシークレットキーを使用して API を呼び出しましょう。このコマンドで認証情報を取得できます。
aws iam create-access-key --user-name apigw-user
# 出力からアクセスキーとシークレットキーをコピーし、
# API の呼び出しに使用できるようにします
{
"AccessKey": {
"UserName": "apigw-user",
"Status": "Active",
"CreateDate": "2019-12-26T22:11:34Z",
"SecretAccessKey": "xxxxx",
"AccessKeyId": "xxxxx"
}
}
API を呼び出すときに一時的な認証情報を使用することをお勧めします。AWS STS get-session-token コマンドを使用して、一時的な認証情報を取得できます。このコマンドの使用方法については、こちらをご覧ください。
Postman を使用して REST API を呼び出し、コピーした API URL を貼り付け、URL の末尾に次の /api/author/list があることを確認します。
[認証] タブをクリックし、アクセスキーとシークレットキー、およびオプションでセッショントークンを指定して、[送信] をクリックします。
リクエストの出力として著者一覧が表示されます。次の API URL を試して、さまざまな出力を確認できます。
# API URL を次のように変更して、書籍リストを取得します
https://xxxxxxx.execute-api.us-east-1.amazonaws.com/prod/api/book/list
# ISBN13 の 1 つを出力からコピーし、API URL を次のように変更します
https://xxxxxxx.execute-api.us-east-1.amazonaws.com/prod/api/book/9781617293825
クリーンアップ
クリーンアップするために、デプロイとサービスを削除しましょう。
cd ~/environment/api-gateway-ingress-blog/
kubectl delete -f book-deployment.yml
kubectl delete -f book-service.yml
kubectl delete -f author-deployment.yml
kubectl delete -f author-service.yml
API Gateway Ingress Controller を削除すると、Network Load Balancer、API Gateway API、および作成した他のリソースが削除されます。
kubectl delete ingress api-95d8427d
API Gateway Ingress Controller の Helm チャートを削除します
# 次のコマンドを使用して、API Gateway イングレスチャートの名前を取得します
helm ls
# チャートの名前は異なります
NAME REVISION STATUS CHART APP VERSION NAMESPACE
lame-fox 1 DEPLOYED amazon-apigateway-ingress-controller-0.1.0 1.0 default
NAME CHART
filled-butterfly amazon-apigateway-ingress-controller-0.1.0
newbie-narwhal kube2iam-2.1.0
# 次のコマンドを発行して、両方の Helm チャートを削除します
helm delete filled-butterfly
helm delete newbie-narwhal
Amazon EKS クラスターが不要な場合は、削除できます。
eksctl delete cluster --name=eksworkshop-blog
お試しください
Amazon API Gateway Ingress Controller は、Karthikk Dhandapani と Anand Modh によって維持されている完全にオープンソースのプロジェクトです。Karthikk と Anand は、Amazon のシステム開発エンジニアです。彼らは、Amazon Fulfillment Technologies 内の Amazon EKS の顧客であり、自動化に夢中になっています。彼らは、コンテナ化されたサーバーレスアプリケーションを構築することを好みます。AWS チームは、Amazon EKS で Ingress Controller のテストも行っており、現在、Kubernetes バージョン 1.14 をサポートしています。
その他リソース: