Tekton+Argocd實現自動化流水線

本文和所有涉及到的圖片、yaml都已經上傳到我的github上了://github.com/goofy-z/k8s-learning/tree/master/Tekton-Argocd

什麼是tekton

Tekton 是一個功能強大且靈活的Kubernetes 原生開源框架,用於雲上持續集成和交付(CI/CD)系統,通過Operator的方式集成到k8集群中,並以容器作為驅動,完成流水線模版定義的任務,社區也提供了很多任務模版來方便使用。

安裝tekton

kubectl apply -f //storage.googleapis.com/tekton-releases/pipeline/previous/v0.26.0/release.yaml

總共部署了兩個deployment,默認是在namespacetekton-pipelines

kubectl get deploy -n tekton-pipelines 
NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
tekton-dashboard              1/1     1            1           88d // 這個是dashboard
tekton-pipelines-controller   1/1     1            1           69d
tekton-pipelines-webhook      1/1     1            1           88d

安裝Dashboard

kubectl apply --filename //storage.googleapis.com/tekton-releases/dashboard/latest/tekton-dashboard-release.yaml

默認dashboard服務是只能通過ClusterIP訪問,我們可以通過修改它的svc的類型為NodePort或者直接在當前節點使用代理訪問kubectl port-forward svc/tekton-dashboard -n tekton-pipelines 37033:9097

Tekton提供的CRD

  • Task: 任務模版,你可以在裡面定義相應的steps來表示需要執行的步驟,每個step代表一個pod。
  • TaskRun:任務模版的執行實例,通過傳入任務模版定義的參數來創建。
  • Pipeline:流水線模版,包含一系列任務並且定義各個任務之間的先後順序。
  • PipelineRun:流水線模版實例,關聯到流水線並傳入所有的任務參數來執行

安裝argocd

創建argocd

kubectl create namespace argocd
kubectl apply -n argocd -f //raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

執行完之後我們能看到在argocd Namespace下創建了4個deployment

kubectl get deployment -n argocd
NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
argocd-dex-server    1/1     1            1           14m
argocd-redis         1/1     1            1           14m
argocd-repo-server   1/1     1            1           14m
argocd-server        1/1     1            1           14m
  • argocd-dex-server: 與SSO有關

  • argocd-redis:這就是redis服務

  • argocd-repo-server:維護保存應用程式清單的Git存儲庫的本地快取,並負責生成和返回Kubernetes清單

  • argocd-server: API伺服器是gRPC/REST伺服器,它公開Web UI、CLI和CI/CD系統所使用的API。

此外還有一個sts資源

kubectl get sts -n argocd 
NAME                            READY   AGE
argocd-application-controller   1/1     14m
  • argocd-application-controller: 一個k8s控制器,監控運行的應用,並將當前的活動狀態與所需的目標狀態(在repo中指定)進行比較。

然後是創建5個svc

kubectl get svc -n argocd 
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP             
argocd-dex-server       ClusterIP   172.31.104.178   <none>      
argocd-metrics          ClusterIP   172.31.130.239   <none>      
argocd-redis            ClusterIP   172.31.81.161    <none>       
argocd-repo-server      ClusterIP   172.31.61.26     <none>        
argocd-server           NodePort    172.31.93.217    <none>      
argocd-server-metrics   ClusterIP   172.31.154.210   <none>       

注意:argocd-server被我修改成了NodePort的形式便於我通過UI介面訪問,暴露了http和https的埠

安裝客戶端

curl -sSL -o /usr/local/bin/argocd //github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x /usr/local/bin/argocd

連接argocd server

訪問argocd-server有兩種方式,一個是通過UI來登錄,一種通過客戶端,但首先還是得獲取登錄的密碼,帳號是admin.

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
VntlGg8mCy1chAzE // 這就是密碼

使用客戶端登錄:

argocd login 172.31.93.217 // 在集群內部可以用ClusterIP
WARNING: server certificate had error: x509: cannot validate certificate for 172.31.93.217 because it doesn't contain any IP SANs. Proceed insecurely (y/n)? y
Username: admin
Password: 

創建App

  1. 配置倉庫(repo)

    argocd作為GitOps解決方案,本身依賴一個存儲應用程式聲明文件的Git倉庫,同步集群中相關資源狀態為Git倉庫中聲明文件的期望狀態。

    創建一個repo對象需要能夠真正能訪問該repo,並且具有許可權,因為argocd會主動去訪問該git的API從而獲取對應的目錄結構、分支等資訊,我們通過創建帶ssh私鑰的Secret的來或得訪問許可權。

    argocd repo add [email protected]:DaoCloud/Atr-api.git --ssh-private-key-path /root/.ssh/id_rsa
    

    查看repo是否創建成功

    argocd repo list
    TYPE  NAME  REPO                                 INSECURE  OCI    LFS    CREDS  STATUS      MESSAGE
    git         [email protected]:DaoCloud/Atr-api.git  false     false  false  false  Successful
    
  2. 創建APP

    還是通過客戶端的方式來創建

    argocd app create guestbook --repo git_url --path deploy --dest-server //kubernetes.default.svc --dest-namespace default --revision branch
    

    參數解釋:

    • create後的第一個位置參數代表app的名稱
    • repo:該應用綁定的配置倉庫
    • path:監聽的聲明文件在配置倉庫的路徑
    • dest-server:部署的目標集群,//kubernetes.default.svc
    • dest-namespace:部署的目標集群NameSpace
  3. 同步app到集群

    argocd app sync guestbook
    TIMESTAMP                  GROUP        KIND   NAMESPACE                   NAME    STATUS   HEALTH        HOOK  MESSAGE
    2021-10-22T18:20:35+08:00   apps  Deployment  default            kaifang-ui    Synced  Healthy              
    2021-10-22T18:20:35+08:00   apps  Deployment  default            kaifang-ui    Synced  Healthy              deployment.apps/kaifang-ui unchanged
    
    Name:               guestbook
    Project:            default
    Server:             //kubernetes.default.svc
    Namespace:          xxxxx
    URL:                //172.31.93.217/applications/guestbook
    Repo:               xxxx.git
    Target:             develop-goofy5
    Path:               deploy
    SyncWindow:         Sync Allowed
    Sync Policy:        <none>
    Sync Status:        Synced to develop-goofy5 (c8e8289)
    Health Status:      Healthy
    
    Operation:          Sync
    Sync Revision:      c8e828979745b3589515196ec469bdbca271da29
    Phase:              Succeeded
    Start:              2021-10-22 18:20:34 +0800 CST
    Finished:           2021-10-22 18:20:35 +0800 CST
    Duration:           1s
    Message:            successfully synced (all tasks run)
    
    GROUP  KIND        NAMESPACE    NAME        STATUS  HEALTH   HOOK  MESSAGE
    apps   Deployment  kongtianbei  kaifang-ui  Synced  Healthy        deployment.apps/kaifang-ui unchanged
    

集群中查看效果

添加集群

argocd添加集群需要在部署了argocd的集群能夠訪問到待添加集群,可以在kubeconfig文件中添加目標集群的集群證書和用戶證書等資訊,下面命令實際就是去創建一套該sa並綁定到admin的ClusterRole角色

argocd cluster add zone_41 // zone_41 位目標集群的context

開始構建CI/CD流水線

由於一些任務依賴與Argocd創建的應用的配置,需要提前建立好Argocd的應用,具體方式參考上面。

流水線共有以下幾個任務:

  • Git Clone:clone倉庫,提供工作區用於鏡像構建。
  • Build Image:藉助容器中構建鏡像技術,如kaniko來構建鏡像,並push到指定倉庫。
  • Change Config:修改應用的部署聲明文件,這裡替換deployment聲明文件的Image為新的Image。
  • Git Push Config:提交應用的聲明文件到argocd監聽的git倉庫。
  • Deploy:主動觸發Argocd的同步,從而實現鏡像替換的部署。

創建Task

接下來會介紹對每一個任務的功能實現細節,在此之前還需要介紹一個tekton的資源對象workspaces,在CI過程中多個任務share同一個工作區,所以依賴一個能夠在多個任務(也就是pod)間共享的存儲,而workspaces資源對象正是為每一個Task抽象出一個文件系統,但需要在TaskRun中指定其實現方式:包括ConfigmapSecretPVC;如果不需要在多個任務間共享則可以使用pvemptyDir的形式。

Git Clone

這一步是將目標程式碼倉庫程式碼拉取到工作區,共包含下述幾個任務參數:

  • CLONE_URL: git倉庫地址
  • SUBDIR:git clone之後的項目名
  • BRANCH:git clone的分支

下面是從tekton hub上找到的git-cli模版,做了一些修改:git-cli.yaml

同時依賴至少兩個workspaces

  • source:用於存放程式碼的工作區,使用pvc實現存儲。
  • ssh-directory:一個保存了ssh私鑰known_hostsSecret,使其能夠有目標git倉庫的許可權。

Build Image

任務的主要功能是構建鏡像並push到指定的鏡像倉庫,任務參數如下:

  • IMAGE:構建之後的目標鏡像
  • CONTEXT:工作區的目錄,這裡對應上一步的SUBDIR
  • DOCKERFILE: Dockerfile文件路徑

下面同樣是從tekton hub上找到的git-cli模版,做了一些修改:kaniko.yaml

同時依賴至少兩個workspaces

  • source:用於存放程式碼的工作區,使用pvc實現存儲。
  • dockerconfig:一個保存了docker的auth配置資訊的configmap,使其能夠有push鏡像倉庫的許可權。

Change Config

在鏡像build完成且推送鏡像倉庫成功後,需要取更新應用聲明文件里的鏡像地址,目前是藉助yq工具修改指定名稱文件的deployment資源定義文件里鏡像,需要自己寫yq的表達式。

  • CONTEXT:工作區需要更改的git項目目錄,這個git必須是argocd監聽的項目
  • CONFIG_FILE:deployment資源定義文件名,必須是位於argocd設置的path
  • EXPRESSION:yq表達式,例如在pipelineRun傳入(.spec.template.spec.containers.[]|select(.name == \"api\").image)|=,這個表達式的意思就是找到名稱為api容器並將image欄位替換為=後的新鏡像,在後面定義pipeline時,我們時直接將pipelineRun傳入的IMAGEEXPRESSION參數組合成:$(params.EXPRESSION)\"$(params.IMAGE)\"傳入到該任務,這樣完整的yq表達式為(.spec.template.spec.containers.[]|select(.name == \"api\").image)|="新構建的鏡像"

只依賴source這一個workspace。

Git Push Config

這一步就是提交應用聲明文件的更改。

  • SUBDIR:argocd監聽git項目目錄名
  • BRANCH:argocd監聽git項目的分支

同樣是從tekton hub上找到的argocd部署任務模版:git-push-config.yaml

Git Clone一樣依賴兩個workspacessroucessh-directory

Deploy

藉助argocd的客戶端來執行同步過程,

  • APP_NAME:Argocd的APP名稱
  • BRANCH:Argocd監聽項目的分支

同樣是從tekton hub上找到的argocd部署任務模版:deploy-argocd.yaml

在這個任務中需要制定argocd-server的服務地址,還需要能夠操作argocd的用戶名和密碼,這些可以不作為變數,直接hardcode在模版中

創建Pipeline

ci-cd-pipeline.yaml

創建TaskRun(示例)

run.yaml