在K8S中部署gitlab-runner
在K8S中部署gilab-runner
目錄開始寫yml之前的思考:
寫一個gitlab-runner的yaml檔案進行在K8S上執行runner 方案: 1、daemonset 每個node上執行一個runner 缺點: 如果叢集中的node並不都是來做runner時 此路就不通了(註冊了不用 也是可以的) 優點:yaml檔案簡單,操作步驟少 2、deployment 缺點:操作步驟較多,需要對node進行打標籤以及選擇標籤的方式來選擇機器進行部署runner 優點:靈活安排那些node進行執行runner,解決“叢集中並不是所有node都是來進行執行runner的”情況 這兩種方式都是需要進行配合configmap以及serct進行關鍵詞以及配置檔案的傳入 借鑑博主思路: 1、configmap 來儲存runner註冊時的url地址以及限制pod的資源 2、configmap資源型別來定義一個指令碼 “用於註冊、執行和取消註冊” 3、sercet來儲存runner註冊的token 4、rbac的一個授權 5、StatefulSet來執行runner並使用以上定義的configmap以及sercet等資源
最終成品
apiVersion: v1 kind: Namespace metadata: name: gitlab-ci --- apiVersion: v1 kind: Secret metadata: name: gitlab-ci-token namespace: gitlab-ci labels: app: gitlab-ci-runner data: GITLAB_CI_TOKEN: WmF0Y3JNbUxUbmNncnpKem5CX1UK --- apiVersion: v1 data: run.sh: | #!/bin/bash unregister() { kill %1 echo "Unregistering runner ${RUNNER_NAME} ..." /usr/bin/gitlab-ci-multi-runner unregister -t "$(/usr/bin/gitlab-ci-multi-runner list 2>&1 | tail -n1 | awk '{print $4}' | cut -d'=' -f2)" -n ${RUNNER_NAME} exit $? } trap 'unregister' EXIT HUP INT QUIT PIPE TERM echo "Registering runner ${RUNNER_NAME} ..." /usr/bin/gitlab-ci-multi-runner register -r ${GITLAB_CI_TOKEN} sed -i 's/^concurrent.*/concurrent = '"${RUNNER_REQUEST_CONCURRENCY}"'/' /etc/gitlab-runner/config.toml echo "Starting runner ${RUNNER_NAME} ..." /usr/bin/gitlab-ci-multi-runner run -n ${RUNNER_NAME} & wait kind: ConfigMap metadata: labels: app: gitlab-ci-runner name: gitlab-ci-runner-scripts namespace: gitlab-ci --- apiVersion: v1 data: KUBERNETES_NODE_TOLERATIONS: "node-role.kubernetes.io/master:NoSchedule" KUBERNETES_IMAGE: "python" RUNNER_TAG_LIST: "training" REGISTER_NON_INTERACTIVE: "true" REGISTER_LOCKED: "false" METRICS_SERVER: "0.0.0.0:9100" CI_SERVER_URL: "http://git.enflame.cn/" RUNNER_REQUEST_CONCURRENCY: "4" RUNNER_EXECUTOR: "kubernetes" KUBERNETES_NAMESPACE: "gitlab-ci" KUBERNETES_PRIVILEGED: "true" KUBERNETES_CPU_LIMIT: "1" KUBERNETES_CPU_REQUEST: "500m" KUBERNETES_MEMORY_LIMIT: "1Gi" KUBERNETES_SERVICE_CPU_LIMIT: "1" KUBERNETES_SERVICE_MEMORY_LIMIT: "1Gi" KUBERNETES_HELPER_CPU_LIMIT: "500m" KUBERNETES_HELPER_MEMORY_LIMIT: "100Mi" KUBERNETES_PULL_POLICY: "if-not-present" KUBERNETES_TERMINATIONGRACEPERIODSECONDS: "10" KUBERNETES_POLL_INTERVAL: "5" KUBERNETES_POLL_TIMEOUT: "360" kind: ConfigMap metadata: labels: app: gitlab-ci-runner name: gitlab-ci-runner-cm namespace: gitlab-ci --- apiVersion: v1 kind: ServiceAccount metadata: name: gitlab-ci namespace: gitlab-ci --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: gitlab-ci namespace: gitlab-ci rules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: gitlab-ci namespace: gitlab-ci subjects: - kind: ServiceAccount name: gitlab-ci namespace: gitlab-ci roleRef: kind: Role name: gitlab-ci apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1 kind: StatefulSet metadata: name: gitlab-ci-runner namespace: gitlab-ci labels: app: gitlab-ci-runner spec: updateStrategy: type: RollingUpdate replicas: 1 selector: matchLabels: app: gitlab-ci-runner serviceName: gitlab-ci-runner template: metadata: labels: app: gitlab-ci-runner spec: volumes: - name: gitlab-ci-runner-scripts projected: sources: - configMap: name: gitlab-ci-runner-scripts items: - key: run.sh path: run.sh mode: 0755 serviceAccountName: gitlab-ci containers: - image: gitlab/gitlab-runner:alpine-v14.2.0 name: gitlab-ci-runner command: - /scripts/run.sh envFrom: - configMapRef: name: gitlab-ci-runner-cm - secretRef: name: gitlab-ci-token env: - name: RUNNER_NAME valueFrom: fieldRef: fieldPath: metadata.name ports: - containerPort: 9100 name: http-metrics protocol: TCP volumeMounts: - name: gitlab-ci-runner-scripts mountPath: "/scripts" readOnly: true restartPolicy: Always tolerations: - key: "node-role.kubernetes.io/master" operator: "Exists" effect: "NoSchedule"
註釋版-StatefulSet(此版本只是參考作用)
#定義namespace apiVersion: v1 #K8S的api介面版本 kind: Namespace #定義名稱空間 metadata: #屬性 name: kube-ops #名稱空間的名字 --- #定義註冊的token apiVersion: v1 #K8S的api介面版本 kind: Secret #資源型別 metadata: #屬性 name: gitlab-ci-token #secret的名字 namespace: kube-ops #選擇名稱空間 labels: #給資源打上標籤 app: gitlab-ci-runner #標籤內容 data: #定義鍵值對資料 儲存runner註冊時的token GITLAB_CI_TOKEN: WURnUG14aUFBZFE0dFRrZ21RSkgK --- #指令碼用來註冊和取消註冊的命令,會在runner中進行執行 apiVersion: v1 #K8S的api介面版本 kind: ConfigMap #資源型別 data: #定義configmap中的內容 鍵值對方式定義 run.sh: | #!/bin/bash unregister() { kill %1 #殺死後臺執行程式為1的job echo "Unregistering runner ${RUNNER_NAME} ..." /usr/bin/gitlab-ci-multi-runner unregister -t "$(/usr/bin/gitlab-ci-multi-runner list 2>&1 | tail -n1 | awk '{print $4}' | cut -d'=' -f2)" -n ${RUNNER_NAME} #根據runner的token登出註冊runner exit $? } trap 'unregister' EXIT HUP INT QUIT PIPE TERM #當接收到 關閉的訊號後 進行取消註冊runner 好處就是當pod刪除時 gitlab上自動刪除此runner,不會導致任務分配過來而不執行的情況。 echo "Registering runner ${RUNNER_NAME} ..." /usr/bin/gitlab-ci-multi-runner register -r ${GITLAB_CI_TOKEN} sed -i 's/^concurrent.*/concurrent = '"${RUNNER_REQUEST_CONCURRENCY}"'/' /etc/gitlab-runner/config.toml echo "Starting runner ${RUNNER_NAME} ..." /usr/bin/gitlab-ci-multi-runner run -n ${RUNNER_NAME} & #進行註冊runner wait metadata: #屬性 labels: #標籤 app: gitlab-ci-runner #標籤具體內容 name: gitlab-ci-runner-scripts #configmap的名字 namespace: kube-ops #選擇名稱空間 --- #定義runner執行時的環境變數(這些變數runner部分是藉助/usr/bin/gitlab-ci-multi-runner進行使用的,檢視有哪些變數 /usr/bin/gitlab-ci-multi-runner register --help) apiVersion: v1 kind: ConfigMap data: REGISTER_NON_INTERACTIVE: "true" #非互動式註冊 REGISTER_LOCKED: "false" #暫存器鎖定 METRICS_SERVER: "0.0.0.0:9100" #度量伺服器 CI_SERVER_URL: "http://10.0.0.6/" #gitlab的url 註冊地址 RUNNER_REQUEST_CONCURRENCY: "4" #請求併發數量 RUNNER_EXECUTOR: "kubernetes" #runner的執行器型別 KUBERNETES_NAMESPACE: "kube-ops" #指定名稱空間 KUBERNETES_PRIVILEGED: "true" #有特權的 KUBERNETES_CPU_LIMIT: "1" #限制CPU資源為 1 KUBERNETES_CPU_REQUEST: "500m" #要求500m KUBERNETES_MEMORY_LIMIT: "1Gi" #記憶體限制為1G KUBERNETES_SERVICE_CPU_LIMIT: "1" #限制CPU為1 KUBERNETES_SERVICE_MEMORY_LIMIT: "1Gi" #記憶體為1G KUBERNETES_HELPER_CPU_LIMIT: "500m" #輔助程式CPU限制 KUBERNETES_HELPER_MEMORY_LIMIT: "100Mi" # KUBERNETES_PULL_POLICY: "if-not-present" KUBERNETES_TERMINATIONGRACEPERIODSECONDS: "10" KUBERNETES_POLL_INTERVAL: "5" KUBERNETES_POLL_TIMEOUT: "360" metadata: labels: app: gitlab-ci-runner name: gitlab-ci-runner-cm namespace: kube-ops --- #進行rbac授權 apiVersion: v1 kind: ServiceAccount metadata: name: gitlab-ci namespace: kube-ops --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: gitlab-ci namespace: kube-ops rules: - apiGroups: [""] resources: ["*"] verbs: ["*"] --- apiVersion: v1 kind: RoleBinding metadata: name: gitlab-ci namespace: kube-ops subjects: - kind: ServiceAccount name: gitlab-ci namespace: kube-ops roleRef: kind: Role name: gitlab-ci apiGroup: rbac.authorization.k8s.io --- #執行runner apiVersion: apps/v1 #api版本 kind: StatefulSet #資源型別 metadata: 元資料 name: gitlab-ci-runner 指定資源的名稱 namespace: kube-ops 指定名稱空間 labels: 標籤 app: gitlab-ci-runner 標籤具體內容 spec: 屬性 updateStrategy: #指定更新策略 type: RollingUpdate replicas: 1 指定副本數 selector: 指定選擇 matchLabels: app: gitlab-ci-runner serviceName: gitlab-ci-runner template: metadata: labels: app: gitlab-ci-runner spec: 進行資料卷掛在 volumes: - name: gitlab-ci-runner-scripts #使用指令碼 projected: sources: - configMap: name: gitlab-ci-runner-scripts #引用configmap中定義的那個指令碼 items: #引用key - key: run.sh path: run.sh mode: 0755 serviceAccountName: gitlab-ci #指定serviceaccount 進行繫結 containers: #容器資訊 - image: gitlab/gitlab-runner:alpine-v12.10.1 #指定容器執行時的映象 name: gitlab-ci-runner #容器名字 command: #執行的命令 - /scripts/run.sh envFrom: - configMapRef: name: gitlab-ci-runner-cm #引入環境變數 - secretRef: name: gitlab-ci-token #引入token env: #環境變數 - name: RUNNER_NAME valueFrom: fieldRef: fieldPath: metadata.name #runner-name的名稱 pod的 ports: #容器埠 - containerPort: 9100 name: http-metrics protocol: TCP volumeMounts: - name: gitlab-ci-runner-scripts mountPath: "/scripts" readOnly: true #只讀的方式掛載 restartPolicy: Always
daemonset
#定義runner工作的namespace
apiVersion: v1
kind: Namespace
metadata:
name: kube-ops
---
#定義runner註冊時用到的token
apiVersion: v1
kind: Secret
metadata:
name: gitlab-ci-token
namespace: kube-ops
labels:
app: gitlab-ci-runner
data:
GITLAB_CI_TOKEN: WURnUG14aUFBZFE0dFRrZ21RSkgK
---
#定義一個指令碼(暫時不明白博主為何這麼操作)
apiVersion: v1
data:
run.sh: |
#!/bin/bash
unregister() {
kill %1
echo "Unregistering runner ${RUNNER_NAME} ..."
/usr/bin/gitlab-ci-multi-runner unregister -t "$(/usr/bin/gitlab-ci-multi-runner list 2>&1 | tail -n1 | awk '{print $4}' | cut -d'=' -f2)" -n ${RUNNER_NAME}
exit $?
}
trap 'unregister' EXIT HUP INT QUIT PIPE TERM
echo "Registering runner ${RUNNER_NAME} ..."
/usr/bin/gitlab-ci-multi-runner register -r ${GITLAB_CI_TOKEN}
sed -i 's/^concurrent.*/concurrent = '"${RUNNER_REQUEST_CONCURRENCY}"'/' /home/gitlab-runner/.gitlab-runner/config.toml
echo "Starting runner ${RUNNER_NAME} ..."
/usr/bin/gitlab-ci-multi-runner run -n ${RUNNER_NAME} &
wait
kind: ConfigMap
metadata:
labels:
app: gitlab-ci-runner
name: gitlab-ci-runner-scripts
namespace: kube-ops
---
#定義runner執行時的環境變數
apiVersion: v1
data:
REGISTER_NON_INTERACTIVE: "true"
REGISTER_LOCKED: "false"
METRICS_SERVER: "0.0.0.0:9100"
CI_SERVER_URL: "http://10.0.0.6/"
RUNNER_REQUEST_CONCURRENCY: "4"
RUNNER_EXECUTOR: "kubernetes"
KUBERNETES_NAMESPACE: "kube-ops"
KUBERNETES_PRIVILEGED: "true"
KUBERNETES_CPU_LIMIT: "1"
KUBERNETES_CPU_REQUEST: "500m"
KUBERNETES_MEMORY_LIMIT: "1Gi"
KUBERNETES_SERVICE_CPU_LIMIT: "1"
KUBERNETES_SERVICE_MEMORY_LIMIT: "1Gi"
KUBERNETES_HELPER_CPU_LIMIT: "500m"
KUBERNETES_HELPER_MEMORY_LIMIT: "100Mi"
KUBERNETES_PULL_POLICY: "if-not-present"
KUBERNETES_TERMINATIONGRACEPERIODSECONDS: "10"
KUBERNETES_POLL_INTERVAL: "5"
KUBERNETES_POLL_TIMEOUT: "360"
kind: ConfigMap
metadata:
labels:
app: gitlab-ci-runner
name: gitlab-ci-runner-cm
namespace: kube-ops
---
#定義RBAC授權
apiVersion: v1
kind: ServiceAccount
metadata:
name: gitlab-ci
namespace: kube-ops
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: gitlab-ci
namespace: kube-ops
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: gitlab-ci
namespace: kube-ops
subjects:
- kind: ServiceAccount
name: gitlab-ci
namespace: kube-ops
roleRef:
kind: Role
name: gitlab-ci
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: gitlab-ci-runner
namespace: kube-ops
labels:
app: gitlab-ci-runner
spec:
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
app: gitlab-ci-runner
template:
metadata:
labels:
app: gitlab-ci-runner
spec:
volumes:
- name: gitlab-ci-runner-scripts
projected:
sources:
- configMap:
name: gitlab-ci-runner-scripts
items:
- key: run.sh
path: run.sh
mode: 0755
serviceAccountName: gitlab-ci
containers:
- image: gitlab/gitlab-runner:alpine-v12.10.1
name: gitlab-ci-runner
command:
- /scripts/run.sh
envFrom:
- configMapRef:
name: gitlab-ci-runner-cm
- secretRef:
name: gitlab-ci-token
env:
- name: RUNNER_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- containerPort: 9100
name: http-metrics
protocol: TCP
volumeMounts:
- name: gitlab-ci-runner-scripts
mountPath: "/scripts"
readOnly: true
restartPolicy: Always
遇到的問題
問題一:指令碼中註冊runner的是什麼方式進行註冊的?
問題描述:當我嘗試以手動的方式執行指令碼的內容時,發現指令碼中用到了runner的token 並不是gitlab-server的註冊runner時的token從而產生了疑惑:難道註冊gitlab-runner還能用自己的token(gitlab-runner的token)
思考:應該不是使用token的方式 因為命令列方式獲取得到的token和gitlab-ci獲取的token值是不一樣的
解決:
此yaml中 使用runner的token進行的登出操作
註冊runner是根據Secret中的token進行註冊的(也就是gitlab-server中的token)
提問問題時沒搞明白指令碼的具體含義,指令碼中是 藉助gitlab-runner的token來進行登出runner的一個操作 而註冊的操作還是使用gitlab-server提供的token
問題二:configmap中的變數從哪裡可以看到?
在configmap中gitlab-ci-runner-cm的其他變數怎麼沒看到使用?
這些變數是藉助/usr/bin/gitlab-ci-multi-runner進行使用的,自帶的內建變數引數
檢視有哪些變數 /usr/bin/gitlab-ci-multi-runner register --help
問題四:RUNNER_NAME這個變數是自帶的嗎?
根據K8S中的pod自帶獲取名稱方式獲取的
metadata.name
問題五:kill %1 是什麼意思?
kill %1這條命令表示殺死一個後臺程式,這個後臺程式的“工作號碼(jobnumber)”是1號。job命令的作用就是將放在後臺執行的程式(& nohup等方式執行的程序)給顯示出來,kill %1 則是將後臺程式的job號碼為1的給殺掉。
問題六:設定容忍度
問題描述:將K8S自動設定的系統汙點誤認為是人為設定的,導致找不到對應的key:value值,陷入不知道該如何設定容忍度的問題
正常情況下 kubectl describe node work1 |grep Taint 命令是可以看到人為設定的key:value的汙點的。
我誤認為 磁碟故障而導致K8S系統自動給node節點打的汙點 是人為設定的汙點,導致使用kubectl describe node work1|grep Taint 而沒有找到key:value,從而陷入不知道該如何設定容忍的困境
解決: 如果是人為設定的汙點,kubectl describe node work1 其實是可以看到設定的汙點的key:value的
work1因為磁碟的故障而自動打汙點
Warning Evicted 1s kubelet The node had condition: [DiskPressure].
問題七:gitlab-runner建立的容器需要設定容忍度
問題描述:gitlab-runner在接收到任務時 自動建立執行具體內容的容器 無法容忍汙點 一直處於pending的狀態
因為在yml檔案中可以設定gitlab-runner的容忍,但是不清楚gitlab-runner執行後自動建立的容器是怎麼設定汙點容忍的。
解決:
須知:①gitlab-runner建立的容器 是從configmap中定義的環境變數中來獲取資訊的;②configmap中設定的gitlab-runner的環境變數獲取方式為:/usr/bin/gitlab-ci-multi-runner register --help|grep kubernetes-node-tolerations
root@c75cacba4598:/# /usr/bin/gitlab-ci-multi-runner register --help|grep kubernetes-node-tolerations
Runtime platform arch=amd64 os=linux pid=50 revision=8925d9a0 version=14.1.0
--kubernetes-node-tolerations value A toml table/json object of key=value:effect. Value and effect are expected to be strings. When set, pods will tolerate the given taints. Only one toleration is supported through environment variable configuration. (default: "{}") [$KUBERNETES_NODE_TOLERATIONS]
具體解決方法:在yml中的configmap中設定 gitlab-runner建立容器時的特性
KUBERNETES_NODE_TOLERATIONS: "node-role.kubernetes.io/master:NoSchedule"
補充gitlab-ci-multi-runner命令解釋
NAME:
gitlab-ci-multi-runner - a GitLab Runner
USAGE:
gitlab-ci-multi-runner [global options] command [command options] [arguments...]
VERSION:
14.1.0 (8925d9a0)
AUTHOR:
GitLab Inc. <[email protected]>
COMMANDS:
exec 在本地執行構建
list 列出所有配置的執行程式
run 執行多執行程式服務
register 登記新的runner
install 安裝服務
uninstall 解除安裝服務
start 開始服務
stop 停止服務
restart 重啟服務
status 獲取服務狀態
run-single 啟動單執行緒runner
unregister 取消註冊特定的執行程式
verify 驗證所有已註冊的runner
artifacts-downloader 下載並提取構建工件(內部)
artifacts-uploader 建立和上載構建工件(內部)
cache-archiver 建立和上載快取工件(內部)
cache-extractor 下載並提取快取工件(內部)
cache-init 已更改快取路徑的許可權(內部)
health-check 檢查特定地址的執行狀況
read-logs 從kubernetes executor(內部)使用的檔案讀取作業日誌
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--cpuprofile value write cpu profile to file [$CPU_PROFILE]
--debug debug mode [$DEBUG]
--log-format value Choose log format (options: runner, text, json) [$LOG_FORMAT]
--log-level value, -l value Log level (options: debug, info, warn, error, fatal, panic) [$LOG_LEVEL]
--help, -h show help
--version, -v print the version
因為你不會,所以你才會---大司馬