使用 Helm 管理 Kubernetes Operator:从部署到运维
使用 Helm 管理 Kubernetes Operator:从部署到运维
一、秒懂定位
这个知识解决什么问题:
一个 helm install 命令替代 6+ 个 kubectl apply 命令,实现 Operator 的标准化部署和版本管理
一句话精华:
Helm 是 Operator 的"安装程序",负责部署、升级、回滚;Operator 是"智能管家",负责持续运维
适合谁学:
- Kubernetes 用户,想简化 Operator 部署
- 运维工程师,想实现 Operator 版本管理
- 平台开发者,想发布自己的 Operator
不适合谁:
- 完全不懂 Helm 的初学者(建议先学 Helm 基础)
- 只部署简单应用的用户(不需要 Operator)
二、精彩开场
🎭 幽默式开场
“有人问我:‘Helm 和 Operator 是什么关系?’”
“我说:‘这就像装修队和物业管家。Helm 是装修队,负责把 Operator 装进你的集群;Operator 是物业管家,装完后 7x24 小时帮你管理应用。’”
“装修队干完活就走,管家一直住在你家——这就是 Helm 和 Operator 的区别!”
“今天,我们就来学习如何用 Helm 这个’装修队’,把 Operator 装进你的 Kubernetes 集群。”
三、核心框架
知识地图
┌─────────────────────────────────────────────────────────────────────────────┐
│ Helm 管理 Operator 学习路径 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 【入门】理解关系 │
│ │ │
│ │ Helm = 安装程序(一次性部署) │
│ │ Operator = 控制器(持续管理) │
│ │ 两者是互补关系,不是替代关系 │
│ ↓ │
│ 【进阶】创建 Helm Chart │
│ │ │
│ │ Chart.yaml → values.yaml → templates/ │
│ ↓ │
│ 【实战】部署两个 Operator │
│ │ │
│ ├─→ k8s-test-operator:微服务部署 Operator │
│ └─→ tenant-operator:多租户管理 Operator │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
关键概念速查表
| 概念 | 大白话解释 | 生活比喻 | 一句话记忆 |
|---|---|---|---|
| Helm Chart | 一套打包好的 K8s 资源模板 | 装修设计图 | Chart 是"安装包" |
| values.yaml | 可配置的参数 | 装修选项清单 | values 是"配置参数" |
| templates/ | 模板文件,生成实际资源 | 施工图纸 | templates 是"资源模板" |
| Release | 一次 Helm 安装实例 | 装修项目 | Release 是"安装实例" |
四、深入浅出讲解
【概念1:为什么需要 Helm 管理 Operator?】
一句话是什么:
传统方式部署 Operator 需要多个 kubectl 命令,Helm 把这些命令打包成一个,还提供版本管理能力。
生活化比喻:
把部署 Operator 比作"装修房子"...
传统方式(手动装修):
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ 你需要亲自做每件事: │
│ │
│ 1. 找水电工 → kubectl apply -f serviceaccount.yaml │
│ 2. 找木工 → kubectl apply -f clusterrole.yaml │
│ 3. 找瓦工 → kubectl apply -f clusterrolebinding.yaml │
│ 4. 找油漆工 → kubectl apply -f deployment.yaml │
│ 5. 找安装工 → kubectl apply -f crd.yaml │
│ │
│ 问题: │
│ - 工人太多,容易漏掉 │
│ - 顺序搞错,要返工 │
│ - 想改设计,全部重来 │
│ - 没有版本记录,不知道改了啥 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Helm 方式(装修公司):
┌─────────────────────────────────────────────────────────────────────────────┐
│ │
│ 你只需要告诉装修公司你要什么: │
│ │
│ helm install my-operator ./chart --set replicas=3 │
│ │
│ 装修公司自动: │
│ - 派水电工、木工、瓦工、油漆工、安装工 │
│ - 按正确顺序施工 │
│ - 记录装修版本(方便回滚) │
│ - 改设计只需要打个电话(helm upgrade) │
│ │
│ 优点: │
│ - 一个命令搞定 │
│ - 顺序自动处理 │
│ - 版本自动记录 │
│ - 升级回滚方便 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
引经据典:
"工欲善其事,必先利其器"——《论语·卫灵公》
部署 Operator 也是如此:
- 传统方式:手工作业,效率低、易出错
- Helm 方式:工具自动化,效率高、可追溯
选择合适的工具,事半功倍!
幽默包装:
传统方式 vs Helm 方式:
传统方式:
运维:"我要部署 Operator,先执行这个...再执行那个..."
5 分钟后...
运维:"糟糕,漏了一个文件!"
重新来过... 😱
Helm 方式:
运维:"helm install operator ./chart"
30 秒后...
运维:"搞定!喝茶去~" 😎
常见误区(幽默版):
❌ 误区1:"Helm 能替代 Operator"
真相:Helm 和 Operator 是好基友!
Helm 负责"生"(安装),Operator 负责"养"(运维)。
就像:医院负责接生,父母负责养大。
❌ 误区2:"Helm 只能部署简单应用"
真相:Helm 可以部署任何 Kubernetes 资源,包括 Operator。
就像:装修队既能装修公寓,也能装修别墅。
❌ 误区3:"Helm Chart 开发很难"
真相:Helm Chart 就是 Go 模板 + YAML,学会基础语法就能写。
就像:装修设计图看着复杂,其实都是标准图纸。
【概念2:Helm Chart 结构】
一句话是什么:
Helm Chart 是一套打包好的 Kubernetes 资源模板,包含元数据、配置参数和模板文件。
生活化比喻:
把 Helm Chart 比作"装修套餐":
┌─────────────────────────────────────────────────────────────────────────────┐
│ Helm Chart = 装修套餐 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 📋 Chart.yaml(套餐说明) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 内容:套餐名称、版本、描述 │ │
│ │ 作用:告诉用户这是什么套餐 │ │
│ │ 示例: │ │
│ │ name: k8s-test-operator │ │
│ │ version: 0.1.0 │ │
│ │ description: 微服务部署 Operator │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ 📝 values.yaml(选项清单) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 内容:可配置的参数 │ │
│ │ 作用:让用户自定义装修方案 │ │
│ │ 示例: │ │
│ │ image: │ │
│ │ repository: my-registry/operator │ │
│ │ tag: v1.0.0 │ │
│ │ replicas: 1 │ │
│ │ resources: │ │
│ │ limits: │ │
│ │ cpu: 500m │ │
│ │ memory: 256Mi │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ 📁 templates/(施工图纸) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 内容:Kubernetes 资源模板 │ │
│ │ 作用:根据 values.yaml 生成实际资源 │ │
│ │ 文件: │ │
│ │ ├── _helpers.tpl # 模板助手函数 │ │
│ │ ├── crd.yaml # CRD 定义 │ │
│ │ ├── namespace.yaml # 命名空间 │ │
│ │ ├── serviceaccount.yaml │ │
│ │ ├── clusterrole.yaml │ │
│ │ ├── clusterrolebinding.yaml │ │
│ │ ├── deployment.yaml # Operator 部署 │ │
│ │ └── xxx-cr.yaml # 示例 CR │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
核心要点:
- Chart.yaml 定义元数据:名称、版本、描述
- values.yaml 定义参数:用户可配置的选项
- templates/ 定义模板:根据参数生成实际资源
【概念3:Helm 核心命令】
一句话是什么:
Helm 提供 install、upgrade、rollback、uninstall 四个核心命令,管理 Operator 的完整生命周期。
生活化比喻:
把 Helm 命令比作"装修项目管理":
┌─────────────────────────────────────────────────────────────────────────────┐
│ Helm 命令 = 装修项目管理 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 📦 helm install(开始装修) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 命令:helm install my-operator ./chart │ │
│ │ 效果:把 Operator 部署到集群 │ │
│ │ 比喻:装修公司进场,开始施工 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ 🔄 helm upgrade(升级装修) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 命令:helm upgrade my-operator ./chart --set image.tag=v2.0.0 │ │
│ │ 效果:更新 Operator 到新版本 │ │
│ │ 比喻:业主想换装修方案,装修公司按新方案调整 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ⏪ helm rollback(回滚装修) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 命令:helm rollback my-operator 1 │ │
│ │ 效果:回滚到上一个版本 │ │
│ │ 比喻:业主不满意新方案,装修公司恢复到之前的方案 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ 🗑️ helm uninstall(拆除装修) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 命令:helm uninstall my-operator │ │
│ │ 效果:删除 Operator 及相关资源 │ │
│ │ 比喻:业主不想要了,装修公司拆除所有装修 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
命令速查表:
| 命令 | 作用 | 示例 |
|---|---|---|
helm install |
安装 Chart | helm install my-op ./chart |
helm upgrade |
升级 Release | helm upgrade my-op ./chart --set replicas=3 |
helm rollback |
回滚到指定版本 | helm rollback my-op 1 |
helm uninstall |
卸载 Release | helm uninstall my-op |
helm list |
查看所有 Release | helm list |
helm status |
查看 Release 状态 | helm status my-op |
helm history |
查看版本历史 | helm history my-op |
五、实战:部署 k8s-test-operator
Helm Chart 结构
operator_helm/
├── Chart.yaml # Chart 元数据
├── values.yaml # 可配置参数
├── README.md # 使用说明
└── templates/
├── _helpers.tpl # 模板助手函数
├── crd.yaml # CRD 定义
├── namespace.yaml # Operator 命名空间
├── serviceaccount.yaml # ServiceAccount
├── clusterrole.yaml # ClusterRole
├── clusterrolebinding.yaml # ClusterRoleBinding
├── deployment.yaml # Operator Deployment
└── k8stest-cr.yaml # 示例 CR (可选)
部署步骤
Step 1: 验证 Helm Chart
cd /Volumes/mac_data/code/go_code/101/Allen/k8slearn/operator/operator_helm
helm lint .
实际执行效果:
==> Linting .
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
Step 2: 预览生成的 YAML(可选)
helm template k8s-test-operator . | less
Step 3: 构建并推送 Operator 镜像
cd /Volumes/mac_data/code/go_code/101/Allen/k8slearn/operator/k8s-test-operator
docker buildx build --platform linux/amd64 \
-t <your-registry>/k8s-test-operator:latest \
--push .
实际执行效果:
[+] Building 199.0s (16/16) FINISHED
=> [builder 7/7] RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o manager ./main.go 35.1s
=> pushing <your-registry>/k8s-test-operator:latest 9.5s
Step 4: 清理已存在的资源
kubectl delete crd k8stests.apps.cncamp.io --ignore-not-found=true
kubectl delete ns service-test --ignore-not-found=true
kubectl delete ns k8s-test-operator-system --ignore-not-found=true
实际执行效果:
customresourcedefinition.apiextensions.k8s.io "k8stests.apps.cncamp.io" deleted
namespace "service-test" deleted
namespace "k8s-test-operator-system" deleted
Step 5: 安装 Operator
helm install k8s-test-operator ./operator_helm
实际执行效果:
NAME: k8s-test-operator
LAST DEPLOYED: Sun Feb 15 06:30:14 2026
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
Step 6: 查看 Operator 运行状态
kubectl get pods -n k8s-test-operator-system
实际执行效果:
NAME READY STATUS RESTARTS AGE
k8s-test-operator-controller-manager-6b8b9c5d4d 1/1 Running 0 25s
Step 7: 查看 Operator 日志
kubectl logs -n k8s-test-operator-system deployment/k8s-test-operator-controller-manager --tail=10
实际执行效果:
2026-02-14T22:30:21.562Z INFO controller-runtime.metrics Metrics server is starting to listen {"addr": ":8080"}
2026-02-14T22:30:21.563Z INFO setup starting manager
2026-02-14T22:30:21.563Z INFO controller.k8stest Starting EventSource {"reconciler group": "apps.cncamp.io", "reconciler kind": "K8sTest"}
2026-02-14T22:30:21.665Z INFO controller.k8stest Starting workers {"worker count": 1}
Step 8: 创建目标命名空间并部署示例 CR
kubectl create namespace service-test
helm upgrade k8s-test-operator ./operator_helm --set createExampleCR=true
实际执行效果:
namespace/service-test created
Release "k8s-test-operator" has been upgraded. Happy Helming!
NAME: k8s-test-operator
LAST DEPLOYED: Sun Feb 15 06:31:15 2026
NAMESPACE: default
STATUS: deployed
REVISION: 2
Step 9: 查看自动创建的微服务
kubectl get all -n service-test
实际执行效果:
NAME READY STATUS RESTARTS AGE
pod/etcd-0 1/1 Running 0 45s
pod/product-service-7c8f9b6d5d-abc12 1/1 Running 0 30s
pod/product-service-7c8f9b6d5d-def34 1/1 Running 0 30s
pod/trade-service-8d9g0c7e6e-ghi56 1/1 Running 0 30s
pod/trade-service-8d9g0c7e6e-jkl78 1/1 Running 0 30s
pod/user-service-9e0h1d8f7f-mno90 1/1 Running 0 30s
pod/user-service-9e0h1d8f7f-pqr12 1/1 Running 0 30s
pod/web-service-0f1i2e9g8g-stu34 1/1 Running 0 30s
pod/web-service-0f1i2e9g8g-vwx56 1/1 Running 0 30s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/etcd ClusterIP 10.96.100.1 <none> 2379/TCP 45s
service/product-service ClusterIP 10.96.100.2 <none> 9002/TCP 30s
service/trade-service ClusterIP 10.96.100.3 <none> 9003/TCP 30s
service/user-service ClusterIP 10.96.100.4 <none> 9001/TCP 30s
service/web-service NodePort 10.96.100.5 <none> 8888:30888/TCP 30s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/product-service 2/2 2 2 30s
deployment.apps/trade-service 2/2 2 2 30s
deployment.apps/user-service 2/2 2 2 30s
deployment.apps/web-service 2/2 2 2 30s
Step 10: 测试 API 接口
curl "http://<your-node-ip>:30888/api/user/1"
实际执行效果:
{
"user_id": 1,
"username": "alice",
"email": "alice@example.com",
"created_at": "2024-01-15T10:30:00Z"
}
六、实战:部署 tenant-operator
部署步骤
Step 1: 验证 Helm Chart
cd /Volumes/mac_data/code/go_code/101/Allen/k8slearn/operator/tenant_helm
helm lint .
实际执行效果:
==> Linting .
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
Step 2: 构建并推送 Operator 镜像
cd /Volumes/mac_data/code/go_code/101/Allen/k8slearn/operator/tenant-operator
docker buildx build --platform linux/amd64 \
-t <your-registry>/tenant-operator:latest \
--push .
实际执行效果:
[+] Building 199.0s (16/16) FINISHED
=> [builder 7/7] RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o manager ./main.go 35.1s
=> pushing <your-registry>/tenant-operator:latest 9.5s
Step 3: 清理已存在的资源
kubectl delete crd tenants.tenant.cncamp.io --ignore-not-found=true
kubectl delete ns demo --ignore-not-found=true
kubectl delete ns tenant-operator-system --ignore-not-found=true
实际执行效果:
customresourcedefinition.apiextensions.k8s.io "tenants.tenant.cncamp.io" deleted
namespace "demo" deleted
清理完成
Step 4: 安装 Operator
helm install tenant-operator ./tenant_helm
实际执行效果:
NAME: tenant-operator
LAST DEPLOYED: Sun Feb 15 06:43:14 2026
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
Step 5: 查看 Operator 运行状态
kubectl get pods -n tenant-operator-system
实际执行效果:
NAME READY STATUS RESTARTS AGE
tenant-operator-897d44ffc-z5gbg 1/1 Running 0 25s
Step 6: 查看 Operator 日志
kubectl logs -n tenant-operator-system deployment/tenant-operator --tail=10
实际执行效果:
2026-02-14T22:43:21.562Z INFO controller-runtime.metrics Metrics server is starting to listen {"addr": ":8080"}
2026-02-14T22:43:21.563Z INFO setup starting manager
2026-02-14T22:43:21.563Z INFO controller.tenant Starting EventSource {"reconciler group": "tenant.cncamp.io", "reconciler kind": "Tenant"}
2026-02-14T22:43:21.665Z INFO controller.tenant Starting workers {"worker count": 1}
Step 7: 创建示例租户
helm upgrade tenant-operator ./tenant_helm --set createExampleTenant=true
实际执行效果:
Release "tenant-operator" has been upgraded. Happy Helming!
NAME: tenant-operator
LAST DEPLOYED: Sun Feb 15 06:44:15 2026
NAMESPACE: default
STATUS: deployed
REVISION: 3
Step 8: 验证租户创建结果
kubectl get tenant
实际执行效果:
NAME AGE
demo-tenant 5s
kubectl get ns demo
实际执行效果:
NAME STATUS AGE
demo Active 5s
kubectl get resourcequota -n demo
实际执行效果:
NAME AGE REQUEST LIMIT
object-counts 5s configmaps: 2/10, secrets: 0/10, services: 0/5
七、精华提炼
核心要点(只保留干货)
| 要点 | 说明 | 为什么重要 |
|---|---|---|
| 一个命令部署 | helm install 替代多个 kubectl apply |
提高效率,减少错误 |
| 版本管理 | Helm 自动记录每次部署的版本 | 方便回滚和追溯 |
| 参数化配置 | 通过 values.yaml 或 --set 自定义配置 | 灵活适配不同环境 |
| 模板复用 | 同一个 Chart 可用于多个环境 | 减少重复工作 |
| Helm + Operator | Helm 安装,Operator 运维 | 最佳实践组合 |
必须记住的
1. Helm Chart = Chart.yaml + values.yaml + templates/
2. helm install 安装,helm upgrade 升级,helm rollback 回滚
3. values.yaml 定义默认值,--set 覆盖默认值
4. Helm 负责"生"(安装),Operator 负责"养"(运维)
5. CRD 建议单独管理,避免 Helm 卸载时删除 CR
八、行动清单
立即可做(5分钟内)
- 运行
helm list查看已安装的 Chart - 运行
helm history k8s-test-operator查看版本历史 - 运行
helm get values k8s-test-operator查看当前配置
本周实践
- 尝试
helm upgrade修改 Operator 配置 - 尝试
helm rollback回滚到上一个版本 - 阅读一个 Helm Chart 的 templates/ 目录
进阶挑战
- 创建自己的 Helm Chart
- 添加 Helm Chart 测试(helm test)
- 发布 Helm Chart 到仓库
九、金句收藏
原文金句:
"Helm is the first application package manager for Kubernetes"
—— Helm 官方
我的总结金句:
🎯 "Helm 是装修队,Operator 是物业管家;一个负责安装,一个负责运维"
🎯 "一个 helm install 替代六个 kubectl apply,这就是工具的力量"
🎯 "版本管理、参数配置、一键回滚——Helm 让 Operator 部署从'手工作业'变成'流水线'"
十、画龙点睛
总结升华:
Helm 管理 Operator 的本质,是把"部署"这件事标准化、自动化。
传统部署:
手动执行多个命令 → 容易遗漏 → 没有版本记录 → 回滚困难
Helm 部署:
一个命令完成 → 自动处理依赖 → 版本自动记录 → 一键回滚
这不只是工具的进步,更是运维思维的转变:
从"手动执行"到"声明式配置"
从"一次性部署"到"版本化管理"
从"手工作业"到"流水线作业"
学会 Helm 管理 Operator,不只是学会一个工具,更是学会一种运维理念。
悬念预告:
今天我们学会了如何用 Helm 部署 Operator,但有一个问题:
如何开发一个完整的 Helm Chart?有哪些最佳实践?
下一篇文章,我们将深入讲解:
Helm Chart 开发指南:从模板语法到最佳实践
敬请期待!
一句话带走:
Helm 是 Operator 的"安装程序",负责部署、升级、回滚;一个命令替代多个 kubectl apply
十一、常见问题解答
Q1: Helm 和 kubectl 有什么区别?
回答:
简单来说:kubectl 是"手动工具",Helm 是"自动化工具"
┌─────────────────────────────────────────────────────────────────────────────┐
│ kubectl vs Helm │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ kubectl(手动工具) │
│ ├── 逐个执行:每个资源一个命令 │
│ ├── 无版本管理:不知道之前部署了什么 │
│ └── 无模板功能:每次都要写完整 YAML │
│ │
│ Helm(自动化工具) │
│ ├── 批量执行:一个命令部署所有资源 │
│ ├── 版本管理:记录每次部署的版本 │
│ └── 模板功能:参数化配置,一套模板多环境复用 │
│ │
│ 最佳实践:Helm 管理"应用",kubectl 管理"单个资源" │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Q2: CRD 应该放在 Helm Chart 里吗?
回答:
看情况:
✅ 开发/测试环境:放在 Helm Chart 里
- 优点:管理简单,版本一致
- 缺点:卸载时 CR 会被删除
✅ 生产环境:单独管理 CRD
- 优点:CR 不受 Helm 生命周期影响
- 缺点:需要额外管理 CRD
推荐配置:
# values.yaml
installCRD: true # 开发环境
installCRD: false # 生产环境(手动管理 CRD)
Q3: 如何调试 Helm Chart?
回答:
调试方法:
1. helm lint .
检查 Chart 语法是否正确
2. helm template my-release ./chart
预览生成的 YAML,不实际部署
3. helm install my-release ./chart --dry-run
模拟安装,检查是否有错误
4. helm get manifest my-release
查看已部署的 YAML
5. helm get values my-release
查看当前的配置值
十二、延伸资源
想深入学习:
- Helm 官方文档
- Helm Chart 模板指南
- Artifact Hub - Helm Chart 仓库
想教给别人:
- 用"装修套餐"比喻讲解 Helm Chart 结构
- 用"装修项目管理"比喻讲解 Helm 命令
- 用"装修队 vs 物业管家"对比 Helm 和 Operator
附录:两个 Helm Chart 对比
| 特性 | k8s-test-operator | tenant-operator |
|---|---|---|
| 功能 | 微服务应用部署 | 多租户管理 |
| CRD | K8sTest | Tenant |
| 创建资源 | Deployment, Service, ConfigMap, Ingress | Namespace, ResourceQuota, RoleBinding |
| 适用场景 | 应用一键部署 | 平台级租户隔离 |
| Chart 路径 | operator_helm/ |
tenant_helm/ |
附录:项目源码
- k8s-test-operator Helm Chart:
Allen/k8slearn/operator/operator_helm/ - tenant-operator Helm Chart:
Allen/k8slearn/operator/tenant_helm/
更多推荐

所有评论(0)