内容
会社の業務でk8sを使用したGitOps(参考リンク)を実現する為にCI/CDのCI側の実装をcircleciで行ったのでその内容を残します
※ 本記事はAmazon ECR・EKSの使用を想定しておりGKE等の他のクラウドを使ったk8s運用には少し外れる内容になることご了承ください。
対象者
- これから会社にk8sを導入しciの選定をしている方
- コンテナ自体初めてでcircleciからpushをするのも初めてな方(ECS運用にも使える部分はあります)
ECRへのpush
先ずはECRへのpushを先に実装します
circleciにはorbという便利なものがありECRもそれに対応しているのでそれを使用します。
https://circleci.com/orbs/registry/orb/circleci/aws-ecr
今回ですが2つのjobを用意しました
詳細に関しては別の記事にも参考になるものがございますのでそちらをご参照ください
こちらがとてもわかりやすいです
https://qiita.com/nyasba/items/517c0d6b15600bf774b5
workflows:
build_and_push_image_dev:
jobs:
- aws-ecr/build-and-push-image:
account-url: AWS_ECR_ACCOUNT_URL
aws-access-key-id: AWS_ACCESS_KEY_ID
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
region: AWS_DEFAULT_REGION
repo: '${DEV_ECR_REPO}'
tag: '${CIRCLE_SHA1}'
path: .
filters:
branches:
only:
- master
build_and_push_image_prod:
jobs:
- aws-ecr/build-and-push-image:
account-url: AWS_ECR_ACCOUNT_URL
aws-access-key-id: AWS_ACCESS_KEY_ID
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
region: AWS_DEFAULT_REGION
repo: '${PROD_ECR_REPO}'
tag: '${CIRCLE_TAG}'
path: ./poc/
filters:
tags:
only:
- /^v[0-9](\.[0-9]){2}$/
branches:
ignore: /.*/
build_and_push_image_dev:
こちらですがmaster branchにpush(merge)された際にjobが走ることを想定しています。
build_and_push_image_prod:
こちらはGithubにバージョンtagをつけた際に発火するjobです、production環境にリリースする際にはこちらのjobでdocker image tagにgit version tagをつけてECRにpushしています。
ECRへのpushはここまでです。
image tagの更新
ここからはk8sのmanifestのdocker image tagの更新をします
kustomizeを使用してmanifestファイルの管理をしています
https://qiita.com/ryodocx/items/008fdaf5c68678656749
k8s/overlays/dev/bases/kustomization.yaml
という構造になっていて
kustomization.yaml
のファイルはこのようになっています
~省略~
images:
- name: nginx
newTag: 1.15.2
- name: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend-admin
newName: 767177527229.dkr.ecr.ap-northeast-1.amazonaws.com/backend-admin
newTag: latest
- name: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/frontend-admin
newName: 767177527229.dkr.ecr.ap-northeast-1.amazonaws.com/frontend-admin
newTag: latest
今回はbackend-admin
というところのnewTag
を更新していきます
circleciで実装していきます
jobs:
create-pull-request:
docker:
- image: circleci/python:3.7.4-stretch
environment:
PR_TEMPLATE: ./github/PULL_REQUEST_TEMPLATE.md
steps:
- checkout
- run:
name: install hub
command: |
curl -sSLf https://github.com/github/hub/releases/download/v2.8.3/hub-linux-amd64-2.8.3.tgz | \
tar zxf - --strip-components=1 -C /tmp/ && \
sudo mv /tmp/bin/hub /usr/local/bin/hub
hub --version
- run:
name: install yq
command: |
sudo pip install --upgrade pip
sudo pip install yq
- run:
name: git clone commit push create pull request
command: |
git config --global user.name ${GITHUB_NAME}
git config --global user.email ${GITHUB_EMAIL}
git clone https://${GITHUB_NAME}:${GITHUB_TOKEN}@github.com/username/appname.git
cd appname
git init
git checkout -b feature-backend-admin-${CIRCLE_SHA1}
yq -y -i '.images |= map(select(.name=="XXXXXXXXXXXX.dkr.ecr.リージョン.amazonaws.com/backend-admin").newTag |= "'$CIRCLE_SHA1'")' k8s/overlays/dev/bases/kustomization.yaml
git add .
git commit -m "feature-backend-admin-${CIRCLE_SHA1}"
git push --set-upstream origin feature-backend-admin-${CIRCLE_SHA1}
hub pull-request -F $PR_TEMPLATE -m "[image update] backend-admin ${CIRCLE_SHA1}"
先に全ての実装を載せました。
やっていることを説明します
- run:
name: install hub
command: |
curl -sSLf https://github.com/github/hub/releases/download/v2.8.3/hub-linux-amd64-2.8.3.tgz | \
tar zxf - --strip-components=1 -C /tmp/ && \
sudo mv /tmp/bin/hub /usr/local/bin/hub
こちらは最後のPRを出すためのhubというツールをinstallしています
- run:
name: install yq
command: |
sudo pip install --upgrade pip
sudo pip install yq
こちらはmanifestのyamlをいじる為にyqというツールのinstallをしています
- run:
name: git clone commit push create pull request
command: |
git config --global user.name ${GITHUB_NAME}
git config --global user.email ${GITHUB_EMAIL}
git clone https://${GITHUB_NAME}:${GITHUB_TOKEN}@github.com/username/appname.git
cd appname
git init
git checkout -b feature-backend-admin-${CIRCLE_SHA1}
yq -y -i '.images |= map(select(.name=="XXXXXXXXXXXX.dkr.ecr.リージョン.amazonaws.com/backend-admin").newTag |= "'$CIRCLE_SHA1'")' k8s/overlays/dev/bases/kustomization.yaml
git add .
git commit -m "feature-backend-admin-${CIRCLE_SHA1}"
git push --set-upstream origin feature-backend-admin-${CIRCLE_SHA1}
hub pull-request -F $PR_TEMPLATE -m "[image update] backend-admin ${CIRCLE_SHA1}"
こちらですがコマンドのままなのですがgit cloneでmanifestのリポジトリをcloneしてそこからbranchを切り、manifestのimage tagの更新を
yq -y -i '.images |= map(select(.name=="XXXXXXXXXXXX.dkr.ecr.リージョン.amazonaws.com/backend-admin").newTag |= "'$CIRCLE_SHA1'")' k8s/overlays/dev/bases/kustomization.yaml
で行っています
参考 https://qiita.com/mafuyuk/items/d6b62c25691a4ca29aba
最後に最初にinstallしたhubでPull Requestを送るとGitHub側にPull Requestが上がります。
branch名や${${CIRCLE_SHA1}}
の部分は好きなものにしていただいて構いません。
異常がcircleciでのGitOpsにおけるCIの部分の実装でした。
この実装にテストを加えることにより、GitHubからPushするだけで自動でテスト、Docker imageのpush manifest側にdocker imageの更新のPull Requestが送れるのでスムーズな運用が可能になります。
k8sを運用しようと検討したり運用方法に戸惑っている開発者の方もいらっしゃると思いますので参考になれば幸いです。
次はCD側の実装について記事を書こうと思います
参考にした記事、サイト
https://circleci.com/orbs/registry/orb/circleci/aws-ecr
https://qiita.com/nyasba/items/517c0d6b15600bf774b5
https://qiita.com/ryodocx/items/008fdaf5c68678656749
https://dev.classmethod.jp/tool/git/hub/
https://dev.classmethod.jp/tool/yq/
https://qiita.com/mafuyuk/items/d6b62c25691a4ca29aba