k8s~節(jie)點的親和性
在Kubernetes中(zhong),你可(ke)以(yi)使用(yong)節點(dian)親和性(xing)(Node Affinity)來控制Pod部署在哪(na)些(xie)節點(dian)上(shang)。通(tong)過配置節點(dian)親和性(xing),你可(ke)以(yi)指定一些(xie)規則,以(yi)確保(bao)多個服務不會(hui)被調度(du)到(dao)同一個節點(dian)上(shang)。
兩種策略
-
requiredDuringSchedulingIgnoredDuringExecution:通過
requiredDuringSchedulingIgnoredDuringExecution,可以定義在(zai)調(diao)度期(qi)間必須滿足的 Affinity 規則。這意味著規則在(zai)調(diao)度期(qi)間必須滿足,但(dan)如(ru)果在(zai)運行時不滿足,則不會強制執行。 -
preferredDuringSchedulingIgnoredDuringExecution:使用
preferredDuringSchedulingIgnoredDuringExecution,可以定義(yi)首(shou)選的(de) Affinity 規(gui)則。這意味著規(gui)則是(shi)首(shou)選的(de),但不(bu)是(shi)強制的(de),如果(guo)無法滿足則可以繼續調度。
節點親和性實現
以下是一些在部(bu)署Deployment時避免多(duo)個(ge)服(fu)務部(bu)署到(dao)同一節點的常用方法:
- 使用節點親和性標簽(Node Affinity):你可以給每個服務定義一個獨特的節點親和性標簽,然后通過
affinity字段將這些標簽添加到對應的PodSpec中。例如,給服務A定義service=a的標簽,給服務B定義service=b的標簽。然后,在Deployment的PodSpec中使用nodeAffinity字段來指定節點親和性規則,確保兩個服務不會調度到同一個節點上。
- 使用requiredDuringSchedulingIgnoredDuringExecution強制策略,如果不滿足,你的pod將不能被調度
- 節點A上添加標簽type=product,service-a將被調度到這個節點
- 節點B上添加標簽type=order,service-b將被調度到這個節點
- service-a.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: service-a
spec:
replicas: 1
selector:
matchLabels:
app: service-a
template:
metadata:
labels:
app: service-a
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: type
operator: In
values:
- product
containers:
- name: service-a
image: nginx:stable-alpine
- service-b.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: service-b
spec:
replicas: 1
selector:
matchLabels:
app: service-b
template:
metadata:
labels:
app: service-b
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: type
operator: In
values:
- order
containers:
- name: service-b
image: nginx:stable-alpine
上面使用正(zheng)則(ze)表(biao)達(da)式matchExpressions來(lai)確定目標(biao),也可以使用標(biao)簽matchLabels的方式,更簡潔,如下:
# 親和性
affinity:
# Pod親和性規則
podAffinity:
# 強制性的調度規則, 但不會影響已在節點上運行的Pod
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: kubernetes.io/hostname
# 標簽選擇器
labelSelector:
matchLabels:
app: service-a
- 使用非強制策略,配置weight權重一起使用
apiVersion: apps/v1
kind: Deployment
metadata:
name: service-a-order
spec:
# Pod副本數量
replicas: 4
selector:
matchLabels:
app: service-a-order
# Pod模板
template:
metadata:
# 標簽信息: 應用的后端服務
labels:
app: service-a-order
spec:
# 親和性
affinity:
# Pod親和性規則
podAntiAffinity:
# 強制性的調度規則, 但不會影響已在節點上運行的Pod
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
topologyKey: kubernetes.io/hostname
# 標簽選擇器
labelSelector:
matchExpressions: # 也需要matchLabels
- key: app
operator: In
values:
- service-a-order
# 容器信息
containers:
- name: service-a-order
image: nginx:stable-alpine
擴展閱讀
app.kubernetes.io/instance Kubernetes的應用標識
在Kubernetes中,app.kubernetes.io/instance是一(yi)個標簽(Label),用(yong)(yong)于(yu)標識應用(yong)(yong)程序實例(li)的實例(li)ID或名稱。
標簽是鍵值對的形式,用于為資源對象(如Pod、Deployment、Service等)添加元數據信息。app.kubernetes.io/instance是一個預定義的標簽(qian)鍵,用于表示應用程(cheng)序實例的唯一標識符。
通常,當您使用Kubernetes部署多個相同類型的應用程序實例時,每個實例都會被分配一個唯一的實例ID或名稱。您可以使用app.kubernetes.io/instance標簽來標識和區分這些應用程序實例。
例如,假設您使用Kubernetes部署了一個名為"my-app"的應用程序,并在該應用程序的多個副本之間進行了擴展。每個副本都會被分配一個唯一的實例ID或名稱。通過為每個副本設置app.kubernetes.io/instance標(biao)簽,您(nin)可以區分和識(shi)別每(mei)個(ge)應用程(cheng)序實(shi)例。
標簽可以通過Kubernetes API或命令行工具(如kubectl)進行管理和查詢。您可以使用kubectl get pods --show-labels命令來查看資源對象的標簽信息,包括app.kubernetes.io/instance標簽(qian)和對應的實例ID或名稱(cheng)值。
kubernetes.io/hostname 節點的主機名
在Kubernetes中,kubernetes.io/hostname是一個節(jie)點(dian)標簽(qian)(Node Label),用于(yu)標識節(jie)點(dian)的主機名(Hostname)。
節點標簽是一種鍵值對的形式,用于為節點添加自定義的元數據信息。通過為節點添加標簽,您可以根據標簽進行節點選擇和調度。kubernetes.io/hostname是一個預(yu)定義的標簽(qian)鍵,用于表示節點(dian)的主機名。
節點的主機名是節點所在主機的唯一標識符。Kubernetes使用主機名來識別和管理節點,并在集群中唯一標識每個節點。kubernetes.io/hostname標(biao)簽的值將設(she)置為節點的實際主機名。
例如,假設您在Kubernetes集群中有多個節點,并且每個節點都有不同的主機名。通過查看節點的kubernetes.io/hostname標簽,您可以了解(jie)到每個(ge)節點的(de)實際主機名,并在進(jin)行節點選擇或調度時使(shi)用這些信息。
節點標簽可以通過Kubernetes API或命令行工具(如kubectl)進行管理和查詢。您可以使用kubectl get nodes --show-labels命令來查看節點標簽信息,包括kubernetes.io/hostname標簽和(he)對(dui)應的(de)主機名值。