前回はシンプルなIRISアプリケーション をGoogleクラウドにデプロイしました。 今回は、同じプロジェクトを Amazon Web Services(アマゾンウェブサービス) のElastic Kubernetes Service (EKS)を使って、デプロイします。
IRISプロジェクトをあなた自身のプライベート・リポジトリにすでにFORKしていると想定します。この記事では<username>/my-objectscript-rest-docker-templateという名前にしています。 <root_repo_dir>は、そのルートディレクトリです。
開始する前に、 AWSコマンドラインインターフェースと、Kubernetesクラスタ作成用のシンプルなCLIユーティリティeksctlをインストールします。 AWSの場合 aws2 の使用を試すことができますが、ここで説明するようにkube設定ファイルでaws2の使用法を設定する必要があります 。
AWS EKS
一般的なAWSリソースと同様に、EKSは無料ではありません 。 ただし、無料利用枠のアカウントを作成して、AWSの機能を試すことができます。 ただし、試してみたい機能のすべてが無料枠に含まれているわけではないことに注意してください。 ですから、現在の予算を管理し、金銭的な問題を理解するには、 これと これを読んでください。
ここでは既にAWSアカウントとrootアクセス権があり、このrootアクセス権を使用せず、管理者権限のあるユーザーが作成されていると想定します。 このユーザーのアクセスキーと秘密キーを [dev] プロファイル(またはあなたがつけたプロファイル名)の下のAWS認証情報ファイルに配置する必要があります。
[dev]
aws_access_key_id = ABCDEFGHIJKLMNOPQRST
aws_secret_access_key = 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234
今回は、 AWS「eu-west-1」リージョンにリソースを作成しますが、あなたが今いる場所に最も近いリージョンを選択し、以下に記載されている「eu-west-1」のすべてを選択したリージョンで置き換えてください。
ちなみに、必要なすべてのファイル(.circleci 、eks/、k8s/)も、ここに保存されており 、簡単にコピーと貼り付けができます。 必要なすべてのEKSリソースは最初から作成されます。 Amazon EKS Workshop は、良いリソースだと思います。
次に、AWSへのアクセスを確認します(ここではダミーのアカウントを使用しています)。
$ aws sts get-caller-identity
{
"Account": "012345678910",
"UserId": " ABCDEFGHIJKLMNOPQRSTU",
"Arn": "arn:aws:iam::012345678910:user/FirstName.LastName"
}
$ eksctl version
[ℹ] version.Info{BuiltAt:"", GitCommit:"", GitTag:"0.10.2"}
すべてのデフォルト設定が適切であるという事実に従い、「 eksctl create cluster <cluster_name> --region eu-west-1 」を実行することもできますし、設定ファイルを作成して独自の設定を管理することもできます。
後者は、そのようなファイルをバージョン管理システム(VCS)に保存できるため、よりよい方法です。設定の例はここにあります。 さまざまな設定に関するここの記述を読んだら、独自の設定を作成してみましょう。
$ cat cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: dev-cluster
region: eu-west-1
version: '1.14'
vpc:
cidr: 10.42.0.0/16
nat:
gateway: Single
clusterEndpoints:
publicAccess: true
privateAccess: false
nodeGroups:
- name: ng-1
amiFamily: AmazonLinux2
ami: ami-059c6874350e63ca9 # AMI is specific for a region
instanceType: t2.medium
desiredCapacity: 1
minSize: 1
maxSize: 1
# Worker nodes won't have an access FROM the Internet
# But have an access TO the Internet through NAT-gateway
privateNetworking: true
# We don't need to SSH to nodes for demo
ssh:
allow: false
# Labels are Kubernetes labels, shown when 'kubectl get nodes --show-labels'
labels:
role: eks-demo
# Tags are AWS tags, shown in 'Tags' tab on AWS console'
tags:
role: eks-demo
# CloudWatch logging is disabled by default to save money
# Mentioned here just to show a way to manage it
#cloudWatch:
# clusterLogging:
# enableTypes: []
「nodeGroups.desiredCapacity = 1」は本番環境では意味がありませんが、デモでは問題ありません。
また、AMIイメージはリージョン間で異なる可能性があることに注意してください。 「amazon-eks-node-1.14」を探し、最新の1つを選択します。
次に、クラスター(コントロールプレーンとワーカーノード)を作成します。
ちなみに、クラスターが不要になった場合は、以下を使用してクラスターを削除できます。
クラスターの作成には約15分かかります。 この間、eksctlの出力を確認できます。
CloudFormationコンソールを参照すると、2つのスタックがあります。それぞれにドリルダウンして、[リソース] タブを参照すると、何が作成されるかを正確に確認でき、[イベント] タブで、リソース作成の現在の状態を確認できます。
クラスターは正常に作成されましたが、eksctl の出力で「EKSクラスターでkubectlを使用できません」というメッセージがあり、接続に問題があったことがわかります。
aws-iam-authenticator(IAM)をインストールしてkubeコンテキストを作成し、これを解決しましょう。
/usr/local/bin/aws-iam-authenticator
$ aws eks update-kubeconfig --name dev-cluster --region eu-west-1
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-42-140-98.eu-west-1.compute.internal Ready <none> 1m v1.14.7-eks-1861c5
これで動作するはずですが、管理者権限を持つユーザーでクラスターを作成しました。 CircleCIからの通常のデプロイ処理では、プログラムによるアクセスのみで、次のポリシーが付与されている特別なAWSユーザー(この例ではCircleCIと名付けられたユーザー)を作成する と良いでしょう。
最初のポリシーはAWSに組み込まれているため、それを選択するだけで済みます。 2つ目は自分で作成する必要があります。 作成プロセスの説明はここにあります。 ポリシー「 AmazonEKSDescribePolicy 」は次のようになります。
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"eks:DescribeCluster",
"eks:ListClusters"
],
"Resource": "*"
}
]
}
ユーザーの作成後、ユーザーのアクセスキーと秘密のアクセスキーを保存します。これらのキーはすぐに必要になります。
また、この記事で説明されているように、Kubernetesクラスター内でこのユーザー権限を付与したいと考えています。 つまり、EKSクラスターを作成した後は、IAMユーザー、すなわち作成者のみがそれにアクセスできます。 CircleCIユーザーを追加するには、クラスターのAWS認証設定(configmap aws-auth、 'data'セクション)のデフォルトの空の「mapUsers」セクションをkubectl editを使って(‘01234567890’の代わりに自分のアカウントIDを使います)次の行に置き換える必要があります。
...
data:
...
mapUsers: |
- userarn: arn:aws:iam::01234567890:user/CircleCI
username: circle-ci
groups:
- system:masters
以前の記事ののKubernetesマニフェストを使用します (「Googleクラウドの前提条件」のセクションを参照)。以前のやり方と違う点は、デプロイのイメージフィールドでプレースホルダを使うということだけです。 これらのマニフェストを<root_repo_dir>/k8sディレクトリに保存します。 デプロイファイルの名前がdeployment.tplに変更されたことに注意してください。
...
spec:
containers:
- image: DOCKER_REPO_NAME/iris-rest:DOCKER_IMAGE_TAG
...
CircleCI
CircleCI側のデプロイ処理は、GKEに使用される処理に似ています。
- リポジトリをPullする
- Dockerイメージをビルドする
- Amazon クラウドで認証する
- イメージをAmazon Elastic Container Registry(ECR)にアップロードする
- このイメージを基にしたAWS EKSでコンテナを実行する
前回と同様に、作成およびテスト済みのCircleCI構成テンプレートorbsを利用します。
- イメージを構築してECRにPushするためのaws-ecr orb
- AWS認証のためのaws-eks orb
- Kubernetesマニフェストのデプロイのためのkubernetes orb
デプロイ構成は次のようになります。
version: 2.1
orbs:
aws-ecr: circleci/aws-ecr@6.5.0
aws-eks: circleci/aws-eks@0.2.6
kubernetes: circleci/kubernetes@0.10.1
jobs:
deploy-application:
executor: aws-eks/python3
parameters:
cluster-name:
description: |
Name of the EKS cluster
type: string
aws-region:
description: |
AWS region
type: string
account-url:
description: |
Docker AWS ECR repository url
type: string
tag:
description: |
Docker image tag
type: string
steps:
- checkout
- run:
name: Replace placeholders with values in deployment template
command: |
cat k8s/deployment.tpl |\
sed "s|DOCKER_REPO_NAME|<< parameters.account-url >>|" |\
sed "s|DOCKER_IMAGE_TAG|<< parameters.tag >>|" > k8s/deployment.yaml; \
cat k8s/deployment.yaml
- aws-eks/update-kubeconfig-with-authenticator:
cluster-name: << parameters.cluster-name >>
install-kubectl: true
aws-region: << parameters.aws-region >>
- kubernetes/create-or-update-resource:
action-type: apply
resource-file-path: "k8s/namespace.yaml"
show-kubectl-command: true
- kubernetes/create-or-update-resource:
action-type: apply
resource-file-path: "k8s/deployment.yaml"
show-kubectl-command: true
get-rollout-status: true
resource-name: deployment/iris-rest
namespace: iris
- kubernetes/create-or-update-resource:
action-type: apply
resource-file-path: "k8s/service.yaml"
show-kubectl-command: true
namespace: iris
workflows:
main:
jobs:
- aws-ecr/build-and-push-image:
aws-access-key-id: AWS_ACCESS_KEY_ID
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
region: AWS_REGION
account-url: AWS_ECR_ACCOUNT_URL
repo: iris-rest
create-repo: true
dockerfile: Dockerfile-zpm
path: .
tag: ${CIRCLE_SHA1}
- deploy-application:
cluster-name: dev-cluster
aws-region: eu-west-1
account-url: ${AWS_ECR_ACCOUNT_URL}
tag: ${CIRCLE_SHA1}
requires:
- aws-ecr/build-and-push-image
ワークフローのセクションにはジョブリストが含まれ、各ジョブはaws-ecr/build-and-push-imageなどのorbから呼び出すか、構成で「deploy-application」を使って直接定義できます。
次のコードは、aws-ecr/build-and-push-imageジョブが終了した後で、deploy-applicationジョブが呼び出されることを意味します。
- aws-ecr/build-and-push-image
[ジョブ] セクションには、デプロイ・アプリケーションジョブの説明と、次のような定義された手順のリストが含まれています。
- checkoutで、GitリポジトリからPullする
- runで、Docker-imageリポジトリとタグを動的に設定するスクリプトを実行する
- aws-iam-authenticatorを使用する aws-eks /update-kubeconfig-with-authenticatorを使用して Kubernetesへの接続を設定する
- CircleCIから「kubectl apply」を実行する方法として数回使用されるkubernetes/create-or-update-resource
変数を使用しますが、もちろんそれらはCircleCIの「環境変数」タブで定義する必要があります。
次の表は、使用される変数の意味を示しています。
AWS_ACCESS_KEY_ID |
CircleCI IAMユーザーのアクセスキー |
AWS_SECRET_ACCESS_KEY |
CircleCI IAMユーザーの秘密キー |
AWS_REGION |
eu-west-1、この場合 |
AWS_ECR_ACCOUNT_URL |
01234567890.dkr.ecr.eu-west-1.amazonaws.comなどのAWS ECR Docker レジストリのURL 「01234567890」がアカウント IDの場合 |
デプロイ処理をトリガーする方法は次のとおりです。
$ git commit -m “AWS EKS deployment”
$ git push
これにより、このワークフローにおける2つのジョブが表示されます。
どちらのジョブもクリック可能であり、これにより、実行した手順の詳細を確認できます。
デプロイには数分かかります。 完了したら、KubernetesリソースとIRISアプリケーション自体のステータスを確認できます。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
iris-rest LoadBalancer 172.20.190.211 a3de52988147a11eaaaff02ca6b647c2-663499201.eu-west-1.elb.amazonaws.com 52773:32573/TCP 15s
DNSレコードが反映されるまで数分かかります。 それまでは、curlを実行すると「ホストを解決できませんでした」というエラーが表示されます。
[{"Name":"John Dou"},]
まとめ
一見するとAWS EKSへのデプロイはGKEへのデプロイよりも複雑に見えますが、それほど大きな違いはありません。 組織でAWSを使用している場合は、Kubernetesをスタックに追加する方法を理解されたと思います。
最近、EKS APIが拡張され、管理グループをサポートできるようになりました。これにより、コントロールプレーンとデータプレーンを全体としてデプロイでき、これは将来有望と思われます。 さらに、コンテナ用のAWSサーバーレスコンピューティングエンジンであるFargateが利用可能になりました。
最後に、AWS ECRに関する簡単な注意事項を記します:イメージにライフサイクルポリシーを設定することを忘れないでください。
InterSystems Open Exchangeで関連アプリケーション をご確認ください。