深入理解pod


深入理解pod

pod定義詳解

 

apiVersion: v1 //版本 kind: pod //類型,pod metadata: //元數據  name: String //元數據,pod的名字  namespace: String //元數據,pod的命名空間  labels: //元數據,標簽列表  - name: String //元數據,標簽的名字  annotations: //元數據,自定義注解列表  - name: String //元數據,自定義注解名字 spec: //pod中容器的詳細定義  containers: //pod中的容器列表,可以有多個容器  - name: String  image: String //容器中的鏡像  imagesPullPolicy: [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: Srting  memory: String  requeste:  cpu: String  memory: String  livenessProbe: //pod內容器健康檢查的設置  exec:  command: [String]  httpGet: //通過httpget檢查健康  path: String  port: number  host: String  scheme: Srtring  httpHeaders:  - name: Stirng  value: String  tcpSocket: //通過tcpSocket檢查健康  port: number  initialDelaySeconds: 0//首次檢查時間  timeoutSeconds: 0 //檢查超時時間  periodSeconds: 0 //檢查間隔時間  successThreshold: 0  failureThreshold: 0  securityContext: //安全配置  privileged: falae  restartPolicy: [Always|Never|OnFailure]//重啟策略  nodeSelector: object //節點選擇  imagePullSecrets:  - name: String  hostNetwork: false //是否使用主機網絡模式,默認否  volumes: //在該pod上定義共享存儲卷  - name: String  meptyDir: {}  hostPath:  path: string  secret: //類型為secret的存儲卷  secretName: String  item:  - key: String  path: String  configMap: //類型為configMap的存儲卷  name: String  items:  - key: String  path: String

 

pod的特點

• 最小部署單元 

• 一組容器的集合

• 一個Pod中的容器共享網絡命名空間 puase

• Pod是短暫的 (重拉pod ip會發生變化)

image.png

pod由於有個根容器pause,所以pod中的其他容器可以共享網絡 和 存儲

示例:share-volume.yaml

說明,兩個centos容器write和read   

write容器:向 /data/hello 文件每隔1秒追加1到100數字

read容器: tailf -f /data/hello  

效果:查看write 容器中的/data/hello文件是不斷寫入,查看read容器 /data/hello 也是不斷寫入的

說明:同一個pod中的容器 共享存儲,共享網絡

apiVersion: v1 kind: Pod metadata:  name: my-pod spec:  containers:  - name: write  image: centos  command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"]  volumeMounts:  - name: data  mountPath: /data  - name: read  image: centos  command: ["bash","-c","tail -f /data/hello"]  volumeMounts:  - name: data  mountPath: /data  volumes:  - name: data  emptyDir: {}

image.png

image.png

image.png

pod應用場景

• Pod為親密性應用而存在。 親密性應用場景:

• 兩個應用之間發生文件交互

• 兩個應用需要通過127.0.0.1或者socket通信

• 兩個應用需要發生頻繁的調用

 

鏡像拉取策略(imagePullPolicy)

• IfNotPresent:默認值,鏡像在宿主機上不存在時才拉取

• Always:每次創建 Pod 都會重新拉取一次鏡像

• Never: Pod 永遠不會主動拉取這個鏡像

 

apiVersion: v1 kind: Pod metadata:  name: foo  namespace: awesomeapps spec:  containers:  - name: foo  image: janedoe/awesomeapp:v1  imagePullPolicy: IfNotPresent 

 

apiVersion: v1 kind: Pod metadata:  name: foo  namespace: awesomeapps spec:  containers:  - name: foo  image: janedoe/awesomeapp:v1  imagePullSecrets:  - name: myregistrykey

如果使用私有倉庫需要定義一個secret 用於存放登錄registry倉庫的信息

 kubectl create secret docker-registry myregistry --docker-username=benjamin7788 --docker-password=a7260488 --docker-server=registry.cn-hangzhou.aliyuncs.com -n awesomeapps 

 

pod的資源限制

• spec.containers[].resources.limits.cpu

• spec.containers[].resources.limits.memory

• spec.containers[].resources.requests.cpu

• spec.containers[].resources.requests.memory

 

kubernetes會根據Request的值去查找有足夠資源的node來調度此pod

limit對應資源量的上限, 既最多允許使用這個上限的資源量, 由於cpu是可壓縮的, 進程是無法突破上限的, 而memory是不可壓縮資源, 當進程試圖請求超過limit限制時的memory, 此進程就會被kubernetes殺掉

對於cpu和內存而言, pod的request和limit是指該pod中所有容器的 Requests或Limits的總和,

例如: 某個節點cpu資源充足, 而內存為4G,其中3GB可以運行pod, 而某個pod的memory request為1GB, limit為2GB, 那么這個節點上最多可以運行3個這樣的pod

待調度pod的request值總和超過該節點提供的空閑資源, 不會調度到該節點node上;

一般 limits設置的值大於等於 request設置的值

resource.yaml

apiVersion: apps/v1 kind: Deployment metadata:  name: nginx-deployment spec:  selector:  matchLabels:  app: nginx  replicas: 1  template:  metadata:  labels:  app: nginx  spec:  containers:  - name: nginx  image: nginx:1.11  ports:  - containerPort: 80  resources:  limits:  cpu: 0.75 #750m=0.75c  memory: 500Mi #500MB=500Mi  requests:  cpu: 0.5  memory: 500Mi

image.png

 

重啟策略(restartPolicy)

• Always:當容器終止退出后,總是重啟容器,默認策略。

• OnFailure:當容器異常退出(退出狀態碼非0)時,才重啟容器。

• Never:當容器終止退出,從不重啟容器。

每個策略適用相應的場景,

never 適用定時任務,OnFailure 和 Always 適用一般應用程序,具體還是要根據業務性質來設置

 

apiVersion: v1 kind: Pod metadata:  name: foo  namespace: awesomeapps spec:  containers:  - name: foo  image: janedoe/awesomeapp:v1  restartPolicy: Always

健康檢查(Probe)

 livenessProbe

如果檢查失敗,將殺死容器,根據Pod的restartPolicy來操作。

 readinessProbe

如果檢查失敗,Kubernetes會把Pod從service endpoints中剔除。 Probe支持以下三種檢查方法:

 httpGet

發送HTTP請求,返回200-400范圍狀態碼為成功。

 exec

執行Shell命令返回狀態碼是0為成功。

 tcpSocket

發起TCP Socket建立成功。

livenessProbe.yaml

apiVersion: v1 kind: Pod metadata:  labels:  test: liveness  name: liveness-exec spec:  containers:  - name: liveness  image: busybox  args:  - /bin/sh  - -c  - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60  livenessProbe:  exec:  command:  - cat  - /tmp/healthy  initialDelaySeconds: 5 #容器啟動之后5s開始檢查  periodSeconds: 5 #周期是5s  readinessProbe:  exec:  command:  - cat  - /tmp/healthy  initialDelaySeconds: 5  periodSeconds: 5

注意:這邊未設置重啟策略,一般缺省的默認策略是Always,鏡像拉取策略 缺省的策略也是Always

image.png

健康檢查失敗,容器將會被重啟,在k8s里沒有重啟一說,實際是刪除容器重拉鏡像重新起一個新的容器

image.png

image.png

image.png

查看pod已經重啟了2次

image.png

 

 

pod調度策略

image.png

 

create pod ---》write apiserver ---》write etcd ---》scheduler ---》bind pod to node ---》write etcd ---》

kubelet(apiserver get pod) ---》docker api create container ---》apiserver ---》update pod status to etcd ---》kubectl get pods

 

 

  • nodeName:

用於將Pod調度到指定的Node名稱上

pod-nodename.yaml

apiVersion: v1 kind: Pod metadata:  name: pod-example2  labels:  app: nginx spec:  nodeName: k8s-node2  containers:  - name: nginx  image: nginx:1.15

image.png

  • nodeSelector:

用於將Pod調度到匹配Label的Node上

pod-nodeselector.yaml

 

apiVersion: v1 kind: Pod metadata:  name: pod-example2  labels:  app: nginx spec:  nodeSelector:  team: a  containers:  - name: nginx  image: nginx:1.15

查看 k8s-node1的默認lable

image.png

給k8s-node1 加一個 team=a的標簽

kubectl label node k8s-node1 team=a

image.png

根據上面的yaml生成pod  符合預期,pod將會被調度到 label   為team=a 的 k8s-node1的節點上

image.png

說明:nodeSelector  相比 nodeName 組合更加靈活

nodeName不經過scheduler直接調度到指定節點,nodeSelector經過shceduler需要經過一些調度算法處理最后調度到相應節點。

如果都沒指定這兩種方式,則采用k8s默認的調度策略

污點與容忍

默認node節點都是沒有打污點的,master節點是打上污點的。

image.png

 

應用場景:

• 節點獨占

• 具有特殊硬件設備的節點

• 應對節點故障

kubectl taint node [node] key=value[effect]

其中[effect] 可取值:

NoSchedule :一定不能被調度。

PreferNoSchedule:盡量不要調度。

NoExecute:不僅不會調度,還會驅逐Node上已有的Pod。

 

給k8s-node1打污點

kubectl taint node k8s-node1 abc=123:NoSchedule

打完污點后將之前根據pod-nodeselector.yaml 創建的 pod-example2  這個pod 刪除,重新創建pod-example2

 

kubectl delete pod pod-example2 kubectl apply -f pod-nodeselector.yaml

查看pod 狀態會發現一直是pedding狀態

image.png

describe 查看發現 pod 沒有可被調度的 node,這是符合預期的,因為指定了 含有lable  team=a的k8s-node1調度

然后 k8s-node1 被打了 污點,所以這時候 event 提示沒有可被調度的節點

image.png

 

設置容忍

pod-nodetaint.yaml

apiVersion: v1 kind: Pod metadata:  name: pod-example2  labels:  app: nginx spec:  tolerations:  - key: "abc"  operator: "Equal"  value: "123"  effect: "NoSchedule"  nodeSelector:  team: a  containers:  - name: nginx  image: nginx:1.15

按照如上yaml設置容忍后 ,成功調度到k8s-node1

image.png

 

pod無法啟動排查

kubectl describe TYPE/NAME kubectl logs TYPE/NAME [-c CONTAINER] kubectl exec POD [-c CONTAINER] -- COMMAND [args...]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM