K8s 集群部署微服务 - DevOps(一)
| K8s 集群环境搭建 - yaml 版本(一) |
|---|
| K8s 集群部署中间件 - yaml 版本(二) |
| K8s 集群部署微服务 - yaml 版本(三) |
| K8s 集群部署微服务 - DevOps(一) |
文章目录
- [K8s 集群部署微服务 - DevOps(一)](#K8s 集群部署微服务 - DevOps(一))
- 前言
- [一、 Helm](#一、 Helm)
-
- [1. 安装 Helm](#1. 安装 Helm)
- [2. Helm 常用命令:](#2. Helm 常用命令:)
- [二、 kubeSphere](#二、 kubeSphere)
-
- [1. 安装 kubeSphere](#1. 安装 kubeSphere)
- [2. 激活 kubeSphere 社区版](#2. 激活 kubeSphere 社区版)
- [3. 设置 Harbor 为应用仓库](#3. 设置 Harbor 为应用仓库)
- 三、部署中间件
-
- [1. 部署 mysql](#1. 部署 mysql)
- [2. 部署 nacos](#2. 部署 nacos)
- 四、疑问与总结
前言
- 在前面我们手动搭建了 k8s 集群,并手动使用命令行部署了 中间件、微服务项目。部署的过程中深刻体会到了过程繁琐、yaml 文件难以管理的痛点。
- 接下来我们使用 kubeSphere 和 helm 来解决这个痛点,实现 CI/CD,从代码提交后,后续流程通过配置的流水线自动化更新部署。
一、 Helm
-
Helm 是 Kubernetes 的包管理工具,可以方便的发现、共享和构建 kubernetes 应用。可以解决每次部署中间件或微服务众多yaml 文件难以管理、已经多集群环境下的yaml 文件无法重用的问题。我们可以可以通过 Helm 构建 chart,使用chart 来构建应用。Helm 组件如下:Chart:包含部署 k8s 一个应用所有的yaml (比如 deployment,services,ingress,configMap)文件以及其他申明文件(比如版本,变量信息),一起整合后的 chart 包。Helm 同步部署该 chart 包来部署应用,解决了之前我们部署应用yaml文件难以管理的问题。Helm 客户端:负责和 k8s apiserver 通信。Release:使用 chart 包部署生成的一个实例就是 Release。部署多次就生成多个 Release。Repository:用于发布和存储 chart 的仓库,类似于 docker 仓库,我后面使用的是 harbor 作为 仓库。
-
chart 目录结构如下:
javamysql-chart/ ├── charts # 存放当前Chart依赖的子Chart(子图表),无依赖时为空 ├── Chart.yaml # Chart元数据文件,存储名称、版本、描述等核心信息 ├── templates # Kubernetes资源模板目录,Helm会渲染生成最终YAML │ ├── deployment.yaml # 定义Deployment资源,管理MySQL Pod的创建、扩容和自愈 │ ├── _helpers.tpl # 模板辅助函数库,存放可复用的模板片段(如名称、标签定义) │ ├── hpa.yaml # 定义HPA(水平自动扩缩容),根据资源使用率调整Pod数量 │ ├── httproute.yaml # 定义Gateway API的HTTPRoute,用于流量路由(替代传统Ingress) │ ├── ingress.yaml # 定义Ingress资源,暴露服务到集群外(MySQL常用NodePort/LoadBalancer) │ ├── NOTES.txt # 部署成功后的提示信息,指导用户使用应用(如连接方式) │ ├── serviceaccount.yaml # 定义ServiceAccount,为Pod提供Kubernetes API访问权限 │ ├── service.yaml # 定义Service资源,为MySQL Pod提供固定访问地址和端口 │ └── tests # 测试用例目录,验证应用部署是否成功 │ └── test-connection.yaml # Helm测试钩子,部署后测试MySQL连接可用性 └── values.yaml # Chart配置文件,存储所有可配置参数(如镜像、资源、密码等) -
Helm 常用内置对象:
类别 核心对象 作用 Release .Release 包含当前 Release(部署实例)的元信息(名称、版本、命名空间等) Chart .Chart 包含当前 Chart 的元数据(名称、版本、描述等,来自 Chart.yaml) Values .Values 包含用户配置的参数(来自 values.yaml 或 --set 参数),属性由用户自定义 Files .Files 读取 Chart 内的非模板文件(如配置文件、证书) Capabilities .Capabilities 描述 K8s 集群的能力(版本、支持的 API 资源等) Template .Template 包含当前模板文件的元信息(名称、路径) -
.Release:
子属性 说明 示例值 .Release.Name Release 名称(helm install 指定的名称) my-mysql .Release.Namespace Release 部署的命名空间(未指定时为 default) mysql-prod .Release.Revision Release 的版本号(首次安装为 1,每次升级 / 回滚递增) 2 .Release.IsInstall 布尔值,是否为首次安装(helm install) true/false .Release.IsUpgrade 布尔值,是否为升级操作(helm upgrade) true/false .Release.IsRollback 布尔值,是否为回滚操作(helm rollback) true/false .Release.Service 部署服务名称(通常为 Helm) Helm .Release.Time Release 操作的时间戳(RFC3339 格式) 2024-05-20T10:00:00Z -
.Chart:
子属性 说明 示例值 .Chart.Name Chart 名称(Chart.yaml 中 name 字段) my-mysql-chart .Chart.Version Chart 版本(Chart.yaml 中 version 字段,SemVer 格式) 1.0.0 .Chart.AppVersion 应用版本(Chart.yaml 中 appVersion 字段,如 MySQL 版本) 8.0.36 .Chart.Description Chart 描述(Chart.yaml 中 description 字段) 自定义 MySQL Chart .Chart.Maintainers 维护者信息(数组,包含 name/email 等) [{name: "张三", email: "zhangsan@example.com"}] .Chart.Dependencies Chart 依赖(数组,来自 Chart.yaml 中 dependencies) [{name: "redis", version: "17.3.12"}] -
.Files:
方法 说明 示例 .Files.Get "path" 读取文件内容(路径为 Chart 内相对路径) .Files.Get "config/my.cnf" .Files.Glob "pattern" 按通配符匹配文件(返回文件列表) .Files.Glob "config/*.yaml" .Files.AsConfig 将文件内容转为 ConfigMap 格式(自动处理键值对) `.Files.Get "config/application.properties" .Files.AsSecrets 将文件内容转为 Secret 格式(Base64 编码) `.Files.Get "certs/tls.key" -
.Capabilities:
子属性 说明 示例 .Capabilities.KubeVersion K8s 版本信息(包含 Major/Minor/GitVersion) {Major: "1", Minor: "25", GitVersion: "v1.25.0"} .Capabilities.APIVersions.Has "group/version" 检查集群是否支持某个 API 版本(如 apps/v1) .Capabilities.APIVersions.Has "apps/v1" .Capabilities.APIVersions.AvailableVersions "group" 获取某个 API 组的所有可用版本 .Capabilities.APIVersions.AvailableVersions "apps" -
.Template
子属性 说明 示例 .Template.Name 当前模板文件的名称(相对路径) templates/deployment.yaml .Template.BasePath Chart 中模板目录的路径(通常为 templates/) templates/
-
1. 安装 Helm
-
一键安装 Helm :
javacurl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash -
安装后查看 Helm 版本:helm version

2. Helm 常用命令:
-
仓库管理(Repository):
helm repo add [仓库名] [仓库地址]:添加远程仓库。helm repo add bitnami https://charts.bitnami.com/bitnami。helm repo update [仓库名]:更新仓库索引(拉取最新 Chart 列表)。helm repo update(更新所有仓库),helm repo update bitnami(仅更新 bitnami 仓库)。helm repo list: 查看已添加的仓库。helm repo remove [仓库名]:移除仓库。helm repo remove bitnami。
-
Chart 操作(Chart):
helm create [chart 名]:创建标准化 Chart 骨架(自动生成目录结构)。helm create my-springboot-chart。helm search repo [仓库名/chart名]: 搜索仓库中的 Chart。helm search repo bitnami/mysql(搜索 bitnami 仓库的 MySQL Chart)
helm search repo nginx --versions(查看所有版本)helm show [values、模板、说明] [仓库名/chart名]:查看 Chart 详细信息(values、模板、说明)。helm show values bitnami/mysql(查看默认配置);helm show chart bitnami/mysql(查看 Chart 元数据);helm show readme bitnami/mysql(查看说明文档)。helm pull [仓库名/chart名]:拉取 Chart 到本地(不安装)。helm pull bitnami/mysql --version 9.10.1(指定版本拉取)。
-
Release 生命周期管理(核心):
helm install [release名] [仓库名/chart名]:安装 Chart 为 Release 。helm install my-mysql bitnami/mysql(默认配置安装);helm install my-mysql bitnami/mysql --set auth.rootPassword=123456 -n mysql --create-namespace(自定义参数 + 指定命名空间);helm install my-app ./my-chart -f custom-values.yaml(用自定义 values 文件安装)helm upgrade 升级已安装的 Release(更新 Chart 版本或配置)。helm upgrade my-mysql bitnami/mysql --set replicaCount=3(更新配置);helm upgrade my-mysql bitnami/mysql --version 9.10.2(升级 Chart 版本)helm rollback:回滚 Release 到历史版本。helm rollback my-mysql 1(回滚到版本 1);helm rollback my-mysql(默认回滚到上一版本)helm uninstall: 卸载 Release(删除应用及相关资源)。helm uninstall my-mysql -n mysqlhelm list:查看已安装的 Release。helm list(默认显示当前命名空间);helm list -A(显示所有命名空间);helm list -n mysql(指定命名空间)
-
调试与模板渲染:
helm template [release名] [仓库名/chart名]: 渲染 Chart 模板(不部署,仅输出 YAML)。helm template my-mysql bitnami/mysql --set auth.rootPassword=123456。helm install [release名] [仓库名/chart名] --dry-run:模拟安装(检查配置和依赖,不实际部署)。helm install my-mysql bitnami/mysql --dry-run --debug(--debug 显示详细日志)helm get [release名] :获取 Release 的已渲染模板、values 或 hooks。helm get values my-mysql(查看当前使用的 values 配置);helm get manifest my-mysql(查看已部署的 YAML 清单)
-
其他常用命令:
- helm version:查看 Helm 版本 helm version
- helm help:查看命令帮助(万能调试) helm help install(查看 install 命令详情)。helm install --help
- helm test :运行 Release 的测试用例(验证应用可用性) helm test my-mysql -n mysql
- helm plugin :管理 Helm 插件(扩展功能)。 helm plugin install https://github.com/chartmuseum/helm-push(安装推送插件)。
二、 kubeSphere
- kubeSphere 简介:一款基于 Kubernetes 构建的开源容器平台,简化 Kubernetes 集群的部署、运维和应用管理流程,降低云原生技术的使用门槛。可视化运维:KubeSphere 对 Helm 部署的应用提供监控、日志、伸缩等一体化运维;
- kubeSphere 的
核心定位:- 为 Kubernetes 提供可视化的操作界面,替代复杂的 kubectl 命令行操作;
- 集成丰富的云原生组件(如 DevOps、监控、日志、服务网格等),实现一站式集群管理;
- 支持多集群统一管理,适配公有云、私有云、混合云等多种部署环境。
- KubeSphere 的核心
功能模块:集群与节点管理:可视化管理 Kubernetes 集群的节点、命名空间、资源配额、存储卷等核心资源;支持集群的扩缩容、节点状态监控、污点和容忍度配置,简化集群运维。应用生命周期管理:提供应用商店(App Store),支持 Helm Chart 一键部署主流云原生应用(如 MySQL、Redis、Elasticsearch 等);支持应用的发布、回滚、扩缩容和版本管理,支持无状态 / 有状态应用部署。DevOps 平台:内置 CI/CD 流水线,兼容 Jenkins 核心能力,支持代码仓库(GitLab/GitHub)、镜像仓库(Harbor)无缝集成;提供代码检查、自动化构建、测试、部署的全流程支持,适配 DevOps 实践落地。监控与可观测性:集成 Prometheus 和 Grafana,实现集群、节点、Pod、应用的多维度指标监控和可视化;支持日志收集(ELK/Loki)、链路追踪(Jaeger/Zipkin),快速定位系统故障。服务网格(ServiceMesh):基于 Istio 实现服务网格的可视化管理,支持流量治理(熔断、限流、路由)、服务监控、分布式追踪;无需修改业务代码,即可实现微服务的高可用和可观测性。多租户与权限管理:基于 Kubernetes RBAC 实现细粒度的权限控制,支持企业级的租户(工作空间)、角色、项目管理;适配多团队协作的资源隔离和权限分配需求。存储与网络管理:支持主流存储插件(如 CSI、NFS、Ceph)和网络插件(Calico、Flannel)的可视化配置;提供存储类(StorageClass)、负载均衡(Service/Ingress)的便捷管理。
1. 安装 kubeSphere
-
kubeSphere 的部署有以下三种:
- All-in-One 单节点部署:适用于测试和开发环境,一键部署 KubeSphere 和 Kubernetes 所有组件。
- Multi-Node 多节点部署:适用于生产环境,支持高可用集群部署,可指定主节点和工作节点。
- Kubernetes 集群上部署:在已有的 Kubernetes 集群(如 EKS、ACK、自建集群)上安装 KubeSphere,仅部署平台组件,复用现有集群资源。我们之前已经部署过了 k8s 集群,这里便直接通过如下方式进行部署。所有的部署、使用方式参考自官网。
-
安装 helm 3:helm 官网安装教程
javacurl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh -
验证 helm,查看版本:
javahelm version -
添加 Helm 国内仓库:
java# 华为云 Helm 仓库 helm repo add huawei https://mirrors.huaweicloud.com/kubernetes-charts/ # 阿里云 Helm 仓库 helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts # 更新仓库索引(关键步骤,确保获取最新 Chart 列表) helm repo update # 验证查看已添加的仓库 helm repo list -
安装 KubeSphere 的核心组件:KubeSphere Core (ks-core) 。KubeSphere Core 安装完成后,即可访问 KubeSphere Web 控制台。
javachart=oci://hub.kubesphere.com.cn/kse/ks-core version=1.2.3 helm upgrade --install -n kubesphere-system --create-namespace ks-core $chart --debug --wait --version $version --reset-values --set extension.imageRegistry=swr.cn-north-9.myhuaweicloud.com/ks -
如下提示标识安装成功:首次登录需要提示中的用户名和密码,并且第一次登录成功后会让我们修改密码。

-
访问提示中的 30880 端口进行访问:安装完成。

2. 激活 kubeSphere 社区版
- 登录 kubeSphere 之后,我们需要激活kubeSphere社区办,不然部分功能不可用,步骤如下:
-
登录 KubeSphere Web 控制台,点击组件坞 > 平台设置 > 许可证,进入许可证页面,获取当前集群的集群 ID:

-
申请 KubeSphere 社区版的免费许可。填入个人信息和集群 ID,提交申请。

-
提交申请之后会收到邮件,将邮件中的 license 复制到KubeSphere Web 控制台的许可证页面,点击添加许可证。

-
3. 设置 Harbor 为应用仓库
-
我的 harbor 版本如下:v2.11.1

-
该版本的 harbor 需要注意以下几点:
- Harbor 2.8 版本及之后移除 ChartMuseum,全面转向 OCI 管理 Helm Chart,这是 2.8 最核心的变化,彻底删除了 Helm Chart 仓库的传统实现 ChartMuseum,所有 Helm Chart 必须以 OCI 制品形式存储和分发,与容器镜像共用存储和权限体系,不再支持--with-chartmuseum启动参。
- Harbor 2.8 及以后版本(包括 v2.11)在创建 Charts 仓库时,无需单独创建 "Helm Charts 仓库",而是与 Docker 镜像仓库统一合并为OCI 制品仓库,即不再区分 "镜像仓
- 库" 和 "Charts 仓库"。
-
所以我们添加 harbor 为应用仓库时,需要设置 OIC://,而不是 http:// 或 https://。如下:

-
其中的域名 mortal.harbor.com 需要配置在coredns 中,不然会报:
no such hostjavakubectl edit configmap coredns -n kube-system -
添加如下配置:

-
保存退出后,重启 CoreDNS 生效:
javakubectl rollout restart deployment coredns -n kube-system -
还需要给 kubeSphere 配置 harbor 的证书,添加授权,不然验证无法通过,会报 401:unauthorized。

-
添加 harbor 为应用仓库,具体交互流程如下:
java用户点击"添加仓库" ↓ ks-apiserver 接收请求 ↓ ks-apiserver 尝试连接 Harbor (验证证书) ← 需要证书信任 ↓ 返回"连接成功"给用户界面 ↓ ks-controller-manager 检测到新仓库需要同步 ↓ ks-controller-manager 开始拉取 Helm Chart 索引 ← 需要证书信任 ↓ 同步状态更新为"成功" -
获取 Harbor CA 证书:
javaecho | openssl s_client -connect mortal.harbor.com:443 -showcerts 2>/dev/null | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > /tmp/harbor-ca.crt -
创建 CA 证书 ConfigMap,用于给 ks-apiserver 和 ks-controller-manager 进行挂载:
javakubectl create configmap harbor-ca-cert \ --from-file=harbor-ca.crt=/tmp/harbor-ca.crt \ -n kubesphere-system -
为 ks-apiserver 添加证书挂载:
java# 编辑 ks-apiserver 部署 kubectl edit deployment ks-apiserver -n kubesphere-systemjava# 1. 在 spec.template.spec.containers 中找到 ks-apiserver 容器 # 在 containers 下的 volumeMounts 部分添加: volumeMounts: - mountPath: /etc/ssl/certs/harbor-ca.crt # 挂载路径 name: harbor-ca-volume # 卷名称 subPath: harbor-ca.crt # 引用 ConfigMap 中的文件名 readOnly: true # 2. 在 spec.template.spec.volumes 部分添加: volumes: - name: harbor-ca-volume # 卷名称,与上面匹配 configMap: name: harbor-ca-cert # ConfigMap 名称 defaultMode: 420 # 权限 0644 -
为 ks-controller-manager 添加证书挂载:
java# 编辑 ks-controller-manager 部署 kubectl edit deployment ks-controller-manager -n kubesphere-systemjava# 在 ks-controller-manager 容器的 volumeMounts 部分添加: volumeMounts: - mountPath: /etc/ssl/certs/harbor-ca.crt name: harbor-ca-volume subPath: harbor-ca.crt readOnly: true # 在 volumes 部分添加: volumes: - name: harbor-ca-volume configMap: name: harbor-ca-cert defaultMode: 420 -
保存后,pod 会重启,等待重启后验证:
java# 验证证书文件 kubectl exec deployment/ks-controller-manager -n kubesphere-system -- cat /etc/ssl/certs/harbor-ca.crt | head -3 # 应显示:-----BEGIN CERTIFICATE----- -
配置完之后,添加 Harbor 应用仓库便可以验证通过了,并且能成功同步。

-
如果还是401,由于 kubeSphere 是社区版,只能有一个应用仓库,并且 UI 界面无法配置 用户密码,可通过控制台手动修改已有的该仓库地址和添加用户密码:
-
编辑现有仓库:
javakubectl edit repo builtin-stable -n kubesphere-system -
修改信息如下:
spec.url:替换为 https://mortal.harbor.com/chartrepo/charts-repo;`spec.credential`:添加认证信息(如果该字段不存在,则添加;如果存在,则更新)java# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: application.kubesphere.io/v2 kind: Repo metadata: annotations: kubesphere.io/alias-name: built-stable kubesphere.io/sync-timestamp: "1764660162" creationTimestamp: "2025-12-02T01:17:35Z" generation: 2 labels: app.kubernetes.io/managed-by: Helm application.kubesphere.io/sync-app-store: "true" kubesphere.io/workspace: system-workspace name: builtin-stable resourceVersion: "11196151" uid: 1a4cffaf-39ab-43d3-8a0e-2f0e9b6ff978 spec: credential: password: Harbor131413 username: admin description: Harbor Helm Repository syncPeriod: 300 url: oci://mortal.harbor.com/charts-repo status: lastUpdateTime: "2025-12-02T12:56:39Z" state: successful
-
三、部署中间件
1. 部署 mysql
-
创建 mysql-chart
javahelm create mysql-chart -
调整文件后结构如下:
javamysql-chart ├── Chart.yaml ├── templates │ ├── configmap.yaml │ ├── secret.yaml │ ├── service.yaml │ └── statefulset.yaml └── values.yaml -
编写 Chart.yaml
javaapiVersion: v2 name: mysql-chart description: A Helm chart for Kubernetes # A chart can be either an 'application' or a 'library' chart. # # Application charts are a collection of templates that can be packaged into versioned archives # to be deployed. # # Library charts provide useful utilities or functions for the chart developer. They're included as # a dependency of application charts to inject those utilities and functions into the rendering # pipeline. Library charts do not define any templates and therefore cannot be deployed. type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) version: 0.1.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. appVersion: "8.3.0" -
编写 values.yaml
java# 镜像配置 image: repository: mortal.harbor.com/mortal/mysql tag: 8.3.0 pullPolicy: IfNotPresent pullSecrets: harbor-creds # 服务配置 service: headless: name: mysql-headless nodePort: name: mysql-service nodePort: 30306 # 存储配置 persistence: enabled: true storageClass: nfs-sc size: 10Gi # MySQL 配置 mysql: rootPassword: "root" # 实际使用时建议通过 --set 覆盖 timezone: "Asia/Shanghai" maxConnections: 1000 serverId: 1 -
编写 configMap.yaml:
javaapiVersion: v1 kind: ConfigMap metadata: name: mysql-config namespace: {{ .Release.Namespace }} data: my.cnf: | [client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 [mysqld] server-id = {{ .Values.mysql.serverId }} log-bin=mysql-bin binlog_expire_logs_seconds = 2592000 sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION' max_connections={{ .Values.mysql.maxConnections }} symbolic-links=0 default-time_zone = '+8:00' character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci -
编写 secret.yaml:
javaapiVersion: v1 kind: Secret metadata: name: mysql-secret namespace: {{ .Release.Namespace }} type: Opaque data: root-password: {{ .Values.mysql.rootPassword | b64enc }} -
编写 service.yaml:
javaapiVersion: v1 kind: Service metadata: name: {{ .Values.service.headless.name }} namespace: {{ .Release.Namespace }} spec: clusterIP: None selector: app: mysql release: {{ .Release.Name }} ports: - port: 3306 targetPort: 3306 type: ClusterIP --- apiVersion: v1 kind: Service metadata: name: {{ .Values.service.nodePort.name }} namespace: {{ .Release.Namespace }} spec: type: NodePort ports: - port: 3306 targetPort: 3306 nodePort: {{ .Values.service.nodePort.nodePort }} selector: app: mysql release: {{ .Release.Name }} -
编写 statefulset.yaml:
javaapiVersion: apps/v1 kind: StatefulSet metadata: name: {{ .Release.Name }}-mysql namespace: {{ .Release.Namespace }} spec: serviceName: {{ .Values.service.headless.name }} replicas: 3 selector: matchLabels: app: mysql release: {{ .Release.Name }} template: metadata: labels: app: mysql release: {{ .Release.Name }} spec: imagePullSecrets: - name: {{ .Values.image.pullSecrets }} containers: - name: mysql image: {{ .Values.image.repository }}:{{ .Values.image.tag }} ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: root-password - name: TZ value: {{ .Values.mysql.timezone }} volumeMounts: - name: mysql-config mountPath: /etc/mysql/conf.d/my.cnf subPath: my.cnf - name: mysql-data mountPath: /var/lib/mysql livenessProbe: exec: command: ["mysqladmin", "ping", "-uroot", "-p$(MYSQL_ROOT_PASSWORD)"] initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: exec: command: ["mysqladmin", "ping", "-uroot", "-p$(MYSQL_ROOT_PASSWORD)"] initialDelaySeconds: 5 periodSeconds: 5 volumes: - name: mysql-config configMap: name: mysql-config volumeClaimTemplates: - metadata: name: mysql-data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: {{ .Values.persistence.size }} storageClassName: {{ .Values.persistence.storageClass }} -
结构如下:
javamysql-chart ├── Chart.yaml ├── templates │ ├── configmap.yaml │ ├── secret.yaml │ ├── service.yaml │ └── statefulset.yaml └── values.yaml -
将 chart 进行打包:
javahelm package nysql-chart -
打完包后推送至 harbor 仓库:
javahelm push mysql-chart-0.1.0.tgz oci://mortal.harbor.com/charts-repo --insecure-skip-tls-verify
-
登录 kubeSphere,点击 [ 企业空间管理 ] -> [ 选择我们要安装的集群 ] -> [ 应用负载 ] -> [ 应用 ] -> [ 创建 ],选择从应用模板创建,选择我们前面创建的 harbor 应用仓库。

-
选择 mysql-chart 安装,安装之后,集群中就可以使用该应用了。

-
并且可以直观的看到部署详情,以及可以直接点击控制扩容或缩容,而不用依赖命令行了。

2. 部署 nacos
-
创建 nacos-chart
javahelm create nacos-chart -
需要对文件进行下调整,结构如下:
javanacos-chart/ ├── Chart.yaml ├── templates │ ├── configmap.yaml │ ├── headless-svc.yaml │ ├── mysql-init-job.yaml │ ├── service.yaml │ └── statefulset.yaml └── values.yaml -
Chart.yaml:
javaapiVersion: v2 name: nacos description: A simple Nacos Helm Chart without _helpers.tpl type: application version: 0.1.0 appVersion: "2.1.1" -
values.yaml:
java# 固定配置(无需动态调整) namespace: mortal-system replicaCount: 3 image: repository: mortal.harbor.com/mortal/nacos tag: 2.1.1 pullPolicy: IfNotPresent # MySQL 配置 mysql: serviceName: mysql-headless rootPassword: root dbName: nacos_config port: 3306 # 存储配置 storage: className: nfs-sc size: 5Gi # 服务配置 service: external: type: NodePort port: 8848 nodePort: 30848 headless: ports: http: 8848 clientRpc: 9848 serverRpc: 9849 # Nacos 配置 nacos: auth: enabled: false cluster: name: mortal-cluster raft: dataDir: /home/nacos/data/raft -
configmap.yaml:
javaapiVersion: v1 kind: ConfigMap metadata: name: nacos-config namespace: {{ .Values.namespace }} data: application.properties: | spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://{{ .Values.mysql.serviceName }}:{{ .Values.mysql.port }}/{{ .Values.mysql.dbName }}?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC db.user=root db.password={{ .Values.mysql.rootPassword }} nacos.core.auth.enabled={{ .Values.nacos.auth.enabled }} nacos.server.ip=0.0.0.0 nacos.naming.data.warmup=true nacos.core.singleton=false nacos.raft.dataDir={{ .Values.nacos.raft.dataDir }} nacos.naming.cluster.name={{ .Values.nacos.cluster.name }} nacos.server.rpc.port={{ .Values.service.headless.ports.serverRpc }} nacos.inetutils.prefer-hostname-over-ip=true # 直接生成集群地址(替代 helpers) nacos.naming.serverAddr={{- $replicas := int .Values.replicaCount -}} {{- $namespace := .Values.namespace -}} {{- $httpPort := .Values.service.headless.ports.http -}} {{- range $i := until $replicas -}} nacos-{{ $i }}.nacos-headless.{{ $namespace }}.svc.cluster.local:{{ $httpPort }}{{- if ne $i (sub $replicas 1) }},{{ end -}} {{- end -}} -
headless-svc.yaml:
javaapiVersion: v1 kind: Service metadata: name: nacos-headless namespace: {{ .Values.namespace }} spec: clusterIP: None ports: - port: {{ .Values.service.headless.ports.http }} targetPort: {{ .Values.service.headless.ports.http }} name: http - port: {{ .Values.service.headless.ports.clientRpc }} targetPort: {{ .Values.service.headless.ports.clientRpc }} name: client-rpc - port: {{ .Values.service.headless.ports.serverRpc }} targetPort: {{ .Values.service.headless.ports.serverRpc }} name: server-rpc selector: app: nacos -
service.yaml:
javaapiVersion: v1 kind: Service metadata: name: nacos-service namespace: {{ .Values.namespace }} spec: type: {{ .Values.service.external.type }} ports: - port: {{ .Values.service.external.port }} targetPort: {{ .Values.service.external.port }} nodePort: {{ .Values.service.external.nodePort }} selector: app: nacos -
我希望部署nacos的时候,同时完成 nacos 相关表的初始化工作。mysql-init-job.yaml:
javaapiVersion: batch/v1 kind: Job metadata: name: nacos-mysql-init-job namespace: {{ .Values.namespace }} labels: app: nacos component: mysql-init env: {{ .Values.env | default "prod" }} # 用 Values 定义环境标签 job-type: init # 自定义标签 spec: backoffLimit: 3 template: spec: restartPolicy: OnFailure containers: - name: mysql-init image: mortal.harbor.com/mortal/mysql:8.3.0 env: - name: MYSQL_ROOT_PASSWORD value: "{{ .Values.mysql.rootPassword }}" - name: MYSQL_SERVICE_NAME value: "{{ .Values.mysql.serviceName }}" - name: NACOS_DB_NAME value: "{{ .Values.mysql.dbName }}" command: ["/bin/sh", "-c"] args: - | until mysql -h $MYSQL_SERVICE_NAME -u root -p$MYSQL_ROOT_PASSWORD --default-auth=mysql_native_password -e "SELECT 1"; do echo "等待 MySQL 服务启动中..." sleep 3 done mysql -h $MYSQL_SERVICE_NAME -u root -p$MYSQL_ROOT_PASSWORD --default-auth=mysql_native_password <<'EOF' CREATE DATABASE IF NOT EXISTS `nacos_config` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE `nacos_config`; -- 1. config_info CREATE TABLE IF NOT EXISTS `config_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(255) DEFAULT NULL COMMENT 'group_id', `content` longtext NOT NULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', `c_desc` varchar(256) DEFAULT NULL COMMENT 'configuration description', `c_use` varchar(64) DEFAULT NULL COMMENT 'configuration usage', `effect` varchar(64) DEFAULT NULL COMMENT 'configuration effect', `type` varchar(64) DEFAULT NULL COMMENT 'configuration type', `c_schema` text COMMENT 'configuration schema', PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='config_info'; -- 2. config_info_aggr CREATE TABLE `config_info_aggr` ( `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL COMMENT 'data_id', `group_id` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL COMMENT 'group_id', `datum_id` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL COMMENT 'datum_id', `content` longtext CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL COMMENT '内容', `gmt_modified` datetime(0) NULL DEFAULT NULL COMMENT '修改时间', `app_name` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT NULL, `tenant_id` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NULL DEFAULT '' COMMENT '租户字段', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `uk_configinfoaggr_datagrouptenantdatum`(`data_id`, `group_id`, `tenant_id`, `datum_id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_bin COMMENT = '增加租户字段' ROW_FORMAT = Dynamic; -- 3. config_info_beta CREATE TABLE IF NOT EXISTS `config_info_beta` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(128) NOT NULL COMMENT 'group_id', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', `content` longtext NOT NULL COMMENT 'content', `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='config_info_beta'; -- 4. config_info_tag CREATE TABLE IF NOT EXISTS `config_info_tag` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(128) NOT NULL COMMENT 'group_id', `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', `tag_id` varchar(128) NOT NULL COMMENT 'tag_id', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', `content` longtext NOT NULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='config_info_tag'; -- 5. config_tags_relation CREATE TABLE IF NOT EXISTS `config_tags_relation` ( `id` bigint(20) NOT NULL COMMENT 'id', `tag_name` varchar(128) NOT NULL COMMENT 'tag_name', `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(128) NOT NULL COMMENT 'group_id', `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', `nid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'nid,自增标识', PRIMARY KEY (`nid`), UNIQUE KEY `uk_configtagrelation_configtag` (`data_id`,`group_id`,`tenant_id`,`tag_name`,`tag_type`), KEY `idx_tag_name` (`tag_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='config_tag_relation'; -- 6. group_capacity CREATE TABLE IF NOT EXISTS `group_capacity` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群', `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值', `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '已使用量', `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置最大大小,0表示使用默认值', `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,0表示使用默认值', `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大总大小,0表示使用默认值', `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大历史配置个数,0表示使用默认值', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_group_id` (`group_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='集群、Group 容量信息表'; -- 7. his_config_info CREATE TABLE IF NOT EXISTS `his_config_info` ( `id` bigint(64) unsigned NOT NULL COMMENT 'id', `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '历史记录ID', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(128) NOT NULL COMMENT 'group_id', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', `content` longtext NOT NULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip', `op_type` char(10) DEFAULT NULL COMMENT 'operation type', `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (`nid`), KEY `idx_gmt_create` (`gmt_create`), KEY `idx_gmt_modified` (`gmt_modified`), KEY `idx_did` (`data_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='多租户改造'; -- 8. tenant_capacity CREATE TABLE IF NOT EXISTS `tenant_capacity` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID', `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值', `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '已使用量', `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置最大大小,0表示使用默认值', `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,0表示使用默认值', `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大总大小,0表示使用默认值', `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大历史配置个数,0表示使用默认值', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_tenant_id` (`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户容量信息表'; -- 9. tenant_info CREATE TABLE IF NOT EXISTS `tenant_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `kp` varchar(128) NOT NULL COMMENT 'kp', `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', `tenant_name` varchar(128) DEFAULT '' COMMENT 'tenant_name', `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc', `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source', `gmt_create` bigint(20) NOT NULL COMMENT '创建时间', `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`), KEY `idx_tenant_id` (`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='tenant_info'; -- 10. users CREATE TABLE IF NOT EXISTS `users` ( `username` varchar(50) NOT NULL PRIMARY KEY COMMENT 'username', `password` varchar(500) NOT NULL COMMENT 'password', `enabled` boolean NOT NULL COMMENT 'enabled' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='users'; -- 11. roles CREATE TABLE IF NOT EXISTS `roles` ( `username` varchar(50) NOT NULL COMMENT 'username', `role` varchar(50) NOT NULL COMMENT 'role', UNIQUE KEY `uk_username_role` (`username`,`role`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='roles'; -- 12. permissions CREATE TABLE IF NOT EXISTS `permissions` ( `role` varchar(50) NOT NULL COMMENT 'role', `resource` varchar(255) NOT NULL COMMENT 'resource', `action` varchar(8) NOT NULL COMMENT 'action', UNIQUE KEY `uk_role_permission` (`role`,`resource`,`action`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='permissions'; -- 13. config_blacklist CREATE TABLE IF NOT EXISTS `config_blacklist` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(255) NOT NULL COMMENT 'group_id', `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_configblacklist_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='配置黑名单'; -- 14. external_storage_config CREATE TABLE IF NOT EXISTS `external_storage_config` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `storage_type` varchar(32) NOT NULL COMMENT '存储类型', `config_key` varchar(128) NOT NULL COMMENT '配置key', `config_value` varchar(2048) NOT NULL COMMENT '配置value', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_externalstorageconfig_storagetype_configkey` (`storage_type`,`config_key`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='外部存储配置'; -- 初始化 Nacos 管理员账号(密码:nacos) INSERT INTO `users` (`username`, `password`, `enabled`) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE); INSERT INTO `roles` (`username`, `role`) VALUES ('nacos', 'ROLE_ADMIN'); INSERT INTO `permissions` (`role`, `resource`, `action`) VALUES ('ROLE_ADMIN', '*', 'all'); EOF echo "Nacos 数据库全量表初始化完成!共创建 14 张表 + 管理员账号" -
statefulset.yaml :
javaapiVersion: apps/v1 kind: StatefulSet metadata: name: nacos namespace: {{ .Values.namespace }} spec: serviceName: nacos-headless replicas: {{ .Values.replicaCount }} selector: matchLabels: app: nacos template: metadata: labels: app: nacos spec: containers: - name: nacos image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - containerPort: {{ .Values.service.headless.ports.http }} name: http - containerPort: {{ .Values.service.headless.ports.clientRpc }} name: client-rpc - containerPort: {{ .Values.service.headless.ports.serverRpc }} name: server-rpc env: - name: NACOS_REPLICAS value: "{{ .Values.replicaCount }}" - name: NACOS_SERVERS # 直接生成集群地址 value: "{{- $replicas := int .Values.replicaCount -}} {{- $namespace := .Values.namespace -}} {{- $httpPort := .Values.service.headless.ports.http -}} {{- range $i := until $replicas -}} nacos-{{ $i }}.nacos-headless.{{ $namespace }}.svc.cluster.local:{{ $httpPort }}{{- if ne $i (sub $replicas 1) }} {{ end -}} {{- end -}}" - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: NACOS_SERVER_PORT value: "{{ .Values.service.headless.ports.http }}" volumeMounts: - name: nacos-config mountPath: /home/nacos/conf/application.properties subPath: application.properties - name: nacos-data mountPath: /home/nacos/data volumes: - name: nacos-config configMap: name: nacos-config volumeClaimTemplates: - metadata: name: nacos-data spec: accessModes: [ "ReadWriteMany" ] storageClassName: "{{ .Values.storage.className }}" resources: requests: storage: "{{ .Values.storage.size }}" -
打包并上传至 harbor:
javahelm package nacos-chart helm push nacos-0.1.0.tgz oci://mortal.harbor.com/charts-repo --insecure-skip-tls-verify -
同步下仓库:

-
部署nacos:

-
验证:成功创建了 nacos-config 及其 14 张表;成功访问 nacos 控制台。


...其他中间件后续再补充,不过都是这样的流程。
四、疑问与总结
- 通过 helm 和 kubeSphere,解决了部署应用的过程中 yaml 文件难以管理,以及 多套集群环境原先需要多套yaml文件的问题。
- yaml 文件交于了 helm 进行管理,以及使用helm 上传应用之后,只需要再部署时选择对应的集群即可,实现多套环境一次部署。
- 同时 kubeSphere 提供了可视化平台,直接可查看日志,缩容,扩容,无需在通过繁琐的命令行进行查看。
- 在部署应用的时候发现,服务(或资源)名称后的后缀格式存在差异,比如一些资源启动后,会接后缀 -0,-1,有些事借 -sdf3j,这样的随机字母,这是为什么呢?
- 有状态资源用有序数字后缀:资源类型为 StatefulSet Pod,保证有状态应用的顺序和唯一性,便于实现持久化存储绑定、集群节点身份识别(如主从选举)。
- 无状态资源用随机字符串后缀:资源类型为 Deployment/Job Pod,避免名称冲突,支持无状态部署。