上文說了一下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大神。
來都來了,關注一波再溜唄。