Choerodon豬齒魚 Agent——基於GitOps的雲原生持續交付模型

本文將介紹Choerodon平臺持續交付部署流水線的一個核心組件——Choerodon Agent。git

▌文章的主要內容包括:github

  • 概述
  • 實現分析
  • 具體設計
    • 創建鏈接初始化信息
    • Command/Response模式
    • 實時狀態反饋
    • Helm Operator
    • GitOps
    • 狀態同步與修復
    • Log和Exec長鏈接
  • 總結

概述

Choerodon Agent是支撐Choerodon平臺持續交付部署流水線的一個核心組件,負責將平臺生成的部署文件應用到應用部署環境對應的Kubernetes集羣之中。並實施返回各個應用實例以及應用實例下全部資源的最新狀態信息,同時經過監聽各個環境對應的部署文件Git庫,執行CD操做。並且支持混合雲以及多雲做爲平臺的部署環境,經過返回回來的容器信息和反饋回來各個實例下的容器,還能夠實時獲取容器日誌,以及容器exec執行遠程命令。web

Choerodon持續交付能夠支持任意數量的集羣加入平臺,做爲應用的部署環境,只要將平臺中生成的Agent安裝腳本在任意Kubernetes集羣中執行,就能夠將該集羣加入平臺,而後在平臺上建立環境時能夠選擇該集羣,能夠一鍵建立環境。在同一個集羣中能夠建立多個環境,各個環境之間經過Kubernetes的命令空間隔離。api

平臺初始化部署集羣只須要將平臺生成的Agent安裝腳本在Kubernetes環境中執行。Agent在集羣中安裝以後即可以在該集羣中建立環境。做爲項目應用的部署環境。安全

建立集羣以後,平臺會提供一份激活指令,將指令粘貼至Kubernetes集羣中執行,成功後集羣就鏈接成功了。在平臺的界面上集羣顯示的狀態也爲運行中。下圖所示腳本就是Agent的激活指令。微信

helm install --repo=http://chart.choerodon.com.cn/choerodon/c7ncd/ \
--namespace=choerodon \
--name=choerodon-cluster-agent-test \
--version=2018.12.10-112732-master \
--set config.connect=ws://devops.com.cn/agent/ \
--set config.token=dccf4539-43e7-4970-a2d4-271267850d67 \
--set config.clusterId=21 \
--set config.choerodonId=434ha8v7sz90 \
--set rbac.create=true \
choerodon-cluster-agent

集羣鏈接成功以後,能夠在環境流水線管理界面,選擇相應的集羣一鍵建立環境。建立環境時,平臺會給Agent發送一條指令,讓Agent建立相應命令空間,並拉去初始化環境對應的Git庫,開始準備同步。網絡

環境建立成功以後相關持續交付的部署操做便可選擇該環境做爲目標環境,進行應用部署,網絡、域名、證書的建立。全部操做都將發送至Agent由Agent執行,所對應資源對象狀態的變動也有Agent傳輸回來,進行實時展現。框架

實現分析

基於以上的這些功能目標,並且考慮到Choerodon Agent做爲一個連通持續交付平臺和Kubernetes集羣的代理客戶端,須要具有實時性、穩定性和高性能,因此決定用go語言實現,充分利用go輕量高效的特性。使用go做爲開發語言,能夠便捷的使用client-go,helm client等現成工具庫開發CD相關操做。因爲須要實時監聽,實時反饋,等特性,Agent與DevOps之間的交互採用WebSocket長鏈接。而且使用客戶端的方式,不提供對外暴露訪問接口,充分保證安全性並且不須要集羣提供對外暴露訪問接口。socket

用戶在平臺中建立環境時同時會建立一個與環境對應的Git倉庫用來存放部署配置文件,以後全部在環境中部署相關操做,都會轉化爲Git庫中部署配置文件的操做,用戶在平臺界面操做部署或者直接推送部署文件至Git庫都會觸發Git庫配置的Webhook,以後繼續交付微服務拉取最新提交,解析並生成tag,而後通知環境客戶端去執行環境對應Git庫中最新的變動。環境客戶端收到持續交付服務通知後,執行最新一次的tag,執行完畢後生成執行tag,當環境的最新提交Commit sha,與持續交付服務解釋tag的sha,與環境客戶端執行的tag sha一致時,表示最新的操做或者提交都已經應用到環境。微服務

  1. 用戶能夠經過直接向Git庫提交和在界面上進行相關部署操做,在GitOps中,界面上進行的部署操做都會先直接修改環境對應的部署文件Git庫。例如一個應用實例版本更新部署操做對應在部署文件中的提交如上圖。

  2. 部署文件Git庫產生提交後,git庫中的webhook隨機觸發,將變動發送至DevOps服務

  3. DevOps服務拉取庫中最新提交,與上一個tag版本進行比較,根據比較結果分別生成建立、更新、刪除記錄,從新生成tag。

  4. 通知對應環境Agent拉取DevOps服務最新解析tag。

  5. Agent從部署庫中拉取最新DevOps解析tag。

  6. 並根據部署庫文件,與環境中真實部署的對象列表進行比較,而後在環境執行建立、更新、刪除操做。執行完成後將執行結果發回至DevOps服務。

具體設計

Choerodon Agent經過WebSocket Client與外部的豬齒魚部署服務進行鏈接、執行命令等交互。內部經過Helm客戶端與Kubernetes集羣。

內部的tiller server執行Chart安裝刪除等操做,而且經過Kube Client直接對Kubernetes各類資源對象進行操做,監聽各資源對象的狀態變動。

經過長鏈接及時通知部署服務。Choerodon Agent和部署服務之間的交互採用Command/Response模式,啓動時當即向部署服務創建鏈接,接收Command執行並返回結果Repsonse。做爲WebSocket Client將Command經過Channel不斷的發送至執行器,執行器Worker是一個可伸縮配置的工做線程/協程池,執行後將結果經過Channel給Websocket Client寫回。具體實現可主要分爲以下幾個主要功能塊。

創建鏈接初始化信息

Agent啓動時當即與DevOps服務創建WebSocket長鏈接,經過Websocket Client當即與DevOps服務創建WebSocket長鏈接,鏈接成功以後,DevOps服務集羣的初始化信息從WebSocket發送至Agent、Agent根據初始化信息,啓動Controller監聽對應的命名空間,對集羣下的每一個GitOps環境庫啓動Git庫同步程序。初始配置信息包含對各個環境Git庫的SSH配置,以下所示。

Host c7n-agile-prod
   HostName code.choerodon.com.cn
   StrictHostKeyChecking no
   UserKnownHostsFile /dev/null
   IdentityFile /rsa-c7n-agile-prod
   LogLevel error
 Host c7n-tm-prod
   HostName code.choerodon.com.cn
   StrictHostKeyChecking no
   UserKnownHostsFile /dev/null
   IdentityFile /rsa-c7n-tm-prod
   LogLevel error

Command/Response模式

Agent不斷從長鏈接中讀取命令,也不停的從Channel中讀取返回結果寫至長鏈接中,命令解析出來以後經過Channel發送至Worker,而後在Worker中經過K8S Client或者Helm Client執行相應命令。執行成功以後將結果再經過Channel發回至 Agent Websocket Client,Client將結果經過長鏈接發送回DevOps。

實時狀態反饋

經過Controller機制監聽實例下的各個Kubernetes資源對象、只要有對象建立、更新或者刪除、Controller中就會監聽到,在Controller監聽到對應的資源對象以後,判斷,並實時反饋傳輸回DevOps服務。

func NewpodController(podInformer v1_informer.PodInformer, responseChan chan<- *model.Packet, namespaces *manager.Namespaces) *controller {
   c := &controller{
      queue:            workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "pod"),
      workerLoopPeriod: time.Second,
      lister:           podInformer.Lister(),
      responseChan:     responseChan,
      namespaces:        namespaces,
   }

  podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
      AddFunc: c.enqueuepod,
      UpdateFunc: func(old, new interface{}) {
         newpod := new.(*v1.Pod)
         oldpod := old.(*v1.Pod)
         if newpod.ResourceVersion == oldpod.ResourceVersion                 {        return
         }
         c.enqueuepod(new)
      },

      DeleteFunc: c.enqueuepod,
   })
   c.podsSynced = podInformer.Informer().HasSynced
   return c

}

Helm Operator

將Chart應用實例經過K8S自定義對象描述出來,執行建立或者修改實例時候,先建立相應實例對應的文件或者修改應用實例在Git庫中對應的文件,Controller中監聽到這些文件的變化以後在經過文件執行相應的Install或者Upgrade操做。保證環境中實例的狀態與描述文件的狀態一致。

---
apiVersion: choerodon.io/v1alpha1
kind: C7NHelmRelease
metadata:
  name: choerodon-front-devops-5c483
spec:
  chartName: choerodon-front-devops
  chartVersion: 0.11.0
  repoUrl: http://chart.choerodon.com.cn/choerodon/c7ncd/
  values: |-
    env:
      open:
        PRO_HEADER_TITLE_NAME: Choerodon1

GitOps

在GitOps中針對每一個環境,在Agent初始化以後,將各個環境Git庫SSH配置建立出來、並將Git庫經過SSH拉至本機,檢測是否有權限建立和刪除tag,定時拉取最新的提交、同時在收到DevOps服務執行指令後,將最新的提交版本中的全部K8S資源文件執行至環境對應的命令空間之中。

狀態同步與修復

因爲Agent和DevOps服務之間鏈接交互採用長鏈接,可能出現因爲網絡或者其餘緣由致使消息丟失,從而產生預期與實際的狀態不一致。因此增長了狀態同步和修復的機制。保證一致性。當網絡鏈接斷開從新鏈接以後,各個Controller從新同步各種Kubernetes資源,使DevOps服務中各種資源對象的狀態與實際狀況保持一致,避免環境中的各實例資源狀態與平臺中展現的不一致.同時Devops服務會定時將一些超過一段時間還處於中間狀態的對象發送至DevOps服務查詢狀態。若是中間Agent發給DevOps的部分消息丟失或者處理失敗,形成一些不一致的狀態,會經過這個狀態修復功能將該對象的狀態修復正常,以保證兩邊的資源狀態一致性。

Log和Exec長鏈接

Agent從長鏈接中收到Log或者Exec請求指令後,創建一個Pipe,經過K8S Client Log或者Exec相關Api創建與Api Server的長鏈接,同時經過WebSocket Client 向DevOps請求創建一個長鏈接,經過這個Pipe中轉打通兩個長鏈接。從而實現Log和Exec長鏈接的中轉代理。

總結

Choerodon Agent 自發布以來,經歷了一系列優化與改進,不論是易用性仍是穩定性都在不斷提高,例如應用Chart模板中的資源對象將不用再預先插入平臺所須要的標籤,每一個環境一個Agent客戶端改爲了一個集羣一個客戶端。增長了按期同步各資源狀態的邏輯,有效地消除了平臺中與集羣的K8S資源狀態的不一致,GitOps流程也愈來愈穩定。同時也感謝社區的朋友們反饋的一些Bug和建議,一塊兒爲產品完善而努力。

關於Choerodon豬齒魚

Choerodon豬齒魚是一個開源企業服務平臺,基於Kubernetes的容器編排和管理能力,整合DevOps工具鏈、微服務和移動應用框架,來幫助企業實現敏捷化的應用交付和自動化的運營管理的開源平臺,同時提供IoT、支付、數據、智能洞察、企業應用市場等業務組件,致力幫助企業聚焦於業務,加速數字化轉型。

你們也能夠經過如下社區途徑瞭解豬齒魚的最新動態、產品特性,以及參與社區貢獻:

相關文章
相關標籤/搜索