日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

1、深入理解Pod

發(fā)布時(shí)間:2023/12/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1、深入理解Pod 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1、基本用法

1、對(duì)于容器的要求

kubernetes對(duì)長(zhǎng)時(shí)間運(yùn)行的容器要求:必須一直在前臺(tái)執(zhí)行。如果是后臺(tái)執(zhí)行的程序,例如

Nohup ./start.sh &

則會(huì)在執(zhí)行完成之后銷毀Pod,但是可以借助一些方式讓后臺(tái)程序在前臺(tái)執(zhí)行,例如supervisor

2、一個(gè)Pod多個(gè)容器

? 如果兩個(gè)容器耦合性較強(qiáng),可以放在一個(gè)Pod里面,此時(shí)他們可以共享網(wǎng)絡(luò)和文件。例如:

1、前端應(yīng)用容器直接通過localhost訪問后臺(tái)應(yīng)用容器服務(wù);

2、一個(gè)應(yīng)用寫日志到本地,一個(gè)應(yīng)用從本地讀日志;

2、靜態(tài)Pod

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

?

靜態(tài)Pod是指由kubelet管理僅存在于特定Node上的Pod,不能1、通過API Server管理 2、與RC、Deployment關(guān)聯(lián) 3、kubelet無(wú)法進(jìn)行健康檢查

創(chuàng)建靜態(tài)Pod有配置文件和HTTP方式。

1、配置文件

設(shè)置kubelet的啟動(dòng)參數(shù)"–pod-manifest-path=/root/yaml/",對(duì)于該目錄下的yaml或者json文件,kubelet服務(wù)會(huì)定期進(jìn)行掃描和創(chuàng)建。

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

1、刪除Pod

靜態(tài)Pod無(wú)法通過kubectl delete刪除,刪除后狀態(tài)會(huì)變成Pending,刪除需要?jiǎng)h除對(duì)應(yīng)config目錄下的json和yaml配置。

1、HTTP方式

指定kubelet的啟動(dòng)參數(shù)"–manifest-url"。

3、Pod容器共享卷Volume和網(wǎng)絡(luò)

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

一個(gè)Pod內(nèi)存在多個(gè)容器時(shí),容器可以共享掛載卷,實(shí)現(xiàn)同一個(gè)目錄,一個(gè)容器應(yīng)用讀取,一個(gè)容器應(yīng)用寫入。

例如:

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: {}

這里有點(diǎn)要注意:容器啟動(dòng)是異步的,啟動(dòng)順序是安裝配置文件來(lái),但是第二個(gè)啟動(dòng)時(shí)第一個(gè)不一定啟動(dòng)OK了,所有加入linux腳本命令等待第一個(gè)執(zhí)行完畢。

4、Pod的配置管理

kubernetes1.2提供一種統(tǒng)一的應(yīng)用配置管理方案:ConfigMap。注意是通過環(huán)境變量注入到容器,而且可以實(shí)現(xiàn)將node上的文件變?yōu)榕渲?#xff0c;配置然后掛載成容器中的文件。

1、創(chuàng)建ConfigMap

1、YAML配置文件創(chuàng)建

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

可以將配置文件的內(nèi)容作為data中的value

2、通過命令行創(chuàng)建

# 從目錄中進(jìn)行創(chuàng)建,文件名作為key,文件內(nèi)容作為value kubectl create configmap ConfigMap名稱 --from-file=目錄

2、在Pod中使用ConfigMap

1、通過環(huán)境變量進(jìn)行使用

1、通過環(huán)境變量

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 # 執(zhí)行完畢后退出,不重啟,默認(rèn)時(shí)Always

2、1.6之后的新字段envFrom將ConfigMap中所有定義的key=value自動(dòng)生成環(huán)境變量

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 # 執(zhí)行完畢后退出,不重啟,默認(rèn)時(shí)Always

2、通過volumeMount使用ConfigMap

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

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中的那些項(xiàng)將被掛載- key: apploglevel # configmap中的keypath: apploglevel.txt # 文件名- key: appdatadir # configmap中的keypath: appdatadir.log # 文件名restartPolicy: Never # 執(zhí)行完畢后退出,不重啟,默認(rèn)時(shí)Always

2、掛載configmap中的所有配置

此時(shí)無(wú)法指定文件名了,只能以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 # 執(zhí)行完畢后退出,不重啟,默認(rèn)時(shí)Always

3、ConfigMap的限制

1、必須在Pod前創(chuàng)建

2、受namespace限制

3、靜態(tài)Pod無(wú)法使用

4、文件掛載時(shí),會(huì)覆蓋容器內(nèi)原本的文件

5、容器內(nèi)獲取Pod信息

主要是通過Downward API進(jìn)行注入,兩種方式:1、環(huán)境變量 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 # 執(zhí)行完畢后退出,不重啟,默認(rèn)時(shí)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 # 執(zhí)行完畢后退出,不重啟,默認(rèn)時(shí)Always

Downward API提供的變量有:

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

3、作用

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

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

1、生命周期

狀態(tài)描述
pendingAPI Server已經(jīng)創(chuàng)建該P(yáng)od,但是Pod中還有容器沒有創(chuàng)建,包括鏡像下載的過程
RunningPod內(nèi)所有容器都已經(jīng)創(chuàng)建,容器處于運(yùn)行、正在啟動(dòng)、正在重啟狀態(tài)
Complete/SucceededPod中所有容器都已經(jīng)成功執(zhí)行并且退出,且不會(huì)再重啟
FailedPod中所有容器都已退出,但有容器的退出狀態(tài)為失敗(exitcode非0)
Unknown網(wǎng)絡(luò)不通,無(wú)法獲取狀態(tài)

2、重啟策略

yaml文件中restartPolicy的取值:

  • Always:容器失效時(shí),kubelet自動(dòng)重啟該容器
  • OnFailure:容器終止且退出code不為0時(shí),由kubelet自動(dòng)重啟該容器
  • Never:無(wú)論容器運(yùn)行狀態(tài)如何,kubelet都不會(huì)重啟該容器

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

總結(jié):需要長(zhǎng)時(shí)間運(yùn)行的程序設(shè)置為Always,只需要執(zhí)行一次的程序設(shè)置為Never或者OnFailure

7、Pod健康檢查和服務(wù)可用性檢查

Kubernetes提供三種方式進(jìn)行Pod中容器的健康檢查,健康檢查不通過時(shí)會(huì)依據(jù)配置的重啟策略進(jìn)行重啟。

1、在容器中執(zhí)行命令

2、TCP連接測(cè)試

3、HTTP請(qǐng)求測(cè)試

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

1、執(zhí)行命令

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: # 執(zhí)行cat /tmp/health命令,如果后面文件不存在時(shí)cat命令返回code是0,可以通過執(zhí)行命令后執(zhí)行echo $?查看exec:command:- cat- /tmp/healthinitialDelaySeconds: 15 # 延遲15s后執(zhí)行timeoutSeconds: 1 # 響應(yīng)超時(shí)時(shí)間restartPolicy: Never

這里會(huì)一直重啟該P(yáng)od,這個(gè)Pod執(zhí)行會(huì)一直失敗.

2、TCP

apiVersion: v1 kind: Pod metadata:name: test-liveness-tcp spec:containers:- name: nginximage: nginxports:- containerPort: 80livenessProbe: # 與本地的8080端口建立連接,沒有開啟這個(gè)端口,所以容器健康檢查會(huì)失敗,容器退出tcpSocket:port: 8080initialDelaySeconds: 30 # 延遲30s后執(zhí)行timeoutSeconds: 1 # 響應(yīng)超時(shí)時(shí)間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沒有,所以會(huì)404,健康檢查失敗容器退出httpGet:path: /_status/healthzport: 80initialDelaySeconds: 30 # 延遲30s后執(zhí)行timeoutSeconds: 1 # 響應(yīng)超時(shí)時(shí)間restartPolicy: Never

8、Pod調(diào)度

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

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

1、web應(yīng)用,不限定node

2、數(shù)據(jù)庫(kù)類Pod部署到ssd的node上

3、某兩個(gè)pod不能部署到同一個(gè)node上或者某 兩個(gè)pod必須部署到同一個(gè)node上(共用網(wǎng)絡(luò)和數(shù)據(jù)卷)

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

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

1、全自動(dòng)調(diào)度:Deployment

Deployment可以控制指定Pod的數(shù)量,且可以實(shí)現(xiàn)全自動(dòng)調(diào)度。

Deployment也是依據(jù)ReplicaSet來(lái)進(jìn)行管理Pod的,所以我們創(chuàng)建一個(gè)Deployment的時(shí)候也會(huì)創(chuàng)建一個(gè)ReplicaSet對(duì)象。

1、部署三個(gè)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、兩個(gè)版本的nginx,共三個(gè),TODO

2、定向調(diào)度

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

將Pod調(diào)度到指定的node上

1、給node打上標(biāo)簽

有兩種方式打標(biāo)簽,命令行和文件的方式,都是在master結(jié)點(diǎn)上進(jìn)行。

1、命令行

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

例如,給node1結(jié)點(diǎn)打上disk=ssd的標(biāo)簽

kubectl label nodes node1 disk=ssd

tips:

查看每個(gè)node上的labels

kubectl get nodes --show-labels

通過查看,我們可以知道每個(gè)node的一些基本信息:操作系統(tǒng)、系統(tǒng)架構(gòu)、主機(jī)名等信息都已經(jīng)默認(rèn)作為label標(biāo)記在node上了。

刪除指定node上的label

kubectl label nodes node1 disk-

修改指定node上label值

沒有就會(huì)新建,相當(dāng)于save=create or update

kubectl label nodes node1 disk=ssd --overwrite

2、將Pod調(diào)度到指定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調(diào)度到打了disk=ssd的node上,標(biāo)簽不存在或者沒有可用的node時(shí)就會(huì)調(diào)度失敗nodeSelector:disk: ssd

然后查看pod的情況,即可看到pod已經(jīng)調(diào)度到了指定的node上了

kubectl get pods -o wide

3、注意點(diǎn)

  • 如果指定的標(biāo)簽多個(gè)node有,則由schedule自動(dòng)選擇一個(gè)可用節(jié)點(diǎn)進(jìn)行調(diào)度
  • 如果指定標(biāo)簽的node沒有或者不存在,則調(diào)度會(huì)失敗,pod的狀態(tài)會(huì)一直處于Pending的狀態(tài)
  • 屬于一種比較強(qiáng)硬的限制調(diào)度的手段

3、Node親和性調(diào)度

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

NodeAffinity調(diào)度屬于升級(jí)版,既可以支持硬限制,也可以支持軟限制:優(yōu)先級(jí)、順序、權(quán)重。

IgnoreDuringExecution:如果在Pod運(yùn)行期間標(biāo)簽發(fā)生了變更,不再符合Pod的親和性需求,系統(tǒng)將會(huì)忽略該變化,Pod能繼續(xù)在該節(jié)點(diǎn)運(yùn)行

分為:

1、RequiredDuringSchedulingIgnoreDuringExecution:硬限制

對(duì)于定向調(diào)度的,我們可以這樣寫,也是一樣的效果

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標(biāo)簽的node不存在或者不可用,定向調(diào)度就會(huì)失敗,我們使用軟限制就可以讓其退而求其次在其他node上進(jìn)行調(diào)度:

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

此時(shí),我們的node上都沒有disk=ssd1這個(gè)標(biāo)簽,但是還是能正常調(diào)度到其它node上。

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

1、注意點(diǎn)

  • 定向調(diào)度nodeSelector和親和性調(diào)度nodeAffinity同時(shí)存在時(shí),必須兩個(gè)都滿足才能正常調(diào)度。是"and與"的關(guān)系。
  • 親和性調(diào)度的硬限制,nodeSelectorTerms之間是"or或"的關(guān)系,而matchExpressions是"and與"的關(guān)系。

2、調(diào)度到指定的node

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

4、Pod親和和互斥調(diào)度

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

這時(shí)我們就可以使用Pod親和和互斥調(diào)度

1、親和性

1、首先創(chuàng)建一個(gè)參考模板Pod

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

2、創(chuàng)建一個(gè)帶有親和性規(guī)則的Pod

其實(shí)Pod的親和性調(diào)度還是依賴Pod上的標(biāo)簽,從需要指定topologyKey屬性就可以看出來(lái),親和性規(guī)則:

在具有標(biāo)簽X的Node上運(yùn)行了一個(gè)或者多個(gè)符合條件Y的Pod,那么該P(yáng)od應(yīng)該允許在這個(gè)Node上

這里有兩個(gè)條件:1、標(biāo)簽X的node 2、符合條件Y的Pod

但是我們可以推廣第一個(gè)條件為全部的node,此時(shí)我們可以設(shè)置這個(gè)標(biāo)簽為每個(gè)node都有的默認(rèn)的標(biāo)簽,例如: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

此時(shí)我們?cè)俨榭磏ode就會(huì)發(fā)現(xiàn),兩個(gè)pod就調(diào)度到同一個(gè)node節(jié)點(diǎn)上了。

2、互斥性

一個(gè)Pod不能和另外一個(gè)Pod調(diào)度到同一臺(tái)機(jī)器上,可以使用podAntAffinity,指定另外一個(gè)Pod的標(biāo)簽。

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、污點(diǎn)Taints和容忍Tolerations

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

前面的調(diào)度是讓Pod調(diào)度到node節(jié)點(diǎn)上,而Taints是讓node拒絕Pod的運(yùn)行。

Taints是node的屬性,Tolerations是Pod的屬性,node有taints,除非Pod明確表明能夠容忍node的Taints,否則無(wú)法Pod無(wú)法調(diào)度或者運(yùn)行在指定的node上。

1、設(shè)置Taints

1、禁止再將Pod調(diào)度到該node

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

效果:

effect描述
NoSchedule沒有指定Tolerations的Pod不會(huì)被調(diào)度到該node,master節(jié)點(diǎn)配置了這個(gè)屬性,key為node-role.kubernetes.io/master
PreferNoSchedule沒有指定Tolerations的Pod不會(huì)被優(yōu)先調(diào)度到該node
NoExecute沒有指定Tolerations的Pod會(huì)被立即驅(qū)逐,指定tolerationSeconds后會(huì)在指定時(shí)間后被驅(qū)逐

2、設(shè)置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(盡量避免調(diào)度,非強(qiáng)制)、NoExecute

operator一些規(guī)則:

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

使用場(chǎng)景:

1、部分node只給指定應(yīng)用用,在node添加NoSchedule的taints,然后只在指定Pod上設(shè)置tolerations

2、node故障時(shí),通過給node添加taints驅(qū)逐node上的pods

3、kubernetes的node有問題或者網(wǎng)絡(luò)有問題時(shí),會(huì)自動(dòng)給node添加內(nèi)置的taint使之無(wú)法調(diào)度到該節(jié)點(diǎn)

6、Pod優(yōu)先級(jí)調(diào)度

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

1、創(chuàng)建PriorityClasses

apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata:name: high-priority # 超過一億被系統(tǒng)保留,給系統(tǒng)組件使用 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的優(yōu)先級(jí)

集群情況:兩個(gè)node,每個(gè)node一個(gè)CPU,2G內(nèi)存

先部署兩個(gè)redis,每個(gè)使用半個(gè)CPU,將所有資源占滿,再部署一個(gè)高優(yōu)先級(jí)的使用半個(gè)CPU的tomcat,此時(shí)tomcat調(diào)度時(shí)就會(huì)驅(qū)逐掉一個(gè)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、缺點(diǎn)

  • 復(fù)雜性增加
  • 可能帶來(lái)不穩(wěn)定因素
  • 資源緊張應(yīng)該考慮擴(kuò)容
  • 如果非要使用,可以考慮有監(jiān)管的優(yōu)先級(jí)調(diào)度

7、DaemonSet每個(gè)Node上部署一個(gè)Pod

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

需求:

  • 每個(gè)Node上都運(yùn)行一個(gè)日志采集程序,例如:Logstach
  • 每個(gè)Node上都運(yùn)行一個(gè)性能監(jiān)控程序,例如:Prometheus Node Exporter
  • 每個(gè)Node上都運(yùn)行一個(gè)GlusterFS存儲(chǔ)或者Ceph存儲(chǔ)的Daemon進(jìn)程

使用:

apiVersion: apps/v1 kind: DaemonSet metadata:name: fluentd-elasticsearchnamespace: kube-systemlabels:k8s-app: fluentd-logging spec:selector:matchLabels:name: fluentd-elasticsearch# 滾動(dòng)升級(jí)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

此時(shí),包括master也會(huì)部署一個(gè)node。

1.6版本后,DaemonSet也能進(jìn)行滾動(dòng)升級(jí)。

1、刪除

刪除掉DaemonSet,默認(rèn)不會(huì)刪除每個(gè)node上的Pod,添加–cascade=false命令,將會(huì)一起刪除每個(gè)node上的Pod。

2、在部分節(jié)點(diǎn)上部署

通過使用nodeSelect進(jìn)行過濾,參考Pod親和性和互斥

3、滾動(dòng)升級(jí)

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

1、yaml文件中進(jìn)行配置更新策略為滾動(dòng)升級(jí)

2、修改配置后進(jìn)行apply操作

8、Job批處理調(diào)度

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

基本格式:

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

三種使用方式:

1、一個(gè)任務(wù)創(chuàng)建一個(gè)Job,一個(gè)Job執(zhí)行一個(gè)Pod

2、多個(gè)任務(wù)創(chuàng)建一個(gè)Job(使用Redis隊(duì)列),一個(gè)Job執(zhí)行多個(gè)Pod,N個(gè)任務(wù)N個(gè)Job

3、多個(gè)任務(wù)創(chuàng)建一個(gè)Job(使用Redis隊(duì)列),一個(gè)Job執(zhí)行多個(gè)Pod,N個(gè)任務(wù)M個(gè)Job

9、Cronjob定時(shí)任務(wù)

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

創(chuàng)建CronJob之后,每隔一分鐘就會(huì)創(chuàng)建一個(gè)Pod執(zhí)行一次。

1、CRON語(yǔ)法

# ┌───────────── 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 * * * *

*和/的作用:

*:任意值

/:表示從起始時(shí)間開始,每隔固定時(shí)間觸發(fā)一次;例如*/1 * * * *表示從現(xiàn)在開始每隔一分鐘執(zhí)行一次

計(jì)算網(wǎng)站:

https://crontab.guru/

10、自定義調(diào)度器

TODO

9、Init Container

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

1.3版本引入,應(yīng)用啟動(dòng)之前啟動(dòng)一個(gè)初始化容器,完成應(yīng)用啟動(dòng)前的預(yù)置條件,例如

  • 等待關(guān)聯(lián)組件正確運(yùn)行(數(shù)據(jù)庫(kù)或者后臺(tái)服務(wù))
  • 基于環(huán)境變量和配置模板生成配置文件
  • 從遠(yuǎn)程數(shù)據(jù)庫(kù)獲取本地所需配置
  • 下載相關(guān)依賴包,或者對(duì)系統(tǒng)進(jìn)行預(yù)配置

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

apiVersion: v1 kind: Pod metadata:name: nginxlabels:name: nginx spec:initContainers:- name: init-nginx-indeximage: busybox# 將百度主頁(yè)下載到/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的區(qū)別:

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

10、Pod的升級(jí)和回滾

1、滾動(dòng)升級(jí)

新建一個(gè)deployment

apiVersion: apps/v1 kind: Deployment # Deployment metadata:name: mynginx # Deployment的名稱,全局唯一 spec:replicas: 3 # Pod副本的期待數(shù)量selector:matchLabels: # 注意這里寫法和RC的不一樣,因?yàn)橹С侄鄠€(gè)selectorapp: mynginx # 符合目標(biāo)的pod擁有此標(biāo)簽,===1此處應(yīng)當(dāng)一致template: # 根據(jù)此模板創(chuàng)建pod的副本metadata:labels:app: mynginx # pod副本擁有的標(biāo)簽,===1此處應(yīng)當(dāng)一致spec:containers: # pod中容器的定義部分- name: mynginx # 容器名稱image: nginx:1.7.9 # 容器對(duì)應(yīng)的docker鏡像ports:- containerPort: 80 # 容器應(yīng)用監(jiān)聽的端口號(hào) # 查看滾動(dòng)升級(jí)過程,完成后就只有成功的日志了 kubectl rollout status deployment/deployment名稱
  • 修改deployment鏡像
# 格式 kubectl set image deployment/deployment名稱 容器名稱=鏡像名稱:鏡像版本# 例如 kubectl set image deployment/mynginx mynginx=nginx:1.9.1

此時(shí)為滾動(dòng)升級(jí),先運(yùn)行一個(gè)新的,新的運(yùn)行起來(lái)后,再停止一個(gè)舊的;主要通過新建一個(gè)RS,然后調(diào)整兩個(gè)RS的數(shù)量

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

1、更新的策略

Deployment的更新由對(duì)應(yīng)yaml文件中的配置指定,下面是默認(rèn)值

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

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

maxSurge:滾動(dòng)升級(jí)過程中,Pod總數(shù)超過Pod期望副本數(shù)部分的最大值,向上取整

maxUnavailable:滾動(dòng)升級(jí)過程中,可用Pod占Pod總數(shù)的百分比,向下取整,也可以是大于零的絕對(duì)值。

2、多重更新

在上一次更新途中,如果又觸發(fā)一次更新操作,將會(huì)終止上一次更新創(chuàng)建的Pod,然后再進(jìn)行更新

3、增刪改Deployment標(biāo)簽選擇器的問題

新增或者修改Deployment的標(biāo)簽選擇器時(shí),必須修改Pod上的標(biāo)簽,不然原本的Pod會(huì)處于孤立狀態(tài),不會(huì)被系統(tǒng)自動(dòng)刪除,也不受新的RS控制。

刪除Deployment標(biāo)簽選擇器,對(duì)應(yīng)的RS和Pod不會(huì)受到任何的影響。

2、回滾

1、查看歷史版本

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

2、回滾到指定版本

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

3、暫停和恢復(fù)Deployment的部署操作

# 暫停Deployment的更新,暫停后對(duì)deployment的更新不會(huì)觸發(fā)操作,只有恢復(fù)后才會(huì)進(jìn)行 kubectl rollout pause deployment/mynginx# 恢復(fù)Deployment的更新 kubectl rollout resume deployment/mynginx

暫停和更新有助于我們對(duì)Deployment進(jìn)行復(fù)雜的修改

4、RC的滾動(dòng)升級(jí)

# 使用一個(gè)新的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滾動(dòng)升級(jí)

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

2、apply舊版本配置文件

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。