我们前面部署的pod调度取决于kube-scheduler,它会根据自己的算法,集群的状态来选择合适的node部署我们的pod。
下面我们来看下如何来根据我们自己的要求,来影响pod的调度。
定向node调度
有时候我们想将pod调度到某一些node上,比如csharp开发的程序,调度到某一些node,java开发的程序调度到另一些node,这时候我们可以选择定向调度。
定向调度需要用到我们前面说的label,具体做法就是将node打上指定的label,然后在定义pod/deployment的时候根据nodeselector指定node
node1添加label
代码语言:javascript复制kubectl label nodes k8s-node1 language=csharp
指定nodeSelector字段
代码语言:javascript复制apiVersion: apps/v1
kind: Deployment
metadata:
name: chesterdeployment
namespace: chesterns
labels:
app: chesterapi
spec:
replicas: 1
selector:
matchLabels:
app: chesterapi
template:
metadata:
labels:
app: chesterapi
spec:
containers:
- name: oneapi
image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest
ports:
- containerPort: 5000
livenessProbe:
httpGet:
path: /test
port: 5000
- name: twoapi
image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest
ports:
- containerPort: 5001
livenessProbe:
httpGet:
path: /test/calloneapi
port: 5001
nodeSelector:
language: csharp
代码语言:javascript复制
重新apply deployment即可发现pod已经调度到我们的node1上
代码语言:javascript复制kubectl delete -f deployment.yaml
kubectl apply -f deployment.yaml
kubectl describe pod -n chesterns
亲和性
节点亲和类似于nodeSelector,可以根据节点上的标签来约束Pod可以调度到哪些节点。相比nodeSelector,亲和性有以下特点:
- 匹配有更多的逻辑组合,不只是字符串的完全相等
- 调度分为软策略和硬策略,而不是硬性要求
- required:必须满足
- preferred:尝试满足,但不保证
下面我们通过亲和性来将pod,调度到node1上
代码语言:javascript复制apiVersion: apps/v1
kind: Deployment
metadata:
name: chesterdeployment
namespace: chesterns
labels:
app: chesterapi
spec:
replicas: 1
selector:
matchLabels:
app: chesterapi
template:
metadata:
labels:
app: chesterapi
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: language
operator: In
values:
- csharp
- golang
containers:
- name: oneapi
image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest
ports:
- containerPort: 5000
livenessProbe:
httpGet:
path: /test
port: 5000
- name: twoapi
image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest
ports:
- containerPort: 5001
livenessProbe:
httpGet:
path: /test/calloneapi
port: 5001
可以通过kubectl apply来验证结果。
亲和性有In、NotIn、Exists、DoesNotExist、Gt、Lt操作符
亲和性规则
- 如果同时定义了nodeSelector和nodeAffinity,那么必须两个条 件都得到满足,Pod才能最终运行在指定的Node上。
- 如果nodeAffinity指定了多个nodeSelectorTerms,那么其中一个 能够匹配成功即可。
- 如果在nodeSelectorTerms中有多个matchExpressions,则一个节 点必须满足所有matchExpressions才能运行该Pod。
删除node上的label
代码语言:javascript复制kubectl label nodes k8s-node1 language-
资源开销
容器的资源开销同样会影响pod的调度,在调度时,kube-scheduler会找到一台与yaml中限制的资源匹配的node.
容器资源限制:
- resources.limits.cpu
- resources.limits.memory
容器使用的最小资源需求,作为容器调度时资源分配的依据:
- resources.requests.cpu
- resources.requests.memory
apiVersion: apps/v1
kind: Deployment
metadata:
name: chesterdeployment
namespace: chesterns
labels:
app: chesterapi
spec:
replicas: 1
selector:
matchLabels:
app: chesterapi
template:
metadata:
labels:
app: chesterapi
spec:
containers:
- name: oneapi
image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest
ports:
- containerPort: 5000
livenessProbe:
httpGet:
path: /test
port: 5000
resources:
limits:
cpu: 1000m
memory: 2000Mi
requests:
cpu: 100m
memory: 200Mi
代码语言:javascript复制
污点Taint
NodeAffinity节点亲和性,是在Pod上定义的一种属性, 使得Pod能够被调度到某些Node上运行(优先选择或强制要求)。Taint 则正好相反,它让Node拒绝Pod的运行。
设置污点
代码语言:javascript复制#k ubectl taint node [node] key=value:[effect]
kubectl taint node k8s-node1 language=csharp:NoExecute
其中[effect] 可取值:
- NoSchedule :一定不能被调度。
- PreferNoSchedule:尽量不要调度。
- NoExecute:不仅不会调度,还会驱逐Node上已有的Pod。
apiVersion: apps/v1
kind: Deployment
metadata:
name: chesterdeployment
namespace: chesterns
labels:
app: chesterapi
spec:
replicas: 1
selector:
matchLabels:
app: chesterapi
template:
metadata:
labels:
app: chesterapi
spec:
containers:
- name: oneapi
image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest
ports:
- containerPort: 5000
livenessProbe:
httpGet:
path: /test
port: 5000
- name: twoapi
image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest
ports:
- containerPort: 5001
livenessProbe:
httpGet:
path: /test/calloneapi
port: 5001
代码语言:javascript复制
可以通过kubectl apply来验证结果。
Tolerations
在 Node上设置一个或多个Taint之后,除非Pod明确声明能够容忍这些污点,否则无法在这些Node上运行。Toleration是Pod的属性,让Pod能够 (注意,只是能够,而非必须)运行在标注了Taint的Node上。
代码语言:javascript复制apiVersion: apps/v1
kind: Deployment
metadata:
name: chesterdeployment
namespace: chesterns
labels:
app: chesterapi
spec:
replicas: 1
selector:
matchLabels:
app: chesterapi
template:
metadata:
labels:
app: chesterapi
spec:
tolerations:
- key: "language"
operator: "Equal"
value: "csharp"
effect: "NoExecute"
containers:
- name: oneapi
image: registry.cn-beijing.aliyuncs.com/chester-k8s/oneapi:latest
ports:
- containerPort: 5000
livenessProbe:
httpGet:
path: /test
port: 5000
- name: twoapi
image: registry.cn-beijing.aliyuncs.com/chester-k8s/twoapi:latest
ports:
- containerPort: 5001
livenessProbe:
httpGet:
path: /test/calloneapi
port: 5001
代码语言:javascript复制
通过以下命令验证
kubectl delete -f deployment.yaml
kubectl apply -f deployment.yaml
kubectl describe pod -n chesterns
去掉污点
代码语言:javascript复制kubectl taint node [node] key:[effect]-