DevOps 工程師成長日記系列五:部署

圖片

原文地址:https://medium.com/@devfire/how-to-become-a-devops-engineer-in-six-months-or-less-part-5-deploy-83e790545c23
原文作者:Igor Kantor
翻譯君:CODING 戴維奧普斯

讓我們簡要回顧下我們的 DevOps 之旅:
在第一篇,我們介紹了 DevOps 文化以及相關的基礎技能;
在第二篇,我們討論瞭如何爲將來的代碼部署奠定基礎;
在第三篇,我們討論瞭如何有組織地管理代碼;
在第四篇,我們討論如何簡單地打包代碼。
以下是我們貫穿前後的路線圖:

圖片

如果在上圖每列的技術棧上花費一個月左右的話,那麼我們現在處於第 4 個月。基於前文的學習,我們已經知道了如何配置將要運行代碼的服務器基礎架構、如何正確地對代碼進行版本管理、如何將代碼打包以備部署。今天我們要討論如何部署代碼。

部署代碼

注意到了嗎?我沒有說“如何輕鬆地部署代碼”,因爲代碼從開發環境到正確部署仍然是一個充滿了錯誤和失敗的痛苦過程。

原因很多,但在我看來,這主要歸結爲差異。具體而言,創建代碼的環境與實際代碼運行的環境之間存在差異。我認爲減少這些差異意味着你不僅可以在整體代碼部署中實現最大的改進,還可以在代碼部署後的運行時達到一定的優化。那麼,我們如何減少或消除生產和非生產環境之間的差異呢?

在我的機器上明明是可以跑的

如果你的開發基礎設施是這樣的:


用“溫柔的愛和關懷”手工組裝而成的開發基礎設施

但你的生產環境基礎設施看起來像這樣:

圖片

那你就會遇到麻煩。

如果你使用基礎設施即爲代碼的方式而不是手動配置,那麼差異這事兒你已經搞定得七七八八了。如果不是,請不要絕望 —— 你並不孤單。花一個下午,找出你所碰到的所有差異(培訓、文化、人員、流程等),並逐一消除它們。

最重要的是,如果你仍在手動配置,那你可能很難去管理現代技術棧。因此你需要做的第一件事是確保涉及產品的所有內容都是由部署服務器構建的版本化軟件包。假設上述事情你已經完成,我會告訴你部署代碼的最佳方法是不部署代碼

現代化的代碼部署

將代碼部署到生產環境機器是一件非常 90 年代的事情。

圖片
現有技術的“代碼部署裝置”

將代碼部署到一組固定生產環境機器的最大問題是:你的生產環境服務器(代碼運行的地方)與你的開發環境服務器(編寫代碼的地方)不同。這就難怪在部署後會立即出現大量問題。

因此,你需要盡一切可能確保構建產物(而不是一小段代碼)一直處在運行環境當中。換句話說,將代碼一次性部署到開發環境,克隆運行代碼的整個機器環境,然後將其複製到需要的任何位置。這被稱爲“不可變部署”,是一個非常強大的模式,可以避免你數小時部署後的頭痛。當然,如果你運行容器,同樣的想法也是適用的:在任何地方部署相同的容器即可。

“但是我的生產環境和開發環境就是不同的!”你可能會說。數據庫用戶名密碼,連接字符串,S3 存儲桶位置等等,這些都是不同的。解決這個問題的方法是使用 12 因子應用配置原則。所有配置都需要外部化並作爲環境變量傳遞到服務器。

例如,如果在 AWS,可以使用 SSM 作爲外部參數存儲,它很好地集成了 CloudFormation。直接通過 aws ssm cli 命令行工具設置環境變量也非常容易。當然,其它雲廠商也提供了類似的機制。

當出現問題時,你需要壓制“修理”生產環境機器的衝動。這些機器是不可變的,這意味着你所做的任何修復都必須來自開發環境。事實上,你的終極目標應該是根本不允許任何在生產環境服務器上的接入。沒有 ssh、沒有 scp、沒有人有任何訪問權限,不是你,更不是覬覦中的黑客。

但如果我需要日誌來解決問題呢?所以日誌也應該外部化。理想情況下可以通過ElasticSearch / Logstash / Kibana(ELK)技術棧或商業軟件(如 SumoLogic 或Datadog)將日誌轉儲到其它地方。

無論你做什麼,你的產品都是“黃牛” —— 它們會在出現最輕微的不健康信號時就被替換。它們不是“寵物”,需要耗費數小時進行故障排除來恢復健康。我知道這個比喻被太多人使用了,並且我聽到那些真正養牛的人說過實際上他們的工作原理和我們剛所討論的不同,但重點事務確實如此。不要“修復”你的生產環境機器,而是修復你的開發環境並重新部署。

代碼部署機制

所以你知道要做些啥了,但怎麼做呢?

“不幸”的是,這就是 Jenkins 的用武之地,Jenkins 是最受歡迎的開源部署自動化服務器之一。我說“不幸”是因爲 Jenkins(及其前任 Hudson)已經存在了近十年,並且在漫長的使用過程當中我們發現了:它的設置很複雜,維護起來更復雜。它帶有數以百萬計的可疑質量插件。這些插件往往會在最不合適的時候崩潰,把所有事情搞砸。實際上,真正具有彈性的分佈式 Jenkins 設置很少見,通常只有最大的研發組織裏才能看到。

那爲什麼我還建議你從 Jenkins 開始呢?因爲儘管存在各種缺陷,它仍然非常受歡迎,並且在我們的行業中被大量使用。瞭解 Jenkins,特別是 Jenkinsfile 的結構,對就業前景會是一個巨大並且不容忽視的好處。當你學習 Jenkins 時,請確保你遵循較新的 Pipeline BlueOcean 技術路徑,而不是更舊的“Jenkins jobs”。

參考閱讀:
Jenkinsfile:https://jenkins.io/doc/book/pipeline/jenkinsfile/
Pipeline BlueOcean:https://jenkins.io/doc/book/blueocean/

當你希望 CI/CD 流水線被直接包含在代碼倉庫當中後,持續集成工具會變得非常重要,這樣的話流水線本身就是一段版本化的代碼。

一切都是代碼

你的應用程序如何被部署、監控、配置等等——說到底最終都化作爲存儲在代碼倉庫裏被正確版本化的代碼片段。

我們的目標是爲核心開發人員(編寫功能代碼的軟件工程師)創建一個真正無摩擦的環境。例如,我應該能夠編寫我自己的微服務、添加我認爲必要的測試、添加監控即代碼的配置、在一些“env.yaml” 文件中指定我的參數、將它們全部存儲在一個代碼倉庫中;通過 CI/CD 流水線自動觸發構建、測試、部署(金絲雀發佈或藍綠髮布),並在完成後給我發送電子郵件。事實上,這是 DevOps 工程師核心使命的本質。

Jenkins 的替代品

就像我之前說過的那樣,Jenkins 已經被廣大開發者使用很長一段時間了。現在還有其它的工具,在我看來更好,即使沒有 Jenkins 那麼爲人所知。

  • 一個是 AWS 自己的 CodeDeploy 服務。它有侷限性,但 CodeDeploy 背後的開發人員在過去一年做了很大的改進,如果你在用 AWS,建議你試一試。
  • 另一個是 GitLab CI。如果你的研發組織運行在 GitLab 上,你可以考慮使用,因爲它與 GitLab 的其它部分良好地集成在一起。
  • 去年十月 GitHub 宣佈了 Actions(目前仍處在公測中),用於 GitHub 用戶的自動化工作流場景。

我認爲這裏的工具並不是最重要的。重要的是要記住包括代碼部署流水線在內的所有內容都是版本化的軟件部件,它首先得來自於開發環境,而不是生產環境。

如果你從 Jenkins 開始學習持續集成,請嘗試將其設置爲容器模式。這並不是一件非常困難的事情,反而會是一個很不錯的學習機會,你可以找到彈性的、容器化的 Jenkins 機器節點來部署容器化的 Jenkins。

你也完全可以從簡單的、沒有任何容器編排的方式開始,這是下一篇文章的主題,敬請關注。

寫在最後

原文作者給我們介紹了一個非常重要的實踐:在部署環境遇到的問題要去調整和修改開發環境,讓生產環境與開發環境保持一致,修改生產環境治標不治本。同時也給我們介紹了一些他喜歡的國外持續集成工具。針對國內的工具,譯者推薦你還可以考慮使用 CODING 持續集成,它是 CODING 提供的一站式 DevOps 解決方案中重要的一環。其構建腳本在語法上全面兼容 Jenkins,又免除開發者部署和維護持續集成環境的繁雜事務。

同時 CODING 支持包括 Docker 鏡像、Jar、APK 等軟件包的構建,預置了主流開發語言的構建環境:Java、PHP、Go、Python 等等;開啓緩存加速功能可以平均提高 300% 的構建速度。對於包括 Maven,NPM 在內的主流鏡像源有專用網絡優化,保證拉取速度; 支持單項目並行構建,以滿足重度持續集成用戶的需求。對不太喜歡腳本的同學還提供了完善的圖形化編排能力,以降低使用門檻。

圖片

CODING 還對構建產物提供了統一的製品庫管理,目前製品庫已支持 Docker 鏡像、NPM、Helm 等常見包類型的製品管理。後續 CODING 會逐步支持多種主流的軟件包類型來進一步完善 DevOps 工作流,敬請期待。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章