目录
PodAffinity、PodAntiAffinity 配置详解
语雀同文笔记:亲/反亲和性 · 语雀
调度 遗留的问题
pod 与 node 之间的关系 | 某些Pod优先选择有ssd=true标签的节点,如果没有在考虑部署到其它节点;如果只是使用labels 和 nodeselector,如果所有节点没有 ssd=true 这个标签,那么pod将无法调度一直处于pending状态。 |
某些Pod需要部署在ssd=true和type=physical的节点上,但是优先部署在ssd=true的节点上; | |
pod 与 pod 之间的关系 | 同一个应用的Pod不同的副本或者同一个项目的应用 尽量或必须不部署(反亲和性)在同一个节点或者符合某个标签的一类节点上或者不同的区域; |
相互依赖的两个Pod 尽量或必须部署(亲和性)在同一个节点上或者同一个域内 |
提高可用率演示
将服务部署在不同的机器上
Pod 的副本都部署在一个机器上,当此机器出现故障,业务无法访问。
将pod副本部署在不同的机器上,当有一个机器出现故障,其他pod仍可提供应用服务。
将服务部署在不同的机房中
将服务部署在同一机房中,机房发生故障,所有服务都将中断。
将 pod 部署在不同的机房中当某个机房发生故障,其他机房仍可提供服务。
Affinity 的分类
亲和力的本质:Node 节点上有符合亲和力中某个matchExpressions的标签匹配规则就可以将pod调度到/调离该节点。
- 补充1:某个matchExpressions 下面有多个key,Node节点必须同时满足每个key的匹配规则。
- 补充2:Node 其实也有反亲和力,只不过是通过 Operator 设置为 NotIn 来实现的。
小技巧:Node亲和力和Pod亲和力配置文件都差不多,唯一不同的就是软硬亲和力下面的第一个参数:
- 硬亲和力(requiredDuringSchedulingIgnoredDuringExecution):
-
- Node 硬亲和力:NodeSelectorTerms
- Pod 硬亲和力:LabelSelector
- 软亲和力(preferredDuringSchedulingIgnoredDuringExecution):
-
- Node 软亲和力:perference
- Pod 软亲和力:podAffinityTerm -> labelSelector
NodeAffinity 配置详解
本质:亲和力中定义规则 与 Node标签 是否匹配。
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
namespace: test-affinity
spec:
containers:
- name: nginx1
image: dockerpull.org/nginx
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms: # Node亲和力,硬限制下面是NodeSelectorTerms
# 必须同时满足 e2e-az-name=e2e-az1|az-2 && hostname= k8s-master01
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- az-2
- key: hostname
operator: In
values:
- k8s-master01
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
requiredDuringSchedulingIgnoredDuringExecution:硬亲和力配置
- nodeSelectorTerms:节点选择器配置,
-
- matchExpressions(匹配节点的标签):可以配置多个(满足其一),每个matchExpressions下可以配置多个key、value类型的选择器(都需要满足),其中values可以配置多个
preferredDuringSchedulingIgnoredDuringExecution (满足其一) :软亲和力配置
- weight:软亲和力的权重,权重越高优先级越大,范围1-100
- preference:软亲和力配置项,和weight同级,可以配置多个,
-
- matchExpressions和硬亲和力一致
-
-
- operator:标签匹配的方式
-
-
-
-
- In:相当于key = value的形式
- NotIn:相当于key != value的形式
- Exists:节点存在label的key为指定的值即可,不能配置values字段
- DoesNotExist:节点不存在label的key为指定的值即可,不能配置values字段
- Gt:大于value指定的值
- Lt:小于value指定的值
-
-
PodAffinity、PodAntiAffinity 配置详解
本质:亲和力中定义规则 与 Pod 的标签 是否匹配。
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
namespace: test-affinity
spec:
containers:
- name: nginx-pod-affinity
image: dockerpull.org/nginx
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
topologyKey: failure-domain.beta.kubernetes.io/zone
namespaces:
- test-affinity
labelSelector | Pod选择器配置,可以配置多个。 |
operator | 配置和节点亲和力一致,但是没有Gt和Lt。 |
topologyKey | 匹配的拓扑域的key,也就是节点上label的key,key和 value相同的为同一个域,可以用于标注不同的机房和地区。 |
Namespaces | 和哪个命名空间的Pod进行匹配,为空为当前命名空间。 |
- 注意:Pod亲和力也可以配置多个个 matchExpressions(匹配pod的标签),也就是配置多个labelselector;Pod亲和力需要配置 topology(拓扑域)
Topology 详解
topologyKey:拓扑域,主要针对宿主机,相当于对宿主机进行区域的划分。用label进行判断,不同的key和不同的value是属于不同的拓扑域。同一拓扑域必须满足标签的key和value都相等。
Affinity 的使用
示例1:同一应用部署在不同的宿主机
解释:该pod不会和具有 must-be-diff-nodes 这个标签的pod部署在一起,此示例中的 pod 本身打了must-be-diff-nodes 这个标签,所以此服务的多个副本pod不会部署在一起。
apiVersion: apps/v1
kind: Deployment
metadata:
name: must-be-diff-nodes
namespace: test-affinity
labels:
app: must-be-diff-nodes
spec:
replicas: 3
selector:
matchLabels:
app: must-be-diff-nodes
template:
metadata:
# pod 本身打了must-be-diff-nodes 这个标签
labels:
app: must-be-diff-nodes
spec:
containers:
- name: nginx-test-pod-antiaffinity
image: dockerpull.org/nginx
imagePullPolicy: IfNotPresent
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
# 不和具有 must-be-diff-nodes 这个标签的pod部署在一起
matchExpressions:
- key: app
operator: In
values:
- must-be-diff-nodes
# kubernetes.io/hostname=k8s-master01,kubernetes.io/hostname=k8s-master02
# 每个节点的拓扑域不同所以 每个机器都能部署一个pod
topologyKey: kubernetes.io/hostname
示例2:同一个应用不同副本固定节点
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-cache
namespace: test-affinity
spec:
replicas: 3
selector:
matchLabels:
app: store
template:
metadata:
labels:
app: store
spec:
containers:
- name: redis-server
image: dockerpull.org/redis:3.2-alpine
imagePullPolicy: IfNotPresent
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: kubernetes.io/hostname
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- store
示例3:应用和缓存尽量部署在同一域内
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
namespace: test-affinity
spec:
replicas: 3
selector:
matchLabels:
app: web-store
template:
metadata:
labels:
app: web-store
spec:
containers:
- name: web1
image: dockerpull.org/nginx
imagePullPolicy: IfNotPresent
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-store
topologyKey: kubernetes.io/hostname
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-store
topologyKey: kubernetes.io/hostname
示例4:尽量调到高配置服务器上
# 给 maseter01 节点打上 ssd=true,master=true
# 给 node01 节点打上 ssd=true; 给 node02打上 type=physical 标签
apiVersion: apps/v1
kind: Deployment
metadata:
name: prefer-ssd
namespace: test-affinity
spec:
replicas: 1
selector:
matchLabels:
app: prefer-ssd
template:
metadata:
labels:
app: prefer-ssd
spec:
containers:
- name: nginx1
image: dockerpull.org/nginx
imagePullPolicy: IfNotPresent
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: ssd
operator: In
values:
- "true"
- key: master
operator: NotIn
values:
- "true"
- weight: 50
preference:
matchExpressions:
- key: type
operator: In
values:
- physical
示例5:同一应用多区域部署
# 给 master01,master02 划分到 China 地区
# 给 master03,node01 划分到 America 地区
# 给 node02 划分到 MiddleEast 地区
kubectl label node k8s-master01 k8s-master02 region=China
kubectl label node k8s-master03 k8s-node01 region=America
kubectl label node k8s-node02 region=MiddleEast
apiVersion: apps/v1
kind: Deployment
metadata:
name: must-be-diff-zone
namespace: test-affinity
labels:
app: must-be-diff-zone
spec:
replicas: 3
selector:
matchLabels:
app: must-be-diff-zone
template:
metadata:
labels:
app: must-be-diff-zone
spec:
containers:
- name: nginx1
image: dockerpull.org/nginx
imagePullPolicy: IfNotPresent
affinity:
podAntiAffinity:
# 同一个region域内只能有一个pod,
# 也就是说 master01、master02 机器上只能有一个 pod
# master03 node01 机器上只能有一个 pod
# node02 机器上只能有一个 pod
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- must-be-diff-zone
topologyKey: region
注意:如果机器没有配置拓扑域(没有给node节点打上region标签),pod将会被调度到相同的机器
此时5个节点共有3个域 China、America、MiddleEast,每个域内只能存在一个pod,如果有第四个副本,那个pod将会处于pending状态。
柠檬的留言
账号整体情况
小伙伴们好,目前柠檬的账号处于整改和建设中,欢迎大家在各个平台的评论区留言或私信“柠檬”提出您宝贵的建议,非常感谢!
- 语雀笔记:hualulemon、HuaLuLemon
- CSDN:华鹿札记、华鹿札记-CSDN博客
- 公众号:华鹿札记
- 其他平台:华鹿札记
- 作者:柠檬(Lemon)
资源获取方式
小伙伴们好,柠檬会逐步地将自己所有的资源都通过网盘的方式分享给大家,资源内容包括(PDF、笔记、视频、音频、安装包等等),如果您有需要可以按照下面的操作获取资源,以专业资源获取方式例:
- 第一步:访问“语雀专业资源页面”:🖇️🖇️🖇️专业资源🖇️🖇️🖇️
- 第二步:在“华鹿札记”公众号输入你要获取的资源的“关键字”(通过第一步得知)
- 第三步:百度网盘保存链接,将资源转移到你自己的百度网盘中即可。
注意:千万不要让资料吃灰哦,祝您学有所成💯