Kubernetes控制節(jié)點(diǎn)的部署
標(biāo)簽和nodeSelector
標(biāo)簽(Label)是附加到 Kubernetes 對象上的鍵值對,如果用 json 表示附加到 metadata 的 label:
"metadata": { "labels": { "key1" : "value1", "key2" : "value2" } }
yaml:
metadata: labels: key1: "value1" key2: "value2"
標(biāo)簽主要是用于表示對用戶有意義的對象的屬性標(biāo)識。
可以給節(jié)點(diǎn)設(shè)定一些 Label,例如在 kube-system 命名空間中,運(yùn)行著 Kubernetes 的核心組件,我們可以查看此命名空間中所有組件的 Label。
kubectl get nodes --namespace=kube-system --show-labels
beta.kubernetes.io/arch=amd64, beta.kubernetes.io/os=linux, kubernetes.io/arch=amd64, ... ...
我們也可以手動給一個(gè) Node 添加標(biāo)簽。
kubectl label nodes <node-name> <label-key>=<label-value>
例如我們給節(jié)點(diǎn)設(shè)置一個(gè) disksize
,表示節(jié)點(diǎn)的硬盤是否夠大。
kubectl label nginx disksize=big
然后我們在編寫 yaml 文件時(shí),希望這個(gè) pod 在容量大的 Node 上運(yùn)行,可以這樣寫:
nodeSelector: disksize=big
順便聊一下官方的一個(gè)例子,設(shè)置 Node 的 Label,表示硬盤是 ssd。
kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd
在 yaml 文件的節(jié)點(diǎn)選擇器中,添加選擇。
spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent nodeSelector: disktype: ssd
Label 可以在多個(gè)地方使用,例如在 Node 上添加 Label,標(biāo)識此 Node;而在 NodeSelector 里使用,可以選擇合適的 Node 運(yùn)行 Pod;在 metadata
中使用,可以對元數(shù)據(jù)加以描述。
在 metadata 中添加的 Label,可以在命令查詢時(shí)做篩選。
查詢 pod 的 Label:
kubectl get pods --show-labels
查找符合條件的 pod(參考 LABELS 字段,可以根據(jù)里面的標(biāo)簽選擇):
kubectl get pods -l app=nginx
標(biāo)簽選擇
在前面,我們學(xué)習(xí)了 nodeSelector ,可以幫助我們選擇合適的 Node 運(yùn)行 Pod,實(shí)際上 Kubernets 的標(biāo)簽選擇是豐富多樣的,例如:
nodeSelector: disktype: ssd disksize: big
則表示節(jié)點(diǎn)選擇器是等值選擇,表達(dá)式是 disktype=ssd && disksize=big
。
標(biāo)簽選擇有等值和集合兩種,其中等值選擇有 =
、==
、!=
三種,=
和 ==
無區(qū)別。在多個(gè)需求(多個(gè)label)的情況下,相對于使用 &&
運(yùn)算符,但是選擇器不存在 ||
這種邏輯或運(yùn)算符。
yaml 只支持 {key}:{value}
這種形式,而我們使用命令形式時(shí),則可使用以上三種運(yùn)算符。
kubectl get nodes -l disktype=ssd,disksize!=big # 多個(gè)條件使用 逗號","" 隔開,而不是 "&&"。
對于集合選擇方式,支持三種操作符:in
、notin
和 exists
。不過別理解成是從集合中選擇,下面舉個(gè)例子。
假如有三個(gè) Node,其 disksize 有 big、medium、small,我們要部署一個(gè) pod,在 big、medium 中都可以運(yùn)行,則:
... -l disksize in (big,medium)
... -l disksize notin (small) # 不在 small 中運(yùn)行
而 exists 則跟 !=
類似,但是 exists 表示只要存在這個(gè) label 即可,而不論其設(shè)置了是什么值。
-l disksize # 等同 -l disksize in (big,medium,small)
我們也可以使用 ''
把選擇表達(dá)式包起來。
kubectl get pods -l 'app=nginx'
前面已經(jīng)提到了 yaml 的 nodeSelector 和 命令式的選擇,這里我們介紹 yaml 的 selector。
前面我們提到在 Deployment 的 metadata 中加上 Label,即 pod 加上 Label,我們也在 kubectl get pods
中使用 Label 選擇過濾 pod。同樣,當(dāng)我們創(chuàng)建 Service 或者使用 ReplicationController 時(shí),也可以使用標(biāo)簽選擇合適的 pod。
假如我們已經(jīng)部署了 nginx,那么查詢 kubectl get pods --show-labels
時(shí),其 pod 的 LABELS 會有 app=nginx
,那么我們可以這樣選擇:
selector: app: nginx
完整版本:
apiVersion: v1 kind: Service metadata: name: my-service spec: type: LoadBalancer selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 6666 status: loadBalancer: ingress: - ip: 192.0.2.127
selector 還支持以下選擇方式 matchLabels
、matchExpressions
:
matchLabels
是由 {key,value}
對組成的映射。 matchLabels
映射中的單個(gè) {key,value }
等同于 matchExpressions
的元素, 其 key
字段為 "key",operator
為 "In",而 values
數(shù)組僅包含 "value"。
matchExpressions
是 Pod 選擇算符需求的列表。 有效的運(yùn)算符包括 In
、NotIn
、Exists
和 DoesNotExist
。 在 In
和 NotIn
的情況下,設(shè)置的值必須是非空的。 來自 matchLabels
和 matchExpressions
的所有要求都按邏輯與的關(guān)系組合到一起 -- 它們必須都滿足才能匹配。
示例如下:
selector: matchLabels: component: redis matchExpressions: - {key: tier, operator: In, values: [cache]} - {key: environment, operator: NotIn, values: [dev]}
這里就不在詳細(xì)說這些選擇規(guī)則了,前面提到的已經(jīng)夠用了,讀者可以查閱官方文檔學(xué)習(xí)更多復(fù)雜的操作:https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/labels/
親和性和反親和性
前面我們學(xué)習(xí)了 nodeSelector
,使用 nodeSelector
選擇合適的 Label,可以表達(dá)我們約束的類型。
親和性則類似于 nodeSelector,可以根據(jù)節(jié)點(diǎn)上的標(biāo)簽約束 pod 可以調(diào)度到哪些節(jié)點(diǎn)。
pod 親和性有兩種別為:
requiredDuringSchedulingIgnoredDuringExecution
硬需求,將 pod 調(diào)度到一個(gè)節(jié)點(diǎn)必須滿足的規(guī)則。
preferredDuringSchedulingIgnoredDuringExecution
。嘗試執(zhí)行但是不能保證偏好。
這是官方的一個(gè)例子:
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/e2e-az-name operator: In values: - e2e-az1 - e2e-az2 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: another-node-label-key operator: In values: - another-node-label-value containers: - name: with-node-affinity image: k8s.gcr.io/pause:2.0
親和性的約束相對于:
... ... -l kubernetes.io/e2e-az-name in (e2e-az1,e2e-az2)
affinity 設(shè)置親密關(guān)系,nodeAffinity 設(shè)置節(jié)點(diǎn)親密關(guān)系,最后才到 親和性,它們表示必須滿足和盡量滿足。
如果我們設(shè)置了多個(gè) nodeSelectorTerms :
requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: ... nodeSelectorTerms:
則只需要滿足其中一種即可調(diào)度 pod 到 node 上。
如果你同時(shí)指定了 nodeSelector
和 nodeAffinity
,兩者必須都要滿足, 才能將 Pod 調(diào)度到候選節(jié)點(diǎn)上。
節(jié)點(diǎn)親和性語法支持下面的操作符: In
,NotIn
,Exists
,DoesNotExist
,Gt
,Lt
。
Pod 親和性與反親和性的合法操作符有 In
,NotIn
,Exists
,DoesNotExist
。
通過 -Affinity
可以設(shè)置親和性,例如節(jié)點(diǎn)親和性 nodeAffinity
,而且設(shè)置反親和性使用 -AntiAffinity
,例如 nodeAntiAffinity
。
反親和性跟親和性一樣,都有 requiredDuringSchedulingIgnoredDuringExecution
硬限制和 preferredDuringSchedulingIgnoredDuringExecution
軟限制,只是反親和性是相反的表示,如果符合條件則不能調(diào)度。
關(guān)于親和性和反親和性的說明就到這里,著兩者的配置比較多和復(fù)雜,讀者可以參考官方文檔,這里不在贅述。
污點(diǎn)和容忍度
前面提到親和性和反親和性,我們加以通過 pod 選擇合適的 node,或者 service 選擇合適的 pod,這些擁有 Label 的對象都是被選擇的。
這里,我們介紹污點(diǎn)和容忍度,它們可以排斥 “被選擇” 的命運(yùn)。
節(jié)點(diǎn)污點(diǎn)(taint) 可以排斥一類特定的 pod,而 容忍度(Tolerations)則表示能夠容忍這個(gè)對象的污點(diǎn)。
當(dāng)節(jié)點(diǎn)添加一個(gè)污點(diǎn)后,除非 pod 聲明能夠容忍這個(gè)污點(diǎn),否則 pod 不會被調(diào)度到這個(gè) 節(jié)點(diǎn)上。
系統(tǒng)會 盡量 避免將 Pod 調(diào)度到存在其不能容忍污點(diǎn)的節(jié)點(diǎn)上, 但這不是強(qiáng)制的。Kubernetes 處理多個(gè)污點(diǎn)和容忍度的過程就像一個(gè)過濾器:從一個(gè)節(jié)點(diǎn)的所有污點(diǎn)開始遍歷, 過濾掉那些 Pod 中存在與之相匹配的容忍度的污點(diǎn)。
但是如果你只有一個(gè) worker,那么設(shè)置了污點(diǎn),那 pod 也只能選擇在這個(gè)節(jié)點(diǎn)上運(yùn)行。
添加污點(diǎn)格式:
kubectl taint node [node] key=value:[effect]
更新污點(diǎn)或覆蓋:
kubectl taint node [node] key=value:[effect] --overwrite=true
使用 kubectl taint
給節(jié)點(diǎn)增加一個(gè)污點(diǎn)。
kubectl taint nodes node1 key1=value1:NoSchedule
移除污點(diǎn):
kubectl taint nodes node1 key1=value1:NoSchedule-
其中,污點(diǎn)需要設(shè)置 label ,并設(shè)置這個(gè) label 的效果為 NoSchedule。
污點(diǎn)的效果稱為 effect ,節(jié)點(diǎn)的污點(diǎn)可以設(shè)置為以下三種效果:
NoSchedule
:不能容忍此污點(diǎn)的 Pod 不會被調(diào)度到節(jié)點(diǎn)上;不會影響已存在的 pod。PreferNoSchedule
:Kubernetes 會避免將不能容忍此污點(diǎn)的 Pod 安排到節(jié)點(diǎn)上。NoExecute
:如果 Pod 已在節(jié)點(diǎn)上運(yùn)行,則會將該 Pod 從節(jié)點(diǎn)中逐出;如果尚未在節(jié)點(diǎn)上運(yùn)行,則不會將其安排到節(jié)點(diǎn)上。
但是某些系統(tǒng)創(chuàng)建的 Pod 可以容忍所有 NoExecute
和 NoSchedule
污點(diǎn),因此不會被逐出,例如 master 節(jié)點(diǎn)是不能被部署 pod 的,但是 kube-system
命名空間卻有很多系統(tǒng) pod。當(dāng)然通過修改污點(diǎn),可以讓 戶 pod 部署到 master 節(jié)點(diǎn)中。
查詢節(jié)點(diǎn)的污點(diǎn):
kubectl describe nodes | grep Taints
Taints: node-role.kubernetes.io/master:NoSchedule Taints: key1=value1:NoSchedule
系統(tǒng)默認(rèn)污點(diǎn)
我們?nèi)コ?master 的污點(diǎn):
kubectl taint node instance-1 node-role.kubernetes.io/master:NoSchedule-
然后部署 nginx pod。
kubectl create deployment nginxtaint --image=nginx:latest --replicas=3
查看 pod:
kubectl get pods -o wide
結(jié)果筆者查到三個(gè)副本都在 master 節(jié)點(diǎn)上。
為了保證集群安全,我們需要恢復(fù) master 的污點(diǎn)。
kubectl taint node instance-1 node-role.kubernetes.io/master:NoSchedule
當(dāng)某種條件為真時(shí),節(jié)點(diǎn)控制器會自動給節(jié)點(diǎn)添加一個(gè)污點(diǎn)。當(dāng)前內(nèi)置的污點(diǎn)包括:
node.kubernetes.io/not-ready
:節(jié)點(diǎn)未準(zhǔn)備好。這相當(dāng)于節(jié)點(diǎn)狀態(tài)Ready
的值為 "False
"。node.kubernetes.io/unreachable
:節(jié)點(diǎn)控制器訪問不到節(jié)點(diǎn). 這相當(dāng)于節(jié)點(diǎn)狀態(tài)Ready
的值為 "Unknown
"。node.kubernetes.io/out-of-disk
:節(jié)點(diǎn)磁盤耗盡。node.kubernetes.io/memory-pressure
:節(jié)點(diǎn)存在內(nèi)存壓力。node.kubernetes.io/disk-pressure
:節(jié)點(diǎn)存在磁盤壓力。node.kubernetes.io/network-unavailable
:節(jié)點(diǎn)網(wǎng)絡(luò)不可用。node.kubernetes.io/unschedulable
: 節(jié)點(diǎn)不可調(diào)度。node.cloudprovider.kubernetes.io/uninitialized
:如果 kubelet 啟動時(shí)指定了一個(gè) "外部" 云平臺驅(qū)動, 它將給當(dāng)前節(jié)點(diǎn)添加一個(gè)污點(diǎn)將其標(biāo)志為不可用。在 cloud-controller-manager 的一個(gè)控制器初始化這個(gè)節(jié)點(diǎn)后,kubelet 將刪除這個(gè)污點(diǎn)。
容忍度
一個(gè) node 可以設(shè)置污點(diǎn),排斥 pod,但是 pod 也可以設(shè)置 容忍度,容忍 node 的污點(diǎn)。
tolerations: - key: "key1" operator: "Exists" effect: "NoSchedule"
也可以設(shè)置 value。
tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule"
operator
的默認(rèn)值是 Equal
。
一個(gè)容忍度和一個(gè)污點(diǎn)相“匹配”是指它們有一樣的鍵名和效果,并且:
如果
operator
是Exists
此時(shí)容忍度不能指定
value
,如果存在 key 為 key1 的 label,且污點(diǎn)效果為NoSchedule
,則容忍。如果
operator
是Equal
,則它們的value
應(yīng)該相等
如果 effect
留空,則表示只要是 label 為 key1
的節(jié)點(diǎn),都可以容忍。
如果:
tolerations: operator: "Exists"
則表示此 pod 能夠容忍任意的污點(diǎn),無論 node 怎么設(shè)置 key
、value
、effect
,此 pod 都不會介意。
如果要在 master 上也能部署 pod,則可以修改 pod 的容忍度:
spec: 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/master effect: NoSchedule
DaemonSet
在 Kubernetes 中,有三個(gè) -Set
,分別是 ReplicaSet、DaemonSet、StatefulSets。而 負(fù)載類型有 Deployments、ReplicaSet、DaemonSet、StatefulSets等(或者說有這幾個(gè)控制器)。
前面已經(jīng)介紹過 Deployments ,而 kind: ReplicaSet
一般是沒必要的,可以在 kind: Deployment
加上 replicas:
。
而 kind: DaemonSet
需要使用一個(gè) yaml 來描述,但是整體跟 Deployment 一樣。
DaemonSet 可以確保一個(gè)節(jié)點(diǎn)只運(yùn)行一個(gè) Pod 副本,假如有個(gè) nginx 的 pod,當(dāng)新的 Node 加入集群時(shí),會自動在這個(gè) Node 上部署一個(gè) pod;當(dāng)節(jié)點(diǎn)從集群中移開時(shí),這個(gè) Node 上的 Pod 會被回收;如果 DaemontSet 配置被刪除,則也會刪除所有由它創(chuàng)建的 Pod。
DaemonSet 的一些典型用法:
- 在每個(gè)節(jié)點(diǎn)上運(yùn)行集群守護(hù)進(jìn)程
- 在每個(gè)節(jié)點(diǎn)上運(yùn)行日志收集守護(hù)進(jìn)程
- 在每個(gè)節(jié)點(diǎn)上運(yùn)行監(jiān)控守護(hù)進(jìn)程
在 yaml 中,要配置 Daemont,可以使用 tolerations
,配置示例:
kind: DaemontSet ... ...
其它地方跟 Deployment 一致。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Kubernetes中Deployment的升級與回滾
- 了解Kubernetes中的Service和Endpoint
- Kubernetes部署實(shí)例并配置Deployment、網(wǎng)絡(luò)映射、副本集
- Kubernetes關(guān)鍵組件與結(jié)構(gòu)組成介紹
- 配置Kubernetes外網(wǎng)訪問集群
- 使用kubeadm命令行工具創(chuàng)建kubernetes集群
- Minikube搭建Kubernetes集群
- kubernetes中的namespace、node、pod介紹
- Kubernetes集群的組成介紹
- Dashboard管理Kubernetes集群與API訪問配置
相關(guān)文章
kubernetes中的namespace、node、pod介紹
這篇文章介紹了kubernetes中的namespace、node、pod,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03Kubernetes Visitor設(shè)計(jì)模式及發(fā)送pod創(chuàng)建請求解析
這篇文章主要為大家介紹了Kubernetes Visitor設(shè)計(jì)模式及發(fā)送pod創(chuàng)建請求解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Kubernetes Informer數(shù)據(jù)存儲Index與Pod分配流程解析
這篇文章主要為大家介紹了Kubernetes Informer數(shù)據(jù)存儲Index與Pod分配流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11kubernetes數(shù)據(jù)持久化PV?PVC深入分析詳解
這篇文章主要為大家介紹了kubernetes數(shù)據(jù)持久化PV?PVC分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11KubeSphere接入外部Elasticsearch實(shí)戰(zhàn)示例
這篇文章主要為大家介紹了KubeSphere接入外部Elasticsearch實(shí)戰(zhàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12k8s集群部署時(shí)etcd容器不停重啟問題以及處理詳解
一次在k8s集群中創(chuàng)建實(shí)例發(fā)現(xiàn)etcd集群狀態(tài)出現(xiàn)連接失敗狀況,導(dǎo)致創(chuàng)建實(shí)例失敗,下面這篇文章主要給大家介紹了關(guān)于k8s集群部署時(shí)etcd容器不停重啟問題以及處理的相關(guān)資料,需要的朋友可以參考下2023-01-01