zoukankan      html  css  js  c++  java
  • Pod系列 (二) Pod调度策略

    一、Pod创建流程

    上述过程分为在master节点和node节点上:

    • master节点

    create pod-->API Server-->Etcd,客户请求创建Pod,API Server进行创建,并且将创建的Pod信息写入到etcd中。

    Scheduler-->API Server-->Etcd,Scheduler监听API Server,一旦监听到有新的Pod被创建,那么就负责调度,从Etcd中获取Pod信息,并且将其调度到合适的node节点中。

    • node节点

    Kubelet-->API Server-->Etcd-->docker run,Kubelet监听Api Server,负责将分配到该节点的Pod从Etcd中取出并且分配到该节点上,然后创建容器,完成Pod创建。

    二、影响Pod调度的因素

    上述中Scheduler负责调度Pod到合适的节点,那么它是如何具体调度的呢?主要有三方面控制:

    • 资源限制和节点选择器
    • 节点亲和性
    • 污点和污点容忍

    (一)资源限制和节点选择器

    •  资源限制
    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod 
    spec:
        containers:
        - name: db
          image: mysql
          env:
          - name: MYSQL_ROOT_PASSWORD
            value: "password"
          resources:
            requests:
              memory: "64Mi"
              cpu: "250m"
            limits:
              memory: "128Mi"
              cpu: "500m"

    requests和limits进行资源限制,调度到符合该资源要求的节点上。

    • 节点选择器

    如果将Pod调度到测试环境进行部署,那么只需要将测试环境的节点打上一个标签,然后在写Pod的yaml文档时指定即可,所以首先应该对相应的节点打上标签。

    [root@k8smaster ~]# kubectl label node k8snode1 env_role=dev
    node/k8snode1 labeled
    [root@k8smaster ~]# kubectl get nodes k8snode1 --show-labels 
    NAME       STATUS   ROLES    AGE   VERSION   LABELS
    k8snode1   Ready    <none>   60d   v1.18.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,env_role=dev,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8snode1,kubernetes.io/os=linux

    此时可以进行yaml文档编写:

    apiVersion: v1
    kind: Pod
    metadata:
      name: selector-pod 
    spec:
      nodeSelector: 
        env_role: dev
      containers:
      - name: nginx
        image: nginx: 1.15

    因为给node1节点打上dev标签,所以该Pod会被调度到node1节点上。

    (二)节点亲和性

     节点亲和性nodeAffinity和节点选择器nodeSelector基本一样,根据节点上的标签来决定Pod调度到那些节点上,节点亲和性分为:

    • 硬亲和性 约束条件必需满足
    • 软亲和性 尝试满足
    apiVersion: v1
    kind: Pod
    metadata:
      name: with-node-affinity
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:  #硬亲和性
            nodeSelectorTerms:
            - matchExpressions:
              - key: env_role
                operator: In
                values:
                - dev
                - test
          preferredDuringSchedulingIgnoredDuringExecution: #软亲和性
          - weight: 1
            preference:
              matchExpressions:
              - key: group
                operator: In
                values:
                - prod     
      containers:
      - name: web
        image: nginx
        imagePullPolicy: IfNotPresent

    其中operator为操作符,节点亲和性支持的操作符有In、NotIn、Exists、DoesNotExist、Gt、Lt.

    (三)污点和污点容忍

    节点亲和性时Pod的一种属性,它使Pod被吸引到一类特定的节点上。污点(Taint)则相反,是节点的属性,它使节点能够排斥一类特定的Pod。

    容忍度是应用于Pod上的,允许(但并不要求)Pod调度到有与之匹配的污点的节点上。

    污点和容忍度(Toleration)相互配合,可以用来避免 Pod 被分配到不合适的节点上。

    其应用场景有:

    • 专用节点
    • 配备了特殊硬件的节点
    • 基于污点的驱逐

    1、查看节点污点的情况

    [root@k8smaster ~]# kubectl describe node k8smaster | grep Taint
    Taints:             node-role.kubernetes.io/master:NoSchedule

    从上面看出有一个NoSchedule的值,也就是说污点有三个值可供选择:

    • NoSchedule 一定不被调度
    • PreferNoSchedule 尽量不被调度
    • NoExecute 不会调度,并且驱逐node中已有Pod

    2、为节点添加污点

    # 格式
    kubectl taint node [node] key=value:污点的三个值
    
    # 添加污点
    [root@k8smaster ~]# kubectl taint node k8snode1 env_role=yes:NoSchedule
    node/k8snode1 tainted

    假如此时我创建Pod,那么因为node1节点添加了污点,其值是NoSchedule,一定不会被调用。

    [root@k8smaster ~]# kubectl create deployment web --image=nginx
    deployment.apps/web created
    [root@k8smaster ~]# kubectl get pods -o wide
    NAME                   READY   STATUS              RESTARTS   AGE   IP       NODE       NOMINATED NODE   READINESS GATES
    web-5dcb957ccc-89fl2   0/1     ContainerCreating   0          5s    <none>   k8snode2   <none>           <none>
    [root@k8smaster ~]# kubectl scale deployment web --replicas=5
    deployment.apps/web scaled
    [root@k8smaster ~]# kubectl get pods -o wide
    NAME                   READY   STATUS              RESTARTS   AGE   IP       NODE       NOMINATED NODE   READINESS GATES
    web-5dcb957ccc-2rjfz   0/1     ContainerCreating   0          3s    <none>   k8snode2   <none>           <none>
    web-5dcb957ccc-89fl2   0/1     ErrImagePull        0          56s   <none>   k8snode2   <none>           <none>
    web-5dcb957ccc-fcq2f   0/1     ContainerCreating   0          3s    <none>   k8snode2   <none>           <none>
    web-5dcb957ccc-gnw4n   0/1     ContainerCreating   0          3s    <none>   k8snode2   <none>           <none>
    web-5dcb957ccc-jb7sd   0/1     ContainerCreating   0          3s    <none>   k8snode2   <none>           <none>

    可以看到都在node2节点上。

    3、删除污点

    去除node1节点上的污点:

    [root@k8smaster ~]# kubectl taint node k8snode1 env_role:NoSchedule-
    node/k8snode1 untainted

    4、污点容忍度

    如果设置的某节点污点值是NoSchedule,那么如果满足污点容忍度也是可以被调度到的,如:

    tolerations:
    - key: "key1"
      operator: "Equal"
      value: "value1"
      effect: "NoSchedule"

    可以在PodSpec中定义Pod的容忍度,如果Pod满足上述的容忍度就能够被分配到node1节点上。

    作者:iveBoy
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    网络抓包工具使用
    JAVA 原子操作类
    guava collection/cache初探
    MiniGUI
    Cookie
    System V IPC
    SQLite交叉编译
    NCurses交叉编译
    双向循环链表
    VMware安装Windows Server 2008
  • 原文地址:https://www.cnblogs.com/shenjianping/p/14894729.html
Copyright © 2011-2022 走看看