使用 KubeSphere 和極狐GitLab 打造雲原生持續交付系統

KubeSphere發表於2022-06-01

KubeSphere 簡介

Kubernetes 是一個非常複雜的容器編排平臺,學習成本非常高,KubeSphere 所做的事情就是高度產品化和抽象了底層 Kubernetes,是一個面向雲原生的作業系統。講得再通俗一點,Kubernetes 遮蔽了底層容器執行時的差異,而 KubeSphere 則遮蔽了底層 Kubernetes 叢集的差異,它解決了 K8s 使用門檻高和雲原生生態工具龐雜的痛點。你可以在視覺化介面上點幾下滑鼠即可將 Pod 排程到叢集的不同節點中,無需編寫 YAML。

上面是 KubeSphere 的功能架構,可以看到 KubeSphere 包含了非常多的應用場景,比如微服務、DevOps、應用管理、可觀測性和安全等,每一個場景生態下面都包含了很多對研發和運維人員比較友好的元件,而且所有的元件都是可插拔的,使用者可以根據自己的意願自由選擇啟用哪個元件。

從 v4.0 開始,KubeSphere 會提供前後端可插拔的架構和框架,任何第三方合作夥辦和 ISV 都可以基於 KubeSphere 4.0 開放框架,開發擴充套件自己想要的功能外掛,這些功能外掛與 KubeSphere 有完全一致的 UI 體驗,形成更強大的應用生態。這就好比 Mac OS 和 App Store 之間的關係一樣,任何企業或團隊都可以釋出自己開發的外掛到應用商店,靈活滿足各類使用者的需求,在社群與 KubeSphere 合作互利共贏。

極狐GitLab 簡介

極狐GitLab 是一個一體化的 DevOps 平臺,可以簡單理解為 GitLab 在國內的“發行版”。是由極狐(GitLab)公司推出的產品(極狐(GitLab)公司是以“中外合資3.0”模式成立的公司,在國內獨立運營,為國內使用者提供適合本土化的 DevOps 平臺以及支援服務)。

極狐GitLab 是開源的,任何人都可以參與開源共建,程式碼託管在極狐GitLab SaaS 上:https://jihulab.com/gitlab-cn...。其提供的一體化 DevOps 能力覆蓋軟體開發全生命週期(從計劃到運維),同時內建了安全功能,能夠利用開箱即用的安全能力構建 DevSecOps 體系。

更重要的一點是,極狐GitLab 支援自建(私有部署)和 SaaS 兩種服務。在私有部署的時候,支援多種安裝方式,其中就包括雲原生的安裝方式,因此,結合 KubeSphere 和極狐GitLab,可以打造出一個適應雲原生時代的持續交付系統。

在 KubeSphere 上安裝極狐GitLab 和 Runner

目前在 KubeSphere 上部署極狐GitLab 非常便利,只需要利用 KubeSphere 的應用商店即可一鍵部署。

應用商店與應用全生命週期管理是 KubeSphere 獨有的特色,KubeSphere 為使用者提供了一個基於 Helm 的應用商店,用於應用生命週期管理。而且從 3.2.0 版本開始,KubeSphere 新增了 “動態載入應用商店” 的功能,合作伙伴可申請將應用的 Helm Chart 整合到 KubeSphere 應用商店,相關的 Pull Request 被合併後,KubeSphere 應用商店即可動態載入應用,不再受到 KubeSphere 版本的限制。目前極狐 Gitlab 就是通過動態載入的方式將其 Helm Chart 上架到了 KubeSphere 的應用商店。

安裝極狐GitLab

直接選擇下圖紅色方框中的 jh-gitlab 即可開始部署。

下一步需要修改一些引數,即 Helm Chart 中的 values。

大家需要根據自己的實際情況修改,我的私有環境不需要 Ingress,可以通過 Cluster IP 直連,所以才將域名全部設定成了 Service Name。除此之外,還需要取消安裝 Runner,後續再單獨安裝。其他引數可以自己酌情修改,比如我取消了 Certmanager 和 Ingress-Nginx。

檢視建立好的工作負載:

部署完成後,就可以通過設定好的域名訪問極狐GitLab。

預設使用者名稱是 root,初始密碼可以通過以下命令獲取:

$ kubectl -n jh-gitlab get secret jh-gitlab-gitlab-initial-root-password -o go-template --template='{{.data.password}}' | base64 -D

登入之後可以先建立一個專案,下面安裝 Runner 和演示 Demo 的章節都會用到。

安裝極狐GitLab Runner

極狐GitLab Runner 只是極狐GitLab 的其中一個元件,所以不能再通過應用商店來安裝。KubeSphere 除了過應用商店之外,還可以通過應用倉庫和應用模板來安裝應用。所謂應用倉庫,就是一個寬鬆版的應用商店,應用商店是所有使用者共用的,應用倉庫只是個人版的應用商店,不需要審批,只會存在於你自己的叢集中。只需將相關應用 Helm Chart 的 URL 匯入,即可變成應用倉庫中的一個應用。這裡我們選擇匯入極狐GitLab 的 Helm Chart。

然後在『應用』中點選『建立』。

然後選擇『從應用模板』,在彈出皮膚的下拉框中選擇 GitLab。

選擇 gitlab-runner,然後設定應用名稱,繼續點選下一步,開始修改部署引數。

其中,gitlabUrl 的值為極狐GitLab 的視覺化介面地址,runnerRegistrationToken 的值可以設定為想要使用該 Runner 的專案的 CI/CD Specific runners 的 registration token,例如:

同時還需要開啟 RBAC:

rbac:
  create: true
  rules: []
  clusterWideAccess: false
  podSecurityPolicy:
    enabled: false
    resourceNames:
      - gitlab-runner

其他引數可根據實際情況酌情修改,修改完成後點選下一步開始安裝。安裝完成後,可以進入 Pod 檢視註冊情況:

$ kubectl -n jh-gitlab get pod -l release=gitlab-runner
NAME                                          READY   STATUS        RESTARTS   AGE
gitlab-runner-gitlab-runner-c7c999dfc-wgg56   1/1     Running       0          61s

$ kubectl -n jh-gitlab exec -it gitlab-runner-gitlab-runner-c7c999dfc-wgg56 -- bash
Defaulted container "gitlab-runner-gitlab-runner" out of: gitlab-runner-gitlab-runner, configure (init)
bash-5.0$ gitlab-runner list
Runtime platform                                    arch=amd64 os=linux pid=106 revision=f761588f version=14.10.1
Listing configured runners                          ConfigFile=/home/gitlab-runner/.gitlab-runner/config.toml
gitlab-runner-gitlab-runner-c7c999dfc-wgg56         Executor=kubernetes Token=dSz6WoJzpD5bjkDhP5xN URL=https://jihulab.com/
bash-5.0$

可以看到 Pod 裡面已經內建了 gitlab-runner 命令,且有註冊成功的 Runner 例項 gitlab-runner-gitlab-runner-c7c999dfc-wgg56,而這就是剛剛用應用模板安裝的 Runner。在極狐GitLab 的 Web 頁面也可以看到註冊成功的 Runner。

CI/CD Demo 演示

接下來我們通過一個簡單的流水線示例來演示極狐GitLab 的 CI/CD 流水線工作原理。演示流水線之前,先來了解幾個基本概念。

極狐GitLab 流水線包含兩個核心元件:

  • Job : 描述需要執行的任務;
  • Stage : 定義 Job 執行的順序。

而流水線(Pipeline)則是一組執行在各個 Stage 中的 Job 集合,可以包含多個流程:編譯、測試、部署等等,任何提交或 Merge Request 都能觸發流水線。

負責執行 Job 的就是 Runner,Runner 的本體,是執行在某臺機器上的守護程式,類似於 Jenkins agent。在 Runner 自己看來,沒有型別的區別,它只是根據 Token 和 URL,註冊到指定的極狐GitLab 而已。

講完了基礎概念,直接來看示例倉庫。

這個示例應用是用 Go 寫的 HTTP Server,程式碼很簡單,我就不解釋了。

package main

import (
    "fmt"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello this is kubesphere")
}

func main() {
    http.HandleFunc("/ks", handler)
    log.Fatal(http.ListenAndServe(":9999", nil))
}

流水線編排檔案是 .gitlab-ci.yml,內容如下:

stages:
  - build
  - deploy

build:
  image: 
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  stage: build
  tags: 
    - kubernetes
  script:
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"${CI_REGISTRY}\":{\"auth\":\"$(printf "%s:%s" "${CI_REGISTRY_USER}" "${CI_REGISTRY_PASSWORD}" | base64 | tr -d '\n')\"}}}" > /kaniko/.docker/config.json
    - >-
      /kaniko/executor
      --context "${CI_PROJECT_DIR}"
      --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
      --destination "${CI_REGISTRY_IMAGE}:1.0.0"

deploy:
  image: bitnami/kubectl:latest
  stage: deploy
  tags: 
    - kubernetes
  variables:
    KUBERNETES_SERVICE_ACCOUNT_OVERWRITE: jh-gitlab
  only:
    - main
  script:
    - kubectl -n jh-gitlab apply -f deployment.yaml

由於最新版的 Kubernetes 無情地拋棄了 Docker,推薦使用 Containerd 作為執行時,所以就沒法使用 Docker 來構建映象啦,我們可以選擇使用 Kaniko。Kaniko 是谷歌開源的一款用來構建容器映象的工具。與 Docker 不同,Kaniko 並不依賴於 Docker Daemon 程式,完全是在使用者空間根據 Dockerfile 的內容逐行執行命令來構建映象,這就使得在一些無法獲取 Docker Daemon 程式的環境下也能夠構建映象,比如在標準的 Kubernetes 叢集上。

這個流水線總共包含兩個階段:構建和部署。部署階段需要注意的是,預設情況下 Kubernetes 中的 Pod 是沒有許可權建立工作負載的,所以我們需要建立一個新的 ServiceAccount,將其繫結到具有許可權的 ClusterRole 上面。

# rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jh-gitlab
  namespace: jh-gitlab
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: gitlab-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: jh-gitlab
    namespace: jh-gitlab
$ kubectl apply -f rbac.yaml

最後再讓 Runner 使用這個新的 ServiceAccount,即:

  variables:
    KUBERNETES_SERVICE_ACCOUNT_OVERWRITE: jh-gitlab

但是這樣還不行,預設情況下流水線沒有許可權修改 Runner 的 ServiceAccount,需要修改 Runner 的部署清單,賦予其修改許可權。

注意圖中右側的高亮部分,表示允許 jh-gitlab 這個 namespace 下面的 Pod 更改其 ServiceAccount。修改完畢後點選更新即可。

這是我的完整配置,供大家參考:

imagePullPolicy: IfNotPresent
gitlabUrl: 'https://jihulab.com/'
runnerRegistrationToken: GR1348941fycCAhY3_LnRFPqy3DL4
terminationGracePeriodSeconds: 3600
concurrent: 10
checkInterval: 30
sessionServer:
  enabled: false
rbac:
  create: true
  rules: []
  clusterWideAccess: false
  podSecurityPolicy:
    enabled: false
    resourceNames:
      - gitlab-runner
metrics:
  enabled: false
  portName: metrics
  port: 9252
  serviceMonitor:
    enabled: false
service:
  enabled: false
  type: ClusterIP
runners:
  config: |
    [[runners]]
      [runners.kubernetes]
        namespace = "{{.Release.Namespace}}"
        image = "ubuntu:16.04"
  privileged: true
  tags: "kubernetes"
  cache: {}
  builds: {}
  services: {}
  helpers: {}
securityContext:
  runAsUser: 100
  fsGroup: 65533
resources: {}
affinity: {}
nodeSelector: {}
tolerations: []
envVars:
  - name: KUBERNETES_SERVICE_ACCOUNT_OVERWRITE_ALLOWED
    value: jh-gitlab
hostAliases: []
podAnnotations: {}
podLabels: {}
secrets: []
configMaps: {}

現在隨便修改倉庫中的檔案(比如 README)來觸發流水線。

可以看到流水線被成功觸發並執行成功。最後我們來看看構建好的映象有沒有被成功部署。

從 KubeSphere 視覺化介面裡可以看到應用被成功部署了。最後可以測試一下這個 HTTP Server 是否正常工作:

$ kubectl -n jh-gitlab get pod -l app=cicd-demo -owide
NAME                         READY   STATUS    RESTARTS   AGE     IP             NODE           NOMINATED NODE   READINESS GATES
cicd-demo-86d7fb797c-428xs   1/1     Running   0          4m40s   10.233.65.81   k3s-worker02   <none>           <none>

$ curl http://10.233.65.81:9999/ks
Hello this is kubesphere

總結

本文給大家介紹了 KubeSphere 和極狐GitLab 以及各自的優勢,並探討了如何結合 KubeSphere 和極狐GitLab 來打造一個雲原生時代的持續交付系統,最後通過一個流水線示例來展示極狐 GiLab 流水線的工作原理。

從最後的示例可以看出,CD(即部署階段)的過程還是比較麻煩的,比如需要安裝配置額外工具(kubectl),還需要 Kubernetes 對其進行授權,如果 Kubernetes 部署在雲平臺中,還需要雲平臺對其授權。最重要的是,它無法感知部署的狀態,部署完了之後無法獲知該工作負載是否正常提供服務。

那麼這個問題有沒有解決辦法呢?我將在下一篇文章中給大家介紹如何通過 GitOps 來解決這個問題。

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章