簡介:在k8s中,一般使用yaml格式的文件來創建符合我們預期期望的pod,這樣的yaml文件我們一般稱為資源清單
一、k8s中存在那些資源
名稱空間級別
① 工作負載型資源(workload):Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob(ReplicationController在v1.11版本被廢棄
② 服務發現及負載均衡型資源(ServiceDiscoveryLoadBalance):Service、Ingress、...
③ 配置與存儲型資源:Volume(存儲卷)、CSI(容器存儲接口,可以擴展各種各樣的第三方存儲卷)
④ 特殊類型的存儲卷:ConfigMap(當配置中心來使用的資源類型)、Secret(保存敏感數據)、DownwardAPI(把外部環境中的信息輸出給容器)
集群級資源
Namespace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBinding
元數據型資源
HPA、PodTemplate(pod模板)、LimitRange(資源限制)
二、常用字段解釋
1、必須存在的屬性(必須寫)
2、主要對象(有的可不寫,有默認值)
3、額外的參數項
4、字段配置格式
apiVersion <string> #表示字符串類型 metadata <Object> #表示需要嵌套多層字段 labels <map[string]string> #表示由k:v組成的映射 finalizers <[]string> #表示字串列表 ownerReferences <[]Object> #表示對象列表 hostPID <boolean> #布爾類型 priority <integer> #整型 name <string> -required- #如果類型后面接 -required-,表示為必填字段 kubectl get pod xx.xx.xx -o yaml <!--使用 -o 參數加 yaml,可以將資源的配置以 yaml的格式輸出出來,也可以使用json,輸出為json格式-->
三、資源清單格式
1、注釋
apiVersion: group/apiversion # 如果沒有給定 group 名稱,那么默認為 core,可以使用 kubectl api-versions # 獲取當前 k8s 版本上所有的 apiVersion 版本信息( 每個版本可能不同 ) kind: #資源類別 metadata: #資源元數據 name namespace lables annotations # 主要目的是方便用戶閱讀查找 spec: # 期望的狀態(disired state) status: # 當前狀態,本字段有 Kubernetes 自身維護,用戶不能去定義
2、新建一個pod.舉例
vim pod.yaml 例子: apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: myapp version: v1 spec: containers: - name: app image: hub.lqz.com/library/nginx:latest
三、pod的基本用法
1、pod類型
u 自主式Pod:Pod退出了,此類型的pod不會被創建(可理解為此pod沒有管理者,他的死亡不會被拉起)
u 控制器管理的Pod:在控制器的生命周期里,始終要維持Pod的副本數目(一般為此類型)
2、pod控制器類型
① ReplicationController & ReplicaSet & Deployment
>HPA(HorizontalPodAutoScale)
② StatefullSet
③ DaemonSet
④ Job,Cronjob
- ReplicationController 用來確保容器應用的副本數始終保持在用戶定義的副本數,即如果有容器異常退出,會自動創建新的Pod 來替代;而如果異常多出來的容器也會自動回收。在新版本的Kubernetes 中建議使用ReplicaSet 來取代ReplicationControlle
- ReplicaSet 跟ReplicationController 沒有本質的不同,只是名字不一樣,並且ReplicaSet 支持集合式的selector
- 雖然ReplicaSet 可以獨立使用,但一般還是建議使用Deployment 來自動管理ReplicaSet ,這樣就無需擔心跟其他機制的不兼容問題(比如ReplicaSet 不支持rolling-update 但Deployment 支持)
- Deployment 為Pod 和ReplicaSet 提供了一個聲明式定義(declarative) 方法,用來替代以前的ReplicationController 來方便的管理應用。典型的應用場景包括:
- *定義Deployment 來創建Pod 和ReplicaSet
- *滾動升級和回滾應用
- *擴容和縮容
- *暫停和繼續Deployment
Horizontal Pod Autoscaling 僅適用於Deployment 和ReplicaSet ,在V1 版本中僅支持根據Pod 的CPU 利用率擴所容,在v1alpha 版本中,支持根據內存和用戶自定義的metric 擴縮容
StatefulSet是為了解決有狀態服務的問題(對應Deployments 和ReplicaSets是為無狀態服務而設計),其應用場景包括:
- 穩定的持久化存儲,即Pod 重新調度后還是能訪問到相同的持久化數據,基於PVC 來實現
- 穩定的網絡標志,即Pod 重新調度后其PodName和HostName不變,基於Headless Service (即沒有Cluster IP 的Service )來實現
- 有序部署,有序擴展,即Pod 是有順序的,在部署或者擴展的時候要依據定義的順序依次依次進行(即從0 到N-1,在下一個Pod 運行之前所有之前的Pod 必須都是Running 和Ready 狀態),基於init containers 來實現
- 有序收縮,有序刪除(即從N-1 到0)
DaemonSet 確保全部(或者一些)Node 上運行一個Pod 的副本。當有Node 加入集群時,也會為他們新增一個Pod 。當有Node 從集群移除時,這些Pod 也會被回收。刪除DaemonSet 將會刪除它創建的所有Pod使用DaemonSet 的一些典型用法:
- 運行集群存儲daemon,例如在每個Node 上運行glusterd、ceph。
- 在每個Node 上運行日志收集daemon,例如fluentd、logstash。
- 在每個Node 上運行監控daemon,例如Prometheus Node Exporter
Job 負責批處理任務,即僅執行一次的任務,它保證批處理任務的一個或多個Pod 成功結束Cron Job管理基於時間的Job,即:
- 在給定時間點只運行一次
- 周期性地在給定時間點運行
四、網絡通訊方式
1、網絡通訊模式
Kubernetes 的網絡模型假定了所有Pod 都在一個可以直接連通的扁平的網絡空間中,這在GCE(Google Compute Engine)里面是現成的網絡模型,Kubernetes 假定這個網絡已經存在。而在私有雲里搭建Kubernetes 集群,就不能假定這個網絡已經存在了。我們需要自己實現這個網絡假設,將不同節點上的Docker 容器之間的互相訪問先打通,然后運行Kubernetes
- 同一個Pod 內的多個容器之間:lo
- 各Pod 之間的通訊:Overlay Network
- Pod 與Service 之間的通訊:各節點的Iptables 規則
2、網絡解決方案Kubernetes + Flannel -1
Flannel 是CoreOS 團隊針對Kubernetes 設計的一個網絡規划服務,簡單來說,它的功能是讓集群中的不同節點主機創建的Docker 容器都具有全集群唯一的虛擬IP地址。而且它還能在這些IP 地址之間建立一個覆蓋網絡(Overlay Network),通過這個覆蓋網絡,將數據包原封不動地傳遞到目標容器內
ETCD 之 Flannel 提供說明:
> 存儲管理Flannel 可分配的IP 地址段資源
> 監控ETCD 中每個 Pod 的實際地址,並在內存中建立維護 Pod 節點路由表
同一個Pod 內部通訊:同一個Pod 共享同一個網絡命名空間,共享同一個Linux 協議棧
Pod1 至Pod2
> Pod1 與Pod2 不在同一台主機,Pod的地址是與docker0在同一個網段的,但docker0網段與宿主機網卡是兩個完全不同的IP網段,並且不同Node之間的通信只能通過宿主機的物理網卡進行。將Pod的IP和所在Node的IP關聯起來,通過這個關聯讓Pod可以互相訪問
> Pod1 與Pod2 在同一台機器,由Docker0 網橋直接轉發請求至Pod2,不需要經過Flannel
Pod 至 Service的網絡:目前基於性能考慮,全部為iptables 維護和轉發
Pod 到外網:Pod 向外網發送請求,查找路由表, 轉發數據包到宿主機的網卡,宿主網卡完成路由選擇后,iptables執行Masquerade,把源IP 更改為宿主網卡的IP,然后向外網服務器發送請求
外網訪問Pod:Service
3、編程方式
命令式編程:它側重於如何實現程序,就像我們剛接觸編程的時候那樣,我們需要把程序的實現過程按照邏輯結果一步步寫下來(ReplicaSet:creat)
聲明式編程:它側重於定義想要什么,然后告訴計算機/引擎,讓他幫你去實現(Deployment:apply)
Deployment通過ReplicaSet來管理Pod
4、不同情況下網絡通信方式
kubectl explain pod:看pod模板有那些 kubectl explain pod.apiVersion:查看具體某一個模板 創建pod:kubectl apply -f pod.yaml kubectl create -f pod.yaml 查看pod:kubectl get pod kubectl get pod -o wide 詳細信息 刪除pod:kubectl delete pod myapp-pod
訪問:curl 10.244.2.8
Kubectl describe pod myapp-pod //查看描述信息
kubectl log myapp-pod -c text //查看日志
五、pod容器生命周期
1、init容器
1.1、定義
Pod能夠具有多個容器,應用運行在容器里面,但是它也可能有一個或多個先於應用容器啟動的Init容器
Init容器與普通的容器非常像,除了如下兩點:
- Init容器總是運行到成功完成為止
- 每個Init容器都必須在下一個Init容器啟動之前成功完成
如果Pod的Init容器失敗,Kubernetes會不斷地重啟該Pod,直到Init容器成功為止。然而,如果Pod對應的restartPolicy為Never,它不會重新啟動
1.2、init容器的作用
因為Init容器具有與應用程序容器分離的單獨鏡像,所以它們的啟動相關代碼具有如下優勢:
① 它們可以包含並運行實用工具,但是出於安全考慮,是不建議在應用程序容器鏡像中包含這些實用工具的
② 它們可以包含使用工具和定制化代碼來安裝,但是不能出現在應用程序鏡像中。例如,創建鏡像沒必要FROM另一個鏡像,只需要在安裝過程中使用類似sed、awk、python或dig這樣的工具。
③ 應用程序鏡像可以分離出創建和部署的角色,而沒有必要聯合它們構建一個單獨的鏡像。
④ Init容器使用LinuxNamespace,所以相對應用程序容器來說具有不同的文件系統視圖。因此,它們能夠具有訪問Secret的權限,而應用程序容器則不能。
⑤ 它們必須在應用程序容器啟動之前運行完成,而應用程序容器是並行運行的,所以Init容器能夠提供了一種簡單的阻塞或延遲應用容器的啟動的方法,直到滿足了一組先決條件。
1.3、特殊說明
① 在Pod啟動過程中,Init容器會按順序在網絡和數據卷初始化之后啟動。每個容器必須在下一個容器啟動之前成功退出(網絡和數據卷初始化是在pause)
② 如果由於運行時或失敗退出,將導致容器啟動失敗,它會根據Pod的restartPolicy指定的策略進行重試。然而,如果Pod的restartPolicy設置為Always,Init容器失敗時會使用RestartPolicy策略
③ 在所有的Init容器沒有成功之前,Pod將不會變成Ready狀態。Init容器的端口將不會在Service中進行聚集。正在初始化中的Pod處於Pending狀態,但應該會將Initializing狀態設置為true
④ 如果Pod重啟,所有Init容器必須重新執行
⑤ #對Init容器spec的修改被限制在容器image字段,修改其他字段都不會生效。更改Init容器的image字段,等價於重啟該Pod
⑥ Init容器具有應用容器的所有字段。除了readinessProbe(就緒檢測),因為Init容器無法定義不同於完成(completion)的就緒(readiness)之外的其他狀態。這會在驗證過程中強制執行
⑦ 在Pod中的每個app和Init容器的名稱必須唯一;與任何其它容器共享同一個名稱,會在驗證時拋出錯誤
2、容器探針
探針是由kubelet對容器執行的定期診斷。要執行診斷,kubelet調用由容器實現的Handler。有三種類型的處理程序:
- ExecAction:在容器內執行指定命令。如果命令退出時返回碼為0則認為診斷成功。
- TCPSocketAction:對指定端口上的容器的IP地址進行TCP檢查。如果端口打開,則診斷被認為是成功的。
- HTTPGetAction:對指定的端口和路徑上的容器的IP地址執行HTTPGet請求。如果響應的狀態碼大於等於200且小於400,則診斷被認為是成功的
每次探測都將獲得以下三種結果之一:
- 成功:容器通過了診斷。
- 失敗:容器未通過診斷。
- 未知:診斷失敗,因此不會采取任何行動
探測方式
① livenessProbe:指示容器是否正在運行。如果存活探測失敗,則kubelet會殺死容器,並且容器將受到其重啟策略的影響。如果容器不提供存活探針,則默認狀態為Success(會隨着容器的生命周期一直存在)
② readinessProbe:指示容器是否准備好服務請求。如果就緒探測失敗,端點控制器將從與Pod匹配的所有Service的端點中刪除該Pod的IP地址。初始延遲之前的就緒狀態默認為Failure。如果容器不提供就緒探針,則默認狀態為Success
3、Pod hook
Podhook(鈎子)是由Kubernetes管理的kubelet發起的,當容器中的進程啟動前或者容器中的進程終止之前運行,這是包含在容器的生命周期之中。可以同時為Pod中的所有容器都配置hook
Hook的類型包括兩種:
- exec:執行一段命令
- HTTP:發送HTTP請求
4、重啟策略
PodSpec中有一個restartPolicy字段,可能的值為Always、OnFailure和Never。默認為Always。restartPolicy適用於Pod中的所有容器。restartPolicy僅指通過同一節點上的kubelet重新啟動容器。失敗的容器由kubelet以五分鍾為上限的指數退避延遲(10秒,20秒,40秒...)重新啟動,並在成功執行十分鍾后重置。如Pod文檔中所述,一旦綁定到一個節點,Pod將永遠不會重新綁定到另一個節點。
5、Podphase
- Pod的status字段是一個PodStatus對象,PodStatus中有一個phase字段。
- Pod的相位(phase)是Pod在其生命周期中的簡單宏觀概述。該階段並不是對容器或Pod的綜合匯總,也不是為了做為綜合狀態機
- Pod相位的數量和含義是嚴格指定的。除了本文檔中列舉的狀態外,不應該再假定Pod有其他的phase值
Podphase可能存在的值
① 掛起(Pending):Pod已被Kubernetes系統接受,但有一個或者多個容器鏡像尚未創建。等待時間包括調度Pod的時間和通過網絡下載鏡像的時間,這可能需要花點時間
② 運行中(Running):該Pod已經綁定到了一個節點上,Pod中所有的容器都已被創建。至少有一個容器正在運行,或者正處於啟動或重啟狀態
③ 成功(Succeeded):Pod中的所有容器都被成功終止,並且不會再重啟
④ 失敗(Failed):Pod中的所有容器都已終止了,並且至少有一個容器是因為失敗終止。也就是說,容器以非0狀態退出或者被系統終止
⑤ 未知(Unknown):因為某些原因無法取得Pod的狀態,通常是因為與Pod所在主機通信失敗
1、docker pull busybox 2、vim init-pod.yaml apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox command: ['sh','-c','echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox command: ['sh','-c','until nslookup myservice; do echo waiting for myservice; sleep 2;done;'] - name: init-mydb image: busybox command: ['sh','-c','until nslookup mydb; do echo waiting for mydb; sleep 2; done;'] 3、service可以簡稱svc 創建service kind: Service apiVersion: v1 metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 kind: Service apiVersion: v1 metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377
查看pod
kubectl delete deployment --all 刪除所有deployment
kubectl delete pod --all 刪除所有pod
版本最好不用latest;因為現在和以后的最新版本不一樣
查看具體pod信息
鏈接:https://www.bilibili.com/video/av66617940/?p=17