Linux 上的 .NET Core,馬背上的 DevOps

我們盡最大努力開發 DevOps。我們有 8 個人,Vasya 是 Windows 上最酷的。突然 Vasya 離開了,我的任務是啟動一個由 Windows 開發提供的新專案。當我把整個 Windows 開發堆疊倒在桌子上時,我意識到情況很痛苦...

故事就是這樣開始的 亞歷珊卓辛奇諾娃開發營運大會。當這位領先的 Windows 專家離開公司時,亞歷山大想知道現在該怎麼辦。當然是切換到 Linux! Alexander 將透過為 100 個最終用戶完成的專案範例,告訴您他如何成功開創先例,並將部分 Windows 開發轉移到 Linux。

Linux 上的 .NET Core,馬背上的 DevOps

如何使用TFS、Puppet、Linux .NET core輕鬆輕鬆地將專案交付到RPM?如果開發團隊第一次聽到Postgres和Flyway這兩個詞,而截止日期是後天,如何支援專案資料庫的版本控制?如何與Docker整合?如何激勵 .NET 開發人員放棄 Windows 和 Smoothies,改用 Puppet 和 Linux?如果沒有實力、沒有意願、沒有資源來維護 Windows 的生產,如何解決意識形態衝突?關於這一點,以及關於 Web 部署、測試、CI、關於在現有專案中使用 TFS 的實踐,當然還有關於破拐杖和工作解決方案,都在 Alexander 的報告中。


於是,Vasya離開了,任務就落在了我身上,開發者們拿著乾草叉不耐煩地等待著。當我最終意識到瓦夏無法歸來時,我開始談正事。首先,我評估了我們的機群中 Win 虛擬機器的百分比。分數對 Windows 不利。

Linux 上的 .NET Core,馬背上的 DevOps

由於我們正在積極開發 DevOps,我意識到啟動新應用程式的方法需要改變。只有一種解決方案 - 如果可能的話,將所有內容轉移到 Linux。 Google 幫助了我——當時 .Net 已經移植到 Linux 上,我意識到這就是解決方案!

為什麼.NET core要與Linux結合?

造成這種情況的原因有幾個。在「付錢」和「不付錢」之間,大多數人會選擇第二個——就像我一樣。 MSDB 授權的費用約為 1 美元;維護一組 Windows 虛擬機器的費用為數百美元。對於一家大公司來說,這是一筆很大的開銷。這就是為什麼 儲  - 第一個原因。不是最重要的,但卻是最重要的之一。

Windows 虛擬機器比 Linux 虛擬機器佔用更多資源。 它們很重。鑑於公司的規模,我們選擇了Linux。

該系統只需整合到現有 CI 中。我們認為自己是進步的 DevOps,我們使用 Bamboo、Jenkins 和 GitLab CI,所以我們大部分的工作都在 Linux 上運作。

最後一個原因是 方便的伴奏。 我們需要降低「護衛」的進入門檻,也就是了解技術部分、確保服務不間斷、維護二線服務的人員。他們已經熟悉 Linux 堆疊,因此他們理解、支援和維護新產品比花費額外的資源來了解 Windows 平台的類似軟體功能要容易得多。

需求

第一件也是最重要的事情是 新解決方案為開發人員帶來便利。並不是所有人都做好了改變的準備,尤其是在 Linux 這個字被提出之後。開發人員想要他們最喜歡的 Visual Studio、TFS 以及程式集和冰沙的自動測試。如何交付生產對他們來說並不重要。因此,我們決定不改變通常的流程,對Windows開發保持一切不變。

需要新項目 整合到現有的 CI 中。軌道已經在那裡,所有工作都必須考慮配置管理系統的參數、公認的交付標準和監控系統來完成。

易於支援和操作,作為來自不同部門和支持部門的所有新參與者的最低進入門檻的條件。

截止日期 - 昨天.

贏發展集團

當時 Windows 團隊在與什麼合作?

Linux 上的 .NET Core,馬背上的 DevOps

現在我可以自信地說 身份伺服器4 是 ADFS 的一個很酷的免費替代品,具有類似的功能,還是什麼? 實體框架核心 — 開發人員的天堂,在這裡您不必費心編寫 SQL 腳本,而是用 OOP 術語描述資料庫中的查詢。但後來,在討論行動計畫的過程中,我把這個堆疊視為蘇美楔形文字,只辨識 PostgreSQL 和 Git。

當時我們正在積極使用 木偶 作為配置管理系統。在我們的大多數項目中,我們使用 亞搏體育app CI, 鬆緊帶、平衡高負載服務的幫助 HA代理 在幫助下監控一切 ZABBIX, 韌帶 格拉法納 и 普羅米修斯, ,而這一切都在硬體上旋轉 HPESXi的 上 VMware的。每個人都熟悉該類型的經典作品。

Linux 上的 .NET Core,馬背上的 DevOps

讓我們看看並嘗試了解在我們開始所有這些幹預措施之前發生了什麼。

發生了什麼

TFS 是一個相當強大的系統,不僅可以將程式碼從開發人員交付到最終的生產機器,而且還具有一套與各種服務非常靈活的整合 - 在跨平台層級上提供 CI。

Linux 上的 .NET Core,馬背上的 DevOps
以前,這些都是實心窗戶。 TFS 使用多個建置代理,在其上組裝了許多專案。每個代理有 3-4 個工作人員來並行任務並優化流程。然後,根據發布計劃,TFS將剛出爐的Build交付到Windows應用伺服器上。

我們想要實現的目標

對於交付和開發,我們使用 TFS,並在 Linux 應用程式伺服器上運行應用程序,它們之間存在某種魔力。這 魔術盒 還有前面的工作。在拆解它之前,我先談談該應用程式。

項目

該應用程式提供處理預付卡的功能。

Linux 上的 .NET Core,馬背上的 DevOps

客戶端

有兩種類型的使用者。 第一 透過使用 SSL SHA-2 憑證登入取得存取權限。 U 第二 使用登入名稱和密碼進行存取。

HAProxy的

然後客戶端請求去了HAProxy,解決了以下問題:

  • 主要授權;
  • SSL 終止;
  • 調整 HTTP 請求;
  • 廣播請求。

用戶端憑證沿鏈進行驗證。我們 - 權威 我們可以負擔得起,因為我們自己為服務客戶頒發證書。

請注意第三點,我們稍後再討論。

後端

後端計劃在 Linux 上建置。後端與資料庫交互,載入必要的權限列表,然後根據授權使用者擁有的權限,提供簽署財務文件並將其發送以供執行或產生某種報告的存取權限。

使用 HAProxy 節省成本

除了每個客戶經歷的兩個上下文之外,還有一個身分上下文。 身份伺服器4 只允許您登錄,這是一個免費且強大的模擬 ADFS的  - Active Directory聯合身份驗證服務.

身份請求分幾個步驟處理。第一步 - 顧客 進入後台,它與該伺服器通訊並檢查客戶端是否存在令牌。如果沒有找到,請求將返回到它來自的上下文,但會進行重定向,並且透過重定向它會轉到身分。

第二步-請求已收到 到IdentityServer中的授權頁面, 在客戶端註冊的地方,等待已久的令牌出現在 IdentityServer 資料庫中。

第三步是 客戶端被重定向回來 到它所來自的上下文。

Linux 上的 .NET Core,馬背上的 DevOps

IdentityServer4有一個特色: 它透過 HTTP 傳回對傳回請求的回應。無論我們如何努力設定伺服器,無論我們如何透過文件啟發自己,我們每次都會收到帶有透過 HTTPS 傳入的 URL 的初始客戶端請求,並且 IdentityServer 返回相同的上下文,但使用 HTTP。我們很震驚!我們透過身分上下文將所有這些傳輸到 HAProxy,並且在標頭中我們必須將 HTTP 協定修改為 HTTPS。

有什麼改進以及在哪裡節省了?

我們透過使用免費的解決方案來授權一組使用者和資源,從而節省了資金,因為我們沒有將IdentityServer4 作為單獨的節點放置在單獨的段中,而是將其與應用程式後端運行的同一伺服器上的後端一起使用。

它應該如何運作

所以,正如我所承諾的 - 魔盒。我們已經明白,我們肯定會轉向 Linux。讓我們制定需要解決方案的具體任務。

Linux 上的 .NET Core,馬背上的 DevOps

傀儡顯現。 為了交付和管理服務和應用程式的配置,必須編寫很酷的配方。一卷鉛筆雄辯地表明了它的完成速度和效率。

運輸方式。 標準是轉速。每個人都知道,在 Linux 中你離不開它,但專案本身在組裝後是一組可執行的 DLL 檔案。大約有150人左右,工程難度相當高。唯一和諧的解決方案是將這個二進位檔案打包到 RPM 中並從中部署應用程式。

版本控制。 我們必須經常發布,並且必須決定如何形成套件名稱。這是與TFS整合程度的問題。我們在 Linux 上有一個建置代理程式。當 TFS 將任務傳送到處理程序(工作程序)到建置代理程式時,它也會向其傳遞一堆落入處理程序進程環境中的變數。這些環境變數包含建置名稱、版本名稱和其他變數。在“構建 RPM 包”部分中了解更多相關資訊。

設定 TFS 歸根結底是建立管道。以前,我們在 Windows 代理上組裝所有 Windows 項目,但現在出現了 Linux 代理 - 一個 Build 代理,需要將其包含在構建組中,豐富一些工件,並告知將在這個 Build 代理上組裝什麼類型的項目,並以某種方式修改管道。

身份伺服器。 ADFS 不是我們的方式,我們支援開源。

讓我們來看看這些組件。

魔術盒

由四部分組成。

Linux 上的 .NET Core,馬背上的 DevOps

Linux 建置代理程式。 Linux,因為我們是為它而建構的——這是合乎邏輯的。這部分分三步驟完成。

  • 配置工作人員 而且並不孤單,因為預計該專案的工作將分散進行。
  • 安裝.NET Core 1.x。當 1 已經在標準儲存庫中可用時,為什麼還要使用 2.0.x?因為我們開始開發的時候穩定版本是1.09,就決定基於它來做專案。
  • git 2.x.

RPM 儲存庫。 RPM 包需要儲存在某個地方。假設我們將使用可供所有 Linux 主機使用的同一公司 RPM 儲存庫。他們也確實這麼做了。儲存庫伺服器已配置 網絡掛鉤 即從指定位置下載所需的RPM套件。包版本由建置代理程式報告給 webhook。

亞搏體育app 注意力!這裡的 GitLab 不是由開發人員使用,而是由營運部門使用,用於控制應用程式版本、軟體包版本、監控所有 Linux 機器的狀態,並且它儲存配方 - 所有 Puppet 清單。

木偶 — 解決了所有有爭議的問題並提供了我們想要從 Gitlab 獲得的配置。

我們開始潛水。 DLL 交付如何在 RPM 中進行?

將 DDL 交付給 RPM

假設我們有一位 .NET 開發搖滾明星。它使用 Visual Studio 並建立一個發布分支。之後,它上傳到Git,這裡的Git是一個TFS實體,也就是說,它是開發人員使用的應用程式儲存庫。

Linux 上的 .NET Core,馬背上的 DevOps

之後,TFS 發現新的提交已到達。哪個應用程式?在 TFS 設定中,有一個標籤指示特定建置代理程式擁有哪些資源。在本例中,他看到我們正在建置一個 .NET Core 項目,並從池中選擇一個 Linux 建置代理程式。

建立代理接收來源並下載必要的 依賴 c .NET 儲存庫、npm 等。在建置應用程式本身並進行後續打包之後,將 RPM 套件傳送至 RPM 儲存庫。

另一方面,會發生以下情況。營運部門工程師直接參與專案的推出:他更改了包的版本 希拉 在儲存應用程式配方的儲存庫中,之後 Puppet 觸發 百勝,從儲存庫檢索新包,並且新版本的應用程式可供使用。

Linux 上的 .NET Core,馬背上的 DevOps

一切都很簡單,但是建立代理本身內部發生了什麼?

DLL RPM 打包

我們收到了TFS發來的專案原始碼和組裝任務。建構代理 開始從原始碼建置專案本身。組裝好的項目可以作為一套提供 DLL檔案,它們打包在 zip 檔案中以減少檔案系統的負載。

ZIP 存檔被丟棄 到 RPM 包建置目錄。 接下來,Bash 腳本初始化環境變量,尋找 Build 版本、專案版本、建置目錄的路徑,並啟動 RPM-build。建置完成後,套件將發佈到 本機儲存庫,它位於建置代理上。

接下來,從Build代理到RPM儲存庫中的伺服器 JSON 請求已傳送 指示版本和建置的名稱。我之前談到的 Webhook 從建置代理程式上的本機儲存庫下載這個包,並使新組件可供安裝。

Linux 上的 .NET Core,馬背上的 DevOps

為什麼採用這種特定方案將套件交付到 RPM 儲存庫?為什麼我不能立即將組裝好的套件送到儲存庫?關鍵是這是安全的要求。這種情況限制了未經授權的人將 RPM 軟體包上傳到所有 Linux 電腦均可存取的伺服器的可能性。

資料庫版本控制

在與開發團隊協商後,發現這些人更接近 MS SQL,但在大多數非 Windows 專案中我們已經全力使用 PostgreSQL。既然我們已經決定放棄一切付費的東西,我們也開始在這裡使用 PostgreSQL。

Linux 上的 .NET Core,馬背上的 DevOps

在這一部分中,我想告訴您我們如何對資料庫進行版本控制以及我們如何在 Flyway 和 Entity Framework Core 之間進行選擇。讓我們看看它們的優點和缺點。

缺點

Flyway只有一個方向,我們 我們無法回滾 - 這是一個顯著的缺點。您可以從其他方面將其與 Entity Framework Core 進行比較 - 從開發人員便利性的角度來看。您還記得我們把它放在最前面,主要標準是不改變 Windows 開發的任何內容。

對於 Flyway 我們 需要某種包裝紙這樣人們就不會寫 SQL查詢。它們更接近以 OOP 術語進行操作。我們編寫了使用資料庫物件的說明,產生了 SQL 查詢並執行它。新版本的資料庫已準備就緒,已經過測試 - 一切都很好,一切正常。

Entity Framework Core 有一個缺點 - 在重負載下 建構次優 SQL 查詢,並且資料庫中的縮減可能會很大。但由於我們沒有高負載的服務,所以我們不會以數百RPS來計算負載,我們接受了這些風險並將問題委託給未來的我們。

優點

實體框架核心 開箱即用且易於開發,和飛行路線 輕鬆整合到現有 CI。但我們為開發人員提供了方便:)

捲起程式

Puppet 發現軟體包版本即將發生變化,包括負責遷移的版本。首先,它安裝一個包含遷移腳本和與資料庫相關的功能的套件。此後,與資料庫一起使用的應用程式將重新啟動。接下來是其餘組件的安裝。 Puppet 清單中描述了安裝套件和啟動應用程式的順序。

應用程式使用敏感數據,例如令牌、資料庫密碼,所有這些都從 Puppet Master 提取到配置中,並以加密形式儲存。

TFS問題

在我們決定並意識到一切確實對我們有用之後,我決定看看其他專案的 Win 開發部門的 TFS 中的程式集發生了什麼情況 - 無論我們是否快速建置/發布,並發現速度方面存在重大問題。

其中一個主要項目需要 12 到 15 分鐘才能組裝起來——那是很長的時間,你不能這樣生活。快速分析顯示 I/O 嚴重下降,而且這是在陣列上。

經過逐個組件分析後,我確定了三個焦點。第一的 - “卡巴斯基防毒軟體”,它掃描所有 Windows 建置代理程式上的來源。第二 - Windows 索引器。 它沒有被停用,部署過程中的所有內容都在建立代理程式上即時索引。

第三 - npm 安裝。 事實證明,在大多數 Pipeline 中我們都使用了這種場景。他為什麼不好?當依賴樹形成時,執行 Npm 安裝過程 包-lock.json,其中記錄了將用於建立專案的套件的版本。缺點是 Npm install 每次都會從互聯網上獲取最新版本的軟體包,這在大型專案中會花費大量時間。

開發人員有時會在本機電腦上進行實驗,以測試特定部分或整個專案的工作方式。有時,事實證明一切在本地都很酷,但他們組裝起來,推出來,卻沒有任何效果。我們開始找出問題所在 - 是的,不同版本的軟體包具有依賴關係。

解決方法

  • AV 例外中的來源。
  • 禁用索引。
  • 去 國家公共管理委員會.

npm ci 的優點就是我們 我們收集一次依賴樹,我們有機會為開發商提供 目前的包列表,他可以隨心所欲地在本地進行實驗。這 節省時間 編寫程式碼的開發人員。

組態

現在介紹一下儲存庫配置。歷史上我們曾經使用過 關係 用於管理儲存庫,包括 內部回購協議。這個內部儲存庫包含我們用於內部目的的所有元件,例如自編寫的監控。

Linux 上的 .NET Core,馬背上的 DevOps

我們也使用 努格特,因為它比其他套件管理器快取得更好。

導致

在我們優化建置代理程式後,平均建置時間從 12 分鐘減少到 7 分鐘。

如果我們算上所有本可以用於 Windows 的機器,但在這個專案中改用 Linux,我們節省了大約 10 美元。這還只是許可證方面的費用,如果我們考慮到內容,那就更多了。

計劃

下個季度的計劃是致力於優化程式碼交付。

切換到預先建置的 Docker 映像。 TFS 是一個很酷的東西,它有很多插件,允許您整合到 Pipeline 中,包括基於觸發器的構建,例如 Docker 映像。我們希望在同一個觸發器上觸發此觸發器 包-lock.json。如果用於建置專案的元件的組成發生某種變化,我們會建置一個新的 Docker 映像。隨後使用它來部署具有組裝的應用程式的容器。現在情況並非如此,但我們正計劃切換到 Kubernetes 中的微服務架構,該架構正在我們公司積極開發,並且長期以來一直服務於生產解決方案。

總結

我鼓勵大家丟掉Windows,但這並不是因為我不知道該如何烹飪它。原因是大多數開源解決方案都是 Linux堆疊。你好嗎? 節省資源。在我看來,未來在於 Linux 上具有強大社群的開源解決方案。

亞歷山大·辛奇諾夫 (Alexander Sinchinov) 演講者簡介 在 GitHub 上.

開發營運大會 是一個由專業人士為專業人士舉辦的開發、測試和營運流程整合的會議。這就是亞歷山大談到的專案的原因?已實施並運行,演出當天成功發布了兩個版本。在 RIT++ 的 DevOps 大會 27月28日、XNUMX日還會有更多類似學員的案例。您仍然可以跳上最後一節車廂 提交一份報告 或者慢慢來 票。在斯科爾科沃與我們見面!

來源: www.habr.com

添加評論