雲原生 (Cloud Native)
雲原生 (雲端 + 原生) 是在雲端原生架構上來規劃設計更方便擴展 (Scalable) 的軟體服務或應用。
為什麼會演變到雲原生 (Cloud Native)? 這跟軟體的開發、架構、運算和儲存單元演進有關
- 軟體開發: 瀑布式開發 -> 敏捷式開發 -> DevOps
- 軟體架構: 單層式架構 -> 多層式架構 -> 微服務
- 運算單元: 實體機 -> 虛擬機 -> 容器化
- 儲存單元: 資料中心 -> 服務代管 -> 雲端 (公有、私有、混合)
雲端原生常見架構和技術
- 微服務 (Microservice)
- 容器 (Container)
- 容器管理 (Kubernetes)
- 服務網格 (Service meshes)
- 不可變的基礎設施 (Immutable infrastructure)
- 聲明式 API (Declarative API)
Cloud Native Computing Foundation (CNCF) 定義了導入雲原生的主要五個步驟
- 容器化
- CI/CD
- 編排與應用定義,像是 HELM
- 可觀測性與分析,常見的像是普羅米修斯或是 Fluentd
- 服務代理、發現、網格 (Service Mesh)
微服務 (Microservice)
微服務其實就是將大型單體架構的服務,分別依照屬性或業務邏輯拆分部屬後的服務,透過雲端的架構可以更好的水平或垂直擴展並且進行迭代和更新。
部屬過後增加的複雜度是
- 更多服務間的溝通需要被連結
- 更多的服務生命週期需要被管理和監控
- 服務重啟的時候該怎麼做到 Zero Downtime
通常一個微服務用觀念的角度看,主要會包含 Service 跟 Job 兩個部分
- Service
- Non-Background Service: 不能死掉的服務
- Background Service: 像是監控之類的服務
- Job
- One Time Job: 服務起來之後需要執行的
- Cron Job: 定時執行
Service Cluster 的概念也蠻值得理解的,通常就是用來處理
- 增加高可用性 (High Availability) 或是備援,
- 拿來做附載平衡 (Load Balancing)
- 增加平行運算的處理量。
常見的 HA 模式,需考量多台機器怎麼互相知道對方狀態以及能自動啟動或停止,停止後怎麼恢復相關的資料。
- Active/Passive Mode (AP) 或是 Active/Standby Mode (AS): 用途是 HA 一台起著一台待命
- Active/Active Mode (AA): 用途是 Load Balancing 跟 AP 差別不大,問題是當 AA 有一台掛了之後只剩一台能不能撐住兩台的流量
容器 (Container)
微服務不一定需要容器實現,但容器相對於虛擬機較輕量也更方便去封裝和部屬。
容器是一個透過受設定檔建置出來的映象檔運行起來的服務
- Docker Container: Image 執行後會產生的執行環境
- Image: 透過 IaC (Infrastructure as Code) 來定義服務執行環境所建置出來的映象檔
- Repository: 存放 Image 的地方
PS: Jave EE Web 的容器是用來 deploy 各種 Web Application 用的,概念不太一樣
容器管理 (Kubernetes)
Kubernetes 是管理容器與服務的開源平台,主要分 Control Plane 跟 Worker Node 兩大塊,寫應用主要關注 Worker Node。
Control Plane
- kube-apiserver: 對外
- etcd: 紀錄狀態方便 failover
- kube-scheduler
- kube-controller-manager
- cloud-controller-manager
Worker Node
- kubelet
- kube-proxy
- container runntime
Worker Node 用層級來看
- Cluster: 多個 Node 的集合
- Node: 可以看成是某台 VM,Work Node 會負責把 Pod 跑起來
- Namespaces: 可以依照使用情境或產品別去分類及管理相關的 Deployment
- Deployment: 依照需求透過 ReplecaSet 描述 Pod 要開多少個怎麼去 Deploy
- Pod: 最小的 Deploy 單位,包含多個 container
- Container: Docker 的容器
- Pod: 最小的 Deploy 單位,包含多個 container
- Deployment: 依照需求透過 ReplecaSet 描述 Pod 要開多少個怎麼去 Deploy
- Namespaces: 可以依照使用情境或產品別去分類及管理相關的 Deployment
- Node: 可以看成是某台 VM,Work Node 會負責把 Pod 跑起來
在管理 Pod 上通常會透過 Deployment 來進行部屬 Deployment -> ReplicaSet -> Pod,除了 ReplicaSet 還有兩種部屬 Pod 的方法
- Deployment、ReplicaSet: 通常跟狀態無關
- statefulset: 像是資料庫服務需要一對一的關係就適合使用
- daemonset: 較偏系統面 (ex: 收 Log 的服務),寫 AP 的較不需要處理
一個 Kubernetes Components 主要包含 Pod 跟 Service 兩個部分
- Pod: 最小的 Deploy 單位,描述服務是怎麼構成和產生
- image
- port
- Service: 描述如何存取服務,Ingress -> Service -> Pod
- protocol
- port
- node port
- target port 會對應到 Pod 的 port
為什麼要使用 Kubernetes,相關的考量和優缺點有哪些?
原來可以跑的服務,放到 K8s 上不一定可以跑,維護上需思考服務設計是否適合放在 k8s 上,舉例來說 OOM 後會關掉並重啟,相關的機制該怎麼設計?
- K8s 維運相關設定: 要給多少 CPU、MEM 才可以避免 OOM 的問題
- Failover、debug: 服務並不會因為架在不同地方就變得更不穩定,但 k8s 因為多了一層會增加 debug 的難易度
- 升級或是修補漏洞: k8s 的 node 會需要常常更新,服務要怎麼做到 Zero Downtime
Kubernetes 的好處在於統一的管理介面,並且因為是 IaC 的關係,所有的人都無法像以前一樣直接 Access Node 意味著服務就會更加安全,操作並不會變簡單但會統一。
- 資料的備份與恢復: 方便程度代管服務 > K8s > VM
- 監控、觀測與警示: 方便程度代管服務 > K8s > VM,K8s 已有解決方案
成本上需要考量執行成本、維護成本、人力成本,要達到同樣的效能在各個環境 (VM、代管服務、K8s) 的成本會不一樣。
- 最佳化: 通常實體機或是 VM 的最佳化都比較簡單調整,K8s 較複雜
- 人力成本: 放 k8s 上維護知識需要理解服務、VM、k8s
服務網格 (Service meshes)
支持微服務之間通訊與溝通問題的一種技術,常見的解決方案為 Istio,微服務在啟動後都會透過服務代理 (Sidecar Proxy) 來處理。
有看到兩種名詞:
- Container Network Interface (CNI): 管理分配 Pod IP,管理相關連接網路的能力與限制
- Software Defined Networking (SDN): 軟體定義網路,用軟體去管理和維護網路相關的決策,舉例來說 Nginx 就是很好的附載平衡軟體定義網路代理,附載平衡這件事也可以用硬體做到。
不可變的基礎設施 (Immutable infrastructure)
當服務被部屬後就不可被修改,若有需要更新都需要透過 YAML 檔來更新 IaC (Infrastructure as Code),舉例來說透過 label 來建立 Deployment 和 Service 之間的連結後,需要注意的是 Label 不能修改名稱,所以會影響服務的維運方式。
聲明式 API (Declarative API)
告訴電腦該完成什麼,顯示的是結果,所以每次修改都是透過 kubectl apply YAML 來驅動相關的改變。
喜歡這篇文章,請幫忙拍拍手喔 🤣