默认情况下创建pod调度是根据kubernetes scheduler
默认的调度规则去进行调度的,但有些时候,有些应用有一些特殊的需求比如指定部署到对应的节点、多个pod之间需要部署在不同一个节点,需要互斥、pod和pod间相互交流比较频繁需要跑在同一个节点,需要亲和。这时就需要灵活配置scheduler来实现了。
NodeSelector
NodeSelector
是 Kubernetes 中一种用于调度 Pod 到特定节点的机制。通过在 Pod 的配置中定义 nodeSelector
字段,您可以为 Pod 指定一组键值对标签。这些标签将与集群中的节点标签进行匹配,以确定 Pod 应该被调度到哪个节点上运行。
具体而言,nodeSelector
允许您按照节点的标签选择性地将 Pod 调度到集群中。这种机制非常适用于具有特定硬件要求或运行特定环境的 Pod,以确保它们在正确的节点上运行。
NodeSelector基本用法
此 Pod 配置文件描述了一个拥有节点选择器 disktype: ssd
的 Pod。这表明该 Pod 将被调度到有 disktype=ssd 标签的节点。
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
以下通过案例演示的方式来阐述NodeSelector
的基本用法:
- 列出你的集群中的节点, 包括这些节点上的标签,输出类似如下:
controlplane $ kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
controlplane Ready control-plane 12h v1.29.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=controlplane,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=
node01 Ready <none> 12h v1.29.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux
- 从你的节点中选择一个,为它添加标签
kubectl label nodes node01 disktype=ssd
- 验证你选择的节点确实带有
disktype=ssd
标签:
- 创建一个将被调度到你选择的节点的Pod
kubectl create -f pod-nginx.yaml
- pod-nginx.yaml文件的内容是上述yaml所示。
- 创建成功后这个pod会调度到包含有
disktype=ssd
的标签中
执行成功后,验证Pod 确实运行在你选择的节点上:
controlplane $ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 11s 192.168.1.4 node01 <none> <none>
我们还可以通过设置spec.nodeName
参数将某个Pod 调度到特定的节点。演示yaml如下:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: foo-node # 调度 Pod 到特定的节点
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
亲和性
理论知识
- 亲和性分为软亲和以及硬亲和性。
preferredDuringSchedulingIgnoredDuringExecution
:软策略 可以不再最好在requiredDuringSchedulingIgnoredDuringExecution
:硬策略 必须在
- 键值运算
In
:label 的值在某个列表中NotIn
:label 的值不在某个列表中Gt
:label 的值大于某个值Lt
:label 的值小于某个值Exists
:某个 label 存在DoesNotExist
:某个 label 不存在
Affinity
翻译成中文是“亲和性”,它对应的是 Anti-Affinity
,我们翻译成“互斥”。这两个词比较形象,可以把 pod 选择 node 的过程类比成磁铁的吸引和互斥,不同的是除了简单的正负极之外,pod 和 node 的吸引和互斥是可以灵活配置的。
- Affinity的优点
- 匹配有更多的逻辑组合,不只是字符串的完全相等
- 调度分成软策略(soft)和硬策略(hard),在软策略下,如果没有满足调度条件的节点,pod会忽略这条规则,继续完成调度。
- 目前主要的node affinity
requiredDuringSchedulingIgnoredDuringExecution
:表示pod必须部署到满足条件的节点上,如果没有满足条件的节点,就不停重试。其中IgnoreDuringExecution表示pod部署之后运行的时候,如果节点标签发生了变化,不再满足pod指定的条件,pod也会继续运行。requiredDuringSchedulingRequiredDuringExecution
:表示pod必须部署到满足条件的节点上,如果没有满足条件的节点,就不停重试。其中RequiredDuringExecution表示pod部署之后运行的时候,如果节点标签发生了变化,不再满足pod指定的条件,则重新选择符合要求的节点。preferredDuringSchedulingIgnoredDuringExecution
:表示优先部署到满足条件的节点上,如果没有满足条件的节点,就忽略这些条件,按照正常逻辑部署。preferredDuringSchedulingRequiredDuringExecution
:表示优先部署到满足条件的节点上,如果没有满足条件的节点,就忽略这些条件,按照正常逻辑部署。其中RequiredDuringExecution表示如果后面节点标签发生了变化,满足了条件,则重新调度到满足条件的节点。
案例演示
- 下面是一个官方的示例:
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: gcr.io/google_containers/pause:2.0
这个 pod 同时定义了 requiredDuringSchedulingIgnoredDuringExecution 和 preferredDuringSchedulingIgnoredDuringExecution 两种 nodeAffinity。第一个要求 pod 运行在特定 AZ 的节点上,第二个希望节点最好有对应的 another-node-label-key:another-node-label-value 标签。
CKA真题
真题截图
中文解析
切换 k8s 集群环境:kubectl config use-context k8s
Task:
创建一个 Pod,名字为 nginx-kusc00401
,镜像地址是 nginx
,调度到具有 disk=spinning
标签的节点上。
官方参考文档
将 Pod 分配给节点 | Kubernetes
做题解答
- 切换切换k8s集群环境
kubectl config use-context k8s
- 创建Pod的资源对象
apiVersion: v1
kind: Pod
metadata:
name: nginx-kusc00401
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disk: spinning
- 执行命令创建pod
kubectl apply -f nginx-kusc00401.yaml