上文說了一下k8s的簡單使用,接下來就讓我們來具體深入了解一下Pod。為了避免篇幅太長,所以會分成幾篇。
目錄:
- Pod定義詳解
- 靜態Pod
- Pod容器共享Volume
一、Pod定義詳解
先看一個簡單的nginx的Pod定義:
apiVersion: v1
kind: Pod
metadata:
nam: nginx-test
labels:
app: nginx-test
spec:
containers:
- name: nginx-test
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
上述是一個Pod內包含一個容器,容器中運行nginx,容器對外暴漏80端口
Pod定義主要分成四大塊:
(1)api
apiVersion: v1
(2)kind
kind: Pod
(3)metadata
metadata是Pod的元數據定義
metadata: #元數據
name: string #Pod名稱
namespace: string #Pod所屬命名空間,缺省默認是default
labels: #自定義標簽列表
- key: value
annotations: #自定義注解列表
- key: value
(4)spec
spec是Pod中容器的詳細定義,主要分成以下幾塊
containers
containers是Pod中的容器列表,數組類型。
spec:
containers: #容器列表
- name: string #容器名稱
image: string #所用鏡像
imagePullPolicy: [Always|Never|IfNotPresent] #鏡像拉取策略
command: [string] #容器的啟動命令列表
args: [string] #啟動命令參數列表
workingDir: string #工作目錄
volumeMounts: #掛載在容器內部的存儲卷配置
- name: string #共享存儲卷名稱
mountPath: string #存儲卷絕對路徑
readOnly: boolean #是否只讀
ports: #容器需要暴露的端口號列表
- name: string #端口名稱
containerPort: int #容器監聽端口
hostPort: int #映射宿主機端口
protocol: string #端口協議
env: #環境變量
- name: string
value: string
resources: #資源限制
limits:
cpu: string #單位是core
memory: string #單位是MiB、GiB
livenessProbe: #探針,對Pod各容器健康檢查的設置,如幾次無回應,則會自動重啟
exec:
command: [string]
httpGet:
path: string
port: number
host: string
scheme: string
httpHeaders:
- name: string
value: string
tcpSocket:
port: number
initialDelaySeconds: 0 #啟動后多久進行檢測
timeoutSeconds: 0 #超時時間
periodSeconds: 0 #間隔時間
successThreshold: 0 #
failureThreshold: 0
securityContext: #權限設置
privileged: false #是否允許創建特權模式的Pod
探針測試:
列出文件或文件夾aaa(此目錄是不存在的),容器啟動后5s開始執行探針,每隔5s執行一次,
apiVersion: v1
kind: Pod
metadata:
name: nginx-test
labels:
app: nginx-test
spec:
containers:
- name: nginx-test
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
livenessProbe:
exec:
command: ["ls","aaa"]
initialDelaySeconds: 5
timeoutSeconds: 5
查看探針三次失敗后是否有重啟容器:
使用如下命令查看容器的Event項
kubectl describe pods/nginx-test
從上圖可以看到,容器重啟了5次
restartPolicy
容器重啟策略:
spec: restartPolicy: [Always|Never|OnFailure]
- Always:Pod一旦終止運行,kubelet都會進行重啟,這也是默認值
- Never:不會進行重啟
- OnFailure:容器非正常退出(即是退出碼不為0),kubelet會重啟容器,反之不會重啟。
nodeSelector
指定Pod被調度到哪個節點運行。
spec:
nodeSelector:
K: V
比如想把一個Pod調度給cnode-2節點運行:
獲取集群中所有節點列表:
給cnode-2節點打標簽:
kubectl label nodes/cnode-2 name=cnode-2
查看cnode-2節點標簽信息:
定義Pod的yaml文件:nginx-ns.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-test
labels:
app: nginx-test
spec:
containers:
- name: nginx-test
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
nodeSelector:
name: cnode-2
使用如下命令創建Pod:
kubectl create -f nginx-ns.yaml
查看這個Pod運行在哪個節點:
imagePullSecrets
拉取鏡像時使用的Secret名稱,以name:secretKey格式指定
spec:
imagePullSecrets:
name: secretKey
Secret是用來保存私密憑據的,比如密碼等信息
hostNetwork
是否使用主機網絡模式
spec: hostNetwork: true|false
如果使用主機網絡模式的話,Pod的IP就是跟宿主機IP是一樣的
例如:創建下列Pod
apiVersion: v1
kind: Pod
metadata:
name: nginx-test
labels:
app: nginx-test
spec:
containers:
- name: nginx-test
image: nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
nodeSelector:
name: cnode-3
hostNetwork: true
然后查看Pod被分配的IP與主機IP是否相同
volumes
Pod上定義的共享存儲列表:
spec:
volumes: #存儲卷
- name: string
emptyDir: {} #表示與Pod同生命周期的一個臨時目錄
hostPath: #宿主機Host
path: string
secret: #掛載集群預定義的secret對象到容器內部
secretName: string
items:
- key: string
path: string
configMap: #掛載集群預定義的configMap對象到容器內部
name: string
items:
- key: string
path: string
二、靜態Pod
由kubelet管理的僅存在於特定Node上的Pod,不能通過API Service進行管理,無法與RC、deployment或DaemonSet進行關聯,並且kubelet也無法對他們進行健康檢查,有kubelet創建並運行在kubelet所在的Node上運行。
靜態Pod的yaml文件在修改之后,kubelet會進行自動重啟該Pod至配置文件生效
創建靜態Pod有兩種方式:配置文件或者HTTP方式。
下面說一下配置文件的創建方式:
配置文件
需要設置kubelet啟動參數“--config”,指定kubelet需要監控的配置文件所在的目錄,kubelet會定期掃描該目錄,並根據目錄中的yaml或json文件進行創建操作
(1)如果集群是通過kubeadm創建的,那么已經配置好了靜態pod的路徑
查看kubelet的啟動參數配置文件路徑:
systemctl status kubelet
查看配置文件:
啟動參數配置在一個叫/var/lib/kubelet/config.yaml的文件中
在此文件中會發現由下圖中的配置,也就是靜態Pod路徑配置為/etc/kubernetes/manifests路徑
所以只需要將靜態Pod的yaml文件放置在此目錄下即可。
這四個Master上運行的核心組件就是通過此方式進行創建的。
例如上圖中我將static-nginx.yaml放到/etc/kubernetes/manifests目錄下:
apiVersion: v1
kind: Pod
metadata:
name: static-nginx
labels:
name: static-nginx
spec:
containers:
- name: static-nginx
image: nginx
ports:
- containerPort: 80
此時使用kubelet get pods就可以查看到相應的Pod
(2)如果不是由kubeadm創建的集群,則需要在kubelet啟動參數配置文件中添加如下一行:
Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true
修改配置之后需要重啟kubelet
systemctl stop kubelet systemctl daemon-reload systemctl start kubelet
例如我在cnode-2上配置了kubelet的啟動參數,將靜態Pod文件目錄設置為/usr/soft/k8s/yaml/staticPod,然后重啟kubelet
此時在目錄下放置一個yaml文件
保存后就可以查看到相應的Pod是否已創建
【注意】如果Pod沒創建成功,可以使用如下命令查看日志
systemctl status kubelet -l
我這邊因為是之前配置了Pod安全策略,所以導致無法創建,我排查了一天啊我天
,痛苦的教訓
Http方式
通過設置kubelet的啟動參數“--manifest-url”,kubelet將會定期從該URL地址下載Pod的定義文件,並以.yaml或.json文件的格式進行解析, 然后創建Pod。其實現方式與配置文件方式是一致的。
【注意】靜態Pod無法通過kubectl delete進行刪除,只能刪除對應的yaml文件
三、Pod容器共享Volume
在同一個Pod中的多個容器能夠共享Pod級別的存儲卷Volume,可以定義為各種類型,至於Volume是何種類型,在k8s基本概念中已有提到,多個容器各自進行掛載,將一個Volume掛在為容器內部需要的目錄
比如:Pod里面有兩個容器,分別是tomcat和busybox,tomcat往/usr/local/tomcat/logs寫日志,busybox從/logs目錄讀取日志。
新建一個yaml文件:
這里設置的Volume名為app-logs,類型為emptyDir,掛載到tomcat容器內 的/usr/local/tomcat/logs目錄,同時掛載到busybox容器內的/logs目錄。
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
containers:
- name: tomcat
image: tomcat
ports:
- containerPort: 8080
volumeMounts:
- name: app-logs
mountPath: /usr/local/tomcat/logs
- name: busybox
image: busybox
command: ["sh","-c","tail -f /logs/catalina*.log"]
volumeMounts:
- name: app-logs
mountPath: /logs
volumes:
- name: app-logs
emptyDir: {}
創建之后查看busybox的日志輸出:
kubectl logs pods/volume-pod -c busybox
進入tomcat容器中查看日志文件:
#進入tomcat容器,-c參數指明是哪個容器 kubectl exec -it pods/volume-pod -c tomcat /bin/bash
進入在Pod創建時設置的日志目錄:
/usr/local/tomcat/logs
===============================
我是Liusy,一個喜歡健身的程序員。
歡迎關注微信公眾號【Liusy01】,一起交流Java技術及健身,獲取更多干貨,領取Java進階干貨,領取最新大廠面試資料,一起成為Java大神。
來都來了,關注一波再溜唄。
