1. 什么是Pod调度,它由谁负责?
在 Kubernetes 中,Pod 调度是指将一个新创建的 Pod 分配到集群中某个合适的节点(Node)上运行的过程。这个过程由 Kubernetes Scheduler(调度器) 负责。
什么是 Pod 调度?
当你提交一个 Pod 的创建请求后,Kubernetes 会先创建该 Pod 的对象并将其保存在 etcd 中。
此时,Pod 处于
Pending状态,表示尚未被分配到任何节点。调度器会观察所有处于
Pending状态的 Pod,并根据一系列策略(如资源需求、亲和性、污点容忍等)选择一个最合适的节点来运行这个 Pod。一旦选定节点,调度器就会将 Pod 绑定(bind)到该节点,随后 kubelet 在该节点上启动 Pod 中的容器。
调度器的主要职责:
监听 API Server:通过 Watch 机制获取新创建的 Pod。
执行调度算法:
过滤(Filtering):筛选出满足 Pod 资源需求、节点选择器、污点容忍等条件的节点。
打分(Scoring):对符合条件的节点进行打分,选出最优节点(例如负载最低、资源最充足等)。
绑定节点(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"
标签的作用对象
Kubernetes 中几乎所有资源都可以使用标签,以下是一些常见的支持标签的对象:
3. 保障k8s集群有2个node节点,并且为两个node节点打上不同的标签
假设你要为两个节点分别打上如下标签:
worker-1标签:zone=beijingworker-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) 是两种用于管理节点状态的操作,它们的目的和使用场景不同。
一、概念区别
二、操作流程对比
1. cordon 操作流程
将节点标记为
SchedulingDisabled;已有 Pod 不受影响;
新 Pod 不会被调度到该节点;
可用于维护前的准备阶段。
kubectl cordon node-12. drain 操作流程
先执行
cordon;对节点上的所有可驱逐 Pod 执行
graceful termination;Pod 会被控制器(如 Deployment)重新调度到其他节点;
适用于节点下线、升级、维护等需要清空节点的场景。
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
三、使用场景对比
5. 什么是亲和性与反亲和性?有哪些使用场景
在 Kubernetes 中,亲和性(Affinity) 和 反亲和性(Anti-Affinity) 是用于控制 Pod 与节点(Node)之间、或 Pod 与 Pod 之间的调度策略。它们通过标签选择器来决定 Pod 应该或不应该被调度到哪些节点上,或者与其他哪些 Pod 共存或隔离。
一、什么是亲和性与反亲和性?
1. 亲和性(Affinity)
定义:让 Pod 更倾向于调度到具有某些标签的节点上,或者与其他具有特定标签的 Pod 调度在一起。
目的:实现资源聚合、提高性能、满足部署需求等。
2. 反亲和性(Anti-Affinity)
定义:让 Pod 尽量避免调度到具有某些标签的节点上,或者避免与其他特定 Pod 调度在一起。
目的:实现负载均衡、故障隔离、提升可用性等。
二、分类
Kubernetes 支持两种类型的亲和性/反亲和性:
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-a或app=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(地域级)
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)
目标:
限制只有特定 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 的调度机制(如 nodeSelector、affinity 和 topologyKey)来控制 Pod 调度到不同的节点上。
目标
创建两个 Pod:pod-a 和 pod-b,确保它们被调度到不同节点上。
实现方式一:使用 nodeSelector(需要手动打标签)
1. 给节点打标签(假设你有两个节点 node-1 和 node-2):
kubectl label nodes node-1 role=node-a
kubectl label nodes node-2 role=node-b2. 创建 Pod A(调度到 node-1)
apiVersion: v1
kind: Pod
metadata:
name: pod-a
spec:
containers:
- name: app
image: nginx
nodeSelector:
role: node-a3. 创建 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 属于
BestEffortQoS 类型。在内存不足(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.requests 和 resources.limits 来决定其 QoS 类型,并据此在资源紧张时做出调度和驱逐决策。
一、QoS 的作用
资源保障级别划分:不同 QoS 级别的 Pod 在资源不足时受到不同的对待。
影响 OOM(Out of Memory)优先级:当节点内存不足时,内核 OOM Killer 会优先杀死低优先级的 Pod。
影响调度行为:调度器会根据请求资源量来选择合适的节点。
二、QoS 类型及判断条件
Kubernetes 将 Pod 分为三种 QoS 类型:
三、QoS 优先级排序(从高到低)
Guaranteed
容器设置了固定的资源请求和限制(
requests == limits)调度器确保节点上有足够的资源
内存不足时最后才被 OOM 杀死
Burstable
容器设置了资源请求但未设上限(
requests < limits或只设了requests)可以突发使用额外资源,但超过后可能被限流或杀掉
OOM 优先级居中
BestEffort
没有设置任何资源请求和限制
不受调度器保护,容易被调度到资源不足的节点
OOM 时第一个被杀