1、Pod
1.1、Pod概述
Pod是K8S系統中可以建立和管理的最小單元,是資源對象模型中由使用者建立或部署的最小資源對象模型,也是在K8S上運作容器化應用的資源對象,其它的資源對象都是用來支撐或者擴充Pod對象功能的,比如控制器對象是用來管控Pod對象的,Service或者Ingress資源對象是用來暴露Pod引用對象的,PersistentVolume資源對象是用來為Pod提供存儲等等,K8S不會直接處理容器,而是Pod,Pod是由一個或多個container組成。
Pod是Kubernetes的最重要概念,每一個Pod都有一個特殊的被稱為 “根容器”的Pause容器。Pause容器對應的鏡像屬于Kubernetes平台的一部分,除了Pause容器,每個Pod還包含一個或多個緊密相關的使用者業務容器。
1.2、Pod基本概念
- 最小部署的單元
- Pod裡面是由一個或多個容器組成【一組容器的集合】
- 一個pod中的容器是共享網絡命名空間
- Pod是短暫的
- 每個Pod包含一個或多個緊密相關的使用者業務容器
2、Pod存在的意義
- 建立容器使用docker,一個docker對應一個容器,一個容器運作一個應用程序
- Pod是多程序設計,運用多個應用程式,也就是一個Pod裡面有多個容器,而一個容器裡面運作一個應用程式
- Pod的存在是為了親密性應用
- 兩個應用之間進行互動
- 網絡之間的調用【通過127.0.0.1 或 socket】
- 兩個應用之間需要頻繁調用
Pod是在K8S叢集中運作部署應用或服務的最小單元,它是可以支援多容器的。Pod的設計理念是支援多個容器在一個Pod中共享網絡位址和檔案系統,可以通過程序間通信和檔案共享這種簡單高效的方式組合完成服務。同時Pod對多容器的支援是K8S中最基礎的設計理念。在生産環境中,通常是由不同的團隊各自開發建構自己的容器鏡像,在部署的時候組合成一個微服務對外提供服務。
Pod是K8S叢集中所有業務類型的基礎,可以把Pod看作運作在K8S叢集上的小機器人,不同類型的業務就需要不同類型的小機器人去執行。目前K8S的業務主要可以分為以下幾種
- 長期伺服型:long-running
- 批處理型:batch
- 節點背景支撐型:node-daemon
- 有狀态應用型:stateful application
上述的幾種類型,分别對應的小機器人控制器為:Deployment、Job、DaemonSet 和 StatefulSet (後面将介紹控制器)
3、Pod實作機制
主要有以下兩大機制
- 共享網絡
- 共享存儲
3.1、共享網絡
容器本身之間互相隔離的,一般是通過 namespace 和 group 進行隔離,那麼Pod裡面的容器如何實作通信?
- 首先需要滿足前提條件,也就是容器都在同一個namespace之間
關于Pod實作原理,首先會在Pod會建立一個根容器: pause容器,然後我們在建立業務容器 【nginx,redis 等】,在我們建立業務容器的時候,會把它添加到 pause容器中(info容器 )中而在 info容器 中會獨立出 ip位址,mac位址,port 等資訊,然後實作網絡的共享
- 通過 Pause 容器,把其它業務容器加入到Pause容器裡,讓所有業務容器在同一個名稱空間中,可以實作網絡共享
3.2、共享存儲
Pod持久化資料,專門存儲到某個地方中
使用 Volumn資料卷進行共享存儲,案例如下所示
4、 Pod鏡像拉取政策
我們以具體執行個體來說,拉取政策就是 imagePullPolicy
拉取政策主要分為了以下幾種
- IfNotPresent:預設值,鏡像在主控端上不存在才拉取
- Always:每次建立Pod都會重新拉取一次鏡像
- Never:Pod永遠不會主動拉取這個鏡像
5、Pod資源限制
也就是我們Pod在進行排程的時候,可以對排程的資源進行限制,例如我們限制 Pod排程是使用的資源是 2核4G,那麼在排程對應的node節點時,隻會占用對應的資源,對于不滿足資源的節點,将不會進行排程
我們在下面的地方進行資源的限制,它本身就是用docker做到的,這裡分了兩個部分
- request:表示排程所需的資源
- limits:表示最大所占用的資
6、Pod重新開機機制
因為Pod中包含了很多個容器,假設某個容器出現問題了,那麼就會觸發Pod重新開機機制
重新開機政策主要分為以下三種
- Always:當容器終止退出後,總是重新開機容器,預設政策 【nginx等,需要不斷提供服務】
- OnFailure:當容器異常退出(退出狀态碼非0)時,才重新開機容器。
- Never:當容器終止退出,從不重新開機容器 【批量任務】
7、Pod健康檢查
通過容器檢查,原來我們使用下面的指令來檢查
kubectl get pod
但是有的時候,程式可能出現了 Java 堆記憶體溢出,程式還在運作,但是不能對外提供服務了,這個時候就不能通過 容器檢查來判斷服務是否可用了,這個時候就可以使用應用層面的檢查
# 存活檢查,如果檢查失敗,将殺死容器,根據Pod的restartPolicy【重新開機政策】來操作
livenessProbe
# 就緒檢查,如果檢查失敗,Kubernetes會把Pod從Service endpoints中剔除
readinessProbe
Probe支援以下三種檢查方式
- http Get:發送HTTP請求,傳回200 - 400 範圍狀态碼為成功
- exec:執行Shell指令傳回狀态碼是0為成功
- tcpSocket:發起TCP Socket建立成功
8、Pod排程政策
8.1、建立Pod流程
- 首先建立一個pod,然後建立一個API Server 和 Etcd【把建立出來的資訊存儲在etcd中】
- 然後建立 Scheduler,監控API Server是否有新的Pod,如果有的話,會通過排程算法,把pod排程某個node上
- 在node節點,會通過 kubelet -- apiserver讀取etcd 拿到配置設定在目前node節點上的pod,然後通過docker建立容器
8.2、影響Pod排程的屬性
Pod資源限制對Pod的排程會有影響
8.2.1、根據request找到足夠node節點進行排程
8.2.2、 節點選擇器标簽影響Pod排程
關于節點選擇器,其實就是有兩個環境,然後環境之間所用的資源配置不同
我們可以通過以下指令,給我們的節點新增标簽,然後節點選擇器就會進行排程了
kubectl label node k8snode1 env_role=prod
檢視節點标簽
kubectl get nodes --show-labels
8.2.3、 節點親和性
節點親和性 nodeAffinity 和 之前nodeSelector 基本一樣的,根據節點上标簽限制來決定Pod排程到哪些節點上
- 硬親和性:限制條件必須滿足
- 軟親和性:嘗試滿足,不保證
支援常用操作符:in、NotIn、Exists、Gt、Lt、DoesNotExists 反親和性:就是和親和性剛剛相反,如 NotIn、DoesNotExists等
8.2.4、污點和污點容忍
概述
nodeSelector 和 NodeAffinity,都是Pod排程到某些節點上,屬于Pod的屬性,是在排程的時候實作的。
Taint 污點:節點不做普通配置設定排程,是節點屬性
場景
- 專用節點【限制ip】
- 配置特定硬體的節點【固态硬碟】
- 基于Taint驅逐【在node1不放,在node2放】
檢視污點情況
kubectl describe node k8smaster | grep Taints
污點值有三個
- NoSchedule:一定不被排程
- PreferNoSchedule:盡量不被排程【也有被排程的幾率】
- NoExecute:不會排程,并且還會驅逐Node已有Pod
節點添加污點
kubectl taint node [node] key=value:污點的三個值
#舉例:
kubectl taint node k8snode1 env_role=yes:NoSchedule
master節點預設是NoSchedule:一定不被排程
案例:
通過設定k8snode1節點為NoSchedule:一定不被排程,導緻後面建立的pod都配置設定到node2節點
删除污點:
kubectl taint node k8snode1 env_role:NoSchedule-
污點容忍
污點容忍就是節點雖然設定成NoSchedule,該節點如果設定如下配置,節點可能被排程,也可能不被排程