如何在 GKE 上部署 Gitlab Runner (使用 Helm) 並整合 Workload Identity
Gitlab Runner + Helm + workload Identity to deploy Application on GKE
建立 Service Account 給 Gitlab Runner 使用
如果想讓 Gitlab Runner 可以在 GCP 上部署任何應用程式, 必須給他一組有特定權限的 Service Account
Gitlab Runner 要使用這個 Service Account, 比較 Hardcore 一點的做法是, 直接下載 Service Account 的 Credential, 再透過 gcloud 指令拿 Credential 去做認證
gcloud auth activate-service-account $SERVICE_ACCOUNT_EMAIL \
--key-file=$CRED \
--project=$PROJECT
這個做法的缺點是, 需要煩惱如何安全地保管 Credential
比較安全一點的做法是
透過 GKE Workload Identity 將 GKE 裡的 Service Account 與 GCP 上的 Service Account 連結在一起
假設 Gitlab Runner 架構規劃如下:
在 GCP 上總共有三個 Project (cicd/dev/prod), cicd 的 Project 裡有一座 GKE 用來跑 Gitlab Runner, Runner 會將應用程式部署到 dev, 以及 prod 的 App Engine 上
要實現以上的架構
首先
Step 1. 建立 Google Service Account
# Parameters
KSA_NAME="gitlab-runner-pd"
RUNNER_GSA_PROJECT="cicd"
NAMESPACE="gitlab"
RUNNER_NAME="gitlab-runner-pd"
TOKEN="eZH45H6uQAy1hRLLHksU"
gcloud iam service-accounts create ${KSA_NAME} --project=${RUNNER_GSA_PROJECT} \ --description="" \
--display-name=${KSA_NAME}
Step 2. 賦予 workloadIdentityUser 的角色
gcloud iam service-accounts add-iam-policy-binding ${KSA_NAME}@${RUNNER_GSA_PROJECT}.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:${RUNNER_GSA_PROJECT}.svc.id.goog[${NAMESPACE}/${KSA_NAME}]"
Step 3. 開部署權限給 Service Account
開 dev 環境的部署權限
DEPLOY_PROJECT="dev"
gcloud projects add-iam-policy-binding ${DEPLOY_PROJECT} \
--member="serviceAccount:${KSA_NAME}@${RUNNER_GSA_PROJECT}.iam.gserviceaccount.com" \
--role="roles/editor"
開 prod 環境的部署權限
DEPLOY_PROJECT="prod"
gcloud projects add-iam-policy-binding ${DEPLOY_PROJECT} \
--member="serviceAccount:${KSA_NAME}@${RUNNER_GSA_PROJECT}.iam.gserviceaccount.com" \
--role="roles/editor"
Step 4. 建立 Kubernetes service account
kubectl create serviceaccount ${KSA_NAME} --namespace ${NAMESPACE}
Step 5. 連結 Kubernetes service account 跟 Google service account
透過 kubectl annotate 將 Service Account 連結在一起
kubectl annotate serviceaccount ${KSA_NAME} \
--namespace ${NAMESPACE} \
iam.gke.io/gcp-service-account=${KSA_NAME}@${RUNNER_GSA_PROJECT}.iam.gserviceaccount.com
部署 Gitlab Runner
接下來會使用 helm 來部署 Gitlab Runner
Step 6. 建立 values.yaml
因為 Gitlab Runner 的 helm chart 上需要指定 Token, Tag, 以及 Kubernetes Service Account, ... 等等, 所以這邊先將這些參數寫到 values.yaml
(以下使用 Python 的 jinja 套件來建立 values.yaml 檔案)
from jinja2 import Template
TAG='k8s-runner'
VALUE_FILE_NAME='values.yaml'
FILE_CONTENT="""
image: gitlab/gitlab-runner:alpine-v12.9.0
imagePullPolicy: IfNotPresent
## Default container image to use for initcontainer
init:
image: busybox
tag: latest
gitlabUrl: "https://gitlab.andy.co/"
runnerRegistrationToken: "{{ TOKEN }}"
unregisterRunners: true
concurrent: 100
checkInterval: 30
rbac:
create: true
clusterWideAccess: false
serviceAccountName: "{{ KSA_NAME }}"
metrics:
enabled: true
runners:
## Default container image to use for builds when none is specified
##
image: ubuntu:16.04
tags: "{{ TAG }}"
privileged: true
namespace: gitlab
cachePath: "/opt/cache"
cache: {}
builds: {}
services: {}
helpers: {}
resources: {}
"""
import os
TemplatePath=os.path.expanduser(VALUE_FILE_NAME)
Template(FILE_CONTENT).stream(TOKEN=f"{TOKEN}",
KSA_NAME=f"{KSA_NAME}",
TAG=f"{TAG}"
).dump(TemplatePath)
Step 7. 部署 Gitlab Runner
最後使用剛剛建立的 values.yaml 來部署 Runner
helm install --namespace gitlab ${RUNNER_NAME} -f values.yaml gitlab/gitlab-runner
留言
張貼留言