Kubernetes从入门到精通(高级篇)04

目录

一、云原生储存及存储进阶

1、什么是StorageClass和CSI

2、什么是Rook

3、Rook核心架构

4、安装Rook

1)集群初始化

2)安装rook

3)安装ceph

4)安装ceph客户端工具

5)块存储

创建块存储的Storageclass

测试动态申请PV

创建有状态服务挂载pvc

测试动态申请pv

6)文件存储

创建文件存储的Stroageclass

测试动态申请pv

7)PVC扩容

文件存储扩容

块存储扩容

8)PVC克隆

文件存储克隆

块存储克隆

二、Helm

1、什么是helm

2、helm基础认知

3、安装helm

4、helm常用命令

仓库管理

chart搜索下载

安装应用

查看已部署的应用

升级和回滚

卸载应用

本地chart开发

测试渲染

5、自定义chart实例

1、创建前置环境配置文件

chart.yaml

values.yaml

[pv / pvc.yaml](#pv / pvc.yaml)

主从节点deployment

service

2、安装Release(redis)

3、测试实例

4、升级Release

5、回滚Release

6、卸载Release


一、云原生储存及存储进阶

现在的集群里,Pod 的数据默认存在节点本地磁盘:

  • Pod 删了、漂移到其他节点,数据就丢了
  • 多个 Pod 想共享数据做持久化,原生很难搞定

所以 K8s 引入了:

  • PersistentVolume(PV):集群里的 "持久化存储卷",相当于硬盘
  • PersistentVolumeClaim(PVC):Pod 申请使用 PV 的 "申请单"

但问题来了:PV 谁来创建?手动创建 PV 太麻烦,还得写死节点路径,无法动态分配。

这时候就需要 StorageClass + CSI 来解决。

1、什么是StorageClass和CSI

StorageClass 是 K8s 里的 "存储类型模板",用来自动创建 PV,实现存储动态供给。

关键作用:

1、动态创建PV(不用管理员手动创建 PV,用户只要在 PVC 里指定 storageClassName,集群会自动创建对应的 PV 并绑定。)

2、区分不用存储类型(fast:高性能 SSD 存储 slow:大容量 HDD 存储 nfs:共享存储)

3、定义回收策略,绑定模式(比如 PV 用完删除时,数据是直接删除还是保留,由 StorageClass 统一控制。)

CSI 是一套标准接口,让外部存储(NFS / 云盘 / 本地盘)能接入 K8s,提供持久化存储能力。

CSI的工作原理

  • 你在集群里部署 CSI 驱动(比如 Cephfs CSI 驱动)
  • CSI 驱动会监听集群里的 PVC 申请
  • 当 PVC 指定了对应 StorageClass,驱动就会:自动在存储服务器上创建卷,在 K8s 里创建对应的 PV,把 PV 绑定给 PVC,Pod 启动时自动挂载卷到容器里
组件 角色 一句话定位
CSI 驱动 干活的底层驱动 连接外部存储,执行创建 / 挂载 / 删除卷的操作
StorageClass 配置模板 告诉 CSI 驱动:用哪种存储、什么参数、怎么创建 PV

2、什么是Rook

​ Rook 允许 Ceph 存储使用 Kubernetes 原语在 Kubernetes 上运行。通过在 Kubernetes 集群中运行 Ceph,Kubernetes 应用程序可以挂载由 Rook 管理的块设备和文件系统,或者可以使用 S3/Swift API 进行对象存储。Rook 操作员会自动配置存储组件并监控集群,以确保存储保持可用和健康。

​ Rook 操作员是一个简单的容器,它具有引导和监视存储集群所需的一切。操作员将启动和监视Ceph 监视 pod、Ceph OSD 守护进程以提供 RADOS 存储,以及启动和管理其他 Ceph 守护进程。操作员通过初始化 pod 和运行服务所需的其他资源来管理池、对象存储 (S3/Swift) 和文件系统的 CRD。

​ 操作员将监控存储守护进程,以确保集群健康。必要时将启动 Ceph mons 或进行故障转移,并随着集群的增长或收缩进行其他调整。操作员还将监视 Ceph 自定义资源 (CR) 中指定的所需状态更改并应用更改。

​ Rook 会自动配置 Ceph-CSI 驱动程序以将存储安装到您的 pod。该rook/ceph镜像包含管理集群所需的所有工具。Rook 不在 Ceph 数据路径中。许多 Ceph 概念(如放置组和 Crush 地图)都是隐藏的,因此您不必担心它们。相反,Rook 为管理员创建了一种简化的用户体验,包括物理资源、池、卷、文件系统和存储桶。可以使用 Ceph 工具在需要时应用高级配置。

3、Rook核心架构

  1. Rook Operator

Rook 核心控制组件,以容器方式运行:

  • 自动初始化、拉起 Ceph 存储集群
  • 持续监控 Ceph 各类守护进程健康状态
  • 故障自愈、配置变更、版本升级全自动化
  1. Rook Agent
  • 以 DaemonSet 运行在每个 K8s 存储节点
  • 集成 FlexVolume/CSI 存储插件,对接 K8s 存储卷框架
  • 负责底层主机存储操作:磁盘格式化、卷挂载 / 卸载、网络存储设备接入
  1. Rook Discover
  • 自动探测每个节点上新增 / 已有裸磁盘、存储设备
  • 自动上报硬件信息到 Rook 对应 CRD
  • 节点新增磁盘后:Discover 感知 → 通知 Operator → Operator 调度 Agent 完成磁盘格式化、初始化并纳入 Ceph 集群作为 OSD 存储盘
  1. Rook Cluster
  • 通过 CRD 提供存储集群整体配置能力
  • 对外提供三类存储服务:块存储、对象存储、共享文件存储
  • 集群内部可划分多个 Pool 做资源隔离与配额管理

4、安装Rook

1)集群初始化

前置准备

  • 每个准备做存储的节点,必须要有空闲裸硬盘(不分区,不格式化,不挂载,空盘)
  • 所有节点时间必须同步
  • 集群网络互通,无防火墙拦截

这里使用的是TKE的kubernetes服务

主机名 节点角色 配置 数据盘 是否作为 OSD
k8s-master 平台托管控制节点 托管节点
172.17.16.167 存储工作节点 4C8G /dev/vdb
172.17.17.21 存储工作节点 4C8G /dev/vdb
172.17.16.243 存储工作节点 4C8G /dev/vdb

版本选择

官网:https://rook.io/

查看版本匹配k8s版本:https://rook.io/docs/rook/latest-release/Getting-Started/quickstart/

2)安装rook

复制代码
# 创建存放目录下载安装包
[root@VM-16-167-tencentos ~]# mkdir rook  && cd rook
[root@VM-16-167-tencentos ~]# wget https://github.com/rook/rook/archive/refs/tags/v1.19.5.tar.gz



# 解压安装包
[root@VM-16-167-tencentos rook]# tar -zxvf rook-1.19.5.tar.gz 
[root@VM-16-167-tencentos rook]# cd rook-1.19.5/deploy/examples/

# 创建CRD(给K8s 安装 Rook 的 专属 API)不装这个,后面所有资源都创建不了。
[root@VM-16-167-tencentos examples]# kubectl apply -f crds.yaml 

# 查看创建出来的crd
[root@VM-16-167-tencentos examples]# kubectl get crd | grep rook
cephblockpoolradosnamespaces.ceph.rook.io                2026-05-03T08:05:49Z
cephblockpools.ceph.rook.io                              2026-05-03T08:05:49Z
cephbucketnotifications.ceph.rook.io                     2026-05-03T08:05:49Z
cephbuckettopics.ceph.rook.io                            2026-05-03T08:05:49Z
cephclients.ceph.rook.io                                 2026-05-03T08:05:49Z
cephclusters.ceph.rook.io                                2026-05-03T08:05:49Z
cephcosidrivers.ceph.rook.io                             2026-05-03T08:05:50Z
cephfilesystemmirrors.ceph.rook.io                       2026-05-03T08:05:51Z
cephfilesystems.ceph.rook.io                             2026-05-03T08:05:51Z
cephfilesystemsubvolumegroups.ceph.rook.io               2026-05-03T08:05:51Z
cephnfses.ceph.rook.io                                   2026-05-03T08:05:51Z
cephnvmeofgateways.ceph.rook.io                          2026-05-03T08:05:52Z
cephobjectrealms.ceph.rook.io                            2026-05-03T08:05:53Z
cephobjectstores.ceph.rook.io                            2026-05-03T08:05:53Z
cephobjectstoreusers.ceph.rook.io                        2026-05-03T08:05:53Z
cephobjectzonegroups.ceph.rook.io                        2026-05-03T08:05:54Z
cephobjectzones.ceph.rook.io                             2026-05-03T08:05:54Z
cephrbdmirrors.ceph.rook.io                              2026-05-03T08:05:54Z

# 创建rook的权限(ServiceAccount + RBAC + NameSpace)
[root@VM-16-167-tencentos examples]# kubectl apply -f common.yaml

# 创建operator (是 Rook 的「总管 + 安装工」)
# 创建之前需要更改yaml文件中的一些配置
[root@VM-16-167-tencentos examples]# vim operator.yaml 

添加默认使用的镜像
ROOK_CSI_CEPH_IMAGE: "registry.cn-hangzhou.aliyuncs.com/rookcloud/cephcsi:v3.12.2"
ROOK_CSI_REGISTRAR_IMAGE: "registry.cn-hangzhou.aliyuncs.com/rookcloud/csi-node-driver-registrar:v2.11.1"
ROOK_CSI_RESIZER_IMAGE: "registry.cn-hangzhou.aliyuncs.com/rookcloud/csi-resizer:v1.11.1"
ROOK_CSI_PROVISIONER_IMAGE: "registry.cn-hangzhou.aliyuncs.com/rookcloud/csi-provisioner:v5.0.1"
ROOK_CSI_SNAPSHOTTER_IMAGE: "registry.cn-hangzhou.aliyuncs.com/rookcloud/csi-snapshotter:v8.0.1"
ROOK_CSI_ATTACHER_IMAGE: "registry.cn-hangzhou.aliyuncs.com/rookcloud/csi-attacher:v4.6.1"

# 修改使用的主镜像
622       containers:
623         - name: rook-ceph-operator
624           image: registry.cn-hangzhou.aliyuncs.com/rookcloud/ceph:v1.15.6
625           imagePullPolicy: IfNotPresent

复制代码
# 修改ROOK_ENABLE_DISCOVERY_DAEMON为"true"
= true:开启 Rook 自动磁盘发现守护进程
创建初期集群不需要(因为我们后面在 cluster.yaml 里手动指定了磁盘 / 节点)
后期扩容时:新节点插入新磁盘 → 自动发现、自动加入 Ceph 集群,不用再改配置

复制代码
# 关闭新版本的独立csi模式
ROOK_USE_CSI_OPERATOR: "false"

复制代码
# 创建资源
[root@VM-16-167-tencentos examples]# kubectl apply -f operator.yaml 


# 查看资源,必须所有pod都running及READY1/1才可以执行下一步
[root@VM-16-167-tencentos examples]# kubectl get pod -n rook-ceph 
NAME                                 READY   STATUS    RESTARTS   AGE
rook-ceph-operator-9f659b74f-fpn4n   1/1     Running   0          3m2s
rook-discover-52lzr                  1/1     Running   0          101s
rook-discover-hkmgq                  1/1     Running   0          101s
rook-discover-vxcvs                  1/1     Running   0          101s

说明:
rook-ceph-operator :Ceph 集群大管家 / 总指挥
rook-discover(每台节点都一个):全集群磁盘扫描探头

3)安装ceph

cluster.yaml是用于部署Rook集群的YAML文件,它定义了Rook集群的配置和部署方式。

包含的资源:Cluster、ClusterRole、ClusterRoleBinding、Service、PodDisruptionBudget、DaemonSet、Secret(可选)

功能和特点:

  • Cluster:该部分定义了Rook集群的配置,包括Ceph存储的版本、Monitors的数量、池的配置、网络设置等。
  • ClusterRole:该部分定义了Rook集群所需要的权限,以便能够执行与Ceph存储相关的操作,如创建OSD等。
  • ClusterRoleBinding:该部分将ClusterRole和ServiceAccount绑定在一起,以授予Rook集群所需的权限。
  • Service:该部分定义了用于访问Rook集群的Service,包括Ceph Monitors和MGR的服务。
  • PodDisruptionBudget:该部分定义了Pod的干扰预算,确保在维护和升级期间仍然能够保持足够的可用性。
  • DaemonSet:该部分定义了在每个节点上运行的Rook组件,如Ceph Monitors、OSDs和MGRs。
  • Secret(可选):该部分可以包含用于访问Ceph集群的认证密钥。

cluster.yaml文件提供了一个可用的示例配置,您可以根据需要进行修改和自定义。

复制代码
[root@VM-16-167-tencentos examples]# vim cluster.yaml 
# 修改镜像
image: registry.cn-hangzhou.aliyuncs.com/rookcloud/ceph:v18.2.4
imagePullPolicy: IfNotPresent

复制代码
# 修改skipUpgradeChecks: false为true
说明:升级时是否跳过前置健康检查
当你升级 Ceph 版本时(比如换个镜像版本),Rook 会先做这些检查:
集群状态是否健康(ceph status 是 HEALTH_OK)
PG 状态是否正常(没有 unclean/peering 状态的 PG)
OSD、MON 等组件是否全在线

如果 skipUpgradeChecks: false(默认):
升级前必须所有检查都通过
集群不健康会直接阻止升级,避免数据风险

如果改成 true:
跳过这些健康检查,直接开始升级
风险很高,不建议在生产环境开启,仅用于特殊紧急场景
复制代码
# 关闭 SSL/TLS 加密访问 Dashboard
ssl: fals
复制代码
# 关闭节点自动发现开关
# 含义:是否让 Rook 自动在集群里的所有节点上部署 Ceph 组件(OSD、MON 等)
# 当前值 true 表示:只要是 K8s 节点,都会被纳入候选,Rook 会尝试在上面部署服务
useAllNodes: false


# 关闭磁盘自动发现开关
# 含义:是否让 Rook 自动使用节点上的所有裸盘作为 Ceph OSD 存储
# 当前值 true 表示:节点上所有未分区、未挂载的裸盘,都会被 Rook 扫描并尝试创建 OSD

useAllDevices: false

复制代码
# allowMultiplePerNode: false修改true
说明:
我们现在处于TKE上得K8S,标签名中得hostname都是IP地址,K8S调度里非常容易识别失败!,所有要改成True,这样反亲和就会失效

只要hostname不是IP地址,能分清就不需要更改
复制代码
# 添加ceph安装节点和磁盘名字
    nodes:
      - name: "172.17.16.167"
        devices:
          - name: "vdb"
      - name: "172.17.17.21"
        devices:
          - name: "vdb"
      - name: "172.17.16.243"
        devices:
          - name: "vdb"

# 注意这里的name是node节点名字
[root@VM-16-167-tencentos examples]# kubectl get nodes
NAME            STATUS   ROLES    AGE   VERSION
172.17.16.167   Ready    <none>   29m   v1.34.1-tke.4
172.17.16.243   Ready    <none>   29m   v1.34.1-tke.4
172.17.17.21    Ready    <none>   29m   v1.34.1-tke.4
就是这里的名字

复制代码
# 创建资源
[root@VM-16-167-tencentos examples]# kubectl apply -f cluster.yaml 

# 查看资源
[root@VM-16-167-tencentos examples]# kubectl get pod -n rook-ceph 
NAME                                                      READY   STATUS      RESTARTS   AGE
csi-cephfsplugin-bmg7t                                    3/3     Running     0          2m17s
csi-cephfsplugin-cpwk2                                    3/3     Running     0          2m17s
csi-cephfsplugin-h4flp                                    3/3     Running     0          2m16s
csi-cephfsplugin-provisioner-85bc477bd7-djtxm             6/6     Running     0          2m17s
csi-cephfsplugin-provisioner-85bc477bd7-gnccx             6/6     Running     0          2m16s
csi-rbdplugin-ckd59                                       3/3     Running     0          2m17s
csi-rbdplugin-hq6s8                                       3/3     Running     0          2m17s
csi-rbdplugin-provisioner-7cf84d4f9f-kbqfx                6/6     Running     0          2m17s
csi-rbdplugin-provisioner-7cf84d4f9f-nmch9                6/6     Running     0          2m17s
csi-rbdplugin-rcqxv                                       3/3     Running     0          2m17s
rook-ceph-crashcollector-172.17.16.167-64d9756974-6hh56   1/1     Running     0          53s
rook-ceph-crashcollector-172.17.16.243-65957f598c-5tnb9   1/1     Running     0          62s
rook-ceph-crashcollector-172.17.17.21-6f95c85cd4-h5w64    1/1     Running     0          51s
rook-ceph-exporter-172.17.16.167-657c4db5fb-xqfx7         1/1     Running     0          50s
rook-ceph-exporter-172.17.16.243-5679c594d9-xknpg         1/1     Running     0          62s
rook-ceph-exporter-172.17.17.21-7ffbbfbf78-jfjfx          1/1     Running     0          47s
rook-ceph-mgr-a-7fd648b999-scckb                          3/3     Running     0          82s
rook-ceph-mgr-b-668cf49488-kcthp                          3/3     Running     0          81s
rook-ceph-mon-a-5cdd448c8d-hdwml                          2/2     Running     0          2m5s
rook-ceph-mon-b-67fc67fd75-mwb5w                          2/2     Running     0          102s
rook-ceph-mon-c-7f6ccccdd5-g826b                          2/2     Running     0          92s
rook-ceph-operator-9f659b74f-fpn4n                        1/1     Running     0          21m
rook-ceph-osd-0-55799b548d-8rnnc                          2/2     Running     0          54s
rook-ceph-osd-1-856974c8c5-s4b8g                          2/2     Running     0          53s
rook-ceph-osd-2-6c75bb476c-hkmmg                          2/2     Running     0          53s
rook-ceph-osd-prepare-172.17.16.167-lcggw                 0/1     Completed   0          60s
rook-ceph-osd-prepare-172.17.16.243-9sng2                 0/1     Completed   0          59s
rook-ceph-osd-prepare-172.17.17.21-782bl                  0/1     Completed   0          59s
rook-discover-52lzr                                       1/1     Running     0          19m
rook-discover-hkmgq                                       1/1     Running     0          19m
rook-discover-vxcvs                                       1/1     Running     0          19m

4)安装ceph客户端工具

安装此工具会可以使用ceph相关命令

复制代码
# 修改toolbox.yaml文件
[root@VM-16-167-tencentos examples]# vim toolbox.yaml

# 修改镜像地址
registry.cn-hangzhou.aliyuncs.com/rookcloud/ceph:v18.2.4

# apply
[root@VM-16-167-tencentos examples]# kubectl apply -f toolbox.yaml 

# 查看工具pod
[root@VM-16-167-tencentos examples]# kubectl get po -n rook-ceph -l app=rook-ceph-tools
NAME                               READY   STATUS    RESTARTS   AGE
rook-ceph-tools-69997987f6-5kjq4   1/1     Running   0          14s

# 进入工具pod检查
[root@VM-16-167-tencentos examples]# kubectl exec -it rook-ceph-tools-69997987f6-5kjq4 -n rook-ceph -- bash

# 查看ceph集群状态
bash-5.1$ ceph status
  cluster:
    id:     8e60842b-2ea4-4e20-ba5a-35340d7e4a90
    health: HEALTH_OK
 
  services:
    mon: 3 daemons, quorum a,b,c (age 20m)
    mgr: a(active, since 19m), standbys: b
    osd: 3 osds: 3 up (since 19m), 3 in (since 20m)
 
  data:
    pools:   1 pools, 1 pgs
    objects: 2 objects, 449 KiB
    usage:   80 MiB used, 150 GiB / 150 GiB avail
    pgs:     1 active+clean

# 查看osd状态 
bash-5.1$ ceph osd status
ID  HOST            USED  AVAIL  WR OPS  WR DATA  RD OPS  RD DATA  STATE      
 0  172.17.16.167  26.7M  49.9G      0        0       0        0   exists,up  
 1  172.17.17.21   26.7M  49.9G      0        0       0        0   exists,up  
 2  172.17.16.243  26.7M  49.9G      0        0       0        0   exists,up  

# 查看ceph集群空间
bash-5.1$ ceph df
--- RAW STORAGE ---
CLASS     SIZE    AVAIL    USED  RAW USED  %RAW USED
hdd    150 GiB  150 GiB  80 MiB    80 MiB       0.05
TOTAL  150 GiB  150 GiB  80 MiB    80 MiB       0.05
 
--- POOLS ---
POOL  ID  PGS   STORED  OBJECTS     USED  %USED  MAX AVAIL
.mgr   1    1  449 KiB        2  1.3 MiB      0     47 GiB

# 查看svc
# 由于新版的rook-ceph-mgr-dashboard不支持修改svc的type,就算修改成nodeport,系统一会自动修改为clusterip类型,所以要重新创建一个svc的yaml文件
[root@VM-16-167-tencentos examples]# kubectl get svc -n rook-ceph 
NAME                      TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)             AGE
rook-ceph-exporter        ClusterIP   192.168.1.45      <none>        9926/TCP            22m
rook-ceph-mgr             ClusterIP   192.168.122.32    <none>        9283/TCP            22m
rook-ceph-mgr-dashboard   ClusterIP   192.168.124.151   <none>        7000/TCP            22m
rook-ceph-mon-a           ClusterIP   192.168.26.127    <none>        6789/TCP,3300/TCP   23m
rook-ceph-mon-b           ClusterIP   192.168.30.23     <none>        6789/TCP,3300/TCP   22m
rook-ceph-mon-c           ClusterIP   192.168.1.37      <none>        6789/TCP,3300/TCP   22m

# 创建nodeport的svc
[root@VM-16-167-tencentos examples]# kubectl apply -f dashboard-external-http.yaml

# 查看
[root@VM-16-167-tencentos examples]# kubectl get svc -n rook-ceph 
NAME                                    TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)             AGE
rook-ceph-exporter                      ClusterIP   192.168.1.45      <none>        9926/TCP            25m
rook-ceph-mgr                           ClusterIP   192.168.122.32    <none>        9283/TCP            25m
rook-ceph-mgr-dashboard                 ClusterIP   192.168.124.151   <none>        7000/TCP            25m
rook-ceph-mgr-dashboard-external-http   NodePort    192.168.85.140    <none>        7000:32015/TCP      3s
rook-ceph-mon-a                         ClusterIP   192.168.26.127    <none>        6789/TCP,3300/TCP   25m
rook-ceph-mon-b                         ClusterIP   192.168.30.23     <none>        6789/TCP,3300/TCP   25m
rook-ceph-mon-c                         ClusterIP   192.168.1.37      <none>        6789/TCP,3300/TCP   25m

访问我们的公网ip + nodeport的端口

账号:admin

密码:kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{.data.password}" | base64 --decode && echo

5)块存储

块存储只针对有状态的服务,且容器需要单独的存储,数据不需要共享,例如redis集群,mysql集群等等,集群中的所有容器都需要挂载一款独有的块存储。

创建块存储的Storageclass
复制代码
# 查看ceph提供的存储驱动
[root@VM-16-167-tencentos ~]# kubectl get csidriver
NAME                            ATTACHREQUIRED   PODINFOONMOUNT   STORAGECAPACITY   TOKENREQUESTS   REQUIRESREPUBLISH   MODES        AGE
rook-ceph.cephfs.csi.ceph.com   true             false            false             <unset>         false               Persistent   34m
rook-ceph.rbd.csi.ceph.com      true             false            false             <unset>         false               Persistent   34m

# 创建storageclass动态存储
[root@VM-16-167-tencentos rbd]# kubectl apply -f storageclass.yaml 

StorageClass文件说明


# ==============================================
# Ceph RBD 块存储池(3副本,生产级高可用配置)
# ==============================================
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: replicapool             # 存储池名称,SC 会引用它
  namespace: rook-ceph          # 必须与 Rook 集群命名空间一致
spec:
  failureDomain: host           # 副本打散级别:host = 跨节点分散,保证高可用
  replicated:
    size: 3                     # 三副本,数据安全,丢失1个节点不影响业务
    requireSafeReplicaSize: true # 强制安全副本数,禁止单副本导致数据丢失

---

# ==============================================
# Ceph RBD 块存储 StorageClass
# 用于 K8s 动态供给 PV(块存储最常用)
# ==============================================
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-ceph-block         # SC 名称,PVC 必须填写这个名字
provisioner: rook-ceph.rbd.csi.ceph.com  # RBD CSI 驱动名称(固定)
parameters:
  clusterID: rook-ceph          # Ceph 集群所在命名空间(固定)
  pool: replicapool              # 绑定上面创建的 RBD 存储池
  imageFormat: "2"               # RBD 镜像格式,v2 是标准格式
  imageFeatures: layering        # RBD 特性,兼容所有内核,最稳定

  # ========================
  # CSI 密钥配置(自动生成,无需修改)
  # ========================
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
  csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
  csi.storage.k8s.io/controller-publish-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/controller-publish-secret-namespace: rook-ceph
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
  csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph

  csi.storage.k8s.io/fstype: ext4  # 磁盘格式:ext4 最稳定,推荐生产使用

allowVolumeExpansion: true     # 允许存储在线扩容(生产必备)
reclaimPolicy: Delete           # PVC 删除后,Ceph 中的块设备自动清理
volumeBindingMode: Immediate    # 立即绑定 PV,无需等待 Pod 启动

# 查看StorageClass(没有命名空间隔离性)
[root@VM-16-167-tencentos rbd]# kubectl  get sc
NAME              PROVISIONER                  RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
cbs (default)     com.tencent.cloud.csi.cbs    Delete          Immediate           false                  86m
rook-ceph-block   rook-ceph.rbd.csi.ceph.com   Delete          Immediate           true                   46s

cbs (default)腾讯云自带的云硬盘 SC

说明:

application_metadata: rbd代表这个池已经被 Ceph 标记为 RBD(块存储)专用,这是 CSI 驱动能识别并创建卷的前提条件。

crush_rule: replicapool绑定了我们在 CephBlockPool 里配置的 CRUSH 规则,副本会按 failureDomain: host 策略跨节点分布,保证高可用。

create_time: 2026-05-03T09:12:50.056316+0000存储池创建时间,证明它是刚被我们的 CephBlockPool 资源创建的。

其他缓存相关参数(cache_*)当前都是默认值,说明我们没有配置缓存层,使用的是基础三副本策略,稳定可靠,适合生产环境使用。

测试动态申请PV
复制代码
# 创建工作目录
[root@VM-16-167-tencentos ~]# mkdir storageClass && cd storageClass

# 创建pvc文件
[root@VM-16-167-tencentos storageClass]# vim block-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app: wordpress
spec:
  storageClassName: rook-ceph-block # 块存储CSI名称
  accessModes:
    - ReadWriteOnce # 访问模式
  resources:
    requests:
      storage: 10Gi # 请求容量

说明:
块存储只能使用ReadWriteOnce,Ceph RBD 是块设备,就像服务器里的一块物理硬盘,有一个核心限制:
同一块硬盘,不能同时被多台服务器挂载并读写,否则会出现数据错乱、文件系统损坏。
所以 RBD 块存储天生只支持 ReadWriteOnce,这也是数据库等单实例业务最常用的模式

# 创建pvc 并查看是否自动申请pv
[root@VM-16-167-tencentos storageClass]# kubectl apply -f block-pvc.yaml 


# 查看pv和pvc
[root@VM-16-167-tencentos storageClass]# kubectl get pv,pvc 
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS      VOLUMEATTRIBUTESCLASS   REASON   AGE
persistentvolume/pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e   10Gi       RWO            Delete           Bound    default/mysql-pv-claim   rook-ceph-block   <unset>                          10s

NAME                                   STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
persistentvolumeclaim/mysql-pv-claim   Bound    pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e   10Gi       RWO            rook-ceph-block   <unset>                 10s

# 查看pvc的绑定情况
[root@VM-16-167-tencentos storageClass]# kubectl describe pvc mysql-pv-claim 
Name:          mysql-pv-claim
Namespace:     default
StorageClass:  rook-ceph-block
Status:        Bound
Volume:        pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e  # PV
Labels:        app=wordpress
Annotations:   pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
               volume.beta.kubernetes.io/storage-provisioner: rook-ceph.rbd.csi.ceph.com
               volume.kubernetes.io/storage-provisioner: rook-ceph.rbd.csi.ceph.com
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      10Gi
Access Modes:  RWO
VolumeMode:    Filesystem
Used By:       <none>

# 查看ceph和pv的ID对应关系
[root@VM-16-167-tencentos storageClass]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS      VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e   10Gi       RWO            Delete           Bound    default/mysql-pv-claim   rook-ceph-block   <unset>                          2m40s
[root@VM-16-167-tencentos storageClass]# kubectl get pv pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e -o yaml
.....
 volumeHandle: 0001-0009-rook-ceph-0000000000000002-7f13570f-016c-4ea5-88b6-77294ca932b3

这是 Ceph 块存储(RBD)的 唯一卷 ID(UUID)K8s 和 Ceph 之间靠它识别你这块 10GiB 存储。

创建有状态服务挂载pvc

​ StatefulSet是部署有状态的服务,一般情况是以集群的形式出现,故无法给其中的每一个副本单独绑定一个pvc,所以k8s则出现volumeClaimTemplates的概念。

复制代码
[root@VM-16-167-tencentos storageClass]# vim mysql-sts.yaml
# ----------------------------------------------
# MySQL StatefulSet 部署文件
# 命名空间:tcloud
# 存储类型:Ceph RBD 块存储(rook-ceph-block)
# ----------------------------------------------

# Headless Service(有状态应用必须使用)
# 作用:为 MySQL Pod 提供稳定的 DNS 域名访问
apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: tcloud       # 资源所属命名空间
  labels:
    app: mysql
spec:
  ports:
  - port: 3306            # MySQL 默认服务端口
    name: mysql
  clusterIP: None         # Headless Service 固定配置
  selector:
    app: mysql            # 关联标签匹配的 Pod

---

# StatefulSet:用于部署 MySQL 这类有状态应用
# 特点:Pod 有序创建、固定名称、独立存储、稳定网络
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: tcloud       # 资源所属命名空间
spec:
  serviceName: "mysql"    # 绑定 Headless Service
  replicas: 3             # 3 副本实例
  selector:
    matchLabels:
      app: mysql

  # Pod 模板定义
  template:
    metadata:
      labels:
        app: mysql
    spec:
      terminationGracePeriodSeconds: 10  # 优雅停止等待时间
      containers:
      - name: mysql
        image: mysql:8.0
        ports:
        - containerPort: 3306
          name: mysql

        # MySQL  root 密码(环境变量配置)
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"

        # 数据盘挂载
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql

  # ------------------------------
  # 存储申请模板(自动创建 PVC)
  # 每个 MySQL Pod 都会独立创建一块存储
  # 使用 Ceph 块存储:rook-ceph-block
  # ------------------------------
  volumeClaimTemplates:
  - metadata:
      name: mysql-data
    spec:
      accessModes:
        - ReadWriteOnce     # 块存储仅支持单节点读写
      storageClassName: rook-ceph-block  # Ceph 块存储类(全局可用)
      resources:
        requests:
          storage: 5Gi     # 每个实例分配 5GB 存储空间

# apply
[root@VM-16-167-tencentos storageClass]# kubectl create ns tcloud
[root@VM-16-167-tencentos storageClass]# kubectl apply -f mysql-sts.yaml 


# 查看pvc
[root@VM-16-167-tencentos storageClass]# kubectl get pvc -n tcloud 
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
mysql-data-mysql-0   Bound    pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   5Gi        RWO            rook-ceph-block   <unset>                 11s
mysql-data-mysql-1   Bound    pvc-70d3b8a1-fb60-4c7b-a104-b29d74314b1d   5Gi        RWO            rook-ceph-block   <unset>                 9s
mysql-data-mysql-2   Bound    pvc-159cfe3a-8aca-4039-99e6-ddca664d5226   5Gi        RWO            rook-ceph-block   <unset>                 1s


# 查看pv
[root@VM-16-167-tencentos storageClass]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                       STORAGECLASS      VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-159cfe3a-8aca-4039-99e6-ddca664d5226   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-2   rook-ceph-block   <unset>                          11s
pvc-70d3b8a1-fb60-4c7b-a104-b29d74314b1d   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-1   rook-ceph-block   <unset>                          18s
pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-0   rook-ceph-block   <unset>                          21s
pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e   10Gi       RWO            Delete           Bound    default/mysql-pv-claim      rook-ceph-block   <unset>                          20m
测试动态申请pv
复制代码
# 查看pod
[root@VM-16-167-tencentos storageClass]# kubectl get pod -n tcloud 
NAME      READY   STATUS    RESTARTS   AGE
mysql-0   1/1     Running   0          64s
mysql-1   1/1     Running   0          61s
mysql-2   1/1     Running   0          54s

# 进入pod 添加测试数据
[root@VM-16-167-tencentos storageClass]# kubectl exec -it mysql-0 -n tcloud -- mysql -uroot -p123456

mysql> create database test_ceph;
Query OK, 1 row affected (0.02 sec)

mysql> use test_ceph;
Database changed
mysql> create table t_user(id int);
Query OK, 0 rows affected (0.07 sec)

mysql> insert into t_user values(100);
Query OK, 1 row affected (0.02 sec)

mysql> select * from t_user;
+------+
| id   |
+------+
|  100 |
+------+
1 row in set (0.00 sec)

# 删除pod
[root@VM-16-167-tencentos storageClass]# kubectl delete pod mysql-0 -n tcloud


# 等待pod重新running
[root@VM-16-167-tencentos storageClass]# kubectl exec -it mysql-0 -n tcloud -- mysql -uroot -p123456


# 查询数据
mysql> use test_ceph;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from t_user;
+------+
| id   |
+------+
|  100 |
+------+
1 row in set (0.00 sec)

6)文件存储

​ 用于多个pod共享一个文件,例如nginx,tomcat等等

复制代码
[root@VM-16-167-tencentos storageClass]# cd /root/rook/rook-1.19.5/deploy/examples/
[root@VM-16-167-tencentos examples]# kubectl apply -f filesystem.yaml 

# 查看pod
[root@VM-16-167-tencentos examples]# kubectl -n rook-ceph get pod -l app=rook-ceph-mds
NAME                                    READY   STATUS    RESTARTS   AGE
rook-ceph-mds-myfs-a-fc895576c-p77mg    2/2     Running   0          12s
rook-ceph-mds-myfs-b-55b79dcb5c-8dj8c   2/2     Running   0          11s
创建文件存储的Stroageclass
复制代码
[root@VM-16-167-tencentos examples]# cd csi/cephfs/
[root@VM-16-167-tencentos cephfs]# kubectl apply -f storageclass.yaml 

文件说明

# ==============================================
# Rook CephFS StorageClass 配置文件
# 作用:提供 Kubernetes 共享文件存储(ReadWriteMany 多节点读写)
# ==============================================

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-cephfs  # StorageClass 名称,PVC 中直接引用

# 存储供应者:CephFS CSI 驱动
provisioner: rook-ceph.cephfs.csi.ceph.com

parameters:
  # Rook Ceph 集群所在命名空间
  clusterID: rook-ceph

  # CephFS 文件系统名称(必须与已创建的 fsName 一致)
  fsName: myfs

  # CephFS 数据存储池
  pool: myfs-replicated

  # CSI 插件使用的认证密钥(Rook 自动生成)
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner
  csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
  csi.storage.k8s.io/controller-expand-secret-name: rook-csi-cephfs-provisioner
  csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
  csi.storage.k8s.io/controller-publish-secret-name: rook-csi-cephfs-provisioner
  csi.storage.k8s.io/controller-publish-secret-namespace: rook-ceph
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node
  csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph

# 回收策略:删除 PVC 时自动删除存储数据
reclaimPolicy: Delete

# 允许存储在线扩容
allowVolumeExpansion: true

# 查看sc
[root@VM-16-167-tencentos cephfs]# kubectl get sc
NAME              PROVISIONER                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
cbs (default)     com.tencent.cloud.csi.cbs       Delete          Immediate           false                  128m
rook-ceph-block   rook-ceph.rbd.csi.ceph.com      Delete          Immediate           true                   43m
rook-cephfs       rook-ceph.cephfs.csi.ceph.com   Delete          Immediate           true                   45s
测试动态申请pv
复制代码
[root@VM-16-167-tencentos storageClass]# vim nginx-ceph.yaml
# Nginx + CephFS 共享存储测试
# 作用:3 副本 Nginx 共享同一个存储(ReadWriteMany)
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: tcloud
  labels:
    app: nginx
spec:
  type: ClusterIP
  ports:
  - port: 80
    name: web
  selector:
    app: nginx

---
# CephFS 共享存储 PVC
# 支持多节点同时读写(RWX)
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nginx-share-pvc
  namespace: tcloud
spec:
  storageClassName: rook-cephfs   # 使用 CephFS 文件存储
  accessModes:
  - ReadWriteMany                # 多节点共享读写
  resources:
    requests:
      storage: 1Gi                # 申请 1GB 共享空间

---
# Nginx 多副本 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: tcloud
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web
        # 挂载共享存储到 Nginx 网页目录
        volumeMounts:
        - name: web-root
          mountPath: /usr/share/nginx/html

      # 引用 CephFS 共享 PVC
      volumes:
      - name: web-root
        persistentVolumeClaim:
          claimName: nginx-share-pvc

# apply
[root@VM-16-167-tencentos storageClass]# kubectl apply -f nginx-ceph.yaml 

# 查看pvc和pv
[root@VM-16-167-tencentos storageClass]# kubectl get pvc -n tcloud 
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
mysql-data-mysql-0   Bound    pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   5Gi        RWO            rook-ceph-block   <unset>                 16m
mysql-data-mysql-1   Bound    pvc-70d3b8a1-fb60-4c7b-a104-b29d74314b1d   5Gi        RWO            rook-ceph-block   <unset>                 16m
mysql-data-mysql-2   Bound    pvc-159cfe3a-8aca-4039-99e6-ddca664d5226   5Gi        RWO            rook-ceph-block   <unset>                 16m
nginx-share-pvc      Bound    pvc-a83b1ee0-15ae-4168-95a0-4378396bbf87   1Gi        RWX            rook-cephfs       <unset>                 16s



[root@VM-16-167-tencentos storageClass]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                       STORAGECLASS      VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-159cfe3a-8aca-4039-99e6-ddca664d5226   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-2   rook-ceph-block   <unset>                          17m
pvc-70d3b8a1-fb60-4c7b-a104-b29d74314b1d   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-1   rook-ceph-block   <unset>                          17m
pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-0   rook-ceph-block   <unset>                          17m
pvc-a83b1ee0-15ae-4168-95a0-4378396bbf87   1Gi        RWX            Delete           Bound    tcloud/nginx-share-pvc      rook-cephfs       <unset>                          31s
pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e   10Gi       RWO            Delete           Bound    default/mysql-pv-claim      rook-ceph-block   <unset>                          37m

# 查看pod
[root@VM-16-167-tencentos storageClass]# kubectl get pod -n tcloud 
NAME                    READY   STATUS    RESTARTS   AGE
mysql-0                 1/1     Running   0          15m
mysql-1                 1/1     Running   0          17m
mysql-2                 1/1     Running   0          17m
nginx-8b6bcb6c6-4kdp9   1/1     Running   0          69s
nginx-8b6bcb6c6-h8sdq   1/1     Running   0          69s
nginx-8b6bcb6c6-hpwrf   1/1     Running   0          69s


# 进入pod添加测试页面
[root@VM-16-167-tencentos storageClass]# kubectl exec -it nginx-8b6bcb6c6-4kdp9 -n tcloud -- bash
root@nginx-8b6bcb6c6-4kdp9:/# echo 'Hello CephFS' > /usr/share/nginx/html/index.html


# 进入别的pod看index.html文件内容
[root@VM-16-167-tencentos storageClass]# kubectl exec -it nginx-8b6bcb6c6-h8sdq -n tcloud -- bash
root@nginx-8b6bcb6c6-h8sdq:/# cat /usr/share/nginx/html/index.html 
Hello CephFS


# 删除pod等重建running看数据是否还存在
[root@VM-16-167-tencentos storageClass]# kubectl delete pod nginx-8b6bcb6c6-4kdp9 -n tcloud 

[root@VM-16-167-tencentos storageClass]# kubectl exec -it nginx-8b6bcb6c6-c26b8 -n tcloud -- cat /usr/share/nginx/html/index.html
Hello CephFS

7)PVC扩容

文件存储扩容

支持 CEPHFS 在线热扩容

复制代码
# 先查看需要扩容的pvc
[root@VM-16-167-tencentos ~]# kubectl get pvc
NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
mysql-pv-claim   Bound    pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e   10Gi       RWO            rook-ceph-block   <unset>                 89m
[root@VM-16-167-tencentos ~]# kubectl get pvc -A
NAMESPACE   NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
default     mysql-pv-claim       Bound    pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e   10Gi       RWO            rook-ceph-block   <unset>                 89m
tcloud      mysql-data-mysql-0   Bound    pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   5Gi        RWO            rook-ceph-block   <unset>                 69m
tcloud      mysql-data-mysql-1   Bound    pvc-70d3b8a1-fb60-4c7b-a104-b29d74314b1d   5Gi        RWO            rook-ceph-block   <unset>                 69m
tcloud      mysql-data-mysql-2   Bound    pvc-159cfe3a-8aca-4039-99e6-ddca664d5226   5Gi        RWO            rook-ceph-block   <unset>                 69m
tcloud      nginx-share-pvc      Bound    pvc-a83b1ee0-15ae-4168-95a0-4378396bbf87   1Gi        RWX            rook-cephfs       <unset>                 52m


# 扩容tcloud命名空间下的nginx-share-pvc
[root@VM-16-167-tencentos ~]# kubectl edit pvc -n tcloud nginx-share-pvc 
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 5Gi  # 修改空间为5G
  storageClassName: rook-cephfs

# 查看pvc是否容量是否为5G
[root@VM-16-167-tencentos ~]# kubectl get pvc -n tcloud 
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
mysql-data-mysql-0   Bound    pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   5Gi        RWO            rook-ceph-block   <unset>                 73m
mysql-data-mysql-1   Bound    pvc-70d3b8a1-fb60-4c7b-a104-b29d74314b1d   5Gi        RWO            rook-ceph-block   <unset>                 73m
mysql-data-mysql-2   Bound    pvc-159cfe3a-8aca-4039-99e6-ddca664d5226   5Gi        RWO            rook-ceph-block   <unset>                 73m
nginx-share-pvc      Bound    pvc-a83b1ee0-15ae-4168-95a0-4378396bbf87   5Gi        RWX            rook-cephfs       <unset>                 56m

# 查看pv是否也是5G
[root@VM-16-167-tencentos ~]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                       STORAGECLASS      VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-159cfe3a-8aca-4039-99e6-ddca664d5226   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-2   rook-ceph-block   <unset>                          73m
pvc-70d3b8a1-fb60-4c7b-a104-b29d74314b1d   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-1   rook-ceph-block   <unset>                          74m
pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-0   rook-ceph-block   <unset>                          74m
pvc-a83b1ee0-15ae-4168-95a0-4378396bbf87   5Gi        RWX            Delete           Bound    tcloud/nginx-share-pvc      rook-cephfs       <unset>                          57m
pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e   10Gi       RWO            Delete           Bound    default/mysql-pv-claim      rook-ceph-block   <unset>                          94m

# 验证pod的挂载空间是否生效
[root@VM-16-167-tencentos ~]# kubectl exec -n tcloud $(kubectl get pod -n tcloud | grep nginx | awk '{print $1}') -- df -h /usr/share/nginx/html
Filesystem                                                                                                                                               Size  Used Avail Use% Mounted on
192.168.26.127:6789,192.168.30.23:6789,192.168.1.37:6789:/volumes/csi/csi-vol-6f3c0e76-c37c-4c3a-9042-b4520d186024/4eab5b2b-6501-427a-b4b7-3f45c4583ab7  5.0G     0  5.0G   0% /usr/share/nginx/html
块存储扩容

块存储支持热扩容

复制代码
# 验证mysqlpod的存储空间
[root@VM-16-167-tencentos ~]# kubectl exec -it mysql-0 -n tcloud -- df -h /var/lib/mysql
Filesystem      Size  Used Avail Use% Mounted on
/dev/rbd0       4.9G  201M  4.7G   5% /var/lib/mysql
是5G


# 找到mysql-0的pvc
[root@VM-16-167-tencentos ~]# kubectl get pvc -n tcloud 
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
mysql-data-mysql-0   Bound    pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   5Gi        RWO            rook-ceph-block   <unset>                 78m
mysql-data-mysql-1   Bound    pvc-70d3b8a1-fb60-4c7b-a104-b29d74314b1d   5Gi        RWO            rook-ceph-block   <unset>                 78m
mysql-data-mysql-2   Bound    pvc-159cfe3a-8aca-4039-99e6-ddca664d5226   5Gi        RWO            rook-ceph-block   <unset>                 78m
nginx-share-pvc      Bound    pvc-a83b1ee0-15ae-4168-95a0-4378396bbf87   5Gi        RWX            rook-cephfs       <unset>                 62m


# 扩容
[root@VM-16-167-tencentos ~]# kubectl edit pvc -n tcloud mysql-data-mysql-0 
  - ReadWriteOnce
  resources:
    requests: 
      storage: 20Gi   # 扩容
  storageClassName: rook-ceph-block

等一会,扩容需要时间

复制代码
# 查看pvc是否也是20
[root@VM-16-167-tencentos ~]# kubectl get pvc -n tcloud 
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
mysql-data-mysql-0   Bound    pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   20Gi       RWO            rook-ceph-block   <unset>                 80m
mysql-data-mysql-1   Bound    pvc-70d3b8a1-fb60-4c7b-a104-b29d74314b1d   5Gi        RWO            rook-ceph-block   <unset>                 80m
mysql-data-mysql-2   Bound    pvc-159cfe3a-8aca-4039-99e6-ddca664d5226   5Gi        RWO            rook-ceph-block   <unset>                 80m
nginx-share-pvc      Bound    pvc-a83b1ee0-15ae-4168-95a0-4378396bbf87   5Gi        RWX            rook-cephfs       <unset>                 63m


# pv
[root@VM-16-167-tencentos ~]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                       STORAGECLASS      VOLUMEATTRIBUTESCLASS   REASON   AGE
pvc-159cfe3a-8aca-4039-99e6-ddca664d5226   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-2   rook-ceph-block   <unset>                          80m
pvc-70d3b8a1-fb60-4c7b-a104-b29d74314b1d   5Gi        RWO            Delete           Bound    tcloud/mysql-data-mysql-1   rook-ceph-block   <unset>                          81m
pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   20Gi       RWO            Delete           Bound    tcloud/mysql-data-mysql-0   rook-ceph-block   <unset>                          81m
pvc-a83b1ee0-15ae-4168-95a0-4378396bbf87   5Gi        RWX            Delete           Bound    tcloud/nginx-share-pvc      rook-cephfs       <unset>                          64m
pvc-d0f7176c-ed44-40b2-95c3-3508b2295a5e   10Gi       RWO            Delete           Bound    default/mysql-pv-claim      rook-ceph-block   <unset>                          101m

可以看到对应的PV也成功扩容

# 查看mysql-0的挂载空间
[root@VM-16-167-tencentos ~]# kubectl exec -it mysql-0 -n tcloud -- df -h /var/lib/mysql
Filesystem      Size  Used Avail Use% Mounted on
/dev/rbd0        20G  201M   20G   1% /var/lib/mysql

8)PVC克隆

文件存储克隆

基于已有的 CephFS PVC,直接完整复制一份全新 PVC,数据一模一样,不用备份、不用传文件、不用停机。

复制代码
# 先看源 PVC 信息
[root@VM-16-167-tencentos ~]# kubectl get pvc nginx-share-pvc -n tcloud
NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
nginx-share-pvc   Bound    pvc-a83b1ee0-15ae-4168-95a0-4378396bbf87   5Gi        RWX            rook-cephfs    <unset>                 76m


#  编写克隆 PVC yaml
[root@VM-16-167-tencentos ~]# vim cephfs-clone.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-share-pvc-clone
  namespace: tcloud
spec:
  storageClassName: rook-cephfs
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 3Gi    #克隆的大小 必须 ≥ (源PVC)5Gi
  # 核心克隆配置:指定源PVC
  dataSource:
    name: nginx-share-pvc
    kind: PersistentVolumeClaim

# apply
[root@VM-16-167-tencentos ~]# kubectl apply -f cephfs-clone.yaml

# 查看
[root@VM-16-167-tencentos ~]# kubectl get pvc -n tcloud nginx-share-pvc-clone 
NAME                    STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
nginx-share-pvc-clone   Bound    pvc-31900ef3-2e2f-4434-831a-240d3105230e   5Gi        RWX            rook-cephfs    <unset>                 46s


#  起一个新 Nginx,挂载克隆 PVC
[root@VM-16-167-tencentos ~]# vim nginx-clone-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-clone-test
  namespace: tcloud
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-clone
  template:
    metadata:
      labels:
        app: nginx-clone
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        volumeMounts:
        - name: web-data
          mountPath: /usr/share/nginx/html
      volumes:
      - name: web-data
        persistentVolumeClaim:
          claimName: nginx-share-pvc-clone

# apply
[root@VM-16-167-tencentos ~]# kubectl apply -f nginx-clone-test.yaml


# 查看index.html和之前写入的测试文件是否一致
[root@VM-16-167-tencentos ~]# kubectl exec -it $(kubectl get pod -n tcloud | grep nginx-clone | awk '{print $1}') -n tcloud -- cat /usr/share/nginx/html/index.html
Hello CephFS
块存储克隆

基于pod的mysql-0的pvc进行克隆,因为我们之前写入过测试数据

复制代码
# 查看pvc
[root@VM-16-167-tencentos ~]# kubectl get pvc -n tcloud mysql-data-mysql-0
NAME                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
mysql-data-mysql-0   Bound    pvc-7e9e80c8-440f-47b5-bec1-9aa6023a2fe0   20Gi       RWO            rook-ceph-block   <unset>                 103m


# 编写克隆pvc的yaml
[root@VM-16-167-tencentos ~]# vim mysql-rbd-clone.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-data-mysql-0-clone
  namespace: tcloud
spec:
  storageClassName: rook-ceph-block
  accessModes:
    - ReadWriteOnce
  # 容量和源盘保持一致
  resources:
    requests:
      storage: 20Gi
  # 克隆数据源:原mysql-0的PVC
  dataSource:
    kind: PersistentVolumeClaim
    name: mysql-data-mysql-0


# apply
[root@VM-16-167-tencentos ~]# kubectl apply -f mysql-rbd-clone.yaml


# 查看克隆的pvc
nginx-share-pvc-clone      Bound    pvc-31900ef3-2e2f-4434-831a-240d3105230e   5Gi        RWX            rook-cephfs       <unset>                 9m21s
[root@VM-16-167-tencentos ~]# kubectl get pvc -n tcloud mysql-data-mysql-0-clone
NAME                       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      VOLUMEATTRIBUTESCLASS   AGE
mysql-data-mysql-0-clone   Bound    pvc-4bb4d9e1-647a-4121-842b-08974ee4b765   20Gi       RWO            rook-ceph-block   <unset>                 22s

# 用 MySQL 镜像启动克隆盘(直接带数据)
[root@VM-16-167-tencentos ~]# vim mysql-clone.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-clone
  namespace: tcloud
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql-clone
  template:
    metadata:
      labels:
        app: mysql-clone
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"
      volumes:
      - name: mysql-data
        persistentVolumeClaim:
          claimName: mysql-data-mysql-0-clone

# apply
[root@VM-16-167-tencentos ~]# kubectl apply -f mysql-clone.yaml


# 进入挂载克隆pvc的mysql查看数据
[root@VM-16-167-tencentos ~]# kubectl exec -it $(kubectl get pod -n tcloud | grep mysql-clone | head -n1 | awk '{print $1}') -n tcloud -- bash
bash-5.1# mysql -uroot -p123456

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test_ceph          |
+--------------------+
5 rows in set (0.00 sec)

mysql> use test_ceph;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+---------------------+
| Tables_in_test_ceph |
+---------------------+
| t_user              |
+---------------------+
1 row in set (0.00 sec)

mysql> select * from t_user;
+------+
| id   |
+------+
|  100 |
+------+
1 row in set (0.00 sec)

之前写的测试数据,完整克隆过来了!

二、Helm

1、什么是helm

Helm 是 Kubernetes 官方提供的包管理器,类比 Linux 系统的 YUM/Apt,核心作用是简化 K8s 应用的部署、版本管理和生命周期维护。在无 Helm 时,需手动依次部署 Deployment、Service 等资源,步骤繁琐且难以规模化管理;Helm 通过打包机制将 K8s 资源配置动态化,支持版本控制,大幅降低复杂应用(尤其是微服务)的部署难度。

Helm 4 是 Kubernetes 包管理工具 Helm 时隔 6 年发布的全新主版本(2025 年 11 月正式发布 v4.0.0),在完全兼容 Helm 3 主流 Chart 格式的基础上,完成了核心架构重构、扩展能力全面升级、安全性与现代化改造,解决了 Helm 3 的架构技术债务,为未来的功能迭代奠定了基础。

2、helm基础认知

  • Chart:Helm 的 "安装包",包含运行一个 Kubernetes 应用所需的所有资源定义(如 Deployment、Service 等)。
  • Repository:存储和共享 Chart 的仓库,类似代码仓库(如官方的 Bitnami 仓库、私有仓库)。
  • Release:Chart 在 Kubernetes 集群中的 "运行实例",一个 Chart 可部署为多个不同 Release。
  • Values:配置文件,用于在部署时自定义 Chart 参数(如镜像版本、服务端口),实现 "一次打包,多环境复用"。
  • Templates:Kubernetes 资源的模板文件,结合 Values 动态生成最终部署配置。

3、安装helm

复制代码
# 安装Helm(这里是使用的是最新版)
[root@k8s-master01 helm]# wget https://get.helm.sh/helm-v4.1.4-linux-amd64.tar.gz
 
# 解压
[root@k8s-master01 helm]# tar -zxvf helm-v4.1.4-linux-amd64.tar.gz 
[root@k8s-master01 helm]# mv linux-amd64/helm /usr/local/bin/
[root@k8s-master01 helm]# helm version
version.BuildInfo{Version:"v4.1.4", GitCommit:"05fa37973dc9e42b76e1d2883494c87174b6074f", GitTreeState:"clean", GoVersion:"go1.25.9", KubeClientVersion:"v1.35"}

# 配置仓库
# 添加阿里仓库和Bitnami仓库(Bitnami 包含大量主流应用 Chart)
[root@k8s-master01 ~]# helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
[root@k8s-master01 ~]# helm repo add bitnami https://charts.bitnami.com/bitnami


# 更新仓库
[root@k8s-master01 ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "aliyun" chart repository
...Successfully got an update from the "bitnami" chart repository
...Successfully got an update from the "ingress-nginx" chart repository
Update Complete. ⎈Happy Helming!⎈
# 如果ingress-nginx报错就是网络问题


# 查看仓库
[root@k8s-master01 ~]# helm repo list
NAME         	URL                                                   
ingress-nginx	https://kubernetes.github.io/ingress-nginx            
aliyun       	https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
bitnami      	https://charts.bitnami.com/bitnami                    

4、helm常用命令

仓库管理

复制代码
# 添加仓库
helm repo add 仓库名 地址

# 查看已添加仓库
helm repo list

# 删除仓库
helm repo remove 仓库名

# 更新所有仓库索引
helm repo update

chart搜索下载

复制代码
# 搜索仓库应用
helm search repo 关键词

# 下载 Chart(压缩包)
helm pull 仓库/应用名

# 下载并解压
helm pull 仓库/应用名 --untar

# Helm4 推荐:OCI 源直接拉取(无需添加仓库)
helm pull oci://registry.k8s.io/ingress-nginx/ingress-nginx --untar

安装应用

复制代码
# 基础安装
helm install 发布名 仓库/应用名

# 指定命名空间 + 自动创建命名空间
helm install 发布名 仓库/应用名 -n 命名空间 --create-namespace

# 自定义配置文件
helm install 发布名 仓库/应用名 -f values.yaml

# Helm4 新参数:部署失败自动回滚(替代旧 --atomic)
helm install 发布名 仓库/应用名 --rollback-on-failure

查看已部署的应用

复制代码
# 查看所有命名空间的 Release
helm list -A

# 查看指定命名空间
helm list -n 命名空间

# 查看应用详情
helm status 发布名 -n 命名空间

# 查看版本更新历史
helm history 发布名 -n 命名空间

升级和回滚

复制代码
# 升级应用
helm upgrade 发布名 仓库/应用名 -n 命名空间

# 升级 + 自定义配置
helm upgrade 发布名 仓库/应用名 -f values.yaml -n 命名空间

# Helm4 新参数:升级失败自动回滚
helm upgrade 发布名 仓库/应用名 --rollback-on-failure

# 回滚到上一版本
helm rollback 发布名 -n 命名空间

# 回滚到指定版本
helm rollback 发布名 版本号 -n 命名空间

卸载应用

复制代码
# 卸载 Release
helm uninstall 发布名 -n 命名空间

本地chart开发

复制代码
# 创建新 Chart
helm create 目录名

# 检查 Chart 语法
helm lint 目录名

# 打包 Chart
helm package 目录名

测试渲染

复制代码
# 本地渲染 YAML(不部署)
helm template 发布名 Chart路径

# 模拟安装(不真实创建资源)
helm install 发布名 仓库/应用名 --dry-run

5、自定义chart实例

Helm Chart标准目录结构

复制代码
mychart/                  # Chart 根目录(自定义名称)
├── Chart.yaml            # Chart 元数据(名称、版本、描述)
├── values.yaml           # 默认配置参数(用户可覆盖)
├── templates/             # K8s 资源模板目录
│   ├── deployment.yaml    # Deployment 模板
│   ├── service.yaml       # Service 模板
│   ├── ingress.yaml       # Ingress 模板
│   ├── _helpers.tpl       # 辅助函数、标签定义(复用代码)
│   ├── NOTES.txt          # 安装完成后的提示信息
│   └── hpa.yaml           # 可选:弹性伸缩模板
├── charts/                # 可选:存放依赖的子 Chart
├── Chart.lock             # 可选:依赖版本锁定文件
├── .helmignore            # 可选:打包时忽略的文件(类似 .gitignore)
└── README.md              # 可选:Chart 使用说明

1、创建前置环境配置文件

复制代码
# 创建实例标准数据目录
[root@k8s-master01 ~]# mkdir -p redis-ms/templates
chart.yaml

Chart.yaml 是 Helm 安装包(Chart)的身份证 / 说明书,没有这个文件,Helm 就不认识你的部署模板,无法安装、升级、管理应用。

复制代码
# 1. Chart.yaml
cat > redis-ms/Chart.yaml << EOF
apiVersion: v2
name: redis-ms
version: 1.0.0
appVersion: latest
EOF
values.yaml

所有可变参数(密码、镜像、节点、副本数)都写在这里,只改这一个文件,就能全局生效,不用去修改 Deployment / PVC 等底层模板。

复制代码
# 2. values.yaml
cat > redis-ms/values.yaml << EOF
password: "123456"
image:
  repository: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/redis
  tag: latest
master:
  replicas: 1
slave:
  replicas: 1
nodeName: k8s-node01
EOF
pv / pvc.yaml
复制代码
# 3. PV
cat > redis-ms/templates/pv.yaml << EOF
apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis-data-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /opt/redis-data
    type: Directory
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k8s-node01
  persistentVolumeReclaimPolicy: Retain
EOF

# 4. PVC
cat > redis-ms/templates/pvc.yaml << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redis-data-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  volumeName: redis-data-pv
EOF
主从节点deployment
复制代码
# 5. Redis 主节点 Deployment
cat > redis-ms/templates/master-deploy.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-master
spec:
  replicas: {{ .Values.master.replicas }}
  selector:
    matchLabels:
      app: redis
      role: master
  template:
    metadata:
      labels:
        app: redis
        role: master
    spec:
      # 固定调度到 k8s-node01,防止Pod漂移
      nodeName: {{ .Values.nodeName }}
      containers:
      - name: redis-master
        image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
        command: ["redis-server"]
        args:
        - --requirepass {{ .Values.password }}  # Redis访问密码
        - --save 60 1                           # RDB持久化
        - --appendonly yes                      # AOF持久化
        volumeMounts:
        - name: data
          mountPath: /data  # 数据持久化挂载目录
        ports:
        - containerPort: 6379
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: redis-data-pvc  # 绑定PVC实现持久化
EOF

# 6. Redis 从节点 Deployment
cat > redis-ms/templates/slave-deploy.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-slave
spec:
  replicas: {{ .Values.slave.replicas }}
  selector:
    matchLabels:
      app: redis
      role: slave
  template:
    metadata:
      labels:
        app: redis
        role: slave
    spec:
      # 与主节点同节点部署,保证网络连通
      nodeName: {{ .Values.nodeName }}
      containers:
      - name: redis-slave
        image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
        command: ["redis-server"]
        args:
        - --slaveof redis-master 6379    # 【核心】连接主节点(Service名称)
        - --masterauth {{ .Values.password }}  # 主节点密码
        - --requirepass {{ .Values.password }}  # 从节点密码
        ports:
        - containerPort: 6379
EOF
service

因为主节点用来做通信,从节点不需要和外部服务通信,所以不需要service

复制代码
# 7. 主节点SVC
cat > redis-ms/templates/master-svc.yaml << EOF
apiVersion: v1
kind: Service
metadata:
  name: redis-master
spec:
  type: ClusterIP
  ports:
  - port: 6379
  selector:
    app: redis
    role: master
EOF

2、安装Release(redis)

复制代码
# 在node1上创建redis数据存放目录
[root@k8s-node01 ~]# mkdir -p /opt/redis-data
[root@k8s-node01 ~]# chmod 777 /opt/redis-data

# 创建命令空间
[root@k8s-master01 ~]# kubectl create ns redis-ms

# 创建实例
[root@k8s-master01 ~]# helm install redis-ms ./redis-ms -n redis-ms

# 查看安装的资源
[root@k8s-master01 ~]# kubectl get pod -n redis-ms 
NAME                            READY   STATUS    RESTARTS   AGE
redis-master-567bcd8577-qb9q8   1/1     Running   0          117s
redis-slave-5bf8bb8b86-rjslq    1/1     Running   0          117s
[root@k8s-master01 ~]# kubectl get pv
NAME            CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
redis-data-pv   1Gi        RWO            Retain           Bound    redis-ms/redis-data-pvc                  <unset>                          2m5s
[root@k8s-master01 ~]# kubectl get pvc -n redis-ms 
NAME             STATUS   VOLUME          CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
redis-data-pvc   Bound    redis-data-pv   1Gi        RWO                           <unset>                 2m11s
[root@k8s-master01 ~]# kubectl get svc -n redis-ms 
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
redis-master   ClusterIP   10.96.113.113   <none>        6379/TCP   2m17s

3、测试实例

复制代码
# 进入master pod写入测试数据
[root@k8s-master01 ~]# kubectl exec -it $(kubectl get pods -n redis-ms -l role=master -o name) -n redis-ms -- redis-cli -a 123456 set test hello


# 在node01节点查询数据情况
[root@k8s-node01 ~]# ls /opt/redis-data
appendonlydir  dump.rdb


# 进入slave pod查询数据
[root@k8s-master01 ~]# kubectl exec -it $(kubectl get pods -n redis-ms -l role=slave -o name) -n redis-ms -- redis-cli -a 123456 get test
"hello"


# 删除pod重建
[root@k8s-master01 ~]# kubectl delete $(kubectl get pods -n redis-ms -l role=master -o name) -n redis-ms

# 查询数据持久化
[root@k8s-master01 ~]# kubectl exec -it $(kubectl get pods -n redis-ms -l role=master -o name) -n redis-ms -- redis-cli -a 123456 get test
"hello"

4、升级Release

复制代码
# 1. 修改节点副本数(1→2)
[root@k8s-master01 ~]# sed -i 's/replicas: 1/replicas: 2/g' redis-ms/values.yaml


# 2. 执行升级命令
[root@k8s-master01 ~]# helm upgrade redis-ms ./redis-ms -n redis-ms


# 3. 验证升级结果
[root@k8s-master01 ~]# kubectl get pods -n redis-ms
NAME                            READY   STATUS    RESTARTS   AGE
redis-master-567bcd8577-ftgt5   1/1     Running   0          3m20s
redis-master-567bcd8577-pjg64   1/1     Running   0          10s
redis-slave-5bf8bb8b86-mv8s8    1/1     Running   0          10s
redis-slave-5bf8bb8b86-rjslq    1/1     Running   0          8m10s

5、回滚Release

复制代码
# 查看release的历史版本
[root@k8s-master01 ~]# helm history redis-ms -n redis-ms
REVISION	UPDATED                 	STATUS    	CHART         	APP VERSION	DESCRIPTION     
1       	Wed May  6 13:09:20 2026	superseded	redis-ms-1.0.0	latest     	Install complete
2       	Wed May  6 13:17:19 2026	deployed  	redis-ms-1.0.0	latest     	Upgrade complete


# 回滚初始版本1
[root@k8s-master01 ~]# helm rollback redis-ms 1 -n redis-ms
Rollback was a success! Happy Helming!


# 验证pod
[root@k8s-master01 ~]# kubectl get pods -n redis-ms
NAME                            READY   STATUS    RESTARTS   AGE
redis-master-567bcd8577-ftgt5   1/1     Running   0          5m5s
redis-slave-5bf8bb8b86-rjslq    1/1     Running   0          9m55s

6、打包Release

打包是为了规范、安全、分发、版本管理,适合团队 / 生产使用。

复制代码
[root@k8s-master01 ~]# helm package redis-ms/
Successfully packaged chart and saved it to: /root/redis-ms-1.0.0.tgz

#  执行完成后,会生成文件:redis-ms-1.0.0.tgz
#  把这个 tgz 文件传输给别人

# 同事使用
# 1. 创建命名空间
kubectl create ns redis-ms

# 2. 在node01上安装数据存储目录
mkdir -p /opt/redis-data
chmod 777 /opt/redis-data

# 3. 直接安装压缩包(无需解压!无需改配置)
helm install redis-ms ./redis-ms-1.0.0.tgz -n redis-ms

如果同事需要改密码、节点、镜像,不用改模板,直接两种方式:
方式 1:解压修改配置(推荐)
# 解压
tar -zxvf redis-ms-1.0.0.tgz

# 修改配置文件
vim redis-ms/values.yaml

# 安装
helm install redis-ms ./redis-ms -n redis-ms



方式 2:安装时直接覆盖参数
helm install redis-ms ./redis-ms-1.0.0.tgz -n redis-ms \
  --set password=654321 \
  --set nodeName=k8s-node02

7、卸载Release

复制代码
# 1. 卸载 Redis 实例(Release)
[root@k8s-master01 ~]# helm uninstall redis-ms -n redis-ms

# 2. 删除命名空间(连带删除 PVC/Pod/SVC)
[root@k8s-master01 ~]# kubectl delete namespace redis-ms
相关推荐
阿里云云原生1 小时前
阿里云微服务引擎 MSE 及 API 网关 2026 年 4 月产品动态
微服务·云原生
张文君2 小时前
上古世纪服务端编译安装AAEmu docker编译安装
运维·docker·容器
阿里云云原生3 小时前
从“对话式编程”到“规格驱动”:民生银行企业级AI研发范式重构实践
云原生
苍煜3 小时前
现代生产级微服务+容器治理完整技术栈与架构方案详解(国内主流完整云原生微服务闭环架构)
微服务·云原生·架构
小猿姐3 小时前
GitLab on Kubernetes:使用 KubeBlocks 部署生产级高可用 PostgreSQL 和 Redis
redis·postgresql·kubernetes
Stackflowed4 小时前
Docker安装Oracle
docker·oracle·容器
邵奈一4 小时前
OrbStack 环境下 Dify 启动报错完整解决方案教程:validating docker-compose.yaml
docker·容器·eureka
一只小bit5 小时前
Docker 镜像制作:包含自定义镜像及常用命令
运维·docker·容器