日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

1、深入理解Pod

發布時間:2023/12/20 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1、深入理解Pod 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、基本用法

1、對于容器的要求

kubernetes對長時間運行的容器要求:必須一直在前臺執行。如果是后臺執行的程序,例如

Nohup ./start.sh &

則會在執行完成之后銷毀Pod,但是可以借助一些方式讓后臺程序在前臺執行,例如supervisor

2、一個Pod多個容器

? 如果兩個容器耦合性較強,可以放在一個Pod里面,此時他們可以共享網絡和文件。例如:

1、前端應用容器直接通過localhost訪問后臺應用容器服務;

2、一個應用寫日志到本地,一個應用從本地讀日志;

2、靜態Pod

https://kubernetes.io/zh/docs/tasks/configure-pod-container/static-pod/

?

靜態Pod是指由kubelet管理僅存在于特定Node上的Pod,不能1、通過API Server管理 2、與RC、Deployment關聯 3、kubelet無法進行健康檢查

創建靜態Pod有配置文件和HTTP方式。

1、配置文件

設置kubelet的啟動參數"–pod-manifest-path=/root/yaml/",對于該目錄下的yaml或者json文件,kubelet服務會定期進行掃描和創建。

apiVersion: v1 kind: Pod metadata:name: static-weblabels:role: myrole spec:containers:- name: webimage: nginxports:- name: webcontainerPort: 80protocol: TCP

1、刪除Pod

靜態Pod無法通過kubectl delete刪除,刪除后狀態會變成Pending,刪除需要刪除對應config目錄下的json和yaml配置。

1、HTTP方式

指定kubelet的啟動參數"–manifest-url"。

3、Pod容器共享卷Volume和網絡

Note: 卷的名稱只能是xx-xx的形式,不能使用小駝峰.

一個Pod內存在多個容器時,容器可以共享掛載卷,實現同一個目錄,一個容器應用讀取,一個容器應用寫入。

例如:

apiVersion: v1 kind: Pod metadata:name: share-volumes-pod spec:containers:- name: tomcatimage: tomcatvolumeMounts:- name: log-volumesmountPath: /usr/local/tomcat/logsports:- containerPort: 8080- name: ubuntu-curlimage: nanda/ubuntu-curl:v1volumeMounts:- name: log-volumesmountPath: /logscommand: - sh- -cargs:- while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8080)" != '200' ]]; do echo Waiting for tomcat;sleep 5; done; tail -f /logs/catalina*.log;volumes:- name: log-volumesemptyDir: {}

這里有點要注意:容器啟動是異步的,啟動順序是安裝配置文件來,但是第二個啟動時第一個不一定啟動OK了,所有加入linux腳本命令等待第一個執行完畢。

4、Pod的配置管理

kubernetes1.2提供一種統一的應用配置管理方案:ConfigMap。注意是通過環境變量注入到容器,而且可以實現將node上的文件變為配置,配置然后掛載成容器中的文件。

1、創建ConfigMap

1、YAML配置文件創建

apiVersion: v1 kind: ConfigMap # ConfigMap metadata:name: app-vars # ConfigMap的名稱,全局唯一 data:apploglevel: infoappdatadir: /var/data

可以將配置文件的內容作為data中的value

2、通過命令行創建

# 從目錄中進行創建,文件名作為key,文件內容作為value kubectl create configmap ConfigMap名稱 --from-file=目錄

2、在Pod中使用ConfigMap

1、通過環境變量進行使用

1、通過環境變量

apiVersion: v1 kind: Pod metadata:name: test-use-configmap spec:containers:- name: ubuntu-curlimage: nanda/ubuntu-curl:v1command: - sh- -cargs:- env | grep APP;env: - name: APPLOGLEVELvalueFrom:configMapKeyRef:name: app-vars # ConfiMap的名稱key: apploglevel # ConfigMap中Key的名稱restartPolicy: Never # 執行完畢后退出,不重啟,默認時Always

2、1.6之后的新字段envFrom將ConfigMap中所有定義的key=value自動生成環境變量

apiVersion: v1 kind: Pod metadata:name: test-use-configmap spec:containers:- name: ubuntu-curlimage: nanda/ubuntu-curl:v1command: - sh- -cargs:- env;envFrom: - configMapRef:name: app-vars # ConfiMap的名稱restartPolicy: Never # 執行完畢后退出,不重啟,默認時Always

2、通過volumeMount使用ConfigMap

通過將ConfigMap中的key作為文件名,value作為文件內容掛載到容器中。

1、指定掛載configmap中的某一些配置

apiVersion: v1 kind: Pod metadata:name: test-use-configmap spec:containers:- name: ubuntu-curlimage: nanda/ubuntu-curl:v1command: - sh- -cargs:- ls /configfiles && cat /configfiles/apploglevel.txt && cat /configfiles/appdatadir.log;volumeMounts:- name: testvolumes # 卷名稱mountPath: /configfiles # 掛載到容器中的目錄volumes:- name: testvolumesconfigMap:name: app-vars # 掛載的configmap名稱items: # configmap中的那些項將被掛載- key: apploglevel # configmap中的keypath: apploglevel.txt # 文件名- key: appdatadir # configmap中的keypath: appdatadir.log # 文件名restartPolicy: Never # 執行完畢后退出,不重啟,默認時Always

2、掛載configmap中的所有配置

此時無法指定文件名了,只能以key作為文件名。

apiVersion: v1 kind: Pod metadata:name: test-use-configmap spec:containers:- name: ubuntu-curlimage: nanda/ubuntu-curl:v1command: - sh- -cargs:- ls /configfiles && cat /configfiles/apploglevel.txt && cat /configfiles/appdatadir.log;volumeMounts:- name: testvolumes # 卷名稱mountPath: /configfiles # 掛載到容器中的目錄volumes:- name: testvolumesconfigMap:name: app-vars # 掛載的configmap名稱restartPolicy: Never # 執行完畢后退出,不重啟,默認時Always

3、ConfigMap的限制

1、必須在Pod前創建

2、受namespace限制

3、靜態Pod無法使用

4、文件掛載時,會覆蓋容器內原本的文件

5、容器內獲取Pod信息

主要是通過Downward API進行注入,兩種方式:1、環境變量 2、文件掛載

1、Pod信息

apiVersion: v1 kind: Pod metadata:name: test-get-pod-infolabels:a: ab: bc: cannotations:build: twobuilder: jhn-doe spec:containers:- name: ubuntu-curlimage: nanda/ubuntu-curl:v1command: - sh- -cargs:- env | grep POD_NAME && ls /configfiles && cat /configfiles/labels && cat /configfiles/annotationsenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.namevolumeMounts:- name: podinfomountPath: /configfilesreadOnly: falsevolumes:- name: podinfodownwardAPI:items:- path: "labels"fieldRef:fieldPath: metadata.labels- path: "annotations"fieldRef:fieldPath: metadata.annotationsrestartPolicy: Never # 執行完畢后退出,不重啟,默認時Always

Downward API提供的變量有:

  • metadata.name
  • status.podIP
  • metadata.namespace
  • metadata.labels
  • metadata.annotations

2、容器資源信息

apiVersion: v1 kind: Pod metadata:name: test-get-pod-resource-info spec:containers:- name: ubuntu-curlimage: nanda/ubuntu-curl:v1command: - sh- -cargs:- env | grep MY_resources:requests:memory: "32Mi"cpu: "125m"limits:memory: "64Mi"cpu: "250m"env:- name: MY_REQUEST_CPUvalueFrom:resourceFieldRef:containerName: ubuntu-curlresource: requests.cpu- name: MY_LIMITS_CPUvalueFrom:resourceFieldRef:containerName: ubuntu-curlresource: limits.cpu- name: MY_REQUEST_MEMORYvalueFrom:resourceFieldRef:containerName: ubuntu-curlresource: requests.memory- name: MY_LIMITS_MEMORYvalueFrom:resourceFieldRef:containerName: ubuntu-curlresource: limits.memoryrestartPolicy: Never # 執行完畢后退出,不重啟,默認時Always

Downward API提供的變量有:

  • requests.cpu
  • limits.cpu
  • requests.memory
  • limits.memory
  • limits.ephemeral-storage
  • requests.ephemeral-storage

3、作用

某些程序啟動時,可能需要自身的某些信息(自身標示或者IP)然后注冊到服務注冊中心的地方,這時可以使用啟動腳本將注入的POD信息寫到配置文件中,然后啟動程序。

6、Pod生命周期和重啟策略

1、生命周期

狀態描述
pendingAPI Server已經創建該Pod,但是Pod中還有容器沒有創建,包括鏡像下載的過程
RunningPod內所有容器都已經創建,容器處于運行、正在啟動、正在重啟狀態
Complete/SucceededPod中所有容器都已經成功執行并且退出,且不會再重啟
FailedPod中所有容器都已退出,但有容器的退出狀態為失敗(exitcode非0)
Unknown網絡不通,無法獲取狀態

2、重啟策略

yaml文件中restartPolicy的取值:

  • Always:容器失效時,kubelet自動重啟該容器
  • OnFailure:容器終止且退出code不為0時,由kubelet自動重啟該容器
  • Never:無論容器運行狀態如何,kubelet都不會重啟該容器

重啟的時間:sync-frequency*2n,最長延遲5分鐘,并且在成功重啟后的10分鐘后重置改時間。

總結:需要長時間運行的程序設置為Always,只需要執行一次的程序設置為Never或者OnFailure

7、Pod健康檢查和服務可用性檢查

Kubernetes提供三種方式進行Pod中容器的健康檢查,健康檢查不通過時會依據配置的重啟策略進行重啟。

1、在容器中執行命令

2、TCP連接測試

3、HTTP請求測試

TCP和HTTP方式即使失敗,退出碼也是0,所以配置為Never的情況下,失敗會變成Complete

1、執行命令

apiVersion: v1 kind: Pod metadata:name: test-liveness-cmd spec:containers:- name: ubuntu-curlimage: nanda/ubuntu-curl:v1command: - sh- -cargs:- echo ok > /tmp/health; sleep 10; rm -rf /tmp/health; sleep 600;livenessProbe: # 執行cat /tmp/health命令,如果后面文件不存在時cat命令返回code是0,可以通過執行命令后執行echo $?查看exec:command:- cat- /tmp/healthinitialDelaySeconds: 15 # 延遲15s后執行timeoutSeconds: 1 # 響應超時時間restartPolicy: Never

這里會一直重啟該Pod,這個Pod執行會一直失敗.

2、TCP

apiVersion: v1 kind: Pod metadata:name: test-liveness-tcp spec:containers:- name: nginximage: nginxports:- containerPort: 80livenessProbe: # 與本地的8080端口建立連接,沒有開啟這個端口,所以容器健康檢查會失敗,容器退出tcpSocket:port: 8080initialDelaySeconds: 30 # 延遲30s后執行timeoutSeconds: 1 # 響應超時時間restartPolicy: Never

3、HTTP

apiVersion: v1 kind: Pod metadata:name: test-liveness-http spec:containers:- name: nginximage: nginxports:- containerPort: 80livenessProbe: # 訪問localhost:80/_status/healthz,nginx沒有,所以會404,健康檢查失敗容器退出httpGet:path: /_status/healthzport: 80initialDelaySeconds: 30 # 延遲30s后執行timeoutSeconds: 1 # 響應超時時間restartPolicy: Never

8、Pod調度

https://kubernetes.io/zh/docs/concepts/scheduling-eviction/

我們的Pod可能根據不同的情況需要被調度到不同的Node上,可能存在以下幾種情況:

1、web應用,不限定node

2、數據庫類Pod部署到ssd的node上

3、某兩個pod不能部署到同一個node上或者某 兩個pod必須部署到同一個node上(共用網絡和數據卷)

4、zk、es、mongo、kafka,必須部署到不同的node上,恢復后需要掛載原來的volume,復雜

5、日志采集、性能采集每個node上都需要有且部署一個

1、全自動調度:Deployment

Deployment可以控制指定Pod的數量,且可以實現全自動調度。

Deployment也是依據ReplicaSet來進行管理Pod的,所以我們創建一個Deployment的時候也會創建一個ReplicaSet對象。

1、部署三個Nginx Pod

apiVersion: apps/v1 kind: Deployment metadata:name: nginx-deployment spec:replicas: 3selector:matchLabels:app: nginx-deploymenttemplate:metadata:labels:app: nginx-deploymentspec:containers:- name: nginx-deploymentimage: nginxresources:limits:memory: "128Mi"cpu: "250m"ports:- containerPort: 80

2、兩個版本的nginx,共三個,TODO

2、定向調度

https://kubernetes.io/zh/docs/concepts/scheduling-eviction/assign-pod-node/

將Pod調度到指定的node上

1、給node打上標簽

有兩種方式打標簽,命令行和文件的方式,都是在master結點上進行。

1、命令行

kubectl label nodes <node-name> <label-key>=<label-value>

例如,給node1結點打上disk=ssd的標簽

kubectl label nodes node1 disk=ssd

tips:

查看每個node上的labels

kubectl get nodes --show-labels

通過查看,我們可以知道每個node的一些基本信息:操作系統、系統架構、主機名等信息都已經默認作為label標記在node上了。

刪除指定node上的label

kubectl label nodes node1 disk-

修改指定node上label值

沒有就會新建,相當于save=create or update

kubectl label nodes node1 disk=ssd --overwrite

2、將Pod調度到指定node

apiVersion: v1 kind: ReplicationController metadata:name: redis-master spec:replicas: 1selector:app: redis-mastertemplate:metadata:name: redis-masterlabels:app: redis-masterspec:containers:- name: redis-masterimage: redis ports:- containerPort: 6379# 將該rc控制的pod調度到打了disk=ssd的node上,標簽不存在或者沒有可用的node時就會調度失敗nodeSelector:disk: ssd

然后查看pod的情況,即可看到pod已經調度到了指定的node上了

kubectl get pods -o wide

3、注意點

  • 如果指定的標簽多個node有,則由schedule自動選擇一個可用節點進行調度
  • 如果指定標簽的node沒有或者不存在,則調度會失敗,pod的狀態會一直處于Pending的狀態
  • 屬于一種比較強硬的限制調度的手段

3、Node親和性調度

上面的定向調度nodeselector屬于一種硬限制,而且只能將Pods調度到指定的Nodes上。

NodeAffinity調度屬于升級版,既可以支持硬限制,也可以支持軟限制:優先級、順序、權重。

IgnoreDuringExecution:如果在Pod運行期間標簽發生了變更,不再符合Pod的親和性需求,系統將會忽略該變化,Pod能繼續在該節點運行

分為:

1、RequiredDuringSchedulingIgnoreDuringExecution:硬限制

對于定向調度的,我們可以這樣寫,也是一樣的效果

apiVersion: v1 kind: Pod metadata:name: scheduling-softlabels:name: scheduling-soft spec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: diskoperator: Invalues: - ssd1containers:- name: scheduling-softimage: redisresources:limits:memory: "128Mi"cpu: "250m"ports:- containerPort: 6379

2、PreferredDuringSchedulingignoredDuringExecution:軟限制

例如上面的例子,如果disk=ssd標簽的node不存在或者不可用,定向調度就會失敗,我們使用軟限制就可以讓其退而求其次在其他node上進行調度:

apiVersion: v1 kind: Pod metadata:name: scheduling-softlabels:name: scheduling-soft spec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: beta.kubernetes.io/archoperator: Invalues: - amd64preferredDuringSchedulingIgnoredDuringExecution:- weight: 1preference:matchExpressions:- key: diskoperator: Invalues: - ssd1containers:- name: scheduling-softimage: redisresources:limits:memory: "128Mi"cpu: "250m"ports:- containerPort: 6379

此時,我們的node上都沒有disk=ssd1這個標簽,但是還是能正常調度到其它node上。

Note:operator操作包括:In、NotIn、Exists、DoesNotExist、Gt、Lt

1、注意點

  • 定向調度nodeSelector和親和性調度nodeAffinity同時存在時,必須兩個都滿足才能正常調度。是"and與"的關系。
  • 親和性調度的硬限制,nodeSelectorTerms之間是"or或"的關系,而matchExpressions是"and與"的關系。

2、調度到指定的node

apiVersion: v1 kind: Pod metadata:name: nginx spec:containers:- name: nginximage: nginxnodeName: node1

4、Pod親和和互斥調度

該功能1.4引入,前面的定向調度和node親和性調度是站在node的角度上來對pod進行調度,但是我們有些需求是做pod之間的親和和互斥,例如前端工程pod和后端工程pod部署在同一node上,mysql不能和redis部署在同一node上。

這時我們就可以使用Pod親和和互斥調度

1、親和性

1、首先創建一個參考模板Pod

apiVersion: v1 kind: Pod metadata:name: nginxlabels:name: nginx spec:containers:- name: nginximage: nginxresources:limits:memory: "128Mi"cpu: "500m"ports:- containerPort: 80

2、創建一個帶有親和性規則的Pod

其實Pod的親和性調度還是依賴Pod上的標簽,從需要指定topologyKey屬性就可以看出來,親和性規則:

在具有標簽X的Node上運行了一個或者多個符合條件Y的Pod,那么該Pod應該允許在這個Node上

這里有兩個條件:1、標簽X的node 2、符合條件Y的Pod

但是我們可以推廣第一個條件為全部的node,此時我們可以設置這個標簽為每個node都有的默認的標簽,例如:kubernetes.io/hostname

apiVersion: v1 kind: Pod metadata:name: pod-affinitylabels:name: pod-affinity spec:containers:- name: pod-affinityimage: tomcatresources:limits:memory: "128Mi"cpu: "250m"ports:- containerPort: 8080affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: nameoperator: Invalues: - nginxtopologyKey: kubernetes.io/hostname

此時我們再查看node就會發現,兩個pod就調度到同一個node節點上了。

2、互斥性

一個Pod不能和另外一個Pod調度到同一臺機器上,可以使用podAntAffinity,指定另外一個Pod的標簽。

apiVersion: v1 kind: Pod metadata:name: pod-affinity-mutexlabels:name: pod-affinity-mutex spec:containers:- name: pod-affinity-muteximage: tomcatresources:limits:memory: "128Mi"cpu: "250m"ports:- containerPort: 8080affinity:# 互斥podAntAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: nameoperator: Invalues: - nginxtopologyKey: kubernetes.io/hostname

5、污點Taints和容忍Tolerations

https://kubernetes.io/zh/docs/concepts/scheduling-eviction/taint-and-toleration/

前面的調度是讓Pod調度到node節點上,而Taints是讓node拒絕Pod的運行。

Taints是node的屬性,Tolerations是Pod的屬性,node有taints,除非Pod明確表明能夠容忍node的Taints,否則無法Pod無法調度或者運行在指定的node上。

1、設置Taints

1、禁止再將Pod調度到該node

# 給node1添加一個鍵為key,值為value,效果為NoSchedule的taints。 kubectl taint nodes node1 key=value:NoSchedule# 刪除,后面加個減號 kubectl taint nodes node1 key=value:NoSchedule-# 查看node的所有Taints kubectl describe node node2 | grep Taints

效果:

effect描述
NoSchedule沒有指定Tolerations的Pod不會被調度到該node,master節點配置了這個屬性,key為node-role.kubernetes.io/master
PreferNoSchedule沒有指定Tolerations的Pod不會被優先調度到該node
NoExecute沒有指定Tolerations的Pod會被立即驅逐,指定tolerationSeconds后會在指定時間后被驅逐

2、設置Tolerations

apiVersion: v1 kind: Pod metadata:name: nginxlabels:env: test spec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresenttolerations:- key: "key"operator: "Exists"effect: "NoSchedule"

operator的取值:Equal、Exist

effect的取值:NoSchedule、PreferNoSchedule(盡量避免調度,非強制)、NoExecute

operator一些規則:

  • operator的值是Exists,則無需指定value
  • operator的值是Equal并且value相等

使用場景:

1、部分node只給指定應用用,在node添加NoSchedule的taints,然后只在指定Pod上設置tolerations

2、node故障時,通過給node添加taints驅逐node上的pods

3、kubernetes的node有問題或者網絡有問題時,會自動給node添加內置的taint使之無法調度到該節點

6、Pod優先級調度

https://kubernetes.io/zh/docs/concepts/scheduling-eviction/pod-priority-preemption/

1、創建PriorityClasses

apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata:name: high-priority # 超過一億被系統保留,給系統組件使用 value: 1000000 globalDefault: false description: "description priority"

scheduling.k8s.io/v1beta1 PriorityClass is deprecated in v1.14+, unavailable in v1.22+; use scheduling.k8s.io/v1 PriorityClass

1.22中PriorityClass就成了正式版了

2、指定Pod的優先級

集群情況:兩個node,每個node一個CPU,2G內存

先部署兩個redis,每個使用半個CPU,將所有資源占滿,再部署一個高優先級的使用半個CPU的tomcat,此時tomcat調度時就會驅逐掉一個redis

apiVersion: v1 kind: ReplicationController metadata:name: redis-master spec:replicas: 2selector:app: redis-mastertemplate:metadata:name: redis-masterlabels:app: redis-masterspec:containers:- name: redis-masterimage: redis ports:- containerPort: 6379resources:limits:memory: "128Mi"cpu: "500m" apiVersion: v1 kind: ReplicationController metadata:name: tomcat spec:replicas: 1selector:app: tomcattemplate:metadata:name: tomcatlabels:app: tomcatspec:containers:- name: tomcatimage: tomcat ports:- containerPort: 8080resources:limits:memory: "128Mi"cpu: "500m"priorityClassName: high-priority

3、缺點

  • 復雜性增加
  • 可能帶來不穩定因素
  • 資源緊張應該考慮擴容
  • 如果非要使用,可以考慮有監管的優先級調度

7、DaemonSet每個Node上部署一個Pod

https://kubernetes.io/zh/docs/concepts/workloads/controllers/daemonset/

需求:

  • 每個Node上都運行一個日志采集程序,例如:Logstach
  • 每個Node上都運行一個性能監控程序,例如:Prometheus Node Exporter
  • 每個Node上都運行一個GlusterFS存儲或者Ceph存儲的Daemon進程

使用:

apiVersion: apps/v1 kind: DaemonSet metadata:name: fluentd-elasticsearchnamespace: kube-systemlabels:k8s-app: fluentd-logging spec:selector:matchLabels:name: fluentd-elasticsearch# 滾動升級updateStrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 1template:metadata:labels:name: fluentd-elasticsearchspec:tolerations:# this toleration is to have the daemonset runnable on master nodes# remove it if your masters can't run pods- key: node-role.kubernetes.io/mastereffect: NoSchedulecontainers:- name: fluentd-elasticsearchimage: quay.io/fluentd_elasticsearch/fluentd:v2.5.2resources:limits:memory: 200Mirequests:cpu: 100mmemory: 200MivolumeMounts:- name: varlogmountPath: /var/log- name: varlibdockercontainersmountPath: /var/lib/docker/containersreadOnly: trueterminationGracePeriodSeconds: 30volumes:- name: varloghostPath:path: /var/log- name: varlibdockercontainershostPath:path: /var/lib/docker/containers

此時,包括master也會部署一個node。

1.6版本后,DaemonSet也能進行滾動升級。

1、刪除

刪除掉DaemonSet,默認不會刪除每個node上的Pod,添加–cascade=false命令,將會一起刪除每個node上的Pod。

2、在部分節點上部署

通過使用nodeSelect進行過濾,參考Pod親和性和互斥

3、滾動升級

https://kubernetes.io/zh/docs/tasks/manage-daemon/update-daemon-set/

1、yaml文件中進行配置更新策略為滾動升級

2、修改配置后進行apply操作

8、Job批處理調度

https://kubernetes.io/zh/docs/concepts/workloads/controllers/job/

基本格式:

apiVersion: batch/v1 kind: Job metadata:name: pi spec:completions: 8 # Pod的執行次數parallelism: 2 # Pod的并行個數template:spec:containers:- name: piimage: perlcommand: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]restartPolicy: NeverbackoffLimit: 4 # 重試次數

三種使用方式:

1、一個任務創建一個Job,一個Job執行一個Pod

2、多個任務創建一個Job(使用Redis隊列),一個Job執行多個Pod,N個任務N個Job

3、多個任務創建一個Job(使用Redis隊列),一個Job執行多個Pod,N個任務M個Job

9、Cronjob定時任務

https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/

apiVersion: batch/v1beta1 kind: CronJob metadata:name: hello spec:schedule: "*/1 * * * *"jobTemplate:spec:template:spec:containers:- name: helloimage: busyboximagePullPolicy: IfNotPresentcommand:- /bin/sh- -c- date; echo Hello from the Kubernetes clusterrestartPolicy: OnFailure

CronJob類型apiVersion在1.18中是batch/v1beta1,書籍和官方最新文檔是v1,沒搞懂是什么情況。TODO

創建CronJob之后,每隔一分鐘就會創建一個Pod執行一次。

1、CRON語法

# ┌───────────── minute (0 - 59) # │ ┌───────────── hour (0 - 23) # │ │ ┌───────────── day of the month (1 - 31) # │ │ │ ┌───────────── month (1 - 12) # │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday; # │ │ │ │ │ 7 is also Sunday on some systems) # │ │ │ │ │ # │ │ │ │ │ # * * * * * EntryDescriptionEquivalent to
@yearly (or @annually)Run once a year at midnight of 1 January0 0 1 1 *
@monthlyRun once a month at midnight of the first day of the month0 0 1 * *
@weeklyRun once a week at midnight on Sunday morning0 0 * * 0
@daily (or @midnight)Run once a day at midnight0 0 * * *
@hourlyRun once an hour at the beginning of the hour0 * * * *

*和/的作用:

*:任意值

/:表示從起始時間開始,每隔固定時間觸發一次;例如*/1 * * * *表示從現在開始每隔一分鐘執行一次

計算網站:

https://crontab.guru/

10、自定義調度器

TODO

9、Init Container

https://kubernetes.io/zh/docs/concepts/workloads/pods/init-containers/

1.3版本引入,應用啟動之前啟動一個初始化容器,完成應用啟動前的預置條件,例如

  • 等待關聯組件正確運行(數據庫或者后臺服務)
  • 基于環境變量和配置模板生成配置文件
  • 從遠程數據庫獲取本地所需配置
  • 下載相關依賴包,或者對系統進行預配置

例子:初始化Nginx前,為Nginx創建一個Index.html(Nginx鏡像沒有index.html文件,訪問localhost:80會404)

apiVersion: v1 kind: Pod metadata:name: nginxlabels:name: nginx spec:initContainers:- name: init-nginx-indeximage: busybox# 將百度主頁下載到/work-dir/下command: - wget - "-O"- "/work-dir/index.html"- http://www.baidu.comvolumeMounts:- name: workdirmountPath: /work-dircontainers:- name: nginximage: nginxresources:limits:memory: "128Mi"cpu: "500m"ports:- containerPort: 80volumeMounts:- name: workdirmountPath: /usr/share/nginx/htmlvolumes:- name: workdiremptyDir: {}

查看init-container日志

kubectl logs nginx -c init-nginx-index

初始化容器與Pod的區別:

  • 多個init-container依次按順序運行
  • 多個init-container都設置了資源限制,取最大值作為所有init-container的資源限制值
  • Pod資源限制在:1、所有容器資源限制之和 2、init-container資源限制值,中取最大值

10、Pod的升級和回滾

1、滾動升級

新建一個deployment

apiVersion: apps/v1 kind: Deployment # Deployment metadata:name: mynginx # Deployment的名稱,全局唯一 spec:replicas: 3 # Pod副本的期待數量selector:matchLabels: # 注意這里寫法和RC的不一樣,因為支持多個selectorapp: mynginx # 符合目標的pod擁有此標簽,===1此處應當一致template: # 根據此模板創建pod的副本metadata:labels:app: mynginx # pod副本擁有的標簽,===1此處應當一致spec:containers: # pod中容器的定義部分- name: mynginx # 容器名稱image: nginx:1.7.9 # 容器對應的docker鏡像ports:- containerPort: 80 # 容器應用監聽的端口號 # 查看滾動升級過程,完成后就只有成功的日志了 kubectl rollout status deployment/deployment名稱
  • 修改deployment鏡像
# 格式 kubectl set image deployment/deployment名稱 容器名稱=鏡像名稱:鏡像版本# 例如 kubectl set image deployment/mynginx mynginx=nginx:1.9.1

此時為滾動升級,先運行一個新的,新的運行起來后,再停止一個舊的;主要通過新建一個RS,然后調整兩個RS的數量

  • 修改deployment的配置
# 格式 kubectl edit deployment/deployment名稱# 例如 kubectl edit deployment/mynginx

1、更新的策略

Deployment的更新由對應yaml文件中的配置指定,下面是默認值

spec:strategy:rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdate

type有兩種取值:recreate(停止所有舊的,再啟動新的)和RollingUpdate(默認)

maxSurge:滾動升級過程中,Pod總數超過Pod期望副本數部分的最大值,向上取整

maxUnavailable:滾動升級過程中,可用Pod占Pod總數的百分比,向下取整,也可以是大于零的絕對值。

2、多重更新

在上一次更新途中,如果又觸發一次更新操作,將會終止上一次更新創建的Pod,然后再進行更新

3、增刪改Deployment標簽選擇器的問題

新增或者修改Deployment的標簽選擇器時,必須修改Pod上的標簽,不然原本的Pod會處于孤立狀態,不會被系統自動刪除,也不受新的RS控制。

刪除Deployment標簽選擇器,對應的RS和Pod不會受到任何的影響。

2、回滾

1、查看歷史版本

# 查看Depolyment的歷史 kubectl rollout history deployment/mynginx# 查看指定版本Depolyment的詳情信息 kubectl rollout history deployment/mynginx --revision=4# ??????只有更新Deployment時加上--record=true時才會記錄該條歷史 kubectl set image deployment/mynginx mynginx=nginx:1.9.1 --record=true

2、回滾到指定版本

# 回滾到上一個版本 kubectl rollout undo deployment/mynginx# 回滾到指定版本 kubectl rollout undo deployment/mynginx --to-revision=3

3、暫停和恢復Deployment的部署操作

# 暫停Deployment的更新,暫停后對deployment的更新不會觸發操作,只有恢復后才會進行 kubectl rollout pause deployment/mynginx# 恢復Deployment的更新 kubectl rollout resume deployment/mynginx

暫停和更新有助于我們對Deployment進行復雜的修改

4、RC的滾動升級

# 使用一個新的RC代替舊的RC kubectl rolling-update old-rc-name -f new-rc.yaml# 修改舊的RC鏡像 kubectl rolling-update old-rc-name --image=image-name:version

5、DaemonSet滾動升級

1、配置DaemonSet的yaml滾動策略為RollingUpdate(1.6引入)

2、apply舊版本配置文件

總結

以上是生活随笔為你收集整理的1、深入理解Pod的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。