AWS上で動くKubernetesクラスタのためのCI/CDパイプライン
17590 ワード
- いろいろと苦戦したのでまとめます
前提
- クラウドはAWS
- ソース管理はCodeCommit
- ビルド環境はCodeBuild
- 同じAWSのアカウント上で稼働しているKubernetesクラスタがデプロイターゲット
- マニフェストファイルはHelmチャートで管理
- アプリケーション毎にHelmチャートのリポジトリが存在する
- Spinnakerが使える状態にある
却下案1(CodePipelineですべて管理)
- CodeCommit
- CodeBuild(ビルド用)
- CodeBuild(デプロイ用)
- CodeCommit
- CodeBuild(ビルド用)
- CodeBuild(デプロイ用)
概要
- 大前提として、AWSにはKubernetesにデプロイするサービスが無い
- そのため、デプロイの実装 or デプロイツールの構築が必要になる
- ここではデプロイ用のCodeBuildを作成し、BuildSpecにデプロイコマンドを記載(Helmを使用しているのでHelmコマンド)
- デプロイ用のBuildSpecもアプリ毎に作る必要がある
-
helm install
(初回のデプロイ)とhelm upgrade
(2回目以降のデプロイ)を使い分けないといけない- これはHelmを使わなければ回避できる
- CodeBuildの本来の使用用途に合ってない感がすごい
却下案2(全てSpinnakerで管理)
- CodeCommit
- Spinnaker
- CodeCommitへのPushをトリガーにAPIでSpinnakerのパイプラインをスタート
- API(POST)→LambdaでCodeBuildを叩き、随時API(GET)→LambdaでCodeBuildのStatusを取得
- Spinnakerのステージとしては「Webhook」で作成する
- StatusがSucceededになったらのデプロイ
- Spinnakerのステージとしては「Bake」と「Deploy」
- CodeCommitへのPushをトリガーにAPIでSpinnakerのパイプラインをスタート
- API(POST)→LambdaでCodeBuildを叩き、随時API(GET)→LambdaでCodeBuildのStatusを取得
- Spinnakerのステージとしては「Webhook」で作成する
- StatusがSucceededになったらのデプロイ
- Spinnakerのステージとしては「Bake」と「Deploy」
概要
CDツールのSpinnakerだが、こちらでBuildの状況なども管理するやり方(こちらも本来の使い方とは違うと思いますが)
アプリ毎にAPI GatewayとLambda3つ(パイプライン開始用、CodeBuild開始用、CodeBuildのStatus取得用)を作成する必要がある、、、管理したくない
採用案
- CodePipeline(CI)
- CodeCommit
- CodeBuild
- Spinnaker(CD)
概要
- 却下案1と却下案2の良いところを合わせたような構成
- CodePipelineでCodeBuildでのビルドまでを管理し、CDはSpinnakerで実行
- SpinnakerのパイプラインでトリガーをWebhookに設定しておき、CodeBuildの最後にそのURLを叩く
- 開発環境・本場環境で別々のCodeBuildを作成し、それぞれのCodePipelineを定義する
- CodeCommit
- CodeBuild
CI(開発環境)
CodeBuildの作成
-
CodeBuildでやりたいことは以下の通り
- ソースコードのビルド、テスト
- Dockerイメージのビルド、プッシュ
- S3へHelmChartをアップロード
- S3経由でSpinnakerに渡すため
- Spinnakerのパイプライン開始
-
CodeBuildの設定
- 対象のソースコードと、Helmチャートが格納されているリポジトリのdevelopブランチを「Source」に指定する
- 公式で提供されているCodeBuild用のDockerイメージ を基に、以下のパッケージを追加
- helm
- yq
- yamlを操作するツール
- NAT Gatewayが作成されているSubnetを含むVPC内で稼働させる
- Spinnakerに紐付くセキュリティグループにこのIPアドレスを指定してパイプラインを始められるようにするため
- HelmチャートをアップロードするS3バケットをArtifactsに指定しておく
Buildspec
- コメントで概要を記載
buildspec.yaml
version: 0.2
env:
variables:
REGION_NAME: "ap-northeast-1"
REPOSITORY_NAME: "test"
BRANCH_NAME: "develop"
ECR_REPOSITORY: "XXXXXXXXXXX.dkr.ecr.$REGION_NAME.amazonaws.com/xxxxxxx"
# Helmチャートの名前
CHART_NAME: "test"
# Helmチャートをアップロードするバケット内のパス
ARTIFACT_PATH: "test-dev"
# Spinnakerのパイプラインでトリガーに設定しているURL
URL : "deploy-test-dev"
phases:
install:
# Dockerデーモンの起動
runtime-versions:
docker: 18
commands:
- nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 --storage-driver=overlay&
- timeout 15 sh -c "until docker info; do echo .; sleep 1; done"
pre_build:
commands:
- $(aws ecr get-login --no-include-email --region $REGION_NAME)
build:
commands:
# - ソースのビルドがあればここに記載
# CODEBUILD_SRC_DIRは後述
- cd $CODEBUILD_SRC_DIR
- docker build -t tmp:latest .
post_build:
commands:
# CODEBUILD_RESOLVED_SOURCE_VERSIONは、CodeBuildの環境にデフォルトで設定されている環境変数
# 対象のソースのコミットIDが設定されている
# ここではビルドするDockerイメージのタグとして使用する
- COMMIT_ID_APP=`echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-8`
- docker tag tmp:latest $ECR_REPOSITORY:$COMMIT_ID_APP
- docker push $ECR_REPOSITORY:$COMMIT_ID_APP
# CODEBUILD_SRC_DIR_infは後述
- cd $CODEBUILD_SRC_DIR_inf
# Helmチャートのvalues.yamlにデプロイ対象のDockerイメージのタグが記載されている
# これを先ほど取得したコミットIDに書き換え
# 更新ができなかったので、一時的にtmp.yamlという名前で保存→既存のvalues.yamlと置き換えを行なっている
- yq -y '.image.tag |= "'$COMMIT_ID_APP'"' $CHART_NAME/values.yaml > $CHART_NAME/tmp.yaml
- mv $CHART_NAME/tmp.yaml $CHART_NAME/values.yaml
# packageコマンドでtgz形式に変換
# この形式でSpinnakerに渡すことができる
- helm package $CHART_NAME
# S3にアップロード
- aws s3 cp $CHART_NAME*.tgz s3://[backet name]/$ARTIFACT_PATH/$CHART_NAME.tgz
# Spinnakerのパイプラインを開始
- curl https://XXXXXXXXXX.com/webhooks/webhook/$URL -X POST -d "{ }" -H "content-type:application/json"
CODEBUILD_SRC_DIRについて
- CodeBuildでは、Sourceに指定したソースコードやファイルがCodeBuildの環境にマウントされている
- CODEBUILD_SRC_DIRにはSource1に指定したSourceのパスが設定されており、例えばリポジトリを設定しておけば、
cd $CODEBUILD_SRC_DIR
コマンドでそのレポジトリのソースが格納されたパスに移動できる
- 2つ以上のSourceを指定することもでき、2つ目以降はSource identiferを指定する。ここでは2つ目のSourceにinfというSource identiferを指定したため、CODEBUILD_SRC_DIR_infにそのSourceのパスが設定されている。つまり、CODEBUILD_SRC_DIR_[自分で設定したidentifer]という環境変数で呼び出すことができる
CodePipeline
- 対象のCodeCommitのリポジトリのdevelopブランチと対象のCodeBuildを指定して保存
- これにより、developブランチへのpushをトリガーにこのパイプラインか開始される
CD(開発環境)
Spinnakerでのパイプランの作成
- Application→Actions→「Create Application」からApplicationを作成
CodeBuildでやりたいことは以下の通り
- ソースコードのビルド、テスト
- Dockerイメージのビルド、プッシュ
- S3へHelmChartをアップロード
- S3経由でSpinnakerに渡すため
- Spinnakerのパイプライン開始
CodeBuildの設定
- 対象のソースコードと、Helmチャートが格納されているリポジトリのdevelopブランチを「Source」に指定する
- 公式で提供されているCodeBuild用のDockerイメージ を基に、以下のパッケージを追加
- helm
- yq
- yamlを操作するツール
- NAT Gatewayが作成されているSubnetを含むVPC内で稼働させる
- Spinnakerに紐付くセキュリティグループにこのIPアドレスを指定してパイプラインを始められるようにするため
- HelmチャートをアップロードするS3バケットをArtifactsに指定しておく
buildspec.yaml
version: 0.2
env:
variables:
REGION_NAME: "ap-northeast-1"
REPOSITORY_NAME: "test"
BRANCH_NAME: "develop"
ECR_REPOSITORY: "XXXXXXXXXXX.dkr.ecr.$REGION_NAME.amazonaws.com/xxxxxxx"
# Helmチャートの名前
CHART_NAME: "test"
# Helmチャートをアップロードするバケット内のパス
ARTIFACT_PATH: "test-dev"
# Spinnakerのパイプラインでトリガーに設定しているURL
URL : "deploy-test-dev"
phases:
install:
# Dockerデーモンの起動
runtime-versions:
docker: 18
commands:
- nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2375 --storage-driver=overlay&
- timeout 15 sh -c "until docker info; do echo .; sleep 1; done"
pre_build:
commands:
- $(aws ecr get-login --no-include-email --region $REGION_NAME)
build:
commands:
# - ソースのビルドがあればここに記載
# CODEBUILD_SRC_DIRは後述
- cd $CODEBUILD_SRC_DIR
- docker build -t tmp:latest .
post_build:
commands:
# CODEBUILD_RESOLVED_SOURCE_VERSIONは、CodeBuildの環境にデフォルトで設定されている環境変数
# 対象のソースのコミットIDが設定されている
# ここではビルドするDockerイメージのタグとして使用する
- COMMIT_ID_APP=`echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-8`
- docker tag tmp:latest $ECR_REPOSITORY:$COMMIT_ID_APP
- docker push $ECR_REPOSITORY:$COMMIT_ID_APP
# CODEBUILD_SRC_DIR_infは後述
- cd $CODEBUILD_SRC_DIR_inf
# Helmチャートのvalues.yamlにデプロイ対象のDockerイメージのタグが記載されている
# これを先ほど取得したコミットIDに書き換え
# 更新ができなかったので、一時的にtmp.yamlという名前で保存→既存のvalues.yamlと置き換えを行なっている
- yq -y '.image.tag |= "'$COMMIT_ID_APP'"' $CHART_NAME/values.yaml > $CHART_NAME/tmp.yaml
- mv $CHART_NAME/tmp.yaml $CHART_NAME/values.yaml
# packageコマンドでtgz形式に変換
# この形式でSpinnakerに渡すことができる
- helm package $CHART_NAME
# S3にアップロード
- aws s3 cp $CHART_NAME*.tgz s3://[backet name]/$ARTIFACT_PATH/$CHART_NAME.tgz
# Spinnakerのパイプラインを開始
- curl https://XXXXXXXXXX.com/webhooks/webhook/$URL -X POST -d "{ }" -H "content-type:application/json"
cd $CODEBUILD_SRC_DIR
コマンドでそのレポジトリのソースが格納されたパスに移動できるSpinnakerでのパイプランの作成
- Application→Actions→「Create Application」からApplicationを作成
- 作成したApplicationの画面に遷移し、PIPELINES→「Configure a new pipeline」をクリック
- パイプラインの名前を入力してCreate
Configuration
- 最初にConfigurationの画面が表示されるので必要な設定を行う
Automated Triggers
- パイプラインを開始するトリガーを設定する
- 今回はCodeBuildからURLを叩いて開始したいので、「Webhook」を指定する
- 「Source」にCodeBuildで指定した文字列を入力する
Expected Artifacts
- Spinnakerに渡したいArtifactを指定する
- 今回はCodeBuildでS3にアップロードしたHelmチャートを使用したいのでそのパスを入力する
- 「Use Sefault Artifact」にチェックを入れ、同じパスを入力する
ステージ追加
-
今回必要なステージは2つ
- Bake (Manifest)
- Helmチャートを読み込ませてマニフェストファイルを生成する
- Deploy(Manifest)
- Bakeステージで作成したマニフェストファイルをKubernetesクラスタに適用する
- Bake (Manifest)
Bake (Manifest)
Bake (Manifest) Configuration
- Template Render
- リソースの名前やNamespaceを指定する
- Template Artifact
- パイプラインのConfigurationで指定したArtifactがプルダウン形式で選択できる
- Overrides
Produces Artifacts
- Base64を指定する
- 名前を適当に入力
Deploy (Manifest)
- Bakeステージが終わってから始めるので「Depends On」に該当のステージ名を入力する
- パラレルで複数のステージを実行することもできる
Deploy (Manifest) Configuration
- Manifest Configuration
- Artifactを選択して、Bakeステージで生成したArtifactをプルダウンから選択する
- 「Save Changes」を押下して完了!
- 作成したパイプラインが表示されている
CI(本番環境)
CodeBuildの作成
- CodeBuildでやりたいことは以下の通り
- 開発環境のパイプラインで作成したHelmチャートをS3から取得し、対象のDockerイメージのタグを取得する
- 本番環境用のHelmチャートに取得したDockerイメージのタグを上書きする
- 編集したHelmチャートをS3へアップロード
- Spinnakerのパイプライン(本番環境用)開始
- CodeBuildの設定
- 基本的には開発環境用に作成したCodeBuildと同じ
- 対象のソースコードと、Helmチャートが格納されているリポジトリのmasterブランチを「Source」に指定する
Buildspec
- コメントで概要を記載
buildspec.yaml
version: 0.2
env:
variables:
REPOSITORY_NAME_INF: "test_inf"
BRANCH_NAME: "master"
CHART_NAME: "test"
ARTIFACT_PATH: "test"
URL : "deploy-test-prod"
phases:
post_build:
commands:
# developのパイプラインで作成したHelmチャートをS3から取得し、対象のDockerイメージのタグを取得する
- cd $CODEBUILD_SRC_DIR_dev
- tar -xvf $CHART_NAME.tgz
- CURRENT_COMMIT_ID=`yq -r '.image.tag' $CHART_NAME/values.yaml`
# 本番環境用のHelmチャートに取得したDockerイメージのタグを上書きする
- cd $CODEBUILD_SRC_DIR_inf
- yq -y '.image.tag |= "'$CURRENT_COMMIT_ID'"' $CHART_NAME/values.yaml > $CHART_NAME/tmp.yaml
- mv $CHART_NAME/tmp.yaml $CHART_NAME/values.yaml
# packageコマンドでtgz形式に変換
- helm package $CHART_NAME
- mv $CHART_NAME*.tgz $CHART_NAME.tgz
# S3にアップロード
- aws s3 cp $CHART_NAME*.tgz s3://[backet name]/$ARTIFACT_PATH/$CHART_NAME.tgz
# Spinnakerのパイプラインを開始
- curl https://XXXXXXXXXX.com/webhooks/webhook/$URL -X POST -d "{ }" -H "content-type:application/json"
Sourceの設定
- CodeBuildのSourceについてはCODEBUILD_SRC_DIRについてを参照
- CodeBuildのSourceには以下を指定している
- Source identifer:無
- 該当リポジトリのmasterブランチ
- Source identifer:dev
- 開発環境用のパイプラインでアップロードしたHelmチャートが格納されているバケット
- Source identifer:inf
- Helmチャートが格納されているリポジトリのmasterブランチ
CodePipeline
- 対象のCodeCommitのリポジトリのmasterブランチと対象のCodeBuildを指定して保存
- masterブランチへのpush(merge)をトリガーにこのパイプラインか開始される
CD(本番環境)
- 本番環境用のパイプラインをSpinnaker上で作成
- 作成方法は開発環境用に作成したものと同様
- 変更する点は以下
- Triggerに設定するURL(CodeBuildeの最後に叩いているURLとあわせる)
- Expected Artifactsに指定するパス
- デプロイターゲットとなるKubernetesクラスタ
まとめ
- AWS上のKubernetsクラスタにデプロイするためのパイプラインを作成
- リポジトリのpushとCodeBuildeでのビルドはCodePipelineで管理し、KubernetesクラスタへのデプロイはSpinnakerで管理する方法を紹介
- 改善点があれば随時更新予定!
- 開発環境のパイプラインで作成したHelmチャートをS3から取得し、対象のDockerイメージのタグを取得する
- 本番環境用のHelmチャートに取得したDockerイメージのタグを上書きする
- 編集したHelmチャートをS3へアップロード
- Spinnakerのパイプライン(本番環境用)開始
- 基本的には開発環境用に作成したCodeBuildと同じ
- 対象のソースコードと、Helmチャートが格納されているリポジトリのmasterブランチを「Source」に指定する
buildspec.yaml
version: 0.2
env:
variables:
REPOSITORY_NAME_INF: "test_inf"
BRANCH_NAME: "master"
CHART_NAME: "test"
ARTIFACT_PATH: "test"
URL : "deploy-test-prod"
phases:
post_build:
commands:
# developのパイプラインで作成したHelmチャートをS3から取得し、対象のDockerイメージのタグを取得する
- cd $CODEBUILD_SRC_DIR_dev
- tar -xvf $CHART_NAME.tgz
- CURRENT_COMMIT_ID=`yq -r '.image.tag' $CHART_NAME/values.yaml`
# 本番環境用のHelmチャートに取得したDockerイメージのタグを上書きする
- cd $CODEBUILD_SRC_DIR_inf
- yq -y '.image.tag |= "'$CURRENT_COMMIT_ID'"' $CHART_NAME/values.yaml > $CHART_NAME/tmp.yaml
- mv $CHART_NAME/tmp.yaml $CHART_NAME/values.yaml
# packageコマンドでtgz形式に変換
- helm package $CHART_NAME
- mv $CHART_NAME*.tgz $CHART_NAME.tgz
# S3にアップロード
- aws s3 cp $CHART_NAME*.tgz s3://[backet name]/$ARTIFACT_PATH/$CHART_NAME.tgz
# Spinnakerのパイプラインを開始
- curl https://XXXXXXXXXX.com/webhooks/webhook/$URL -X POST -d "{ }" -H "content-type:application/json"
- Source identifer:無
- 該当リポジトリのmasterブランチ
- Source identifer:dev
- 開発環境用のパイプラインでアップロードしたHelmチャートが格納されているバケット
- Source identifer:inf
- Helmチャートが格納されているリポジトリのmasterブランチ
- 本番環境用のパイプラインをSpinnaker上で作成
- 作成方法は開発環境用に作成したものと同様
- 変更する点は以下
- Triggerに設定するURL(CodeBuildeの最後に叩いているURLとあわせる)
- Expected Artifactsに指定するパス
- デプロイターゲットとなるKubernetesクラスタ
まとめ
- AWS上のKubernetsクラスタにデプロイするためのパイプラインを作成
- リポジトリのpushとCodeBuildeでのビルドはCodePipelineで管理し、KubernetesクラスタへのデプロイはSpinnakerで管理する方法を紹介
- 改善点があれば随時更新予定!
Author And Source
この問題について(AWS上で動くKubernetesクラスタのためのCI/CDパイプライン), 我々は、より多くの情報をここで見つけました https://qiita.com/str416yb/items/01522a57c0b3c79d9bbc著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .