网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
metadata:
name: test
apiVersion: v1
kind: Pod
metadata:
labels:
app: nodeaffinity-required-label
name: nodeaffinity-required
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
affinity: # 亲和性配置
nodeAffinity: # node亲和性配置
requiredDuringSchedulingIgnoredDuringExecution: # Node节点必须满足指定的所有规则才可以,相当于硬规则,类似于定向调度
nodeSelectorTerms: # 节点选择列表
- matchExpressions:
- key: role # 匹配存在标签的key为role的节点,并且value是"user111"或"admin111"的节点
operator: In
values:
- “user”
- “admin666”
* 重新执行配置文件:
[root@k8s-master ~]# kubectl delete -f nodeaffinity-required.yaml
[root@k8s-master ~]# kubectl apply -f nodeaffinity-required.yaml
* **可以看到我们的Pod节点成功调度到slave01节点上了,因为我们上面定义的规则slave01是满足的。**
[root@k8s-master ~]# kubectl describe pods nodeaffinity-required -n test
Name: nodeaffinity-required
Events:
Type Reason Age From Message
Normal Scheduled 43s default-scheduler Successfully assigned test/nodeaffinity-required to k8s-slave01
Normal Pulled 42s kubelet, k8s-slave01 Container image “nginx:1.17” already present on machine
Normal Created 42s kubelet, k8s-slave01 Created container nginx-container
Normal Started 42s kubelet, k8s-slave01 Started container nginx-container
###### nodeAffinity(preferredDuringSchedulingIgnoredDuringExecution软限制类型)
* required(硬限制)和preferred(软限制)两种类型的区别就是:
+ **required(硬限制):1种情况**
- 1:**required(硬限制)如果找不到符合定义的条件的Pod或者node,则直接调度失败。**
+ **preferred(软限制):3种情况**
- 1:preferred(软限制)如果找不到符合定义的条件的Pod或者node,则也会将Pod调度到不符合条件的节点上。
- 2:如果找到符合定义的条件的Pod或者node,并且只有一个Pod或者node满足条件,则直接调度上去。
- 3:如果找到符合定义的条件的Pod或者node,并且如果定义了多个条件都是同时满足的话,就会通过weight(权值)进行筛选,挑选出Pod或者node满足的条件对应的weight值最大的那一个。
###### podAffinity
**podAffinity:让Pod调度到符合标签的Pod所在的node节点上。(说白了就是靠近符合标签的Pod)**
* podAffinity的可选配置项:
pod.spec.affinity.podAffinity
requiredDuringSchedulingIgnoredDuringExecution 硬限制
namespaces 指定参照pod的namespace
topologyKey 指定调度作用域
labelSelector 标签选择器
matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
key 键
values 值
operator 关系符 支持In, NotIn, Exists, DoesNotExist.
matchLabels 指多个matchExpressions映射的内容
preferredDuringSchedulingIgnoredDuringExecution 软限制
podAffinityTerm 选项
namespaces
topologyKey
labelSelector
matchExpressions
key 键
values 值
operator
matchLabels
weight 倾向权重,在范围1-100(权值越大,优先级越高)
* **topologyKey用于指定调度的作用域,例如:**
+ **如果指定为kubernetes.io/hostname,那就是以Node节点为区分范围。说白了就是调度到目标Pod相同的node节点上。(常用)**
+ 如果指定为beta.kubernetes.io/os,则以**Node节点的操作系统**类型来区分。
>
> 案例:创建一个targetPod,打上podrole: pod-admin标签,并且定向调度到slave02节点上,再创建一个新的Pod使用Pod亲和性调度匹配podrole标签值为user111或者pod-admin,符合上面的条件则调度到这个targetPod所在的node上。如果案例实验成功,则会出现podaffinity-required的Pod调度到了slave02上。
>
>
>
* 创建yaml文件
vim podaffinity-required.yaml
* 内容如下:
apiVersion: v1
kind: Namespace
metadata:
name: test
apiVersion: v1
kind: Pod
metadata:
labels:
podrole: pod-admin
name: targetpod
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
nodeName: k8s-slave02
apiVersion: v1
kind: Pod
metadata:
labels:
app: podaffinity-required-label
name: podaffinity-required
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
affinity: # 亲和性配置
podAffinity: # Pod亲和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
- labelSelector:
matchExpressions:
- key: podrole
operator: In
values:
- “user111”
- “pod-admin”
topologyKey: kubernetes.io/hostname
namespaces:
- “test” #参照(target)Pod所在的namespace
* 执行配置文件:
[root@k8s-master ~]# kubectl apply -f podaffinity-required.yaml
namespace/test unchanged
pod/targetpod unchanged
pod/podaffinity-required created
* 查看Pod:(成功)
[root@k8s-master ~]# kubectl get pods -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
podaffinity-required 1/1 Running 0 23s 10.244.2.28 k8s-slave02
targetpod 1/1 Running 0 2m9s 10.244.2.27 k8s-slave02
###### podAntiAffinity
**podAntiAffinity:让Pod调度到不符合标签的Pod所在的node节点上。(说白了就是远离符合标签的Pod)**
>
> 案例:创建一个targetPod,打上podrole: pod-admin标签,并且定向调度到slave02节点上,再创建一个新的Pod使用Pod的反亲和性调度匹配podrole标签值为user111或者pod-admin,符合上面的条件则调度到这个targetPod相反(不同)的node上。如果案例实验成功,则会出现podaffinity-required的Pod调度到了slave01上。
>
>
>
* 创建yaml文件
vim podantiaffinity-required.yaml
* 内容如下:
apiVersion: v1
kind: Namespace
metadata:
name: test
apiVersion: v1
kind: Pod
metadata:
labels:
podrole: pod-admin
name: targetpod
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
nodeName: k8s-slave02
apiVersion: v1
kind: Pod
metadata:
labels:
app: podantiaffinity-required-label
name: podantiaffinity-required
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
affinity: # 亲和性配置
podAntiAffinity: # Pod的反亲和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬限制
- labelSelector:
matchExpressions:
- key: podrole
operator: In
values:
- “user111”
- “pod-admin”
topologyKey: kubernetes.io/hostname
namespaces:
- “test” #参照(target)Pod所在的namespace
* 执行配置文件:
[root@k8s-master ~]# kubectl apply -f podantiaffinity-required.yaml
namespace/test created
pod/targetpod created
pod/podantiaffinity-required created
* 查看Pod:(成功)
[root@k8s-master ~]# kubectl get pods -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
podantiaffinity-required 1/1 Running 0 33s 10.244.1.23 k8s-slave01
targetpod 1/1 Running 0 33s 10.244.2.31 k8s-slave02
###### 污点、容忍调度
###### Taints
* 污点与亲和性调度有什么区别?
+ **亲和性调度的作用范围可以是node和Pod。而污点的作用范围只能是node**,**我们只能通过给node打上污点(和label不同,污点是taint)**
+ **污点说白了就是node的一种驱赶策略。除了PreferNoSchedule类型,其他类型的情况下,Pod如果想要调度到有污点的node上,需要进行容忍这个污点,否则Pod将无法调度上去。**
* 污点的格式为:key=value:effect ,key=value是污点标签,effect是污点的类型。污点有三种类型,分为三个等级,第1级最友好,第3级最不友好。
* + 1(最低级):PreferNoSchedule:kubernetes将尽量避免把Pod调度到具有该污点的Node上,除非没有其他节点可以调度。
* + 2(中等):NoSchedule:kubernetes将不会把Pod调度到具有该污点的Node上,但是不会影响当前Node上已经存在的Pod。
* + 3(最高级):NoExecute:kubernetes将不会把Pod调度到具有该污点的Node上,同时也会将Node上已经存在的Pod驱逐。
>
> 设置污点:
>
>
>
格式:
kubectl taint node node节点名称 key=value:effect
>
> 去除污点:
>
>
>
格式:
kubectl taint node node节点名称 key:effect-
>
> 去除所有污点:
>
>
>
kubectl taint node node节点名称 key-
>
> 查看指定节点上的污点:
>
>
>
kubectl describe node node节点名称
>
> 案例要求:
>
>
> 1:关闭slave02服务器,只保留master和slave01服务器。
>
>
> 2:给slave01打上PreferNoSchedule污点(taintkey=taintvalue),再创建一个Pod或者Pod控制器,查看pod调度情况。
>
>
> 3:取消slave01的污点,再给slave01打上NoSchedule污点(taintkey=taintvalue),再创建一个Pod或者Pod控制器,查看pod调度情况。
>
>
> 4:取消slave01的污点,再给slave01打上NoExecute污点(taintkey=taintvalue),再创建一个Pod或者Pod控制器,查看pod调度情况。
>
>
>
* 创建一个命名空间:
kubectl create ns dev
* 给k8s-slave01打上污点(PreferNoSchedule):
kubectl taint node k8s-slave01 taintkey=taintvalue:PreferNoSchedule
* 运行一个Pod控制器(自动会产生Pod并调度到节点上):
[root@k8s-master ~]# kubectl run pod1 --image=nginx:1.17 -n dev
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/pod1 created
* 查看Pod调度情况:
[root@k8s-master ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1-65b5d99b46-5cj47 1/1 Running 0 32s 10.244.1.25 k8s-slave01
* 删除slave01的污点
[root@k8s-master ~]# kubectl taint node k8s-slave01 taintkey:PreferNoSchedule-
node/k8s-slave01 untainted
* 给slave01打上NoSchedule污点(taintkey=taintvalue)
[root@k8s-master ~]# kubectl taint node k8s-slave01 taintkey=taintvalue:NoSchedule
node/k8s-slave01 tainted
* 运行一个Pod控制器:
kubectl run pod2 --image=nginx:1.17 -n dev
* 查看Pod,发现我们的pod2没有成功调度。
[root@k8s-master ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1-65b5d99b46-5cj47 1/1 Running 1 18h 10.244.1.26 k8s-slave01
pod2-d68559894-j2f5t 0/1 Pending 0 73s
* 使用describe查看Pod2,因为我们只有一个node节点,而那个节点却被打上了NoSchedule污点,所以无法调度上去,**但是我们可以从上面看到pod1处于(Running状态)正常运行中。**
[root@k8s-master ~]# kubectl describe pods pod2-d68559894-j2f5t -n dev
Name: pod2-d68559894-j2f5t
Events:
Type Reason Age From Message
Warning FailedScheduling default-scheduler 0/3 nodes are available: 3 node(s) had taints that the pod didn’t tolerate.
Warning FailedScheduling default-scheduler 0/3 nodes are available: 3 node(s) had taints that the pod didn’t tolerate.
* 删除slave01的污点
kubectl taint node k8s-slave01 taintkey:NoSchedule-
* 给slave01打上NoExecute污点(taintkey=taintvalue)
kubectl taint node k8s-slave01 taintkey=taintvalue:NoExecute
* 查看Pod:
[root@k8s-master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pod1-65b5d99b46-tvzcg 0/1 Pending 0 10s
pod2-d68559894-268mr 0/1 Pending 0 10s
**我们发现之前被成功调度到slave01的pod1从Running变成了Pending!!!**
* 运行一个Pod控制器:
kubectl run pod3 --image=nginx:1.17 -n dev
[root@k8s-master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pod1-65b5d99b46-tvzcg 0/1 Pending 0 112s
pod2-d68559894-268mr 0/1 Pending 0 112s
pod3-5fc49f964b-pqsmx 0/1 Pending 0 2s
**可以发现NoExecute类型的污点不仅仅会把已经被调度到该节点的Pod赶走,还会让其他新创建的Pod调度失败。**
###### tolerations
* 容忍的作用是什么?
+ 当我们想让Pod可以调度到被打上污点的node节点上的时候,我们就需要使用容忍机制。
+ **如果不使用容忍机制的话,我们创建的Pod是无法被调度到打了污点(除了PreferNoSchedule类型的污点)的node节点上的,只有当我们的Pod容忍这个污点的时候我们才可以调度到这些node节点上去。**
* \*\*使用kubeadm构建的kubernetes集群,默认会把我们的master节点打上NoSchedule污点,这也是为什么我们的Pod只会调度到node工作节点上,而不会被调度到master管理节点上的原因。\*\*这些后面再讲。
>
> 容忍的配置:
>
>
>
[root@k8s-master ~]# kubectl explain pods.spec.tolerations
KIND: Pod
VERSION: v1
RESOURCE: tolerations <[]Object>
FIELDS:
key # 对应着要容忍的污点的键,空意味着匹配所有的键
value # 对应着要容忍的污点的值
operator # key-value的运算符,支持Equal和Exists(默认)
effect # 对应污点的effect,空意味着匹配所有影响
tolerationSeconds # 容忍时间, 当effect为NoExecute时生效,表示pod在Node上的停留时间
>
> 配置容忍的几种情况:
>
>
>
* **当operator为Equal的时候:**
+ **1:如果Node节点有多个Taint污点,那么Pod每个Taint污点都需要被容忍才能部署上去。**
* **当operator为Exists的时候:**
+ 1:容忍指定的污点,污点带有指定的effect:
tolerations: # 容忍
- key: “tag” # 要容忍的污点的key
operator: Exists # 操作符
effect: NoExecute # 添加容忍的规则,这里必须和标记的污点规则相同
+ 2:容忍指定的污点,不考虑具体的effect:
tolerations: # 容忍
- key: “tag” # 要容忍的污点的key
operator: Exists # 操作符
+ 3:容忍一切污点:(小心使用)
tolerations: # 容忍
- operator: Exists # 操作符
>
> 案例过程:
>
>
> 1:先给k8s-slave01打上NoExecute污点,这样所有节点都无法调度上去。
>
>
> 2:创建一个Pod,设置其能够容忍NoExeucute污点。
>
>
> 3:查看Pod调度情况。
>
>
>
* 1:先给k8s-slave01打上NoExecute污点,这样所有节点都无法调度上去。
kubectl taint node k8s-slave01 taintkey=taintvalue:NoExecute
* 2:创建一个Pod,设置其能够容忍NoExeucute污点。
创建配置文件:
vim podtoleration.yaml
文件内容:
apiVersion: v1
kind: Namespace
metadata:
name: dev
apiVersion: v1
kind: Pod
metadata:
name: podtoleration
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
tolerations: # 配置容忍
- key: “taintkey” # 要容忍的污点的key
operator: Equal # 操作符
value: “taintvalue” # 要容忍的污点的value
effect: NoExecute # 添加容忍的规则,这里必须和标记的污点规则相同
执行配置文件:
[root@k8s-master ~]# kubectl apply -f podtoleration.yaml
namespace/dev created
pod/podtoleration created
* 3:查看Pod调度情况。
[root@k8s-master ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
podtoleration 1/1 Running 0 75s 10.244.1.32 k8s-slave01
**可以看到虽然我们的k8s-slave01被打上了NoExecute污点,但是由于我们新创建的Pod容忍了这个污点,所以才可以调度上去。**
###### 为什么Master节点不会被调度
* 使用describe查看master节点:
[root@k8s-master ~]# kubectl describe node k8s-master
Name: k8s-master
Roles: master
Taints: node-role.kubernetes.io/master:NoSchedule
…
* **可以看到我们的master节点默认就被打上了NoSchedule类型的污点,所以我们的Pod是不会被调度到这个master节点上的。**
❤️💛🧡**本章结束,我们下一章见**❤️💛🧡
![img](https://img-blog.csdnimg.cn/img_convert/41ed2475f8e44b64da78396e83e55510.png)
![img](https://img-blog.csdnimg.cn/img_convert/88525f0eecb9566390403d136e581e5d.png)
![img](https://img-blog.csdnimg.cn/img_convert/8f0e45c05cdf99120fd46bae17e31eb8.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**
8s-slave01被打上了NoExecute污点,但是由于我们新创建的Pod容忍了这个污点,所以才可以调度上去。**
###### 为什么Master节点不会被调度
* 使用describe查看master节点:
[root@k8s-master ~]# kubectl describe node k8s-master
Name: k8s-master
Roles: master
Taints: node-role.kubernetes.io/master:NoSchedule
…
* **可以看到我们的master节点默认就被打上了NoSchedule类型的污点,所以我们的Pod是不会被调度到这个master节点上的。**
❤️💛🧡**本章结束,我们下一章见**❤️💛🧡
[外链图片转存中...(img-nfq1xThA-1715622191089)]
[外链图片转存中...(img-SEdsEoBq-1715622191090)]
[外链图片转存中...(img-zYnFIwXH-1715622191090)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**