有貨基於Kubernetes容器環境的持續交付實踐
Spinnaker介紹
Spinnaker通過將公佈和各個雲平臺解耦,來將部署流程流水線化,從而減少平臺遷移或多雲平臺部署應用的複雜度。它本身內部支援Google、AWS EC2、Microsoft Azure、Kubernetes和OpenStack等雲平臺,並且它能夠無縫整合其它持續整合(CI)流程。如Git、Jenkins、Travis CI、Docker registry、cron排程器等。
應用管理
Spinnaker主要用於展示與管理你的雲端資源。
先要了解一些關鍵的概念:Applications。Cluster,and Server Groups,通過Load balancers and firewalls將服務展示給使用者。官方給的結構例如以下:
Application
定義了叢集中一組的Cluster的集合。也包含了Firewalls與Load Balancers,儲存了服務全部的部署相關的的資訊。
Server Group
定義了一些基礎的源比方(VM image、Docker image),以及一些基礎的配置資訊,一旦部署後。在容器中相應Kubernetes Pod的集合。
Cluster
Server Groups的有關聯的集合。(Cluster中能夠依照dev,prod的去建立不同的服務組),也能夠理解為對於一個應用存在多個分支的情況。
Load Balancer
它在例項之間做負載均衡流量。您還能夠為負載均衡器啟用健康檢查,靈活地定義健康標準並指定健康檢查端點。有點相似於Kubernetes中Ingress。
Firewall
防火牆定義了網路流量訪問,定義了一些訪問的規則。如安全組等等。
頁面預覽
頁面展演示樣例如以下。還是比較精簡的。能夠在它的操作頁面上看到專案以及應用的具體資訊,還能夠進行叢集的伸縮、回滾、改動以及刪除的操作。
部署管理
上圖中。Infrastructure左側為Pipeline的設計:主要講兩塊內容:Pipeline的建立以及基礎功能,與部署的策略。
Pipeline
較強的Pipeline的能力:它的Pipeline能夠複雜到無以復加,它還有非常強的表示式功能(興許的操作中前面的引數均通過表示式獲取)。
觸發的方式:定時任務、人工觸發、Jenkins job、Docker images。或者其它的Pipeline的步驟。
通知方式:Email、SMS or HipChat。
將全部的操作都融合到Pipeline中,比方回滾、金絲雀分析、關聯CI等等。
部署策略
因為我們用的是Kubernetes Provider V2(Manifest Based)方式:可改動yaml中:spec.strategy.type。
Recreate,先將全部舊的Pod停止,然後再啟動新的Pod相應當中的第一種方式。
RollingUpdate,即滾動升級。相應下圖中另外一種方式。
Canary以下會單獨的介紹當中的使用。
非常多人都是感覺這個非常難安裝,事實上基本的原因還是牆的問題,僅僅要把這個攻克了就會方便非常多,官方的文件寫的非常具體,並且Spinnaker的社群也非常的活躍,有問題均能夠在上面進行提問。
安裝提供的方式
Halyard安裝方式(官方推薦安裝方式)
Helm搭建Spinnaker平臺
Development版本號安裝
Helm方式若是須要自己定義一些個性化的內容會比較複雜,全然依賴於原始映象,而Development須要對Spinnaker非常的熟悉,以及每一個版本號之間的相應關係均要了解。
Halyard方式安裝注意點
Halyard代理的配置
部署機器選擇vim /opt/halyard/bin/halyard
DEFAULT_JVM_OPTS='-Dhttp.proxyHost=192.168.102.10 -Dhttps.proxyPort=3128'
因為Spinnaker涉及的應用較多,以下會單獨的介紹。須要消耗比較大的記憶體,官方推薦的配置例如以下:
18 GB of RAM
A 4 core CPU
Ubuntu 14.04, 16.04 or 18.04
Spinnaker安裝步驟
Halyard下載以及安裝。
選擇雲提供者:我選擇的是Kubernetes Provider V2(Manifest Based),須要在部署Spinnaker的機器上完畢Kubernetes叢集的認證,以及許可權管理。
部署的時候選擇安裝環境:我選擇的是Debian包的方式。
選擇儲存:官方推薦使用Minio。我選擇的是Minio的方式。
選擇安裝的版本號:我當時最新的是V1.8.0。
接下來進行部署工作,初次部署時間較長,會連線代理下載相應的包。
全部下載與完畢後,檢視相應的日誌,就可以使用localhost:9000訪問就可以。
完畢以上的步驟則能夠在Kubernetes上面部署相應的應用了。
涉及的元件
下圖是Spinnaker的各個元件之間的關係。
Deck:面向使用者UI介面元件,提供直觀簡單介紹的操作介面。視覺化操作公佈部署流程。
API:面向呼叫API元件,我們能夠不使用提供的UI,直接呼叫API操作,由它後臺幫我們執行公佈等任務。
Gate:是API的閘道器元件,能夠理解為代理。全部請求由其代理轉發。
Rosco:是構建beta映象的元件,須要配置Packer元件使用。
Orca:是核心流程引擎元件,用來管理流程。
Igor:是用來整合其它CI系統元件。如Jenkins等一個元件。
Echo:是通知系統元件。傳送郵件等資訊。
Front50:是儲存管理元件。須要配置Redis、Cassandra等元件使用。
Cloud driver:是用來適配不同的雲平臺的元件。比方Kubernetes、Google、AWS EC2、Microsoft Azure等。
Fiat:是鑑權的元件。配置許可權管理,支援OAuth、SAML、LDAP、GitHub teams、Azure groups、 Google Groups等。
元件 | 埠 | 依賴元件 | 埠 |
Clouddriver | 7002 | Minio | |
Fiat | 7003 | Jenkins | |
Front50 | 8080 | Ldap | |
Orca | 8083 | GitHub | |
Gate | 8084 | ||
Rosco | 8087 | ||
Igor | 8088 | ||
Echo | 8089 | ||
Deck | 9000 | ||
Kayenta | 8090 |
例如以下Pipeline設計就是開發將版本號合到某一個分支後,通過Jenkins映象構建。公佈測試環境。進而自己主動化以及人工驗證,在由人工推斷是否須要公佈到線上以及回滾。若是選擇公佈到線上則公佈到prod環境。從而進行prod自己主動化的CI。若是選擇回滾則回滾到上個版本號,從而進行dev自己主動化的CI。
Stage-configuration
設定觸發的方式,定義全域性變數,執行報告的通知方式,是Pipeline的起點。
Automated Triggers。當中支援多種觸發的方式:定時任務Corn,Git,Jenkins,Docker Registry。Travis,Pipeline,Webhook等觸發方式,從而能夠滿足我們自己主動回撥的功能。
Parameters,此處定義的全域性變數會在整個Pipeline中使用${ parameters['branch']}得到。這樣大大的簡化了我們設計Pipeline的通用性。
Notifications。這裡通知支援:SMS。Email,HipChat等等的方式。
我們使用了郵件通知的功能:須要在echo的配置檔案裡添加發件郵箱的基本資訊。
Stage-jenkins
呼叫Jenkins來執行相關的任務。當中Jenkins的服務資訊存在放hal的配置檔案裡(例如以下展示),Spinnaker可自己主動以同步Jenkins的Job以及引數等等的資訊。執行後能夠看到相應的Job ID以及狀態:
執行完畢後展演示樣例如以下。我們能夠檢視相關的build的資訊,以及此stage執行的相關資訊。點選build能夠跳到相應的Jenkins的Job檢視相關的任務資訊。
Stage-deploy
因為我們配置Spinnaker的時候採用的是Kubernetes Provider V2方式。我們的公佈均採用yaml的方式來實現,能夠將檔案存放在GitHub中或者直接在頁面上進行配置。同一時候yaml中檔案支援了非常多的引數化,這樣大大的方便了我們日常的使用。
Halyard關聯Kubernetes的配置資訊:因為我們採用的雲服務是Kubernetes,配置的時候須要將部署Spinnaker的機器對Kubernetes叢集做認證。
Spinnaker公佈資訊展示:此處Manifest Source支援引數化形式,相似於我們寫入的yaml部署檔案。可是這裡支援引數化的方式。
具體的配置項例如以下:
- apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: '${ parameters.deployName }-deployment'
namespace: dev
spec:
replicas: 2
template:
metadata:
labels:
name: '${ parameters.deployName }-deployment'
spec:
containers:
- image: >-
192.168.105.2:5000/${ parameters.imageSource }/${
parameters.deployName }:${ parameters.imageversion }
name: '${ parameters.deployName }-deployment'
ports:
- containerPort: 8080
imagePullSecrets:
- name: registrypullsecret
- apiVersion: v1
kind: Service
metadata:
name: '${ parameters.deployName }-service'
namespace: dev
spec:
ports:
- port: 8080
targetPort: 8080
selector:
name: '${ parameters.deployName }-deployment'
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: '${ parameters.deployName }-ingress'
namespace: dev
spec:
rules:
- host: '${ parameters.deployName }-dev.ingress.dev.yohocorp.com'
http:
paths:
- backend:
serviceName: '${ parameters.deployName }-service'
servicePort: 8080
path: /
執行結果的演示樣例:
Stage-Webhook
Webhook我們能夠做一些簡單的環境驗證以及去呼叫其它的服務的功能,它自身也提供了一些結果的驗證功能,支援多種請求的方式。
執行結果的演示樣例:
Stage-Manual Judgment
Spinnaker配置資訊。用於人工的邏輯推斷,新增Pipeline的控制性(比方公佈到線上須要測試人員認證以及領導審批),內容支援多種語法表達的方式。
執行結果的演示樣例:
Stage-Check Preconditions
上邊Manual Judgment Stage配置了兩個Judgment Inputs推斷項。接下來我們建兩個Check Preconditions Stage來分別對這兩種推斷項做條件檢測,條件檢測成功,則執行相應的興許Stage流程。
比方上面的操作。若是選擇公佈到prod。則執行公佈到線上的分支,若是選擇執行回滾的操作則進行回滾相關的分支。
Spinnaker配置資訊:
執行結果的演示樣例:如上圖中我選擇了rollback。
則prod分支推斷為失敗,會堵塞後面的stage執行。
Stage-Undo Rollout(Manifest)
若是我們公佈發現出現故障。也能夠設計回滾的stage。Spinnaker的回滾極其的方便,在我們的日常部署中。每一個版本號都會存在相應的部署記錄,例如以下所看到的:
Spinnaker Pipeline配置資訊:回滾的Pipeline描寫敘述中我們須要選擇相應的deployment的回滾資訊,以及回滾的版本號數量。
執行結果的演示樣例:
Stage-Canary Analysis
金絲雀部署方式:在我們公佈新版本號時引入部分流量到Canary的服務中,Kayenta會讀取Spinnaker中配置的Prometheus中收集的指標。比方記憶體,CPU,介面超時時間,失敗率等等通過Kayenta中Netflix ACA Judge來進行分析與推斷。將分析的結果存於S3中,終於會給出這段時間的終於結果。
Canary分析主要經過例如以下四個步驟:
驗證資料
清理資料
比對指標
分數計算
設計的模型例如以下:
執行結果的設計與展示:
我們須要相應用開啟Canary的配置。
創建出Baseline與Canary的deployment由同一個Service指向這兩個deployment。
我們這裡採用讀取Prometheus的指標,須要在hal中新增Prometheus配置。
Metric能夠直接匹配Prometheus的指標。
須要配置收集指標以及指標的權重:
在Pipeline中指定收集分析的頻率以及須要指定的源,同一時候能夠配置scoring從而覆蓋模板中的配置。
每次分析的執行記錄:
結果展演示樣例如以下,因為我們設定的目標是75,所以pipeline的結果判定為失敗。
我們是騰訊雲的客戶,採用騰訊雲容器服務主要看重以下幾個方面:
Kubernetes在自搭建的叢集中。要實現Overlay網路,在騰訊雲的環境裡。它本身就是軟體定義網路VPC,所以它在網路上的實現能夠做到在容器環境裡和原生的VM網路一樣的快,沒有不論什麼的效能犧牲。
應用型負載均衡器和Kubernetes裡的Ingress相關聯,對於須要外部訪問的服務能夠高速的建立。
騰訊雲的雲儲存能夠被Kubernetes管理,便於持久化的操作。
騰訊雲的部署以及告警也對外提供了服務與介面,能夠更好的檢視與監控相關的Node與Pod的情況。
騰訊雲日誌服務非常好的與容器進行融合,能夠方便的收集與檢索日誌。
下圖是我們在線上以及灰度環境的公佈示意圖。
為了容災我們使用了北京二區與北京三區兩個叢集。若是須要灰度驗證時。則將線上北京三區的權重改動為0,這樣通過灰度負載均衡器就可以到達新版本號應用。日常使用中二區與三區均同一時候提供掛服務。
Q:為什麼沒有和CI結合在一起?使用這個比較重的Spannaker有什麼優勢?A:能夠和CI進行結合。比方Webhook的方式,或者採用Jenkins排程的方式。優勢在於能夠和非常多雲平臺進行結合。並且他的Pipeline比較的完美,引數化程度非常高。
Q:眼下IaaS僅僅支援OpenStack和國外的公有云廠商,國內的雲服務商假設要支援的話,底層須要怎麼做呢(管理雲主機而不是容器)?自己實現的話easy嗎?怎麼入手?A:眼下我們主要使用Spinnaker用來管理容器這部分的內容,對於國內的雲廠商Spinnaker支援都不是非常的好。像LB,安全策略這些都不可在Spinnaker上面控制。若是須要研究能夠檢視Cloud driver這個元件的功能。
Q:Spinnaker能不能在Pipeline裡通過http API獲取一個deployment yaml進行deploy,這個yaml可能是動態生成的?A:部署服務有兩種方式:1. 在Spinnaker的UI中直接填入Manifest Source。事實上就是相應的deployment YAML。僅僅只是這裡能夠寫入Pipeline的引數。2. 能夠從GitHub中拉取相應的檔案,來部署。
Q:Spannaker的安全性方面怎麼控制?A:Spinnaker中Fiat是鑑權的元件。配置許可權管理。Auth、SAML、LDAP、GitHub teams、Azure Groups、 Google Groups,我們就採用LDAP,登陸後會在上面顯示相應的登陸人員。
Q: deploy和test以及rollback能夠跟helm chart整合嗎?A:我認為是能夠,非常笨的方法終於都是能夠藉助於Jenkins來實現,可是Spinnaker的回滾與部署技術非常強大,在頁面上點選就能夠進行高速的版本號回滾與部署。
Q: Spannaker之前的截圖看到也有對部分使用者開發的功能。用Spannaker之後還須要Istio嗎?A:這兩個有不同的功能。【對部分使用者開發的功能】這個是依靠建立不同的service以及Ingress來實現的,他的路由能力肯定沒有Istio強悍,並且也不具備熔斷等等的技術。我們線下這麼建立主要為了方便開發者進行高速的部署與除錯。