DevOps 實戰:Jenkins Docker

語言: CN / TW / HK

隨時 Docker 的普及,雲原生時代已經到來,開發工程師對應用環境的掌控力進一步加強,運維成本進一步降低。DevOps 採用 Docker 更是如虎添翼,持續整合更快更靈活,部署更簡單。本課程主要講解 Docker 伺服器架構和技術要點,以及實戰使用 Jenkins 構建 Docker。

本次騰訊雲大學大咖分享課程邀請 CODING DevOps 架構師 楊周 分享關於“DevOps 實戰:Jenkins Docker”課程的內容。

本次分享內容:

1、Docker 伺服器架構 2、Docker 下載和構建加速 3、專案容器化的技術要點 4、DevOps 實戰:Jenkins 構建 Docker

Docker 伺服器架構

上節課我們講了伺服器架構從買伺服器演進到了租伺服器,再到雲端計算租一切,比如 雲端儲存、雲資料庫、企業郵箱,分別屬於 IaaS、PaaS、SaaS。

IaaS 是“基礎設施即服務”,採用伺服器叢集虛擬化技術,面向運維人員,不用關心伺服器怎麼加記憶體、壞了怎麼辦,節約了硬體和網路維護成本;

PaaS 是“平臺即服務”,提供資料庫等軟體服務,面向開發者程式設計呼叫,不需要自己搭建了,節約了運維成本,而執行環境能否標準化取代自建,是個問題;

SaaS 是“軟體即服務”,提供企業郵箱、程式碼託管等軟體服務,面向辦公人士圖形化介面操作,不需要運維也不需要開發。

如果租了臺雲伺服器,在上面安裝了資料庫,這叫做 IaaS + 自建,缺點是:自己負責資料庫備份,升級非常困難,運維成本很高,當然比以前買伺服器有進步。

如果租了臺雲伺服器,再租了臺雲資料庫,然後搭建開源郵箱和程式碼庫,這叫做 IaaS + PaaS + 自建,缺點是:自己負責郵箱和程式碼庫的升級,運維成本中等,而且開源產品的圖形介面往往比較難用,並且無人跟進及時升級導致安全隱患大、服務不穩定,運維自己搭的郵箱夜裡出故障了,客戶發的郵件丟了,沒有人知道,而專門做企業郵箱的公司承諾 SLA,有專人值守。現在很少有公司自己搭郵箱了,是一大進步,但還是有不少公司自己搭程式碼庫,浪費了很多人力物力,結果還難用降低了研發效率。

做工程的最佳實踐是:不要重複造輪子,只要能買到就不要自己造自己搭,專注於產品業務。除非這個輪子是你的核心依賴,比如手機晶片,那屬於科研,而不是工程。所以首先需要明確本公司是業務驅動,還是科研驅動。關於工程師和科學家的區別,推薦閱讀矽谷創業之父寫的《黑客與畫家》

PaaS 提供的雲資料庫等標準化軟體服務,非常方便,而標準化執行環境卻沒有流行起來,為什麼?

2010 年,dotCloud 成立做 PaaS 執行環境,結果發展不好,把其中的 Docker 開源,卻很受歡迎,大家可以閱讀這段有趣的歷史《Docker 傳奇之 dotCloud》

PaaS 讓開發者無需關心作業系統,比如雲資料庫後面是什麼系統,開發者不用管,最多改個配置重啟一下,很方便。而開發者用各種語言寫的應用,都是定製化的,而不是標準化的,比如 Apache 配置不一樣,開啟的模組不一樣,或者用的是 Nginx,所以開發者需要的是把 專案、語言環境 和 Apache 一起打包部署,甚至還有編譯安裝的元件,那就需要把整個系統打包。所以統一的應用執行環境無法滿足,沒有流行起來。

而 Docker 是一種輕量級虛擬機器,解決了這個問題,非常方便。單機部署和執行 Docker 很簡單,而網際網路專案往往使用者量大,需要多臺伺服器,如何部署叢集並且自動伸縮,就需要叢集管理工具。

Google 推出了 K8s,Docker 官方推出了 Swarm,經過兩年的競爭,從 Google 搜尋的關鍵詞熱度圖可以看出 K8s 已經勝出,目前國內的雲端計算大廠也紛紛支援 K8s。

具體的技術對比,大家可以閱讀 《揭祕騰訊雲的PaaS技術選型策略》

Docker 屬於作業系統層虛擬化,稱為“容器”,它在 Linux 系統裡建立一個虛擬層,共用一個 Linux 核心,既做到了隔離,速度又快於傳統的硬體抽象層虛擬機器(比如 VirtualBox,可以在 Windows 系統裡建立 Linux 虛擬機器)。

以前不管多麼小的專案都要申請一臺新伺服器,因為多個專案部署在一起會衝突,比如語言版本不同、共用一個 Apache 導致上線重啟時中斷別的專案。

而 Docker 隔離了各個專案,一臺伺服器可以跑很多個 Docker,大幅度降低伺服器成本,初期只需要買 1 臺伺服器,根據效能需求再增加。

第一步:安裝 Docker,按照官方文件,結果內地非常慢,甚至安裝失敗。經過分析安裝指令碼的原始碼,發現官方支援加速,但文件裡面沒有寫,很多人都不知道。

可以看到 Docker 用的是 Cloudflare 國際 CDN,這家 CDN 是有中國節點的,但在中國辦網站需要備案,對於尚未在中國開展業務的公司,尤其是各種英語的技術服務,都不會來備案,所以內地開發者訪問很慢,甚至超時。

這時候就需要有人提供國內映象加速,這是個吃力不討好的事情,目前只有 163 一家提供免註冊的 Docker 公網加速,非常感謝。從圖中可以看到,拉取成功,速度挺快。

專案容器化需要開發者寫一個 Dockerfile,基於各個語言的官方映象再安裝需要的庫和包,比如我們通過加速下載了 PHP 官方的 php:7.4-apache 映象,需要 apt 安裝一些庫,結果 docker build 的時候卡住了,這時候有個很好的除錯方法:docker run 登入進去,就是我們熟悉的 Linux 系統了,執行 Dockerfile 裡面的那些步驟,看看哪一步慢。看圖片右下角,可以發現 apt update 很慢,才 10 KB/s。這時候就要想辦法加速 apt 了。

Docker 下載和構建加速

apt 加速有大廠提供了,composer install 也有了,但沒人提供 get composer,所以我做了個開源專案提供加速服務,大家課後可掃碼瞭解。

專案容器化的技術要點

專案容器化的技術要點有4個:

  • 國內加速,掌握各種軟體源的國內加速。
  • HTTPS,SSL證書不要放在Docker裡,應放在Docker裡,應放在雲端計算提供的負載均衡裡。Docker只提供HTTP服務即可。
  • 雲端儲存,檔案不要上傳到Docker裡,重啟就丟了,應上傳到雲端儲存。
  • Log採集,Log不要記錄在Docker裡的檔案中,而應該輸出到STDOUT和STDERR,再使用Log採集工具。

有一個 Laravel 專案在本地執行,Apache 也配好了,如何對它進行 Docker 化?

第一步:搜尋框架官方的 Docker 映象,如果沒有,再尋找語言官方映象。比如 Laravel 沒有官方映象,那就用 PHP 映象,安裝一些元件即可。

把本地專案的依賴包刪除,然後掛載到 Docker 裡,進行依賴安裝,逐個解決報錯,比如圖中 composer install 報錯缺少 zip,那就需要通過 apt 安裝。

apt 安裝需要使用國內加速,請看最上面一行程式碼。apt 安裝完畢,再進行專案包安裝,最後把所有的依賴都裝好,專案終於跑了起來。

Docker 始終在前臺執行,映象無狀態,重啟就會丟失所有檔案,所以 log 應該通過標準輸出,而不應該儲存為檔案。可以看到 Apache 已經把 log 檔案指向了標準輸出。

專案中會記錄業務 log,也需要改造為標準輸出。左邊是專案的 log 配置,右邊是業務程式碼打 log,下面是最終執行效果。

最後中國版的 Dockerfile 是這樣的,黃色的部分用來國內加速,其餘部分是國際通用的。

DevOps 實戰:Jenkins 構建 Docker

以前持續整合依賴廠商提供的語言環境,不支援某些語言或者版本過時經常發生,而到了 Docker 時代,持續整合環境根據開發者的 Dockerfile 進行搭建,可以支援任何環境,開發者的掌控力進一步加強,廠商也無需投入資金去支援各種語言了,達到了雙贏。

部署 Docker 映象的成本也很低,尤其是 K8s 彈性叢集,不需要購買伺服器,根據效能自動伸縮,很多網站夜間訪問量很低,可降低到一兩臺,比包年包月的伺服器便宜。

可以看出需要3個服務:持續整合、私有 Docker 倉庫、K8s 叢集管理。如果自己搭建,維護成本很高,不符合雲端計算的理念,採用 PaaS 最合適。

第一步,尋找 Jenkins 雲服務和製品倉庫,比如 coding.net

這個專案的程式碼很簡單,就是一個 Laravel demo,大家可以提交自己熟悉的語言 demo,然後創建制品庫。

建立了 Docker 製品庫,就會獲得一個倉庫連結,用來推送和拉取映象。

然後配置一下 Jenkins,建議除錯階段使用線上靜態 Jenkinsfile,除錯通過以後,再儲存到程式碼庫裡。

CODING Jenkins 圖形化編輯器

Jenkins 構建 Docker 很簡單,和本地一樣,只是要掌握一些 Jenkins 語法。需要注意的是:要判斷分支,比如只構建 master。

構建成功後,可以在製品庫中看到映象。下一步就是把它部署到 K8s 叢集裡。

找一家雲端計算廠商,如騰訊雲,建立 K8s 叢集,會獲得一個 KubeConfig,放在本地即可使用 kubectl 命令遠端操作。

不過 K8s 來自 Google,官網在國外,內地無法下載,所以需要國內加速。對 kubectl 命令不熟悉的話,也可以使用雲端計算網頁後臺建立網站,比如圖中用 apache 官方映象建立了一個網站。

把 K8s 金鑰錄入 CODING,授權給持續整合。

看圖中高亮的程式碼,先在 K8s 中建立一個金鑰用來儲存私有 Docker 倉庫的地址、使用者名稱、密碼,然後部署時指定私有映象和金鑰即可。

Jenkins 執行成功,在本地使用 kubectl get pods 命令可以看到正在建立一個新容器,老的容器繼續執行。

還可以通過 kubectl edit deploy web 命令檢視目前的配置。

從第一張圖可以看到 K8s 配置裡有了私有映象和倉庫金鑰。

第二張圖可以看到新容器建立成功以後,老的容器才會被刪除,不像傳統上線那樣導致服務中斷。

第三張圖是部署成功的專案首頁。

 

課程原始碼:https://codes-farm.coding.net/p/laravel-demo/d/laravel-demo/git