Kubernetes應(yīng)用服務(wù)質(zhì)量管理詳解
服務(wù)質(zhì)量管理
在Kubernetes中,Pod是最小的調(diào)度單元,所以跟資源和調(diào)度相關(guān)的屬性都是Pod對(duì)象的字段,而其中最重要的就是CPU和內(nèi)存。
如下所示:
--- apiVersion: v1 kind: Pod metadata: name: pod-demo spec: containers: - name: myweb image: wordpress imagePullPolicy: IfNotPresent resources: requests: memory: "128Mi" cpu: "250m" limits: memory: "256Mi" cpu: "500m"
其中resources就是資源限制部分。
注:由于一個(gè)Pod里可以定義多個(gè)Containers,而每個(gè)資源限制都是配置在各自的Container,所以Pod的整體配置資源是所有Containers的總和。
在Kubernetes中,CPU這樣的資源被稱為"可壓縮資源",所謂可壓縮資源就是當(dāng)可用資源不足的時(shí)候,Pod只會(huì)"饑餓",不會(huì)退出。而向Memory這樣的資源被稱為"不可壓縮資源",所謂的不可壓縮資源就是當(dāng)資源不足的時(shí)候Pod只會(huì)OOM。
其中CPU的設(shè)置單位是CPU的個(gè)數(shù),比如CPU=1就表示這個(gè)Pod的CPU限額是1個(gè)CPU,而到底是1個(gè)CPU核心、是1個(gè)vCPU還是1個(gè)CPU超線程,這要取決于宿主機(jī)上CPU實(shí)現(xiàn)方式,而Kunernetes只需要保證該P(yáng)od能夠使用到1個(gè)CPU的使用能力。
Kubernetes允許將CPU的限額設(shè)置位分?jǐn)?shù),比如上面我們?cè)O(shè)置的CPU.limits的值為500m,而所謂的500m就是500milliCPU,也就是0.5個(gè)CPU,這樣,這個(gè)Pod就會(huì)被分到一個(gè)CPU一半的計(jì)算能力。所以我們可以直接把配置寫成cpu=0.5,不過官方推薦500m的寫法,這是Kubernetes內(nèi)部的CPU計(jì)算方式。
在Kubernetes中,內(nèi)存資源的單位是bytes,支持使用Ei,Pi,Ti,Gi,Mi,Ki的方式作為bytes的值,其中需要注意Mi和M的區(qū)別(1Mi=1024_1024,1M=1000_1000)。
Kubernetes中Pod的CPU和內(nèi)存的資源限制,實(shí)際上分為requests和limits兩種情況。
spec.containers[].resources.limits.cpu spec.containers[].resources.limits.memory spec.containers[].resources.requests.cpu spec.containers[].resources.requests.memory
這兩者的區(qū)別如下:
- 在調(diào)度的時(shí)候,kube-scheduler會(huì)安requests的值進(jìn)行計(jì)算;
- 在設(shè)置CGroups的時(shí)候,kubelet會(huì)安limits的值來進(jìn)行設(shè)置;
QoS模型
Kubernetes中支持三種QoS模型。其分類是基于requests和limits的不同配置。
Guaranteed
當(dāng)Pod里的每一個(gè)Containers都設(shè)置了requests和limits,并且其值都相等的時(shí)候,這種Pod就屬于Guaranteed類別,如下:
apiVersion: v1 kind: Pod metadata: name: qos-demo namespace: qos-example spec: containers: - name: qos-demo-ctr image: nginx resources: limits: memory: "200Mi" cpu: "700m" requests: memory: "200Mi" cpu: "700m"
注意,當(dāng)這Pod僅設(shè)置limits,沒有設(shè)置requests的時(shí)候,系統(tǒng)默認(rèn)為它分配于limits相等的requests值,也就會(huì)被劃分為Guaranteed類別。
Burstable
而當(dāng)這個(gè)Pod不滿足Guaranteed條件,但至少有一個(gè)Contaienrs設(shè)置了requests,那么這個(gè)Pod就會(huì)被劃分為Burstable類別。如下:
apiVersion: v1 kind: Pod metadata: name: qos-demo-2 namespace: qos-example spec: containers: - name: qos-demo-2-ctr image: nginx resources: limits memory: "200Mi" requests: memory: "100Mi"
BestEffort
如果這個(gè)Pod既沒有設(shè)置requests值,也沒有設(shè)置limits的值的時(shí)候,那么它的QoS類別就是BestEffort類別。
apiVersion: v1 kind: Pod metadata: name: qos-demo-3 namespace: qos-example spec: containers: - name: qos-demo-3-ctr image: nginx
而QoS劃分的主要場(chǎng)景就是當(dāng)宿主機(jī)資源緊張的時(shí)候,kubelet對(duì)資源進(jìn)行Eviction時(shí)需要用到。目前Kubernetes設(shè)置的默認(rèn)Eviction的閾值如下:
memory.available<100Mi nodefs.available<10% nodefs.inodesFree<5% imagefs.available<15%
上述條件可以在kubelet中設(shè)置:
kubelet --eviction-hard=imagefs.available<10%,memory.available<500Mi,nodefs.available<5%,nodefs.inodesFree<5% --eviction-soft=imagefs.available<30%,nodefs.available<10% --eviction-soft-grace-period=imagefs.available=2m,nodefs.available=2m --eviction-max-pod-grace-period=600
Kubernetes中的Eviction分為Soft Eviction和Hard Eviction兩種模式。
- Soft Eviction允許設(shè)置優(yōu)雅等待時(shí)間,如上設(shè)置imagefs.available=2m,允許在Imagefs不足閾值達(dá)到2分鐘之后才進(jìn)行Eviction;
- Hard Eviction在達(dá)到閾值就進(jìn)行Eviction;
當(dāng)宿主機(jī)的Eviction閾值達(dá)到后,就會(huì)進(jìn)入MemoryPressure或者DiskPressure狀態(tài),從而避免新的Pod調(diào)度到上面去。而當(dāng)Eviction發(fā)生時(shí),kubelet刪除Pod的先后順序如下:
- BestEffort 類型的Pod;
- Burstable類別并且發(fā)生"饑餓"的資源使用量已經(jīng)超出了requests的Pod;
- Guaranteed類別并且只有當(dāng)Guaranteed類別的Pod的資源使用量超過了其limits限制,或者宿主機(jī)本身處于Memory Pressure狀態(tài)時(shí),Guaranteed才會(huì)被選中被Eviction;
cpuset
cpuset,就是把容器綁定到某個(gè)CPU核上,減少CPU的上下文切換。
- Pod必須是Guaranteed類型;
- 只需要將Pod的CPU資源的requests和limits設(shè)置為同一個(gè)相等的數(shù)值;
spec: containers: - name: nginx image: nginx resources: limits: memory: "200Mi" cpu: "2" requests: memory: "200Mi" cpu: "2"
LimitRange
在正常配置應(yīng)用Pod的時(shí)候,都會(huì)把服務(wù)質(zhì)量加上,也就是配置好requests和limits,但是,如果Pod非常多,而且很多Pod只需要相同的限制,我們還是像上面那樣一個(gè)一個(gè)的加就非常繁瑣了,這時(shí)候我們就可以通過LimitRange
做一個(gè)全局限制。如果在部署Pod的時(shí)候指定了requests和Limits,則指定的生效。反之則由全局的給Pod加上默認(rèn)的限制。
總結(jié),LimitRange
可以實(shí)現(xiàn)的功能:
- 限制namespace中每個(gè)pod或container的最小和最大資源用量。
- 限制namespace中每個(gè)PVC的資源請(qǐng)求范圍。
- 限制namespace中資源請(qǐng)求和限制數(shù)量的比例。
- 配置資源的默認(rèn)限制。
常用的場(chǎng)景如下(來自《Kubernetes權(quán)威指南》)
- 集群中的每個(gè)節(jié)點(diǎn)都有2GB內(nèi)存,集群管理員不希望任何Pod申請(qǐng)超過2GB的內(nèi)存:因?yàn)樵谡麄€(gè)集群中都沒有任何節(jié)點(diǎn)能滿足超過2GB內(nèi)存的請(qǐng)求。如果某個(gè)Pod的內(nèi)存配置超過2GB,那么該P(yáng)od將永遠(yuǎn)都無法被調(diào)度到任何節(jié)點(diǎn)上執(zhí)行。為了防止這種情況的發(fā)生,集群管理員希望能在系統(tǒng)管理功能中設(shè)置禁止Pod申請(qǐng)超過2GB內(nèi)存。
- 集群由同一個(gè)組織中的兩個(gè)團(tuán)隊(duì)共享,分別運(yùn)行生產(chǎn)環(huán)境和開發(fā)環(huán)境。生產(chǎn)環(huán)境最多可以使用8GB內(nèi)存,而開發(fā)環(huán)境最多可以使用512MB內(nèi)存。集群管理員希望通過為這兩個(gè)環(huán)境創(chuàng)建不同的命名空間,并為每個(gè)命名空間設(shè)置不同的限制來滿足這個(gè)需求。
- 用戶創(chuàng)建Pod時(shí)使用的資源可能會(huì)剛好比整個(gè)機(jī)器資源的上限稍小,而恰好剩下的資源大小非常尷尬:不足以運(yùn)行其他任務(wù)但整個(gè)集群加起來又非常浪費(fèi)。因此,集群管理員希望設(shè)置每個(gè)Pod都必須至少使用集群平均資源值(CPU和內(nèi)存)的20%,這樣集群能夠提供更好的資源一致性的調(diào)度,從而減少了資源浪費(fèi)。
(1)、首先創(chuàng)建一個(gè)namespace
apiVersion: v1 kind: Namespace metadata: name: coolops
(2)、為namespace配置LimitRange
apiVersion: v1 kind: LimitRange metadata: name: mylimit namespace: coolops spec: limits: - max: cpu: "1" memory: 1Gi min: cpu: 100m memory: 10Mi maxLimitRequestRatio: cpu: 3 memory: 4 type: Pod - default: cpu: 300m memory: 200Mi defaultRequest: cpu: 200m memory: 100Mi max: cpu: "2" memory: 1Gi min: cpu: 100m memory: 10Mi maxLimitRequestRatio: cpu: 5 memory: 4 type: Container
參數(shù)說明:
- max:如果type是Pod,則表示pod中所有容器資源的Limit值和的上限,也就是整個(gè)pod資源的最大Limit,如果pod定義中的Limit值大于LimitRange中的值,則pod無法成功創(chuàng)建。如果type是Container,意義類似。
- min:如果type是Pod,則表示pod中所有容器資源請(qǐng)求總和的下限,也就是所有容器request的資源總和不能小于min中的值,否則pod無法成功創(chuàng)建。如果type是Container,意義類似。
- maxLimitRequestRatio:如果type是Pod,表示pod中所有容器資源請(qǐng)求的Limit值和request值比值的上限,例如該pod中cpu的Limit值為3,而request為0.5,此時(shí)比值為6,創(chuàng)建pod將會(huì)失敗。
- defaultrequest和defaultlimit則是默認(rèn)值,只有type為Container才有這兩項(xiàng)配置
注意:
(1)、如果container
設(shè)置了max
, pod
中的容器必須設(shè)置limit
,如果未設(shè)置,則使用defaultlimt
的值,如果defaultlimit
也沒有設(shè)置,則無法成功創(chuàng)建
(2)、如果設(shè)置了container
的min
,創(chuàng)建容器的時(shí)候必須設(shè)置request
的值,如果沒有設(shè)置,則使用defaultrequest
,如果沒有defaultrequest
,則默認(rèn)等于容器的limit
值,如果limit
也沒有,啟動(dòng)就會(huì)報(bào)錯(cuò)
創(chuàng)建上面配置的LimitRange:
$ kubectl apply -f limitrange.yaml limitrange/mylimit created $ kubectl get limitrange -n coolops NAME CREATED AT mylimit 2022-08-02T06:08:43Z $ kubectl describe limitranges -n coolops mylimit Name: mylimit Namespace: coolops Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Pod cpu 100m 1 - - 3 Pod memory 10Mi 1Gi - - 4 Container cpu 100m 2 200m 300m 5 Container memory 10Mi 1Gi 100Mi 200Mi 4
(3)、創(chuàng)建一個(gè)允許范圍之內(nèi)的requests和limits的pod
apiVersion: v1 kind: Pod metadata: name: pod01 namespace: coolops spec: containers: - name: pod-01 image: nginx imagePullPolicy: IfNotPresent resources: requests: cpu: 200m memory: 30Mi limits: cpu: 300m memory: 50Mi
我們通過kubectl apply -f pod-01.yaml
可以正常創(chuàng)建Pod。
(4)、創(chuàng)建一個(gè)cpu超出允許訪問的Pod
apiVersion: v1 kind: Pod metadata: name: pod02 namespace: coolops spec: containers: - name: pod-02 image: nginx imagePullPolicy: IfNotPresent resources: requests: cpu: 200m memory: 30Mi limits: cpu: 2 memory: 50Mi
然后我們創(chuàng)建會(huì)報(bào)如下錯(cuò)誤:
# kubectl apply -f pod-02.yaml Error from server (Forbidden): error when creating "pod-02.yaml": pods "pod02" is forbidden: [maximum cpu usage per Pod is 1, but limit is 2, cpu max limit to request ratio per Pod is 3, but provided ratio is 10.000000, cpu max limit to request ratio per Container is 5, but provided ratio is 10.000000]
(5)創(chuàng)建低于允許范圍的Pod
apiVersion: v1 kind: Pod metadata: name: pod03 namespace: coolops spec: containers: - name: pod-03 image: nginx imagePullPolicy: IfNotPresent resources: requests: cpu: 200m memory: 30Mi limits: cpu: 100m memory: 10Mi
然后會(huì)報(bào)如下錯(cuò)誤:
# kubectl apply -f pod-03.yaml The Pod "pod03" is invalid: * spec.containers[0].resources.requests: Invalid value: "200m": must be less than or equal to cpu limit * spec.containers[0].resources.requests: Invalid value: "30Mi": must be less than or equal to memory limit
(6)、創(chuàng)建一個(gè)未定義request或Limits的Pod
apiVersion: v1 kind: Pod metadata: name: pod04 namespace: coolops spec: containers: - name: pod-04 image: nginx imagePullPolicy: IfNotPresent resources: requests: cpu: 200m memory: 200Mi
然后我們創(chuàng)建完P(guān)od后會(huì)發(fā)現(xiàn)自動(dòng)給我們加上了limits。如下:
# kubectl describe pod -n coolops pod04 ... Limits: cpu: 300m memory: 200Mi Requests: cpu: 200m memory: 200Mi ...
上面我指定了requests,LimitRange自動(dòng)給我們加上了defaultLimits,你也可以試一下全都不加或者加一個(gè),道理是一樣的。值得注意的是這里要注意一下我們?cè)O(shè)置的maxLimitRequestRatio
,配置的比列必須小于等于我們?cè)O(shè)置的值。
上文有介紹LimitRange還可以限制還可以限制PVC,如下:
apiVersion: v1 kind: LimitRange metadata: name: storagelimits namespace: coolops spec: limits: - type: PersistentVolumeClaim max: storage: 2Gi min: storage: 1Gi
創(chuàng)建完后即可查看:
kubectl describe limitranges -n coolops storagelimits Name: storagelimits Namespace: coolops Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- PersistentVolumeClaim storage 1Gi 2Gi - - -
你可以創(chuàng)建PVC進(jìn)行測(cè)試,道理是一樣的。
服務(wù)可用性管理
高可用
生產(chǎn)級(jí)別應(yīng)用,為了保證應(yīng)用的可用性,除了特殊應(yīng)用(例如批次應(yīng)用)都會(huì)保持高可用,所以在設(shè)計(jì)應(yīng)用Pod的時(shí)候,就要考慮應(yīng)用的高可用。
最簡(jiǎn)單的就是多副本,也就是在創(chuàng)建應(yīng)用的時(shí)候,至少需要2個(gè)副本,如下指定replicas為3就表示該應(yīng)用有3個(gè)副本:
apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx-deployment spec: progressDeadlineSeconds: 600 replicas: 3 revisionHistoryLimit: 10 selector: matchLabels: app: nginx strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: nginx spec: containers: - image: nginx:1.8 imagePullPolicy: IfNotPresent name: nginx resources: requests: cpu: 0.5 memory: 500M limits: cpu: 0.5 memory: 500M ports: - containerPort: 80 name: http protocol: TCP
但是光配置多副本就夠了么?
如果這三個(gè)副本都調(diào)度到一臺(tái)服務(wù)器上,該服務(wù)器因某些原因宕機(jī)了,那上面的應(yīng)用是不是就不可用?
為了解決這個(gè)問題,我們需要為同一個(gè)應(yīng)用配置反親和性,也就是不讓同一應(yīng)用的Pod調(diào)度到同一主機(jī)上,將上面的應(yīng)用YAML改造成如下:
apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx-deployment spec: progressDeadlineSeconds: 600 replicas: 3 revisionHistoryLimit: 10 selector: matchLabels: app: nginx strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: nginx spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: kubernetes.io/hostname containers: - image: nginx:1.8 imagePullPolicy: IfNotPresent name: nginx resources: requests: cpu: 0.5 memory: 500M limits: cpu: 0.5 memory: 500M ports: - containerPort: 80 name: http protocol: TCP
這樣能保證同應(yīng)用不會(huì)被調(diào)度到同節(jié)點(diǎn),基本的高可用已經(jīng)做到了。
可用性
但是光保證應(yīng)用的高可用,應(yīng)用本身不可用,也會(huì)導(dǎo)致異常。
我們知道Kubernetes的Deployment的默認(rèn)更新策略是滾動(dòng)更新,如何保證新應(yīng)用更新后是可用的,這就要使用readinessProbe,用來確保應(yīng)用可用才會(huì)停止老的版本,上面的YAML修改成如下:
apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx-deployment spec: progressDeadlineSeconds: 600 replicas: 3 revisionHistoryLimit: 10 selector: matchLabels: app: nginx strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: nginx spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: kubernetes.io/hostname containers: - image: nginx:1.8 imagePullPolicy: IfNotPresent name: nginx resources: requests: cpu: 0.5 memory: 500M limits: cpu: 0.5 memory: 500M readinessProbe: failureThreshold: 3 httpGet: path: / port: http scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 3 ports: - containerPort: 80 name: http protocol: TCP
這樣至少能保證只有新版本可訪問才接收外部流量。
但是應(yīng)用運(yùn)行過程中異常了呢?這就需要使用livenessProbe來保證應(yīng)用持續(xù)可用,上面的YAML修改成如下:
apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx-deployment spec: progressDeadlineSeconds: 600 replicas: 3 revisionHistoryLimit: 10 selector: matchLabels: app: nginx strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: nginx spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: kubernetes.io/hostname containers: - image: nginx:1.8 imagePullPolicy: IfNotPresent name: nginx resources: requests: cpu: 0.5 memory: 500M limits: cpu: 0.5 memory: 500M readinessProbe: failureThreshold: 3 httpGet: path: / port: http scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 3 livenessProbe: failureThreshold: 3 httpGet: path: / port: http scheme: HTTP initialDelaySeconds: 20 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 3 ports: - containerPort: 80 name: http protocol: TCP
上面的readinessProbe和livenessProbe都是應(yīng)用在運(yùn)行過程中如何保證其可用,那應(yīng)用在退出的時(shí)候如何保證其安全退出?
所謂安全退出,也就是能正常處理退出邏輯,能夠正常處理退出信號(hào),也就是所謂的優(yōu)雅退出。
優(yōu)雅退出有兩種常見的解決方法:
- 應(yīng)用本身可以處理SIGTERM信號(hào)。
- 設(shè)置一個(gè)preStop hook,在hook中指定怎么優(yōu)雅停止容器
這里拋開應(yīng)用本身可以處理SIGTERM信號(hào)不談,默認(rèn)其能夠處理,我們要做的就是協(xié)助其能優(yōu)雅退出。在Kubernetes中,使用preStop hook來協(xié)助處理,我們可以將上面的YAML修改成如下:
apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx-deployment spec: progressDeadlineSeconds: 600 replicas: 3 revisionHistoryLimit: 10 selector: matchLabels: app: nginx strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: nginx spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - nginx topologyKey: kubernetes.io/hostname containers: - image: nginx:1.8 imagePullPolicy: IfNotPresent name: nginx lifecycle: preStop: exec: command: - /bin/sh - -c - sleep 15 resources: requests: cpu: 0.5 memory: 500M limits: cpu: 0.5 memory: 500M readinessProbe: failureThreshold: 3 httpGet: path: / port: http scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 3 livenessProbe: failureThreshold: 3 httpGet: path: / port: http scheme: HTTP initialDelaySeconds: 20 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 3 ports: - containerPort: 80 name: http protocol: TCP
當(dāng)然,這里只是一個(gè)樣例,實(shí)際的配置還需要根據(jù)企業(yè)情況做跳轉(zhuǎn),比如企業(yè)使用了注冊(cè)中心如zk或者nacos,我們就需要把服務(wù)從注冊(cè)中心下掉。
PDB
上面的那些配置基本可以讓應(yīng)用順利的在Kubernetes里跑了,但是不可避免有維護(hù)節(jié)點(diǎn)的需求,比如升級(jí)內(nèi)核,重啟服務(wù)器等。
而且也不是所有的應(yīng)用都可以多副本,當(dāng)我們使用kubectl drain
的時(shí)候,為了避免某個(gè)或者某些應(yīng)用直接銷毀而不可用,Kubernetes引入了PodDisruptionBudget(PDB)控制器,用來控制集群中Pod的運(yùn)行個(gè)數(shù)。
在PDB中,主要通過兩個(gè)參數(shù)來控制Pod的數(shù)量:
- minAvailable:表示最小可用Pod數(shù),表示在Pod集群中處于運(yùn)行狀態(tài)的最小Pod數(shù)或者是運(yùn)行狀態(tài)的Pod數(shù)和總數(shù)的百分比;
- maxUnavailable:表示最大不可用Pod數(shù),表示Pod集群中處于不可用狀態(tài)的最大Pod數(shù)或者不可用狀態(tài)Pod數(shù)和總數(shù)的百分比;
注意:minAvailable和maxUnavailable是互斥了,也就是說兩者同一時(shí)刻只能出現(xiàn)一種。
kubectl drain命令已經(jīng)支持了PodDisruptionBudget控制器,在進(jìn)行kubectl drain操作時(shí)會(huì)根據(jù)PodDisruptionBudget控制器判斷應(yīng)用POD集群數(shù)量,進(jìn)而保證在業(yè)務(wù)不中斷或業(yè)務(wù)SLA不降級(jí)的情況下進(jìn)行應(yīng)用POD銷毀。在進(jìn)行kubectl drain或者Pod主動(dòng)逃離的時(shí)候,Kubernetes會(huì)通過以下幾種情況來進(jìn)行判斷:
- minAvailable設(shè)置成了數(shù)值5:應(yīng)用POD集群中最少要有5個(gè)健康可用的POD,那么就可以進(jìn)行操作。
- minAvailable設(shè)置成了百分?jǐn)?shù)30%:應(yīng)用POD集群中最少要有30%的健康可用POD,那么就可以進(jìn)行操作。
- maxUnavailable設(shè)置成了數(shù)值5:應(yīng)用POD集群中最多只能有5個(gè)不可用POD,才能進(jìn)行操作。
- maxUnavailable設(shè)置成了百分?jǐn)?shù)30%:應(yīng)用POD集群中最多只能有30%個(gè)不可用POD,才能進(jìn)行操作。
在極端的情況下,比如將maxUnavailable設(shè)置成0,或者設(shè)置成100%,那么就表示不能進(jìn)行kubectl drain操作。同理將minAvailable設(shè)置成100%,或者設(shè)置成應(yīng)用POD集群最大副本數(shù),也表示不能進(jìn)行kubectl drain操作。
注意:使用PodDisruptionBudget控制器并不能保證任何情況下都對(duì)業(yè)務(wù)POD集群進(jìn)行約束,PodDisruptionBudget控制器只能保證POD主動(dòng)逃離的情況下業(yè)務(wù)不中斷或者業(yè)務(wù)SLA不降級(jí),例如在執(zhí)行kubectldrain命令時(shí)。
(1)、定義minAvailable
apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: pdb-demo spec: minAvailable: 2 selector: matchLabels: app: nginx
(2)、定義maxUnavailable
apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: pdb-demo spec: maxUnavailable: 1 selector: matchLabels: app: nginx
可以看到PDB是通過label selectors和應(yīng)用Pod建立關(guān)聯(lián),而后在主動(dòng)驅(qū)逐Pod的時(shí)候,會(huì)保證app: nginx的Pod最大不可用數(shù)為1,假如本身是3副本,至少會(huì)保證2副本正常運(yùn)行。
總結(jié)
上面只是對(duì)Kubernetes中應(yīng)用做了簡(jiǎn)單的可用性保障,在生產(chǎn)中,應(yīng)用不僅僅是它自己,還關(guān)聯(lián)上游、下游的應(yīng)用,所以全鏈路的應(yīng)用可用性保障才能讓應(yīng)用更穩(wěn)定。
以上就是Kubernetes應(yīng)用服務(wù)質(zhì)量管理詳解的詳細(xì)內(nèi)容,更多關(guān)于Kubernetes服務(wù)質(zhì)量管理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Kubernetes Informer數(shù)據(jù)存儲(chǔ)Index與Pod分配流程解析
- Kubernetes scheduler啟動(dòng)監(jiān)控資源變化解析
- Kubernetes ApiServer三大server權(quán)限與數(shù)據(jù)存儲(chǔ)解析
- Kubernetes Visitor設(shè)計(jì)模式及發(fā)送pod創(chuàng)建請(qǐng)求解析
- Kubernetes kubectl中Pod創(chuàng)建流程源碼解析
- Kubernetes?權(quán)限管理認(rèn)證鑒權(quán)詳解
- Kubernetes調(diào)度管理優(yōu)先級(jí)和搶占機(jī)制詳解
- Kubernetes?controller?manager運(yùn)行機(jī)制源碼解析
相關(guān)文章
2022最新青龍面板對(duì)接機(jī)器人的詳細(xì)過程(傻妞對(duì)接onebot(oicq)協(xié)議實(shí)現(xiàn)機(jī)器人功能)
這篇文章主要介紹了2022最新青龍面板對(duì)接機(jī)器人的詳細(xì)過程(傻妞對(duì)接onebot(oicq)協(xié)議實(shí)現(xiàn)機(jī)器人功能),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05kubernetes?k8s?CRD自定義資源學(xué)習(xí)筆記
這篇文章主要介紹了kubernetes?k8s?CRD自定義資源學(xué)習(xí)筆記,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05k8s Job 執(zhí)行一次性以及批處理任務(wù)使用場(chǎng)景案例
這篇文章主要為大家介紹了k8s Job 執(zhí)行一次性以及批處理任務(wù)使用場(chǎng)景案例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04解決k8s namespace 一直處于 Terminating 狀態(tài)的問題
這篇文章主要介紹了k8s namespace 一直處于 Terminating 狀態(tài)的解決方法,以下的 tool 為 Terminating 狀態(tài)的 namespace,下面相關(guān)的一些操作記得將 tool 修改成自己的 namespace 名稱,需要的朋友可以參考下2022-10-10阿里云kubernetes查找鏡像中jar包的方法(docker查看鏡像中的jar)
這篇文章主要給大家介紹了關(guān)于阿里云kubernetes查找鏡像中jar包的方法,也就是在docker查看鏡像中的jar,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09kubernetes部署dashboard及應(yīng)用小結(jié)
Dashboard?是基于網(wǎng)頁的?Kubernetes?用戶界面,可以對(duì)?Deployment?實(shí)現(xiàn)彈性伸縮、發(fā)起滾動(dòng)升級(jí)、重啟?Pod?或者使用向?qū)?chuàng)建新的應(yīng)用,這篇文章主要介紹了kubernetes部署dashboard,需要的朋友可以參考下2024-06-06kubernetes存儲(chǔ)之GlusterFS集群詳解
最近工作中用到了GlusterFS作為Kubernetes的存儲(chǔ),這篇文章主要給大家介紹了關(guān)于kubernetes存儲(chǔ)之GlusterFS集群的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04