一、高级调度

1、CronJob计划任务

编写cron-job-pd.yaml文件,创建CronJob对象,用于执行定时任务。

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cron-job-test
spec:
  concurrencyPolicy: Allow  # 并发策略:允许并发执行
  failedJobsHistoryLimit: 1    # 保留失败任务数:1个
  successfulJobsHistoryLimit: 3 # 保留成功任务数:3个
  suspend: false               # 是否挂起:否
  schedule: "* * * * *"     # 调度时间:每分钟执行一次
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: busybox
            image: busybox:1.28       # 使用镜像:busybox:1.28
            imagePullPolicy: IfNotPresent # 镜像拉取策略:如果不存在则拉取
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster # 执行命令:显示日期并打印信息
          restartPolicy: OnFailure        # 重启策略:任务失败时重启

2、初始化容器InitContainer

初始化容器(InitContainer)的作用是在真正的容器启动前,先启动InitContainer,执行一系列初始化操作,等到初始化操作完成之后再启动真实的容器。

InitContainer保证在EntryPoint之前执行,而postStart钩子则不能。与postStart适合执行简单命令不同,InitContainer作为一个独立的容器,能在其他基础容器环境下执行更复杂的初始化任务。

配置InitContainer的方式:在Pod的创建模板中,通过配置initContainers参数来定义InitContainer,包括镜像、拉取策略、执行命令和容器名称等,如下所示:

spec:
  initContainers:
  - name: init-test
	image: nginx
    imagePullPolicy: IfNotPresent
	command: ["sh", "-c", "echo 'inited;' >> ~/.init"]

3、污点和容忍度

节点亲和性 是 Pod 的一种属性,它使 Pod 被吸引到一类特定的节点 (这可能出于一种偏好,也可能是硬性要求)。 污点(Taint) 则相反——它使节点能够排斥一类特定的 Pod。

容忍度(Toleration) 是应用于 Pod 上的。容忍度允许调度器调度带有对应污点的 Pod。 容忍度允许调度但并不保证调度:作为其功能的一部分, 调度器也会评估其他参数。

污点和容忍度(Toleration)相互配合,可以用来避免 Pod 被分配到不合适的节点上。 每个节点上都可以应用一个或多个污点,这表示对于那些不能容忍这些污点的 Pod, 是不会被该节点接受的。污点可以确保Master节点只运行系统组件,不部署业务应用。

污点(Taint)和容忍度(Toleration)是Kubernetes中用于控制Pod调度的核心机制,它们相互配合可以确保Pod不会被分配到不合适的节点上。

污点(Taint)‌:节点级别的属性,用于标记节点排斥特定类型的Pod。每个污点包含三个部分:

  1. Key:污点的标识符
  2. Value:污点的值(可选)
  3. Effect:污点的效果,可以是以下三种之一:
  • NoSchedule:禁止调度新的Pod到该节点(已运行的Pod不受影响)。
  • PreferNoSchedule:尽量不调度新的Pod到该节点,但不强制。
  • NoExecute:禁止调度新的Pod到该节点,并且会驱逐已运行但不满足容忍度的Pod。

容忍度(Toleration)‌:Pod级别的配置,用于声明Pod可以容忍哪些污点。只有当Pod的容忍与节点的污点匹配时,Pod才能被调度到该节点上。容忍的定义包含以下字段:

  • Key:需要匹配的污点Key
  • Value:需要匹配的污点Value(可选)
  • Operator:匹配操作符(Equal完全匹配或Exists仅匹配Key)
  • Effect:需要匹配的污点Effect(可选)
  • TolerationSeconds:仅对NoExecute污点有效,表示Pod在被驱逐前可以继续运行的时间。

容忍中的操作符operator有两个取值:Equal和Exists,两者的区别:

  • Equal表示Pod容忍中的key和value需要与污点中的key和value都要匹配,否则Pod不能被分配到带有污点的节点上。
  • Exists表示只要Pod容忍中的key与污点中的key匹配,这个Pod就可以被分配到带有污点的节点上,容忍中可以不用配置value。

配置示例:

1. 节点污点设置

# 为节点node1设置污点

kubectl taint nodes node1 key1=value1:NoSchedule

# 移除污点

kubectl taint nodes node1 key1=value1:NoSchedule-

2. Pod容忍度配置(YAML)

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
  tolerations:
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoSchedule"
    tolerationSeconds: 3600  # 仅对NoExecute有效

或者使用Exists操作符:

tolerations:
- key: "key1"
  operator: "Exists"
  effect: "NoSchedule"

实际应用场景举例:

‌1. GPU节点专用‌:

# 标记GPU节点
kubectl taint nodes gpu-node01 accelerator=nvidia:NoSchedule


# AI训练Pod配置
tolerations:
- key: "accelerator"
  operator: "Equal"
  value: "nvidia"
  effect: "NoSchedule"

‌2. 核心服务隔离‌:

# 创建核心业务专用节点池
kubectl taint nodes core-node01 tier=core:NoExecute


# 支付服务Pod配置
tolerations:
- key: "tier"
  operator: "Equal"
  value: "core"
  effect: "NoExecute"

3. ‌节点维护模式‌:

# 进入维护模式(驱逐所有非系统Pod)
kubectl taint nodes node02 maintenance=true:NoExecute


# 关键守护进程配置容忍度
tolerations:
- key: "maintenance"
  operator: "Exists"
  effect: "NoExecute"
  tolerationSeconds: 86400  # 24小时宽限期

污点与节点亲和性的区别:

特性

污点与容忍度

节点亲和性

作用方向

节点排斥Pod

Pod吸引到节点

配置位置

节点设置污点,Pod设置容忍

Pod设置亲和性规则

强制程度

可设置硬性排斥(NoSchedule)或软性排斥(PreferNoSchedule)

可设置硬性要求(required)或软性偏好(preferred)

典型用途

节点专用、节点维护、资源隔离

硬件偏好、性能优化、拓扑分布

高级注意事项:

  1. ‌多污点与多容忍‌:一个节点可以有多个污点,一个Pod可以有多个容忍度。只有当Pod容忍了节点的所有污点时,才能被调度到该节点。
  2. ‌优先级‌:当同时使用节点亲和性和污点/容忍度时,调度器会先检查污点/容忍度,再检查节点亲和性。
  3. ‌手动指定节点‌:如果手动为Pod指定了.spec.nodeName,那么选节点操作会绕过调度器;这个Pod将会绑定到你指定的节点上,即使该节点上有NoSchedule的污点。
  4. ‌静态Pod‌:通过kubelet管理的静态Pod不受污点限制,可以运行在任何节点上。

污点和容忍使用示例:

给节点k8s-node2添加污点memory=low,污点效果是NoSchedule:禁止调度新的Pod到该节点(已运行的Pod不受影响)。

修改Deployment对象,给Pod template添加容忍memory=low,操作符operator: Equal,污点效果是NoSchedule。

或者操作符operator: Exists,只需要配置key: memory和污点效果是NoSchedule即可。

4、亲和力

亲和性(Affinity)和反亲和性(Anti-affinity)是Kubernetes提供的比nodeSelector更强大的Pod调度约束机制。主要优势包括:

  • 表达能力更强‌:支持基于集合的查询操作符(In、NotIn、Exists、DoesNotExist等),而nodeSelector只能精确匹配所有指定标签。
  • ‌规则灵活性‌:可以定义"软需求"(preferred)而非强制要求(required),当无法满足条件时仍允许调度。
  • ‌拓扑感知‌:不仅能基于节点标签,还能基于其他Pod的标签进行调度决策。

亲和性功能由两种类型的亲和性组成:

  • 节点亲和性:节点亲和性功能类似于 nodeSelector 字段,但它的表达能力更强,并且允许你指定软规则。
  • Pod间亲和性/反亲和性:Pod间亲和性/反亲和性允许你根据其他 Pod 的标签来约束 Pod。

节点亲和性是根据节点上的标签来约束Pod可以调度到哪些节点上,类似于nodeSelector。节点亲和性有两种实现方式:

requiredDuringSchedulingIgnoredDuringExecution:调度器只有在规则被满足的时候才能执行调度,这是硬性要求。此功能类似于 nodeSelector, 但其语法表达能力更强。

preferredDuringSchedulingIgnoredDuringExecution: 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod,这是软性要求。

Pod间亲和性表示:如果某个节点上已经运行了一个或多个满足规则的Pod,则满足规则的新Pod也应该运行在这个节点上。

Pod间反亲和性表示:如果某个节点上已经运行了一个或多个满足规则的Pod,则满足规则的新Pod不应该运行在这个节点上。

同样的,Pod间亲和性/反亲和性也有requiredDuringSchedulingIgnoredDuringExecution和preferredDuringSchedulingIgnoredDuringExecution两种实现方式。

示例1:节点亲和性使用示例

可以使用 Pod 规约中的 .spec.affinity.nodeAffinity 字段来设置节点亲和性。例如,下面的 Pod 规约:

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - antarctica-east1
            - antarctica-west1
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: registry.k8s.io/pause:2.0

在这一示例中,所应用的规则如下:

  • 节点必须包含一个键名为 topology.kubernetes.io/zone 的标签,并且该标签的取值必须为 antarctica-east1 或 antarctica-west1(需要事先给节点打标签)。
  • 节点最好具有一个键名为 another-node-label-key 且取值为 another-node-label-value 的标签。

可以使用 operator 字段来为 Kubernetes 设置在解释规则时要使用的逻辑操作符。例如,可以使用 In、NotIn、Exists、DoesNotExist、Gt 和 Lt 之一作为操作符。NotIn和DoesNotExist可用来实现节点反亲和性行为,也可以使用节点污点将Pod从特定节点上驱逐。

权重(weight)用于定义软性偏好(preferredDuringSchedulingIgnoredDuringExecution)‌规则的优先级,权重越大,该规则的优先级越高‌,但最终调度决策还受其他因素影响(如资源可用性、其他调度策略等)。

示例2:Pod间亲和性/反亲和性使用示例

要使用 Pod 间亲和性,可以使用 Pod 规约中的 .affinity.podAffinity 字段。对于 Pod 间反亲和性,可以使用 Pod 规约中的 .affinity.podAntiAffinity 字段。

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: topology.kubernetes.io/zone
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: topology.kubernetes.io/zone
  containers:
  - name: with-pod-affinity
    image: registry.k8s.io/pause:2.0

上面示例定义了一条 Pod 亲和性规则和一条 Pod 反亲和性规则。Pod 亲和性规则配置为 requiredDuringSchedulingIgnoredDuringExecution,Pod反亲和性配置为 preferredDuringSchedulingIgnoredDuringExecution。亲和性规则规定只有节点打上topologyKey属性值对应的标签,并且节点上的Pod已打上security=S1标签时,调度器才可以将示例Pod调度到此节点上,否则调度器不会将示例Pod调度到节点上。反亲和性规则规定如果节点打上topologyKey属性值对应的标签,并且节点上的Pod已打上security=S2标签,则调度器应尝试避免将新Pod调度到此节点上。

二、Helm包管理器

Helm是Kubernetes的包管理器,用于高效查找、分享和使用Kubernetes软件构件。其主要功能包括:

  • 管理chart‌:chart是Kubernetes应用程序的模板,Helm可以创建新chart,将其打包为tgz文件,并与chart仓库交互。
  • ‌安装与卸载‌:在Kubernetes集群中安装和卸载chart。
  • ‌发布管理‌:管理chart的发布周期。

Helm涉及三个核心概念:

  1. ‌chart‌:包含创建Kubernetes应用程序所需的一组信息。

Kubernetes应用的打包格式,包含预配置的Kubernetes资源模板(YAML文件)和默认配置。结构示例如下:

mychart/

├── Chart.yaml      # 元数据(名称、版本等)

├── values.yaml     # 默认配置值

├── templates/      # Kubernetes资源模板

│   ├── deployment.yaml

│   ├── service.yaml

│   └── _helpers.tpl  # 模板辅助函数

└── charts/         # 子chart依赖

创建Chart的命令与流程‌:

# 1. 生成chart骨架

helm create mychart

# 2. 编辑关键文件

# - Chart.yaml: 定义元数据(apiVersion/v2, name, version等)

# - values.yaml: 设置默认参数(如replicaCount: 1)

# - templates/*.yaml: 编写Kubernetes资源模板

# 3. 验证模板渲染(不实际部署)

helm template mychart

# 4. 打包chart(生成mychart-0.1.0.tgz)

helm package mychart

  1. ‌config‌:可合并到chart中的配置信息,用于定制应用。

通过values.yaml定义的参数,用于定制化chart部署。支持动态注入到模板中,实现环境差异化配置。

‌配置方式‌:

  • 静态配置‌:直接修改values.yaml文件
  • ‌动态覆盖‌:

# 命令行覆盖

helm install myapp ./mychart --set replicaCount=2

# 通过文件覆盖

helm install myapp ./mychart -f custom-values.yaml

  1. ‌release‌:特定配置下的chart运行实例。Chart与release的关系就像java中的类与对象实例的关系。

Chart在集群中的运行实例。同一chart可多次安装,每次生成独立的release(如dev-mysql和prod-mysql)。

‌部署与升级‌:

# 安装chart(生成release)

helm install myrelease ./mychart

# 查看release状态

helm status myrelease

# 升级release(修改配置后)

helm upgrade myrelease ./mychart --set image.tag=v2

# 回滚到历史版本

helm rollback myrelease 1

1、Helm的安装

安装Helm的步骤:

1. 下载helm压缩包并解压,官网下载地址:https://github.com/helm/helm/releases

wget https://get.helm.sh/helm-v3.2.3-linux-amd64.tar.gz

可以通过wget命令在线下载,或者打开官网地址手动下载之后上传到Linux服务器上。

2. 将解压后目录下的helm程序复制到/usr/local/bin/目录下,并通过helm version验证是否安装成功。

2、Helm的常用命令

‌类别‌

‌命令‌

‌功能说明‌

使用示例

‌Chart操作‌

helm create <chart>

创建新chart模板
<chart>: chart名称

helm create mychart
创建名为mychart的chart目录结构

helm package <chart>

打包chart为.tgz文件
--version: 指定版本号

helm package ./mychart --version 1.0.0
打包并指定版本

helm lint <chart>

检查chart语法错误
--strict: 严格模式

helm lint ./mychart --strict
严格检查chart模板

helm template <chart>

渲染模板但不部署
--values/-f: 指定values文件

helm template mychart -f prod-values.yaml
预览生产环境配置

‌Release管理‌

helm install <release> <chart>

部署chart
--set: 动态覆盖值
--dry-run: 模拟运行

helm install nginx bitnami/nginx --set replicaCount=2
设置副本数

helm upgrade <release> <chart>

升级release
--install: 不存在则安装

helm upgrade myapp ./mychart --set image.tag=v2
更新镜像版本

helm uninstall <release>

卸载release
--keep-history: 保留历史记录

helm uninstall myapp --keep-history
卸载但保留版本历史

helm rollback <release> <rev>

回滚到指定版本
<rev>: 历史版本号

helm rollback myapp 2
回滚到版本

helm list

列出release
-a: 显示所有(包括已删除)

helm list -a
显示完整release列表

helm status <release>

查看release状态
-o: 输出格式(json/yaml)

helm status myapp -o yaml
YAML格式输出状态

helm history <release>

查看版本历史
--max: 限制显示条目数

helm history myapp --max 5
显示最近5次变更

‌仓库操作‌

helm repo add <name> <url>

添加仓库
--username: 认证用户名

helm repo add bitnami https://charts.bitnami.com/bitnami
添加仓库

helm repo update

更新本地仓库索引
--fail-on-repo-update-fail: 更新失败时终止

helm repo update --fail-on-repo-update-fail
严格模式更新

helm repo remove <name>

移除仓库
<name>: 仓库名称

helm repo remove bitnami
移除指定仓库

helm repo list

列出已配置仓库
-o: 输出格式

helm repo list -o json
JSON格式输出仓库列表

‌实用工具‌

helm search repo <keyword>

搜索仓库中的chart
-l: 显示所有版本

helm search repo mysql -l
显示MySQL所有版本

helm pull <chart>

下载chart到本地
--untar: 解压文件

helm pull bitnami/nginx --untar
下载并解压

helm lint <chart>

检查chart语法错误

helm lint mychart

helm get manifest <release>

获取已部署资源清单
--revision: 指定版本

helm get manifest myapp --revision 3
获取版本3的YAML

helm plugin install <path>

安装插件
<path>: 插件路径或URL

helm plugin install https://example.com/helm-diff
安装diff插件

高级用法示例

‌1. 多环境部署‌:

helm install myapp ./mychart -f dev-values.yaml --set env=dev

使用文件覆盖默认配置并动态设置环境变量。

2. 依赖管理‌:

helm dependency update ./mychart

更新chart的子chart依赖。

3. 调试技巧‌:

helm install --dry-run --debug ./mychart

模拟安装并输出调试信息。

3、chart详解

Redis chart实践:

1. 修改Helm源,添加新仓库‌:

  • 添加Bitnami仓库:helm repo add bitnami https://charts.bitnami.com/bitnami
  • 添加阿里云仓库:helm repo add aliyun https://apphub.aliyuncs.com/stable
  • 添加Azure仓库:helm repo add azure http://mirror.azure.cn/kubernetes/charts

添加仓库之后,使用命令helm repo list来列出当前配置的Helm仓库。

2. 搜索chart

# 搜索redis chart

helm search repo redis

# 查看安装说明

helm show readme bitnami/redis

3. 修改配置安装

将Redis Chart拉取到本地并解压:

helm pull bitnami/redis

tar -zxvf redis-xxx.tgz

解压之后得到一个redis目录,这个redis目录就是chart,进入到redis目录,可以看到里面的文件与chart结构一致,包括Chart.yaml、charts、templates和values.yaml等。

修改配置‌:修改values.yaml中的参数,包括‌设置存储类‌为managed-nfs-storage(managed-nfs-storage是在前面讲解“PV与PVC”时创建的StorageClass),‌配置Redis密码‌,‌选择架构‌(standalone或replication),调整‌实例存储大小‌,以及设置‌对外暴露端口‌范围在30000-32767之间。

vim values.yaml

‌创建命名空间与安装‌:‌执行helm install <release> <chart> -n <namespace>命令进行安装

使用kubectl create namespace redis命令创建命名空间‌redis,在解压后的目录中运行helm install redis ./redis -n redis命令来安装Redis,这个命令中第一个redis是安装的服务名称,第二个redis是chart的名称,第三个redis是命名空间的名称。

4. 升级与回滚release

升级redis:执行helm upgrade <release> <chart> -n <namespace>命令进行升级。

回滚redis:执行helm rollback <release> <version> -n <namespace>命令回滚到指定版本。

查看历史版本:helm history <release> -n <namespace>

回滚到上一版本:helm rollback <release> -n <namespace>

5. 删除或卸载release

通过kubectl delete(或uninstall) <release> -n <namespace> 命令卸载release,release卸载之后不会自动删除PVC,如果需要删除PVC,需要手动删除,PVC被删除之后,PV也会被自动删除。PVC是属于命名空间级别的资源,PV是属于集群级别的资源。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐