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