一、背景
1.1 物理機(jī)時(shí)代、虛擬機(jī)時(shí)代、容器化時(shí)代
在介紹K8S之前,先來看看服務(wù)器的演變過程:物理機(jī)時(shí)代、虛擬機(jī)時(shí)代、容器化時(shí)代。
物理機(jī)時(shí)代的缺點(diǎn):
- 部署慢 :每臺(tái)服務(wù)器都要安裝操作系統(tǒng)、相關(guān)的應(yīng)用程序所需要的環(huán)境,各種配置
- 成本高:物理服務(wù)器的價(jià)格十分昂貴
- 資源浪費(fèi):硬件資源不能充分利用
- 擴(kuò)展和遷移成本高:擴(kuò)展和遷移需要重新配置一模一樣的環(huán)境

虛擬機(jī)時(shí)代很好的解決了物理機(jī)時(shí)代的缺點(diǎn),虛擬機(jī)時(shí)代的特點(diǎn)是:
- 易部署:每臺(tái)物理機(jī)可部署多臺(tái)虛擬機(jī),且可以通過模板,部署快,成本低
- 資源池:開出來的虛擬機(jī)可作為資源池備用,充分壓榨服務(wù)器性能
- 資源隔離:每個(gè)虛擬機(jī)都有獨(dú)立分配的內(nèi)存磁盤等硬件資源,虛擬機(jī)之間不會(huì)互相影響
- 易擴(kuò)展:隨時(shí)都能在一個(gè)物理機(jī)上創(chuàng)建或銷毀虛擬機(jī)
虛擬機(jī)的缺點(diǎn)是:每臺(tái)虛擬機(jī)都需要安裝操作系統(tǒng)

容器化時(shí)代解決了虛擬機(jī)時(shí)代的缺點(diǎn),容器化時(shí)代在繼承了虛擬機(jī)時(shí)代優(yōu)點(diǎn)的基礎(chǔ)之上,還有以下優(yōu)勢:
- 更高效的利用硬件資源:所有容器共享主機(jī)操作系統(tǒng)內(nèi)核,不需要安裝操作系統(tǒng)。
- 一致的運(yùn)行環(huán)境:相同的鏡像產(chǎn)生相同的行為
- 更?。狠^虛擬機(jī)而言,容器鏡像更小,因?yàn)椴恍枰虬僮飨到y(tǒng)
- 更快:容器能達(dá)到秒級(jí)啟動(dòng),其本質(zhì)是主機(jī)上的一個(gè)進(jìn)程

1.2 容器編排的需要
容器技術(shù)的代表就是docker,docker在單機(jī)上使用方便快捷,但在集群中表現(xiàn)如何呢?假設(shè)現(xiàn)在有5個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)中都裝有docker,現(xiàn)在要部署一個(gè)應(yīng)用,要求要10個(gè)副本,有如下做法:
- 在5個(gè)節(jié)點(diǎn)上隨機(jī)分配
- 平均分配,每臺(tái)節(jié)點(diǎn)分配2個(gè)
- 根據(jù)不同節(jié)點(diǎn)的負(fù)載狀態(tài)分配,負(fù)載低的優(yōu)先分配
無論選擇哪種方法都需要執(zhí)行相同docker run命令10遍,如果是最后一種做法還需要挨個(gè)檢查每個(gè)節(jié)點(diǎn)的負(fù)載,這種問題叫做不利于自動(dòng)裝箱。
如果以后增加了1個(gè)副本還需要再重復(fù)上面的動(dòng)作,如果增加10個(gè)呢?增加100個(gè)呢?人為去操作那就有點(diǎn)難受了,這種問題叫做不利于水平擴(kuò)容與縮容,簡稱水平擴(kuò)縮。
如果現(xiàn)在要變更版本,更新或者回滾,需要停止容器,然后替換新版本鏡像,再啟動(dòng),這樣的操作每個(gè)副本都要來一次,如果副本太多,簡直是噩夢,這種問題叫做不利于自動(dòng)化上線和回滾。
如果現(xiàn)在一個(gè)容器停止運(yùn)行了,docker的重啟策略會(huì)將它拉起來繼續(xù)運(yùn)行,這沒什么問題,如果節(jié)點(diǎn)宕機(jī)了呢?上面的所有容器都停止了,docker重啟策略就沒用了,這樣副本的數(shù)量就會(huì)減少,這個(gè)問題叫做不能自我修復(fù)。
假設(shè)需要負(fù)載均衡,那么得新增一個(gè)節(jié)點(diǎn)安裝負(fù)載均衡器,并且配置5個(gè)節(jié)點(diǎn)的IP和端口,前提是容器的端口要映射到主機(jī)端口,而且容器之前網(wǎng)絡(luò)是隔離的,不能相互訪問,維護(hù)成本高,這個(gè)問題叫不利于服務(wù)發(fā)現(xiàn)與負(fù)載均衡。
上面的這些操作,就是容器編排,既然存在如上問題,那么就需要一個(gè)技術(shù)進(jìn)行自動(dòng)化編排,這個(gè)技術(shù)就是K8S,K8S即kubernetes /kjub?’n?t?s/
Kubernetes,是一個(gè)工業(yè)級(jí)的容器編排平臺(tái)。Kubernetes 這個(gè)單詞是希臘語,它的中文翻譯是“舵手”或者“飛行員”。在一些常見的資料中也會(huì)看到“ks”這個(gè)詞,也就是“K8s”,它是通過將 8 個(gè)字母“ubernete ”替換為“8”而成為的一個(gè)縮寫。
K8S官網(wǎng):https://kubernetes.io/zh-cn/
根據(jù)官網(wǎng)描述,它有如下功能:
二、K8S架構(gòu)
在K8S中,由Master控制節(jié)點(diǎn)和Worker節(jié)點(diǎn)共同構(gòu)成一個(gè)集群,總體架構(gòu)如下圖所示:


- etcd:分布式KV數(shù)據(jù)庫,使用Raft協(xié)議,用于保存集群中的相關(guān)數(shù)據(jù),項(xiàng)目地址:https://github.com/etcd-io/etcd
- API Server:集群統(tǒng)一入口,以restful風(fēng)格進(jìn)行操作,同時(shí)交給etcd存儲(chǔ)(是唯一能訪問etcd的組件);提供認(rèn)證、授權(quán)、訪問控制、API注冊和發(fā)現(xiàn)等機(jī)制,可以通過kubectl命令行工具,dashboard可視化面板,或者sdk等訪問。
- Scheduler:節(jié)點(diǎn)的調(diào)度,選擇node節(jié)點(diǎn)應(yīng)用部署。
- Controller Manager:處理集群中常規(guī)后臺(tái)任務(wù),一個(gè)資源對(duì)應(yīng)一個(gè)控制器,同時(shí)監(jiān)控集群的狀態(tài),確保實(shí)際狀態(tài)和最終狀態(tài)一致。
2.2 Worker節(jié)點(diǎn)

- kubelet:相當(dāng)于Master派到node節(jié)點(diǎn)代表,管理本機(jī)容器,上報(bào)數(shù)據(jù)給API Server
- Container Runtime:容器運(yùn)行時(shí),K8S支持多個(gè)容器運(yùn)行環(huán)境:Docker、Containerd、CRI-O、Rktlet以及任何實(shí)現(xiàn)- Kubernetes CRI (容器運(yùn)行環(huán)境接口) 的軟件
- kube-proxy:實(shí)現(xiàn)服務(wù)(Service)抽象組件,屏蔽PodIP的變化和負(fù)載均衡
三、核心概念
3.1 Pod
- Pod是最小調(diào)度單元
- Pod里面會(huì)包含一個(gè)或多個(gè)容器(Container)
- Pod內(nèi)的容器共享存儲(chǔ)及網(wǎng)絡(luò),可通過localhost通信

Pod本意是豌豆莢的意思,此處指的是K8S中資源調(diào)度的最小單位,豌豆莢里面的小豆子就像是Container,豌豆莢本身就像是一個(gè)Pod。
3.2 Deployment
Deployment 是在 Pod 這個(gè)抽象上更為上層的一個(gè)抽象,它可以定義一組 Pod 的副本數(shù)目、以及這個(gè) Pod 的版本。一般大家用 Deployment 這個(gè)抽象來做應(yīng)用的真正的管理,而 Pod 是組成 Deployment 最小的單元。
- 定義一組Pod的副本數(shù)量,版本等
- 通過控制器維護(hù)Pod的數(shù)目
- 自動(dòng)恢復(fù)失敗的Pod
- 通過控制器以指定的策略控制版本

3.3 Service
Pod是不穩(wěn)定的,IP是會(huì)變化的,所以需要一層抽象來屏蔽這種變化,這層抽象叫做Service
- 提供訪問一個(gè)或者多個(gè)Pod實(shí)例穩(wěn)定的訪問地址
- 支持多種訪問方式ClusterIP(對(duì)集群內(nèi)部訪問)NodePort(對(duì)集群外部訪問)LoadBalancer(集群外部負(fù)載均衡)

3.4 Volume
Volume就是存儲(chǔ)卷,在Pod中可以聲明卷來問訪問文件系統(tǒng),同時(shí)Volume也是一個(gè)抽象層,其具體的后端存儲(chǔ)可以是本地存儲(chǔ)、NFS網(wǎng)絡(luò)存儲(chǔ)、云存儲(chǔ)(阿里云盤、AWS云盤、Google云盤等)、分布式存儲(chǔ)(比如說像 ceph、GlusterFS )
- 聲明在Pod中容器可以訪問的文件系統(tǒng)
- 可以被掛載在Pod中一個(gè)或多個(gè)容器的指定路徑下
- 支持多種后端儲(chǔ)存

3.5 Namespace
Namespace(命令空間)是用來做資源的邏輯隔離的,比如上面的Pod、Deployment、Service都屬于資源,不同Namespace下資源可以重名。同一Namespace下資源名需唯一
- 一個(gè)集群內(nèi)部的邏輯隔離機(jī)制(鑒權(quán)、資源等)
- 每個(gè)資源都屬于一個(gè)Namespace
- 同一個(gè)Namespace中資源命名唯一
- 不同Namespace中資源可重名

四、K8S安裝
具體的安裝教程可以參考:https://kuboard.cn/install/install-k8s.html
里面寫的很詳細(xì)了,此處不再贅述,簡化過程如下
- 創(chuàng)建虛擬機(jī),2個(gè)或者2個(gè)以上
- 操作系統(tǒng)為 CentOS 7.8 或者 CentOS Stream 8
- 每個(gè)節(jié)點(diǎn)CPU 內(nèi)核數(shù)量大于等于 2,且內(nèi)存大于等于 4G(實(shí)測2G也可以)
- 修改網(wǎng)絡(luò)配置文件:/etc/sysconfig/network-scripts/ifcfg-ens33 改成固定IP
- 安裝containerd/kubelet/kubeadm/kubectl,注意教程中使用的容器運(yùn)行時(shí)為containerd,如果需要使用docker,可以先安裝docker然后跳過腳本中安裝containerd的部分
- 初始化-master-節(jié)點(diǎn)
- 初始化-worker節(jié)點(diǎn)
- 驗(yàn)證:在Master節(jié)點(diǎn)上執(zhí)行kubectl get nodes -o wide,能看到添加的worker節(jié)點(diǎn)即安裝成功
我的環(huán)境情況如下:
NAME STATUS ROLES AGE VERSION INTERNAL-IP
my-master Ready control-plane,master 27h v1.21.0 192.168.108.101
my-node Ready <none> 27h v1.21.0 192.168.108.102
192.168.108.101是Master角色,名字為my-master;192.168.108.102是Worker角色,名字為my-node
五、kubectl常用命令
kubectl 則是 Kubernetes 的命令行工具,用于管理 Kubernetes 集群。
kubectl controls the Kubernetes cluster manager.
意為K8S集群管理的控制器,kubectl --help可以打印幫助命令。
(1)查看集群信息:
kubectl cluster-info # 顯示集群信息。
(2)查看資源狀態(tài):
kubectl get pods # 查看所有Pod的狀態(tài)
kubectl get deployments # 查看所有部署的狀態(tài)
kubectl get services # 查看所有服務(wù)的狀態(tài)
kubectl get nodes # 查看所有節(jié)點(diǎn)的狀態(tài)
kubectl get namespaces # 查看所有命名空間的狀態(tài)
kubectl describe pod <pod-name> # 顯示特定Pod的詳細(xì)信息
kubectl describe node <node-IP/name> # 顯示特定Node的詳細(xì)信息
(3)創(chuàng)建和管理資源:
kubectl create -f <filename> # 根據(jù)YAML文件創(chuàng)建資源
kubectl apply -f <filename> # 根據(jù)YAML文件創(chuàng)建或更新資源
kubectl delete -f <filename> # 根據(jù)YAML文件刪除資源
kubectl scale deployment <deployment-name> --replicas=<replica-count> # 擴(kuò)展或縮減部署的副本數(shù)
kubectl expose deployment <deployment-name> --port=<port> --type=<service-type> # 創(chuàng)建一個(gè)服務(wù)來公開部署
(4)執(zhí)行操作:
kubectl exec -it <pod-name> -- <command> # 在Pod中執(zhí)行特定命令
kubectl logs <pod-name> # 查看Pod的日志
kubectl port-forward <pod-name> <local-port>:<pod-port> # 將本地端口與Pod的端口進(jìn)行轉(zhuǎn)發(fā)
(5)刪除資源:
kubectl delete deployment <deployment-name> # 刪除部署
kubectl delete pod <pod-name> # 刪除Pod
kubectl delete service <service-name> # 刪除服務(wù)
六、K8S實(shí)戰(zhàn)
6.1 水平擴(kuò)容
為什么先實(shí)戰(zhàn)水平擴(kuò)容?因?yàn)檫@個(gè)最簡單,首先來部署一個(gè)喜聞樂見的nginx
kubectl create deployment web --image=nginx:1.14
這句話表示創(chuàng)建一個(gè)資源,啥資源呢?是一個(gè)deployment(可以簡寫為deploy),取名叫web,指定了鏡像為nginx的1.14版本,但是先別執(zhí)行這句話,我們一般不這么部署應(yīng)用,因?yàn)椴缓脧?fù)用,一般通過yaml文件來部署,如下:
kubectl create deployment web --image=nginx:1.14 --dry-run -o yaml > web.yaml
- –dry-run表示試運(yùn)行,試一下看行不行,但是不運(yùn)行
- -o yaml表示以yaml格式輸出
- web.yaml表示將輸出的內(nèi)容重定向到web.yaml文件中
執(zhí)行之后看看web.yaml文件里面有些什么:
apiVersion: apps/v1 # 表示資源版本號(hào)為apps/v1
kind: Deployment # 表示這是一個(gè)Deployment
metadata: # 一些元數(shù)據(jù)信息
creationTimestamp: null
labels: # 標(biāo)簽,可以隨便定義
app: web
name: web # 這個(gè)資源的名字
spec: # 資源的描述或者規(guī)格
replicas: 1 # 副本數(shù)量
selector: # 選擇器
matchLabels: # 需要匹配的標(biāo)簽
app: web # 標(biāo)簽的具體鍵值對(duì)
strategy: {}
template: # 模板。表示Pod的生成規(guī)則
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx:1.14 #指定鏡像文件
name: nginx
resources: {}
status: {}
用下面的命令應(yīng)用web.yaml,web.yaml聲明了一個(gè)Deployment和一個(gè)Pod
kubectl apply -f web.yaml
執(zhí)行完后以后可以通過以下命令查看Deployment和Pod:
kubectl get deploy,po -o wide
結(jié)果如下:
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/web 1/1 1 1 2m40s nginx nginx:1.14 app=web
NAME READY STATUS RESTARTS AGE IP NODE ...
pod/web-5bb6fd4c98-lg555 1/1 Running 0 2m40s 10.100.255.120 my-node ...
可以看到資源已經(jīng)建立起來了,運(yùn)行在Worker節(jié)點(diǎn)中,嘗試訪問一下Pod的IP:
curl 10.100.255.120
有如下nginx的標(biāo)準(zhǔn)返回說明應(yīng)用已經(jīng)部署完畢:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
</html>
有沒有感覺這一路下來挺麻煩的,yaml文件還那么長,還不如無腦docker run呢,別急,在后面擴(kuò)縮容的時(shí)候就可以看到它的威力了,當(dāng)然也可以用最開始的命令來執(zhí)行kubectl create deployment web --image=nginx:1.14,測試可以,在生產(chǎn)環(huán)境中強(qiáng)烈不建議這么做。
【擴(kuò)容實(shí)戰(zhàn)】:假設(shè)現(xiàn)在擴(kuò)容需求來了,需要部署同樣的nginx副本10個(gè),該怎么做?在K8S中很簡單,直接告訴K8S我要10個(gè)副本即可,其他的細(xì)節(jié)不用關(guān)心。
具體的做法是修改上面的web.yaml文件,將replicas: 1聲明成replicas: 10,最后再應(yīng)用一下
kubectl apply -f web.yaml
此時(shí)快速的執(zhí)行kubectl get po,可以看到一些容器已經(jīng)開始運(yùn)行了,一些在創(chuàng)建中,一些還在掛起:
NAME READY STATUS RESTARTS AGE
pod/web-5bb6fd4c98-52qmf 0/1 ContainerCreating 0 1s
pod/web-5bb6fd4c98-5sp5l 0/1 Pending 0 1s
pod/web-5bb6fd4c98-9t2hm 0/1 ContainerCreating 0 1s
pod/web-5bb6fd4c98-lg555 1/1 Running 0 11m
...
稍等片刻可以看到所有Pod都是Running狀態(tài)了!當(dāng)然也可以偷懶一鍵擴(kuò)容:
kubectl scale deploy web --replicas=10
6.2 自動(dòng)裝箱
根據(jù)資源需求和其他約束自動(dòng)放置容器,同時(shí)避免影響可用性。將關(guān)鍵性工作負(fù)載和盡力而為性質(zhì)的服務(wù)工作負(fù)載進(jìn)行混合放置,以提高資源利用率并節(jié)省更多資源。
K8S支持多種策略,包括:節(jié)點(diǎn)污點(diǎn)、節(jié)點(diǎn)標(biāo)簽、Pod調(diào)度策略等。目的是提供最大的靈活性,最終提高整體資源利用率,這就是自動(dòng)裝箱。
6.2.1 節(jié)點(diǎn)污點(diǎn)
Taint 污點(diǎn):節(jié)點(diǎn)不做普通分配調(diào)度,是節(jié)點(diǎn)屬性,屬性值有三個(gè)
- NoSchedule:一定不被調(diào)度
- PreferNoSchedule:盡量不被調(diào)度(也有被調(diào)度的幾率)
- NoExecute:不會(huì)調(diào)度,并且還會(huì)驅(qū)逐Node已有Pod
也就是說,給節(jié)點(diǎn)打上污點(diǎn),那么調(diào)度的時(shí)候就會(huì)根據(jù)上面的屬性來進(jìn)行調(diào)度,一般來說Master節(jié)點(diǎn)的污點(diǎn)值是NoSchedule,查看Master污點(diǎn)值
kubectl describe node my-master | grep Taints
可以看到如下輸出
Taints: node-role.kubernetes.io/master:NoSchedule
6.2.2 Pod調(diào)度策略
Pod調(diào)度策略會(huì)影響到Pod最終被調(diào)度到哪個(gè)節(jié)點(diǎn)上,Pod調(diào)度策略有三類
- Pod聲明的requests和limits,前者就是Pod需要多少資源,后者表示Pod最多用多少資源,資源比如CPU內(nèi)存等
- 節(jié)點(diǎn)標(biāo)簽選擇器,會(huì)選擇符合標(biāo)簽的節(jié)點(diǎn)進(jìn)行調(diào)度
- 節(jié)點(diǎn)親和性,分為硬親和和軟親和,前者必須滿足,后者嘗試滿足,不強(qiáng)制
6.3 Secret
Secret意為秘密,那在K8S中是啥意思呢?在K8S中表示一個(gè)存儲(chǔ)在etcd中的配置,這個(gè)配置是秘密的,是安全的,通常用Base64編碼,此配置可以通過掛載卷或者環(huán)境變量的方式供Pod訪問,首先定義一個(gè)Secret:
# 首先將明文轉(zhuǎn)換成base64編碼
echo -n 'root' | base64 # 結(jié)果是cm9vdA==
echo -n '123456' | base64 # 結(jié)果是MTIzNDU2
通過下面的secret.yaml聲明創(chuàng)建一個(gè)Secret,通過kubectl get secret可以查看剛才創(chuàng)建的Secret:
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: cm9vdA==
password: MTIzNDU2
6.3.1 掛載卷的方式
聲明文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
labels:
app: web
spec:
containers:
- image: nginx:1.14
name: nginx
# 掛載到容器內(nèi)
volumeMounts:
- name: secret-volume
mountPath: /etc/secret-volume
# 卷聲明
volumes:
- name: secret-volume
secret:
secretName: test-secret
status: {}
創(chuàng)建之后進(jìn)入容器,下面是進(jìn)入容器命令,和docker一致,你創(chuàng)建出來的Pod不一定是這個(gè)名web-66d9b4684b-dvwtm,根據(jù)實(shí)際情況進(jìn)入:
kubectl exec -it web-66d9b4684b-dvwtm bash
查看一下掛載的內(nèi)容:
cat /etc/secret-volume/username # 顯示root
cat /etc/secret-volume/password # 顯示123456
6.3.2 環(huán)境變量的方式
聲明文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
labels:
app: web
spec:
containers:
- image: nginx:1.14
name: nginx
# 環(huán)境變量聲明
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: test-secret
key: username
status: {}
執(zhí)行后再容器內(nèi)部查看該環(huán)境變量是否符合預(yù)期值,打印出來的值應(yīng)該是root,即我們設(shè)置的Secret
kubectl exec -it web-848bb777bc-x5mh4 -- /bin/sh -c 'echo $SECRET_USERNAME'
這里有一個(gè)疑問,既然是Base64的編碼方式(不是加密方式),為什么說Secret是安全的呢?此處的安全是K8S提供的,主要是以前幾點(diǎn):
- 傳輸安全(K8S中與API Server的交互都是HTTPS的)
- 存儲(chǔ)安全(Secret被掛載到容器時(shí)存儲(chǔ)在tmpfs中,只存在于內(nèi)存中而不是磁盤中,Pod銷毀Secret隨之消失)
- 訪問安全(Pod間的Secret是隔離的,一個(gè)Pod不能訪問另一個(gè)Pod的Secret)
6.4 ConfigMap
ConfigMap可以看做是不需要加密,不需要安全屬性的Secret,也是和配置相關(guān)的,創(chuàng)建ConfigMap的過程如下,首先創(chuàng)建一個(gè)配置文件,比如redis.properties,包含如下內(nèi)容
redis.port=127.0.0.1
redis.port=6379
redis.password=123456
以下命令從文件redis.properties創(chuàng)建了一個(gè)名為redis-config的ConfigMap
kubectl create configmap redis-config --from-file=redis.properties
使用命令kubectl get configmap可以查看剛才創(chuàng)建的ConfigMap,當(dāng)然ConfigMap也有掛載卷和設(shè)置環(huán)境變量的方式供Pod調(diào)用,此處不再贅述。
6.5 存儲(chǔ)編排
存儲(chǔ)編排可實(shí)現(xiàn)自動(dòng)掛載所選存儲(chǔ)系統(tǒng),包括本地存儲(chǔ)、諸如 GCP 或 AWS 之類公有云提供商所提供的存儲(chǔ)或者諸如 NFS、iSCSI、Gluster、Ceph、Cinder 或 Flocker 這類網(wǎng)絡(luò)存儲(chǔ)系統(tǒng)。
提到存儲(chǔ)就不得不說K8S中的PV和PVC了,解釋如下:
- PV:PersistentVolume,持久化卷
- PVC:PersistentVolumeClaim,持久化卷聲明
PV說白了就是一層存儲(chǔ)的抽象,底層的存儲(chǔ)可以是本地磁盤,也可以是網(wǎng)絡(luò)磁盤比如NFS、Ceph之類,既然有了PV那為什么又要搞一個(gè)PVC呢?
PVC其實(shí)在Pod和PV之前又增加了一層抽象,這樣做的目的在于將Pod的存儲(chǔ)行為于具體的存儲(chǔ)設(shè)備解耦,試想一下,假設(shè)哪天NFS網(wǎng)絡(luò)存儲(chǔ)的IP地址變化了,如果沒有PVC,就需要每個(gè)Pod都改一下IP的聲明,那得多累,有PVC來屏蔽這些細(xì)節(jié)之后只用改PV即可!
6.6 服務(wù)發(fā)現(xiàn)與負(fù)載均衡
服務(wù)發(fā)現(xiàn)與負(fù)載均衡可實(shí)現(xiàn):無需修改你的應(yīng)用程序即可使用陌生的服務(wù)發(fā)現(xiàn)機(jī)制。Kubernetes 為容器提供了自己的 IP 地址和一個(gè) DNS 名稱,并且可以在它們之間實(shí)現(xiàn)負(fù)載均衡。
到目前為止,我們的Pod已經(jīng)可以實(shí)現(xiàn)水平擴(kuò)縮、自動(dòng)裝箱、配置管理、存儲(chǔ)編排了,但是訪問還是個(gè)大問題,擴(kuò)容后這么多Pod應(yīng)該訪問哪一個(gè)?如果能夠自動(dòng)將流量分配到不同的Pod上(負(fù)載均衡);并且當(dāng)擴(kuò)容或者縮容的時(shí)候能夠動(dòng)態(tài)的將Pod添加或者剔除出負(fù)載均衡的范圍,簡而言之就是服務(wù)發(fā)現(xiàn)。
那么在K8S中有沒有東西可以做到服務(wù)發(fā)現(xiàn)和負(fù)載均衡呢?答案是有,這就是Service(還記得前面提到過的核心概念嗎),Service有三種類型:
- ClusterIp:集群內(nèi)部訪問(默認(rèn))
- NodePort:集群外部訪問(包含了ClusterIp)
- LoadBalancer:對(duì)外訪問應(yīng)用使用,公有云
6.7 自我修復(fù)
自我修復(fù)可實(shí)現(xiàn):重新啟動(dòng)失敗的容器,在節(jié)點(diǎn)死亡時(shí)替換并重新調(diào)度容器,殺死不響應(yīng)用戶定義的健康檢查的容器,并且在它們準(zhǔn)備好服務(wù)之前不會(huì)將它們公布給客戶端。
6.7.1 Pod重啟機(jī)制
當(dāng)Pod異常停止時(shí),就會(huì)觸發(fā)Pod的重啟機(jī)制,根據(jù)重啟策略會(huì)表現(xiàn)出不同的行為。
重啟策略主要分為以下三種
- Always:當(dāng)容器終止退出后,總是重啟容器,默認(rèn)策略
- OnFailure:當(dāng)容器異常退出(退出狀態(tài)碼非0)時(shí),才重啟
- Never:當(dāng)容器終止退出,從不重啟容器
6.7.2 Pod健康檢查
健康檢查顧名思義就是檢查Pod是否健康,怎么來定義健康呢?假設(shè)這么一種情況,當(dāng)程序內(nèi)部發(fā)生了錯(cuò)誤已經(jīng)不能對(duì)外提供服務(wù)了,但此時(shí)主程序仍在運(yùn)行,這種情況就是不健康的,或者當(dāng)容器主進(jìn)程已經(jīng)啟動(dòng)了,但是服務(wù)還沒有準(zhǔn)備好,這種情況也是不健康的,這就需要從應(yīng)用層面來檢查,K8S中定義了兩種檢查機(jī)制
- livenessProbe:存活檢查,如果檢查失敗,將殺死容器,根據(jù)Pod的restartPolicy來操作
- readinessProbe:就緒檢查,如果檢查失敗,Kubernetes會(huì)把Pod從Service endpoints中剔除,也就是讓客戶流量不打到readinessProbe檢查失敗的Pod上
具體的檢查方式支持三種文章來源:http://www.zghlxwxcb.cn/news/detail-702099.html
- http Get:發(fā)送HTTP請(qǐng)求,返回200 - 400 范圍狀態(tài)碼為成功
- exec:執(zhí)行Shell命令返回狀態(tài)碼是0為成功
- tcpSocket:發(fā)起TCP Socket建立成功
6.8 自動(dòng)化上線與回滾
Kubernetes 會(huì)分步驟地將針對(duì)應(yīng)用或其配置的更改上線,同時(shí)監(jiān)視應(yīng)用程序運(yùn)行狀況以確保你不會(huì)同時(shí)終止所有實(shí)例。如果出現(xiàn)問題,Kubernetes 會(huì)為你回滾所作更改。你應(yīng)該充分利用不斷成長的部署方案生態(tài)系統(tǒng)。文章來源地址http://www.zghlxwxcb.cn/news/detail-702099.html
參考資料
- K8S原理架構(gòu)與實(shí)戰(zhàn)(基礎(chǔ)篇)
到了這里,關(guān)于K8S原理架構(gòu)與實(shí)戰(zhàn)教程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!