k8s-Pod调度策略(入门攻略)

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: k8s-Pod调度策略(入门攻略)

首先在k8s中,k8s会根据每个work节点的配置,负载差异,自动生成优选函数,根据优选函数,当master节点分配下来任务时,将pod分配带最适合运行的node节点上。


之外我们技术人员还有以下三种方式去影响我们的pod调度,


node节点调度器

亲和性调度

污点容忍度

区别和实例操作


一 .node节点调度


是最直接的调度方式,简单粗暴,所以常用在简单的集群架构中,负载的资源分类和编制不适合这种方式,

解释:大概意思就是给我们的work节点绑定唯一便签,然后在pod的yml文件中去设置node便签匹配器绑定节点,这样就能实现影响k8s优选参数的选择,让当前的pod启动在设置的node节点上。


1、首先通过 kubectl 给 node 打上标签

格式:
kubectl label nodes <node-name> <label-key>=<label-value>
[root@k8s-master ~]# kubectl label nodes k8s-node01 zone=sh
[root@k8s-master ~]# kubectl get nodes --show-labels


2、通过 nodeSelector 调度 pod 到 node

Pod的定义中通过nodeSelector指定label标签,pod将会只调度到具有该标签的node之上

[root@k8s-master ~]# vim pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd


这个例子中pod只会调度到具有 disktype=ssd 的 node 上面.

验证 节点调度

[root@k8s-master ~]# kubectl apply -f pod-demo.yaml 
[root@k8s-master ~]# kubectl get pods -o wide
[root@k8s-master ~]# kubectl describe pod  pod-demo   ##查看事件


二 .亲和性调度


较复杂,应用在复杂的多节点归类,资源分类管理的中大型集群中,有硬亲和,软亲和,亲和性和反亲和,两两为一组,反义词


硬亲和:匹配节点上的其中一个或多个标签(必须存在一个)

软亲和:匹配节点上的其中一个或多个标签(有则选择这个node,没有就参考优选函数)


1.硬亲和

[root@k8s-master ~]# vim pod-nodeaffinity-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-node-affinity-demo
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: zone
            operator: In
            values:
            - foo
            - bar
[root@k8s-master ~]# kubectl apply -f pod-nodeaffinity-demo.yaml
[root@k8s-master ~]# kubectl describe pod pod-node-affinity-demo
# 运行结果:
Warning  FailedScheduling  2s (x8 over 20s)  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.
# 给其中一个node打上foo的标签
[root@k8s-master ~]# kubectl label node k8s-node01 zone=foo
# 正常启动
[root@k8s-master ~]# kubectl get pods


2.软亲和

[root@k8s-master ~]# vim pod-nodeaffinity-demo-2.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-node-affinity-demo-2
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - preference:
          matchExpressions:
          - key: zone
            operator: In
            values:
            - foo
            - bar
        weight: 60
      - preference:
          matchExpressions:
          - key: zone1
            operator: In
            values:
            - foo1
            - bar1
        weight: 10 
[root@k8s-master ~]# kubectl apply -f pod-nodeaffinity-demo-2.yaml


3.同时存在时(硬,软亲和)

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: zone
            operator: In
            values:
            - dev
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
  containers:
  - name: with-node-affinity
    image: nginx


结果:同时存在的话先判断上下顺序,从上到下选择范围,列如硬亲和在上,软亲和在下,就会先选必须匹配到一个标签的多个node上,然后软亲和继续从这些节点去选择,反之亦然。


亲和性:首先是先有一个pod,然后根据上一个pod(辨识标签)在哪里节点启动,就会跟随到这个节点上去启动。

反亲和:查看前面的那个pod的启动节点,必须和它启动到不是一个节点上


1.亲和性

[root@k8s-master ~]# vim pod-required-affinity-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
  labels:
    app: db
    tier: db
spec:
  containers:
  - name: busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["sh","-c","sleep 3600"]
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - {key: app, operator: In, values: ["myapp"]}
        topologyKey: kubernetes.io/hostname
[root@k8s-master ~]# kubectl apply -f pod-required-affinity-demo.yaml 
[root@k8s-master ~]# kubectl get pods -o wide
# 运行结果,两个 pod 在同一 node 节点上
NAME         READY   STATUS    RESTARTS   AGE   IP           NODE
pod-first    1/1     Running   0          11s   10.244.1.6   k8s-node01
pod-second   1/1     Running   0          11s   10.244.1.5   k8s-node01
[root@k8s-master ~]# kubectl delete -f pod-required-affinity-demo.yaml


2.反亲和性

[root@k8s-master ~]# vim pod-required-anti-affinity-demo.yaml 
# 内容为
apiVersion: v1
kind: Pod
metadata:
  name: pod-first
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-second
  labels:
    app: backend
    tier: db
spec:
  containers:
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command: ["sh","-c","sleep 3600"]
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - {key: app, operator: In, values: ["myapp"]}
        topologyKey: kubernetes.io/hostname
[root@k8s-master ~]# kubectl apply -f pod-required-anti-affinity-demo.yaml 
[root@k8s-master ~]# kubectl get pods -o wide
# 运行结果,两个 pod 不在同一个 node
NAME         READY   STATUS    RESTARTS   AGE   IP           NODE
pod-first    1/1     Running   0          5s    10.244.2.4   k8s-node02
pod-second   1/1     Running   0          5s    10.244.1.7   k8s-node01
[root@k8s-master ~]# kubectl delete -f pod-required-anti-affinity-demo.yaml


3.同时存在时(亲和性,反亲和性)

这里就不举例的,直接说一下结果

首先肯定是两个条件的匹配条件不能一样

这时候就会满足两个条件去选择条件,比如,当亲和性在上,反亲和在下,pod会先选择匹配到条件的一些节点上去选择,然后在从中匹配到反亲和的条件,如果有那就必须踢出它,选择其他符合条件的节点。


三.污点和容忍度


与之前两个调度方式不同,污点是首先给节点绑定污点,作用是保护节点,不再让这个节点会scheduler(资源调度)选为pod启动环境。

我们集群中master就是设置污点,所以你启动任何pod都不会在master上工作,保证master的工作效率。


相关参数

介绍几个用到的参数


operator 可以定义为

Equal:表示key是否等于value,默认

Exists:表示key是否存在,此时无需定义value

tain 的 effect 定义对 Pod 排斥效果

NoSchedule:仅影响调度过程,对现存的Pod对象不产生影响;

NoExecute:既影响调度过程,也影响现有的Pod对象;不容忍的Pod对象将被驱逐

PreferNoSchedule: 表示尽量不调度

查看节点的污点

kubectl describe node k8s-node01 | grep Taints

设置污点

kubectl taint node k8s-node01 node-type=production:NoSchedule

创建容器测试

[root@k8s-master ~]# vim deploy-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
[root@k8s-master ~]# kubectl apply -f deploy-demo.yaml 
[root@k8s-master ~]# kubectl get pods -o wide
# 运行结果:
NAME                            READY   STATUS    RESTARTS   AGE   IP           NODE
myapp-deploy-69b47bc96d-cwt79   1/1     Running   0          5s    10.244.2.6   k8s-node02
myapp-deploy-69b47bc96d-qqrwq   1/1     Running   0          5s    10.244.2.5   k8s-node02


所以只能启动到没有污点的node2节点上


设置一个能容忍node1污点的pod测试

[root@k8s-master ~]# vim deploy-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: defaultm
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        ports:
        - name: http
          containerPort: 80
      tolerations:
      - key: "node-type"
        operator: "Equal"
        value: "production"
        effect: "NoSchedule"
[root@k8s-master ~]# kubectl apply -f deploy-demo.yaml


测试

[root@k8s-master ~]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP            NODE
myapp-deploy-65cc47f858-tmpnz   1/1     Running   0          10s   10.244.1.10   k8s-node01
myapp-deploy-65cc47f858-xnklh   1/1     Running   0          13s   10.244.1.9    k8s-node01


其他参数的作用

定义Toleration,是否存在 node-type 这个key 且 effect 值为 NoSchedule

[root@k8s-master ~]# vim deploy-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        ports:
        - name: http
          containerPort: 80
      tolerations:
      - key: "node-type"
        operator: "Exists"
        value: ""
        effect: "NoSchedule"
[root@k8s-master ~]# kubectl apply -f deploy-demo.yaml
[root@k8s-master ~]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP            NODE
myapp-deploy-559f559bcc-6jfqq   1/1     Running   0          10s   10.244.1.11   k8s-node01
myapp-deploy-559f559bcc-rlwp2   1/1     Running   0          9s    10.244.1.12   k8s-node01


定义Toleration,是否存在 node-type 这个key 且 effect 值为空,则包含所有的值

[root@k8s-master ~]# vim deploy-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        ports:
        - name: http
          containerPort: 80
      tolerations:
      - key: "node-type"
        operator: "Exists"
        value: ""
        effect: ""
[root@k8s-master ~]# kubectl apply -f deploy-demo.yaml
# 两个 pod 均衡调度到两个节点
kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP            NODE
myapp-deploy-5d9c6985f5-hn4k2   1/1     Running   0          2m    10.244.1.13   k8s-node01
myapp-deploy-5d9c6985f5-lkf9q   1/1     Running   0          2m    10.244.2.7    k8s-node02
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
9天前
|
Kubernetes 调度 容器
Kubernetes高级调度方式
文章介绍了Kubernetes的高级调度方式,包括调度器的工作机制、节点倾向性(Node Affinity)和Pod倾向性(Affinity)。
35 9
Kubernetes高级调度方式
|
1天前
|
机器学习/深度学习 Kubernetes 调度
Kubernetes与GPU的调度:前世今生
本文详细探讨了Kubernetes与GPU的结合使用,阐述了两者在现代高性能计算环境中的重要性。Kubernetes作为容器编排的佼佼者,简化了分布式系统中应用程序的部署与管理;GPU则凭借其强大的并行计算能力,在加速大规模数据处理和深度学习任务中发挥关键作用。文章深入分析了Kubernetes如何支持GPU资源的检测与分配,并介绍了热门工具如NVIDIA GPU Device Plugin和Kubeflow的应用。
|
5天前
|
Kubernetes 监控 Cloud Native
云原生入门:Kubernetes 集群部署与管理
【8月更文挑战第38天】在数字化浪潮中,云原生技术如同翱翔的雄鹰,引领着企业飞向灵活高效的未来。本文将带你一探究竟,从Kubernetes的基础概念到实际操作,深入浅出地介绍如何在云端构建和管理你的容器化应用。我们将一步步搭建起一个小型的Kubernetes集群,并通过代码示例和图解,让你轻松掌握云原生世界的钥匙。让我们一起开启这趟技术之旅,探索云原生的秘密花园,找到那把打开创新之门的金钥匙。
|
12天前
|
存储 Kubernetes Cloud Native
探索Python编程的奥秘云原生时代的容器编排:Kubernetes入门与实践
【8月更文挑战第30天】本文以浅显易懂的方式,探讨了Python编程的核心概念和技巧。从基础语法到高级特性,再到实际应用案例,逐步引导读者深入理解Python编程的精髓。通过本文的学习,读者将能够掌握Python编程的基本技能,并激发进一步探索的兴趣。
27 13
|
11天前
|
Kubernetes Cloud Native Docker
云原生入门:从容器到Kubernetes的旅程
【8月更文挑战第31天】云原生技术正改变着应用的开发、部署和运维方式。本文将带你走进云原生的世界,从容器的基础开始,探索Docker和Kubernetes如何助力现代软件开发与运维。你将学会如何使用Docker创建和管理容器,以及如何通过Kubernetes进行集群管理,实现服务的自动化部署、扩展和管理。准备好让你的应用在云端自由翱翔了吗?让我们启航!
|
9天前
|
Kubernetes 安全 API
Kubernetes系统安全-授权策略(authorization policy)
文章主要介绍了Kubernetes系统中的授权策略,包括授权模块的概述、RBAC授权模块的详细说明以及如何创建和管理角色(Role)和集群角色(ClusterRole)。
22 0
Kubernetes系统安全-授权策略(authorization policy)
|
12天前
|
运维 Kubernetes Cloud Native
云原生之旅:Kubernetes 集群的搭建与实践Python 编程入门:从零基础到编写实用脚本
【8月更文挑战第30天】在数字化转型的大潮中,云原生技术以其弹性、可扩展性及高效运维能力成为企业IT架构升级的关键。本文将通过实际操作演示如何在本地环境搭建一个简易的Kubernetes集群,带你领略云原生的魅力所在。从集群规划到服务部署,每一步都是对云原生理念的深刻理解和应用。让我们共同探索,如何通过Kubernetes集群的搭建和运维,提升业务灵活性和创新能力。
|
11天前
|
Kubernetes Cloud Native 应用服务中间件
云原生入门:Kubernetes的简易部署与管理
【8月更文挑战第31天】在云计算的浪潮中,云原生技术如同星辰般熠熠生辉。它以容器、服务网格、微服务等为基石,构建起现代化的软件架构。本文将带你一探究竟,通过Kubernetes这个强大的平台,学习如何部署和管理你的应用。我们将手把手教你搭建一个简单的Kubernetes集群,并运行一个示例应用。准备好了吗?让我们启航,探索云原生的世界!
|
11天前
|
Kubernetes 监控 Cloud Native
云原生入门:Kubernetes 集群部署与管理
【8月更文挑战第31天】 在数字化浪潮中,云原生技术如同翱翔的雄鹰,引领着企业飞向灵活高效的未来。本文将带你一探究竟,从Kubernetes的基础概念到实际操作,深入浅出地介绍如何在云端构建和管理你的容器化应用。我们将一步步搭建起一个小型的Kubernetes集群,并通过代码示例和图解,让你轻松掌握云原生世界的钥匙。让我们一起开启这趟技术之旅,探索云原生的秘密花园,找到那把打开创新之门的金钥匙。
|
11天前
|
Kubernetes Cloud Native Linux
云原生入门:Kubernetes的简易部署与应用
【8月更文挑战第31天】在云原生的世界里,Kubernetes(K8s)是一颗璀璨的星。本文将带你走进K8s的世界,从安装到简单应用,轻松驾驭这个强大的容器编排工具。让我们一起探索云原生的奥秘,解锁新技能!