當(dāng)我們的web應(yīng)用跑在容器中,如何擴(kuò)容汉柒?如何管理容器間的調(diào)用,負(fù)載均衡责鳍?自己手動新建nginx管理碾褂?自己手動改代碼完成?不用历葛。已經(jīng)有大牛為我們造好了輪子---Kubernetes正塌,它是一個(gè)容器控制平臺。
Kubernetes 通過一個(gè)簡單的 API 提供底層基礎(chǔ)設(shè)施的抽象恤溶,我們可以向該 API 發(fā)送請求乓诽。這些請求可以讓 Kubernetes 盡最大能力應(yīng)對。例如咒程,可以簡單地要求“Kubernetes 添加映像 x 的 4 個(gè)容器鸠天。”然后 Kubernetes 會找出使用中的節(jié)點(diǎn)帐姻,并在內(nèi)添加新的容器稠集。
這對開發(fā)人員來說意味著什么?意味著開發(fā)人員不需要在意節(jié)點(diǎn)的數(shù)目饥瓷,也不需要在意從哪里運(yùn)行容器以及如何與它們交流剥纷。開發(fā)人員不需要管理硬件優(yōu)化,或擔(dān)心節(jié)點(diǎn)關(guān)閉(它們將遵循墨菲法則)扛伍,因?yàn)樾碌墓?jié)點(diǎn)會添加到 Kubernetes 集群筷畦。同時(shí) Kubernetes 會在其他運(yùn)行的節(jié)點(diǎn)中添加容器。Kubernetes 會發(fā)揮最大的作用刺洒。
在圖中我們看到了一些新東西:
API服務(wù)器:與集群交互的唯一方式鳖宾。負(fù)責(zé)啟動或停止另外一個(gè)容器,或檢查當(dāng)前狀態(tài)逆航,日志等鼎文;
Kubelet:監(jiān)視節(jié)點(diǎn)內(nèi)的容器,并與主節(jié)點(diǎn)交流因俐;
Pod:初始階段我們可以把 pod 當(dāng)成容器拇惋。
Pod
Kubernetes 給我們最小的可部署計(jì)算單元 Pod 。它可以理解為一個(gè)邏輯宿主機(jī)抹剩,可以啟動一個(gè)或者多個(gè)容器撑帖,這些容器共享同一個(gè)端口空間,他們可以通過 localhost 交流澳眷,與其他 Pod 內(nèi)容器的交流可以通過結(jié)合 Pod 的 IP 完成胡嘿。
一個(gè) Pod 內(nèi)的容器共享同一個(gè)卷、同一個(gè) IP钳踊、端口空間衷敌、IPC 命名空間勿侯。
注:容器有個(gè)自己獨(dú)立的文件系統(tǒng),盡管他們可以通過 Kubernetes 的資源卷共享數(shù)據(jù)
pod.yaml文件編寫方式:
apiVersion: v1
kind: Pod
metadata:
name: sa-frontend
labels:
app: sa-frontend
spec:
containers:
- image: rinormaloku/sentiment-analysis-frontend
name: sa-frontend
ports:
- containerPort: 80
- kind:指定我們想創(chuàng)建的 Kubernetes 資源的類型缴罗。這里是 Pod助琐。
- name:定義該資源的名字。我們在這里命名為 sa-frontend面氓。
- spec:該對象定義了資源應(yīng)有的狀態(tài)兵钮。Pod Spec 中最重要的屬性是容器的數(shù)組。
- image:是指我們希望在本 Pod 中啟動的容器的映像侧但。
- name:Pod 中容器中唯一的名字矢空。
- containerPort:是指容器監(jiān)聽的端口號。
終端輸入
kubectl apply -f pod.yaml
創(chuàng)建pod
Service
Kubernetes 服務(wù)資源可以作為一組提供相同服務(wù)的 Pod 的入口禀横。這個(gè)資源肩負(fù)發(fā)現(xiàn)服務(wù)和平衡 Pod 之間負(fù)荷的重任屁药。
在 Kubernetes 集群內(nèi),我們擁有提供不同服務(wù)的 Pod(前端柏锄、Spring 網(wǎng)絡(luò)應(yīng)用和 Flask Python 應(yīng)用程序)酿箭。所以這里的問題是:服務(wù)如何知道該處理哪個(gè) Pod?例如:它如何生成這些 Pod 的終端列表趾娃?
這個(gè)問題可以用標(biāo)簽來解決缭嫡,具體分兩個(gè)步驟:
- 給所有服務(wù)處理的對象 Pod 貼上標(biāo)簽(label);
- 在服務(wù)中使用一個(gè)選擇器(selector)抬闷,該選擇器定義了所有貼有標(biāo)簽的對象 Pod妇蛀。
service.yaml文件編寫方式:
apiVersion: v1
kind: Service
metadata:
name: sa-frontend-lb
spec:
type: LoadBalancer
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: sa-frontend
- kind:服務(wù);
- type:指定類型笤成,我們選擇 LoadBalancer评架,因?yàn)槲覀兿肫胶?Pod 之間的負(fù)荷;
- ports:指定服務(wù)獲取請求的端口炕泳;
- protocol:定義交流纵诞;#5 targetPort:可以將來訪的請求轉(zhuǎn)發(fā)到這個(gè)端口;
- selector:包含選擇pod屬性的對象培遵;
- app:sa-frontend定義了哪個(gè)是目標(biāo) Pod浙芙,只有擁有標(biāo)簽“app: sa-frontend”的才是目標(biāo) Pod。
終端輸入
kubectl apply -f service.yaml
創(chuàng)建service
Deployment
Kubernetes 部署可以幫助每一個(gè)應(yīng)用程序的生命都保持相同的一點(diǎn):那就是變化籽腕。此外嗡呼,只有掛掉的應(yīng)用程序才會一塵不變,否則皇耗,新的需求會源源不斷地涌現(xiàn)晤锥,更多代碼會被開發(fā)出來、打包以及部署廊宪。這個(gè)過程中的每一步都有可能出錯(cuò)矾瘾。
部署資源可以自動化應(yīng)用程序從一版本升遷到另一版本的過程,并保證服務(wù)不間斷箭启,如果有意外發(fā)生壕翩,它可以讓我們迅速回滾到前一個(gè)版本。
現(xiàn)在我們有兩個(gè) Pod 和一個(gè)服務(wù)開放傅寡,而且它們之間有負(fù)載均衡放妈。我們提到過現(xiàn)有的 Pod 還遠(yuǎn)遠(yuǎn)不夠完美。需要分開管理每一個(gè) Pod(創(chuàng)建荐操、更新芜抒、刪除和監(jiān)視他們的情況)⊥衅簦快速更新和迅速回滾根本不可能宅倒!這樣是不行的,部署 Kubernetes 資源可以解決這里的每個(gè)問題屯耸。
deployment.yaml文件編寫方式:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sa-frontend
spec:
replicas: 2
minReadySeconds: 15
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: sa-frontend
spec:
containers:
- image: rinormaloku/sentiment-analysis-frontend
imagePullPolicy: Always
name: sa-frontend
ports:
- containerPort: 80
- kind:部署拐迁;
- replicas:是部署 Spec 對象的一個(gè)屬性,定義了我們想運(yùn)行多少的 Pod疗绣。所以是 2线召;
- type:指定從當(dāng)前版本升遷到下個(gè)版本的時(shí)候,部署使用的策略多矮。此處的策略 RollingUpdate 可以保證部署期間服務(wù)不間斷缓淹;
- maxUnavailable:是 RollingUpdate 對象的一個(gè)屬性,定義了在升級的時(shí)候塔逃,最大允許停止的 Pod 數(shù)量(與希望的狀態(tài)相比)讯壶。對我們的部署來說,我們有 2 個(gè)副本患雏,這意味著在一個(gè) Pod 停止后鹏溯,我們還會有另外一個(gè) Pod 運(yùn)行,所以可以保證應(yīng)用程序可訪問淹仑;
- maxSurge:是 RollingUpdate 對象的另一個(gè)屬性丙挽,定義了添加到部署的最大 Pod 數(shù)量(與希望的狀態(tài)相比)。對我們的部署來說匀借,這意味著在向新版本遷移的時(shí)候颜阐,我們可以加一個(gè) Pod,那么我們可以同時(shí)擁有個(gè) 3 個(gè) Pod吓肋;
- template:指定 Pod 的模板凳怨,部署在創(chuàng)建新 Pod 的時(shí)候,會用到該模板。很可能這個(gè)非常相似的 Pod 會立即吸引你肤舞;
- app: sa-frontend:根據(jù)模板創(chuàng)建的 Pod 將被貼上該標(biāo)簽紫新;
- imagePullPolicy:當(dāng)設(shè)置成 Always 的時(shí)候,每一次新部署都會重新獲取容器映像李剖。
終端輸入
kubectl apply -f deployment.yaml
創(chuàng)建deployment