1. 什么是Pod调度,它由谁负责?

在 Kubernetes 中,Pod 调度是指将一个新创建的 Pod 分配到集群中某个合适的节点(Node)上运行的过程。这个过程由 Kubernetes Scheduler(调度器) 负责。

什么是 Pod 调度?

  • 当你提交一个 Pod 的创建请求后,Kubernetes 会先创建该 Pod 的对象并将其保存在 etcd 中。

  • 此时,Pod 处于 Pending 状态,表示尚未被分配到任何节点。

  • 调度器会观察所有处于 Pending 状态的 Pod,并根据一系列策略(如资源需求、亲和性、污点容忍等)选择一个最合适的节点来运行这个 Pod。

  • 一旦选定节点,调度器就会将 Pod 绑定(bind)到该节点,随后 kubelet 在该节点上启动 Pod 中的容器。

调度器的主要职责:

  1. 监听 API Server:通过 Watch 机制获取新创建的 Pod。

  2. 执行调度算法

    • 过滤(Filtering):筛选出满足 Pod 资源需求、节点选择器、污点容忍等条件的节点。

    • 打分(Scoring):对符合条件的节点进行打分,选出最优节点(例如负载最低、资源最充足等)。

  3. 绑定节点(Binding):将 Pod 分配给选中的节点,并更新 API Server 中的 Pod 对象信息。

影响调度的因素包括:

  • 资源请求(CPU、内存)

  • 污点与容忍度(Taints and Tolerations)

  • 节点选择器(Node Selector)

  • 亲和性与反亲和性(Affinity/Anti-Affinity)

  • 节点标签(Labels)


2. 什么是标签,有哪些作用,作用对象是谁

在 Kubernetes 中,标签(Label) 是一种用于对资源对象进行分类和选择的键值对(key-value)元数据。它不提供语义含义,而是为用户提供了一种灵活的方式来组织、筛选和管理集群中的资源。


什么是标签?

  • 标签是附加在 Kubernetes 对象(如 Pod、Service、Deployment 等)上的元数据。

  • 每个标签由一个 key 和一个可选的 value 组成。

  • 同一对象可以有多个标签。

  • 示例:

    metadata:
      labels:
        app: nginx
        env: production
        version: "1.21"

作用

描述

资源分组

将具有相同特性的资源归类,如按应用、环境、版本等划分。

资源筛选

使用 kubectl get pods -l app=nginx 等命令快速查找特定资源。

控制器匹配

Deployment、Service 等通过标签选择器(label selector)控制哪些 Pod 应该被管理。

服务发现与负载均衡

Service 使用标签选择器将请求路由到匹配的 Pod。

策略绑定

如网络策略(NetworkPolicy)、Pod 安全策略(PodSecurityPolicy)等可以通过标签来限定作用范围。

监控与日志收集

监控系统可以根据标签聚合指标或过滤日志。

标签的作用对象

Kubernetes 中几乎所有资源都可以使用标签,以下是一些常见的支持标签的对象:

资源类型

是否支持标签

Pod

支持

Service

支持

Deployment

支持

ReplicaSet

支持

StatefulSet

支持

DaemonSet

支持

Job / CronJob

支持

Node

支持(但需通过 nodeSelector 或污点容忍机制使用)

Namespace

可以打标签,常用于多租户隔离

PVC / PV

支持,可用于存储策略匹配

Ingress

支持,配合 Service 进行流量路由


3. 保障k8s集群有2个node节点,并且为两个node节点打上不同的标签

假设你要为两个节点分别打上如下标签:

  • worker-1 标签:zone=beijing

  • worker-2 标签:zone=shanghai

执行以下命令:

kubectl label nodes worker-1 zone=beijing --overwrite
kubectl label nodes worker-2 zone=shanghai --overwrite

使用以下命令查看节点标签信息:

kubectl get nodes -o wide --show-labels

或只显示特定标签:

bash

输出示例:

NAME       STATUS   ROLES    AGE   VERSION   ZONE
worker-1   Ready    <none>   2d    v1.27.3   beijing
worker-2   Ready    <none>   2d    v1.27.3   shanghai


4. 节点不可调度(cordon)和驱逐(drain)有什么区别?使用场景?

在 Kubernetes 中,节点不可调度(Cordon)驱逐节点上的 Pod(Drain) 是两种用于管理节点状态的操作,它们的目的和使用场景不同。


一、概念区别

操作

名称

含义

是否影响现有 Pod

是否允许新 Pod 调度

kubectl cordon <node>

节点不可调度

标记节点为不可调度状态,防止新 Pod 被调度到该节点上

不会删除或驱逐已有 Pod

禁止新 Pod 调度

kubectl drain <node>

节点驱逐

安全地驱逐节点上的所有可驱逐 Pod,并标记节点为不可调度

会尝试优雅终止并重新调度已有 Pod

驱逐后禁止新 Pod 调散

二、操作流程对比

1. cordon 操作流程

  • 将节点标记为 SchedulingDisabled

  • 已有 Pod 不受影响;

  • 新 Pod 不会被调度到该节点;

  • 可用于维护前的准备阶段。

kubectl cordon node-1

2. drain 操作流程

  • 先执行 cordon

  • 对节点上的所有可驱逐 Pod 执行 graceful termination

  • Pod 会被控制器(如 Deployment)重新调度到其他节点;

  • 适用于节点下线、升级、维护等需要清空节点的场景。

kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data


三、使用场景对比

使用场景

推荐命令

原因

临时停止调度,保留运行中的 Pod

cordon

如节点性能下降但不希望中断服务时

准备对节点进行维护(如升级内核、重启)

drain

确保 Pod 安全迁移后再操作节点

排查故障节点

cordon → 再决定是否 drain

防止新任务分配到问题节点,同时观察旧 Pod 行为

永久移除节点

drain + kubectl delete node

清空节点内容后从集群中删除

灰度发布/滚动更新特定节点

drain

强制 Pod 迁移到新版本节点


5. 什么是亲和性与反亲和性?有哪些使用场景

在 Kubernetes 中,亲和性(Affinity)反亲和性(Anti-Affinity) 是用于控制 Pod 与节点(Node)之间、或 Pod 与 Pod 之间的调度策略。它们通过标签选择器来决定 Pod 应该或不应该被调度到哪些节点上,或者与其他哪些 Pod 共存或隔离。


一、什么是亲和性与反亲和性?

1. 亲和性(Affinity)

  • 定义:让 Pod 更倾向于调度到具有某些标签的节点上,或者与其他具有特定标签的 Pod 调度在一起。

  • 目的:实现资源聚合、提高性能、满足部署需求等。

2. 反亲和性(Anti-Affinity)

  • 定义:让 Pod 尽量避免调度到具有某些标签的节点上,或者避免与其他特定 Pod 调度在一起。

  • 目的:实现负载均衡、故障隔离、提升可用性等。

二、分类

Kubernetes 支持两种类型的亲和性/反亲和性:

类型

描述

使用场景

节点亲和性(Node Affinity)

控制 Pod 应该调度到哪些节点上

按节点标签调度、区域划分等

Pod 亲和性/反亲和性(Pod Affinity/Anti-Affinity)

控制 Pod 应该/不应该与哪些其他 Pod 一起调度

微服务共部署、避免单点故障等


6. 创建三个Pod,分别为A、B、C,要求利用亲和性与反亲和性,让A和B自动部署到同一节点,但是C会部署到与A和B不同的节点上。

  • Pod A 打上标签,如 app=app-a

  • Pod B 上设置 Pod 亲和性,使其倾向于调度到已有 app=app-a 的节点

  • Pod C 上设置 Pod 反亲和性,使其避免调度到有 app=app-aapp=app-b 的节点

# Pod A
apiVersion: v1
kind: Pod
metadata:
  name: pod-a
  labels:
    app: app-a
spec:
  containers:
    - name: container-a
      image: nginx
# Pod B
apiVersion: v1
kind: Pod
metadata:
  name: pod-b
  labels:
    app: app-b
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
              - key: app
                operator: In
                values:
                  - app-a
          topologyKey: "kubernetes.io/hostname"
  containers:
    - name: container-b
      image: nginx
# Pod C
apiVersion: v1
kind: Pod
metadata:
  name: pod-c
  labels:
    app: app-c
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
              - key: app
                operator: In
                values:
                  - app-a
                  - app-b
          topologyKey: "kubernetes.io/hostname"
  containers:
    - name: container-c
      image: nginx


7. 什么是拓扑域,K8s中有哪些拓扑域

在 Kubernetes 中,拓扑域(Topology Domain) 是指调度器用来判断资源分布的逻辑单位。它通常用于描述节点之间的物理或逻辑关系,比如:节点、机架、区域、数据中心等。


  • 定义:拓扑域是 Kubernetes 调度时使用的“最小隔离单元”,表示某种层级结构下的一个划分单位。

  • 作用:用于控制 Pod 的分布策略(如亲和性/反亲和性、持久卷绑定、副本分布等),以实现高可用、故障隔离、性能优化等目标。

  • 常见形式

    • kubernetes.io/hostname(节点级)

    • topology.kubernetes.io/zone(区域级)

    • topology.kubernetes.io/region(地域级)

拓扑键

描述

使用场景

kubernetes.io/hostname

表示每个节点的主机名

同一节点上的 Pod 分布控制

topology.kubernetes.io/zone

表示节点所属的可用区(Zone)

多副本跨可用区部署、高可用架构

topology.kubernetes.io/region

表示节点所属的地理区域(Region)

多区域部署、容灾架构

rack(自定义)

自定义拓扑键,表示机架级别

高可用部署中避免多个副本落在同一机架

node-group(自定义)

自定义拓扑键,表示节点组

管理特定硬件配置的节点池


8. 什么是污点(Taint)与容忍(Toleration)?它们如何配合使用,有哪些使用场景

在 Kubernetes 中,污点(Taint)容忍(Toleration) 是用于控制 Pod 与节点之间调度关系的核心机制。它们配合使用,可以实现对节点资源的精细调度控制,适用于各种部署需求。


什么是污点和容忍?

污点(Taint)

  • 是附加在节点上的“排斥标签”,表示该节点不欢迎某些 Pod。

  • 如果一个 Pod 没有对应的容忍,它将不会被调度到该节点上。

容忍(Toleration)

  • 是附加在 Pod 上的“接受标签”,表示该 Pod 可以接受某个污点。

  • 只有具备匹配容忍的 Pod 才能被调度到带有对应污点的节点上。

设置污点(Node Taint):

kubectl taint nodes <node-name> <key>=<value>:<effect>

在 Pod 上设置容忍:

tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "highmem"
    effect: "NoSchedule"

污点的作用(Effect)

Effect

含义

NoSchedule

不允许新 Pod 调度到该节点,但不影响已有 Pod

PreferNoSchedule

尽量避免调度,但仍可能被调度

NoExecute

不仅阻止新 Pod 调度,还会驱逐已运行的 Pod(如果无对应容忍)

目标:

限制只有特定 Pod 才能调度到这些节点。

步骤:

给节点打上污点:

kubectl taint nodes gpu-node1 hardware=gpu:NoSchedule


Pod 配置容忍才能调度:

tolerations:
  - key: "hardware"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"


9. 如何使用nodeSelector指定Pod调度到某个节点?

在 Kubernetes 中,nodeSelector 是一种最基础的调度方式,它允许你通过节点上的标签(Label)来指定 Pod 调度到特定的节点上。


使用 nodeSelector 的步骤

1. 给目标节点打标签

首先,你需要为你要调度到的目标节点添加一个或多个标签:

kubectl label nodes <node-name> <key>=<value>

2. 在 Pod 或 Deployment 中使用 nodeSelector

然后,在你的 Pod 或控制器(如 Deployment)的 YAML 文件中添加 nodeSelector 字段,并指定对应的标签键值对。

示例:Pod 配置文件中使用 nodeSelector

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

这样,Kubernetes 调度器会确保该 Pod 只会被调度到带有 disktype=ssd 标签的节点上。


10. 使用调度相关的配置文件,创建两个Pod分别调度到不同的节点上

可以使用 Kubernetes 的调度机制(如 nodeSelectoraffinitytopologyKey)来控制 Pod 调度到不同的节点上。


目标

创建两个 Pod:pod-apod-b,确保它们被调度到不同节点上。


实现方式一:使用 nodeSelector(需要手动打标签)

1. 给节点打标签(假设你有两个节点 node-1 和 node-2):

kubectl label nodes node-1 role=node-a
kubectl label nodes node-2 role=node-b

2. 创建 Pod A(调度到 node-1)

apiVersion: v1
kind: Pod
metadata:
  name: pod-a
spec:
  containers:
    - name: app
      image: nginx
  nodeSelector:
    role: node-a

3. 创建 Pod B(调度到 node-2)

apiVersion: v1
kind: Pod
metadata:
  name: pod-b
spec:
  containers:
    - name: app
      image: nginx
  nodeSelector:
    role: node-b


11. 什么是资源请求(requests)和限制(limits)?

在 Kubernetes 中,资源请求(Requests)资源限制(Limits) 是用于控制容器对 CPU 和内存等资源使用的重要机制。它们帮助调度器决定 Pod 应该运行在哪一个节点上,并防止某个容器占用过多资源导致其他容器无法正常运行。


一、什么是资源请求(Requests)?

  • 定义requests 表示容器启动和运行所需的最小资源量。

  • 作用

    • Kubernetes 调度器会根据 requests 决定将 Pod 调度到哪个节点;

    • 确保节点上有足够的可用资源来运行该容器;

    • 用于 QoS 分级(服务质量等级)判断。

示例:

resources:
  requests:
    memory: "256Mi"
    cpu: "100m"

二、什么是资源限制(Limits)?

  • 定义limits 表示容器可以使用的最大资源上限。

  • 作用

  • 防止容器占用超过设定的 CPU 或内存资源;

  • 如果容器尝试使用超过 limits 的内存,会被 OOM(Out of Memory) 杀掉;

  • 如果是 CPU,超出部分会被限流(throttling),不会完全禁止使用,但性能受限。

resources:
  limits:
    memory: "512Mi"
    cpu: "500m"


12. 如何查看Pod的资源使用情况?

1. 使用 kubectl top pod 查看实时资源使用

命令:

kubectl top pod <pod-name> [-n <namespace>]

2. 查看 Pod 的请求与限制配置

你可以通过以下命令查看 Pod 的资源配置(requests 和 limits):

bash


13. 如果不设置requests/limits会有什么问题?

一、未设置 requests 的潜在问题

1. 调度不合理

  • Kubernetes 调度器(kube-scheduler)会根据 requests 来判断节点是否有足够的资源来运行该 Pod。

  • 如果未设置 requests,调度器将无法做出合理的调度决策,可能导致:

    • 某个节点被调度了多个“高负载”Pod,造成资源争抢;

    • 集群资源利用率不均衡,部分节点空闲,部分节点超载。

2. QoS 等级下降

  • 没有设置任何资源请求和限制的 Pod 属于 BestEffort QoS 类型。

  • 在内存不足(OOM)情况下,这类 Pod 是最先被杀掉的。

3. 影响集群整体资源规划

  • 无法通过 kubectl describe node <node-name> 查看节点上的可用/已分配资源;

  • 难以实现多租户资源配额管理(ResourceQuota);

  • 影响自动扩缩容策略(如 HPA)的准确性。


二、未设置 limits 的潜在问题

1. 资源滥用风险

  • 容器可以无上限地使用 CPU 和内存,可能占用整个节点资源,导致其他服务性能下降或崩溃。

2. 内存溢出(OOM)风险

  • 如果没有设置 limits.memory,当容器使用内存超过节点可承受范围时,会被内核 OOM Killer 杀死,表现为:

3. CPU 资源争用

  • 默认不限制 CPU 使用,一个容器可以占用所有 CPU 资源,影响其他容器性能。


14. 使用yaml为一个Pod配置CPU和内存限制

你可以通过在 Pod 的 YAML 配置文件中使用 resources 字段来设置 CPU 和内存的请求(requests)和限制(limits)


示例:配置 Pod 的 CPU 和内存限制

下面是一个完整的 Pod YAML 示例,设置了容器的 CPU 和内存请求与限制:

apiVersion: v1
kind: Pod
metadata:
  name: resource-pod
spec:
  containers:
    - name: app-container
      image: nginx
      resources:
        requests:
          memory: "256Mi"
          cpu: "100m"
        limits:
          memory: "512Mi"
          cpu: "500m"


15. 什么是QoS?有哪几种类型?它们的优先级排序?

在 Kubernetes 中,QoS(Quality of Service,服务质量等级) 是一种用于描述 Pod 资源保障级别的机制。Kubernetes 根据 Pod 是否设置了 resources.requestsresources.limits 来决定其 QoS 类型,并据此在资源紧张时做出调度和驱逐决策。


一、QoS 的作用

  • 资源保障级别划分:不同 QoS 级别的 Pod 在资源不足时受到不同的对待。

  • 影响 OOM(Out of Memory)优先级:当节点内存不足时,内核 OOM Killer 会优先杀死低优先级的 Pod。

  • 影响调度行为:调度器会根据请求资源量来选择合适的节点。


二、QoS 类型及判断条件

Kubernetes 将 Pod 分为三种 QoS 类型:

类型

判断条件

特点

Guaranteed(保证)

所有容器都设置了 requests == limits

最高优先级,最不容易被杀

Burstable(可爆发)

至少有一个容器设置了 requests < limits 或仅设置了 requests

中等优先级

BestEffort(尽力而为)

所有容器都没有设置 requestslimits

最低优先级,最先被杀


三、QoS 优先级排序(从高到低)

  1. Guaranteed

    • 容器设置了固定的资源请求和限制(requests == limits

    • 调度器确保节点上有足够的资源

    • 内存不足时最后才被 OOM 杀死

  2. Burstable

    • 容器设置了资源请求但未设上限(requests < limits 或只设了 requests

    • 可以突发使用额外资源,但超过后可能被限流或杀掉

    • OOM 优先级居中

  3. BestEffort

    • 没有设置任何资源请求和限制

    • 不受调度器保护,容易被调度到资源不足的节点

    • OOM 时第一个被杀

以他人的幸福为幸福,以他人的享乐为享乐。