11.标签和亲和力
1.标签 Label 1.1.什么是标签 标签(Labels) 是附加到 Kubernetes对象(比如 Pod)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。
1.标签 Label 1.1.什么是标签 标签(Labels) 是附加到 Kubernetes对象(比如 Pod)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。
标签(Labels) 是附加到 Kubernetes对象(比如 Pod)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。 每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。
标签是键值对。有效的标签键有两个段:可选的前缀和名称,用斜杠(/)分隔。 名称段是必需的,必须小于等于 63 个字符,以字母数字字符([a-z0-9A-Z])开头和结尾, 带有破折号(-),下划线(_),点( .)和之间的字母数字。 前缀是可选的。如果指定,前缀必须是 DNS 子域:由点(.)分隔的一系列 DNS 标签,总共不超过 253 个字符, 后跟斜杠(/)。
如果省略前缀,则假定标签键对用户是私有的。 向最终用户对象添加标签的自动系统组件(例如 kube-scheduler、kube-controller-manager、 kube-apiserver、kubectl 或其他第三方自动化工具)必须指定前缀。
kubernetes.io/ 和 k8s.io/ 前缀是为 Kubernetes 核心组件保留的。
有效标签值:
[a-z0-9A-Z])开头和结尾-)、下划线(_)、点(.)和字母或数字例如,以下是一个清单 (manifest),适用于具有 environment: production 和 app: nginx 这两个标签的 Pod:
标签就是为了节点标明属性,用于区分不同的节点。
关于标签的使用,大概分为四方面:增、删、改、查。
修改node节点k8s-node02的label为region=subnet7
oot@k8s-master01:~/hhh# kubectl label nodes node-02 region=subnet7
node/node-02 labeled单个去除node节点k8s-node02的label:region=subnet7
root@k8s-master01:~/hhh# kubectl label nodes node-02 region-
node/node-02 unlabeled批量删除符合标签选择器条件的所有节点的标签
root@k8s-master01:~/hhh# kubectl label node -l region region-单个修改node节点k8s-node02的label:region=subnet120
root@k8s-master01:~/hhh# kubectl label node node-02 region=subnet120 --overwrite
node/node-02 labeled批量修改符合标签选择器条件的所有节点的标签
root@k8s-master01:~/hhh# kubectl label node -l region region=subnet100
查看单个节点的标签
查看所有节点的标签
筛选节点标签含region的节点
选择匹配 region 为subnet100 的 node
nodeSelector 是节点选择约束的最简单推荐形式。你可以将 nodeSelector 字段添加到 Pod 的规约中设置你希望目标节点所具有的节点标签。 Kubernetes 只会将 Pod 调度到拥有你所指定的每个标签的节点上。
下面以一个具体的示例进行演示:
1.修改node节点node-02的label为region=subnet7
root@k8s-master01:~/hhh# kubectl label nodes node-02 region=subnet7 --overwrite
node/node-02 labeled2.筛选标签为region=subnet7的节点
3.在 Deployment 控制器添加标签指定将 Pod 部署到带标签的节点上
4.查看pod部署节点,观察到都已部署到node-02节点上
亲和力(Affinity)是 Kubernetes 中的一种机制,用于指定 Pod 与其他资源(如节点、Pod 或标签)之间的关联性和偏好。
亲和力定义了 Pod 对其他资源的偏好和互动方式,以便在调度过程中进行合适的匹配。通过使用亲和力规则,可以将 Pod 调度到满足特定条件的节点上,或者将 Pod 与其他相关的 Pod 进行关联,以实现特定的调度需求和业务需求。
nodeSelector 提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。 亲和性和反亲和性扩展了你可以定义的约束类型。使用亲和性与反亲和性的一些好处有:
nodeSelector 只能选择拥有所有指定标签的节点。 亲和性、反亲和性为你提供对选择逻辑的更强控制能力。亲和性功能由两种类型的亲和性组成:
nodeSelector 字段,但它的表达能力更强,并且允许你指定软规则。我们可以使用Taint让节点不能随便部署Pod,也通过NodeSelector+Toleration实现了将Pod部署到指定的节点上。但是NodeSelector对节点的选择是强制性的,假如配置了NodeSelector为ssd=true,那么如果集群中没有匹配的节点,这个Pod将一直处于Pending状态。而在生产环境中可能会有这样的需求:
诸如此类的需求单单使用NodeSelector、NodeName、Taint和Toleration是无法实现的,所以Kubernetes引用了Affinity(亲和力)的概念,用于满足生产环境中更复杂的需求。
Affinity根据功能的不同分为节点亲和力(Node Affinity)和Pod亲和力(Pod Affinity),每种亲和力还有两种不同的“实现方法”,即必须和尽量,所以亲和力又分为软亲和力(非强制性)和硬亲和力(强制性)。还可以看出Pod之间可以相互排斥,也可以相互吸引,所以Pod亲和力又分为PodAffinity(Pod亲和力)和PodAntiAffinity(Pod反亲和力),每种亲和力均可以使用软亲和力和硬亲和力。
在使用Kubernetes时,一般都会有很多节点运行容器,此时可以使用Pod反亲和力将同一个应用部署到不同的节点上,达到更高的可用率,以免同一个应用部署到相同的宿主机带来的风险。
1.查看节点污点情况
2.定义一个名为podAntiAffinity01的yaml文件
3.开始部署
root@k8s-master01:~/hhh# kubectl create -f podAntiAffinity01.yaml
deployment.apps/must-be-diff-nodes created4.查看pod状态,观察到pod被部署到不同节点
5.扩容副本数为4个
[root@k8s-master01 Affinity]# kubectl scale deployment must-be-diff-nodes --replicas=4 -n kube-public
deployment.apps/must-be-diff-nodes scaled6.再次查看Pod状态,发现有一个节点处于Pending
7.详细查看Pod处于Pending原因,这是因为我们设置的是硬亲和力,必须部署在不同宿主机上,节点只有5个,而副本数设置为6个,所以导致一直处于Pending
方式一:同一个topology设置Pod反亲和力使Pod只能部署在Node节点上
1.查看节点污点情况
2.给node节点打上标签
root@k8s-master01:~/hhh# kubectl label nodes node-01 node-02 app=must-be-diff-nodes3.定义一个名为podAntiAffinity02的yaml文件
4.开始部署
root@k8s-master01:~/hhh# kubectl create -f podAntiAffinity02.yaml
deployment.apps/must-be-diff-nodes created5.查看pod状态,观察到pod被部署到不同节点
方式二:设置节点亲和力使Pod只能部署在Node0102节点上
1.查看节点污点情况
2.给node01、node02节点打上app=must-be-diff-nodes标签
root@k8s-master01:~/hhh# kubectl label node node-03 app=must-be-diff-nodes
node/node-03 labeled3.定义一个名为podAntiAffinity04的yaml文件
4.开始部署
[root@k8s-master01 Affinity]# kubectl create -f podAntiAffinity04.yaml
deployment.apps/must-be-diff-nodes created5.查看pod状态,观察到pod被部署到node节点
1.给node-01节点打上ssh=true的标签,node-02打上ssh=true和gpu=true的标签,k8s-node03节点打上type=physical的标签方便演示
2.观察以上操作是否完成
3.定义一个yaml文件
4.开始部署
root@k8s-master01:~/hhh# kubectl create -f podAntiAffinity05.yaml
deployment.apps/prefer-ssd created5.结果查看,观察到Pod节点部署到node-01上
6.把k8s-node01节点上的ssd=true标签去除,再次进行创建
7.结果查看,观察到Pod节点部署到node-03上。这是因为node-02节点有gpu限制,所以会次优部署到node-03上。
有时候公司会有一些有状态的服务需要部署在Kubernetes集群中,我们并不需要该服务所在节点宕机时自动漂移Pod,因为可能会带来数据上的丢失,所以需要固定节点去运行,而我们同时也不想每个副本出现部署在同一台宿主机的情况,此时可以使用NodeSelector(NodeAffinity也可以)+PodAntiAffinity实现这一需求。
1.查看节点污点情况
2.给node-03 node-02节点打上app=must-be-diff-nodes标签
root@k8s-master01:~/hhh# kubectl label nodes node-02 node-03 app=must-be-diff-nodes3.定义一个名为podAntiAffinity06的yaml文件
4.开始部署
root@k8s-master01:~/hhh# vim podAntiAffinity06.yaml
root@k8s-master01:~/hhh# kubectl create -f podAntiAffinity06.yaml5.查看pod状态,观察到pod被部署到不同master节点
6.更改副本数为3
一种很常见的架构是后端服务器需要请求缓存中间件,而不是直接请求数据库来提高数据加载速度。在实际使用时,缓存中间件可能也是部署在Kubernetes集群中(如上一个示例),所以此时可以利用Pod反亲和力将后端应用尽量和缓存中间件部署在同一个域内的不同节点,用以减少网络上的消耗。
1.查看节点污点情况
2.定义一个名为podAntiAffinity07的yaml文件
4.开始部署
root@k8s-master01:~/hhh# kubectl create -f podAntiAffinity07.yaml
deployment.apps/must-be-diff-nodes created5.查看pod状态,观察到pod被部署到不同node节点
1.yaml文件展示
上述配置的Pod只能部署在具有label的key为http://kubernetes.io/e2e-az-name、value为e2e-az1或az-2的节点上,但是因为配置了软亲和力,所以在满足上述条件时,会尽量部署在具有another-node-label-key= another-node-label-value的节点上。当然这个条件不是强制要求的,没有该标签的Node不会影响部署。
文件参数说明如下: (1)requiredDuringSchedulingIgnoredDuringExecution:硬亲和力配置
(2)preferredDuringSchedulingIgnoredDuringExecution:软亲和力配置
(3)operator:标签匹配的方式
注意:如果同时指定了NodeSelector和NodeAffinity,需要两者都满足才能被调度;如果配置了多个NodeSelectorTerms,满足其一即可调度到指定的节点上;如果配置了多个MatchExpressions,需要全部满足才能调度到指定的节点上;如果删除了被调度节点上的标签,Pod不会被删除,也就是说亲和力配置只有在调度的时候才会起作用。
NodeAffinity是根据节点上的标签选择性地调度,可以让Pod部署在指定标签的节点上,或者不部署在指定标签的节点上,调度时是根据节点上的标签进行选择的。而Pod亲和力和反亲和力是根据其他Pod的标签进行匹配的,比如想要A服务的Pod不能和具有service=b标签的Pod部署在同一个节点上,此时可以使用Pod亲和力和反亲和力进行配置,该调度是基于Pod的标签进行选择的。
1.yaml文件展示
文件参数说明如下:
上述Pod亲和力配置的是硬亲和力,也就是必须和具有security为S1标签的Pod部署在同一个域内,域的名称为http://failure-domain.beta.kubernetes.io/zone。但同时又配置了Pod反亲和力,尽量不和具有security为S2标签的Pod部署在同一个域内,所以该Pod要求在http://failure-domain.beta.kubernetes.io/zone的域内,要和security为S1部署在一起,尽量不和security为S2部署在一起。
由于Pod的标签是Pod本身的配置,因此它和Pod一样具有隔离性,也就是说在配置Pod亲和力和反亲和力时可以匹配其他Namespace下的Pod的标签。
注意:由于在使用Pod亲和力和Pod反亲和力时,需要进行大量的计算,会降低大规模集群下的调度速率,因此在集群节点超过数百时,并不建议使用过多的Pod亲和力配置。
拓扑域,主要针对宿主机,相当于对宿主机进行区域的划分。用label进行判断,不同的key和不同的value是属于不同的拓扑域.
下面演示同一个应用多区域部署:
1.根据标签区分区域,其中node01为大兴区,node02为朝阳区,node03为XX区
2.查看标签是否已经打上
3.定义一个yaml文件
4.开始部署
root@k8s-master01:~/hhh# kubectl create -f podAntiAffinity03.yaml
deployment.apps/must-be-diff-zone created5.查看pod节点状态
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80root@k8s-master01:~/hhh# kubectl get nodes node-02 --show-labels
NAME STATUS ROLES AGE VERSION LABELS
node-02 Ready node 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-02,kubernetes.io/os=linux,kubernetes.io/role=node,region=subnet100root@k8s-master01:~/hhh# kubectl get nodes node-02 --show-labels
NAME STATUS ROLES AGE VERSION LABELS
node-02 Ready node 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-02,kubernetes.io/os=linux,kubernetes.io/role=node,region=subnet100
root@k8s-master01:~/hhh# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master-01 Ready,SchedulingDisabled master 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master-01,kubernetes.io/os=linux,kubernetes.io/role=master
master-02 Ready,SchedulingDisabled master 32d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master-02,kubernetes.io/os=linux,kubernetes.io/role=master
master-03 Ready,SchedulingDisabled master 33d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master-03,kubernetes.io/os=linux,kubernetes.io/role=master
node-01 Ready node 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-01,kubernetes.io/os=linux,kubernetes.io/role=node,ssd=true
node-02 Ready node 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-02,kubernetes.io/os=linux,kubernetes.io/role=node,region=subnet100
node-03 Ready node 33d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-03,kubernetes.io/os=linux,kubernetes.io/role=noderoot@k8s-master01:~/hhh# kubectl get node --show-labels | grep region
node-02 Ready node 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-02,kubernetes.io/os=linux,kubernetes.io/role=node,region=subnet100root@k8s-master01:~/hhh# kubectl get node -l 'region in (subnet100)' --show-labels
NAME STATUS ROLES AGE VERSION LABELS
node-02 Ready node 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-02,kubernetes.io/os=linux,kubernetes.io/role=node,region=subnet100root@k8s-master01:~/hhh# kubectl get no -l region=subnet7
NAME STATUS ROLES AGE VERSION
node-02 Ready node 34d v1.28.2[root@k8s-master01 practice]# cat nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
nodeSelector:
region: subnet7
containers:
- image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
name: nginx
resources: {}
status: {}root@k8s-master01:~/hhh# kubectl get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-5d576cc5c5-56dp6 1/1 Running 0 12s 10.200.58.229 node-02 <none> <none>
nginx-5d576cc5c5-cr2gc 1/1 Running 0 12s 10.200.58.228 node-02 <none> <none>
nginx-5d576cc5c5-zjcmp 1/1 Running 0 12s 10.200.58.226 node-02 <none> root@k8s-master01:~/hhh# kubectl describe node | grep Taint
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: <none>
Taints: <none>
Taints: <none>[root@k8s-master01 Affinity]# vim podAntiAffinity01.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: must-be-diff-nodes
name: must-be-diff-nodes
namespace: kube-public
spec:
replicas: 3
selector:
matchLabels:
app: must-be-diff-nodes
template:
metadata:
labels:
app: must-be-diff-nodes
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- must-be-diff-nodes
topologyKey: kubernetes.io/hostname
containers:
- image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
imagePullPolicy: IfNotPresent
name: must-be-diff-nodes affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- must-be-diff-nodes
topologyKey: kubernetes.io/hostname
解释:affinity 字段定义了 Pod 的亲和性(affinity)规则。具体来说,podAntiAffinity 字段指定了 Pod 的反亲和性规则,即要求 Pod 在调度时不与具有特定标签的其他 Pod 调度到同一节点上。
在这个示例中,requiredDuringSchedulingIgnoredDuringExecution 字段指定了 Pod 的反亲和性规则是必需的,即必须满足该规则才能进行调度,并且在执行期间不会被忽略。
labelSelector 字段指定了要匹配的标签选择器。在这里,标签选择器要求匹配具有 app 标签,并且其值为 must-be-diff-nodes 的 Pod。
topologyKey 字段指定了用于拓扑约束的键。在这个示例中,使用 kubernetes.io/hostname 作为拓扑约束的键,意味着反亲和性规则将应用于节点的主机名。
因此,这个示例的含义是要求具有标签 app: must-be-diff-nodes 的 Pod 在调度时不会被调度到具有相同主机名的节点上。root@k8s-master01:~/hhh# kubectl get pod -owide -n kube-public
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
must-be-diff-nodes-577dbc86fc-6crs7 1/1 Running 0 109s 10.200.85.252 node-01 <none> <none>
must-be-diff-nodes-577dbc86fc-dsskq 1/1 Running 0 109s 10.200.135.134 node-03 <none> <none>
must-be-diff-nodes-577dbc86fc-rjz4w 1/1 Running 0 109s 10.200.58.231 node-02 <none> <none>root@k8s-master01:~/hhh# kubectl get pod -owide -n kube-public
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
must-be-diff-nodes-577dbc86fc-4gflp 0/1 Pending 0 6s <none> <none> <none> <none>
must-be-diff-nodes-577dbc86fc-6crs7 1/1 Running 0 2m27s 10.200.85.252 node-01 <none> <none>
must-be-diff-nodes-577dbc86fc-dsskq 1/1 Running 0 2m27s 10.200.135.134 node-03 <none> <none>
must-be-diff-nodes-577dbc86fc-rjz4w 1/1 Running 0 2m27s 10.200.58.231 node-02 <none> <none>root@k8s-master01:~/hhh# kubectl describe pod -n kube-public must-be-diff-nodes-577dbc86fc-4gflp
...
...
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 9m46s default-scheduler 0/6 nodes are available: 3 node(s) didn't match pod anti-affinity rules, 3 node(s) were unschedulable. preemption: 0/6 nodes are available: 3 No preemption victims found for incoming pod, 3 Preemption is not helpful for scheduling..
Warning FailedScheduling 4m46s default-scheduler 0/6 nodes are available: 3 node(s) didn't match pod anti-affinity rules, 3 node(s) were unschedulable. preemption: 0/6 nodes are available: 3 No preemption victims found for incoming pod, 3 Preemption is not helpful for scheduling..
root@k8s-master01:~/hhh# kubectl describe node | grep Taint
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: <none>
Taints: <none>
Taints: <none>[root@k8s-master01 Affinity]# vim podAntiAffinity02.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: must-be-diff-nodes
name: must-be-diff-nodes
namespace: kube-public
spec:
replicas: 2
selector:
matchLabels:
app: must-be-diff-nodes
template:
metadata:
labels:
app: must-be-diff-nodes
spec:
nodeSelector:
app: must-be-diff-nodes
containers:
- image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
imagePullPolicy: IfNotPresent
name: must-be-diff-nodesroot@k8s-master01:~/hhh# kubectl get pod -owide -n kube-public
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
must-be-diff-nodes-7ff6887ff5-scttf 1/1 Running 0 4s 10.200.85.254 node-01 <none> <none>
must-be-diff-nodes-7ff6887ff5-w86lh 1/1 Running 0 4s 10.200.58.230 node-02 <none> <none>root@k8s-master01:~/hhh# kubectl describe node | grep Taint
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: <none>
Taints: <none>
Taints: <none>root@k8s-master01:~/hhh# cat podAntiAffinity04.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: must-be-diff-nodes
name: must-be-diff-nodes
namespace: kube-public
spec:
replicas: 3
selector:
matchLabels:
app: must-be-diff-nodes
template:
metadata:
labels:
app: must-be-diff-nodes
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: app
operator: NotIn
values:
- must-be-diff-nodes
containers:
- image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
imagePullPolicy: IfNotPresent
name: must-be-diff-nodes
root@k8s-master01:~/hhh# kubectl get pod -owide -n kube-public
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
must-be-diff-nodes-57f5458d8b-gnjtc 1/1 Running 0 12s 10.200.85.193 node-01 <none> <none>
must-be-diff-nodes-57f5458d8b-nppmh 1/1 Running 0 12s 10.200.58.235 node-02 <none> <none>
must-be-diff-nodes-57f5458d8b-pm8w5 1/1 Running 0 12s 10.200.85.197 node-01 <none> <none>root@k8s-master01:~/hhh# kubectl label node node-01 node-02 ssd=true
root@k8s-master01:~/hhh# kubectl label node node-02 gpu=true
root@k8s-master01:~/hhh# kubectl label node node-03 type=physicalroot@k8s-master01:~/hhh# kubectl get node --show-labels | grep ssd
node-01 Ready node 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-01,kubernetes.io/os=linux,kubernetes.io/role=node,ssd=true
node-02 Ready node 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,gpu=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-02,kubernetes.io/os=linux,kubernetes.io/role=node,region=subnet7,ssd=true
root@k8s-master01:~/hhh# kubectl get node --show-labels | grep gpu
node-02 Ready node 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,gpu=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-02,kubernetes.io/os=linux,kubernetes.io/role=node,region=subnet7,ssd=true[root@k8s-master01 study]# vim podAntiAffinity05.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: prefer-ssd
name: prefer-ssd
namespace: kube-public
spec:
replicas: 1
selector:
matchLabels:
app: prefer-ssd
template:
metadata:
creationTimestamp: null
labels:
app: prefer-ssd
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
- key: ssd
operator: In
values:
- "true"
- key: gpu
operator: NotIn
values:
- "true"
weight: 100
- preference:
matchExpressions:
- key: type
operator: In
values:
- physical
weight: 10
containers:
- env:
- name: TZ
value: Asia/Shanghai
name: LANG
value: C.UTF-8
image: registry.cn-beijing.aliyuncs.com/dotbalo/nginx:1.15.12-alpine
imagePullPolicy: IfNotPresent
name: prefer-ssdroot@k8s-master01:~/hhh# kubectl get po -owide -n kube-public
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
prefer-ssd-7f46fd7d6-f9lpw 1/1 Running 0 22s 10.200.85.196 node-01 <none> <none>root@k8s-master01:~/hhh# kubectl label node node-01 ssd-
node/node-01 unlabeled
root@k8s-master01:~/hhh# kubectl delete -f podAntiAffinity05.yaml
deployment.apps "prefer-ssd" deleted
root@k8s-master01:~/hhh# kubectl create -f podAntiAffinity05.yaml
deployment.apps/prefer-ssd createdroot@k8s-master01:~/hhh# kubectl get po -owide -n kube-public
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
prefer-ssd-7f46fd7d6-4mx2l 1/1 Running 0 13s 10.200.135.154 node-03 <none> <none>[root@k8s-master01 ~]# kubectl describe node | grep Taint
Taints: <none>
Taints: <none>
Taints: <none>
Taints: <none>[root@k8s-master01 Affinity]# vim podAntiAffinity06.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: must-be-diff-nodes
name: must-be-diff-nodes
namespace: kube-public
spec:
replicas: 3
selector:
matchLabels:
app: must-be-diff-nodes
template:
metadata:
labels:
app: must-be-diff-nodes
spec:
nodeSelector:
app: must-be-diff-nodes
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- must-be-diff-nodes
topologyKey: kubernetes.io/hostname
containers:
- image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
imagePullPolicy: IfNotPresent
name: must-be-diff-nodesroot@k8s-master01:~/hhh# kubectl get po -owide -n kube-public
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
must-be-diff-nodes-7ffcb49b94-nlrmh 1/1 Running 0 35s 10.200.135.157 node-03 <none> <none>
must-be-diff-nodes-7ffcb49b94-xg5fw 1/1 Running 0 35s 10.200.58.234 node-02 <none> <none>
root@k8s-master01:~/hhh# kubectl get po -owide -n kube-public
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
must-be-diff-nodes-7ffcb49b94-nlrmh 1/1 Running 0 99s 10.200.135.157 node-03 <none> <none>
must-be-diff-nodes-7ffcb49b94-rs58m 0/1 Pending 0 7s <none> <none> <none> <none>
must-be-diff-nodes-7ffcb49b94-xg5fw 1/1 Running 0 99s 10.200.58.234 node-02 <none> <none>
有一个为pendingroot@k8s-master01:~/hhh# kubectl describe node | grep Taint
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: node.kubernetes.io/unschedulable:NoSchedule
Taints: <none>
Taints: <none>
Taints: <none>[root@k8s-master01 Affinity]# vim podAntiAffinity07.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: must-be-diff-nodes
name: must-be-diff-nodes
namespace: kube-public
spec:
replicas: 3
selector:
matchLabels:
app: must-be-diff-nodes
template:
metadata:
labels:
app: must-be-diff-nodes
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- must-be-diff-nodes
topologyKey: kubernetes.io/hostname
containers:
- image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
imagePullPolicy: IfNotPresent
name: must-be-diff-nodesroot@k8s-master01:~/hhh# kubectl get po -n kube-public -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
must-be-diff-nodes-577dbc86fc-4r8ds 1/1 Running 0 4s 10.200.58.241 node-02 <none> <none>
must-be-diff-nodes-577dbc86fc-mvhfj 1/1 Running 0 4s 10.200.85.212 node-01 <none> <none>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
- az-2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: with-node-affinityapiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: failure-domain.beta.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
namespaces:
- default
topologyKey: failure-domain.beta.kubernetes.io/zone
containers:
- name: with-pod-affinity
image: nginxroot@k8s-master01:~/hhh# kubectl label node node-02 region=chaoyang
root@k8s-master01:~/hhh# kubectl label node node-02 region=chaoyang
root@k8s-master01:~/hhh# kubectl label node node-03 region=xxroot@k8s-master01:~/hhh# kubectl get node -lregion --show-labels
NAME STATUS ROLES AGE VERSION LABELS
node-01 Ready node 34d v1.28.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-01,kubernetes.io/os=linux,kubernetes.io/role=node,region=daxing
node-02 Ready node 34d v1.28.2 app=must-be-diff-nodes,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,gpu=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-02,kubernetes.io/os=linux,kubernetes.io/role=node,region=chaoyang,ssd=true
node-03 Ready node 34d v1.28.2 app=must-be-diff-nodes,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node-03,kubernetes.io/os=linux,kubernetes.io/role=node,region=xx,type=physical[root@k8s-master01 study]# vim podAntiAffinity03.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: must-be-diff-zone
name: must-be-diff-zone
namespace: kube-public
spec:
replicas: 3
selector:
matchLabels:
app: must-be-diff-zone
template:
metadata:
labels:
app: must-be-diff-zone
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- must-be-diff-zone
topologyKey: region
containers:
- image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
imagePullPolicy: IfNotPresent
name: must-be-diff-zoneroot@k8s-master01:~/hhh# kubectl get po -n kube-public -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
must-be-diff-zone-74c5b64688-k7z7k 1/1 Running 0 9s 10.200.135.164 node-03 <none> <none>
must-be-diff-zone-74c5b64688-lgn9z 1/1 Running 0 9s 10.200.85.213 node-01 <none> <none>
must-be-diff-zone-74c5b64688-nxpgm 1/1 Running 0 9s 10.200.58.242 node-02 <none> <none>