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
-
配置倉庫(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
-
創建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
-
同步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
中指定其實現方式:包括Configmap
、Secret
、PVC
;如果不需要在多個任務間共享則可以使用pv
、emptyDir
的形式。
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_hosts
的Secret
,使其能夠有目標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
傳入的IMAGE
和EXPRESSION
參數組合成:$(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
一樣依賴兩個workspaces
:srouce
、ssh-directory
Deploy
藉助argocd的客戶端來執行同步過程,
- APP_NAME:Argocd的APP名稱
- BRANCH:Argocd監聽項目的分支
同樣是從tekton hub上找到的argocd部署任務模版:deploy-argocd.yaml
在這個任務中需要制定argocd-server的服務地址,還需要能夠操作argocd的用戶名和密碼,這些可以不作為變數,直接hardcode在模版中