Kubernetes 簡(jiǎn)介
Kubernetes 是什么?
Kubernetes 是一個(gè)可移植的、可擴(kuò)展的開(kāi)源平臺(tái),用于管理容器化的工作負(fù)載和服務(wù)蒿往,可促進(jìn)聲明式配置和自動(dòng)化。 Kubernetes 擁有一個(gè)龐大且快速增長(zhǎng)的生態(tài)系統(tǒng)湿弦。Kubernetes 的服務(wù)瓤漏、支持和工具廣泛可用。
Kubernetes 這個(gè)名字源于希臘語(yǔ)颊埃,意為“舵手”或“飛行員”蔬充。k8s 這個(gè)縮寫(xiě)是因?yàn)?k 和 s 之間有八個(gè)字符的關(guān)系。 Google 在 2014 年開(kāi)源了 Kubernetes 項(xiàng)目班利。Kubernetes 建立在 Google 在大規(guī)模運(yùn)行生產(chǎn)工作負(fù)載方面擁有十幾年的經(jīng)驗(yàn) 的基礎(chǔ)上饥漫,結(jié)合了社區(qū)中最好的想法和實(shí)踐。
Kubernetes能做什么?
利用 Kubernetes罗标,您能夠達(dá)到以下目標(biāo):
基于容器的應(yīng)用部署庸队、維護(hù)和滾動(dòng)升級(jí)积蜻。
更加充分地利用硬件,最大程度獲取運(yùn)行企業(yè)應(yīng)用所需的資源彻消。
有效管控應(yīng)用部署和更新竿拆,并實(shí)現(xiàn)自動(dòng)化操作。
掛載和增加存儲(chǔ)宾尚,用于運(yùn)行有狀態(tài)的應(yīng)用丙笋。
快速、按需擴(kuò)展容器化應(yīng)用及其資源煌贴。
對(duì)服務(wù)進(jìn)行聲明式管理御板,保證所部署的應(yīng)用始終按照部署的方式運(yùn)行。
利用自動(dòng)布局牛郑、自動(dòng)重啟怠肋、自動(dòng)復(fù)制以及自動(dòng)擴(kuò)展功能,對(duì)應(yīng)用實(shí)施狀況檢查和自我修復(fù)井濒。
插件機(jī)制保證擴(kuò)展性。
Kubernetes特性
-
服務(wù)發(fā)現(xiàn)和負(fù)載均衡
Kubernetes 可以使用 DNS 名稱(chēng)或自己的 IP 地址公開(kāi)容器列林,如果進(jìn)入容器的流量很大瑞你, Kubernetes 可以負(fù)載均衡并分配網(wǎng)絡(luò)流量,從而使部署穩(wěn)定希痴。
-
存儲(chǔ)編排
Kubernetes 允許你自動(dòng)掛載你選擇的存儲(chǔ)系統(tǒng)者甲,例如本地存儲(chǔ)、公共云提供商等砌创。
-
自動(dòng)部署和回滾
你可以使用 Kubernetes 描述已部署容器的所需狀態(tài)虏缸,它可以以受控的速率將實(shí)際狀態(tài) 更改為期望狀態(tài)。例如嫩实,你可以自動(dòng)化 Kubernetes 來(lái)為你的部署創(chuàng)建新容器刽辙, 刪除現(xiàn)有容器并將它們的所有資源用于新容器。
-
自動(dòng)完成裝箱計(jì)算
Kubernetes 允許你指定每個(gè)容器所需 CPU 和內(nèi)存(RAM)甲献。 當(dāng)容器指定了資源請(qǐng)求時(shí)宰缤,Kubernetes 可以做出更好的決策來(lái)管理容器的資源。
-
自我修復(fù)
Kubernetes 重新啟動(dòng)失敗的容器晃洒、替換容器慨灭、殺死不響應(yīng)用戶(hù)定義的 運(yùn)行狀況檢查的容器,并且在準(zhǔn)備好服務(wù)之前不將其通告給客戶(hù)端球及。
-
密鑰與配置管理
Kubernetes 允許你存儲(chǔ)和管理敏感信息氧骤,例如密碼、OAuth 令牌和 ssh 密鑰吃引。 你可以在不重建容器鏡像的情況下部署和更新密鑰和應(yīng)用程序配置筹陵,也無(wú)需在堆棧配置中暴露密鑰刽锤。
-
水平擴(kuò)縮
使用一個(gè)簡(jiǎn)單的命令、一個(gè) UI 或基于 CPU 使用情況自動(dòng)對(duì)應(yīng)用程序進(jìn)行擴(kuò)縮惶翻。
-
為擴(kuò)展性設(shè)計(jì)
無(wú)需更改上游源碼即可擴(kuò)展你的 Kubernetes 集群姑蓝。
Kubernetes架構(gòu)
Kubernetes 主要由以下幾個(gè)核心組件組成:
etcd 保存了整個(gè)集群的狀態(tài);
API Server 提供了資源操作的唯一入口吕粗,并提供認(rèn)證纺荧、授權(quán)、訪問(wèn)控制颅筋、API 注冊(cè)和發(fā)現(xiàn)等機(jī)制宙暇;
Controller Manager 負(fù)責(zé)維護(hù)集群的狀態(tài),比如故障檢測(cè)议泵、自動(dòng)擴(kuò)展占贫、滾動(dòng)更新等;
Scheduler 負(fù)責(zé)資源的調(diào)度先口,按照預(yù)定的調(diào)度策略將 Pod 調(diào)度到相應(yīng)的機(jī)器上型奥;
Kubelet 負(fù)責(zé)維護(hù)容器的生命周期,同時(shí)也負(fù)責(zé) Volume(CVI)和網(wǎng)絡(luò)(CNI)的管理碉京;
Container Runtime 負(fù)責(zé)鏡像管理以及 Pod 和容器的真正運(yùn)行(CRI)厢汹;
Kube-proxy 負(fù)責(zé)為 Service 提供 cluster 內(nèi)部的服務(wù)發(fā)現(xiàn)和負(fù)載均衡;
kubectl 用于通過(guò)命令行與 kube-apiserver 進(jìn)行交互谐宙,而對(duì)Kubernetes進(jìn)行操作烫葬,實(shí)現(xiàn)在集群中進(jìn)行各種資源的增刪改查等操作;
控制平面組件(Control Plane Components)
控制平面的組件對(duì)集群做出全局決策(比如調(diào)度)凡蜻,以及檢測(cè)和響應(yīng)集群事件(例如搭综,當(dāng)不滿(mǎn)足部署的 replicas 字段時(shí),啟動(dòng)新的 pod)划栓。
控制平面組件可以在集群中的任何節(jié)點(diǎn)上運(yùn)行兑巾。 然而,為了簡(jiǎn)單起見(jiàn)忠荞,設(shè)置腳本通常會(huì)在同一個(gè)計(jì)算機(jī)上啟動(dòng)所有控制平面組件闪朱, 并且不會(huì)在此計(jì)算機(jī)上運(yùn)行用戶(hù)容器。
kube-apiserver
API 服務(wù)器是 Kubernetes 控制面的組件钻洒, 該組件公開(kāi)了 Kubernetes API奋姿。 API 服務(wù)器是 Kubernetes 控制面的前端。
Kubernetes API 服務(wù)器的主要實(shí)現(xiàn)是 kube-apiserver素标。 kube-apiserver 設(shè)計(jì)上考慮了水平伸縮称诗,也就是說(shuō),它可通過(guò)部署多個(gè)實(shí)例進(jìn)行伸縮头遭。 你可以運(yùn)行 kube-apiserver 的多個(gè)實(shí)例寓免,并在這些實(shí)例之間平衡流量癣诱。
etcd
etcd 是兼具一致性和高可用性的鍵值數(shù)據(jù)庫(kù),可以作為保存 Kubernetes 所有集群數(shù)據(jù)的后臺(tái)數(shù)據(jù)庫(kù)袜香。
您的 Kubernetes 集群的 etcd 數(shù)據(jù)庫(kù)通常需要有個(gè)備份計(jì)劃撕予。
要了解 etcd 更深層次的信息,請(qǐng)參考 etcd 文檔蜈首。
kube-scheduler
控制平面組件实抡,負(fù)責(zé)監(jiān)視新創(chuàng)建的蜓席、未指定運(yùn)行節(jié)點(diǎn)(node)的 Pods纷责,選擇節(jié)點(diǎn)讓 Pod 在上面運(yùn)行。
調(diào)度決策考慮的因素包括單個(gè) Pod 和 Pod 集合的資源需求拧廊、硬件/軟件/策略約束踩寇、親和性和反親和性規(guī)范啄清、數(shù)據(jù)位置、工作負(fù)載間的干擾和最后時(shí)限俺孙。
如果Pod中指定了NodeName屬性辣卒,則無(wú)需Scheduler參與,Pod會(huì)直接被調(diào)度到NodeName指定的Node節(jié)點(diǎn)
kube-controller-manager
運(yùn)行控制器進(jìn)程的控制平面組件睛榄。
從邏輯上講荣茫,每個(gè)控制器都是一個(gè)單獨(dú)的進(jìn)程, 但是為了降低復(fù)雜性懈费,它們都被編譯到同一個(gè)可執(zhí)行文件计露,并在一個(gè)進(jìn)程中運(yùn)行博脑。
這些控制器包括:
節(jié)點(diǎn)控制器(Node Controller): 負(fù)責(zé)在節(jié)點(diǎn)出現(xiàn)故障時(shí)進(jìn)行通知和響應(yīng)
任務(wù)控制器(Job controller): 監(jiān)測(cè)代表一次性任務(wù)的 Job 對(duì)象憎乙,然后創(chuàng)建 Pods 來(lái)運(yùn)行這些任務(wù)直至完成
端點(diǎn)控制器(Endpoints Controller): 填充端點(diǎn)(Endpoints)對(duì)象(即加入 Service 與 Pod)
服務(wù)帳戶(hù)和令牌控制器(Service Account & Token Controllers): 為新的命名空間創(chuàng)建默認(rèn)帳戶(hù)和 API 訪問(wèn)令牌
kube-controller-manager 中的各種控制器:
Node 組件
節(jié)點(diǎn)組件在每個(gè)節(jié)點(diǎn)上運(yùn)行,維護(hù)運(yùn)行的 Pod 并提供 Kubernetes 運(yùn)行環(huán)境叉趣。
kubelet
每個(gè)Node節(jié)點(diǎn)上都運(yùn)行一個(gè) Kubelet 服務(wù)進(jìn)程泞边,默認(rèn)監(jiān)聽(tīng) 10250 端口,接收并執(zhí)行 Master 發(fā)來(lái)的指令疗杉,管理 Pod 及 Pod 中的容器阵谚。每個(gè) Kubelet 進(jìn)程會(huì)在 API Server 上注冊(cè)所在Node節(jié)點(diǎn)的信息,定期向 Master 節(jié)點(diǎn)匯報(bào)該節(jié)點(diǎn)的資源使用情況烟具,并通過(guò) cAdvisor 監(jiān)控節(jié)點(diǎn)和容器的資源梢什。
kube-proxy
kube-proxy 是集群中每個(gè)節(jié)點(diǎn)上運(yùn)行的網(wǎng)絡(luò)代理, 實(shí)現(xiàn) Kubernetes 服務(wù)(Service) 概念的一部分朝聋。
kube-proxy 維護(hù)節(jié)點(diǎn)上的網(wǎng)絡(luò)規(guī)則嗡午。這些網(wǎng)絡(luò)規(guī)則允許從集群內(nèi)部或外部的網(wǎng)絡(luò)會(huì)話(huà)與 Pod 進(jìn)行網(wǎng)絡(luò)通信。
如果操作系統(tǒng)提供了數(shù)據(jù)包過(guò)濾層并可用的話(huà)冀痕,kube-proxy 會(huì)通過(guò)它來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)規(guī)則荔睹。否則狸演, kube-proxy 僅轉(zhuǎn)發(fā)流量本身。
容器運(yùn)行時(shí)(Container Runtime)
容器運(yùn)行環(huán)境是負(fù)責(zé)運(yùn)行容器的軟件僻他。
Kubernetes 支持多個(gè)容器運(yùn)行環(huán)境: Docker宵距、 containerd、CRI-O 以及任何實(shí)現(xiàn) Kubernetes CRI (容器運(yùn)行環(huán)境接口)吨拗。
工作負(fù)載
Kubernetes 提供若干種內(nèi)置的工作負(fù)載資源满哪,可滿(mǎn)足不同業(yè)務(wù)場(chǎng)景的需要。
Pod
Kubernetes 使用 Pod 來(lái)管理容器丢胚,每個(gè) Pod 可以包含一個(gè)或多個(gè)緊密關(guān)聯(lián)的容器翩瓜。
Pod 是一組緊密關(guān)聯(lián)的容器集合,它們共享 IPC 和 Network namespace携龟,是 Kubernetes 調(diào)度的基本單位兔跌。Pod 內(nèi)的多個(gè)容器共享網(wǎng)絡(luò)和文件系統(tǒng),可以通過(guò)進(jìn)程間通信和文件共享這種簡(jiǎn)單高效的方式組合完成服務(wù)峡蟋。
Pod 定義
在 Kubernetes 中坟桅,所有對(duì)象都使用 manifest(yaml 或 json)來(lái)定義,比如一個(gè)簡(jiǎn)單的 nginx 服務(wù)可以定義為 nginx.yaml蕊蝗,它包含一個(gè)鏡像為 nginx 的容器:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Pod 的特征
包含多個(gè)共享 IPC 和 Network namespace 的容器仅乓,可直接通過(guò) localhost 通信
所有 Pod 內(nèi)容器都可以訪問(wèn)共享的 Volume,可以訪問(wèn)共享數(shù)據(jù)
無(wú)容錯(cuò)性:直接創(chuàng)建的 Pod 一旦被調(diào)度后就跟 Node 綁定蓬戚,即使 Node 掛掉也不會(huì)被重新調(diào)度(而是被自動(dòng)刪除)夸楣,因此推薦使用 Deployment、Daemonset 等控制器來(lái)容錯(cuò)
優(yōu)雅終止:Pod 刪除的時(shí)候先給其內(nèi)的進(jìn)程發(fā)送 SIGTERM子漩,等待一段時(shí)間(grace period)后才強(qiáng)制停止依然還在運(yùn)行的進(jìn)程
特權(quán)容器(通過(guò) SecurityContext 配置)具有改變系統(tǒng)配置的權(quán)限(在網(wǎng)絡(luò)插件中大量應(yīng)用)
Node
Node 是 Pod 真正運(yùn)行的主機(jī)豫喧,可以是物理機(jī),也可以是虛擬機(jī)幢泼。為了管理 Pod紧显,每個(gè) Node 節(jié)點(diǎn)上至少要運(yùn)行 container runtime(比如 docker 或者 rkt)、kubelet 和 kube-proxy 服務(wù)缕棵。
不像其他的資源(如 Pod 和 Namespace)孵班,Node 本質(zhì)上不是 Kubernetes 來(lái)創(chuàng)建的,Kubernetes 只是管理 Node 上的資源招驴。雖然可以通過(guò) Manifest 創(chuàng)建一個(gè) Node 對(duì)象(如下 yaml 所示)篙程,但 Kubernetes 也只是去檢查是否真的是有這么一個(gè) Node,如果檢查失敗别厘,也不會(huì)往上調(diào)度 Pod虱饿。
kind: Node
apiVersion: v1
metadata:
name: 10-240-79-157
labels:
name: my-first-k8s-node
Node 的狀態(tài)
每個(gè) Node 都包括以下?tīng)顟B(tài)信息:
地址:包括 hostname、外網(wǎng) IP 和內(nèi)網(wǎng) IP
條件(Condition):包括 OutOfDisk、Ready郭厌、MemoryPressure 和 DiskPressure
容量(Capacity):Node 上的可用資源袋倔,包括 CPU、內(nèi)存和 Pod 總數(shù)
基本信息(Info):包括內(nèi)核版本折柠、容器引擎版本宾娜、OS 類(lèi)型等
操作Node
# 查看 Node 列表
kubectl get nodes
# 查看指定 Node 概要信息
kubectl get node $NODENAME -owide
# 查看指定 Node 詳細(xì)信息
kubectl describe node $NODENAME
# 給 Node 打標(biāo)簽
kubectl label nodes node-01 disktype=ssd
# 刪除標(biāo)簽
kubectl label nodes node-01 disktype-
# 禁止調(diào)度
kubectl cordon $NODENAME
# 啟用調(diào)度
kubectl uncordon $NODENAME
Namespace
Namespace 是對(duì)一組資源和對(duì)象的抽象集合,比如可以用來(lái)將系統(tǒng)內(nèi)部的對(duì)象劃分為不同的項(xiàng)目組或用戶(hù)組扇售。常見(jiàn)的 pods, services, replication controllers 和 deployments 等都是屬于某一個(gè) namespace 的(默認(rèn)是 default)前塔,而 node, persistentVolumes 等則不屬于任何 namespace。
Namespace 常用來(lái)隔離不同的用戶(hù)承冰,比如 Kubernetes 自帶的服務(wù)一般運(yùn)行在 kube-system namespace 中华弓。
Namespace 操作
kubectl 可以通過(guò) --namespace 或者 -n 選項(xiàng)指定 namespace。如果不指定困乒,默認(rèn)為 default寂屏。查看操作下, 也可以通過(guò)設(shè)置 --all-namespace=true 來(lái)查看所有 namespace 下的資源。
查詢(xún)
$ kubectl get namespaces
NAME STATUS AGE
default Active 11d
kube-system Active 11d
創(chuàng)建
#(1) 命令行直接創(chuàng)建
$ kubectl create namespace new-namespace
#(2) 通過(guò)文件創(chuàng)建
$ cat my-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: new-namespace
$ kubectl create -f ./my-namespace.yaml
注意:命名空間名稱(chēng)滿(mǎn)足正則表達(dá)式 a-z0-9?, 最大長(zhǎng)度為 63 位
刪除
$ kubectl delete namespaces new-namespace
注意:
刪除一個(gè) namespace 會(huì)自動(dòng)刪除所有屬于該 namespace 的資源娜搂。
default 和 kube-system 命名空間不可刪除迁霎。
Replication Controller
ReplicationController 確保在任何時(shí)候都有特定數(shù)量的 Pod 副本處于運(yùn)行狀態(tài)。 換句話(huà)說(shuō)百宇,ReplicationController 確保一個(gè) Pod 或一組同類(lèi)的 Pod 總是可用的考廉。
當(dāng) Pod 數(shù)量過(guò)多時(shí),ReplicationController 會(huì)終止多余的 Pod携御。當(dāng) Pod 數(shù)量太少時(shí)昌粤,ReplicationController 將會(huì)啟動(dòng)新的 Pod。 與手動(dòng)創(chuàng)建的 Pod 不同啄刹,由 ReplicationController 創(chuàng)建的 Pod 在失敗涮坐、被刪除或被終止時(shí)會(huì)被自動(dòng)替換。 例如鸵膏,在中斷性維護(hù)(如內(nèi)核升級(jí))之后膊升,你的 Pod 會(huì)在節(jié)點(diǎn)上重新創(chuàng)建怎炊。 因此谭企,即使你的應(yīng)用程序只需要一個(gè) Pod,你也應(yīng)該使用 ReplicationController 創(chuàng)建 Pod评肆。 ReplicationController 類(lèi)似于進(jìn)程管理器债查,但是 ReplicationController 不是監(jiān)控單個(gè)節(jié)點(diǎn)上的單個(gè)進(jìn)程,而是監(jiān)控跨多個(gè)節(jié)點(diǎn)的多個(gè) Pod瓜挽。
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
確保Pod數(shù)量
彈性伸縮
ReplicationController 的替代方案
ReplicaSet 是下一代 ReplicationController盹廷, 支持新的基于集合的標(biāo)簽選擇算符。 它主要被 Deployment 用來(lái)作為一種編排 Pod 創(chuàng)建久橙、刪除及更新的機(jī)制俄占。 請(qǐng)注意管怠,我們推薦使用 Deployment 而不是直接使用 ReplicaSet,除非 你需要自定義更新編排或根本不需要更新缸榄。
Deployment 是一種更高級(jí)別的 API 對(duì)象渤弛, 它以類(lèi)似于 kubectl rolling-update 的方式更新其底層 ReplicaSet 及其 Pod。 如果你想要這種滾動(dòng)更新功能甚带,那么推薦使用 Deployment她肯,因?yàn)榕c kubectl rolling-update 不同, 它們是聲明式的鹰贵、服務(wù)端的晴氨,并且具有其它特性。
Deployment
Deployment 為 Pod 和 ReplicaSet 提供了一個(gè)聲明式定義 (declarative) 方法碉输,用來(lái)替代以前的 ReplicationController 來(lái)方便的管理應(yīng)用籽前。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:latest
name: container-0
resources: # 資源限制
limits:
cpu: 100m
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
imagePullSecrets:
- name: default-secret
操作 Deployment
# 創(chuàng)建 Deployment
$ kubectl create -f docs/user-guide/nginx-deployment.yaml --record
deployment "nginx-deployment" created
# 查看 Deployment
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deployment 3 0 0 0 1s
# 擴(kuò)容
$ kubectl scale deployment nginx-deployment --replicas 10
# 如果集群支持 horizontal pod autoscaling 的話(huà),還可以為 Deployment 設(shè)置自動(dòng)擴(kuò)展:
$ kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
# 更新鏡像也比較簡(jiǎn)單
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
# 回滾
$ kubectl rollout undo deployment/nginx-deployment
Deployment 的 典型應(yīng)用場(chǎng)景 包括:
定義 Deployment 來(lái)創(chuàng)建 Pod 和 ReplicaSet
滾動(dòng)升級(jí)和回滾應(yīng)用
擴(kuò)容和縮容
暫停和繼續(xù) Deployment
DaemonSet
DaemonSet 確保全部(或者某些)節(jié)點(diǎn)上運(yùn)行一個(gè) Pod 的副本敷钾。 當(dāng)有節(jié)點(diǎn)加入集群時(shí)聚假, 也會(huì)為他們新增一個(gè) Pod 。 當(dāng)有節(jié)點(diǎn)從集群移除時(shí)闰非,這些 Pod 也會(huì)被回收膘格。刪除 DaemonSet 將會(huì)刪除它創(chuàng)建的所有 Pod。
DaemonSet 的一些典型用法:
在每個(gè)節(jié)點(diǎn)上運(yùn)行集群守護(hù)進(jìn)程
在每個(gè)節(jié)點(diǎn)上運(yùn)行日志收集守護(hù)進(jìn)程
在每個(gè)節(jié)點(diǎn)上運(yùn)行監(jiān)控守護(hù)進(jìn)程
指定 Node 節(jié)點(diǎn)
DaemonSet 會(huì)忽略 Node 的 unschedulable 狀態(tài)财松,有兩種方式來(lái)指定 Pod 只運(yùn)行在指定的 Node 節(jié)點(diǎn)上:
nodeSelector:只調(diào)度到匹配指定 label 的 Node 上
nodeAffinity:功能更豐富的 Node 選擇器瘪贱,比如支持集合操作
podAffinity:調(diào)度到滿(mǎn)足條件的 Pod 所在的 Node 上
StatefulSet
StatefulSet 是為了解決有狀態(tài)服務(wù)的問(wèn)題(對(duì)應(yīng) Deployments 和 ReplicaSets 是為無(wú)狀態(tài)服務(wù)而設(shè)計(jì)),其應(yīng)用場(chǎng)景包括
穩(wěn)定的持久化存儲(chǔ)辆毡,即 Pod 重新調(diào)度后還是能訪問(wèn)到相同的持久化數(shù)據(jù)菜秦,基于 PVC 來(lái)實(shí)現(xiàn)
穩(wěn)定的網(wǎng)絡(luò)標(biāo)志,即 Pod 重新調(diào)度后其 PodName 和 HostName 不變舶掖,基于 Headless Service(即沒(méi)有 Cluster IP 的 Service)來(lái)實(shí)現(xiàn)
有序部署球昨,有序擴(kuò)展,即 Pod 是有順序的眨攘,在部署或者擴(kuò)展的時(shí)候要依據(jù)定義的順序依次依序進(jìn)行(即從 0 到 N-1主慰,在下一個(gè) Pod 運(yùn)行之前所有之前的 Pod 必須都是 Running 和 Ready 狀態(tài)),基于 init containers 來(lái)實(shí)現(xiàn)
有序收縮鲫售,有序刪除(即從 N-1 到 0)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # has to match .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # by default is 1
template:
metadata:
labels:
app: nginx # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi
Job
Job 負(fù)責(zé)批量處理短暫的一次性任務(wù) (short lived one-off tasks)共螺,即僅執(zhí)行一次的任務(wù),它保證批處理任務(wù)的一個(gè)或多個(gè) Pod 成功結(jié)束情竹。
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
CronJob
CronJob 即定時(shí)任務(wù)藐不,就類(lèi)似于 Linux 系統(tǒng)的 crontab,在指定的時(shí)間周期運(yùn)行指定的任務(wù)。
.spec.schedule 指定任務(wù)運(yùn)行周期雏蛮,格式同 Cron
.spec.jobTemplate 指定需要運(yùn)行的任務(wù)涎嚼,格式同 Job
.spec.startingDeadlineSeconds 指定任務(wù)開(kāi)始的截止期限
.spec.concurrencyPolicy 指定任務(wù)的并發(fā)策略,支持 Allow挑秉、Forbid 和 Replace 三個(gè)選項(xiàng)
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
負(fù)載均衡
Pod創(chuàng)建完成后铸抑,如何訪問(wèn)Pod呢?直接訪問(wèn)Pod會(huì)有如下幾個(gè)問(wèn)題:
Pod會(huì)隨時(shí)被Deployment這樣的控制器刪除重建衷模,那訪問(wèn)Pod的結(jié)果就會(huì)變得不可預(yù)知鹊汛。
Pod的IP地址是在Pod啟動(dòng)后才被分配,在啟動(dòng)前并不知道Pod的IP地址阱冶。
應(yīng)用往往都是由多個(gè)運(yùn)行相同鏡像的一組Pod組成刁憋,逐個(gè)訪問(wèn)Pod也變得不現(xiàn)實(shí)。
Service
Service 是應(yīng)用服務(wù)的抽象木蹬,通過(guò) labels 為應(yīng)用提供負(fù)載均衡和服務(wù)發(fā)現(xiàn)至耻。匹配 labels 的 Pod IP 和端口列表組成 endpoints,由 kube-proxy 負(fù)責(zé)將服務(wù) IP 負(fù)載均衡到這些 endpoints 上镊叁。
每個(gè) Service 都會(huì)自動(dòng)分配一個(gè) cluster IP(僅在集群內(nèi)部可訪問(wèn)的虛擬地址)和 DNS 名尘颓,其他容器可以通過(guò)該地址或 DNS 來(lái)訪問(wèn)服務(wù),而不需要了解后端容器的運(yùn)行晦譬。
apiVersion: v1
kind: Service
metadata:
name: nginx # Service的名稱(chēng)
spec:
selector: # Label Selector疤苹,選擇包含app=nginx標(biāo)簽的Pod
app: nginx
ports:
- name: service0
targetPort: 80 # Pod的端口
port: 8080 # Service對(duì)外暴露的端口
protocol: TCP # 轉(zhuǎn)發(fā)協(xié)議類(lèi)型,支持TCP和UDP
type: ClusterIP # Service的類(lèi)型
Pod敛腌、RC和Service的關(guān)系
Service的類(lèi)型
ClusterIP:默認(rèn)類(lèi)型卧土,僅僅使用一個(gè)集群內(nèi)部的IP地址,用于在集群內(nèi)部互相訪問(wèn)的場(chǎng)景像樊,通過(guò)ClusterIP訪問(wèn)Service尤莺。
NodePort:在集群內(nèi)部IP的基礎(chǔ)上,在集群的每一個(gè)節(jié)點(diǎn)的端口上開(kāi)放這個(gè)服務(wù)生棍,颤霎。你可以在任意<NodeIP>:NodePort地址上訪問(wèn)到這個(gè)服務(wù)。用于從集群外部訪問(wèn)的場(chǎng)景涂滴,通過(guò)節(jié)點(diǎn)上的端口訪問(wèn)Service友酱,詳細(xì)介紹請(qǐng)參見(jiàn)NodePort類(lèi)型的Service。
LoadBalancer:用于從集群外部訪問(wèn)的場(chǎng)景氢妈,其實(shí)是NodePort的擴(kuò)展粹污,通過(guò)一個(gè)特定的LoadBalancer訪問(wèn)Service段多,這個(gè)LoadBalancer將請(qǐng)求轉(zhuǎn)發(fā)到節(jié)點(diǎn)的NodePort首量,而外部只需要訪問(wèn)LoadBalancer,詳細(xì)介紹請(qǐng)參見(jiàn)LoadBalancer類(lèi)型的Service。
None:用于Pod間的互相發(fā)現(xiàn)加缘,這種類(lèi)型的Service又叫Headless Service鸭叙,詳細(xì)介紹請(qǐng)參見(jiàn)Headless Service。
Ingress
Ingress 是對(duì)集群中服務(wù)的外部訪問(wèn)進(jìn)行管理的 API 對(duì)象拣宏,典型的訪問(wèn)方式是 HTTP沈贝。Ingress 可以提供負(fù)載均衡、SSL 終結(jié)和基于名稱(chēng)的虛擬托管勋乾。Ingress 公開(kāi)了從集群外部到集群內(nèi)服務(wù)的 HTTP 和 HTTPS 路由宋下。 流量路由由 Ingress 資源上定義的規(guī)則控制。
下面是一個(gè)將所有流量都發(fā)送到同一 Service 的簡(jiǎn)單 Ingress 示例:
YAML 示例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80
Ingress 規(guī)則
每個(gè) HTTP 規(guī)則都包含以下信息:
可選的 host辑莫。在此示例中学歧,未指定 host,因此該規(guī)則適用于通過(guò)指定 IP 地址的所有入站 HTTP 通信各吨。 如果提供了 host(例如 foo.bar.com)枝笨,則 rules 適用于該 host。
路徑列表 paths(例如揭蜒,/testpath),每個(gè)路徑都有一個(gè)由 serviceName 和 servicePort 定義的關(guān)聯(lián)后端横浑。 在負(fù)載均衡器將流量定向到引用的服務(wù)之前,主機(jī)和路徑都必須匹配傳入請(qǐng)求的內(nèi)容屉更。
backend(后端)是 Service 文檔中所述的服務(wù)和端口名稱(chēng)的組合徙融。 與規(guī)則的 host 和 path 匹配的對(duì) Ingress 的 HTTP(和 HTTPS )請(qǐng)求將發(fā)送到列出的 backend。
通常在 Ingress 控制器中會(huì)配置 defaultBackend(默認(rèn)后端)瑰谜,以服務(wù)于任何不符合規(guī)約中 path 的請(qǐng)求张咳。
DefaultBackend
沒(méi)有 rules 的 Ingress 將所有流量發(fā)送到同一個(gè)默認(rèn)后端。 defaultBackend 通常是 Ingress 控制器 的配置選項(xiàng)似舵,而非在 Ingress 資源中指定脚猾。
如果 hosts 或 paths 都沒(méi)有與 Ingress 對(duì)象中的 HTTP 請(qǐng)求匹配,則流量將路由到默認(rèn)后端砚哗。
配置和存儲(chǔ)
ConfigMap
應(yīng)用程序的運(yùn)行可能會(huì)依賴(lài)一些配置龙助,而這些配置又是可能會(huì)隨著需求產(chǎn)生變化的,如果我們的應(yīng)用程序架構(gòu)不是應(yīng)用和配置分離的蛛芥,那么就會(huì)存在當(dāng)我們需要去修改某些配置項(xiàng)的屬性時(shí)需要重新構(gòu)建鏡像文件的窘境√崮瘢現(xiàn)在,ConfigMap 可以很好的幫助我們實(shí)現(xiàn)應(yīng)用和配置分離仅淑,避免因?yàn)樾薷呐渲庙?xiàng)而重新構(gòu)建鏡像称勋。
ConfigMap 是一種 API 對(duì)象,用來(lái)將非機(jī)密性的數(shù)據(jù)保存到鍵值對(duì)中涯竟。使用時(shí)赡鲜, Pods 可以將其用作環(huán)境變量空厌、命令行參數(shù)或者存儲(chǔ)卷中的配置文件。
注意:
ConfigMap 并不提供保密或者加密功能银酬。 如果你想存儲(chǔ)的數(shù)據(jù)是機(jī)密的嘲更,請(qǐng)使用 Secret, 或者使用其他第三方工具來(lái)保證你的數(shù)據(jù)的私密性揩瞪,而不是用 ConfigMap赋朦。
apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
# 類(lèi)屬性鍵;每一個(gè)鍵都映射到一個(gè)簡(jiǎn)單的值
player_initial_lives: "3"
ui_properties_file_name: "user-interface.properties"
# 類(lèi)文件鍵
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
你可以使用四種方式來(lái)使用 ConfigMap 配置 Pod 中的容器:
在容器命令和參數(shù)內(nèi)
容器的環(huán)境變量
在只讀卷里面添加一個(gè)文件李破,讓?xiě)?yīng)用來(lái)讀取
編寫(xiě)代碼在 Pod 中運(yùn)行宠哄,使用 Kubernetes API 來(lái)讀取 ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: alpine
command: ["sleep", "3600"]
env:
# 定義環(huán)境變量
- name: PLAYER_INITIAL_LIVES # 請(qǐng)注意這里和 ConfigMap 中的鍵名是不一樣的
valueFrom:
configMapKeyRef:
name: game-demo # 這個(gè)值來(lái)自 ConfigMap
key: player_initial_lives # 需要取值的鍵
- name: UI_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: game-demo
key: ui_properties_file_name
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
# 你可以在 Pod 級(jí)別設(shè)置卷,然后將其掛載到 Pod 內(nèi)的容器中
- name: config
configMap:
# 提供你想要掛載的 ConfigMap 的名字
name: game-demo
# 來(lái)自 ConfigMap 的一組鍵嗤攻,將被創(chuàng)建為文件
items:
- key: "game.properties"
path: "game.properties"
- key: "user-interface.properties"
path: "user-interface.properties"
ConfigMap 使用注意點(diǎn)
ConfigMap 文件大小限制:1MB(*ETCD要求)
Pod 只能引用相同 Namespace 中的ConfigMap
Pod 引用的 ConfigMap 不存在時(shí)琳拨,Pod 無(wú)法創(chuàng)建成功。即 Pod 創(chuàng)建前需要先創(chuàng)建好 ConfigMap
使用 envFrom 從 ConfigMap 來(lái)配置環(huán)境變量時(shí)屯曹,如果 ConfigMap 中的某些 key 被認(rèn)為無(wú)效(比如 key 名稱(chēng)中帶有數(shù)字)狱庇,該環(huán)境變量將不會(huì)注入容器,但是 Pod 可以正常創(chuàng)建
只有通過(guò) K8s API 創(chuàng)建的 Pod 才能使用 ConfigMap恶耽,其他方式創(chuàng)建的 Pod(如 Manifest 創(chuàng)建的 static pod)不能使用 ConfigMap
Secret
Secret 是在集群中用于存儲(chǔ)密碼密任、token等敏感信息用的資源對(duì)象。其中的敏感數(shù)據(jù)采用 base-64 編碼保存偷俭,相比存儲(chǔ)在明文的 ConfigMap 中更規(guī)范浪讳、更安全。
Kubernetes Secret 默認(rèn)情況下存儲(chǔ)為 base64-編碼的涌萤、非加密的字符串淹遵。 默認(rèn)情況下,能夠訪問(wèn) API 的任何人负溪,或者能夠訪問(wèn) Kubernetes 下層數(shù)據(jù)存儲(chǔ)(etcd) 的任何人都可以以明文形式讀取這些數(shù)據(jù)透揣。 為了能夠安全地使用 Secret,我們建議你(至少):
為 Secret 啟用靜態(tài)加密川抡;
啟用 或配置 RBAC 規(guī)則來(lái)限制對(duì) Secret 的讀寫(xiě)操作辐真。 要注意,任何被允許創(chuàng)建 Pod 的人都默認(rèn)地具有讀取 Secret 的權(quán)限崖堤。
apiVersion: v1
kind: Secret
metadata:
name: secret-sa-sample
annotations:
kubernetes.io/service-account.name: "sa-name"
type: kubernetes.io/service-account-token
data:
# 你可以像 Opaque Secret 一樣在這里添加額外的鍵/值偶對(duì)
extra: YmFyCg==
LocalVolume
本地?cái)?shù)據(jù)卷(Local Volume)代表一個(gè)本地存儲(chǔ)設(shè)備侍咱,比如磁盤(pán)、分區(qū)或者目錄等密幔。主要的應(yīng)用場(chǎng)景包括分布式存儲(chǔ)和數(shù)據(jù)庫(kù)等需要高性能和高可靠性的環(huán)境里楔脯。本地?cái)?shù)據(jù)卷同時(shí)支持塊設(shè)備和文件系統(tǒng),通過(guò) spec.local.path 指定胯甩;但對(duì)于文件系統(tǒng)來(lái)說(shuō)昧廷,kubernetes 并不會(huì)限制該目錄可以使用的存儲(chǔ)空間大小堪嫂。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- image: nginx
name: mynginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: html
volumes:
- name: html # 名稱(chēng)
hostPath: # 存儲(chǔ)類(lèi)型
path: /data # 物理節(jié)點(diǎn)上的真實(shí)路徑
type: Directory # 如果該路徑不存在講如何處理,Directory是要求目錄必須存在
PV麸粮、PVC和 StorageClass
參考:k8s之PV溉苛、PVC镜廉、StorageClass詳解
PV:PV描述的是持久化存儲(chǔ)卷弄诲,主要定義的是一個(gè)持久化存儲(chǔ)在宿主機(jī)上的目錄,比如一個(gè)NFS的掛載目錄娇唯。
PVC:PVC描述的是Pod所希望使用的持久化存儲(chǔ)的屬性齐遵,比如,Volume存儲(chǔ)的大小塔插、可讀寫(xiě)權(quán)限等等梗摇。
Kubernetes管理員設(shè)置好網(wǎng)絡(luò)存儲(chǔ)的類(lèi)型,提供對(duì)應(yīng)的PV描述符配置到Kubernetes想许,使用者需要存儲(chǔ)的時(shí)候只需要?jiǎng)?chuàng)建PVC伶授,然后在Pod中使用Volume關(guān)聯(lián)PVC,即可讓Pod使用到存儲(chǔ)資源流纹,它們之間的關(guān)系如下圖所示糜烹。
- StorageClass:PV和PVC方法雖然能實(shí)現(xiàn)屏蔽底層存儲(chǔ),但是PV創(chuàng)建比較復(fù)雜(可以看到PV中csi字段的配置很麻煩)漱凝,通常都是由集群管理員管理疮蹦,這非常不方便。Kubernetes解決這個(gè)問(wèn)題的方法是提供動(dòng)態(tài)配置PV的方法茸炒,可以自動(dòng)創(chuàng)PV愕乎。管理員可以部署PV配置器(provisioner),然后定義對(duì)應(yīng)的StorageClass壁公,這樣開(kāi)發(fā)者在創(chuàng)建PVC的時(shí)候就可以選擇需要?jiǎng)?chuàng)建存儲(chǔ)的類(lèi)型感论,PVC會(huì)把StorageClass傳遞給PV provisioner,由provisioner自動(dòng)創(chuàng)建PV紊册。
Pod 進(jìn)階
Pause Container
Pause容器笛粘,又叫Infra容器,它與用戶(hù)容器”捆綁“運(yùn)行在同一個(gè) Pod 中湿硝,最大的作用是維護(hù) Pod 網(wǎng)絡(luò)協(xié)議棧薪前。
Pause容器是一個(gè)非常小的鏡像点把,大概 700KB 左右颠印,是一個(gè)C語(yǔ)言寫(xiě)的末秃、永遠(yuǎn)處于“暫屠渡”狀態(tài)的容器身隐。由于有了這樣一個(gè) Pause Container 之后澡绩,其他所有容器都會(huì)通過(guò) Join Namespace 的方式加入到 Pause Container 的 Network Namespace 中锤灿。
所以說(shuō)一個(gè) Pod 里面的所有容器第股,它們看到的網(wǎng)絡(luò)視圖是完全一樣的。即:它們看到的網(wǎng)絡(luò)設(shè)備吼拥、IP地址倚聚、Mac地址等等,跟網(wǎng)絡(luò)相關(guān)的信息凿可,其實(shí)全是一份惑折,這一份都來(lái)自于 Pod 第一次創(chuàng)建的這個(gè) Infra container。這就是 Pod 解決網(wǎng)絡(luò)共享的一個(gè)解法枯跑。
它執(zhí)行另一個(gè)重要的功能——即它扮演 PID 1 的角色惨驶,并在子進(jìn)程成為孤兒進(jìn)程的時(shí)候通過(guò)調(diào)用 wait() 收割這些僵尸子進(jìn)程。這樣我們就不用擔(dān)心我們的 Pod 的 PID namespace 里會(huì)堆滿(mǎn)僵尸進(jìn)程了敛助。在 UNIX 系統(tǒng)中粗卜,PID 為 1 的進(jìn)程是 init 進(jìn)程,即所有進(jìn)程的父進(jìn)程纳击。init 進(jìn)程比較特殊续扔,它維護(hù)一張進(jìn)程表并且不斷地檢查其他進(jìn)程的狀態(tài)。init 進(jìn)程的其中一個(gè)作用是當(dāng)某個(gè)子進(jìn)程由于父進(jìn)程的錯(cuò)誤退出而變成了“孤兒進(jìn)程”焕数,便會(huì)被 init 進(jìn)程收養(yǎng)并在該進(jìn)程退出時(shí)回收資源纱昧。
Pause容器特點(diǎn)
鏡像非常小,目前在700KB左右
永遠(yuǎn)處于Pause(暫停)狀態(tài)
Pause容器功能
維護(hù) Pod 網(wǎng)絡(luò)協(xié)議棧百匆,實(shí)現(xiàn) Pod 中各容器共享網(wǎng)絡(luò)協(xié)議棧砌些。
扮演 PID 1 的角色,并在子進(jìn)程成為孤兒進(jìn)程的時(shí)候通過(guò)調(diào)用 wait() 收割這些僵尸子進(jìn)程加匈。
Init Container
Init Container是一種特殊容器存璃,在 Pod 內(nèi)的應(yīng)用容器啟動(dòng)之前運(yùn)行。Init Container就是用來(lái)做初始化工作的容器雕拼,可以是一個(gè)或者多個(gè)纵东,如果有多個(gè)的話(huà),這些容器會(huì)按定義的順序依次執(zhí)行啥寇,只有所有的Init Container執(zhí)行完后偎球,主容器才會(huì)被啟動(dòng)。我們知道一個(gè)Pod里面的所有容器是共享數(shù)據(jù)卷和網(wǎng)絡(luò)命名空間的辑甜,所以Init Container里面產(chǎn)生的數(shù)據(jù)可以被主容器使用到的衰絮。
Init Container 的應(yīng)用場(chǎng)景:
等待其他模塊Ready
做初始化配置
其它場(chǎng)景:如將 pod 注冊(cè)到一個(gè)中央數(shù)據(jù)庫(kù)、配置中心等
下面的例子定義了一個(gè)具有 2 個(gè) Init 容器的簡(jiǎn)單 Pod磷醋。 第一個(gè)等待 myservice 啟動(dòng)猫牡, 第二個(gè)等待 mydb 啟動(dòng)。 一旦這兩個(gè) Init容器 都啟動(dòng)完成邓线,Pod 將啟動(dòng) spec 節(jié)中的應(yīng)用容器淌友。
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
Pod Hook
Pod hook(鉤子)是由 Kubernetes 管理的 kubelet 發(fā)起的煌恢,當(dāng)容器中的進(jìn)程啟動(dòng)前或者容器中的進(jìn)程終止之前運(yùn)行,這是包含在容器的生命周期之中震庭」宓郑可以同時(shí)為 Pod 中的所有容器都配置 hook。
Hook 的類(lèi)型包括兩種:
exec:執(zhí)行一段命令
HTTP:發(fā)送 HTTP 請(qǐng)求器联。
參考下面的配置:
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler> /usr/share/message"]
preStop:
exec:
command: ["/usr/sbin/nginx","-s","quit"]
在容器創(chuàng)建之后二汛,容器的 Entrypoint 執(zhí)行之前,這時(shí)候 Pod 已經(jīng)被調(diào)度到某臺(tái) node 上主籍,被某個(gè) kubelet 管理了习贫,這時(shí)候 kubelet 會(huì)調(diào)用 postStart 操作逛球,該操作跟容器的啟動(dòng)命令是在同步執(zhí)行的千元,也就是說(shuō)在 postStart 操作執(zhí)行完成之前,kubelet 會(huì)鎖住容器颤绕,不讓?xiě)?yīng)用程序的進(jìn)程啟動(dòng)幸海,只有在 postStart 操作完成之后容器的狀態(tài)才會(huì)被設(shè)置成為 RUNNING。
如果 postStart 或者 preStop hook 失敗奥务,將會(huì)終止容器物独。
健康檢查
Pod的健康狀態(tài)由三類(lèi)探針來(lái)檢查:LivenessProbe、ReadinessProbe和 StartupProbe氯葬。
探針類(lèi)型
1. livenessProbe(存活探針)
表明容器是否正在運(yùn)行挡篓。
如果存活探測(cè)失敗,則 kubelet 會(huì)殺死容器帚称,并且容器將受到其 重啟策略的影響官研。
如果容器不提供存活探針,則默認(rèn)狀態(tài)為 Success闯睹。
2. readinessProbe(就緒探針)
表明容器是否可以正常接受請(qǐng)求戏羽。
如果就緒探測(cè)失敗,端點(diǎn)控制器將從與 Pod 匹配的所有 Service 的端點(diǎn)中刪除該 Pod 的 IP 地址楼吃。
初始延遲之前的就緒狀態(tài)默認(rèn)為 Failure始花。
如果容器不提供就緒探針,則默認(rèn)狀態(tài)為 Success孩锡。
3. startup probes(啟動(dòng)探針)
- 啟動(dòng)檢查機(jī)制酷宵,應(yīng)用一些啟動(dòng)緩慢的業(yè)務(wù),避免業(yè)務(wù)長(zhǎng)時(shí)間啟動(dòng)而被前面的探針kill掉
三種健康檢查方法
每種探測(cè)機(jī)制支持三種健康檢查方法躬窜,分別是命令行exec浇垦,httpGet和tcpSocket,其中exec通用性最強(qiáng)斩披,適用與大部分場(chǎng)景溜族,tcpSocket適用于TCP業(yè)務(wù)讹俊,httpGet適用于web業(yè)務(wù)。
exec 提供命令或shell的檢測(cè)煌抒,在容器中執(zhí)行命令檢查仍劈,返回碼為0健康,非0異常(風(fēng)險(xiǎn)提醒:由于exec探針與低版本systemd存在兼容性問(wèn)題寡壮,需要慎重使用贩疙,如需使用需咨詢(xún)Hulk同學(xué))
httpGet http協(xié)議探測(cè),在容器中發(fā)送http請(qǐng)求况既,根據(jù)http返回碼判斷業(yè)務(wù)健康情況
tcpSocket tcp協(xié)議探測(cè)这溅,向容器發(fā)送tcp建立連接,能建立則說(shuō)明正常
配置探針
Probe 有很多配置字段棒仍,可以使用這些字段精確的控制存活和就緒檢測(cè)的行為:
initialDelaySeconds:容器啟動(dòng)后要等待多少秒后存活和就緒探測(cè)器才被初始化悲靴,默認(rèn)是 0 秒,最小值是 0莫其。
periodSeconds:執(zhí)行探測(cè)的時(shí)間間隔(單位是秒)癞尚。默認(rèn)是 10 秒。最小值是 1乱陡。
timeoutSeconds:探測(cè)的超時(shí)后等待多少秒浇揩。默認(rèn)值是 1 秒。最小值是 1憨颠。
successThreshold:探測(cè)器在失敗后胳徽,被視為成功的最小連續(xù)成功數(shù)。默認(rèn)值是 1爽彤。 存活和啟動(dòng)探測(cè)的這個(gè)值必須是 1养盗。最小值是 1。
failureThreshold:當(dāng)探測(cè)失敗時(shí)淫茵,Kubernetes 的重試次數(shù)爪瓜。 存活探測(cè)情況下的放棄就意味著重新啟動(dòng)容器。 就緒探測(cè)情況下的放棄 Pod 會(huì)被打上未就緒的標(biāo)簽匙瘪。默認(rèn)值是 3铆铆。最小值是 1。
apiVersion: v1
kind: Pod
metadata:
name: exec-liveness-probe
annotations:
kubernetes.io/description: "exec-liveness-probe"
spec:
containers:
- name: exec-liveness-probe
image: centos:latest
imagePullPolicy: IfNotPresent
args: #容器啟動(dòng)命令丹喻,生命周期為30s
- /bin/sh
- -c
- touch /tmp/liveness-probe.log && sleep 10 && rm -f /tmp/liveness-probe.log && sleep 20
livenessProbe:
exec: #健康檢查機(jī)制薄货,通過(guò)ls -l /tmp/liveness-probe.log返回碼判斷容器的健康狀態(tài)
command:
- ls
- l
- /tmp/liveness-probe.log
initialDelaySeconds: 1
periodSeconds: 5
生命周期
Pod的狀態(tài)
階段 | 描述 |
---|---|
Pending | Pod 已被 Kubernetes 接受,但尚未創(chuàng)建一個(gè)或多個(gè)容器鏡像碍论。這包括被調(diào)度之前的時(shí)間以及通過(guò)網(wǎng)絡(luò)下載鏡像所花費(fèi)的時(shí)間谅猾,執(zhí)行需要一段時(shí)間。 |
Running | Pod 已經(jīng)被綁定到了一個(gè)節(jié)點(diǎn),所有容器已被創(chuàng)建税娜。至少一個(gè)容器正在運(yùn)行坐搔,或者正在啟動(dòng)或重新啟動(dòng)。 |
Succeeded | 所有容器成功終止敬矩,也不會(huì)重啟概行。 |
Failed | 所有容器終止,至少有一個(gè)容器以失敗方式終止弧岳。也就是說(shuō)凳忙,這個(gè)容器要么已非 0 狀態(tài)退出,要么被系統(tǒng)終止禽炬。 |
Unknown | 由于一些原因涧卵,Pod 的狀態(tài)無(wú)法獲取,通常是與 Pod 通信時(shí)出錯(cuò)導(dǎo)致的腹尖。 |
Pod的生命周期
配置 Pod
環(huán)境變量
環(huán)境變量為容器提供了一些重要的資源柳恐,包括容器和 Pod 的基本信息以及集群中服務(wù)的信息等:
(1) hostname
HOSTNAME 環(huán)境變量保存了該 Pod 的 hostname。
(2)容器和 Pod 的基本信息
Pod 的名字桐臊、命名空間胎撤、IP 以及容器的計(jì)算資源限制等可以以 Downward API 的方式獲取并存儲(chǔ)到環(huán)境變量中晓殊。
使用 Volume
Volume 可以為容器提供持久化存儲(chǔ)断凶,比如
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}
更多掛載存儲(chǔ)卷的方法參考 Volume。
RestartPolicy
支持三種 RestartPolicy
Always:當(dāng)容器失效時(shí)巫俺,由Kubelet自動(dòng)重啟該容器认烁。RestartPolicy的默認(rèn)值。
OnFailure:當(dāng)容器終止運(yùn)行且退出碼不為0時(shí)由Kubelet重啟介汹。
Never:無(wú)論何種情況下却嗡,Kubelet都不會(huì)重啟該容器。
注意嘹承,這里的重啟是指在 Pod 所在 Node 上面本地重啟窗价,并不會(huì)調(diào)度到其他 Node 上去。
鏡像拉取策略
支持三種 ImagePullPolicy
Always:不管本地鏡像是否存在都會(huì)去倉(cāng)庫(kù)進(jìn)行一次鏡像拉取叹卷。校驗(yàn)如果鏡像有變化則會(huì)覆蓋本地鏡像撼港,否則不會(huì)覆蓋。
Never:只是用本地鏡像骤竹,不會(huì)去倉(cāng)庫(kù)拉取鏡像帝牡,如果本地鏡像不存在則Pod運(yùn)行失敗。
IfNotPresent:只有本地鏡像不存在時(shí)蒙揣,才會(huì)去倉(cāng)庫(kù)拉取鏡像靶溜。ImagePullPolicy的默認(rèn)值。
注意:
默認(rèn)為 IfNotPresent,但 :latest 標(biāo)簽的鏡像默認(rèn)為 Always罩息。
拉取鏡像時(shí) docker 會(huì)進(jìn)行校驗(yàn)嗤详,如果鏡像中的 MD5 碼沒(méi)有變,則不會(huì)拉取鏡像數(shù)據(jù)瓷炮。
生產(chǎn)環(huán)境中應(yīng)該盡量避免使用 :latest 標(biāo)簽断楷,而開(kāi)發(fā)環(huán)境中可以借助 :latest 標(biāo)簽自動(dòng)拉取最新的鏡像。
資源限制
Kubernetes 通過(guò) cgroups 限制容器的 CPU 和內(nèi)存等計(jì)算資源崭别,包括 requests(請(qǐng)求冬筒,調(diào)度器保證調(diào)度到資源充足的 Node 上,如果無(wú)法滿(mǎn)足會(huì)調(diào)度失敗)和 limits(上限)等:
spec.containers[].resources.limits.cpu:CPU 上限茅主,可以短暫超過(guò)舞痰,容器也不會(huì)被停止
spec.containers[].resources.limits.memory:內(nèi)存上限,不可以超過(guò)诀姚;如果超過(guò)响牛,容器可能會(huì)被終止或調(diào)度到其他資源充足的機(jī)器上
spec.containers[].resources.limits.ephemeral-storage:臨時(shí)存儲(chǔ)(容器可寫(xiě)層、日志以及 EmptyDir 等)的上限赫段,超過(guò)后 Pod 會(huì)被驅(qū)逐
spec.containers[].resources.requests.cpu:CPU 請(qǐng)求呀打,也是調(diào)度 CPU 資源的依據(jù),可以超過(guò)
spec.containers[].resources.requests.memory:內(nèi)存請(qǐng)求糯笙,也是調(diào)度內(nèi)存資源的依據(jù)贬丛,可以超過(guò);但如果超過(guò)给涕,容器可能會(huì)在 Node 內(nèi)存不足時(shí)清理
spec.containers[].resources.requests.ephemeral-storage:臨時(shí)存儲(chǔ)(容器可寫(xiě)層豺憔、日志以及 EmptyDir 等)的請(qǐng)求,調(diào)度容器存儲(chǔ)的依據(jù)
比如 nginx 容器請(qǐng)求 30% 的 CPU 和 56MB 的內(nèi)存够庙,但限制最多只用 50% 的 CPU 和 128MB 的內(nèi)存:
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
requests:
cpu: "300m"
memory: "56Mi"
limits:
cpu: "500m"
memory: "128Mi"
注意
CPU 的單位是 CPU 個(gè)數(shù)恭应,可以用 millicpu (m) 表示少于 1 個(gè) CPU 的情況,如 500m = 500millicpu = 0.5cpu
內(nèi)存的單位則包括 E, P, T, G, M, K, Ei, Pi, Ti, Gi, Mi, Ki 等耘眨。
QoS
QoS是 Quality of Service 的縮寫(xiě)昼榛,即服務(wù)質(zhì)量。Kubernetes根據(jù)Pod中Containers Resource的request和limit的值來(lái)定義Pod的QoS Class剔难。其中胆屿,指定容器request,代表系統(tǒng)確保能夠提供的資源下限值钥飞。指定容器limit莺掠,代表系統(tǒng)允許提供的資源上限值。
QoS 主要分為Guaranteed读宙、Burstable 和 Best-Effort三類(lèi)彻秆,優(yōu)先級(jí)從高到低。
-
Guaranteed
對(duì)于 QoS 類(lèi)為 Guaranteed 的 Pod:
Pod 中的每個(gè)容器,包含初始化容器唇兑,必須指定內(nèi)存請(qǐng)求和內(nèi)存限制酒朵,并且兩者要相等。
Pod 中的每個(gè)容器扎附,包含初始化容器蔫耽,必須指定 CPU 請(qǐng)求和 CPU 限制,并且兩者要相等留夜。
-
Burstable
如果滿(mǎn)足下面條件匙铡,將會(huì)指定 Pod 的 QoS 類(lèi)為 Burstable:
Pod 不符合 Guaranteed QoS 類(lèi)的標(biāo)準(zhǔn)。
Pod 中至少一個(gè)容器具有內(nèi)存或 CPU 請(qǐng)求碍粥。
-
BestEffort
對(duì)于 QoS 類(lèi)為 BestEffort 的 Pod鳖眼,Pod 中的容器必須沒(méi)有設(shè)置內(nèi)存和 CPU 限制或請(qǐng)求。
調(diào)度控制
Pod調(diào)度策略除了系統(tǒng)默認(rèn)的kube-scheduler調(diào)度器外還有以下幾種實(shí)現(xiàn)方式:
nodeName(直接指定Node主機(jī)名)
nodeSelector (節(jié)點(diǎn)選擇器嚼摩,為Node打上標(biāo)簽钦讳,然后Pod中通過(guò)nodeSelector選擇打上標(biāo)簽的Node)
污點(diǎn)taint與容忍度tolerations
NodeAffinity 節(jié)點(diǎn)親和性
PodAffinity Pod親和性
PodAntAffinity Pod反親和性
更多信息參考:https://cloud.tencent.com/developer/article/1644857
NodeName
NodeNamed這種調(diào)度方式比較簡(jiǎn)單,我們可以指定Pod在哪臺(tái)Node上進(jìn)行運(yùn)行枕面,通過(guò)spec.nodeName參數(shù)來(lái)指定Node主機(jī)名稱(chēng)即可愿卒。
apiVersion: v1
kind: Pod
metadata:
name: nodename-pod
spec:
#指定該P(yáng)od運(yùn)行在k8s-node02節(jié)點(diǎn)上
nodeName: k8s-node02
containers:
- image: busybox:latest
name: nodename-containers
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
NodeSelector
NodeSelector用于將Pod調(diào)度到匹配Label的Node上,所以要先給node打上標(biāo)簽潮秘,然后在Pod配置清單中選擇指定Node的標(biāo)簽琼开。先給規(guī)劃node用途,然后打標(biāo)簽唇跨,例如將兩臺(tái)node劃分給不同團(tuán)隊(duì)使用:
首先給 Node 打上標(biāo)簽
kubectl label nodes node-01 team=development
然后在 pod 中指定 nodeSelector 為 team=development:
apiVersion: v1
kind: Pod
metadata:
name: nodeselector-pod
spec:
nodeSelector: #指定標(biāo)簽選擇器
team: development #label指定開(kāi)發(fā)團(tuán)隊(duì)的label
containers:
- image: busybox:latest
name: nodeselector-containers
command: [ "/bin/sh", "-c", "tail -f /etc/passwd" ]
NodeAffinity
NodeAffinity 目前支持兩種:requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution稠通,分別代表必須滿(mǎn)足條件和優(yōu)選條件。比如下面的例子代表調(diào)度到包含標(biāo)簽 kubernetes.io/e2e-az-name 并且值為 e2e-az1 或 e2e-az2 的 Node 上买猖,并且優(yōu)選還帶有標(biāo)簽 another-node-label-key=another-node-label-value 的 Node。
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: with-node-affinity
image: gcr.io/google_containers/pause:2.0
PodAffinity
PodAffinity 基于 Pod 的標(biāo)簽來(lái)選擇 Node滋尉,僅調(diào)度到滿(mǎn)足條件 Pod 所在的 Node 上玉控,支持 podAffinity 和 podAntiAffinity。這個(gè)功能比較繞狮惜,以下面的例子為例:
如果一個(gè) “Node 所在 Zone 中包含至少一個(gè)帶有 security=S1 標(biāo)簽且運(yùn)行中的 Pod”高诺,那么可以調(diào)度到該 Node
不調(diào)度到 “包含至少一個(gè)帶有 security=S2 標(biāo)簽且運(yùn)行中 Pod” 的 Node 上
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: failure-domain.beta.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: kubernetes.io/hostname
containers:
- name: with-pod-affinity
image: gcr.io/google_containers/pause:2.0
自定義資源
我們平時(shí)在部署一個(gè)簡(jiǎn)單的 Webserver 到 Kubernetes 集群中的時(shí)候,都需要先編寫(xiě)一個(gè) Deployment 的控制器碾篡,然后創(chuàng)建一個(gè) Service 對(duì)象虱而,通過(guò) Pod 的 label 標(biāo)簽進(jìn)行關(guān)聯(lián),最后通過(guò) Ingress 或者 type=NodePort 類(lèi)型的 Service 來(lái)暴露服務(wù)开泽,每次都需要這樣操作牡拇,是不是略顯麻煩,我們就可以創(chuàng)建一個(gè)自定義的資源對(duì)象,通過(guò)我們的 CRD 來(lái)描述我們要部署的應(yīng)用信息惠呼,比如鏡像导俘、服務(wù)端口、環(huán)境變量等等剔蹋,然后創(chuàng)建我們的自定義類(lèi)型的資源對(duì)象的時(shí)候旅薄,通過(guò)控制器去創(chuàng)建對(duì)應(yīng)的 Deployment 和 Service,是不是就方便很多了泣崩,相當(dāng)于我們用一個(gè)資源清單去描述了 Deployment 和 Service 要做的兩件事情少梁。
CRD
CRD(CustomResourceDefinition,自定義資源)是對(duì) Kubernetes API 的擴(kuò)展矫付,kubernetes 中的每個(gè)資源都是一個(gè) API 對(duì)象的集合猎莲,例如我們?cè)?YAML 文件里定義的那些 spec 都是對(duì) kubernetes 中的資源對(duì)象的定義,所有的自定義資源可以跟 kubernetes 中內(nèi)建的資源一樣使用 kubectl 操作技即。
創(chuàng)建 CRD
創(chuàng)建新的 CustomResourceDefinition(CRD)時(shí)著洼,Kubernetes API Server 會(huì)為您指定的每個(gè)版本創(chuàng)建新的 RESTful 資源路徑。CRD 可以是命名空間的而叼,也可以是集群范圍的身笤,可以在 CRD scope 字段中所指定。與現(xiàn)有的內(nèi)置對(duì)象一樣葵陵,刪除命名空間會(huì)刪除該命名空間中的所有自定義對(duì)象液荸。CustomResourceDefinition 本身是非命名空間的,可供所有命名空間使用脱篙。
參考下面的 CRD娇钱,將其配置保存在 resourcedefinition.yaml 文件中:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
# 名稱(chēng)必須符合下面的格式:<plural>.<group>
name: crontabs.stable.example.com
spec:
# REST API使用的組名稱(chēng):/apis/<group>/<version>
group: stable.example.com
# REST API使用的版本號(hào):/apis/<group>/<version>
versions:
- name: v1
# 可以通過(guò) served 來(lái)開(kāi)關(guān)每個(gè) version
served: true
# 有且僅有一個(gè) version 開(kāi)啟存儲(chǔ)
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
cronSpec:
type: string
image:
type: string
replicas:
type: integer
# Namespaced或Cluster
scope: Namespaced
names:
# URL中使用的復(fù)數(shù)名稱(chēng): /apis/<group>/<version>/<plural>
plural: crontabs
# CLI中使用的單數(shù)名稱(chēng)
singular: crontab
# CamelCased格式的單數(shù)類(lèi)型。在清單文件中使用
kind: CronTab
# CLI中使用的資源簡(jiǎn)稱(chēng)
shortNames:
- ct
創(chuàng)建該 CRD:
kubectl create -f resourcedefinition.yaml
創(chuàng)建自定義對(duì)象
創(chuàng)建 CustomResourceDefinition 對(duì)象后绊困,您可以創(chuàng)建自定義對(duì)象文搂。自定義對(duì)象可包含自定義字段。這些字段可以包含任意 JSON秤朗。在以下示例中煤蹭, cronSpec 和 image 自定義字段在自定義對(duì)象中設(shè)置 CronTab。CronTab 類(lèi)型來(lái)自您在上面創(chuàng)建的 CustomResourceDefinition 對(duì)象的規(guī)范取视。
如果您將以下 YAML 保存到 my-crontab.yaml:
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
name: my-new-cron-object
spec:
cronSpec: "* * * * */5"
image: my-awesome-cron-image
并創(chuàng)建它:
kubectl create -f my-crontab.yaml
然后硝皂,您可以使用 kubectl 管理 CronTab 對(duì)象。例如:
$ kubectl get crontab
NAME AGE
my-new-cron-object 6s
使用 kubectl 時(shí)作谭,資源名稱(chēng)不區(qū)分大小寫(xiě)稽物,您可以使用 CRD 中定義的單數(shù)或復(fù)數(shù)形式,以及任何短名稱(chēng)折欠。
您還可以查看原始 YAML 數(shù)據(jù):
kubectl get ct -o yaml
刪除CRD
刪除 CustomResourceDefinition 時(shí)贝或,服務(wù)器將刪除 RESTful API 端點(diǎn)并刪除存儲(chǔ)在其中的所有自定義對(duì)象吼过。
kubectl delete -f resourcedefinition.yaml
kubectl get crontabs
Error from server (NotFound): Unable to list "crontabs": the server could not find the requested resource (get crontabs.stable.example.com)
Operator
Kubernetes Operator 是一種封裝、部署和管理 Kubernetes 應(yīng)用的方法傀缩。我們使用 Kubernetes API(應(yīng)用編程接口)和 kubectl 工具在 Kubernetes 上部署并管理 Kubernetes 應(yīng)用那先。
Kubernetes Operator 是一種特定于應(yīng)用的控制器,可擴(kuò)展 Kubernetes API 的功能赡艰,來(lái)代表 Kubernetes 用戶(hù)創(chuàng)建售淡、配置和管理復(fù)雜應(yīng)用的實(shí)例。
Operator SDK
該項(xiàng)目是Operator Framework的一個(gè)組件慷垮,它是一個(gè)開(kāi)源工具包揖闸,以有效,自動(dòng)化和可擴(kuò)展的方式管理稱(chēng)為Operators的Kubernetes原生應(yīng)用程序料身。
Operator SDK是一個(gè)框架汤纸,旨在簡(jiǎn)化Operator的編寫(xiě),它提供如下功能:
高級(jí)API和抽象芹血,更直觀地編寫(xiě)操作邏輯
用于腳手架和代碼生成的工具贮泞,可以快速引導(dǎo)新項(xiàng)目
擴(kuò)展以涵蓋常見(jiàn)的操作員用例
安裝 Operator SDK
$ mkdir -p $GOPATH/src/github.com/operator-framework
$ cd $GOPATH/src/github.com/operator-framework
$ git clone https://github.com/operator-framework/operator-sdk
$ cd operator-sdk
$ git checkout master
$ make dep
$ make install
該過(guò)程需要幾分鐘,請(qǐng)耐心等待幔烛。確認(rèn) $GOPATH/bin/operator-sdk
文件位于您的 $PATH
目錄下啃擦。
創(chuàng)建項(xiàng)目
$ cd $GOPATH/src/github.com/<your-github-repo>/
$ operator-sdk new <operator-project-name> --api-version=<your-api-group>/<version> --kind=<custom-resource-kind>
$ cd <operator-project-name>
operator-project-name:創(chuàng)建的項(xiàng)目的名稱(chēng)
your-api-group:Kubernetes 自定義 API 的組名,一般用域名如 jimmysong.io
version:Kubernetes 自定義資源的 API 版本
custom-resource-kind:CRD 的名稱(chēng)
更多信息參考:Kubernetes Operator 快速入門(mén)教程
Helm
<u>Helm</u>是一個(gè) Kubernetes 應(yīng)用的包管理工具饿悬,用來(lái)管理 chart——預(yù)先配置好的安裝包資源令蛉,有點(diǎn)類(lèi)似于 Ubuntu 的 APT 和 CentOS 中的 YUM。2019 年 11 月 13 日狡恬,Helm 3 發(fā)布珠叔,2020 年 4 月 30 日,從 CNCF 中畢業(yè)弟劲。
Helm chart 是用來(lái)封裝 Kubernetes 原生應(yīng)用程序的 YAML 文件祷安,可以在你部署應(yīng)用的時(shí)候自定義應(yīng)用程序的一些 metadata,便與應(yīng)用程序的分發(fā)函卒。
Helm 和 chart 的主要作用是:
應(yīng)用程序封裝
版本管理
依賴(lài)檢查
便于應(yīng)用程序分發(fā)
下面是 Helm 的架構(gòu)圖辆憔。
更多信息參考:https://jimmysong.io/kubernetes-handbook/practice/helm.html
調(diào)試和運(yùn)維
kubectl
你可以使用 Kubectl 命令行工具管理 Kubernetes 集群。 kubectl 在 $HOME/.kube 目錄中查找一個(gè)名為 config 的配置文件报嵌。
語(yǔ)法
使用以下語(yǔ)法 kubectl 從終端窗口運(yùn)行命令:
kubectl [command] [TYPE] [NAME] [flags]
其中 command、TYPE熊榛、NAME 和 flags 分別是:
command:指定要對(duì)一個(gè)或多個(gè)資源執(zhí)行的操作锚国,例如 create、apply玄坦、get血筑、describe绘沉、delete。
-
TYPE:指定資源類(lèi)型豺总。資源類(lèi)型不區(qū)分大小寫(xiě)车伞, 可以指定單數(shù)、復(fù)數(shù)或縮寫(xiě)形式喻喳。例如另玖,以下命令輸出相同的結(jié)果:
kubectl get pod pod1 kubectl get pods pod1 kubectl get po pod1
-
NAME:指定資源的名稱(chēng)。名稱(chēng)區(qū)分大小寫(xiě)表伦。 如果省略名稱(chēng)谦去,則顯示所有資源的詳細(xì)信息 kubectl get pods。
在對(duì)多個(gè)資源執(zhí)行操作時(shí)蹦哼,你可以按類(lèi)型和名稱(chēng)指定每個(gè)資源鳄哭,或指定一個(gè)或多個(gè)文件:
flags: 指定可選的參數(shù)。例如纲熏,可以使用 -s 或 -server 參數(shù)指定 Kubernetes API 服務(wù)器的地址和端口妆丘。
kubectl命令
# 查看 pod 概要信息
kubectl get pod $POD_NAME -n $NAMESPACE -owide
# 查看 pod 詳細(xì)信息
kubectl describe pod $POD_NAME -n $NAMESPACE
# 查看 node 概要信息
kubectl get node $NODE_NAME -owide
# 查看 node 詳細(xì)信息
kubectl describe node $NODE_NAME
# dump 輸出 pod 的日志(stdout)
kubectl logs -f $POD_NAME -n $NAMESPACE
# dump 輸出 pod 中容器的日志(stdout,pod 中有多個(gè)容器的情況下使用)
kubectl logs -f $POD_NAME -c $CONTAINER_NAME
# 流式輸出 pod 的日志(stdout)
kubectl logs -f $POD_NAME -n $NAMESPACE
# 流式輸出 pod 中容器的日志(stdout局劲,pod 中有多個(gè)容器的情況下使用)
kubectl logs -f $POD_NAME -c $CONTAINER_NAME
# 強(qiáng)制刪除 pod
kubectl delete pod $POD_NAME -n $NAMESPACE --force --grace-period=0
# 在已存在的容器中執(zhí)行命令(只有一個(gè)容器的情況下)
kubectl exec $POD_NAME -- ls /
# 在已存在的容器中執(zhí)行命令(pod 中有多個(gè)容器的情況下)
kubectl exec $POD_NAME -c $CONTAINER_NAME -- ls /
# 連接到運(yùn)行中的容器
kubectl attach $POD_NAME -i
# 顯示kubernetes 系統(tǒng)中最近的一些事件
kubectl get events
Docker
操作容器
# 啟動(dòng)容器并啟動(dòng)bash(交互方式):
docker run -i -t <image_name/continar_id> /bin/bash
# 啟動(dòng)容器以后臺(tái)方式運(yùn)行(更通用的方式):
$docker run -d -it image_name
# ps:這里的 image_name 包含了tag:hello.demo.kdemo:v1.0
# 附著到容器
# 附著到正在運(yùn)行的容器
docker attach <id勺拣、container_name>
# 進(jìn)入正在運(yùn)行的容器內(nèi)部,同時(shí)運(yùn)行bash(比attach更好用)
docker exec -t -i <id/container_name> /bin/bash
# 查看容器日志
docker logs <id/container_name>
# 實(shí)時(shí)查看日志輸出
docker logs -f <id/container_name> (類(lèi)似 tail -f) (帶上時(shí)間戳-t)
# 列出當(dāng)前所有正在運(yùn)行的container
docker ps
# 用一行列出所有正在運(yùn)行的container(容器多的時(shí)候非常清晰)
docker ps | less -S
# 列出所有的container
docker ps -a
# 列出最近一次啟動(dòng)的container
docker ps -l
# 顯示一個(gè)運(yùn)行的容器里面的進(jìn)程信息
docker top Name/ID
# 查看容器內(nèi)部詳情細(xì)節(jié):
docker inspect <id/container_name>
# 在容器中安裝新的程序
docker run image_name apt-get install -y app_name
ps:docker exec是如此的有用容握,以至于我們通常是將其封裝為一個(gè)腳本宣脉,放到全局可調(diào)用的地方,比如剔氏,可以寫(xiě)成一個(gè)indocker.sh:
$cat indocker.sh
docker exec -t -i $1 /bin/bash
# 查看需要附著的容器id
$docker ps | less -S
CONTAINER ID IMAGE
9cf7b563f689 hello.demo.kdemo:v160525.202747
$./indocker.sh 9cf7b563f689
操作鏡像
# 列出鏡像
docker images
# 下載image
docker pull image_name
# 刪除一個(gè)或者多個(gè)鏡像;
docker rmi image_name
# 顯示一個(gè)鏡像的歷史;
docker history image_name
# 發(fā)布docker鏡像
docker push new_image_name
# ps:要發(fā)布到私有Registry中的鏡像塑猖,在鏡像命名中需要帶上Registry的域名(如果非80端口,同時(shí)需要帶上端口號(hào))比如:
docker push dockerhub.yourdomain.com:443/hello.demo.kdemo:v1.0
# 拉取docker鏡像
docker pull image_name
常見(jiàn)問(wèn)題
下表中列舉了 Pod 的狀態(tài)信息:
狀態(tài) | 描述 |
---|---|
Error | Pod 啟動(dòng)過(guò)程中發(fā)生錯(cuò)誤谈跛。 |
NodeLost | Pod 所在節(jié)點(diǎn)失聯(lián)羊苟。 |
Unkown | Pod 所在節(jié)點(diǎn)失聯(lián)或其他未知異常苛白。 |
Waiting | Pod 等待啟動(dòng)垫桂。 |
Pending | Pod 等待被調(diào)度。 |
ContainerCreating | Pod 容器正在被創(chuàng)建锦担。 |
Terminating | Pod 正在被銷(xiāo)毀阻桅。 |
CrashLoopBackOff | 容器退出凉倚,Kubelet 正在將它重啟。 |
InvalidImageName | 無(wú)法解析鏡像名稱(chēng)嫂沉。 |
ImageInspectError | 無(wú)法校驗(yàn)鏡像稽寒。 |
ErrImageNeverPull | 策略禁止拉取鏡像。 |
ImagePullBackOff | 正在重試?yán) ?/td> |
RegistryUnavailable | 連接不到鏡像中心趟章。 |
ErrImagePull | 通用的拉取鏡像出錯(cuò)杏糙。 |
CreateContainerConfigError | 不能創(chuàng)建 Kubelet 使用的容器配置慎王。 |
CreateContainerError | 創(chuàng)建容器失敗。 |
RunContainerError | 啟動(dòng)容器失敗宏侍。 |
PreStartHookError | 執(zhí)行 preStart hook 報(bào)錯(cuò)赖淤。 |
PostStartHookError | 執(zhí)行 postStart hook 報(bào)錯(cuò)。 |
ContainersNotInitialized | 容器沒(méi)有初始化完畢谅河。 |
ContainersNotReady | 容器沒(méi)有準(zhǔn)備完畢咱旱。 |
ContainerCreating | 容器創(chuàng)建中。 |
PodInitializing | Pod 初始化中旧蛾。 |
DockerDaemonNotReady | Docker 還沒(méi)有完全啟動(dòng)莽龟。 |
NetworkPluginNotReady | 網(wǎng)絡(luò)插件還沒(méi)有完全啟動(dòng)。 |
K8S的10個(gè)常見(jiàn)失敗問(wèn)題的原因
Pod 一直處于 ContainerCreating 或 Waiting 狀態(tài)
Pod 一直處于 ImagePullBackOff 狀態(tài)
Pod 處于 CrashLoopBackOff 狀態(tài)