途徑 交流電 (基礎設施即程式碼)不僅包含儲存在儲存庫中的程式碼,還包含圍繞該程式碼的人員和流程。是否可以重複使用從軟體開發到基礎設施管理和描述的方法?在閱讀本文時記住這個想法是個好主意。
這是我的抄本
幻燈片和視頻
Angielski版本 俄語版 - 試運行 2019-04-24
斯普魯格 DevopsConf 影片(RU) 2019-05-28 DINS DevOps 晚間影片(RU)2019-06-20 幻燈片
作為 bash 歷史的基礎設施
假設你來到一個新項目,他們告訴你:「我們有 基礎架構即代碼」。事實證明 作為 bash 歷史的基礎設施 或例如 作為 bash 歷史記錄的文檔。這是一個非常真實的情況,例如,Denis Lysenko 在一次演講中描述了一個類似的案例
帶著某種願望,我們可以說 作為 bash 歷史的基礎設施 這就像程式碼:
- 再現性:您可以獲得 bash 歷史記錄,從那裡運行命令,順便說一下,您可能會獲得工作配置作為輸出。
- 版本控制:您知道誰進來以及他們做了什麼,這並不是事實,這不會引導您在出口處找到工作配置。
- история:誰做了什麼的故事。只是如果您失去伺服器,您將無法使用它。
怎麼辦呢?
基礎架構即代碼
甚至像這樣奇怪的案例 作為 bash 歷史的基礎設施 你可以拉著它的耳朵 基礎架構即代碼,但當我們想做一些比舊的 LAMP 伺服器更複雜的事情時,我們會得出這樣的結論:這段程式碼需要以某種方式修改、改變、改進。接下來我們要考慮之間的相似之處 基礎架構即代碼 和軟體開發。
乾燥。
在一個儲存系統開發專案中,有一個子任務
- 透過ssh登入這裡並執行命令。
- 將文件複製到那裡。
- 更正此處的配置。
- 在那裡啟動服務
- ...
- 利潤!
對於所描述的邏輯,bash 是綽綽有餘的,特別是在專案的早期階段,剛開始的時候。這
原來還有D.R.Y這樣的做法。 (不要重複自己)。這個想法是重複使用現有的程式碼。這聽起來很簡單,但我們並沒有立即想到這一點。在我們的例子中,這是一個平庸的想法:將配置與腳本分開。那些。如何單獨部署安裝、單獨配置的業務邏輯。
堅硬的。對於CFM
隨著時間的推移,該項目不斷發展並
單一責任原則
每個類別只執行一項任務。
無需混合代碼並製作單一的神聖義大利麵怪物。基礎設施應該由簡單的磚塊組成。事實證明,如果您將 Ansible 劇本分成小部分,閱讀 Ansible 角色,它們會更容易維護。
開閉原則
開閉原則。
- 開放擴充:意味著可以透過建立新的實體類型來擴展實體的行為。
- 禁止更改:由於擴展了實體的行為,因此不應對使用這些實體的程式碼進行任何更改。
最初,我們在虛擬機器上部署了測試基礎設施,但由於部署的業務邏輯與實作是分離的,所以我們新增了部署到裸機,沒有任何問題。
里氏替換原則
芭芭拉·利斯科夫的替代原則。程式中的物件必須可以用其子類型的實例替換,而不改變程式的正確執行
如果你從更廣泛的角度來看,它並不是任何特定項目的功能都可以在那裡應用 堅硬的。,通常是關於CFM的,例如在另一個專案上需要在各種Java、應用伺服器、資料庫、OS等之上部署一個盒裝的Java應用程式。使用這個例子,我將考慮進一步的原則 堅硬的。
在我們的例子中,基礎設施團隊內部達成了一項協議:如果我們安裝了 imbjava 或 oraclejava 角色,那麼我們就有了一個 java 二進位可執行檔。這是必要的,因為上游角色取決於此行為;他們期望 java.lang.同時,這允許我們將一個 java 實作/版本替換為另一個 java 實作/版本,而無需更改應用程式部署邏輯。
這裡的問題在於,在 Ansible 中不可能實現這一點,因此團隊內部出現了一些協議。
介面隔離原則
介面分離原則:「許多特定於客戶端的介面比一個通用介面更好。
最初,我們試圖將應用程式部署的所有可變性放入一個 Ansible playbook 中,但很難支持,並且當我們指定了外部介面(客戶端期望連接埠 443)時,可以從單一基礎設施中組裝基礎設施具體實現的磚塊。
依賴倒置原則
依賴倒置的原理。較高層級的模組不應依賴較低層級的模組。兩種類型的模組都必須依賴抽象。抽像不應該依賴細節。細節必須依賴抽象。
這裡的範例將基於反模式。
- 其中一位客戶擁有私有雲。
- 我們在雲端訂購了虛擬機器。
- 但由於雲端的性質,應用程式部署與虛擬機器所在的虛擬機器管理程式相關聯。
那些。進階應用程式部署邏輯依賴較低層級的虛擬機器管理程序,這意味著重複使用此邏輯時會出現問題。 不要這樣做。
相互作用
基礎設施即程式碼不僅涉及程式碼,還涉及程式碼與人之間的關係,涉及基礎設施開發人員之間的互動。
總線係數
假設您的專案中有 Vasya。 Vasya 了解您的基礎設施的一切,如果 Vasya 突然消失會發生什麼?這是一個非常真實的情況,因為他可能會被公共汽車撞到。有時候這種情況會發生。如果發生這種情況,並且關於程式碼、其結構、工作原理、外觀和密碼的知識沒有在團隊中分佈,那麼您可能會遇到許多不愉快的情況。為了最大限度地減少這些風險並在團隊內分配知識,您可以使用各種方法
配對消除
這不像
另一個特殊情況是事件呼叫。在出現問題時,一群值班人員和相關人員聚集在一起,任命一名領導者,他分享他的螢幕並表達思路。其他參與者跟隨領導者的想法,從控制台監視技巧,檢查他們沒有錯過日誌中的一行,並了解有關係統的新知識。這種方法通常很有效。
代碼審查
主觀上,使用程式碼審查來傳播有關基礎設施及其工作原理的知識更有效:
- 基礎設施由儲存庫中的程式碼描述。
- 更改發生在單獨的分支中。
- 在合併請求期間,您可以看到基礎架構中的變更增量。
這裡的亮點是審稿人是根據時間表一一選出的,即您有可能會進入一個新的基礎設施。
代碼風格
隨著時間的推移,評審期間開始出現爭吵,因為…審查者有自己的風格,審查者的輪換以不同的風格堆疊他們:2個空格或4個,camelCase或snake_case。不可能立即實施這一點。
- 第一個想法是推薦使用linter,畢竟大家都是工程師,大家都很聰明。但不同的編輯器、作業系統,不太方便
- 這演變成一個機器人,它為每個有問題的提交寫入 slack 並附加 linter 輸出。但在大多數情況下,還有更重要的事情要做,而程式碼仍然沒有修復。
綠色建造大師
隨著時間的流逝,我們得出的結論是,未通過某些測試的提交不能被允許進入 master。瞧!我們發明了Green Build Master,它在軟體開發中已經實踐了很長時間:
- 開發工作正在一個單獨的分支中進行。
- 測試正在該線程上運行。
- 如果測試失敗,程式碼將不會進入母版。
做出這個決定是非常痛苦的,因為…引起了很多爭議,但這是值得的,因為...評論開始收到風格上沒有差異的合併請求,隨著時間的推移,問題區域的數量開始減少。
IaC測試
除了樣式檢查之外,您還可以使用其他方法,例如,檢查您的基礎架構是否可以實際部署。或檢查基礎設施的變化不會導致金錢損失。為什麼需要這個?這個問題既複雜又哲學,最好用一個故事來回答:不知何故,Powershell 上有一個自動縮放器,它沒有檢查邊界條件=> 創建了比必要的更多的虛擬機=> 客戶花費了比計劃更多的錢。這不是很令人愉快,但是很可能在早期階段發現這個錯誤。
有人可能會問,為什麼要讓複雜的基礎設施變得更複雜?就像程式碼測試一樣,基礎設施的測試不是為了簡化,而是為了了解基礎設施應該如何運作。
IaC 測試金字塔
IaC 測試:靜態分析
如果你一次部署整個基礎設施並檢查它是否正常工作,你可能會發現這需要花費很多時間並且需要很多時間。所以,基礎一定是見效快的東西,有很多,而且涵蓋了許多原始的地方。
Bash 很棘手
讓我們來看一個簡單的例子。選擇目前目錄中的所有檔案並複製到另一個位置。我首先想到的是:
for i in * ; do
cp $i /some/path/$i.bak
done
如果檔案名稱中有空格怎麼辦?好吧,我們很聰明,我們知道如何使用引號:
for i in * ; do cp "$i" "/some/path/$i.bak" ; done
做得好?不!如果目錄中沒有任何內容怎麼辦,即通配符不起作用。
find . -type f -exec mv -v {} dst/{}.bak ;
現在做得好了嗎?不...忘記檔案名稱中可以包含什麼 n
.
touch x
mv x "$(printf "foonbar")"
find . -type f -print0 | xargs -0 mv -t /path/to/target-dir
靜態分析工具
當我們忘記引號時,可能會發現上一步的問題,為此,自然界中有很多補救措施
語言
工具
打壞
紅寶石
蟒蛇
ansible
IaC 測試:單元測試
正如我們從前面的例子中看到的,linter 並不是萬能的,不能指出所有的問題區域。此外,透過類比軟體開發中的測試,我們可以回憶起單元測試。立即想到的是
一開始我們談到 堅硬的。 我們的基礎設施應該由小磚塊組成。他們的時代已經來臨。
- 基礎設施被分成小塊,例如 Ansible 角色。
- 部署某種環境,無論是 docker 或虛擬機器。
- 我們將 Ansible 角色應用在這個測試環境中。
- 我們檢查一切是否按我們的預期運行(我們運行測試)。
- 我們決定好還是不好。
IaC 測試:單元測試工具
問題,CFM 測試是什麼?您可以簡單地運行腳本,也可以使用現成的解決方案:
CFM
工具
Ansible
廚師
廚師
鹽堆
testinfra 範例,檢查用戶 test1
, test2
存在並且在一個群組中 sshusers
:
def test_default_users(host):
users = ['test1', 'test2' ]
for login in users:
assert host.user(login).exists
assert 'sshusers' in host.user(login).groups
選擇什麼?問題複雜且模糊,以下是 2018-2019 年 github 上專案變更的範例:
IaC 測試框架
問題出現了:如何將它們組合在一起並啟動它?能
CFM
工具
Ansible
廚師
Terraform
2018-2019 年 github 上專案變更範例:
分子對比測試廚房
最初我們
- 並行創建虛擬機器。
- 應用 Ansible 角色。
- 運行檢查。
對於 25-35 個角色,工作時間為 40-70 分鐘,時間很長。
下一步是過渡到 jenkins/docker/ansible/molecule。從本質上講,一切都是一樣的
- Lint 劇本。
- 排列角色。
- 啟動容器
- 應用 Ansible 角色。
- 運行測試基礎設施。
- 檢查冪等性。
40 個角色的檢查和十幾個角色的測試開始需要大約 15 分鐘。
選擇什麼取決於許多因素,例如使用的堆疊、團隊的專業知識等。這裡每個人自己決定如何結束單元測試問題
IaC 測試:整合測試
基礎設施測試金字塔的下一步將是整合測試。它們類似於單元測試:
- 基礎設施被分成小塊,例如 Ansible 角色。
- 部署某種環境,無論是 docker 或虛擬機器。
- 對於此測試環境適用 許多 Ansible 角色。
- 我們檢查一切是否按我們的預期運行(我們運行測試)。
- 我們決定好還是不好。
粗略地說,我們不會像在單元測試中那樣檢查系統單一元素的效能,而是檢查整個伺服器的配置方式。
IaC 測試:端對端測試
在金字塔的頂端,我們受到端到端測試的歡迎。那些。我們不會檢查單獨的伺服器、單獨的腳本或基礎設施的單獨區塊的效能。我們檢查許多伺服器是否連接在一起,我們的基礎設施是否按我們的預期運作。不幸的是,我從未見過現成的盒裝解決方案,可能是因為...基礎設施通常是獨特的,難以模板化和創建測試框架。結果,每個人都創建了自己的解決方案。有需求,但沒有答案。因此,我會告訴你有什麼是為了促使其他人做出正確的想法,或是為了讓我覺得一切都是很久以前就在我們之前發明的。
一個有著豐富歷史的項目。它用於大型組織,可能你們每個人都間接接觸過它。該應用程式支援許多資料庫、整合等。了解基礎設施可能會是什麼樣子的是許多 docker-compose 文件,以了解在哪個環境中執行哪些測試是 Jenkins。
這個方案運行了相當長的一段時間,直到在框架內
研究想法更進一步,在 openshift 中他們發現了 APB(Ansible Playbook Bundle)這樣的東西,它允許您將如何將基礎設施部署到容器中的知識打包。那些。關於如何部署基礎架構有一個可重複、可測試的知識點。
所有這一切聽起來都不錯,直到我們遇到異質基礎架構:我們需要 Windows 來進行測試。因此,關於什麼、在哪裡、如何部署和測試的知識都在 jenkins 中。
結論
基礎設施即程式碼
- 程式碼在儲存庫中。
- 人際交往。
- 基礎設施測試。
鏈接
中文版 從個人部落格交叉發帖 - 試運行 2019-04-24
斯普魯格 DevopsConf 影片(RU) 2019-05-28 DINS DevOps 晚間影片(RU)2019-06-20 從編寫超過 300,000 行基礎設施程式碼中汲取的經驗教訓 &文字版 將基礎設施即程式碼整合到持續交付管道中 測試基礎設施即程式碼 Ansible角色的有效發展與維護 Ansible 不是 bash!
來源: www.habr.com