GKE用のサンプルアプリケーションを、GitHub Actionsを使ってソースがPUSHされたら自動でデプロイされるようにする
#前提
- GitHubにリポジトリは作成済み
- GKE クラスタは作成済み
- Cloud Shell使用
#サンプルプログラムのセット
##GoogleのサンプルアプリケーションをCloneする
https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app?hl=ja
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/hello-app
##リモートリポジトリのセット
予め作っておいたリモートリポジトリを登録する
git remote remove origin
git remote add origin <githubのURL>
#GitHub Actionsのセット
https://docs.github.com/ja/actions/guides/deploying-to-google-kubernetes-engine
##GCPの設定
###Kubernetes Engine及びContainer Registry APIを有効化
gcloud config set <project-name>
gcloud services enable \
containerregistry.googleapis.com \
container.googleapis.com
###サービスアカウントの作成、シークレットの保存
gcloud iam service-accounts create <service-account-name>
gcloud iam service-accounts list
gcloud projects add-iam-policy-binding <project-name> \
--member=serviceAccount:<service-account-mailaddress> \
--role=roles/container.admin \
--role=roles/storage.admin
gcloud iam service-accounts keys create key.json --iam-account=<service-account-mailaddress>
cat key.json | base64
####GitHubにシークレットを登録する
登録するシークレットは以下
- GKE_PROJECT_DEV:開発環境のGCPのプロジェクトID
- GKE_SA_KEY_DEV:出力したサービスアカウントJSONキーの内容
~/.github/workflows/ Actions用にyamlファイルが作成される
今回はdevelopment.ymlというファイル名にする
本番環境へのデプロイを分けたければ、起動条件、シークレットを分けた別yamlを作れば可能となる。
今回は開発環境へデプロイする前提でyamlファイルを作ってみる
name: Build and Deploy to GKE
on:
push:
branches: #以下の名前のブランチがプッシュされたら起動
- 'feature/*'
- 'bugfix/*'
env:
PROJECT_ID: ${{ secrets.GKE_PROJECT_DEV }}
GKE_CLUSTER: <cluster-name>
GKE_ZONE: <cluster-zone>
DEPLOYMENT_NAME: <deployment-name>
IMAGE: hello-app
jobs:
setup-build-publish-deploy:
name: Setup, Build, Publish, and Deploy
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
# gcloud CLI のセットアップ
- uses: google-github-actions/setup-gcloud@v0.2.0
with:
service_account_key: ${{ secrets.GKE_SA_KEY_DEV }}
project_id: ${{ secrets.GKE_PROJECT_DEV }}
# gcloud コマンドラインツールを認証情報ヘルパーとして使用するようにDockerを設定する
- run: |-
gcloud --quiet auth configure-docker
# GKE 認証情報を取得して、クラスタにデプロイできるようにする
- uses: google-github-actions/get-gke-credentials@v0.2.1
with:
cluster_name: ${{ env.GKE_CLUSTER }}
location: ${{ env.GKE_ZONE }}
credentials: ${{ secrets.GKE_SA_KEY_DEV }}
# Docker イメージをビルドする
- name: Build
run: |-
docker build \
--tag "gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA" \
--build-arg GITHUB_SHA="$GITHUB_SHA" \
--build-arg GITHUB_REF="$GITHUB_REF" \
hello-app/
# Docker イメージを Google Container Registry にプッシュする
- name: Publish
run: |-
docker push "gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA"
# kustomize を設定する
- name: Set up Kustomize
run: |-
curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/v3.1.0/kustomize_3.1.0_linux_amd64
chmod u+x ./kustomize
# Docker イメージを GKE クラスタにデプロイする
- name: Deploy
run: |-
cd hello-app/manifests
../../kustomize edit set image gcr.io/$PROJECT_ID/$IMAGE:v1=gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA
../../kustomize build . | kubectl apply -f -
kubectl rollout status deployment/$DEPLOYMENT_NAME
kubectl get services -o wide
###googleのサンプルmanifestの注意点
####ポート設定
デフォルトではhelloweb-deployment.yamlの方はポートが8080設定なのに、
helloweb-service-load-balancer.yamlの方はポート80設定で、ターゲットポートが設定されていないため、アプリケーションにアクセスできない。(アプリケーションはポート8080で待ち受けているのに、80にフォワーディングされる)
helloweb-service-load-balancer.yamlにターゲットポート8080を設定する必要がある。
apiVersion: v1
kind: Service
metadata:
name: helloweb
labels:
app: hello
tier: web
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080 #この部分の追記必要
selector:
app: hello
tier: web
####kustomize設定
kustomize(参考)を動かすために、hello-app/manifestsに以下ファイルを作成し、どのマニフェストファイルがデプロイ対象なのか設定する
resources:
- helloweb-deployment.yaml
- helloweb-service-load-balancer.yaml
#GitHub Actionsを動かす
##トリガーとなるブランチをPUSHする
###master ブランチの変更をコミットしておく
serviceのyamlを更新し、kustomization.ymlを追加したので変更をコミットしておく
###master(main)ブランチの変更をマージしておく
ActionsはGitHub上で作成したので、ローカル環境のmaster(main)にマージしておく
このあたりちょっとややこしいのだが、GitHubのデフォルトリポジトリが2020年後半にmainとなっており、Googleのサンプルがmasterブランチになっているので、mainブランチをつくってそちらにGitHubの変更をマージし、masterブランチは削除する
git branch main
git checkout main
git branch -d master
git fetch
git branch --set-upstream-to=origin/main main
git merge --allow-unrelated-histories origin/main
###ブランチを作成する
feature/* のブランチ名のPUSHがトリガーなので、feature/testというブランチを作成する
git branch feature/test
git checkout feature/test
###feature/testブランチをPUSHする
git push origin HEAD
##Actionsの実行画面
Actionsタブに移動すると
成功すると緑のチェックマークつく
##アプリケーションの確認
kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
helloweb-6459bd8599-l56vb 1/1 Running 0 111s 10.0.0.11 gke-dev-cluster-1-default-pool-6646ab54-rbrl <none> <none>
kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
helloweb LoadBalancer 10.3.240.183 *.*.*.* 80:30222/TCP 2m42s
デプロイできた!
#GigHub Actionsで発生したエラー
##Required "container.clusters.get" permission(s)
サービスアカウントへのcontaner.adminのロール付与がうまくいってなかったので、手動で設定