歡迎光臨
每天分享高質量文章

透過 Kubernetes 和容器實現 DevOps

近兩年,隨著容器、Kubernetes 等技術的興起,DevOps 這個概念被廣泛提及並被大量使用。 本文將會從以下幾個方面著手,結合實驗展現的方式,讓讀者真正理解 DevOps 的含義。
  • DevOps 產生的背景

  • DevOps 與容器、Kubernetes 之間的關係

  • DevOps 的技術實現方式

DevOps 是什麼

DevOps 中的 Dev 指的 Development,Ops 指的是的 Operations,用一句話來說 DevOps 就是打通開發運維的壁壘,實現開發運維一體化。
從瀑布式開發到敏捷開發
談到 DevOps 的發展史,我們需要先談一下敏捷開發。
首先,敏捷開發是面向軟體的,而軟體依賴於計算硬體。我們知道,世界上第一臺計算機是在 1946 年出現的。因此,軟體開發相對於人類歷史而言,時間並不長。相對於軟體開發方法論的掌握,人們更擅長於工程學,如蓋樓、造橋等。為了推動軟體開發,1968 年,人們將工程學的方法應用到軟體領域,由此產生了軟體工程。
軟體工程的方式有其優點,但帶來了不少問題。最關鍵一點是:軟體不同於工程。透過工程學建造的大橋、高樓在竣工後,人們通常不會對大橋高樓的主體有大量使用需求的變更;但軟體卻不同。對於面向終端使用者的軟體,人們對於軟體功能的需求是會不斷變化的。在瀑布式開發的樣式下,當客戶對應用有變化的需求時,軟體廠商得重新開發軟體。這將會使企業的競爭力大幅下降。
傳統的軟體開發流程是:產品經理收集一線業務部門和客戶的需求,這些需求可能是新功能需求,也可能是對產品現有功能做變更的需求。然後進行評估、分析,將這些需求制定為產品的路線圖,並且分配相應的資源進行相關工作。接下來,產品經理將需求輸出給開發部門,開發工程師寫程式碼。寫好以後,就由不同的部門的人員進行後續的程式碼構建、質量檢驗、整合測試、使用者驗收測試,最後給生產部門。這樣帶來的問題是,開發週期比較長,並且如果有任何變更,都要重新走一遍開發流程,在商場如戰場的今天,軟體一個版本推遲釋出,可能到釋出時這個版本在市場上就已經過時了;而競爭對手很可能由於在新軟體釋出上快了一步,而迅速搶佔了客戶和市場。
正是由於商業環境的壓力,軟體廠商需要改進開發方式。
2001 年初,在美國滑雪勝地 snowbird,17 位專家聚集在一起,概括了一些可以讓軟體開發團隊更具有快速工作、相應變化的能力的價值觀原則。他們稱自己為”敏捷聯盟”。
敏捷開發的主要價值觀如下:
表 1. 敏捷開發的核心價值觀
有了敏捷聯盟,有了敏捷開發價值觀,必然會產生開發的流派。主要的敏捷開發流派有:極限程式設計(XP)、Scrum、水晶方法等。
至此,敏捷開發有理念、有方法、有實踐。隨著雲端計算概念的興起,雲端計算的不斷落地,敏捷開發不僅實現了工具化,也得到了升華。
從敏捷開發到 DevOps
談到了敏捷開發,那麼敏捷開發和 DevOps 有什麼關係呢?
敏捷開發是開發域裡的概念,在敏捷開發基礎之上,有如下階段:
敏捷開發->持續整合->持續交付->持續部署->DevOps
從敏捷開發到 DevOps,前一個階段都是後一個階段的基礎;隨著階段的推進,每個階段概念改寫的流程越來越多;最終 DevOps 涵蓋了整個開發和運維階段。正式由於每個階段涉及的範圍不同,因此所以每個概念所提供的工具也是不一樣的。具體內容我們參照下圖:
圖 1. 從敏捷開發到 DevOps 的進階
持續整合(Continuous Integration)指的是:程式碼整合到主幹之前,必須全部透過自動化測試;只要有一個測試用例失敗,就不能整合。持續整合的要實現的標的是:在保持高質量的基礎上,讓產品可以快速迭代。
持續交付(Continuous Delivery)指的是:開發人員頻繁地將軟體的新版本,交付給質量團隊或者使用者,以供評審。如果評審透過,程式碼就被髮布。如果評審不透過,那麼需要開發進行變更後再提交。
持續部署(Continuous Deployment)指的是:程式碼透過評審併發布後,自動部署,以交付使用。
DevOps 是一組完整的實踐,可以自動化軟體開發和 IT 團隊之間的流程,以便他們可以更快、更可靠地構建、測試和釋出軟體。
圖 2. DevOps 示意圖
DevOps 的技術實現

DevOps 的技術實現,需要三個方面:標準交付物、容器排程平臺、DevOps 工具鏈。接下來,我們詳細看一下這個三個方面的內容。
DevOps 的技術實現 1:標準交付物
DevOps 的目的在於讓開發和運維一體化、讓開發和運維相互之間的溝通更加順暢、迅捷,從而使企業更能適應市場的變化。
當然,真正實現開發運維一體化,並非只是讓開發和運維的人坐在一起那麼簡單。從技術角度,DevOps 首先需要有一個包含了“作業系統+Runtime+應用”的標準交付物。除此之外,還需要透過整個 DevOps 流程來打通。
在 IT 早期,廠商硬體和系統平臺的差異化過大,在不同硬體和系統平臺進行應用的無縫遷移幾乎是不可想象的。隨著 X86 伺服器以及 vSphere 等虛擬化技術的普及,作業系統(包括作業系統上的應用)可以在不同 X86 伺服器廠商的硬體平臺上線上無縫遷移。硬體差異化不斷縮小甚至消失,軟體的重要性不斷提升,IT 界真正進入軟體定義一切的時代。在這個背景下,業務提出了更高的要求,如何將應用在不同作業系統之間實現無縫遷移,將開發和生產統一,做到“構建一次,到處執行”。
容器技術的概念最初出現在 2000 年,當時稱為 FreeBSD jail,這種技術可將 FreeBSD 系統分割槽為多個子系統。
但直到 Docker 的出現(2008 年),容器才真正具備了較好的可操作性和實用性。因為 Docker 提供了容器的映象構建、打包等技術,使容器具備了一次打包,到處執行的能力。
對於客戶而言,Docker 只能在一個 Linux 上執行,是“單機版”,很難符合企業對高可用的需求。此外,docker 也缺乏和持久儲存、虛擬網路相關的功能。
DevOps 的技術實現 2:容器排程平臺
2014 年 Kubernetes 的出現,奠定了今天容器排程平臺的事實標準的基礎。
因為透過 Kubernetes,我們不僅實現了容器在多個計算節點上的統一排程,還可以將容器對接持久儲存、對接虛擬網路等。換句話說,Kubernetes 使容器具備企業級的功能。
圖 3. Kubernetes 架構
DevOps 的技術實現 3:DevOps 工具鏈
在有了容器和 Kubernetes 以後,我們還需要相關的 DevOps 工具鏈。
目前在 IT 界,DevOps 相關的工具很多,其中大多數是開源的工具,如下圖。
圖 4. DevOps 工具鏈
在後面的文章中,我們會選擇幾種常用的 DevOps 工具,然後進行試驗展現。
總結:DevOps 與容器和 Kubernetes 的關係
PaaS、DevOps 的概念,在容器和 Kubernetes 普及之前就存在了。廣義上的 PaaS、DevOps 的建設,會包含:人、流程、工具等多方面內容。IT 廠商提供的 PaaS、DevOps 以指工具層面的落地為主、以流程諮詢為輔。
在 Kubernetes 和容器普及之前,我們透過虛擬機器也可以實現 PaaS、CI/CD,只是相對速度較慢,因此普及性不高(想象一下透過 X86 虛擬化來實現中介軟體叢集彈性伸縮的效率)。而正是容器的出現,為 PaaS、DevOps 工具層面的落地提供非常好的承載平臺,使得這兩年容器雲風生水起。這就好比 4G(2014 年出現)和微信(2011 年出現)之間的關係:在手機網速 3G 時代,流量按照兆收費的時候,(即使有)大家對於微信語音聊天、微信影片也不會太感興趣。
所以說, Docker 使容器具備了較好的可操作性、可移植性,Kubernetes 使容器具備企業級使用的條件。而 IT 界眾多基於 Kubernetes 和 Docker 企業級的容器平臺,又成為了 DevOps 工具落地的新一代基礎架構。

 

DevOps 工作流展示

常用 DevOps 工具介紹
  • Kubernetes 叢集:包含 Docker 和 Kubernetes。

  • Gogs:透過 Go 編寫的原生代碼倉庫,功能與 GitHub 類似。

  • Jenkins/Jenkins Slave Pods:持續整合工具。

  • Nexus:工件管理器,能夠解決本地快取構建依賴項。

  • SonarQube:開原始碼分析工具,它可以分析常見程式設計錯誤的原始碼。

以上的 DevOps 工具,都可以以容器方式部署到 Kubernetes 叢集中。在實驗環境中,有一個兩個節點的 Kubernetes 叢集,用於進行實驗展現。
圖 5. Kubernetes 叢集
在 Kubernetes 叢集中建立三個 Namespace:cicd、dev、stage。其中 cicd Namespace 存放的是 DevOps 相關工具鏈。dev、stage 是模擬開發和生產兩個環境。
圖 6. Kubernetes 叢集的 Namespaces
接下來,我們看一下在 cicd Namespace 中部署的 DevOps 工具鏈:
圖 7. Kubernetes 叢集中部署的 DevOps 工具
在工具鏈部署成功以後,我們分別登入工具的 UI 介面進行檢視。
我們首先檢視程式碼倉庫 Gogs 中的原始碼:
圖 8. Gogs 中的原始碼
接下來,我們登入 Jenkins(後續的主要操作將會基於 Jenkins):
圖 9. Jenkins 介面
Nexus 用於存放構建成功、並經過 Code Review 的 war 包,我們檢視 Nexus 的介面:
圖 10. Nexus 介面
SonarQube 負責 Code review:
圖 11. SonarQube 介面
Jenkins Pipeline 工作流分析
整個 DevOps 的流程,透過 Jenkins 的 Pipeline 串接起來。在 Jenkins 中,我們可以透過編寫 Jenkins File,或者透過 Jenkins 瀏覽器頁面的操作來完成 Pipeline 的定製。兩者的實現效果是一樣的,本文以書寫 Jenkins File 方式展現。透過一個 Jenkins File,打通整個 DevOps 流程。
我們檢視 Jenkins File 的內容併進行解釋。
第一步,從 Gogs 拉取原始碼,然後呼叫 maven 進行程式碼編譯:
 
  1. pipeline {
  2.  agent {
  3.    label 'maven'
  4.  }
  5.  stages {
  6.    stage('Build App') {
  7.      steps {
  8.        git branch: 'eap-7', url: 'http://gogs:3000/gogs/openshift-tasks.git'
  9.        script {
  10.            def pom = readMavenPom file: 'pom.xml'
  11.            version = pom.version
  12.        }
  13.        sh "${mvnCmd} install -DskipTests=true"
  14.      }
  15.    }
  16.  }
  17. }
清單 1. Pipeline 第一階段
第二步,構建成功以後,呼叫 mvn 進行測試。
  1. stage('Test') {
  2.  steps {
  3.    sh "${mvnCmd} test"
  4.    step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
  5.  }
  6. }
清單 2. Pipeline 第二階段
第三步,呼叫 SonarQube 進行程式碼 review。
  1. stage('Code Analysis') {
  2.  steps {
  3.    script {
  4.      sh "${mvnCmd} sonar:sonar -Dsonar.host.url=http://sonarqube:9000 -DskipTests=true"
  5.    }
  6.  }
  7. }
清單 3. Pipeline 第三階段
第四步,將測試成功的程式碼存檔到 Nexus:
  1. stage('Archive App') {
  2.  steps {
  3.    sh "${mvnCmd} deploy -DskipTests=true -P nexus3"
  4.  }
  5. }
清單 4. Pipeline 第四階段
第五步,Pipeline 會將構建成功的 war 包,以二進位制的方式註入到 JBoss EAP 的 docker image 中。
  1. stage('Build Image') {
  2.    steps {
  3.      sh "rm -rf oc-build && mkdir -p oc-build/deployments"
  4.      sh "cp target/tasks.war oc-build/deployments/ROOT.war"
  5.    }
  6. }
清單 5. Pipeline 第五階段
接下來,Pileline 先將這個 docker image 部署到 dev 環境,然後引入審批工作流,批准後部署到生產。
  1. stage('Promote to STAGE?') {
  2.      steps {
  3.        timeout(time:15, unit:'MINUTES') {
  4.            input message: "Promote to STAGE?", ok: "Promote"
  5.        }
  6.      }
  7. }
清單 6. Pipeline 中的審批流
DevOps 工具鏈演示
首先,登入到 Jenkins 上,檢視已經建立好的 Pipeline。
圖 12. Jenkins 的 Pipeline
點選“開始構建”,觸發工作流(工作流也可以透過提交程式碼自動觸發):
圖 13. 觸發工作流
Pipeline 的第一個階段是 Build App。
圖 14. 工作流第一個階段
Build App 成功的 logs 如下,我們可以看到生成了 war 包:
  1. [INFO] Installing /tmp/workspace/cicd-monolith-f138/cicd-monolith-f138-tasks-pipeline/target/tasks.war to /home/jenkins/.m2/repository/org/jboss/quickstarts/eap/jboss-tasks-rs/7.0.0-SNAPSHOT/jboss-tasks-rs-7.0.0-SNAPSHOT.war
  2. [INFO] Installing /tmp/workspace/cicd-monolith-f138/cicd-monolith-f138-tasks-pipeline/pom.xml to /home/jenkins/.m2/repository/org/jboss/quickstarts/eap/jboss-tasks-rs/7.0.0-SNAPSHOT/jboss-tasks-rs-7.0.0-SNAPSHOT.pom
清單 7. 構建應用成功的日誌
Pipeline 繼續執行,在 Test 成功以後,開始進行 Code Analysis:
圖 15. 工作流階段 2-3
Test 階段執行成功的 log:
  1. -------------------------------------------------------
  2. T E S T S
  3. -------------------------------------------------------
  4. Running org.jboss.as.quickstarts.tasksrs.service.UserResourceTest
  5. Tests run: 1, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 1.798 sec - in org.jboss.as.quickstarts.tasksrs.service.UserResourceTest
  6. Running org.jboss.as.quickstarts.tasksrs.service.TaskResourceTest
  7. Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.604 sec - in org.jboss.as.quickstarts.tasksrs.service.TaskResourceTest
  8. Results :
  9. Tests run: 4, Failures: 0, Errors: 0, Skipped: 1
清單 8. 測試成功的日誌
Code Analysis 階段執行成功的日誌,我們看到日誌顯示程式碼分析成功,並建議透過瀏覽器訪問 SonarQube:
  1. [INFO] ANALYSIS SUCCESSFUL, you can browse "http://sonarqube:9000/dashboard/index/org.jboss.quickstarts.eap:jboss-tasks-rs">http://sonarqube:9000/dashboard/index/org.jboss.quickstarts.eap:jboss-tasks-rs
  2. [INFO] Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
  3. [INFO] More about the report processing at "http://sonarqube:9000/api/ce/task?id=AWc_R_EGIPI_jn5vc3mt">http://sonarqube:9000/api/ce/task?id=AWc_R_EGIPI_jn5vc3mt
  4. [INFO] Task total time: 18.918 s
清單 9. 程式碼分析成功的日誌
我們登入 SonarQube,檢視結果:
圖 16. SonarQube 執行結果
接下來,Pilepine 進入到 Create Image Builder 階段,其關鍵的步驟是將構建成功的 war 包以二進位制的方式註入到 docker image 中:
  1. [cicd-monolith-f138-tasks-pipeline] Running shell script
  2. + rm -rf oc-build
  3. + mkdir -p oc-build/deployments
  4. [Pipeline] sh
  5. [cicd-monolith-f138-tasks-pipeline] Running shell script
  6. + cp target/tasks.war oc-build/deployments/ROOT.war
清單 10. 構建映象的日誌
Create Image Builder 執行成功以後,會生成包含應用的 docker image。接下來是 Create Dev 和 Deploy Dev,即在 dev 環境部署包含應用的 docker image。當 Deploy Dev 成功以後,會引入工作流,提示是否批准將應用部署到 Stage,如下圖:
圖 17. 工作流審批流程
選擇 Promote,應用會部署到 Stage,Pipeline 流程走完。
圖 18. 工作流執行完畢
最後,透過瀏覽器訪問成功部署到 Dev/Stage Namespace 中的應用:
圖 19. 應用 UI 訪問
至此,您可以看到應用訪問結果,說明 DevOps 全流程已經打通。
總結

透過本文,相信讀者對 DevOps 的概念和工具鏈已經有了大致的瞭解。也對透過 Kubernetes 叢集和容器實現 DevOps 有了一定的理解。
原文連結:https://www.ibm.com/developerworks/cn/cloud/library/cl-lo-devops-via-kubernetes-and-containers/index.html
贊(0)

分享創造快樂