应用商店开发手册
KubeGems 应用商店采用标准的 Helm3 对应用进行打包,应用商店内的 Charts 全部位于仓库 appstore-charts 。这里面大部分都来源于 Bitnami、helm offical以及部分自写的 charts 包。由于 KubeGems 还不支持在界面上传自定义Charts,所以需要将本仓库构建出镜像,并提交 charts-updater
任务触发应用商店更新。
什么是ChartMuseum
ChartMuseum是一个用Go(Golang)编写的开源Helm Chart Repository服务器,支持云存储后端,包括Google云存储,Amazon S3,Microsoft Azure Blob存储,阿里云OSS存储,Openstack对象存储和Oracle云基础架构对象存储.
开发约束
资源名称
在 charts 的 schema 文件中资必须声明 nameOverride
和fullnameOverride
为必填项。
info
为了保证通过 helm 部署应用的资源名称与应用商店填写的最终一致。KubeGems 前端在提交 values 资源时,会将应用名称同时写入到nameOverride
和fullnameOverride
这个两个变量
例如: consul/values.schema.json
"properties": {
"nameOverride": {
"type": "string",
"title": "Consul容器名",
"form": true
},
"fullnameOverride": {
"type": "string",
"title": "Consul服务名",
"form": true
},
监控数据采集
在开发 charts 或集成第三方 charts 时,如果 charts 内部已经带了监控采集的模板(大部分由 prometheus-operator实现),默认将它关闭
info
KubeGems 的接入中心提供了第三方组件的 exporter charts 模板,如果用户集成的第三方 charts 中包含了 serviceMonitor,虽然能被 kubeGems 的 prometheus 采集,当无法通过界面查询数据
例如: consul/values.schema.json
"metrics": {
"type": "object",
"form": true,
"title": "监控服务",
"properties": {
"enabled": {
"type": "boolean",
"title": "启用监控采集端",
"default": false, \\默认关闭
"form": true
}
}
}
Charts 多国语言设置
Helm Charts 默认并没有设计多国语言的配置,KubeGems 在应用商店中加载应用部署时的表单处自行设计了规范,可参考如下
多国语言 json.schema 文件保存在 charts 根下的 i18n目录内,按照语言缩写命名文件
charts
├── i18n
│ └── values.en.json // en_US
│ └── values.jp.json // ja_JP
├── Chart.yaml
├── README.md
├── charts
│ └── common
├── ci
├── templates
├── values.schema.json //default zh_CN
└── values.yaml
多语言内容格式与默认保持一致即可,例如 values.en.json
{
"properties": {
"nameOverride": {
"title": "Zookeeper Name"
},
"fullnameOverride": {
"title": "Zookeeper Fullname"
},
"replicaCount": {
"title": "ReplicaCount"
},
"maxClientCnxns": {
"title": "Max Client Connections"
},
"persistence": {
"properties": {
"enabled": {
"title": "Enable PVC"
},
"size": {
"title": "Capacity"
},
"storageClass": {
"title": "StorageClass"
}
}
},
"metrics": {
"title": "Service Monitor",
"properties": {
"enabled": {
"title": "Enable"
}
}
}
}
}
操作说明
Charts打包
$ make package
构建 docker 镜像
$ make build
更新应用商店
$ make apply
info
修改 Makefile 的CHARTS_UPLOADER
变量将 build 成功的镜像推送在您的私有镜像仓库
通过调用 Chartsmuseum API 更新
设置 Nodeport 将 kubegems-chartmuseum 的服务暴露出来,通过以下命令上传 charts 包。由于
$ curl --data-binary "@<charts包路径>" -w "%{stdout}\n" <chartmuseum地址>/api/kubegems/charts
为 Exporter 类应用设置告警
KubeGems 的应用商店中包含诸多 exporter 类型的 charts,它们的主要作用是为 KubeGems 接入中心提供中间件的监控数据接入能力。
如果您自己开发 appstore-charts 仓库中的中间件 exporter 需遵循如下两条规则
- values 和 schema 文件中设计
alert.eneabled
字段用于判断在部署中是否创建告警规则
alerts:
## If true, a PrometheusRule CRD is created for a prometheus operator
## https://github.com/coreos/prometheus-operator
##
## The rules will be processed as Helm template, allowing to set variables in them.
enabled: true
- 在 charts 的根目录下创建
alerts.yaml
文件,内容为中间件的告警规则,
以下是示例演示
- name: MongodbDown
namespace: __namespace__
expr: mongodb_up{service="__fullname__",namespace="__namespace__"}
message: MongoDB [namespace {{ $labels.namespace }}] [service {{ $labels.service }}] [instance {{ $labels.instance }}] down
for: 0m
alertLevels:
- compareOp: "=="
compareValue: "0"
severity: critical
receivers:
- name: gemcloud-default-webhook
interval: 10m
info
在告警规则的查询语句中必须包含 server="__fullname__"
和 namespace="__namespace__"
这两个标签,它们的作用是用于定位 exporter 的信息。
info
gemcloud-default-webhook 是 KubeGems 内置 webhook 用户将告警事件推送到前端气泡当中
- 自动构建告警规则
$ make generate
info
make命令会扫描仓库内 exporter 应用,并在其 charts.template 下自动创建 prometheusrules.yaml
和 alertmanagerconfig.yaml
常用命令
helm
- 查看所有charts
$ helm search repo xxx
- 下载依赖到charts目录
$ helm dependency update
- helm 本地渲染模板
$ helm template .
- 生成charts索引文件index.yaml
$ helm repo index [DIR] [flags]
JsonSchema 说明
关于 chart 模式文 件values.schema.json, 请参考: https://helm.sh/zh/docs/topics/charts/
KubeGems 应用商店部署页面的中间件表单, 采用 schema文件进行渲染, 针对滑块组件和嵌套依赖组件的渲染, 通过自定义的字段 render 和 hidden 实现,下面是 Kafka 的参考 values.schema.json
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"properties": {
"nameOverride": {
"type": "string",
"title": "nameOverride(Kafka实例名称)",
"description": "Kafka部署到Kubernetes中的Workerload名称",
"form": true
},
"fullnameOverride": {
"type": "string",
"title": "fullnameOverride(Kafka服务名称)",
"description": "Kafka部署到Kubernetes中的Service名称",
"form": true
},
"replicaCount": {
"type": "integer",
"title": "replicaCount(Kafka副本数)",
"form": true,
"default": 1
},
"persistence": {
"type": "object",
"form": true,
"title": "PersistetVolume设置",
"properties": {
"enabled": {
"type": "boolean",
"title": "enabled(启用PersistentVolumeClaim)",
"form": true,
"description": "为Kafka集群提供持久化存储"
},
"size": {
"type": "string",
"title": "size(PersistentVolume空间)",
"form": true,
"render": "slider",
"sliderMin": 1,
"sliderMax": 100,
"sliderUnit": "Gi",
"description": "Kafka持久化磁盘空间容量,默认Gi",
"default": "10Gi",
"hidden": {
"condition": false,
"value": "enabled"
}
},
"storageClass": {
"type": "string",
"title": "StorageClass名称",
"form": true,
"description": "PersistentVolume使用的存储声明",
"hidden": {
"condition": false,
"value": "enabled"
}
}
}
},
"zookeeper": {
"type": "object",
"form": true,
"title": "Zookeeper设置",
"properties": {
"enabled": {
"type": "boolean",
"title": "enabled(启用Zookeeper服务)",
"form": true,
"default": true,
"description": "创建一个Zookeeper集群"
},
"replicaCount": {
"type": "integer",
"title": "replicaCount(Zookeeper集群副本数)",
"form": true,
"default": 1,
"hidden": {
"condition": false,
"value": "enabled"
}
},
"persistence": {
"type": "object",
"form": true,
"title": "PersistentVolume设置",
"hidden": {
"condition": false,
"value": "enabled"
},
"properties": {
"enabled": {
"type": "boolean",
"title": "enabled(启用PersistentVolumeCliam)",
"form": true,
"description": "为Zookeeper机器提供持久化存储"
},
"size": {
"type": "string",
"title": "size(PersistentVolume空间)",
"form": true,
"render": "slider",
"sliderMin": 1,
"sliderMax": 100,
"sliderUnit": "Gi",
"default": "2Gi",
"description": "Zookeeper持久化磁盘空间容量,默认Gi",
"hidden": {
"condition": false,
"value": "enabled"
}
},
"storageClass": {
"type": "string",
"title": "StorageClass名称 ",
"form": true,
"description": "PersistentVolume使用的存储声明",
"hidden": {
"condition": false,
"value": "enabled"
}
}
}
}
}
}
}
}
字段说明
官方文档请参考理解JSON Schema
- type: 字段类型, 如果为object则表示有子属性(字段)
- title: 标题, 对应表单标签信息
- form: 表单是否开启, 如果字段没有该字段或为false, 表示不渲染该字段
- default: 默认值
滑块表单
- render: 渲染类型, slider表示滑块, textArea表示文本框
- sliderMin: 滑块最小值
- sliderMax: 滑块最大值
- sliderUnit: 滑块单位
表单关联
schema 中可以同通过简单的判断逻辑来影响其他其他资源的行为。
caution
不支持跨父节点关联
例如,mysql/values.schema.json
通过persistence.enabled
布尔值来判断后续表单是否隐藏
"master": {
"type": "object",
"title": "MYSQL主库设置",
"form": true,
"properties": {
"persistence": {
"type": "object",
"title": "数据持久化设置",
"form": true,
"properties": {
"enabled": {
"type": "boolean",
"title": "启用存储卷",
"form": true
},
"size": {
"type": "string",
"title": "存储卷容量",
"form": true,
"render": "slider",
"sliderMin": 1,
"sliderMax": 100,
"sliderUnit": "Gi",
"default": "10Gi",
"hidden": {
"path": "master/persistence/enabled",
"value": false
}
},
"storageClass": {
"type": "string",
"title": "存储类型",
"form": true,
"hidden": {
"path": "master/persistence/enabled",
"value": false
}
}
}
}
}
},
整数integer
如果字段类型是整数integer, 则必须添加最小值(sliderMin)/最大值(sliderMax), 前端会根据该范围做表单校验, 比如
"replicaCount": {
"type": "integer",
"title": "replicaCount(emqx副本数)",
"default": "3",
"form": true,
"order": 3,
"sliderMin": 1,
"sliderMax": 10
},
常用链接
Helm3 ArtifactHub (https://artifacthub.io)
Mware bitnami (https://bitnami.com/)