主頁 > 軟體工程 > 構建制品不一致,后續作業都是白費 | 研發效能提升36計

構建制品不一致,后續作業都是白費 | 研發效能提升36計

2022-02-10 08:11:44 軟體工程

image.png

專欄策劃|雅純

志愿編輯|馮朝凱、橙蜂


之前我們舉了《集裝箱改變世界》(作者:馬克.萊文森)中的一個例子,書中提到上世紀五六十年代,集裝箱的使用,使得整體貨運成本降低了95%,大部分的碼頭工人都面臨著失業,

這件事情看起來很簡單,但卻給經濟全球化帶來了非常大的影響,后面美國企業的訂單可以下到中國、以及中國成為“世界工廠”,都與之有很大的關系,集裝箱的背后是標準化和基于統一標準的產業鏈,這里有兩點比較重要的,一個是標準化,另外一個是不可變,

那么,在軟體開發的程序中,我們怎樣才能享受產業生態的紅利,實作軟體交付程序的標準化呢?軟體交付當中的集裝箱應該是什么樣的?

如何保證軟體交付程序的標準化

近十幾年,軟體交付形態發生了很大的變化,從最開始買物理機、建機房到虛擬機再到現在的容器,這中間為什么會產生這樣的變化呢?

image.png

容器本身的底層技術是namespace和cgroup,然而這兩個東西在十幾二十年前就出現了,最早應用這些技術的是對資源利用率和隔離有明確訴求的云廠商,比如說阿里云不希望跑在機器上不同用戶的東西互相串,最好的辦法就是能限制每個用戶的資源,如CPU、記憶體等,有了這個訴求,就會用LXC等方式去隔離,去限制資源,但是這還是沒有產生容器,為什么呢?問題是各個云廠商只能在自己內部做,但是不能對外分發,所以Docker的偉大之處并不是在底層做了多大地創新,而是提供了一個可以對外分發的容器鏡像,

容器鏡像是一個分發的形式,我們可以把容器鏡像分發給別人,或者是讓別人繼承我們的鏡像,同時Docker又提供了Dockerfile,Dockerfile允許我們通過一個檔案的形式去描述鏡像,一旦能夠定義鏡像就可以協作了,有了這樣的能力以后,容器就很快被大家所接受了,所以容器的接受看起來好像是技術發展的程序,其實是隨著云原生、云市場的發展必然帶來的結果,

我們很多人認為的“集裝箱”就是容器,這個容器很多時候我們都認為是docker容器,在K8s里面支持很多個容器運行,大部分的情況都是用docker容器,docker容器的優勢就是剛才說的兩點:鏡像和Dockerfile,這兩點使得docker鏡像可以像集裝箱一樣做分發,

此外,容器還提供了很好的資源隔離,可以在比較小的粒度上進行隔離,虛擬機雖然也做了隔離,但是它的粒度比較大,不僅如此,容器還提供了非常彈性的資源管理方式,這點比虛擬機和物理機都有非常大的改善,本質上它就是物理機上的一個行程,這是它和虛擬機的本質的差別,

了解了軟體集裝箱是什么后,然后我們再來了解下容器鏡像的組成,

image.png

如上圖所示,這張圖非常形象地展示了容器鏡像的內部結構,當我們自己執行dockerbuild構建鏡像的時候,你會發現它出來的日志有很多hash值,一層一層的,實際上它是由很多層組成的,我們通過LXC或者其他的技術,把容器的行程創建出來,這個行程通過namespace和cqroup做了資源隔離和限制,容器鏡像都有一個BaseImage,我們知道運行一個程式,對作業系統的環境是要求的,比如依賴的library等,這個程式如果隨便在一臺物理機和虛擬機部署,會隨著機器的環境不同而不同,有可能導致風險,所以容器鏡像給了一個基本鏡像,把這個東西放里面了,再往上是Addemacs和Addapache,這兩層我們會在Dockerfile中去寫,然后最上面的是Writable,就是我們在容器Container運行的時候真正可以去寫的東西,

那么容器鏡像的特點是什么呢?它是分層的,每一層都是可以復用的,我們在某個機器上有很多個容器,如果Base鏡像一樣,只要下一次就行了,可以看到鏡像的大小是所有的層堆起來的,堆的東西越少,這個鏡像就會越小,容器鏡像有一個最小的鏡像叫scratch,就是一個最原始的基礎鏡像,這里面幾乎什么都沒有,基于它構建一個非常非常小的容器的話,可能就是幾兆的大小,但是如果你基于CentOS基礎鏡像可能就是上G的大小,

容器鏡像有一個非常重要的概念叫“One process per container”(容器生命周期=行程生命周期),我們可以認為容器就是K8s上的一個行程,如果把K8s比作作業系統,那么容器就是它上面運行的一個行程,行程的生命周期是可以被管理的,雖然容器有這么多的優點,但實際在用的時候也會遇到很多的問題,

下面我們聊一聊容器鏡像的一些常見的問題和建議,

容器鏡像常見問題及實踐建議

容器鏡像常見的問題:

  • 把所有的東西都裝到一個容器里面,把容器當虛擬機來用,
  • 把ENTRYPOINT設定為systemd:systemd管理的行程運行的結果和狀態和的容器狀態是不一致的,有可能里面的行程已經僵死了,或者Crash了,但是systemd還活著,從外部看起來這個容器沒問題,
  • 私有化部署的時候帶一堆匯出的鏡像tar包,tar包是不分層的,它不知道里面是有很多層,
  • 每次把基礎鏡像下發到整個集群,導致網路變得特別擁堵

我們的實踐建議是:

  • 盡量采用輕量的基礎鏡像和確定的鏡像版本,
  • 通過分層來復用鏡像內容,避免重復拉取,
  • 避免采用systemd,包括supervisord和類似這樣的daemon管理服務來做ENTRYPOINT,
  • 采用本地的dockerregistry等以層為粒度來離線拷貝鏡像,
  • 避免同時要做大量的pull,可采用P2P的方式(如使用dragonfly)提升鏡像分發效率,

容器鏡像可以實作軟體交付程序的標準化,標準化是手段不是目的,標準化是幫助我們更高效的復用的技術,

回到軟體交付的終態,我們的目的是希望提供一個穩定可預期的系統,

image.png

而達成這個目標的前提是,要有確定的運行環境和軟體制品,確定的環境是指代碼(及其依賴)、構建環境、構建腳本與預期一致的產出軟體制品,這一點如何做到我們后面再作分享,我們先看如何保證軟體制品的一致性,

如何保證軟體制品的一致性

要保證軟體制品的一致性,軟體制品應該有確定的格式、唯一的版本、能夠追溯到原始碼、能夠追溯到生產和消費程序,這樣才能使持續交付更好地服務于企業的制品管理與開發,

image.png

在制品構建程序中,經常會遇到一些問題,例如應用的代碼庫里沒有Makefile,package.json,go.mod而沒法確定依賴,或者制品能構建成功但缺失幾個依賴,又或是在自己的開發環境運行正常而在生產環境出現了開發環境沒有的bug,導致這些問題出現的原因是因為構建本身是可變的,當你構建可變時,就會帶來一系列的問題,為此,我們需要通過不可變構建來使制品與預期一致,

image.png

要實作不可變構建,我們需要保證有:

  • 相同的代碼
  • 相同的構建環境
  • 相同的構建腳本

相同的代碼

例如程式員開發時,不在依賴描述檔案(如go.mod,package-lock.json,pom.xml,requirements.txt等)中指定依賴的版本,則會默認使用最新的版本作為依賴,這樣產出的制品會隨著依賴的更新而不能保持一致,這將帶來完全不在預期內的風險,

image.png

相同的構建環境

對于構建環境來說,Dockerfile可以用來在容器平臺下描述環境,通過Dockerfile我們能為制品使用一致的環境,很多時候我們并不需要在運行中使用構建環境的很多依賴,而構建鏡像的體積往往比較驚人,這個時候我們就需要將構建環境與運行環境分開,以得到盡可能輕量的鏡像制品,

image.png

相同的構建腳本

對應的,使用相同的,與代碼實作無關的構建腳本也是非常重要的,在Dockerfile的環境中必須指定確定的環境依賴版本,

只有在同一份代碼(及同一個依賴)、同樣構建環境的描述、和同樣構建腳本的環境下,所產生的軟體制品才是相同的,這里強調的是說所有的東西都要保證一致性,如果說三者是一樣的話,那產生出來的制品也是一樣的,即使構建時間不同,產出的制品也是相同的,

image.png

做好不可變基礎設施,首先要標準化最終交付制品的形態,并且明確此交付形態的運維管理方式,而要保證不可變,那首先要做好不可變的構建,然后才能有一致的軟體制品,

NOTE:構建準確性,永遠比構建更快重要,制品的構建資訊不準確,導致構建制品不一致、版本不可控,所有后續的作業都是浪費,

如何提升構建效率

在構建這塊,一個需要關注的點的是如何提升構建效率,我們先看一個簡單的計算問題:

image.png

這是一個非常大的資料,也是非常大的損耗,很多時候一個專案的工程效率太低的原因就是因為構建太慢,構建耗時過長使得制品迭代非常慢,功能更新和bug修復也會受到影響,

那我們如何提升構建的效率呢?下面是我們的一些實踐建議:

1個基本原則:保證構建的準確性,構建的準確性永遠優于構建的效率,只有在保證準確性的前提下提升效率才有意義,

5點建議

  • 應用瘦身:檢查應用的依賴情況,應用包體積是否過大,依賴項是否過多,能否去除不必要的依賴,能否構建更小的鏡像,
  • 分層構建:底層的東西先構建出來以后被上層所復用,然后就可以做增量式的了,
  • 構建快取:構建程序中拉取依賴是很耗時的,要避免重復拉取,
  • 網路優化:主要是保證代碼、構建機器和制品庫之間的低網路延時,代碼和構建機器是否是在同一個低時延鏈路中,例如代碼在Github上而使用云效構建,此時的延時相對于內網會高出許多,
  • 倉庫鏡像:倉庫鏡像可以極大地減少拉取依賴項的時間,在國內的網路環境下,如果從源倉庫獲取依賴,可能延時會非常長,這時可以使用鏡像網路降低延時,例如nodejs開發者常使用淘寶的npm鏡像源,而Python開發者使用清華的鏡像源,對于企業來說也可以構建自己的鏡像倉庫以提升可靠性與降低延時,云效也使用了鏡像倉庫,來減少拉取的時間,
(小編推薦:云效流水線Flow 是一款云原生時代的流水線工具,通過容器技術讓企業擺脫對虛擬機構建環境的依賴,您甚至可以根據您的使用需求,在同一條流水線上使用不同的構建環境,此外,云效流水線Flow 還提供了各種語言的容器環境,滿足不同的構建使用場景,點擊文末閱讀原文,了解詳情)

總結

本篇文章,我們從軟體交付的終態出發,提出了不可變構建的概念,希望通過:相同的原始碼+相同的環境+相同的構建腳本=>帶來一致的軟體制品,而這些東西都是保存在源代碼里的,所以源代碼的管理非常重要,

下篇文章,我們將分享如何對源代碼進行有效管理

image.png

閱讀上篇:做到這4點,才是真正的持續交付

點擊下方鏈接立即體驗云效持續交付流水線Flow,

https://www.aliyun.com/product/yunxiao/flow?channel=yy_rccb_36

lQLPDhsGzb2HRiHNBDjNB4CwPRTOVsFHvw0B29IABwA0AA_1920_1080.png

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/423593.html

標籤:其他

上一篇:構建制品不一致,后續作業都是白費 | 研發效能提升36計

下一篇:這樣才是代碼管理和 Commit 的正確姿勢! | 研發效能提升36計

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more