关于云计算:K8s污点容忍度横向主节点

2次阅读

共计 3539 个字符,预计需要花费 9 分钟才能阅读完成。

污点 节点亲和性 容忍度

污点是 K8s 高级调度的个性,用于限度哪些 Pod 能够被调度到某一个节点。在一般节点横向时咱们能够应用污点容忍度创立歹意 pod 来对主节点进行横向管制。

1、kube-scheduler 调度

kube-schedulerKubernetes 集群的默认调度器,并且是集群管制面(master) 的一部分。对每一个新创建的 Pod 或者是未被调度的 Pod,kube-scheduler会抉择一个最优的 Node 去运行这个 Pod。

然而,Pod内的每一个容器对资源都有不同的需要,而且 Pod 自身也有不同的资源需要。因而,Pod 在被调度到 Node 上之前,依据这些特定的资源调度需要,须要对集群中的 Node 进行一次过滤。

如下为在创立 pod 的流程中,调度器的作用:

当创立 pod 时候,会首先把创立的命令申请提交给 apiserver,通过一系列认证受权,apiserver 把 pod 数据存储到 etcd, 创立 deployment 资源并初始化。而后再是 scheduler 通过进行 list-watch 机制进行监测,通过 调度算法 把 pod 调度到某个 node 节点上,最初信息更新到 etcd,再前面就是 kubelet 承受信息到创立容器。

2、哪些因素影响调度

1.pod 资源限度

以后调度器抉择适当的节点时,调度程序会查看每个节点是否有足够的资源满足 Pod 调度,比方查看 CPU 和内存限度是否满足:

通过资源限度调度程序可确保因为过多 Pod 竞争耗费节点所有可用资源,从而导致节点资源耗尽引起其余零碎异样。

2. 节点选择器 nodeSelector

在创立 pod 的时候,节点选择器能够束缚 pod 在特定节点上运行。

nodeSelector 也是节点抉择束缚的最简略举荐模式,nodeSelector 字段增加到 Pod 的规约中设置心愿指标节点所具备的节点标签。K8s 只会将 Pod 调度到领有你所指定的每个标签的节点上。

例子,比方多个节点须要调度时候,通过给 1,2 节点打上标签,创立 pod 时候应用节点选择器,那么 pod 会被依照节点选择器心愿的指标在相应节点调度。

为节点打上标签:

kubectl label node nodename env_role=env

查看节点的标签:

kubectl get nodes nodename --show-labels

3. 节点亲和性 nodeAffinity

节点亲和性概念上相似于 nodeSelector,它使能够依据节点上的标签来束缚 Pod 能够调度到哪些节点上,这种办法比下面的 nodeSelector 更加灵便,它能够进行一些简略的逻辑组合了,不只是简略的相等匹配。

节点亲和性和节点选择器相比性能更弱小,比方还是方才的图,如果我应用节点选择器 env_role:dev1 的话是找不到相应的节点的,就没有方法调度,会始终是一个期待的状态:

但我如果应用节点亲和性,就算以后没有这个节点,我还是能够依据调度调度策略进行调度,不只是简略的相等匹配。

调度策略

调度能够分成软策略 ( 软亲和性 ) 和硬策略 ( 硬亲和性 ) 两种形式:

  • 软亲和性 (preferredDuringSchedulingIgnoredDuringExecution) 就是如果你没有满足调度要求的节点的话,POD 就会疏忽这条规定,持续实现调度过程,说白了就是 满足条件最好了,没有的话也无所谓了 的策略;
  • 硬亲和性 (requiredDuringSchedulingIgnoredDuringExecution) 示意以后的条件必须满足,如果没有满足条件的节点的话,就一直重试直到满足条件为止,简略说就是 你必须满足我的要求,不然我就不干 的策略。

如图能够看到软亲和性和硬亲和性的字段其实差不多,软亲和性多了一个 weight 字段,表权重:

亲和性操作符

如上亲和性还有一个字段是 operator 表匹配的逻辑操作符,能够应用 descirbe 命令查看具体的调度状况是否满足咱们的要求,K8s提供的操作符有上面的几种:

  • In:label 的值在某个列表中
  • NotIn:label 的值不在某个列表中
  • Gt:label 的值大于某个值
  • Lt:label 的值小于某个值
  • Exists:某个 label 存在
  • DoesNotExist:某个 label 不存在

如果 nodeSelectorTerms 上面有多个选项的话,满足任何一个条件就能够了;如果 matchExpressions 有多个选项的话,则必须同时满足这些条件能力失常调度 POD。

污点(Taints)与容忍(tolerations)

容忍度(Toleration)是利用于 Pod 上的,容许(但并不要求)Pod 调度到带有与之匹配的污点的节点上。污点说白了就是不做一般的调度。

对于节点亲和性无论是软亲和性和硬亲和性,都是调度 POD 到预期节点上,而污点 (Taints) 恰好与之相同,如果一个节点标记为 Taints 除非 POD 也被标识为能够容忍污点节点,否则该 Taints 节点不会被调度 pod

污点(Taints)

查看污点状况:

kubectl describe node nodename | grep Taint

能够看到,默认污点也只有 master 有。

污点里的值有三种:

  1. NoSchedule:POD 不会被调度到标记为 taints 节点。
  2. PreferNoSchedule:NoSchedule 的软策略版本。
  3. NoExecute:该选项意味着一旦 Taint 失效,如该节点内正在运行的 POD 没有对应 Tolerate 设置,会间接被逐出。

NoSchedule就是字面意思,不会被调度,PreferNoSchedule说白了是尽量不被调度,NoExecute是不会调度并且还会驱赶 node 已有的pod

创立一个 pod:

如果不加污点,能够看到这个 pod 会随机调度到节点 1 或者节点 2:

这时候把 pod 删除了,从新创立 pod 并且给 node 加上污点:

给节点打污点:

kubectl taint node nodename key=value:NoSchedule

从新创立 pod 并且 deployment 多个:

能够发现全副被调度在节点 2 上,节点 1 的污点 NoSchedule 起了作用。

删除污点:

污点容忍度(tolerations)

容忍度 tolerations 是定义在 Pod对象上的键值型属性数据,用于配置其可容忍的节点污点,而且调度器仅能将 Pod 对象调度至其可能容忍该节点污点的节点之上。

污点定义在节点的 node Spec 中,而容忍度则定义在 PodpodSpec中,它们都是键值型数据。

Pod 对象上定义容忍度时,它反对两种操作符:一种是等值比拟 Equal, 示意容忍度与污点必须在keyvalueeffect三者之上齐全匹配;另一种是存在性判断 Exists,示意二者的keyeffect必须齐全匹配,而容忍度中的 value 字段要应用空值。

这里的 key 和 value 对应的值都是你本人设置的 key 和 value:

说白了就是:

  • 如果 operatorExists(此时容忍度不能指定 value)
  • 如果 operatorEqual,则它们的 value 应该相等

而污点容忍的作用举个例子,如果像下面污点一样设置了 NoSchedule 污点的节点,那么创立 pod 的时候是必不被调度到的,然而如果我应用污点容忍,那这个节点能够在设置 NoSchedule 污点的状况下可能又被调度,相似于亲和性那种作用。

3、污点横向浸透

污点和污点容忍度的作用也就是获取 主节点的 shell,因为像常见或者节点 shell 的流程是创立 pod–》调配到失常 node—》通过惯例挂载目录拿到节点的 shell,而默认主节点是不被调度的,所以只有应用污点容忍度,创立一个可能被调度到 master 节点的 pod,而后通过挂载之类的手法来拿到主节点的 shell。

通过创立一个具备 node-role.kubernetes.io/master:NoSchedule 的容忍度让 Pod 被 Kubernetes Master 所调度。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:
  - key: "node-role.kubernetes.io/master"
    operator: "Exists"
    effect: "NoSchedule"

如上的 Pod 中将宿主机的根目录挂载到容器中(volumes 与 volumeMounts)即可逃逸至 Kubernetes Master 中接管集群。

查看节点,以后是在一般节点:

屡次创立能够发现在 master 节点上了:

能够通过挂载操作 master 节点母机 shell:

正文完
 0