1 K8s核心资源Pod

1.1 Pod是什么?

官方文档:Pod | Kubernetes

Pod 是 Kubernetes(k8s)中最小的部署与调度单元,并非直接运行容器,而是对一个或多个 “紧密关联” 容器的封装。

核心特点可简单总结为 3 点:

  1. 容器的 “组合包”:通常包含 1 个主容器(业务核心,如 Web 服务),也可包含辅助容器(如日志收集、监控代理),所有容器共享 Pod 的资源。
  2. 共享基础环境:同一 Pod 内的容器共享网络命名空间(用localhost就能互相通信,无需跨网络)和存储卷(可共用文件目录),相当于 “在同一台迷你主机上运行”。
  3. 短暂且被管理:Pod 本身是 “一次性” 的(故障、重启后会生成新 Pod,IP 会变),不会自行修复,需依赖 k8s 的控制器(如 Deployment、StatefulSet)来管理其创建、扩缩容和故障恢复。

白话解释:

    可以把 pod 看成是一个“豌豆荚”,里面有很多“豆子”(容器)。一个豌豆荚里的豆子,它们吸收着 共同的营养成分、肥料、水分等,Pod 和容器的关系也是一样,Pod 里面的容器共享 pod 的网络、存储等。

1.1.1 Pod如何管理多个容器

在 Kubernetes 中,Pod 管理多个容器的核心逻辑是 “协同调度、资源共享、生命周期绑定”,具体通过以下方式实现:

  1. 共享基础环境
    同一 Pod 内的所有容器共享网络命名空间(相同的 IP 地址、端口空间)和存储卷(Volume)

    • 网络:容器间可通过localhost直接通信(如localhost:8080访问同一 Pod 内的另一个容器),但需注意端口不冲突;对外表现为一个整体,共享 Pod 的 IP。
    • 存储:Pod 中定义的 Volume(如临时目录emptyDir、持久化存储PersistentVolume)可被所有容器挂载,实现数据共享(如日志容器读取主容器产生的日志文件)。
  2. 生命周期绑定
    多个容器的生命周期与 Pod 强绑定:

    • 同时调度:Pod 被调度到某个节点后,其内所有容器会在同一节点启动。
    • 整体管理:Pod 删除时,所有容器同时终止;Pod 重启(如节点故障重建)时,所有容器重新创建。
    • 重启策略统一:Pod 通过restartPolicy(如AlwaysOnFailure)定义容器故障时的重启规则,适用于所有容器。
  3. 启动与依赖控制
    若容器间有启动顺序或依赖关系,可通过以下机制控制:

    • Init 容器:在应用容器启动前运行的 “初始化容器”,完成前置任务(如配置加载、依赖检查),所有 Init 容器成功退出后,应用容器才会启动。
    • 探针(Probe):通过livenessProbe(存活探针)、readinessProbe(就绪探针)检测容器状态,确保容器按预期运行后再对外提供服务。
  4. 资源隔离与分配
    每个容器可单独设置资源请求(resources.requests)和限制(resources.limits),Pod 会汇总这些需求向 Kubernetes 申请资源,确保容器间资源使用不冲突(如避免某容器耗尽内存影响其他容器)。

1.1.2 Pod网络

Pod 网络核心可总结为:

  • 每个 Pod 有唯一集群内 IP,作为其网络身份;
  • 同一 Pod 内容器共享网络命名空间,通过localhost直接通信;
  • 集群内 Pod 间可直接用 IP 互通(无 NAT),依赖 CNI 插件实现跨节点通信;
  • Pod 访问外部靠节点 SNAT,外部访问 Pod 需通过 Service 作为稳定入口。

1.1.3 Pod存储

创建 Pod 的时候可以指定挂载的存储卷。 POD 中的所有容器都可以访问共享卷,允许这些容器共享数据。 Pod 只要挂载持久化数据卷,Pod 重启之后数据还是会存在的。

1.2 Pod工作方式

在 K8s 中,所有的资源都可以使用一个 yaml 文件来创建,创建 Pod 也可以使用 yaml 配置文件。或者使用 kubectl run 在命令行创建 Pod。

1.2.1 自主式 Pod

所谓的自主式 Pod,就是直接定义一个 Pod 资源,如下:

apiVersion: v1
kind: Pod
metadata:name: nginx-testnamespace: defaultlabels:app: nginx
spec:containers:- name: nginxports:- containerPort: 80image: nginximagePullPolicy: IfNotPresent# 更新资源清单
kubectl apply -f pod-nginx.yaml# 查看pod是否创建成功
kubectl get pods -o wide -l app=nginx

自主式Pod存在一个问题,加入不小心删除了Pod,那么就彻底被删除了,不会再创建一个新的Pod,这如果在生产环境中有非常大的风险,用控制器管理最好。

kubectl delete pods nginx-testkubectl get pods -l app=nginx
#结果为空说明pod已经被删除了

1.2.2 控制器管理的Pod

常见的管理 Pod 的控制器:Replicaset、Deployment、Job、CronJob、Daemonset、Statefulset。 控制器管理的 Pod 可以确保 Pod 始终维持在指定的副本数运行。 如,通过 Deployment 管理 Pod

vim nginx-deploy.yamlapiVersion: v1
kind: Deployment
metadata:name: nginx-testlabels:app: nginx-deploy
spec:selector:matchLabels:app: nginxreplicas: 2        # 副本数为2template:metadata:labels:app: nginx
spec:containers:- name: my-nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80# 更新资源清单文件
kubectl apply -f nginx-deploy.yaml# 查看Deployment
kubectl get deploy -l app=nginx-deploy
NAME READY UP-TO-DATE AVAILABLE AGE 
nginx-test 2/2 2 2 16s#查看 Replicaset
kubectl get rs -l app=nginx 
NAME DESIRED CURRENT READY AGE 
nginx-test-75c685fdb7 2 2 2 71s#查看 pod
kubectl get pods -o wide -l app=nginx
NAME READY STATUS IP 
nginx-test-85c885fdb7-6d4lx 1/1 Running 10.190.102.69 
nginx-test-85c885fdb7-9s95h 1/1 Running 10.190.102.68#删除nginx-test-85c885fdb7-9s95h这个 podkubectl delete pods nginx-test-85c885fdb7-9s95h
kubectl get pods -o wide -l app=nginxNAME READY STATUS IP 
nginx-test-85c885fdb7-6d4lx 1/1 Running 10.190.102.69 
nginx-test-85c885fdb7-6s95h 1/1 Running 10.190.102.68# 发现重新创建了一个新的pod  nginx-test-85c885fdb7-6s95h

通过上面可以发现通过 deployment 管理的 pod,可以确保 pod 始终维持在指定副本数量.

2 命名空间(namespace)

2.1 什么是命名空间?

在 Kubernetes 中,命名空间(Namespace)是用于对集群内资源进行逻辑隔离的机制,核心作用是在共享同一 K8s 集群的场景下,避免资源名称冲突、区分环境或团队,方便管理和权限控制。

核心特点:

  1. 资源隔离:同一命名空间内的资源名称必须唯一,但不同命名空间可以有同名资源(如两个命名空间都能有叫 “nginx” 的 Pod)。

  2. 环境 / 团队划分:通常用于隔离不同环境(如dev开发、test测试、prod生产)或不同团队的资源,避免互相干扰。

  3. 权限控制:可通过 RBAC(基于角色的访问控制)为不同命名空间设置独立的权限规则(如只允许某团队操作dev命名空间)。

常见默认命名空间:

  • default:未指定命名空间时,资源默认创建于此。

  • kube-system:K8s 系统组件(如 kube-proxy、调度器)所在的命名空间。

  • kube-public:所有用户可见的公共资源(通常用于存储集群信息)。

简单说,命名空间就像集群内的 “虚拟分区”,让多场景共享集群时更有序。

2.2 namespace 应用场景

  1. 环境隔离:区分 dev(开发)、test(测试)、prod(生产)环境,避免相互干扰;

  2. 团队 / 项目隔离:为多团队 / 项目划分 “资源池”,防止资源名冲突与误操作;

  3. 资源配额控制:结合 ResourceQuota,限制各场景 / 团队的 CPU、内存等资源上限;

  4. 权限精细化控制:结合 RBAC,让不同角色仅能操作指定 Namespace 的资源,保障安全;

  5. 临时场景隔离:为实验、POC 等临时需求创建 Namespace,用完一键删除,清理高效。

核心是通过逻辑隔离,实现集群资源的有序管理与安全共享。

2.3 namespace 使用案例

# 创建一个命名空间
kubectl create ns test# 切换命名空间
kubectl config set-context --current --namespace=kube-system
# 切换了命名空间后,kubectl get pods 如果不指定-n,查看的就是kube-system命名空间的资源# 查看哪些资源属于命名空间级别的
kubectl api-resources --namespaced=true

2.4 namespace资源限额

kubectl config set-context --current -namespace=default# namespace 是命名空间,里面有很多资源,那么我们可以对命名空间资源做个限制,防止该命名空间
部署的资源超过限制。vim namespace-quota.yamlapiVersion: v1 
kind: ResourceQuota 
metadata: name: mem-cpu-quota namespace: test 
spec: hard: requests.cpu: "2" requests.memory: 2Gi limits.cpu: "4" limits.memory: 4Gi

#创建的 ResourceQuota 对象将在 test 名字空间中添加以下限制:

每个容器必须设置内存请求(memory request),内存限额(memory limit),cpu 请求(cpu

request)和 cpu 限额(cpu limit)。

所有容器的内存请求总额不得超过 2GiB。

所有容器的内存限额总额不得超过 4 GiB。

所有容器的 CPU 请求总额不得超过 2 CPU。

所有容器的 CPU 限额总额不得超过 4CPU。

3 标签(Label)

3.1 什么是标签

标签是附加在对象(如 Pod、Node 等)上的键值对,用于标识、分类对象,可动态添加或修改。核心作用是通过标签选择器筛选、关联对象(如 Service 关联 Pod、Deployment 管理 Pod 等),是 K8s 中对象管理和关联的基础机制。

3.2 给pod资源打标签

给 Pod 打标签有两种方式:创建时指定标签,或为已存在的 Pod 添加 / 修改标签。

1. 创建 Pod 时指定标签(推荐)

apiVersion: v1
kind: Pod
metadata:name: my-podlabels:  # 这里定义标签app: nginxenv: productionversion: v1
spec:containers:- name: nginximage: nginx:latest

创建 Pod:kubectl apply -f pod.yaml

2. 为已存在的 Pod 添加 / 修改标签

使用 kubectl label 命令:

# 给名为my-pod的Pod添加标签(如添加"team=backend")
kubectl label pods my-pod team=backend# 若标签已存在,需加--overwrite强制修改
kubectl label pods my-pod env=test --overwrite

3. 验证标签

# 查看Pod的标签
kubectl get pod my-pod --show-labels# 筛选带有特定标签的Pod(如app=nginx)
kubectl get pods -l app=nginx

标签可用于筛选 Pod、关联 Service/Deployment 等,是 K8s 对象管理的重要工具。

3.3 查看资源标签

在 Kubernetes 中,查看资源标签的常用方式是通过 kubectl 命令,支持查看单个资源、所有资源的标签,或筛选带有特定标签的资源。

1. 查看资源的所有标签(最常用)

使用 --show-labels 选项,可显示指定资源的所有标签:

# 查看所有 Pod 的标签
kubectl get pods --show-labels# 查看单个Pod的标签
kubectl get pods nginx-pod --show-labels# 查看所有 Node(节点) 的标签
kubectl get nodes --show-labels# 查看所有 Deployment 的标签
kubectl get deployment --show-labels

2. 筛选带有特定标签的资源

使用 -l 选项,可按标签筛选资源(支持 =!= 等条件):

# 查看标签为 app=nginx 的所有Pod
kubectl get pods -l app=nginx# 查看标签为 env!=production 的所有Pod
kubectl get pods -l env!=production# 查看同时带有 app=nginx和version=v1的所有Pod
kubectl get pods -l app=nginx,version=v1

3. 查看资源的详细标签信息

使用 describe 命令,可在资源详情的 Metadata.Labels 部分查看标签:

# 查看某个 Pod的详细信息(包含标签)
kubectl describe pod my-pod# 查看某个 Node 的详细信息(包含标签)
kubectl describe node node1

通过以上命令,可快速查看、筛选 Kubernetes 各类资源的标签,方便进行资源管理和关联操作。

4 Pod资源清单详细解读

Pod 资源清单(YAML/JSON 格式)是定义 Kubernetes Pod 运行规范的核心配置文件,包含了 Pod 的元数据、运行容器、资源需求、网络、存储等关键信息。以下是对 Pod 资源清单主要字段的详细解读(以 YAML 为例):

基础结构框架

一个完整的 Pod 清单通常包含 4 个顶级字段(缺一不可):

apiVersion: v1  # API 版本
kind: Pod       # 资源类型
metadata:       # 元数据(标识信息)...
spec:           # 规格(核心配置,定义 Pod 如何运行)...

4.1 顶级字段

  • apiVersion: v1
    指定 Kubernetes API 版本。Pod 是核心资源,稳定版本为 v1(其他资源可能有不同版本,如 apps/v1)。

  • kind: Pod
    声明资源类型为 Pod(Kubernetes 中还有 Deployment、Service 等其他类型)。

4.2 metadata:元数据(标识与属性)

用于唯一标识 Pod 并附加额外信息,常见字段:

metadata:name: my-pod                  # Pod 名称(必填,在命名空间内唯一,只能包含字母、数字、-、_、.)namespace: default            # 所属命名空间(默认是 default,用于资源隔离,可选)labels:                       # 标签(键值对,用于筛选和关联其他资源,如 Service/Deployment)app: nginxenv: productionannotations:                  # 注解(键值对,用于存储非标识性元数据,如运维备注、工具配置)description: "This is a nginx pod"managed-by: "kubectl"uid: "xxxx-xxxx-xxxx"         # 自动生成的唯一 ID(创建后由 K8s 分配,无需手动设置)

4.3 spec:核心规格(定义 Pod 运行规则)

这是 Pod 配置的核心,包含容器、资源、网络、存储等关键信息。

4.3.1 容器配置(spec.containers

Pod 由一个或多个容器组成,containers 是必填列表,每个容器的配置如下:

spec:containers:- name: nginx-container       # 容器名称(在 Pod 内唯一,必填)image: nginx:1.23           # 容器镜像(必填,格式:仓库地址/镜像名:标签,默认拉取 latest)imagePullPolicy: IfNotPresent  # 镜像拉取策略(可选,默认 IfNotPresent)# - Always:每次都拉取镜像;# - IfNotPresent:本地有则用本地,否则拉取;# - Never:只使用本地镜像,不拉取ports:                      # 容器端口配置(可选,用于声明端口,不直接暴露到集群)- containerPort: 80         # 容器内监听的端口(必填,仅用于标识)hostPort: 8080            # 主机映射端口(可选,不推荐,可能导致端口冲突)protocol: TCP             # 协议(默认 TCP,可选 UDP/SCTP)name: http                # 端口名称(可选,用于区分多个端口)command: ["/bin/sh"]        # 容器启动命令(可选,覆盖镜像默认命令)args: ["-c", "echo hello"]  # 启动命令参数(可选,配合 command 使用)env:                        # 环境变量(可选,注入容器内的环境变量)- name: APP_ENV             # 环境变量名称value: "production"       # 直接设值- name: DB_PASSWORD         # 从 Secret 中获取值(更安全)valueFrom:secretKeyRef:name: db-secret       # Secret 名称key: password         # Secret 中的键resources:                  # 资源需求与限制(可选,影响调度和资源分配)requests:                 # 申请的最小资源(调度时参考,确保节点有足够资源)cpu: "100m"             # 100m = 0.1 CPU 核心memory: "128Mi"         # 128 兆内存limits:                   # 资源上限(容器不能超过此限制,否则可能被终止)cpu: "500m"memory: "256Mi"volumeMounts:               # 挂载存储卷(可选,将 spec.volumes 定义的存储挂载到容器内)- name: data-volume         # 要挂载的卷名称(需与 spec.volumes 中名称一致)mountPath: /usr/share/nginx/html  # 容器内挂载路径readOnly: false           # 是否只读(默认 false)livenessProbe:              # 存活探针(可选,检测容器是否"存活",失败则重启容器)httpGet:path: /                 # 探测路径port: 80                # 探测端口initialDelaySeconds: 5    # 容器启动后延迟多久开始探测(秒)periodSeconds: 10         # 探测间隔(秒,默认 10)readinessProbe:             # 就绪探针(可选,检测容器是否"就绪",失败则从 Service 移除)httpGet:path: /readyport: 80initialDelaySeconds: 3periodSeconds: 5securityContext:            # 容器级安全上下文(可选,如运行用户、权限)runAsUser: 1000           # 容器内进程的 UIDrunAsGroup: 3000          # 容器内进程的 GIDallowPrivilegeEscalation: false  # 是否允许提权(默认 true)

4.3.2 初始化容器(spec.initContainers

在应用容器(containers)启动前运行的容器,用于初始化工作(如拉取配置、等待依赖),执行完后退出(必须成功退出,否则 Pod 卡在 Init 状态)。配置格式与 containers 一致:

spec:initContainers:- name: init-configimage: busybox:1.35command: ["wget", "-O", "/config/index.html", "http://config-server/index"]volumeMounts:- name: data-volumemountPath: /config

4.3.3 存储卷(spec.volumes

定义 Pod 可使用的存储卷(供容器挂载),支持多种类型(如临时存储、主机路径、配置文件等):

spec:volumes:- name: data-volume           # 卷名称(供 volumeMounts 引用)emptyDir: {}                # 临时存储(Pod 生命周期内存在,删除后数据丢失)- name: host-path-volumehostPath:                   # 主机路径(挂载节点上的文件/目录,不推荐生产环境)path: /var/logtype: Directory- name: config-volumeconfigMap:                  # 挂载 ConfigMap(配置文件)name: nginx-config        # ConfigMap 名称- name: secret-volumesecret:                     # 挂载 Secret(敏感信息,如密码)secretName: db-credentials

Pod 资源清单通过 metadata 定义标识信息,通过 spec 详细配置容器运行规则(包括镜像、资源、网络、存储、调度策略等)。理解这些字段是编写、调试 Pod 配置的基础,也是使用 Kubernetes 部署应用的核心技能。

4.3.4 调度与节点选择

控制 Pod 被调度到哪个节点:

spec:nodeSelector:                 # 节点选择器(简单匹配,仅支持等于)disk: ssd                   # 调度到带有 label "disk=ssd" 的节点affinity:                     # 亲和性规则(更灵活的调度策略)nodeAffinity:               # 节点亲和性(倾向/必须调度到满足条件的节点)requiredDuringSchedulingIgnoredDuringExecution:  # 硬亲和性(必须满足)nodeSelectorTerms:- matchExpressions:- key: envoperator: Invalues: [production]preferredDuringSchedulingIgnoredDuringExecution:  # 软亲和性(优先满足)- weight: 100preference:matchExpressions:- key: zoneoperator: Invalues: [zone-1]podAntiAffinity:            # Pod 反亲和性(避免与特定 Pod 调度到同一节点)preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: Invalues: [database]topologyKey: "kubernetes.io/hostname"  # 按节点隔离tolerations:                  # 污点容忍(允许 Pod 调度到有特定污点的节点)- key: "node-type"operator: "Exists"effect: "NoSchedule"

5 节点选择器(nodeSelector)

在 Kubernetes 中,节点选择器(nodeSelector) 是一种简单的调度策略,用于将 Pod 限制在具有特定标签的节点上运行。它通过匹配节点的标签(Labels)来实现 Pod 与节点的绑定,是最基础的节点调度方式。

核心作用

让 Pod 只能被调度到拥有指定标签的节点上,确保 Pod 运行在符合预期的节点(如特定硬件、环境或功能的节点)。

5.1 为节点添加标签

首先需要给目标节点打上特定标签(若已有标签可跳过):

# 语法:kubectl label nodes <节点名称> <标签键>=<标签值>
kubectl label nodes node-1 env=production  # 给节点 node-1 打标签 env=production
kubectl label nodes node-2 hardware=gpu     # 给节点 node-2 打标签 hardware=gpu

验证节点标签:

kubectl get nodes --show-labels # 查看所有节点的标签
kubectl describe node node-1 | grep Labels    # 查看单个节点的标签

5.2 在 Pod 中配置 nodeSelector

在 Pod 的资源清单中,通过 spec.nodeSelector 字段指定需要匹配的节点标签,Pod 会被调度到所有标签完全匹配的节点上。

apiVersion: v1
kind: Pod
metadata:name: my-pod
spec:containers:- name: nginximage: nginx:latestnodeSelector:  # 节点选择器:仅调度到同时满足以下标签的节点env: production    # 匹配标签 env=productionhardware: gpu      # 匹配标签 hardware=gpu# 查看pod调度到哪个节点
kubectl get pods -o wideNAME READY STATUS RESTARTS 
my-pod 1/1 Running 0 node2

创建 Pod 后,Kubernetes 调度器会自动将其分配到符合标签条件的节点。

特点与限制

  • 优点:简单直观,适合基础的节点筛选场景。
  • 限制
    • 仅支持精确匹配(标签键和值必须完全一致),不支持 !=InNotIn 等复杂逻辑。
    • 是 “硬性要求”:如果没有匹配标签的节点,Pod 会一直处于 Pending 状态(调度失败)。

适用场景

  • 将 Pod 调度到特定环境的节点(如 env=production 或 env=test)。
  • 将需要特殊硬件的 Pod 调度到对应节点(如 hardware=gpu 或 disk=ssd)。

如果需要更灵活的调度策略(如 “优先调度到某类节点”“避免调度到某类节点” 等),可以使用 节点亲和性(Node Affinity) 替代 nodeSelector。

6 污点和容忍度

6.1 node 节点亲和性(Node Affinity)

在 Kubernetes 中,节点亲和性(Node Affinity) 是一种比 nodeSelector 更灵活的 Pod 调度策略,用于根据节点的标签(Labels)控制 Pod 被调度到哪些节点上。它支持更复杂的匹配逻辑(如 “包含”“不包含”“存在” 等),并分为 “硬性要求” 和 “软性偏好” 两种类型,满足不同调度场景的需求。

核心作用

让 Pod 按照自定义规则 “主动选择” 合适的节点(基于节点标签),既可以强制要求必须满足某些条件,也可以优先选择符合条件的节点(不强制)。

节点亲和性的两种类型

节点亲和性通过 spec.affinity.nodeAffinity 配置,分为以下两种:

类型关键字含义特点
硬亲和性requiredDuringSchedulingIgnoredDuringExecution必须满足的条件,否则 Pod 无法调度(一直处于 Pending 状态)强制约束,类似 “我必须吃饭,不吃饭就会饿”
软亲和性preferredDuringSchedulingIgnoredDuringExecution优先满足的条件,不满足也可以调度到其他节点柔性偏好,类似 “最好是现在吃饭,晚一点吃也没事”

匹配表达式(Operator)

节点亲和性通过 matchExpressions 定义匹配规则,支持多种操作符(比 nodeSelector 更灵活):

操作符含义示例
In节点标签的值必须在指定列表中key: "env"values: ["prod", "test"] → 匹配 env=prod 或 env=test
NotIn节点标签的值必须不在指定列表中key: "env"values: ["dev"] → 不匹配 env=dev
Exists节点必须存在指定标签(不校验值)key: "gpu" → 只要节点有 gpu 标签(无论值是什么)
DoesNotExist节点必须不存在指定标签key: "disk" → 节点不能有 disk 标签
Gt节点标签的值(数字)必须大于指定值key: "cpu-cores"values: ["4"] → 匹配 cpu-cores>4
Lt节点标签的值(数字)必须小于指定值key: "memory-gb"values: ["32"] → 匹配 memory-gb<32

配置示例

假设需要将 Pod 调度到 “生产环境(env=prod)的节点,且优先选择 SSD 磁盘(disk=ssd)的节点”,配置如下:

apiVersion: v1
kind: Pod
metadata:name: affinity-pod
spec:containers:- name: nginximage: nginx:latestaffinity:  # 亲和性配置nodeAffinity:# 硬亲和性:必须满足的条件requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:  # 多个条件组(满足任意一组即可)- matchExpressions:  # 条件组内的多个表达式(需同时满足)- key: envoperator: Invalues: ["prod"]  # 节点必须有 env=prod 标签# 软亲和性:优先满足的条件preferredDuringSchedulingIgnoredDuringExecution:- weight: 100  # 权重(0-100,数值越大优先级越高)preference:matchExpressions:- key: diskoperator: Invalues: ["ssd"]  # 优先选择 disk=ssd 的节点
  • 硬亲和性确保 Pod 只能调度到 env=prod 的节点(不满足则无法调度);
  • 软亲和性让调度器在满足硬亲和性的节点中,优先选择 disk=ssd 的节点(若无则选择其他 env=prod 节点)。

与其他调度策略的区别

策略特点适用场景
nodeSelector仅支持精确匹配(key=value简单的标签匹配场景
节点亲和性支持复杂匹配(In/Exists 等),分硬 / 软亲和性需灵活条件的调度(如 “必须在生产环境,优先用 SSD”)
污点(Taints)+ 容忍度(Tolerations)节点主动排斥 Pod,Pod 需 “容忍” 才能被调度节点隔离(如 “GPU 节点只允许 AI 任务调度”)

典型使用场景

  1. 环境隔离:强制 Pod 只能在 env=prod 节点运行(硬亲和性)。
  2. 资源偏好:优先将计算密集型 Pod 调度到 cpu=high 的节点(软亲和性)。
  3. 硬件依赖:必须将需要 GPU 的 Pod 调度到 gpu=true 的节点(硬亲和性)。

节点亲和性通过灵活的匹配规则和软硬约束,让 Pod 调度更符合实际业务需求,是 Kubernetes 中控制节点选择的核心机制之一。

6.2 Pod节点亲和性(Pod Affinity)

在 Kubernetes 中,Pod 亲和性(Pod Affinity) 是一种基于已运行 Pod 的标签来调度新 Pod 的策略。它用于控制新 Pod 与集群中已存在的 Pod 之间的 “位置关系”—— 即新 Pod 应该和哪些 Pod 调度到同一位置(亲和),或应该远离哪些 Pod(反亲和)。

与 “节点亲和性(Node Affinity)” 基于节点标签调度不同,Pod 亲和性基于其他 Pod 的标签调度,更适合控制服务之间的关联关系(如 “前端 Pod 和后端 Pod 尽量在同一节点”“数据库 Pod 尽量分散在不同节点”)。

核心概念

  • Pod 亲和性(Pod Affinity):新 Pod 倾向于与 “具有特定标签的已有 Pod” 调度到同一拓扑域(如同一节点、同一机房等)。
  • Pod 反亲和性(Pod Anti-Affinity):新 Pod 倾向于与 “具有特定标签的已有 Pod” 调度到不同拓扑域,避免集中部署。

拓扑域(Topology Domain):通过 topologyKey 定义,通常是节点的标签(如 kubernetes.io/hostname 表示 “同一节点”,topology.kubernetes.io/zone 表示 “同一可用区”),用于划分 “位置范围”。

类型与配置

Pod 亲和性 / 反亲和性也分为 “硬性要求” 和 “软性偏好” 两种类型,配置位于 spec.affinity.podAffinity 或 spec.affinity.podAntiAffinity 字段:

类型关键字含义
硬约束requiredDuringSchedulingIgnoredDuringExecution必须满足条件,否则 Pod 无法调度
软约束preferredDuringSchedulingIgnoredDuringExecution优先满足条件,不满足也可调度到其他位置

匹配规则

通过 labelSelector 匹配目标 Pod 的标签,语法与节点亲和性类似,支持 In/NotIn/Exists 等操作符。

配置示例

1. Pod 亲和性(让新 Pod 与目标 Pod 在同一节点)

需求:新的 frontend Pod 尽量与已有的 app=backend Pod 调度到同一节点(降低网络延迟)。

apiVersion: v1
kind: Pod
metadata:name: frontend-podlabels:app: frontend
spec:containers:- name: frontendimage: nginx:latestaffinity:podAffinity:  # Pod 亲和性配置preferredDuringSchedulingIgnoredDuringExecution:  # 软约束(优先满足)- weight: 80  # 权重(0-100)podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: Invalues: ["backend"]  # 匹配标签为 app=backend 的已有 PodtopologyKey: "kubernetes.io/hostname"  # 拓扑域:同一节点(按主机名划分)
2. Pod 反亲和性(让新 Pod 与目标 Pod 不在同一节点)

需求:新的 db Pod 必须与其他 app=db Pod 调度到不同节点(避免单点故障)。

apiVersion: v1
kind: Pod
metadata:name: db-pod-2labels:app: db
spec:containers:- name: dbimage: mysql:5.7affinity:podAntiAffinity:  # Pod 反亲和性配置requiredDuringSchedulingIgnoredDuringExecution:  # 硬约束(必须满足)- labelSelector:matchExpressions:- key: appoperator: Invalues: ["db"]  # 匹配标签为 app=db 的已有 PodtopologyKey: "kubernetes.io/hostname"  # 拓扑域:不同节点(按主机名划分)
  • 若集群中已有 app=db 的 Pod 运行在节点 A,新的 db-pod-2 会被调度到节点 B、C 等(不会再到节点 A)。
  • 若所有节点都已有 app=db 的 Pod,新 Pod 会因不满足硬约束而处于 Pending 状态。

关键参数:topologyKey

topologyKey 是节点的标签键,用于定义 “同一位置” 的范围,常见取值:

  • kubernetes.io/hostname:同一节点(最常用)。
  • topology.kubernetes.io/zone:同一可用区。
  • topology.kubernetes.io/region:同一地域。

例如,topologyKey: "topology.kubernetes.io/zone" 表示 “亲和 / 反亲和范围是同一可用区”,而非同一节点。

适用场景

  1. 服务就近部署:前端与后端 Pod 用亲和性调度到同一节点,减少网络延迟。
  2. 高可用分散:数据库、缓存等核心组件用反亲和性分散到不同节点 / 可用区,避免单点故障。
  3. 资源隔离:不同团队的 Pod 用反亲和性调度到不同节点,避免资源竞争。

与节点亲和性的区别

特性节点亲和性(Node Affinity)Pod 亲和性(Pod Affinity)
依赖对象节点的标签其他 Pod 的标签
调度依据节点本身的属性(如硬件、环境)已有 Pod 的分布位置
核心作用让 Pod 选择符合条件的节点让 Pod 与其他 Pod 保持特定位置关系

Pod 亲和性通过关联已有 Pod 的分布,实现更精细化的调度策略,是构建高可用、高性能集群的重要工具。

6.3 污点(Taints)

6.3.1 为什么需要污点?

假设有一个 Kubernetes 集群,里面有两类节点:

  • 普通节点:只有 CPU,供一般应用使用;

  • 特殊节点:带 GPU,专门给 AI 训练任务用。

如果不做任何限制,普通应用的 Pod 可能会被调度到 GPU 节点上,导致 GPU 资源被浪费(普通应用用不到 GPU)。

这时候就需要一种机制:让 GPU 节点 “主动拒绝” 普通 Pod,只允许 AI 任务的 Pod 进来。这种 “主动拒绝” 的规则,就是污点

6.3.2 污点是什么?

污点是给节点(Node) 打上的 “排斥性标记”,格式是 key=value:effect,由三部分组成:

  • key:污点的名字(比如 dedicatedenv);

  • value:污点的具体值(比如 gpuprod,可选,可空);

  • effect:排斥的 “力度”,决定如何拒绝 Pod(核心!)。

重点:effect 的三种 “排斥力度”
effect 类型通俗解释例子场景
NoSchedule不准新 Pod 进来,但已经在节点上的 Pod 可以继续运行。GPU 节点只允许新的 AI Pod 进来,老 Pod 不动
PreferNoSchedule尽量不让新 Pod 进来(非强制),如果实在没其他节点,也能进来。某个节点性能较差,尽量不调度新 Pod,但不绝对禁止
NoExecute不准新 Pod 进来,且已经在节点上的旧 Pod 也会被赶走(如果旧 Pod 没 “通行证”)。节点要维护了,先把上面的 Pod 赶走,再禁止新 Pod 进来

6.3.3 怎么操作污点?

1. 给节点添加污点

语法:kubectl taint nodes <节点名> <key>=<value>:<effect>

比如给名为 node-gpu-1 的节点添加一个 “禁止普通 Pod 调度” 的污点:

kubectl taint nodes node-gpu-1 dedicated=gpu:NoSchedule

含义:节点 node-gpu-1 现在有一个污点 dedicated=gpu:NoSchedule,表示 “只允许能容忍这个污点的 Pod 调度进来”。

2. 查看节点的污点

想知道节点上有哪些污点,用 describe 命令:

kubectl describe node node-gpu-1 | grep Taints

如果看到 Taints: dedicated=gpu:NoSchedule,说明污点添加成功。

3. 删除节点的污点

语法:在污点后面加一个 -,比如删除上面添加的污点:

kubectl taint nodes node-gpu-1 dedicated=gpu:NoSchedule-

6.3.4 总结:污点的核心作用

污点是节点的 “主动防御机制”,通过 effect 控制对 Pod 的排斥力度:

  • NoSchedule:挡新 Pod,保旧 Pod;

  • NoExecute:挡新 Pod,赶旧 Pod;

  • PreferNoSchedule:尽量挡新 Pod,不绝对。

配合容忍度,就能实现 “节点专用化”“环境隔离”“节点维护” 等场景,让集群资源调度更合理。

6.4 容忍度(Tolerations)

污点是节点的 “排斥规则”,但如果某个 Pod 确实需要用到这个节点(比如 AI 任务需要 GPU),就需要给 Pod 一个 “通行证”——容忍度(Tolerations)

6.4.1 容忍度的配置

容忍度定义在 Pod 配置中,声明 “我能容忍节点的某个污点”。例如,给 AI 任务的 Pod 加一个容忍度,匹配节点的 dedicated=gpu:NoSchedule 污点:

apiVersion: v1
kind: Pod
metadata:name: ai-training-pod
spec:containers:- name: ai-workerimage: ai-training-imagetolerations:  # 容忍度配置- key: "dedicated"       # 匹配污点的 keyoperator: "Equal"      # 精确匹配value: "gpu"           # 匹配污点的 valueeffect: "NoSchedule"   # 匹配污点的 effecttolerationSeconds: 30  # 仅对effect=NoExecute有效:被驱逐前的宽限期(秒)
1. key:要 “容忍” 的污点的名字

必须和节点上污点的key完全一致。比如节点污点是dedicated=gpu:NoSchedule,那么容忍度的key必须是dedicated

2. operator:匹配方式(关键!)

有两种匹配方式,决定了容忍度如何匹配污点:

  • operator: "Equal"精确匹配。需要容忍度的value和污点的value完全一致(比如污点是dedicated=gpu,容忍度value必须是gpu)。
  • operator: "Exists"只要存在就匹配。不关心污点的value是什么,只要节点有这个keyeffect的污点,就允许调度(此时value字段可以省略)。
3. value:污点的值

只有当operator: "Equal"时才需要填,且必须和节点污点的value完全一致。如果operator: "Exists",可以不写value

4. effect:要 “容忍” 的污点的排斥力度

必须和节点污点的effect完全一致(NoSchedule/PreferNoSchedule/NoExecute)。比如节点污点是NoSchedule,容忍度的effect也必须是NoSchedule

5. tolerationSeconds:宽限期(仅用于NoExecute

当节点污点是NoExecute(会驱逐没有容忍度的 Pod)时,这个字段表示:如果 Pod 有容忍度,会在多少秒后再被驱逐(给 Pod 留时间处理收尾工作)。默认不填的话,会立即驱逐。

6.4.2 实战示例:给 Pod 配置容忍度

假设节点node-gpu有污点dedicated=gpu:NoSchedule,配置两个 Pod 的容忍度,看看效果。

示例 1:用Equal精确匹配
# ai-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: ai-pod
spec:containers:- name: ai-workerimage: tensorflow/tensorflow  # 需要GPU的AI任务tolerations:- key: "dedicated"       # 匹配污点的keyoperator: "Equal"      # 精确匹配value: "gpu"           # 匹配污点的valueeffect: "NoSchedule"   # 匹配污点的effect

创建 Pod:kubectl apply -f ai-pod.yaml
结果:这个 Pod 会被正常调度到node-gpu节点(因为容忍度完全匹配污点)。

示例 2:用Exists简化匹配

如果节点污点的value可能变化(比如有时是gpu,有时是nvidia-gpu),但key始终是dedicated,可以用Exists匹配:

# ai-pod-simple.yaml
apiVersion: v1
kind: Pod
metadata:name: ai-pod-simple
spec:containers:- name: ai-workerimage: tensorflow/tensorflowtolerations:- key: "dedicated"       # 只看key是否存在operator: "Exists"     # 不关心valueeffect: "NoSchedule"   # 匹配effect# 这里省略了value,因为Exists不需要

创建 Pod 后,无论节点污点的valuegpu还是nvidia-gpu,这个 Pod 都能被调度到node-gpu上。

反例:没有容忍度的 Pod
# normal-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: normal-pod
spec:containers:- name: nginximage: nginx  # 普通应用,不需要GPU# 没有配置任何容忍度

创建 Pod 后,会发现它一直处于Pending状态(调度失败),因为它没有 “通行证”,被node-gpu的污点拒绝了。

6.4.3 容忍度的常见场景

  1. 访问专用节点:比如 GPU 节点、高性能计算节点,只有带容忍度的 Pod 才能使用。

  2. 节点维护时不被驱逐:如果节点加了NoExecute污点(用于维护),给需要持续运行的 Pod 配置容忍度,可以避免被驱逐。

  3. 灵活匹配动态污点:用operator: "Exists"可以匹配同一key下不同value的污点,减少配置复杂度。

6.4.4 总结:容忍度的核心逻辑

  • 容忍度是 Pod 的 “通行证”,用来匹配节点的污点;

  • 必须满足:keyeffect与污点完全一致;

  • operator: Equal需要value也一致,operator: Exists忽略value

  • 没有容忍度的 Pod,会被有对应污点的节点拒绝。

未完待续.............

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/96914.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/96914.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/96914.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用 Python 调用 Bright Data MCP Server:在 VS Code 中实现实时网页数据抓取

用 Python 调用 Bright Data MCP Server&#xff1a;在 VS Code 中实现实时网页数据抓取&#xff0c;本文介绍了Bright Data的Web MCP Server&#xff0c;这是一款能实现实时、结构化网页数据访问的API&#xff0c;适用于AI应用等场景。其支持静态与动态网页&#xff0c;前3个月…

SPSS绘制ROC曲线并计算灵敏度、特异度

SPSS绘制ROC曲线并计算灵敏度、特异度。 &#xff08;1&#xff09;绘制ROC曲线&#xff1a; 输入&#xff1a;预测值、受试者标签。 在SPSS中点击“分析”-“分类”-“ROC曲线” 变量输入&#xff1a;检验变量输入预测值&#xff0c;状态变量输入受试者标签&#xff0c;如果标…

Modbus协议原理与Go语言实现详解

目录 Modbus协议概述协议架构与通信模式Modbus数据模型Modbus协议帧格式功能码详解Go Modbus库完整实现高级应用示例调试与故障排除 Modbus协议概述 Modbus是一种串行通信协议&#xff0c;由Modicon公司&#xff08;现施耐德电气&#xff09;于1979年开发&#xff0c;用于PL…

下载CentOS 7——从阿里云上下载不同版本的 CentOS 7

没有废话&#xff0c;直接上干货。跟着图片教程&#xff0c;一步一步来就行。 想下载其它版本的&#xff0c;自己可以再选择其它的就行。 想省事的朋友可以直接点击: 1、下载页面链接 2、CentOS-7-x86_64-DVD-2207-02(4.4GB).iso

SpringBoot -原理篇

文章目录配置优先级Bean管理获取beanbean作用域第三方beanSpringBoot原理起步依赖自动配置自动配置原理方案源码跟踪原理分析 Conditional案例&#xff08;自定义starter&#xff09;案例&#xff08;自定义starter分析&#xff09;案例&#xff08;自定义starter实现&#xff…

JavaScript与jQuery:从入门到面试的完整指南

JavaScript与jQuery&#xff1a;从入门到面试的完整指南 第一部分&#xff1a;JavaScript基础 1.1 JavaScript简介 JavaScript是一种轻量级的解释型编程语言&#xff0c;主要用于Web开发&#xff0c;可以为网页添加交互功能。它是ECMAScript规范的一种实现。 // 第一个JavaScri…

解决:Ubuntu、Kylin、Rocky系统中root用户忘记密码

解决Linux系统中root用户忘记密码 Ubuntu2204 重启电脑&#xff0c;启动时&#xff0c;长按Shift键&#xff08;对于 BIOS 系统&#xff09;或 Esc 键&#xff08;对于 UEFI 系统&#xff09;进入GRUB菜单 步骤1&#xff1a;重启Ubuntu系统&#xff0c;长按Shift键进入Ubuntu…

ENVI系列教程(二)——自定义坐标系(北京 54、西安 80、2000 坐标系)

目录 1 概述 1.1 地理投影的基本原理 1.2 国内坐标系介绍 1.3 参数的获取 2 详细操作步骤 2.1 添加椭球体 2.2 添加基准面 2.3 定义坐标系 2.4 使用自定义坐标系 1 概述 1.1 地理投影的基本原理 常用到的地图坐标系有 2 种,即地理坐标系和投影坐标系。地理坐标系是…

一种基于因果干预的少样本学习的故障诊断模型

一、研究背景与问题 ​工业背景​:机械故障诊断对工业系统安全至关重要,但实际中故障样本稀少,难以训练传统深度学习模型。 ​现有问题​: 当前少样本学习(FSL)方法大多基于相关性而非因果关系建模,容易学习到伪相关特征,导致模型可解释性差、泛化能力弱。 跨组件故障诊…

机器视觉光源的尺寸该如何选型的方法

机器视觉光源的尺寸该如何选型的方法&#x1f3af;机器视觉光源的尺寸选型的方法&#x1f3af;一、选型案例&#x1f3af;二、照射方式&#x1f3af;三、镜头选择&#x1f3af;四、光源架构光源的工作距离与视野大小&#x1f3af;五、总结&#xff1a;光源选型 —— 机器视觉检…

HTML新属性

HTML5引入了许多新属性&#xff0c;旨在增强语义化、交互性和多媒体支持。以下是一些重要的新属性及其用途分类&#xff1a;语义化与结构属性data-*&#xff1a;自定义数据属性&#xff0c;允许开发者存储额外信息&#xff08;如data-id"123"&#xff09;。hidden&am…

从工地到链上:一个土建人的 Web3 转行经历

Web3 的风&#xff0c;终究还是吹到了土建行业。2017 年&#xff0c;土建专业&#xff08;给排水工程&#xff09;的刘正源偶然看到一则关于比特币的新闻&#xff0c;被它背后的经济模型与技术架构深深震撼。到了 2021 年&#xff0c;他在工地上再次听人提起区块链&#xff0c;…

20250914-03: Langchain概念:提示模板+少样本提示

20250914-03: Langchain概念&#xff1a;提示模板少样本提示 聊天模型 消息 提示 结构化输出 &#x1f3af; 学习目标 掌握如何“喂给模型正确的输入”并“解析出想要的输出”。 &#x1f517; 核心概念 ​聊天模型&#xff08;ChatModel&#xff09;​消息&#xff08;M…

【AI推理部署】Docker篇04—Docker自动构建镜像

Docker 自动构建镜像1. Dockfile 编写2. 镜像使用使用 Dockerfile 构建镜像 Dockerfile 其实就是把我们前面的一系列安装、配置命令写到一个文件中&#xff0c;通过 docker build 命令&#xff0c;一键完成镜像的构建。接下来&#xff0c;我们以 bitnami/pytorch:2.1.1 作为基础…

LeetCode 674.最长连续递增序列

给定一个未经排序的整数数组&#xff0c;找到最长且 连续递增的子序列&#xff0c;并返回该序列的长度。 连续递增的子序列 可以由两个下标 l 和 r&#xff08;l < r&#xff09;确定&#xff0c;如果对于每个 l < i < r&#xff0c;都有 nums[i] < nums[i 1] &am…

贪心算法java

贪心算法简介贪心算法是一种在每一步选择中都采取在当前状态下最优&#xff08;局部最优&#xff09;的选择&#xff0c;从而希望导致结果是全局最优的算法。贪心算法通常用于解决最优化问题&#xff0c;如最短路径、最小生成树、任务调度等。贪心算法的基本步骤问题分析&#…

【华为OD】解锁犯罪时间

【华为OD】解锁犯罪时间 题目描述 警察在侦破一个案件时&#xff0c;得到了线人给出的可能犯罪时间&#xff0c;形如"HH:MM"表示的时刻。根据警察和线人的约定&#xff0c;为了隐蔽&#xff0c;该时间是修改过的&#xff0c;解密规则为&#xff1a;利用当前出现过的数…

基于linux操作系统的mysql安装

一、检查自己的操作系统是否已经有存在的mysql 1.存在 2.不存在 二、基于操作系统不存在mysql,找官方yum源 网址&#xff1a; Index of /232905https://repo.mysql.com/ 网站打开是这样 看看自己的操作系统是哪个版本&#xff0c;再下载哪个版本&#xff0c;如果和我一样装…

如何用 Git Hook 和 CI 流水线为 FastAPI 项目保驾护航?

url: /posts/fc4ef84559e04693a620d0714cb30787/ title: 如何用Git Hook和CI流水线为FastAPI项目保驾护航? date: 2025-09-14T00:12:42+08:00 lastmod: 2025-09-14T00:12:42+08:00 author: cmdragon summary: 持续集成(CI)在FastAPI项目中通过频繁合并代码和自动验证,确保…

【微服务】SpringBoot 整合Kafka 项目实战操作详解

目录 一、前言 二、Kafka 介绍 2.1 什么是 Apache Kafka 2.2 Kafka 核心概念与架构 2.3 Kafka 为什么如此强大 2.4 Kafka 在微服务领域的应用场景 三、Docker 部署Kakfa服务 3.1 环境准备 3.2 Docker部署Kafka操作过程 3.2.1 创建docker网络 3.2.2 启动zookeeper容器…