K8S最小調度單元POD概述
- k8s核心資源Pod介紹
- Pod是什么
- Pod如何管理多個容器
- Pod網絡
- Pod存儲
- 代碼自動發版更新
- 收集業務日志
- Pod工作方式
- 自主式Pod
- 控制器管理的Pod(防誤刪除)
- 如何基于Pod運行應用
k8s核心資源Pod介紹
K8s官方文檔:https://kubernetes.io/
K8s中文官方文檔: https://kubernetes.io/zh/
K8s Github地址:https://github.com/kubernetes/kubernetes
Pod資源對應的官方文檔:https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/
Pod是什么
Pod是Kubernetes中的最小調度單元,k8s是通過定義一個Pod的資源,然后在Pod里面運行容器,容器需要指定一個鏡像,這樣就可以用來運行具體的服務。一個Pod封裝一個容器(也可以封裝多個容器),Pod里的容器共享存儲、網絡等。也就是說,應該把整個pod看作虛擬機,然后每個容器相當于運行在虛擬機的進程。
Pod是需要調度到k8s集群的工作節點來運行的,具體調度到哪個節點,是根據scheduler調度器實現的。
pod相當于一個邏輯主機–比方說我們想要部署一個tomcat應用,如果不用容器,我們可能會部署到物理機、虛擬機或者云主機上,那么出現k8s之后,我們就可以定義一個pod資源,在pod里定義一個tomcat容器,所以pod充當的是一個邏輯主機的角色。
Pod如何管理多個容器
Pod中可以同時運行多個容器。同一個Pod中的容器會自動的分配到同一個 node 上。同一個Pod中的容器共享資源、網絡環境,它們總是被同時調度,在一個Pod中同時運行多個容器是一種比較高級的用法,只有當你的容器需要緊密配合協作的時候才考慮用這種模式。例如,你有一個容器作為web服務器運行,需要用到共享的volume,有另一個“sidecar”容器來從遠端獲取資源更新這些文件。
一些Pod有init容器和應用容器。 在應用程序容器啟動之前,運行初始化容器。
Pod網絡
Pod是有IP地址的,假如pod不是共享物理機ip,由網絡插件(calico、flannel、weave)劃分的ip,每個pod都被分配唯一的IP地址
- Kubernetes中容器共享的方式
在k8s中,啟動Pod時,會先啟動?個pause 的容器,然后將后續的所有容器都 "link 到這個pause 的容器,以實現?絡共享。
Pod存儲
創建Pod的時候可以指定掛載的存儲卷。 POD中的所有容器都可以訪問共享卷,允許這些容器共享數據。 Pod只要掛載持久化數據卷,Pod重啟之后數據還是會存在的。
代碼自動發版更新
假如生產環境部署了一個go的應用,而且部署了幾百個節點,希望這個應用可以定時的同步最新的代碼,以便自動升級線上環境。這時,我們不希望改動原來的go應用,可以開發一個Git代碼倉庫的自動同步服務,然后通過Pod的方式進行編排,并共享代碼目錄,就可以達到更新java應用代碼的效果。
收集業務日志
某服務模塊已經實現了一些核心的業務邏輯,并且穩定運行了一段時間,日志記錄在了某個目錄下,按照不同級別分別為 error.log、access.log、warning.log、info.log,現在希望收集這些日志并發送到統一的日志處理服務器上。
這時我們可以修改原來的服務模塊,在其中添加日志收集、發送的服務,但這樣可能會影響原來服務的配置、部署方式,從而帶來不必要的問題和成本,也會增加業務邏輯和基礎服務的藕合度。
如果使用Pod的方式,通過簡單的編排,既可以保持原有服務邏輯、部署方式不變,又可以增加新的日志收集服務。
而且如果我們對所有服務的日志生成有一個統一的標準,或者僅對日志收集服務稍加修改,就可以將日志收集服務和其他服務進行Pod編排,提供統一、標準的日志收集方式。
這里的“核心業務服務”、“日志收集服務”分別是一個鏡像,運行在隔離的容器環境中。
Pod工作方式
在K8s中,所有的資源都可以使用一個yaml文件來創建,創建Pod也可以使用yaml配置文件。或者使用kubectl run在命令行創建Pod(不常用)。
自主式Pod
所謂的自主式Pod,就是直接定義一個Pod資源,如下:
vim pod-tomcat.yaml
apiVersion: v1
kind: Pod
metadata:name: tomcat-testnamespace: defaultlabels:app: tomcat
spec:containers:- name: tomcat-javaports:- containerPort: 8080image: tomcat/tomcat-8.5-jre8:v1imagePullPolicy: IfNotPresent
導入鏡像 把tomcat.tar.gz上傳到k8snode1和k8snode2節點,手動解壓:
鏈接:https://pan.baidu.com/s/1BGUFkkwFnZ-OF80weq0pQQ?pwd=r6ri
提取碼:r6ri
ctr -n=k8s.io images import tomcat.tar.gz
更新資源清單文件
kubectl apply -f pod-tomcat.yaml
查看pod是否創建成功
kubectl get pods -o wide -l app=tomcat
但是自主式Pod是存在一個問題的,假如我們不小心刪除了pod:
kubectl delete pods tomcat-test
查看pod是否還在
kubectl get pods -l app=tomcat
結果是空,說明pod已經被刪除了
通過上面可以看到,如果直接定義一個Pod資源,那Pod被刪除,就徹底被刪除了,不會再創建一個新的Pod,這在生產環境還是具有非常大風險的,所以今后我們接觸的Pod,都是控制器管理的。
控制器管理的Pod(防誤刪除)
常見的管理Pod的控制器:Replicaset、Deployment、Job、CronJob、Daemonset、Statefulset。
控制器管理的Pod可以確保Pod始終維持在指定的副本數運行。
如,通過Deployment管理Pod
解壓鏡像:把nginx.tar.gz上傳到k8snode1和k8snode2節點
鏈接:https://pan.baidu.com/s/1EDLQ8Zt9goRFEo9K83Ufwg?pwd=qv3q
提取碼:qv3q
ctr -n=k8s.io images import nginx.tar.gz
vim nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-testlabels:app: nginx-deploy
spec:selector:matchLabels:app: nginxreplicas: 2template:metadata:labels:app: nginxspec:containers:- name: my-nginximage: nginx/nginx:v1imagePullPolicy: IfNotPresentports:- containerPort: 80
更新資源清單文件
kubectl apply -f nginx-deploy.yaml
查看Deployment
kubectl get deploy -l app=nginx-deploy
查看Replicaset
kubectl get rs -l app=nginx
查看pod
kubectl get pods -o wide -l app=nginxNAME READY STATUS IP
nginx-test-75c685fdb7-6d4lx 1/1 Running 10.244.102.69
nginx-test-75c685fdb7-9s95h 1/1 Running 10.244.102.68
刪除nginx-test-75c685fdb7-9s95h這個pod
kubectl delete pods nginx-test-75c685fdb7-9s95h
kubectl get pods -o wide -l app=nginx
NAME READY STATUS IP
nginx-test-75c685fdb7-6d4lx 1/1 Running 10.244.102.69
nginx-test-75c685fdb7-pr8gh 1/1 Running 10.244.102.70
發現重新創建一個新的pod是nginx-test-75c685fdb7-pr8gh
通過上面可以發現通過deployment管理的pod,可以確保pod始終維持在指定副本數量
可以通過指定配置文件刪除對應pod
kubectl delete -f nginx-deploy.yaml
如何基于Pod運行應用
創建pod流程:
kubectl apply -f nginx-deploy.yaml->找到config文件,基于config文件指定的用戶訪問指定的集群,這樣就找到了apiserver
- 通過 kubectl 命令向 apiserver 提交創建pod的請求,apiserver接收到pod創建請求后,會將pod的屬性信息(metadata)寫入etcd。
- apiserver觸發watch機制準備創建pod,信息轉發給調度器scheduler,調度器使用調度算法選擇node,調度器將node信息給apiserver,apiserver將綁定的node信息寫入etcd
- apiserver又通過watch機制,調用kubelet,指定pod信息,調用容器運行時創建并啟動pod內的容器。
- 創建完成之后反饋給kubelet, kubelet又將pod的狀態信息給apiserver,apiserver又將pod的狀態信息寫入etcd。