1、深入理解Pod
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: TCP1、刪除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í)Always2、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í)Always2、通過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í)Always2、掛載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í)Always3、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í)AlwaysDownward 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í)AlwaysDownward 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、生命周期
| pending | API Server已經(jīng)創(chuàng)建該P(yáng)od,但是Pod中還有容器沒有創(chuàng)建,包括鏡像下載的過程 |
| Running | Pod內(nèi)所有容器都已經(jīng)創(chuàng)建,容器處于運(yùn)行、正在啟動(dòng)、正在重啟狀態(tài) |
| Complete/Succeeded | Pod中所有容器都已經(jīng)成功執(zhí)行并且退出,且不會(huì)再重啟 |
| Failed | Pod中所有容器都已退出,但有容器的退出狀態(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: Never3、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: Never8、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: 802、兩個(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=ssdtips:
查看每個(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 --overwrite2、將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 wide3、注意點(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: 63792、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: node14、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: 802、創(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/hostname5、污點(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效果:
| 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-priority3、缺點(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: OnFailureCronJob類型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) # │ │ │ │ │ # │ │ │ │ │ # * * * * *| @yearly (or @annually) | Run once a year at midnight of 1 January | 0 0 1 1 * |
| @monthly | Run once a month at midnight of the first day of the month | 0 0 1 * * |
| @weekly | Run once a week at midnight on Sunday morning | 0 0 * * 0 |
| @daily (or @midnight) | Run once a day at midnight | 0 0 * * * |
| @hourly | Run once an hour at the beginning of the hour | 0 * * * * |
*和/的作用:
*:任意值
/:表示從起始時(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鏡像
此時(shí)為滾動(dòng)升級(jí),先運(yùn)行一個(gè)新的,新的運(yùn)行起來(lái)后,再停止一個(gè)舊的;主要通過新建一個(gè)RS,然后調(diào)整兩個(gè)RS的數(shù)量
- 修改deployment的配置
1、更新的策略
Deployment的更新由對(duì)應(yīng)yaml文件中的配置指定,下面是默認(rèn)值
spec:strategy:rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdatetype有兩種取值: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=true2、回滾到指定版本
# 回滾到上一個(gè)版本 kubectl rollout undo deployment/mynginx# 回滾到指定版本 kubectl rollout undo deployment/mynginx --to-revision=33、暫停和恢復(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:version5、DaemonSet滾動(dòng)升級(jí)
1、配置DaemonSet的yaml滾動(dòng)策略為RollingUpdate(1.6引入)
2、apply舊版本配置文件
總結(jié)
- 上一篇: 病毒木马查杀实战第010篇:QQ盗号木马
- 下一篇: 网络安全之暴露面、攻击面、脆弱性