アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

Argo CD を使ってテスト環境にデプロイした話

最近インフラの勉強を始めた komatsu です。

今回はEKSクラスター作成から ArgoCD を使ったいこーよのデプロイまでの手順とそこから学んだことを書きたいと思います。

現在、いこーよ の Rails アップデートを行っています。 その検証としてカナリアリリースを実施予定ですが、 これは本番のEKSクラスターに ArgoCD でアプリケーションを追加する作業で、ローカル環境でしたかクラスターを作ったことがない不慣れな私にはハードルが高い作業でした。

そこで、テスト用アカウント(本番とはAWS アカウントが異なる)でEKSクラスター作成から ArgoCD を使ったデプロイまでをやってみて手順を確認することにしました。
これならコマンド実行時の AWS アカウントと Context をしっかり確認すれば最悪環境をぶっ壊しても安心です。壊してもいい環境があることに感謝です。

AWS アカウント ID が 111111111111は本番アカウント、
222222222222はテスト用アカウントとします。
リポジトリ名は product とします。

現在の AWS アカウント、Context の確認方法

APIを叩くコマンドの実行前にしっかりテスト用のAWS アカウントと Context になっているかを確認します。 アカウント確認はあらゆるインフラ作業に必須の習慣ですね。

現在の AWS アカウントを確認するコマンド

aws sts get-caller-identity

現在の Context を確認するコマンド

kubectl config current-context

手順

ブランチをビルドしてイメージを作成

まずは CodeBuild で Rails アップデート用ブランチの Docker イメージを作成します。 ビルドプロジェクトはカナリアリリース時のものを使います。 できたイメージは ECR に登録されるようになっています(Buildspec ファイルに処理を記述)

本番アカウントの ECR から ローカルに pull してテスト用アカウントの ECR に push する

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/docker-pull-ecr-image.html に従って進めます。公式ドキュメントを確認するのがポイントです。

本番アカウントの ECR レジストリに対して Docker を認証

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/registry_auth.html を基にECR プライベートレジストリに対して Docker を認証します。

ここで profile を指定する場合は aws --profile prd ecr ~ にします。

aws ecr get-login-password | docker login --username AWS --password-stdin https://111111111111.dkr.ecr.ap-northeast-1.amazonaws.com
product-nginx/production を pull
docker pull 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/product-nginx/production:canarybuild-XXXXXXX
product-rails/production を pull
docker pull 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/product-rails/production:canarybuild-XXXXXXX
イメージのリポジトリ名とタグ名を変更

product-nginx/production

docker tag 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/product-nginx/production:canarybuild-XXXXXXX 222222222222.dkr.ecr.ap-northeast-1.amazonaws.com/product-nginx/production:build-XXXXXXX

product-rails/production

docker tag 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/product-rails/production:canarybuild-XXXXXXX 222222222222.dkr.ecr.ap-northeast-1.amazonaws.com/product-rails/production:build-XXXXXXX
テスト用アカウントの ECR レジストリに対して Docker を認証

profile を指定する場合は aws --profile [] ecr ~ にします。

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 222222222222.dkr.ecr.ap-northeast-1.amazonaws.com
テスト用アカウントの ECR に push する

product-nginx/production

docker push 222222222222.dkr.ecr.ap-northeast-1.amazonaws.com/product-nginx/production:build-XXXXXXX

product-rails/production

docker push 222222222222.dkr.ecr.ap-northeast-1.amazonaws.com/product-rails/production:build-XXXXXXX

push されたのを ECR で確認します。

EKSクラスターの作成

AWS CDK (TypeScript) を使って Cloud Formation 経由でEKSクラスターを作成します。 このあたりは別途学習していかないといけないですね。

デプロイ先となる環境変数 NODE_CONFIG_ENVdevelopment を設定します。

export NODE_CONFIG_ENV=development

確認する

echo $NODE_CONFIG_ENV

スタック一覧を表示してテスト用のスタックになっているか確認します。

yarn cdk list

すべてのスタックをデプロイします。yarn cdk list で確認したスタックがEKSに作られます。

yarn cdk deploy '*-stack'

AWSコンソール上でEKSクラスターが作成されたか確認します。

kubeconfig の追加

Amazon EKS の kubeconfig を作成する - Amazon EKS

aws eks update-kubeconfig ~ コマンドで ~/.kube/config にコンテキストを追加します。kubectl get nodes でクラスターにアクセスできるかとノード数を確認します。

ArgoCDでアプリケーションをデプロイ

ローカルのマニュフェストがあるディレクトリに移動します。

作業ブランチを作成

Kubernetes の YAML管理ツールとして kustomize を使用しています。 argocd/development/kustomization.yaml の patchesStrategicMerge に patch-app-revision.yaml を追加して targetRevision を HEAD(master) から今回用意するブランチ名に上書きします。 これで ArgoCD がこのブランチを監視して変更があれば自動で差分をデプロイしてくれます。
また、アプリケーションの Pod に使用するイメージのIDを書き換えます。 作業ブランチを作成してリモートリポジトリに push します。

kubectl apply を実行

いよいよデプロイですが、その前に Context を必ず確認します。

kubectl apply -k argocd/development

余談ですが、starship を導入して kubernetes の現在 Context をコマンドラインに表示すると常に確認できるのでおすすめです。
https://starship.rs/ja-jp/config/#kubernetes

ArgoCD 起動確認

apply から20分を過ぎても ArgoCD は立ち上がらない事象が発生しました。 自分では原因はわからず、有識者に調べてもらいましたが、稀に起こる事象で
たまたま ClusterAutoScaler の起動が遅くなると、ノードのリソース不足で他のもののが起動できない上に ClusterAutoScaler も起動できずにいつまでの立ち上がれないという状況になっていた。
とのことでAWSコンソールからノード数を 最小サイズ希望のサイズ を3 から 5 に変更したところ ArgoCD が立ち上がりました。 f:id:envgp:20211221194931p:plain

ブラウザ上から ArgoCD にログインして Healthy, Synced であることを確認します。 f:id:envgp:20211221143255p:plain

検証環境確認

ブラウザから検証環境にアクセスすると 503 エラーになりました。 こちらも自分では原因がわからず助けてもらいました。

下記の2つの原因を解消することでアクセスできるようになりました。手順は終了です。

原因1

EKSクラスターのノードグループ の Auto Scaling グループにロードバランサーのターゲットグループが登録されておらず通信できていませんでした。 ALBのターゲットグループがどの Node にリクエストを転送するかを設定している。 これだとまだノードのヘルスチェックがNGになりました (Health status: unhealthy)

原因2

EKSクラスターのセキュリティグループのインバウンドルールにロードバランサーのセキュリティグループが設定されていなかった。 AWSのリソース間通信は、何処とどこが通信するかを登録して、具体的なプロトコルやポート番号はセキュリティグループで設定することが多い。

料金

AWSリソースを作るため、当然料金が発生します。EKSクラスター及びインスタンス使用料金は1時間単位で請求されるので、 使わないリソースは削除するのもクラウド作業では必須の心得ですね。

感想

今の知識ではトラブルシューティングまでできないので学習と経験が必要です。 手順から作る場合は事前に手順書と解決できないエラーが発生した場合の切り戻し手順を作って有識者にレビューしてもらうのがベストですね。 インフラは奥が深いなと改めて感じた次第です。ひとまず習うより慣れろでした。

最後に

アクトインディではエンジニアを募集しています。

actindi.net