2020年2月8日 星期六

讀書筆記|DevOps Handbook: 打造世界級技術組織的實踐指南(Part 3 - Part 6 實踐篇與心得)




本書的六大章節,分別為

Part 1:三步工作法 
Part 2:從何處開始 
Part 3:第一步工作法:暢流的技術實踐
Part 4:第二步工作法:回饋的技術實踐
Part 5:第三步工作法:持續學習與實驗的具體實踐
Part 6:整合資訊安全、變更管理和合規性的技術實踐



以下是 Part 3 - Part 6  的書摘筆記。

/////  

Part 3:暢流的技術實踐



“ 奠定部署管線的基礎 
實現快速可靠的自動化測試 
啟動和實踐持續整合 
自動化並降低發佈風險 
以及建置降低發佈鋒線的架構。”
— 五項暢流的技術實踐


  • 為了使工作快速可靠地從開發階段流向營運階段,必須落實在價值流每階段使用 Pre-prod 環境,且要求以自動化進行佈建
  • 部署pipelines的核心目標就是讓團隊成員能透根據版本控制系統中的資訊,重複佈建整套生產環境。
  • 通用的佈建機制:如開發環境、測試環境和生產環境。
  • Puppet Lab 在 《2014 年 DevOps 現況報告 》中,將營運團隊使用版本控制列為 IT 效能和組織績效的五大預測因子之一。所有變更應一一被記錄在版本控制系統中,幫助查找問題以及 roll back。版本控制不僅僅只涵蓋 code 也應包含環境的可配置參數
  • 重新解釋 "完成"的定義:不只是開發完功能正確的程式碼,還包括在每一個迭代週期結束時,已經在 Pre-Prodction 環境中整合且測試了可運作和可交付的程式碼。
  • 綠色交付 (Push on Green) :Practice in Google,當developer 提交程式碼,就會自動運行測試套件,其包含了成千上萬個自動測試用例。只有當提交的程式碼通過自動化測試後,才會自動和動到主幹,得以被部署到生產環境。另外,希望「退回前一版本」的操作是很容易的。
  • Continuous integration ( CI ) : 通常指將多個程式碼分枝持續整合到主幹中,且確保都通過單元測試。
  • CI+:持續整合 ( CI ) 同時被要求在 pre-production 中運行,並通過整合測試接受度測試 ( by 《 Continuous Delivery 》一書作者 Jez Humble 和 David Farley )。 
  • 部署管線」( Deployment pipeline ) 確保所有check-in 版本系統的程式碼都是以自動化方式佈建,且在 pre-production 中進行測試。如此一來,才能讓開發人員在submit code後,得到立即的反饋,得以修復錯誤。
  • 有了部署管線的基礎後,為了建立實踐 CI,還需要以下三個面向。
    • 全面可靠的自動化測試套件,驗證軟體是否處於可部署狀態。
    • 一種在驗證測試失敗時,可以「中止整條生產線」的文化
    • 開發人員的工作模式是在主幹上以小批量提交變更,而非在生產週期很長的功能分枝上工作。 
  • 依照速度快慢,自動化測試主要分為以下幾類
    • 單元測試:獨立測試每一方法、類別或函數。確保程式碼按照開發人員的設計運行。
    • 驗收測試:測試整個application,確保各個功能模組按照設計正常運作,且沒有破壞以前正常的功能。驗證功能能滿足使用者期待,不僅僅是程式設計師的預期。
    • Smoke test:通常是只針對整個應用,執行一組成熟且完整的驗收測試。
    • 整合測試:確保應用能和與生產環境中的其他應用和服務正確互動。整合測試通常是脆弱的,應減少整合測試,多進行單元和驗收測試。
  • 任何通過自動化測試的佈建版本,都可以繼續用在探索性測試和其他形式的手動測試,或是效能測試等等。
  • 想要確保可靠的自動化測試,最有效的一個方法是透過「測試驅動開發」( test-driven development, TDD ) 和「驗收測試驅動開法」( acceptance test-driven development,ATDD),在日常工作中編寫自動化測試。
  • 《 2015 年 DevOps 現況報告 》顯示,基於主幹的開發模式 ( trunk, or master, mainline) 能帶來更高的生產力、更好的穩定性,甚至提高工作滿意度和降低職業倦怠率。
  • Case study:2012年 Bazaarvoice 的 CI 實踐。 
  • 不同發布模式:
    • 基於環境:藍綠部署模式 ( Blue-green deployment pattern ) 、金絲雀 ( Canary release pattern ) 發佈以及叢集免疫系統發布模式
    • 基於 application :
      • 透過功能切換開關
      • 暗度發佈 ( Dark launch ) :讓功能暫時不被看見、無法使用。2008 年 Facebook 運用 dark launch 的方式發布聊天功能
  • 持續交付( continuous delivery  持續部署 ( continuous deployment )
    • 持續交付 
      • 所有開發人員在主幹上進行小批量工作,或者在短時間內存在的功能分之上工作,定期向主幹進行合併,且始終讓主幹維持可發佈與按需執行一鍵式發布。在引入任何 regression 錯誤時,能快速的得到回饋,而立即加以解決
      • 適用於幾乎所有部署與發佈場景
      • 多數於 Amazon 與 Google的團隊採用持續交付實踐
    • 持續部署
      • 在持續交付的基礎上,由相關人員自助式地定期向生產環境部署優質的佈建版本。甚至每當開發人員 submit code 時,就觸發一次自動化部署。 
      • 更適用於交付線上的 web 服務
      • 持續交付是持續部署的先決條件,如同持續整合是持續交付的先決條件。

  • 架構原型:單體架構 ( Monoliths ) VS. 微服務 ( Microservices )

"沒有一個可以適用所有產品和規模的完美架構。 
任何架構都能滿足特定的一組目標,或一系列需求和條件"      
            --  from Randy Shoup


  • 在產品生產週期的早期階段單體架構通常是最佳的選擇。
  • 由下表中可看出單體架構適合創業公司,而數百個開發團隊的公司較適合微服務。

    • 轉型經驗:2002 年 Amazon 的演進式架構。
    • 扼制模式 Strangler application ) : 具體內容包含以 API 封裝已有功能,按照新架構實現新的功能,僅在必要時調用舊的系統,所有服務都透過版本化 API 進行存取,也稱為版本化服務或不可變服務。可參考 2011 年 Blackboard learn 的經驗。



      Part 4:回饋的技術實踐



      “建立能發現並解決問題的遙測( Telemetry )系統、 
      分析遙測資料以便預測故障和實現目標、
      啟動回饋機制以安全地部署程式碼、 
      「假設驅動開發」和「A/B 測試」整合到日常工作、
      建立評閱和協作流程,提高現有工作品質”      
      —五個回饋技術的實踐

      • 《 2015 年 DevOps 現況報告 》顯示高績效團隊解決生產故障的速度是平均水準的168倍,中等績效團隊的平均修復時間 ( Mean time to recovery,MTTR ) 以分鐘為單位。
      • 監測框架

      • 需確保對所有正在建構和營運的應用建立充分遙測資料。
      • 不同層級的日誌:除錯 ( Debug )、資訊層級 ( Info )、警告層級 ( Warn )、錯誤層級 ( Error ) 以及致命層級 ( Fatal ) 
      • 資訊輻射體 ( information radiator ):敏捷聯盟定義為:「術語源自豐田生產系統。圖表、圖示與其他在團隊辦公室、走廊或其他辦公室公開展示的資訊,讓所有看到的人能夠知道必要的資訊:自動化測試次數、速率、事故報告、持續整合狀態等。」
      • 公開透明地以 information radiator 來溝通問題,並詳細展示正在進行的變更。
      • Case study: 2011 年LinkedIn 建立自助服務指標 ( InGraphs )
      • 充份而完整的遙測資料需涵蓋以下指標
        • 商業層級:如交易訂單數量、營業額、使用者註冊數量、轉換率、A/B測試結果等。
        • 應用程式層級:事務處理時間、使用者響應時間、應用程式故障、新使用者數、登入次數等。目標不僅要確保健康狀況,還要評估組織商業目標的實踐情形
        • 基礎架構層級:如 Web 伺服器運送量、CPU附載能力等。
        • 使用者端軟體層級:含應用程式的出錯和閃退等。
        • 部署管線層級:包含管線狀態、變更部署前置時間等。

      • 異常檢測 ( outlier detection ) :Netflix 團隊使用的一項統計法,用於檢測「可能導致效能顯著下降的異常運行狀況,例如管線無法正常流動等問題」。Netflix 先自動計算出「當前正常值」,然後辨識與之不符的節點,將他們從生產環境中移除。
      • 分析生產環境度量指標,最簡單的一種統計法就是計算平均值/平均數標準差
      • 建立更好的警示方式:可藉由提高訊號雜訊比、專注發現差異值或異常值。例,每天未經授權的登錄次數比平均值大了三個標準差就發出警告。當資料為高斯分佈時,約只有0.3%的資料會觸發警告。非高斯分佈的資料,可採用其他異常檢測技術,如 smoothing、快速傅立葉轉換、 KolmogorovSmirnov 檢驗。
      • 需要監測哪些? 最簡單的做法是分析在近期 ( ex. 30 天內 ) 所遭遇最嚴重的事故,並據此建立一個遙測清單,更即時、快速檢測和診斷問題,並清楚確認是否實施了有效地修復措施。 
      • 開發與營運共同承擔值班工作。ex. facebook 
      • 讓開發人員追蹤工作對下游的影響,含使用者體驗 。
      • 軟體生命週期中營運學習往往太晚開始,導致生產軟體難以穩定運行。也會不斷發生系統管理員只待短期就紛紛離職,生產環境總是故障,部署總是十分痛苦等事件。
      • Google實踐:先讓開發團隊在生產環境中管理自己開發的服務,之後才能交由集中的營運團隊接手管理。保持開發團隊的完整性,在專案後也不解散團隊,以進一步了解生產問題。
      • 服務發佈規範和要求可能包含以下內容:
        • 缺陷計數和嚴重性
        • 警告的類型和頻率
        • 監測的覆蓋率
        • 架構部署
        • 部署過程
        • 生產環境的整潔
      • Google的「服務回傳機制」( service handback mechanism ):針對生產環境中的現有服務,用於保證營運人員不會被困在無法支援的服務中。
        • 當服務回到開發人員手中,營運部門就從提供生產支援的角色轉變為開發部門的顧問,幫助開發團隊再次將服務變成生產環境就緒狀態
        • 對營運團隊來說像是減壓閥
        • 有助於減輕技術債






      • Google 實踐:
        • 網站可靠性工程師 ( Site Reliability Engineer, SRE ):營運工程師的職能定位
        • 開發人員能燃必須在生產環境中管理他們的服務至少六個月以上,然後產品團隊才有資格分配到 SRE 人員。
        • 發佈新服務的兩個關鍵階段,兩套安全安全檢查:交接就緒審核 ( Launch readiness review, LRR ) 與上線就緒審核 ( Hand-offs readiness review, HRR )。
        • 在任何服務公開給使用者前接收生產流量之前,必須進行 LRR,且簽字接收。由產品團隊自行執行並上報。
        • 服務轉為營運管理狀態後 ( LRR 數月後 ),則執行 HRR。
        • LRR 和 HRR 審核清單相當雷同,但 HRR 更加嚴格。
        • 通過 LRR 或 HRR 流程的產品團隊都會分配到一名 SRE 人員,幫他們了解和實現需求。





        • 建構一項功能之前,我們應該嚴肅的問自己:「應該建構它嗎?理由是?」接著以成本最低、速度最快的實驗,透過使用者研究來驗證設想的功能是否能產生預期的業務成果。
        • A/B Testing:也被稱為線上控制實驗 (online controlled experiments) 或拆分測試 ( split test)。對網站的訪客展示兩種網頁版本的其中一種。一為控制組 ( A ),另一個則是實驗組 ( B )。根據使用者後續行為的統計分析,可以判斷兩者結果是否存在顯著差異

        • 實施變更前,和傳統的外部變更批准相比,善用如GitHub 的 同 review 流程,可加速且有效降低風險。GitHub 建立的 Pull Request 流程也應用於「 GitHub Flow 」此一實踐上。

        • 豐田生產系統的核心理念之一是「最了解問題的人,就是那些離問題最近的人」。 《 2014年 DevOps 現況報告 》的一項主要發現是,高績效組織更依賴同評閱而非外部變更批准。
        • Giray 在Twitter 上提到:「 請工程師來審閱十行程式碼,他會找到十個問題。請他審查五百個程式碼,他會說看起來都不錯。」維持小批量規模的原則,也適用於程式碼審查。
        • 2010 年 Google 的程式碼審查:
          • 符合程式語言規範的程式碼可讀性(強制編碼樣式)
          • 指派程式碼分支的所有權,保證一致性和正確性
          • 在團隊中提倡程式碼的透明度和貢獻度
        • Pair programming :由兩個軟體開發工程師同時在同一台工作站上的工作的開發方法。另一個模式是 「測試驅動開發」( test-driven development, TDD ),一位寫程式碼,另一位同時編寫自動化測試。相關研究顯示,寫程式所需時間約多15% ,然而無錯誤的程式碼量卻由70% 增加到 85%。




        Part 5:持續學習與實驗的具體實踐



        “將學習融入日常生活工作、 
        將局部經驗轉化為全局改善、
            為組織學習和改善活動預留時間 ”      
        —三個持續學習與實驗的具體實踐


        • 韌性型組織」( resilient organization ):能夠熟練地發現問題,解決問題,並在整個組織中提供解決方案以擴大驚豔的效果。具有自我恢復的能力。
        • Netflix 的搗亂猴」( Chaos Monkey ):不斷隨機刪除生產伺服器,來模擬 AWS 環境故障。這麼做的原因在於,希望所有的工程團隊習慣在故障發生的情況下持續工作,使得服務能夠在沒有人工干預的情況下,自動恢復正常。此 Practice也讓 Netfliex 成為「2014年 Amazon EC2 伺服器大規模重啟」災害事件中,極為少數幾乎沒有遭受business impact 的企業。
        • 學習型文化的先決條件之一是,當事故發生時,對待事故的反應要公正」。以學習的角度出發,看待錯誤、報錯、失誤、過失等問題。
        • 當事故和重大事件發生時,應該在問題解決後舉行不指責的事後分析」,也就是對事不對人。Scrum 實踐上也常採用的 Retrospective。且儘可能廣泛公開事後分析會議結果,讓個案學到的經驗轉化為適用於整個組織的學習和改善。
        • 重新定義失敗,鼓勵評估風險。《 2014 年 DevOps 現況報告 》證明,高效能 DevOps 組織會更頻繁地失敗和犯下錯誤,這不但是可以接受的,也更是組織需要的。
        • Peter Senge對組織來說,唯一一種永續競爭優勢,就是比對手更快的學習能力
        • 演練日」( Game Day ) :特別災難恢復演練,其目標為幫助團隊模擬和演練事故,讓團隊具備實戰能力。做法為計畫一個災難性事件,例如 data center 掛掉。接著,給團隊準備時間來消除所有的單點故障,並建立必要的監控程式和故障切換程式等,並在演練日執行各種演習。透過這麼做,開始暴露系統中的「潛在缺陷latent defects
        • 如何在組織中不斷累積學習經驗? 可參考以下方法
          • 將自動化工具整合至聊天室
          • 與其將專業知識寫到 Word 文件中,倒不如將完整的各種標準和流程轉化為一種更方便執行、更容易重複使用的形式。甚至在原始程式碼中保存這些知識,讓人可搜尋使用。
          • 建立全組織共享的單一原始程式碼庫,不只只有原始碼也包含其他資料文檔與工具。ex. google
          • 自動化測試紀錄和交流實踐
          • 為 operation 編寫非功能性的需求
        • 美國零售商 Target 的DevOps 道場 」( DevOps Dojo
          • 「 30天挑戰」讓內部團隊在一個月內與專職 DevOps道場教練和工程師一起工作,目的是解決長期困擾他們的內部問題,且在30天內進行突破。與道場教練密切合作—規劃、工作,並在為期兩天的衝刺活動後展現成果。
          • 「快閃建構」( Flash Builds ) : 讓多團隊聚在一起,參與一次為期一到三天的活動,目標是在結束時交付 MVP 或一種功能。
          • 「開放實驗室」:每兩週舉辦一次,任何人都可以來道場和道場教練交談、參加成果演示或接受培訓。
        • 償還技術債
          • 舉辦為期數天或數週的「改善閃電戰」,此時不允許進行任何功能開發。改善內容可著眼於程式碼、環境、架構、工具等等任何一個問題點。
          • 其他例行活動與術語「春季/秋季大掃除」 ( spring or fall cleanings)、「反轉佇列工單週」 (ticket queue inversion week)、「駭客日」 (Hack days )、「黑客松」( hackathons ) 和「 20%的創新時間」(20% innovation time ) 


        Part 6:整合資訊安全、變更管理和合規性的技術實踐

        • DevOpsSec : 將資訊安全工作整合到軟體開發生命週期的各個階段裡的實踐和原則。
        • 相關措施 
          • 使安全成為每個人工作的一部分
          • 將安全整合到缺陷追蹤和事後分析
          • 使預防性的控制程式碼整合到共享程式碼庫中
          • 將安全性整合到部署管線中
          • 保證應用程式的安全性: 
            • 可參考 OWASP 發佈的指導原則,ex. Cheat Sheet
            • Case study: Twitter 的靜態安全測試,他們將靜態程式碼分析整合到 Twitter 的建構過程。經過數年,約將漏洞發現率降低 60%。  
          • 將安全性整合到監控流程,以便快速檢測和恢復
          • 整合部署活動和變更審批流程
          • 降低對責任分離的依賴性



        ////// 一些想法 /////

        • 心目中的 2 YES & 2 NoNo of DevOps
        • 需要觀察什麼?為什麼需要 ? for business? for system?有什麼樣的遙測 ( Telemetry )資料有所幫助?要怎麼有效的拿到這些資料?怎麼build in 進去產品/功能?拿到之後怎麼看?能不能好好的解讀?怎麼根據這些去做改善?整個feedback loop 要怎麼串接暢通?另外,每一部分的 Telemetry的成本是什麼?值得嗎? ( 不要陷入為了有很多 data 而去建置不必要的 telemetry )
        • 每一個部門/組織/團隊都有自己現有的狀態和進度,ex. 可能有的部門有CI ,還沒有CD,有的團隊全部都有。理解歷史背景,對事不對人,在有限的專案資源下,選擇團隊內以及相關 stakeholders 最有共識且最有 Value 的部分先做,一步一步的漸進改善。
        • 出來跑都是要還的,雖然話說還的不一定是自己(誤)。技術債 ( Technical debt ) 最好還是定期還。在溝通技術債償還計畫時,練習思考 “償還此技術債所帶來的價值”,甚至是商業價值,將其提出來,將更有利於爭取資源。話說最近就在還技術債中...
        • 浪費( Waste ):在投入resource去開發前,先和stakeholders ( Product owner, PM and so on ) 確認是否有買家要用,是否這個時間點還能解決了客戶的某個pain point,可帶來價值。
          • 回到現實世界,看看手上的專案相關服務,如何讓它們更加有韌性而較不那麼脆弱?首要的事是?
          • 不同組織型態都有相對應的成功案例可以參考,ex. 職能型的有 Google、Etsy 和 GitHub,市場型的有Amazon 和 Netflix。沒有唯一最好,也不需執著一定要哪一種,只有價值流中的成員知不知道目標和自己在做什麼才是重點。
          • Dev 和 Ops 是該為同一個 team 還是不同 team? 前陣子和專案中的 leader們有一起簡單討論過,因為目前開發的部分很重,先由 team member 輪流值班兼顧。持續觀察狀況。
          • 對於讓團隊成員成為通才這件事,Peggy抱持著正面態度,舉例來說,去年底開始安排讓部門同事們往 "solution engineer with threat knowledge" 這塊靠近。另外,根據過去經驗,想要讓專案更順利,除了培養通才外。另外,在每一個domain 或重要環節,至少要有一到兩位相對應具有精深知識和專業的工程師在那。專才搭配通才, Project 就可以跑的更順利。不過與其強調通才這一點,個人認為是否有快速學習的能力以及具有彈性願意調整此兩項更加的重要。
          • 建立信任且願意說真話的文化。這邊也想來個感謝。團隊內有好幾位優秀的 members 在發現有問題或擔心有問題的時候,願意提出來討論,且同時也會提出possible solutions。 (雙手合十)
          • VSM 實作的部分本書著墨不是那麼多,看完內心還是有些疑問....之後再找時間去多瞭解。


          ///


           有興趣的朋友可參考Peggy之前整理的兩篇讀書筆記
          • Part 1:三步工作法 (筆記)
          • Part 2:從何處開始 (筆記



          原創文章,若有您轉貼需求,請來信討論。 轉貼時禁止修改內容及標題且保持所有連結。禁止商業使用,請註明原文標題、連結以及作者。

          沒有留言:

          張貼留言

          Peggy的實驗空間| 小書庫 Index card ( 讀書筆記總目錄 )

            一直很喜歡閱讀,也常從閱讀好書中與讀書會得到許多的力量與啟發,不管是在人生的低潮抑或是順遂的時候。在閱讀之路上,這幾年也保持一個習慣。當閱讀到喜歡的書籍,且那陣子時間允許,就會提醒自己閱讀完後整理出心得筆記。一方面藉機鍛鍊寫作肌肉與思路,方便之後的複習和查閱。另一方面,也可以...