Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
• 微服務架構崛起緣由與概念剖析
• 單體架構應用瓶頸的分析與拆解
• Kubernetes 與微服務迸出新滋味
• 實際情境技術應用與說明
• 公司架構演化史
• 親自動手做
• 小測驗
• 微服務崛起原因
• 單體、微服務架構三面向分析與比較
崛起原因
• 軟體複雜度提升導致開發效率下降
• 大型團隊花許多時間確認需求、開會
• 回饋循環拉長,工程師無法全力發揮
• 整合測試、出 Build 時間長
• 軟體開發模式開始強調「高」與「短」
• 高交付頻率 (delivery rate)
• 短迭代週期 (iteration)
• 市場競爭加速,強調企業靈活性
• Agile, Scrum, DevOps, 自動化
• 容器化 (containerization)
• 啟動速度快、好部署
• 容器編排器 (container orchestrator)
• Kubernetes 強大功能,節省維運人力
定義
A giant application consist with
multiple component services.
A giant application backed by
only one or few of services.
單體 微服務
系統開發層⾯面
• 模組封裝在一起,本地 API 調用快、穩定
• More is better
• 單一程序負責許多功能,邏輯複雜
• 需要完整回歸測試避免意外
• 些微改動需重新進行完整測試、部署
• 功能落地時間長
• 常以季或月為單位進行交付
• 高內聚、高耦合
• 模組間不正確使用 (內容耦合)
• 模組相依性高,難隨意修改
• 服務分散,遠端 API 調用慢、不穩定
• Do one thing and do it well
• 單一程序負責單一功能,邏輯簡單
• 可針對改動部分進行測試
• 針對改動的服務進行相關測試、部署
• 10+ deploys per day
• 以天、小時為單位進行交付
• 高內聚、低耦合
• 服務間 能透過公開接口溝通
• 服務內相依性高,服務外獨立性高
單體 微服務
系統開發層⾯面 (cont.)
• 團隊難以平行開發
• 彼此等待功能完善
• 審核與整合受到程式碼數量影響
• 無法採用不兼容之新技術
• 系統性能無法提昇
• 可能延伸安全性問題
• 多個團隊可以平行開發
• 服務契約確定後可各自開發
• 程式碼少,審核與整合速度快
• 個別服務可選用不同技術因應不同場景
• NodeJS + Go + Scala
單體 微服務
⽇日常營運層⾯面
• 面對瓶頸多以垂直擴展為主要手段
• 增加硬體規格
• 流量低峰造成大量金錢浪費
• 持續增長時仍會卡在相同瓶頸
• 水平擴展會以整個單體為基本單位擴展
• 閒置服務耗用資源
• 搶奪珍稀系統資源 (X bound)
• 瓶頸服務無法大量擴展
• 以水平擴展為主來解決瓶頸
• 硬體規格夠用即可,錢花在刀口上
• 流量低峰可快速關閉機器
• 流量高峰快速擴展足夠機器應付
• 以個別服務為基本單位擴展
• 資源完整利用
• 獨有珍稀系統資源 (X bound)
• 瓶頸服務可大量擴展
⽇日常營運層⾯面 (cont.)
• 除錯容易
• 需觀察單一服務日誌
• 每次交付、升級牽涉大量改動,問
題難以回朔
• 冷啟動時間長
• 單一服務除錯容易
• 每次交付牽涉少量改動,容易定位問題
• 服務叢集除錯複雜
• 需要有日誌搜集分析系統
• 冷啟動時間短
⽇日常營運層⾯面 (cont.)
• 共用資料庫、快取
• 資料重複性低
• 數據一致性高
• 個別維護資料庫、快取
• 資料重複性高
• 數據一致性低,強調最終一致性
• Siloed functional team
• 團隊成員多
• 負責項目小、技能專精
• 工程師不瞭解實際營運時的關 因
素,系統效能無法有效提昇
• 維運不懂開發或無法做出適當建議,
致使系統除錯曠日費時
團隊組成
• Cross functional team
• 團隊成員人少,團隊數量多
• You Build It, You Run It
• 工程師瞭解實際運作上的瓶頸,進而
改善程式面的運作方式
• 維運能根據實際狀況提供建議,出錯
時能瞭解關 原因,快速定位問題點
• 適用場景
• 專案初期需求不穩定
• 避免微服務開發完後 掉重練
• 專案簡單,不需要應付龐大流量
• 服務瓶頸點仍然未知
應⽤用場景
• 適用場景
• 垂直擴展到達極限
• 改用水平擴張來服務龐大流量
• 單體應用重構、改寫成本超出負荷
• 需採用不兼容技術、語言
• 從單體架構如何朝微服務架構邁進
評估現況是否
適合進行導入
事前評估
STEP I
生
產
力
複雜度
單體
微服務
1 2 3
服務、團隊狀狀況評估
• 專案階段會影響技術選型
• 企業是否能承受轉換陣痛期
• 換句話說: 「誰能扛住 KPI 壓力」
• 微服務開發效率問題
• 理解問題
• Service Traffic Pattern
• 危急程度、是否有暫時解
• 實質效益
• 重構是否能實際解決任何已知問題
• 開發成本跟效益評估
• 團隊成員組成
• 技能樹、團隊氣氛
評估現況是否
適合進行導入
找到問題關
正確下刀
服務切割事前評估
STEP II
分割⾯面向 XYZ
正確下⼑刀避免問題複雜化
• 不求一次到位,是否能解決問題為優先
• 切割帶來的效益
• 明確的服務邊界
• 系統擴展性得到滿足
• 以需求作為出發點進行切割
• 前後端
• 業務邏輯
• 服務擴展
• 感覺粒度 (granularity) 越小越好?
• Or Micro-Monolith is fine ?
A
B
C
思考⼀一下,是否該這樣切割
• Data Repository 負責和資料庫溝通
• 三個模組都需要通過它來存取資料庫
• 它做完格式轉換後存入資料庫
• 問題:
• Data Repository 是否該成為獨立的公
共基礎設施方便大家存取使用?
• 提示
• 程式修改服務
• 服務升級複雜度
• 服務瓶頸
微服務粒度陷阱,以 VMFIVE 為例例
• 切割關 :「是否牽涉到業務邏輯」
• 不互相牽涉則不在此限
• 比如說 DB request proxy
• 系統瓶頸從一個變兩個
• Schema 改變需要修改、升級兩個服務
• 修改範圍增加
• 額外測試項目
• 交付週期變長
• 部署困難度上升
• 多寫只用到一次的例外處理
STEP III
評估現況是否
適合進行導入
找到問題關
正確下刀
團隊全面啟動
平行開發與重構
開發重構服務切割事前評估
步驟⼀一、停⽌止繼續挖洞洞
• 停止繼續 洞 (擴大單體)
• 新功能以微服務架構下去設計
• 曝露自身對外 API 接口
• 整理模組耦合性
• 轉變成資料耦合、 息耦合
• 實作抽象層,未來方便置換底層實作
• 單體逐步轉微服務具有極大優勢
• Gradual code repair
• 將大型重構以小迭代方式進行
• 確保交付品質外也能快速定位問題
• 推薦閱讀 Why Linus is right (as usual)
步驟⼆二、雙⽅方制定服務契約
• Service Contract 就跟 API Spec 類似
• 接口 API 是雙邊溝通的唯一管道
• RESTful API 設計準則
• 以資源 (resource) 為主體
• 狀態碼要能反映問題
• API Versioning 非常重要
• 服務升級後的流量導流
• 注意相容與汰舊
• API 接口粒度「粗、細」要注意
• 過粗: 揉合太多功能在同個路由
• 過細: API 調用頻繁,效能下降
• 特例: API Gateway
[1] https://stackoverflow.com/questions/389169/best-practices-for-api-versioning
步驟⼆二、雙⽅方制定服務契約 (cont.)
• API Gateway
• 負責請求轉發、資 組合、協定轉換
• 透過單一進入點 (single entry point) 減少
大量請求來回時間
• 同步調用後端服務,避免循序呼叫
• 請求的錯誤容忍性 (Partial Failures)
• 需搭配服務探索 (Service Discovery)
• 可能需支援不同協定 (http, grpc ..etc)
• 一樣避免將所有功能放在一起又變單體
• 可透過 DNS 做服務切分
[1] https://stackoverflow.com/questions/389169/best-practices-for-api-versioning
步驟⼆二、雙⽅方制定服務契約 (cont.)
步驟三、前後切割與服務分離
• 逐步切割求穩健
• 前後端
• 呈現層
• 業務邏輯層 + 資料存取層
• 以服務契約作為開發依據
• 例外處理要注意
• 是否支援 Partial Failure
• 是否可重覆嘗試
• 原子性 (Atomic)
• 千萬不要 DDoS 自己
• RetryTimes
• Timeout
STEP IV
評估現況是否
適合進行導入
找到問題關
正確下刀
團隊全面啟動
平行開發與重構
自動化測試
減少人力需求
自動測試開發重構服務切割事前評估
導入⾃自動化測試,減少⼈人⼒力力浪費
• 測試項目 (發 PR 時觸發驗證)
• Unit Test
• E2E 驗證使用者流程 (user scenario)
• 一個測試案例不夠,可以加兩個
• 盡量完整覆蓋可能案例
• 營運面上遇到新問題要能夠反饋
• 採用漸進式服務升級測試
• 方便找出問題
評估現況是否
適合進行導入
找到問題關
正確下刀
團隊全面啟動
平行開發與重構
自動化測試
減少人力需求
Helm 部署
快速無差錯
無誤部署自動測試開發重構服務切割事前評估
STEP V
不要憑經驗,新⼿手也要能上路路
• 能自動化就不要人工
• 下線原因通常跟人為失誤有關
• 降低出錯機率是維運關
• 透過現成工具,降低操作門檻
• Config Management System
• Helm
• Terraform
• Version Control Everything
• Infrastructure as Code
評估現況是否
適合進行導入
找到問題關
正確下刀
團隊全面啟動
平行開發與重構
自動化測試
減少人力需求
Helm 部署
快速無差錯
系統日誌整合
快速定位問題
定位除錯無誤部署自動測試開發重構服務切割事前評估
STEP VI
收集零散資訊,資訊匯流
• 故障偵測、服務探針
• 微服務維運最大難題
• 收集、彙整、避免誤報
• 日誌條目格式準則
• 可溯源性
• 清楚描述問題發生
• 完整表明服務身份
• 要能夠透過麵包 ,回溯使用者流程
• Caller & Callee 都需要紀錄錯誤
• 集中式日誌管理
• 資 匯流、錯誤等級警告
• ELK、EFK、Graylog、StackDriver
評估現況是否
適合進行導入
找到問題關
正確下刀
團隊全面啟動
平行開發與重構
自動化測試
減少人力需求
Helm 部署
快速無差錯
系統日誌整合
快速定位問題
升級與回滾
服務不斷線
升級回滾定位除錯無誤部署自動測試開發重構服務切割事前評估
STEP VII
⼀一次⼀一個避免問題蔓延
• 是否有升級相依性存在
• 制定升、降級步驟
• 要確定是否可以無痛回滾
• 記錄升級前後差異
• 逐步升級,避免瞬間故障蔓延
• 服務要做好 Connection Draining
• 確保使用者不會受到升級影響
• 透過服務探針檢測健康度
• 為什麼我們選擇導入 Kubernetes
• 持續整合、持續交付流水線說明
⼜又稱⼤大⼟土炮時代,⾃自幹各種功能
• 手動升級
• 升級很困難
• 難以管理 多服務
• 服務部署、擴展、HA 都是問題
• 花時間重造輪子
透過⼯工具初步改善部署
• 組態管理系統 (CMS) 現身
• 利用工具協助系統升級,回滾稍嫌麻煩
• 仍然難以管理 多服務
• 服務擴展、HA 仍然是問題
• 程式跟執行環境是分開的
容器化、容器編排軟體⼤大量量現⾝身
• Docker 現身
• Immutable Image
• 程式跟執行環境涵括在映像 內
• Kubernetes 內建強大功能,避免造輪
• 服務損壞自動嘗試修復
• 流量自動負載平衡
• 滾動升級與回滾
• 簡易服務探索
• 管理介面
• 容器跨機器溝通
• 自動伸縮擴展
• 可版控所有部署程式碼
• 資源控管
縮短迭代週期,提⾼高交付頻率
GCPContainer registryBare-metal
• Kubernetes 元件觀念、實際應用細節說明
• 基於 Kubernetes 上的微服務架構設計、維運、監控
關關難過,關關過
• 如何收集分散各地的日誌
• 服務怎麼根據需求切流量
• 流量過大該如何處理
• 服務過多導致使用者發出請求增加
• 如何把服務開在指定節點上
• …
架構說明
觀念念說明
• Pod 內容器生死與共,不會出現跨節點問題
• 一般容器拆離,Pod 則是部分聚合
• 共享相同 Network Namespace
• 內部以 127.0.0.1 相互溝通
• 善用 Port-forward 避免服務裸露
• 服務測試好幫手
• kubectl port-forward
• Pod 除錯
• kubectl logs -f -c
• 利用節點選擇器,擴展至適當位置
• .spec.nodeSelector
掌握 Lifecycle = 掌握升級不斷線
• 優雅結束提高可用性 [1]
• terminationGracePeriodSeconds
• postStart: 建議用 init container 取代
• preStop: graceful shutdown 關
• TERM: 告知 process 終止
• KILL: 強制中斷,工作須在此之前完成
[1] https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods
Sidecar Pattern 使⽤用
• Sidecar Pattern [1]
• 負責不包含在主應用的非核心功能
• 不改動主應用下增添新不同功能
• 服務重用性增加,符合微服務概念
• 靈活性提高
• 避免 Monolith Pod 出現
• 1*主應用 + N*輔應用
• 緊密溝通的容器擺放在一起
• 容器間沒有啟動先後順序
• 應用場景
• 異質環境接口 (平台抽象化)
• Remote Prxoy
• Logging
[1] https://docs.microsoft.com/en-us/azure/architecture/patterns/sidecar
利利⽤用節點選擇器,擴展⾄至適當位置
• 根據節點狀況賦予對應標籤
• disktype=ssd
• Pod 根據不同服務資源需求放到對應節點
• 應用場景
• 分配 Pod 到特定節點
[1] https://tachingchen.com/tw/blog/Kubernetes-Rolling-Update-with-Deployment/
觀念念說明
• 透過 Docker mount 將資料夾掛進去
• 資 分享與永久保存
• 考慮效能、服務特性選擇種類使用
• 種類
• emptyDir: 跟 Pod 同生死
• hostPath: 只存在該節點
• nfs: host 需支援 NFS 功能
• gitRepo: 適用 CI/CD
• secret: 存放 cert、acc/pwd 等
• 應用場景
• Distributed Log Collection
• File Sharing
• Sidecar Pattern
觀念念說明
• 邏輯上的一群 Pod 以及存取他們的規則
• Service 與 Pod 為鬆散耦合
• 服務抽象化
• 可透過 DNS 或環境變數取得服務資
• <svc>.<namespace>.svc.cluster.local
• 存取服務的 DNS A records
• 非 Pod IP,隱藏背後請求處理細節
• 底層實作利用 iptabels 做流量分散
• 網路延遲問題
• 請求可能會被送到不同 Pod、節點
• 長時間下來會是均 分散
• 除特別需求,否則不應該直接使用 Pod IP
• 利用 DNS 降低程式複雜度
• 高可用性、避免強耦合
• K8S 有內建服務探索功能
標籤組合,精密分流
• 過去要設定 LB 將流量分散,太過耗時
• 善用選擇器,精密控流
• 鬆散耦合 + 唯一標籤組合
• 提高粒度,不影響服務高可用性
• 應用場景
• 流量管控,可以隨時切分流量
• 簡易 A/B 測試
• 透過無頭 (Headless) 服務取得 IP
• 設定 clusterIP: None
• 應用場景
• 想避免跟 K8S 耦合過深
• 需要 Pod IP 來做特別使用 (高自由度)
• AKKA 用來作叢集探索
無頭服務,提⾼高應⽤用⾃自由度
• 方法一
• 創建 Service 不指定 selector
• 額外創建 Endpoint 來連線外部服務
• 方法二
• 透過 type: ExternalName 回傳 CNAME
• 應用場景
• Testbed 需要連線外部服務,又希望線上
環境跟測試環境一樣透過 Service 連線
進階應⽤用,連線非叢集內服務
探針實現服務探索,提⾼高應⽤用可⽤用性
• Readiness: 是否準備接受流量
• Liveness: 服務是否正常運作
• 三種檢測方式: CMD、HTTP、TCP
• kubectl describe pod <pod>
• 應用場景
• 避免 Service 把流量送到不健康 Pod
• 自動修復,提高可用性
[1] https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
觀念念說明
• Scale by cloning
• 在 Pod 之上更高層次的抽象化
• Pod 命名為隨機字串
• 降低人力需求與失誤
• 便利升級、Pod 數量確保、自我修復
• 提供各種強大功能
• 滾動升級 (Rolling Update)
• 回滾 (Rollback)
• 暫停/繼續升級
• 應用場景
• 適合無狀態服務使用
• 服務升級、回滾
觀念念說明 (cont.)
• 不要隨意改動 selector 的值
• 造成孤兒 RS, Pod 增加維運困擾
• 設定 Rolling Strategy,才支援滾動升級
• minReadySeconds
• maxSurge
• maxUnavailable
• 利用 ̶record 紀錄每次操作
• 使用 kubectl set image 更新 image,
確保操作歷史清楚易懂
• 設定 .spec.revisionHistoryLimit,保
留定量 revision 即可
[1] https://tachingchen.com/tw/blog/Kubernetes-Rolling-Update-with-Deployment/
觀念念說明
• 部署到每個符合節點選擇器的節點上
• 節點上同時間只會有一個 Daemonset Pod
• Pod 命名為隨機字串
• 根據節點特性自定義適合的標籤
• Daemonset 升級後
• v1.5 以前需手動刪除 Pod
• v1.6+ 有 rolling update 功能
• 應用場景
• 各節點的日誌收集
• 各節點服務探索 (非 K8S 的)
觀念念說明
• 穩定與有序
• 唯一的網路標識、持久化存
• 順序性擴展、刪除 (Optional)
• 須額外創建 Headless Service
• 會幫助創建 pv, pvc
• volume 跟 sts 生命週期為各自獨立
• Pod 被刪除重生後會自動掛載 volume
• 維持原本狀態 (不含記憶體狀態)
• 擴展出來的 Pod 名字為有序
• <sts>-<ordinal>
• <sts>-<ordinal>.<svc>.<namespace>
• 透過 Headless 服務去存取
• 應用場景
• 需要保持狀態的服務
• 需要有穩定的唯一網路標識
[1] http://www.itread01.com/articles/1498460227.html
觀念念說明
• 機密資 與容器解耦合
• 以 案形式掛載到 Pod 內
• 當 secret 有更新時會跟著自動更新
• Pod 需人為介入重啟或程式面要改動
• 以環境變數方式傳入 Pod
• 創建前須以 base64 將 data 編碼
• secret 其實不 secret
• 有權限使用 kubectl 的人都可以看到
• 每台上有執行 etcd 的節點都可以看到
• 針對機器須做好安全管控 (非常基本)
• 只掛載到需要使用的容器內
• 應用場景
• 將機密資 和容器映像 分離
• 統一的帳密管控
觀念念說明
• 非機密資 與容器解耦合
• 以 案形式掛載到 Pod 內
• 當 config 有更新時會跟著自動更新
• Pod 需人為介入重啟或程式面要改動
• 以環境變數方式傳入 Pod
• 以 Key-Value 形式創建無需 base64
• configmap 和 secret 一樣很赤裸
• 有權限使用 kubectl 的人都可以看到
• 每台上有執行 etcd 的節點都可以看到
• 針對機器須做好安全管控 (非常基本)
• 只掛載到需要使用的容器內
• 應用場景
• 將設定和容器映像 分離
• 集中式的設定管理
觀念念說明
• 依據 Pod 負載進行 Deployment 伸縮擴展
• Pod 需要做資源管控,以計算使用量
• 預設每 30s 做 utilization 計算
• HPA 採保守機制
• 開很快、關很慢
• 避免顛簸造成 Pod 重複開關
• 可搭配 GKE Cluster Autoscaler
• Pod 出現 Pending 狀態才會觸發
• 但是該怎麼做才能確保服務正常?
⼀一場價值⼗十六萬的課 (教訓)
• K8S 會將節點所有資源拿來開 Pod (危險)
• 每個節點 K8S 元件會佔去 0.2 0.5 core
• 服務穩定關
• 節點核心數約在 4 6 core 為佳
• 擴展快、元件資源佔比小
• 總節點負荷在六或七成為佳
• 保留資源給 Host 使用與突波
• 單一 Pod 資源不宜過多
• 難分配到其他節點 (容易 Pending)
• 以水平擴展為主要手段
• 面對穩定流量
• 高 Threshold
• 面對瞬間不穩定流量
• 低 Threshold,讓 HPA 容易被觸發
• HPA Demo
觀念念說明
• The Kubernetes Package Manager
• 將部署步驟文件 (YAML) 化
• 設定 + 部署 = 應用叢集
• 方便版控
• CI / CD 更方便
• 升級更方便
• Chart.yaml
• 描述整個部署包的基本資
• values.yaml
• 存放變數以供 templates 內做替換
• templates/*.yaml
• 實際部署的描述
常⽤用指令說明
• 從單體架構如何朝微服務架構邁進
第⼀一代
第⼆二代
第三代
• Helm Chart 練習
環境登入
• 登入帳號資 : https://goo.gl/qwTGmZ
• IP: 35.194.200.23
• Git: https://github.com/life1347/k8s-hands-on
動⼿手做 I
• User 可以透過 LoadBalancer Service 80 port 存取後端的網頁
• 將部署 寫成 Helm chart 以供重複驗證
• 可參考 Repo 內的
• k8s-components-example
• helm-demo
動⼿手做 II
動⼿手做 III
企業導入微服務實戰 - updated
選選看
• 現有的服務探索的服務 (比方說 Consul),都會保存本身狀態以確保服務出現異常後可以復原,請問針對
些需要保存狀態的服務,採用下面 種組合是較佳組合 ?
• Deployment + Persistent Disk
• Statefulset + emptyDir
• Daemonset + hostPath
• 盡量使用 Service IP 而不直接使用 Pod IP 的原因是?(複選)
• 避免將流量流到失敗的 Pod 上
• 速度相對比較快
• 可以分散流量
• 在單體架構漸趨複雜下,導入微服務架構可以解決 些問題?(複選)
• 擴展
• 老
• 交付期
• 資料一致性
企業導入微服務實戰 - updated
讀寫分離、分庫分表
• 讀寫分離
• 寫操作統一進入口
• 讀操作從其他 Replica 讀取
• 瞭解數據特性,效率與一致性權衡
• CAP 理論
• 最終一致性適合應付極大流量
• 臉書塗 牆
• 強一致性適合交易流程
• 銀行交易系統
讀寫分離、分庫分表
• 幾種處理數據的方式
• Service-side Sharding
• Client-side Consistency Hash
• Proxy
• Session Affinity

More Related Content

企業導入微服務實戰 - updated