kubernetes深入理解Pod对象之调度篇

目录

一、Pod调度流程

二、 容器资源限制

2.1 内存和CPU限制

三、 NodeSelector

四、NodeAffinity

4.1 基本概念

4.2 Pod 示例

4.2.1使用首选的节点亲和性调度 Pod

4.2.2依据强制的节点亲和性调度 Pod 

五、Taints与Tolerations

5.1 基本概念

5.2Taints与Tolerations

六、NodeName

6.1 基本概念

6.2 NodeName 字段的 Pod 规约示例


一、Pod调度流程


Kubernetes 基于 list-watch 机制的控制器架构,实现组件间交互的解耦。

其他组件监控自己负责的资源,当这些资源发生变化时,kube- apiserver 会通知这些组件,这个过程类似于发布与订阅。

调度大致流程

  1. 用户使用 create yaml 创建 pod,请求给 apiServer,apiserver 将 yaml 中的属性信息(metadata) 写入 etcd
  2. apiServer 触发 watch 机制准备创建 pod,信息转发给调度器,调度器使用调度算法选择node,调度器将node信息给 apiServer,apiServer 将绑定的 node 信息写入etcd
  3. apiServer 又通过 watch 机制,调用 kubelet,指定 pod 信息,触发 docker run 命令创建容器
  4. 创建完成之后反馈给kubelet, kubelet又将pod的状态信息给apiserver,
  5. apiserver又将pod的状态信息写入etcd。
  6. 其中kubectl get pods命令调用的时etcd_的信息

二、 容器资源限制


2.1 内存和CPU限制

容器使用的最大资源限制:

• resources.limits.cpu

• resources.limits.memory

容器使用的最小资源需求,作为容器调度时资源分配的依据:

• resources.requests.cpu

• resources.requests.memory

官方示例:为容器和 Pod 分配内存资源 | Kubernetes

示例

apiVersion: v1
kind: Pod
metadata:
  name: pod-resource 
spec:
  containers:
  - name: web
    image: nginx
    resources:
      requests:   # 容器最小资源配额
        memory: "64Mi"
        cpu: "250m"
      limits:     # 容器最大资源上限
        memory: "128Mi"
        cpu: "500m"

使用 describe 查看 pod 的描述信息


三、 NodeSelector


nodeSelector:用于将Pod调度到匹配Label的Node上,如果没有匹配的标签会调度失败。作用:

• 约束Pod到特定的节点运行

• 完全匹配节点标签应用场景:

• 专用节点:根据业务线将Node分组管理

• 配备特殊硬件:部分Node配有SSD硬盘、GPU

示例操作

### 给node2 打上SSD 的标签
kubectl label node k8s-node2 disktype=ssd

## 查看node 的标签信息
kubectl get node k8s-node2 --show-labels

 创建一个pod ,将pod调度到 带有 SSD标签的k8s-node2节点上

apiVersion: v1
kind: Pod
metadata:
  name: pod-node-selector
spec:
  nodeSelector:
    disktype: 'ssd'
  containers:
  - name: web
    image: nginx

 查看是否调度到 k8s-node2 节点上


四、NodeAffinity


4.1 基本概念

用节点亲和性把 Pods 分配到工作节点。

nodeAffinity:节点亲和性,与nodeSelector作用一样,但相比更灵活,满足更多条件,诸如:

• 匹配有更多的逻辑组合,不只是字符串的完全相等

• 调度分为软策略和硬策略,而不是硬性要求

• 硬(required):必须满足

• 软(preferred):尝试满足,但不保证

操作符:In、NotIn、Exists、DoesNotExist、Gt、Lt

官方示例:

用节点亲和性把 Pods 分配到节点 | Kubernetes

4.2 Pod 示例

4.2.1使用首选的节点亲和性调度 Pod

下面示例软策略匹配 节点标签 gpu=nvidia

apiVersion: v1
kind: Pod
metadata:
  name: pod-node-affinity
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: gpu
            operator: In
            values:
            - nvidia
  containers:
  - name: web
    image: nginx

 软性策略调度到 k8s-master1 节点上,master1 并没有该 gpu=nvidia 标签 ,软性策略调度成功。

4.2.2依据强制的节点亲和性调度 Pod 

apiVersion: v1
kind: Pod
metadata:
  name: pod-node-affinity2
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: gpu
            operator: In
            values:
            - nvidia
  containers:
  - name: web
    image: nginx

如上改为硬性策略后 ,pod 必须调度到 有标签gpu=nvidia 的节点上,而k8s测试集群中没有这样的节点 

如下 我们可以看到 pod-node-affinity2 处于Pending 状态

使用describe 查看pod 状态,没有匹配到 node

Warning FailedScheduling 36s default-scheduler 0/4 nodes are available: 4 node(s) didn't match Pod's node affinity/selector. preemption: 0/4 nodes are available: 4 Preemption is not helpful for scheduling.


五、Taints与Tolerations


5.1 基本概念

节点亲和性Pod 的一种属性,它使 Pod 被吸引到一类特定的节点 (这可能出于一种偏好,也可能是硬性要求)。 污点(Taint)则相反——它使节点能够排斥一类特定的 Pod。

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

污点和容忍度(Toleration)相互配合,可以用来避免 Pod 被分配到不合适的节点上。 每个节点上都可以应用一个或多个污点,这表示对于那些不能容忍这些污点的 Pod,是不会被该节点接受的。

Taints:避免Pod调度到特定Node上

Tolerations:允许Pod调度到持有Taints的Node上应用场景:

• 专用节点:根据业务线将Node分组管理,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配

• 配备特殊硬件:部分Node配有SSD硬盘、GPU,希望在默认情况下不调度该节点,只有配置了污点容忍才允许分配

• 基于Taint的驱逐

5.2Taints与Tolerations

污点和容忍度 | Kubernetes

查看节点标签

 pod3.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod3
spec:
  containers:
  - name: web
    image: nginx

给 k8s-master1 和 k8s-master2 打上 污点, 键名是 gpu ,键值是 nvidia ,效果是 NoSchedule。表示只有拥有和这个污点相匹配的容忍度的 pod 才能被分配到 两个 master节点上。 

kubectl taint node k8s-master1 gpu=nvidia:NoSchedule
kubectl taint node k8s-master2 gpu=nvidia:NoSchedule

 给两个 node 节点也打上污点

## k8s-node1  打上 GPU 污点
kubectl taint node k8s-node1 gpu=nvidia:NoSchedule
## k8s-node2  打上 ssd 污点
kubectl taint node k8s-node2 ssd=ssd:NoSchedule

## 起一个 Pod
apiVersion: v1
kind: Pod
metadata:
  name: pod4
spec:
  containers:
  - name: web
    image: nginx

可以看到 pod4 处于 Pending 状态,没有配置污点容忍 pod无法调度成功

Warning FailedScheduling 24s default-scheduler 0/4 nodes are available: 1 node(s) had untolerated taint {ssd: ssd}, 3 node(s) had untolerated taint {gpu: nvidia}. preemption: 0/4 nodes are available: 4 Preemption is not helpful for scheduling.

我们给 k8s-node2 加上 ssd 污点容忍,让 pod5 在 k8s-node2 上调度

apiVersion: v1
kind: Pod
metadata:
  name: pod5
spec:
  tolerations:
  - key: "ssd"
    operator: "Equal"
    value: "ssd"
    effect: "NoSchedule"
  containers:
  - name: web
    image: nginx

 由于其他 node 有污点,node2 有 ssd 污点容忍,在 pod5 在node2上成功运行。

污点移除

kubectl taint node k8s-master2 gpu=nvidia:NoSchedule-
kubectl taint node k8s-master1 gpu=nvidia:NoSchedule-
kubectl taint node k8s-node1 gpu=nvidia:NoSchedule-
kubectl taint node k8s-node2 ssd=ssd:NoSchedule-

六、NodeName


6.1 基本概念

nodeName 是比亲和性或者 nodeSelector 更为直接的形式。nodeName 是 Pod 规约中的一个字段。如果 nodeName 字段不为空,调度器会忽略该 Pod, 而指定节点上的 kubelet 会尝试将 Pod 放到该节点上。 使用 nodeName 规则的优先级会高于使用 nodeSelector 或亲和性与非亲和性的规则。

使用 nodeName 来选择节点的方式有一些局限性:

  • 如果所指代的节点不存在,则 Pod 无法运行,而且在某些情况下可能会被自动删除。
  • 如果所指代的节点无法提供用来运行 Pod 所需的资源,Pod 会失败, 而其失败原因中会给出是否因为内存或 CPU 不足而造成无法运行。
  • 在云环境中的节点名称并不总是可预测的,也不总是稳定的。

6.2 NodeName 字段的 Pod 规约示例

apiVersion: v1
kind: Pod
metadata:
  name: pod6
spec:
  containers:
  - name: nginx
    image: nginx
  nodeName: k8s-node2

k8s-master1 和 k8s-master2 ,还有 k8s-node1 和k8s-node2 都打上了污点,nodeName的优先级更高,所以pod 成功调度。

 

猜你喜欢

转载自blog.csdn.net/qq_35995514/article/details/128054680