一直很想把 CI/CD 流程整進去新架設的 Kubernetes 內(透過 GKE 提供的),花了點時間終於搞定了。

建立 Service Account,產生 JSON 格式的 private key,並給予 GCR 及 GKE 權限,分別拿來上傳編譯好的 Docker Image 以及操作 GKE。整個流程大致上如最上面的圖片,其實不難,只是中間如果有東西沒串好,整個流程就不會動。

建立 Kubernetes Role 並綁定 RBAC,這邊設定 extensions/deployments 給予 get/patch/list 權限。

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: deployment-manager-gitlab
rules:
- apiGroups: ["extensions"]
  resources: ["deployments"]
  verbs: ["get", "patch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: deployment-manager
  namespace: default
subjects:
- kind: User
  name: "[[前面建立的 IAM 帳號]]"
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: deployment-manager-gitlab
  apiGroup: rbac.authorization.k8s.io

透過 kubectl apply 設定後,確認 RBAC 綁定狀況:

# kubectl get Role,RoleBinding

NAME                                                       AGE
role.rbac.authorization.k8s.io/deployment-manager-gitlab   138m
role.rbac.authorization.k8s.io/nginx-ingress               14d

NAME                                                       AGE
rolebinding.rbac.authorization.k8s.io/deployment-manager   138m
rolebinding.rbac.authorization.k8s.io/nginx-ingress        14d

設定 GitLab Repo 的 CI/CD 環境變數:

在 GibLab 專案內選單進入 Settings -> CI/CD,展開 Variables 區塊,指定變數名稱(這邊範例是 GCP_SERVICE_ACCOUNT)並將前面取得的 JSON 檔案的內容貼進變數的值。

這邊要先手動方式在 Kubernetes 產生好 Deployment,GitLab CD 只透過 set image 指令更新 image 版本。

撰寫 .gitlab-ci.yaml 檔案,這邊實作兩個步驟:

  1. 編譯 Docker Image 並上傳到 GCR(build-docker)
  2. 透過 kubectl set image 方式更新 Deployment 的 image(deploy-k8s)

(記得自行替換掉 BUCKET_NAME 以及 IMAGE_NAME 甚至是 gcr.io 的 region)

接下來每次 commit 就會自動觸發 GitLab CI/CD,自動編譯出 Docker Image 並上傳到 GCR,然後自動 deploy 到 Kubernetes 上,完成整個持續建置與持續部署的動作。

參考:Publishing Google Cloud Container Registry Images from Gitlab CI