作者 | 郝樹偉(花名:流生) 阿裡雲進階研發工程師
本文整理自架構師成長系列 2 月17 日直播課程。
關注“阿裡巴巴雲原生”公衆号,回複 “217”,即可擷取對應直播回放連結及 PPT 下載下傳連結。
導讀:DevOps 是一種軟體開發人員和 IT人員之間的合作過程,目标是高效地自動執行軟體傳遞和基礎架構更改流程。在雲原生時代,企業又如何借助 DevOps 實作産品快速、穩定、高效和安全地疊代,釋放業務價值呢?
什麼是雲原生
為了解決傳統應用更新緩慢、架構臃腫、不能快速疊代、故障不能快速定位、問題無法快速解決等問題,雲原生這一概念橫空出世。
Pivotal 是雲原生應用的提出者,并推出了 Pivotal Cloud Foundry 雲原生應用平台和 Spring 開源 Java 開發架構,成為雲原生應用架構中先驅者和探路者。

早在 2015 年 Pivotal 公司的 Matt Stine 就寫了一本叫做遷移到雲原生應用架構的小冊子,其中探讨了雲原生應用架構的幾個主要特征:
- 符合 12 因素應用
- 面向微服務架構
- 自服務靈活架構
- 基于 API 的協作
- 抗脆弱性
後來 Pivotal 對雲原生的定義做過幾次更新, 最新的 Pivotal 官網上對雲原生應用的最新介紹是關注以下四點:
- 內建 DevOps
- 持續傳遞
- 微服務
- 容器化
- DevOps 是軟體開發人員和 IT 營運之間的合作,目标是自動執行軟體傳遞和基礎架構更改流程。它創造了一種文化和環境,可在其中快速、頻繁且更可靠地建構、測試和釋出軟體;
- 持續傳遞使得單個應用更改在準備就緒後即可釋出,而不必等待與其它更改捆綁釋出或等待維護視窗期等事件。持續傳遞讓釋出行為變得平淡可靠,是以企業可以以更低的風險頻繁傳遞,并更快地獲得最終使用者的回報,直到部署成為業務流程和企業競争力必不可少的組成部分;
- 微服務是将應用作為小型服務集合進行開發的架構方法,其中每個服務都可實施業務功能,在自己的流程中運作并通過 HTTP API 進行通信。每個微服務都可以獨立于應用中的其他服務進行部署、更新、擴充和重新啟動,通常作為自動化系統的一部分運作,可以在不影響最終客戶的情況下頻繁更新正在使用中的應用;
- 與标準虛拟機相比,容器能同時提供效率和速度。單個作業系統執行個體使用作業系統 級的虛拟化,在一個或多個隔離容器之間進行動态劃分,每個容器都具有唯一的可寫檔案系統和資源配額。建立和破壞容器的開銷較低,再加上單個虛拟機中的高包裝密度,使容器成為部署各個微服務的完美計算工具。
Google 主導成立了雲原生計算基金會(CNCF),對雲原生的定義為:
“雲原生(Cloud Native)技技術幫助企業和機構在公有雲、私有雲和混合雲等新型動态環境中,建構和運作可彈性擴充的應用。雲原生的代表技術包括容器、 服務網格、微服務、不可變基礎設施和聲明式 API;這些技術能夠建構容錯性好、易于管理和便于觀察的松耦合系統。結合可靠的自動化手段,雲原生技術可以使開發者輕松地對系統進行頻 繁并可預測的重大變更 。”
目前雲原生背後最大的推手就是 CNCF,關鍵技術包括容器、微服務、服務網格、devops,聲明式的 API 等等。
雲原生應用與傳統應用的對比,雲原生應用可以充分利用雲的優勢,靈活地在各個雲廠商分發應用,釋放企業生産力,聚焦到業務創新上,而不是花費更多的時間在适配和擴充不同的基礎設施平台上。
雲原生時代的 DevOps 新挑戰
首先我們要清楚地知道, 站在企業的角度來看,在這樣一個快捷商業的時代,企業最需要什麼?
- 唯快不破。這裡的快可以解讀出來兩層含義,一是業務應用快速上線,有利于搶占市場先機,第二層意思就是在你的業務有爆炸式增長的時候,你如何在計算資源上給以充分的保證,這個時候其實追加巨額的 IT 投資購買軟硬體也未必能跟得上業務的快速發展。這個其實就是企業研發效能的問題;
- 穩中求變。業務或者應用的穩定性永遠都是第一位的,如何既保證業務的“穩态”又要滿足快捷商業的“敏态”需求,比如新業務的上線、應用的變更等。這個是企業 IT 架構的問題;
- 節省資源,如何節省計算資源,根據業務是否高峰自動擴容縮容,這個是雲平台建設的問題;
- 開拓創新,開發運維一體化、微服務架構。
DevOps 最初的出現打破了開發人員和運維人員之間曆來存在的壁壘和溝鴻,加強了開發、營運和品質保證人員之間的溝通、協作與整合。在後 DevOps 時代,我們可以借助容器技術更快地對應用進行疊代上線。
下面是應用釋出的一般過程,開發者 push 代碼,觸發建構,建構過程是拉取源碼,應用打包,容器鏡像推送,部署。
這個模型其實已經有很多地方充分利用了雲原生的優勢,比如容器技術、Kubernetes、動态配置設定 slave pod 等。但還有一些挑戰。
- 如何應用在環境棧之間的安全推進釋出
- 如何管理應用釋出的權限和安全審批
- 如何提高應用的平均部署時間和平均恢複時間
- 如何迅速對線上應用進行故障定位、複現和復原
雲原生時代下的 DevOps 之道
首先我們要充分利用雲原生技術的優勢,雲原生可以改進應用開發的效率,改變企業的組織結構,甚至會在文化層面上直接影響一個公司的決策。在容器領域内,Kubernetes 已經成為了容器編排和管理的社群标準。它通過把應用服務抽象成多種資源類型,比如 Deployment、Service 等,提供了一個雲原生應用通用的可移植模型。
在這樣的背景下,我們如何在雲原生的環境下實踐更高效的 DevOps 來達到更有生産力的表現就成為了一個新的課題和訴求。
下面是一個企業應用平台的建設目标:
在此 PaaS 平台的基礎上,我們設計了 GitOps 安全釋出模型來解決前面我們提到的一些挑戰。
在設計 GitOps 釋出模型的時候是有以下這些核心訴求的:
- 版本管理。我們希望每一個釋出的應用的版本号都能跟 git commit id 關聯,這樣的好處就是每一個變更都有曆史記錄查詢、可以更快進行故障定位和修複;
- 基線管理。便于問題複現和快速復原;
- 安全釋出。包括釋出權限管理以及安全審批的内容;
- 快速回報。提高研發效能。
GitOps 釋出模型有以下特性:
- Git 倉庫是任何 CICD 過程的唯一輸入源
- 聲明式的應用編排、建構部署模型
- 應用在環境棧之間的無差别、自動化推進
- PR/MR 觸發的拉取式流水線過程
- 快速回報機制
下面是使用 GitOps 管理應用釋出到不同 Kubernetes 叢集的架構圖。
首先是應用源碼與建構源碼分離,我們可以看到橙色框起來的這兩個源碼項目,一個是我們的應用源碼項目 application-java-demo, 左側的這個源碼項目是用來存放建構源碼的,比如 preview pipeline 的 Jenkinsfile, staging pipeline 的 Jenkinsfile,production pipeline 的 Jenkinsfile, 除了 Jenkinsfile 之外,可能還有一些關于動态建立測試環境、連接配接預發環境或者生産環境的敏感資訊,這些敏感資訊也可以存放在資料庫裡,然後這裡儲存資料庫的連接配接資訊。
這個普通應用 application-java-demo 在 Git 倉庫裡是有不同的分支的,每個分支跟 Kubernetes 叢集環境都有一定的對應關系,比如我們這裡的設定,master 分支對應的是生産環境,latest 分支對應的是預發環境,其他開發分支對應的是測試環境,測試環境的動态建立和銷毀、應用再測試環境的部署釋出是開發測試人員自助的服務,但應用想要部署到預發環境和生産環境中的話是需要經過管理者安全審批的。
普通開發者的權限隻有建立新代碼分支和建立合并請求的權限,除此之外,剩下其他的部分都是管理者才有權限做的,綠色區域是 Jenkins 的流水線任務,當然你也可以是使用其他 cicd 引擎來做這個流水線任務的建構。普通開發者沒有 Jenkins 環境的建立 Job 和建構 Job 的權限,也沒有更改配置的權限,他有的隻是建構 Job 的日志檢視權限。
最後是一個時序圖,示範一個應用從開發測試到業務上線疊代的一個完整流程:
- 開發者送出新的功能分支 feature;
- 開發者建立請求合并代碼到 latest 分支的 Merge Request;
- 開發者建立 Merge Request 的動作自動觸發名為 preview-pipeline 的 Jenkins 流水線任務的建構;
- preview-pipeline 流水線任務從 Git 伺服器拉取 preview-pipeline 源碼項目,并按照項目中 Jenkinsfile 檔案中的聲明式腳本運作源碼編譯、測試、容器鏡像建構和推送、應用部署到 Preview 的容器叢集、釘釘通知的流程;
- 管理者在 Git 伺服器的 Merge Request 頁面檢視應用的預覽連接配接并驗證應用是否可以合并到 latest 分支,如果通過驗證則接受 Merge Request 的合并,觸發步驟 6, 如果不通過則通知開發者進行代碼更新和送出,退回步驟 1;
- 管理者接受 Merge Request 合并的動作會自動觸發 Jenkins 流水線任務 staging-pipeline 的建構;
- staging-pipeline 流水線任務從 Git 伺服器拉取 staging-pipeline 源碼項目,并按照項目中 Jenkinsfile 檔案中的聲明式腳本運作源碼編譯、測試、容器鏡像建構和推送、應用部署到 Staging 的容器叢集、釘釘通知的流程;
- Staging 環境中的應用服務在通過測試和驗證後,管理者可以合并 latest 分支到 master 分支;
- 管理者合并 latest 分支到 master 分支後,會自動觸發 Jenkins 流水線任務 production-pipeline 的建構;
- production-pipeline 流水線任務從 Git 伺服器拉取 production-pipeline 源碼項目,并按照項目中 Jenkinsfile 檔案中的聲明式腳本運作源碼編譯、測試、容器鏡像建構和推送、應用部署到 Production 的容器叢集、釘釘通知的流程。
GitOps 是一套方法論,是以其實是有多種實踐的方式的,會有多種多樣的好用的工具,比如使用 draft 可以幫助完成應用編排模闆的自動化生成,skaffold 用來簡化應用建構部署流程,kaniko 可以實作不依賴 docker daemon 的鏡像建構和推送,helm 用作應用的包管理工具,還有其他 cicd 引擎像 jenkins,tekton,argo 以及為雲原生而生的 jenkinsx 等等。
後面,我們會單獨實戰示範 GitOps 安全釋出模型的工作過程。
參考文獻:
https://pivotal.io/cn/cloud-native“ 阿裡巴巴雲原生 關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術圈。”