在华为云CCE上用Helm部署有状态服务时,持久化存储挂载失败是很常见的问题,很多刚上手的开发者会手足无措,其实只要按一步步的流程排查,就能快速找到原因并解决。咱们先明确这个场景:就是你用Helm准备了需要存数据的服务(比如MySQL、MongoDB这类有状态服务,它们的数据不能丢,所以得挂载专门的存储),部署到华为云CCE的集群里,结果Pod一直启动失败,要么是卡在Pending状态,要么启动后立刻Crash,提示挂载存储失败,这就是咱们要定位解决的核心问题。
一、先定位“问题出在谁身上”
很多人遇到问题会直接乱改配置,其实第一步要做的是找到真正的问题源,分两步走:看Pod的状态和事件,再看存储相关资源的状态。
1.1 先查Pod的状态和事件
Pod是Kubernetes里最小的运行单元,它的状态和事件会直接告诉你为什么启动失败,用的命令都是Kubernetes自带的,完全不用复杂工具,新手也能上手。
示例操作(技术栈:华为云CCE + Kubernetes CLI + Helm):
# 1. 先确定你部署服务的命名空间,假设是专门放业务的myapp,要是你没改就是default,这里用myapp举例
# 2. 找到有状态服务的Pod名,Helm部署有状态服务的时候,Pod名一般是“release名-序号”,比如Helm的release叫myapp,第一个Pod就是myapp-0,第二个是myapp-1,以此类推
# 3. 查看Pod的基本状态,要是状态不是Running或者Completed,就继续查事件
kubectl -n myapp describe pod myapp-0
你执行这个命令后,会看到大量的信息,重点看最下面的Events部分,这里面的最后几行就是Pod的运行事件,错误原因会直接写在这里。比如常见的错误提示有:“FailedBinding: no persistent volumes available for this claim and no storage class is specified”(没找到存储类,也没指定)、“MountVolume.SetUp failed for volume ...”(挂载卷失败),这些都是你定位的关键,不用猜,系统已经把原因说清楚了。
1.2 再查PVC和PV的状态
Pod挂载存储需要用到两种资源:PVC(PersistentVolumeClaim,相当于你申请的存储“申请单”)和PV(PersistentVolume,是集群里实际可用的存储资源),PVC会匹配PV,要是匹配不上,挂载就会失败。
示例操作:
# 1. 查看当前namespace下的所有PVC,有状态服务的PVC名字一般是“release名-序号”,比如myapp-myapp-0
kubectl -n myapp get pvc
# 2. 查看对应的PV,要是PVC的STATUS不是Bound,说明没找到匹配的PV,需要进一步排查
kubectl get pv | grep myapp-myapp-0
比如要是get pvc后,PVC的STATUS是Pending,那基本就是PV找不到,这时候就需要看是不是StorageClass的问题,或者PV的资源不够。
二、常见的挂载失败原因及解决办法
咱们整理了三个最常见的坑,每个都带具体的解决步骤,结合示例说清楚:
2.1 第一个坑:StorageClass不存在或写错了
StorageClass是Kubernetes里用来定义存储类型的,华为云CCE里默认有CBS(云硬盘)的StorageClass,叫cbs,要是你部署的时候没指定StorageClass,或者指定的名字写错了,就会找不到对应的存储,导致PVC一直Pending。
示例:要是你写的Chart里,持久化部分的配置没指定StorageClass,或者写错了,比如写成了csb(少了个字母),就会出问题。正确的配置应该在Helm的values.yaml里明确写StorageClass:
# 技术栈:华为云CCE + Helm + Kubernetes
# 有状态服务Chart的values.yaml里的持久化配置,必须指定正确的StorageClass
persistence:
enabled: true # 一定要打开持久化,要是是false的话,就不会挂载
storageClass: "cbs" # 这里填华为云CCE集群里实际存在的StorageClass名字,别写错,大小写也要对
accessModes:
- ReadWriteOnce # 大部分有状态服务用这个,单节点可读写,CBS只支持这个
size: 10Gi # 存储大小,根据你的服务需要改
怎么确认集群里有对应的StorageClass?用这个命令:
# 查看集群里所有可用的StorageClass
kubectl get sc
要是查不到cbs,那你可以去华为云CCE控制台,进入你的集群,找到“存储”->“存储类”,点击创建,选CBS类型,对应你的集群区域和VPC,创建好就能用了。
2.2 第二个坑:accessModes不匹配
accessModes是存储的访问模式,常见的有ReadWriteOnce(单节点可读写)、ReadWriteMany(多节点可读写),华为云CCE的CBS只支持ReadWriteOnce,要是你的PVC里写的是ReadWriteMany,就匹配不到PV,导致挂载失败。
示例:怎么查PVC和PV的accessModes:
# 查看PVC的accessModes
kubectl -n myapp get pvc myapp-myapp-0 -o yaml | grep accessModes
# 查看对应PV的accessModes,要是你之前没手动创建PV,那匹配的PV的accessModes应该和PVC一致
kubectl get pv <你的PV名字> -o yaml | grep accessModes
要是PVC的accessModes是ReadWriteMany,而PV的是ReadWriteOnce,那你改PVC的accessModes就行,或者在Helm的values.yaml里改:把accessModes改成ReadWriteOnce就好。
2.3 第三个坑:Helm release名写错了导致找不到PVC
Helm部署服务的时候,你会给release起一个名字,比如helm install my-release ./mychart,要是你后来查PVC的时候,错误地用了别的release名,就会找不到对应的PVC,以为挂载失败了。
示例:怎么确认当前namespace下的所有release和对应的资源:
# 查看当前namespace下所有的Helm release,以及对应的资源
helm list -n myapp
要是你发现release名是my-release,那对应的PVC应该是my-release-mychart-0,要是你之前查的是别的名字,那就是你release名写错了,部署的时候记得用正确的release名,或者安装的时候给release起个好记的名字。
三、落地实操的注意事项和总结
3.1 应用场景
这个流程适合所有在华为云CCE上用Helm部署有状态服务的场景,尤其是需要持久化存储的数据库、缓存等服务,不管是刚接触Kubernetes的新手,还是有一定经验的开发者,都能用这个流程快速定位问题,不用到处翻文档找解决方案。
3.2 技术优缺点
优点:所有用到的工具都是Kubernetes和Helm自带的,不需要额外安装复杂的工具,操作步骤简单,适合不同基础的开发者;定位流程是从系统给出的提示入手,不会瞎猜,效率很高,80%以上的常见挂载失败问题都能通过这个流程解决。
缺点:要是遇到比较复杂的问题,比如存储配额不够、集群存储资源故障,这个基础流程可能不够,需要结合华为云CCE的控制台查看存储的具体配额,或者查看CCE的存储日志;另外,要是你用的不是华为云的CBS,是其他存储比如OBS的话,StorageClass的创建流程会不一样,需要额外查对应存储的文档。
3.3 注意事项
一定要先看Pod的事件,别跳过这一步,事件里的错误原因是最直接的,比如“no storage class is specified”就直接告诉你要指定StorageClass,不用自己瞎想;
K8s对名字的大小写是敏感的,StorageClass、PVC、PV的名字一定要和你创建的一致,比如你创建的StorageClass是cbs,就不能写成CBS;
有状态服务的PVC名字是和release名绑定的,部署的时候要记住release名,查资源的时候用release名对应,不然会找不到;
要是你是第一次用华为云CCE部署有状态服务,建议先看CCE里的默认StorageClass有没有,别自己瞎写StorageClass的名字,默认的cbs一般是有的,只要你选对了集群区域。
3.4 总结
总的来说,在华为云CCE上用Helm部署有状态服务时,持久化存储挂载失败的定位流程是:先查Pod的状态和事件→再查PVC和PV的状态→对应错误原因解决,最常见的三个坑是StorageClass不存在、accessModes不匹配、release名写错,按步骤来就能快速解决,不用慌。