本文轉發于【阿里云官方鏡像站:https://developer.aliyun.com/mirror/?utm_content=g_1000307095 】
原文鏈接:https://developer.aliyun.com/article/768471?spm=a2c6h.12873581.0.0.484f27845KWii0
Docker 雖好用,但面對強大的集群,成千上萬的容器,突然感覺不香了。
這時候就需要我們的主角 Kubernetes 上場了,先來了解一下 Kubernetes 的基本概念,后面再介紹實踐,由淺入深步步為營。
關于 Kubernetes 的基本概念我們將會圍繞如下七點展開:
一、Docker 的管理痛點
如果想要將 Docker 應用于龐大的業務實現,是存在困難的編排、管理和調度問題。于是,我們迫切需要一套管理系統,對 Docker 及容器進行更高級更靈活的管理。
Kubernetes 應運而生!Kubernetes,名詞源于希臘語,意為「舵手」或「飛行員」。Google 在 2014 年開源了 Kubernetes 項目,建立在 Google 在大規模運行生產工作負載方面擁有十幾年的經驗的基礎上,結合了社區中最好的想法和實踐。
K8s 是 Kubernetes 的縮寫,用 8 替代了 「ubernete」,下文我們將使用簡稱。
二、什么是 K8s ?
?K8s 是一個可移植的、可擴展的開源平臺,用于管理容器化的工作負載和服務,可促進聲明式配置和自動化。K8s 擁有一個龐大且快速增長的生態系統。K8s 的服務、支持和工具廣泛可用。
通過 K8s 我們可以:
快速部署應用
快速擴展應用
無縫對接新的應用功能
節省資源,優化硬件資源的使用
K8s 有如下特點:
可移植:支持公有云,私有云,混合云,多重云 multi-cloud
可擴展:模塊化,插件化,可掛載,可組合
自動化:自動部署,自動重啟,自動復制,自動伸縮/擴展
三、云架構 & 云原生
?
云和 K8s 是什么關系
云就是使用容器構建的一套服務集群網絡,云由很多的大量容器構成。K8s 就是用來管理云中的容器。
常見幾類云架構
On-Premises(本地部署)
IaaS(基礎設施即服務)
用戶:租用(購買|分配權限)云主機,用戶不需要考慮網絡,DNS,硬件環境方面的問題。
運營商:提供網絡,存儲,DNS,這樣服務就叫做基礎設施服務
PaaS(平臺即服務)
MySQL/ES/MQ/……
SaaS(軟件即服務)
釘釘
財務管理
Serverless
無服務,不需要服務器。站在用戶的角度考慮問題,用戶只需要使用云服務器即可,在云服務器所在的基礎環境,軟件環境都不需要用戶關心。
?可以預見:未來服務開發都是 Serverless,企業都構建了自己的私有云環境,或者是使用公有云環境。
云原生
為了讓應用程序(項目,服務軟件)都運行在云上的解決方案,這樣的方案叫做云原生。
云原生有如下特點:
容器化,所有服務都必須部署在容器中
微服務,Web 服務架構式服務架構
CI/CD
DevOps
?
四、K8s 架構原理
K8s 架構
概括來說 K8s 架構就是一個 Master 對應一群 Node 節點。
?下面我們來逐一介紹 K8s 架構圖中的 Master 和 Node。
Master 節點結構
apiserver 即 K8s 網關,所有的指令請求都必須要經過 apiserver;
scheduler 調度器,使用調度算法,把請求資源調度到某一個 Node 節點;
controller 控制器,維護 K8s 資源對象;
etcd 存儲資源對象;
Node節點
kubelet 在每一個 Node 節點都存在一份,在 Node 節點上的資源操作指令由 kubelet 來執行;
kube-proxy 代理服務,處理服務間負載均衡;
Pod 是 k8s 管理的基本單元(最小單元),Pod 內部是容器,k8s 不直接管理容器,而是管理 Pod;
Docker 運行容器的基礎環境,容器引擎;
Fluentd 日志收集服務;
在介紹完 K8s 架構后,我們又引入了很多技術名詞。不要著急,先有整體概念,再各個擊破。請耐心閱讀下文,相信你一定會有不一樣的收獲。
五、K8s 核心組件
K8s 組件
K8s 是用來管理容器,但是不直接操作容器,最小操作單元是 Pod (間接管理容器)。
一個 Master 有一群 Node 節點與之對應
Master 節點不存儲容器,只負責調度、網管、控制器、資源對象存儲
容器的存儲在 Node 節點,容器是存儲在 Pod 內部的)
Pod 內部可以有一個容器,或者多個容器
Kubelet 負責本地 Pod 的維護
Kube-proxy 負責負載均衡,在多個 Pod 之間來做負載均衡
Pod 是什么?
Pod 也是一個容器,這個容器中裝的是 Docker 創建的容器,Pod 用來封裝容器的一個容器,Pod 是一個虛擬化分組;
Pod 相當于獨立主機,可以封裝一個或者多個容器。
Pod 有自己的 IP 地址、主機名,相當于一臺獨立沙箱環境。
Pod 到底用來干什么?
通常情況下,在服務部署時候,使用 Pod 來管理一組相關的服務。一個 Pod 中要么部署一個服務,要么部署一組有關系的服務。
一組相關的服務是指:在鏈式調用的調用連路上的服務。
Web 服務集群如何實現?
實現服務集群:只需要復制多方 Pod 的副本即可,這也是 K8s 管理的先進之處,K8s 如果繼續擴容,只需要控制 Pod 的數量即可,縮容道理類似。
Pod 底層網絡,數據存儲是如何進行的?
Pod 內部容器創建之前,必須先創建 Pause 容器;
服務容器之間訪問 localhost ,相當于訪問本地服務一樣,性能非常高。
ReplicaSet 副本控制器
控制 Pod 副本「服務集群」的數量,永遠與預期設定的數量保持一致即可。當有 Pod 服務宕機時候,副本控制器將會立馬重新創建一個新的 Pod,永遠保證副本為設置數量。
副本控制器:標簽選擇器-選擇維護一組相關的服務(它自己的服務)。
selector:
app = web
Release = stable
ReplicationController 副本控制器:單選
ReplicaSet 副本控制器:單選,復合選擇
在新版的 K8s 中,建議使用 ReplicaSet 作為副本控制器,ReplicationController 不再使用了。
Deployment 部署對象
服務部署結構模型
滾動更新
ReplicaSet 副本控制器控制 Pod 副本的數量。但是,項目的需求在不斷迭代、不斷的更新,項目版本將會不停的的發版。版本的變化,如何做到服務更新?
部署模型:
ReplicaSet 不支持滾動更新,Deployment 對象支持滾動更新,通常和 ReplicaSet 一起使用;
Deployment 管理 ReplicaSet,RS 重新建立新的 RS,創建新的 Pod。
MySQL 使用容器化部署,存在什么樣的問題?
容器是生命周期的,一旦宕機,數據丟失
Pod 部署,Pod 有生命周期,數據丟失
對于 K8s 來說,不能使用 Deployment 部署有狀態服務。
通常情況下,Deployment 被用來部署無狀態服務,那么對于有狀態服務的部署,使用 StatefulSet 進行有狀態服務的部署。
什么是有狀態服務?
有實時的數據需要存儲
有狀態服務集群中,把某一個服務抽離出去,一段時間后再加入機器網絡,如果集群網絡無法使用
什么是無狀態服務?
沒有實時的數據需要存儲
無狀態服務集群中,把某一個服務抽離出去,一段時間后再加入機器網絡,對集群服務沒有任何影響
StatefulSet
為了解決有狀態服務使用容器化部署的一個問題。
部署模型
有狀態服務
StatefulSet 保證 Pod 重新建立后,Hostname 不會發生變化,Pod 就可以通過 Hostname 來關聯數據。
六、K8s 的服務注冊與發現
Pod 的結構是怎樣的?
Pod 相當于一個容器,Pod 有獨立 IP 地址,也有自己的 Hostname,利用 Namespace 進行資源隔離,獨立沙箱環境。
Pod 內部封裝的是容器,可以封裝一個,或者多個容器(通常是一組相關的容器)
Pod 網絡
Pod 有自己獨立的 IP 地址
Pod 內部容器之間訪問采用 Localhost 訪問
Pod 內部容器訪問是 Localhost,Pod 之間的通信屬于遠程訪問。
Pod 是如何對外提供服務訪問的?
Pod 是虛擬的資源對象(進程),沒有對應實體(物理機,物理網卡)與之對應,無法直接對外提供服務訪問。
那么該如何解決這個問題呢?
Pod 如果想要對外提供服務,必須綁定物理機端口。也就是說在物理機上開啟端口,讓這個端口和 Pod 的端口進行映射,這樣就可以通過物理機進行數據包的轉發。
概括來說:先通過物理機 IP + Port 進行訪問,再進行數據包轉發。
一組相關的 Pod 副本,如何實現訪問負載均衡?
我們先明確一個概念,Pod 是一個進程,是有生命周期的。宕機、版本更新,都會創建新的 Pod。這時候 IP 地址會發生變化,Hostname 會發生變化,使用 Nginx 做負載均衡就不太合適了。
所以我們需要依賴 Service 的能力。
Service 如何實現負載均衡?
簡單來說,Service 資源對象包括如下三部分:
Pod IP:Pod 的 IP 地址
Node IP:物理機 IP 地址
Cluster IP:虛擬 IP ,是由 K8s 抽象出的 Service 對象,這個 Service 對象就是一個 VIP 的資源對象
Service VIP 更深入原理探討
Service 和 Pod 都是一個進程,Service 也不能對外網提供服務;
Service 和 Pod 之間可以直接進行通信,它們的通信屬于局域網通信;
把請求交給 Service 后,Service 使用 iptable,ipvs 做數據包的分發。
Service 對象是如何和 Pod 進行關聯的?
不同的業務有不同的 Service;
Service 和 Pod 通過標簽選擇器進行關聯;
selector:
app=x 選擇一組訂單的服務 pod ,創建一個 service;
通過 endpoints 存放一組 pod ip;
Service 通過標簽選擇器選擇一組相關的副本,然后創建一個 Service。
Pod 宕機、發布新的版本的時候,Service 如何發現 Pod 已經發生了變化?
每個 Pod 中都有 Kube-Proxy,監聽所有 Pod。如果發現 Pod 有變化,就動態更新(etcd 中存儲)對應的 IP 映射關系。
七、關鍵問題
企業使用 K8s 主要用來做什么?
自動化運維平臺,創業型公司,中小型企業,使用 K8s 構建一套自動化運維平臺,自動維護服務數量,保持服務永遠和預期的數據保持一致性,讓服務可以永遠提供服務。這樣最直接的好處就是降本增效。
充分利用服務器資源,互聯網企業,有很多服務器資源「物理機」,為了充分利用服務器資源,使用 K8s 構建私有云環境,項目運行在云。這在大型互聯網公司尤為重要。
服務的無縫遷移,項目開發中,產品需求不停的迭代,更新產品。這就意味著項目不停的發布新的版本,而 K8s 可以實現項目從開發到生產無縫遷移。
K8s 服務的負載均衡是如何實現的?
Pod 中的容器很可能因為各種原因發生故障而死掉。Deployment 等 Controller 會通過動態創建和銷毀 Pod 來保證應用整體的健壯性。換句話說,Pod 是脆弱的,但應用是健壯的。每個 Pod 都有自己的 IP 地址。當 controller 用新 Pod 替代發生故障的 Pod 時,新 Pod 會分配到新的 IP 地址。
這樣就產生了一個問題:如果一組 Pod 對外提供服務(比如 HTTP),它們的 IP 很有可能發生變化,那么客戶端如何找到并訪問這個服務呢?
K8s 給出的解決方案是 Service。 Kubernetes Service 從邏輯上代表了一組 Pod,具體是哪些 Pod 則是由 Label 來挑選。
Service 有自己 IP,而且這個 IP 是不變的。客戶端只需要訪問 Service 的 IP,K8s 則負責建立和維護 Service 與 Pod 的映射關系。無論后端 Pod 如何變化,對客戶端不會有任何影響,因為 Service 沒有變。
無狀態服務一般使用什么方式進行部署?
Deployment 為 Pod 和 ReplicaSet 提供了一個 聲明式定義方法,通常被用來部署無狀態服務。
Deployment 的主要作用:
定義 Deployment 來創建 Pod 和 ReplicaSet 滾動升級和回滾應用擴容和索容暫停和繼續。Deployment不僅僅可以滾動更新,而且可以進行回滾,如果發現升級到 V2 版本后,服務不可用,可以迅速回滾到 V1 版本。
原文鏈接:https://developer.aliyun.com/article/768471?spm=a2c6h.12873581.0.0.484f27845KWii0
審核編輯:符乾江
評論
查看更多