k8s之深入解剖Pod(一)
- 2020 年 12 月 20 日
- 筆記
- Kubernetes
上文說了一下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大神。
來都來了,關注一波再溜唄。