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

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/gitlab。其提供的一體化 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 發佈!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章