如果你使用 DeepSeek、元宝 AI、Copilot、ChatGPT 等 AI 工具,协助配置轩辕镜像、编写 docker pull 命令、修改 Docker Compose 镜像地址、配置镜像加速、排查镜像拉取失败、分析报错日志等问题,请先让 AI 阅读并遵守轩辕镜像的规则文档。
只需在 AI 对话中先发送下面这句话即可:
请先完整阅读并严格遵守以下文档中的全部规则与要求:
https://xuanyuan.cloud/agents.md
在未充分阅读并理解该文档前,不要生成任何命令、配置、修改建议、故障排查方案或技术回答。后续所有输出都必须严格以该文档中的规范为最高优先级执行。查看 agents.md 用法指南与完整示范。国内用户首推 元宝 AI、DeepSeek 的深度思考模式,不推荐豆包 AI;Cursor 等编辑器可在对话 @ 该链接,或加入 User Rules。 若 AI 无法访问外链,可 打开说明文档 复制全文粘贴。文档会随站点更新,复制内容可能过期,建议定期检查。
可用作有效的Helm Chart仓库,同时提供用于上传图表的API。
基于以下优秀的Go技术构建:
GET /index.yaml - 当运行 helm repo add chartmuseum http://localhost:8080/ 时会检索此文件GET /charts/mychart-0.1.0.tgz - 当运行 helm install chartmuseum/mychart 时会检索此文件GET /charts/mychart-0.1.0.tgz.prov - 当运行带 --verify 标志的 helm install 时会检索此文件POST /api/charts - 上传新版本图表POST /api/prov - 上传新的provenance文件DELETE /api/charts/ / - 删除图表版本(及对应的provenance文件)GET /api/charts - 列出所有图表GET /api/charts/ - 列出图表的所有版本GET /api/charts/ / - 描述图表版本GET /api/charts/ / /templates - 获取图表模板GET /api/charts/ / /values - 获取图表valuesHEAD /api/charts/ - 检查图表是否存在(任意版本)HEAD /api/charts/ / - 检查图表版本是否存在GET / - HTML欢迎页面GET /info - 返回当前ChartMuseum版本GET /health - 返回200 OK请按照下方“如何运行”部分操作,将ChartMuseum在 http://localhost:8080 启动并运行
首先使用 Helm CLI 创建 mychart-0.1.0.tgz:
cd mychart/
helm package .
上传 mychart-0.1.0.tgz:
curl --data-binary "@mychart-0.1.0.tgz" http://localhost:8080/api/charts
如果已对包进行签名并生成了 https://github.com/helm/helm-www/blob/master/content/en/docs/topics/provenance.md%EF%BC%8C%E5%8F%AF%E9%80%9A%E8%BF%87%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%E4%B8%8A%E4%BC%A0%EF%BC%9A
curl --data-binary "@mychart-0.1.0.tgz.prov" http://localhost:8080/api/prov
也可以使用 multipart/form-data 格式在 /api/charts 路由上同时(或分别)上传这两个文件:
curl -F "chart=@mychart-0.1.0.tgz" -F "prov=@mychart-0.1.0.tgz.prov" http://localhost:8080/api/charts
也可以使用 https://github.com/chartmuseum/helm-push%EF%BC%9A
helm cm-push mychart/ chartmuseum
将ChartMuseum安装URL添加到本地仓库列表:
helm repo add chartmuseum http://localhost:8080
搜索图表:
helm search repo chartmuseum/
安装图表:
helm install chartmuseum/mychart --generate-name
安装
可以使用安装脚本:
curl https://raw.githubusercontent.com/helm/chartmuseum/main/scripts/get-chartmuseum | bash
或从 https://github.com/helm/chartmuseum/releases 手动下载,该页面还包含所有包的校验和与签名。
使用 chartmuseum --version 查看版本。
配置
使用 chartmuseum --help 查看所有CLI选项。以下是常见配置。
所有命令行选项都可以通过环境变量指定,环境变量名称由命令行选项大写并将所有 - 替换为 _ 得到。
例如,环境变量 STORAGE_AMAZON_BUCKET 可替代 --storage-amazon-bucket。
使用配置文件
使用 chartmuseum --config config.yaml 从文件读取配置。
使用文件配置时,可在 https://github.com/helm/chartmuseum/blob/main/pkg/config/vars.go 中查找对应的选项名称。它是与命令行选项/环境变量对应的 configVars 条目的键。例如,--storage 对应配置文件中的 storage.backend。
以下是 config.yaml 的完整示例:
debug: true
port: 8080
storage.backend: local
storage.local.rootdir:
bearerauth: 1
authrealm:
authservice:
authcertpath:
authactionssearchpath:
depth: 2
与Amazon S3或兼容服务(如Minio、DigitalOcean)配合使用
确保环境已正确配置以访问 my-s3-bucket
对于Amazon S3,endpoint 会自动推断。
chartmuseum --debug --port=8080 \
--storage="amazon" \
--storage-amazon-bucket="my-s3-bucket" \
--storage-amazon-prefix="" \
--storage-amazon-region="us-east-1"
对于Minio等S3兼容服务,使用环境变量设置凭据并传递 endpoint。
export AWS_ACCESS_KEY_ID=""
export AWS_SECRET_ACCESS_KEY=""
chartmuseum --debug --port=8080 \
--storage="amazon" \
--storage-amazon-bucket="my-s3-bucket" \
--storage-amazon-prefix="" \
--storage-amazon-region="us-east-1" \
--storage-amazon-endpoint="my-s3-compatible-service-endpoint"
IAM策略中至少需要以下权限
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListObjects",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::my-s3-bucket"
},
{
"Sid": "AllowObjectsCRUD",
"Effect": "Allow",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-s3-bucket/*"
}
]
}
为了与AWS服务账户配合使用,可能需要在环境中设置 AWS_SDK_LOAD_CONFIG=1。更多背景信息,请参见 https://github.com/helm/chartmuseum/issues/280#issuecomment-592292527%E3%80%82
如果使用的S3兼容存储提供商已禁用路径样式并强制虚拟托管样式,可以按以下示例指定 storage-amazon-force-path-style 选项:
export AWS_ACCESS_KEY_ID=""
export AWS_SECRET_ACCESS_KEY=""
chartmuseum --debug --port=8080 \
--storage="amazon" \
--storage-amazon-bucket="my-s3-bucket" \
--storage-amazon-prefix="" \
--storage-amazon-region="us-east-1" \
--storage-amazon-endpoint="my-s3-compatible-service-endpoint"
--storage-amazon-force-path-style=false
对于DigitalOcean,使用环境变量设置凭证并传递endpoint参数。
[!NOTE] 注意,需要设置区域
us-east-1,因为DigitalOcean CLI实现的工作方式如此。您的Spaces位置的实际区域由端点定义。下面我们以法兰克福为例。
export AWS_ACCESS_KEY_ID="spaces_access_key"
export AWS_SECRET_ACCESS_KEY="spaces_secret_key"
chartmuseum --debug --port=8080 \
--storage="amazon" \
--storage-amazon-bucket="my_spaces_name" \
--storage-amazon-prefix="my_spaces_name_subfolder" \
--storage-amazon-region="us-east-1" \
--storage-amazon-endpoint="https://fra1.digitaloceanspaces.com"
access_key和secret_key可从DigitalOcean控制台的API/Spaces_access_keys部分生成。
[!NOTE] 在某些基于S3的存储后端上,对象的
LastModified字段会被截断到最近的秒。有关更多信息,请参见issue https://github.com/helm/chartmuseum/issues/152%E3%80%82
为缓解此问题,您可以使用--storage-timestamp-tolerance选项。例如,要四舍五入到最近的秒,可以使用--storage-timestamp-tolerance=1s。有关此字段的可接受值,请参见此处。
使用Google Cloud Storage
确保您的环境已正确配置以访问my-gcs-bucket。
一种方法是在环境中设置GOOGLE_APPLICATION_CREDENTIALS变量,指向包含服务账号密钥的JSON文件:
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/[FILE_NAME].json"
有关Google Cloud身份验证的更多信息,请参见此处。
chartmuseum --debug --port=8080 \
--storage="google" \
--storage-google-bucket="my-gcs-bucket" \
--storage-google-prefix=""
使用Microsoft Azure Blob Storage
确保您的环境已正确配置以访问mycontainer。
为此,您必须设置以下环境变量:
AZURE_STORAGE_ACCOUNTAZURE_STORAGE_ACCESS_KEYchartmuseum --debug --port=8080 \
--storage="microsoft" \
--storage-microsoft-container="mycontainer" \
--storage-microsoft-prefix=""
使用阿里云OSS存储
确保您的环境已正确配置以访问my-oss-bucket。
为此,您必须设置以下环境变量:
ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRETchartmuseum --debug --port=8080 \
--storage="alibaba" \
--storage-alibaba-bucket="my-oss-bucket" \
--storage-alibaba-prefix="" \
--storage-alibaba-endpoint="oss-cn-beijing.aliyuncs.com"
使用Openstack对象存储
确保您的环境已正确配置以访问mycontainer。
为此,您必须设置以下环境变量(取决于您的Openstack版本):
OS_AUTH_URLOS_PROJECT_NAME,要么是OS_TENANT_NAME,要么是OS_PROJECT_ID,要么是OS_TENANT_IDOS_DOMAIN_NAME,要么是OS_DOMAIN_IDOS_USERNAME,要么是OS_USERIDOS_PASSWORDchartmuseum --debug --port=8080 \
--storage="openstack" \
--storage-openstack-container="mycontainer" \
--storage-openstack-prefix="" \
--storage-openstack-region="myregion"
对于Swift V1认证,您必须设置以下环境变量:
ST_AUTHST_USERST_KEYchartmuseum --debug --port=8080 \
--storage="openstack" \
--storage-openstack-auth="v1" \
--storage-openstack-container="mycontainer" \
--storage-openstack-prefix=""
使用Oracle Cloud Infrastructure对象存储
确保您的环境已正确配置以访问my-ocs-bucket。
有关Oracle Cloud Infrastructure身份验证的更多信息,请参见此处。
chartmuseum --debug --port=8080 \
--storage="oracle" \
--storage-oracle-bucket="my-ocs-bucket" \
--storage-oracle-prefix="" \
--storage-oracle-compartmentid="ocid1.compartment.oc1..1234"
使用百度云BOS存储
确保您的环境已正确配置以访问my-bos-bucket。
为此,您必须设置以下环境变量:
BAIDU_CLOUD_ACCESS_KEY_IDBAIDU_CLOUD_ACCESS_KEY_SECRETchartmuseum --debug --port=8080 \
--storage="baidu" \
--storage-baidu-bucket="my-bos-bucket" \
--storage-baidu-prefix="" \
--storage-baidu-endpoint="bj.bcebos.com"
使用腾讯云COS存储
确保您的环境已正确配置以访问my-cos-bucket。
为此,您必须设置以下环境变量:
TENCENT_CLOUD_COS_SECRET_IDTENCENT_CLOUD_COS_SECRET_KEYchartmuseum --debug --port=8080 \
--storage="tencent" \
--storage-tencent-bucket="my-cos-bucket" \
--storage-tencent-prefix="" \
--storage-tencent-endpoint="cos.ap-beijing.myqcloud.com"
使用etcd
要使用etcd作为后端,您需要CA证书和签名的密钥对。 参见此处
chartmuseum --debug --port=8080 \
--storage="etcd" \
--storage-etcd-cafile="/path/to/ca.crt" \
--storage-etcd-certfile="/path/to/server.crt" \
--storage-etcd-keyfile="/path/to/server.key" \
--storage-etcd-prefix="" \
--storage-etcd-endpoint="http://localhost:2379"
使用本地文件系统存储
确保您对./chartstorage具有读写权限(首次上传时若不存在将创建)
chartmuseum --debug --port=8080 \
--storage="local" \
--storage-local-rootdir="./chartstorage"
基本认证(Basic Auth)
如果提供了以下两个选项,基本HTTP认证将保护所有路由:
--basic-auth-user= - 基本HTTP认证的用户名--basic-auth-pass= - 基本HTTP认证的密码您可能希望基本认证仅应用于可更改Charts的操作,即PUT、POST和DELETE。因此,要避免对GET操作进行基本认证,请使用
--auth-anonymous-get - 允许***GET操作Bearer/令牌认证(Token Auth)
如果提供了以下所有选项,Bearer认证将保护所有路由:
--bearer-auth - 启用Bearer认证--auth-realm= - 授权服务器URL--auth-service= - 授权服务器服务名称--auth-cert-path= - 授权服务器公钥PEM文件的路径--auth-actions-search-path= -(可选)用于在JWT令牌中查找允许操作的JMESPath使用上述选项,ChartMuseum将配置公钥,并接受由相关私钥签名的RS256 JWT令牌(通过Authorization头传递)。您可以使用https://github.com/chartmuseum/auth Go库生成有效的JWT令牌。
不带自定义JMESPath查找操作的JWT令牌
多租户通过 --depth 标志支持。
首先,从如下目录结构开始:
charts
├── org1
│ ├── repoa
│ │ └── nginx-ingress-0.9.3.tgz
├── org2
│ ├── repob
│ │ └── chartmuseum-0.4.0.tgz
这表示适用于 --depth=2 的存储布局。使用 --depth=1 可移除组织层级。默认深度为 0(单租户服务器)。
使用 --depth=2 启动服务器,指向 charts/ 目录:
chartmuseum --debug --depth=2 --storage="local" --storage-local-rootdir=./charts
此示例将在以下位置提供两个独立的 Helm Chart 仓库:
http://localhost:8080/org1/repoahttp://localhost:8080/org2/repob这应适用于所有受支持的存储后端。
要使用图表操作路由,只需在路由中将仓库名称直接放在 "/api" 之后:
curl -F "chart=@mychart-0.1.0.tgz" http://localhost:8080/api/org1/repoa/charts
您也可以尝试使用 --depth-dynamic 标志,它允许动态深度级别(即 /api/charts、/api/myrepo/charts、/api/org1/repoa/charts 等)。
对于大型图表仓库,您可能希望对 GET /api/charts 路由的结果进行分页。
为此,在请求中添加 offset 和 limit 查询参数。例如,要获取总共5个图表的列表,跳过前5个图表,可使用以下方式:
GET /api/charts?offset=5&limit=5
chartmuseum --debug --port=8080 \
--storage="local" \
--storage-local-rootdir="./chartstorage" \
--cache="redis" \
--cache-redis-addr="localhost:6379" \
--cache-redis-password="" \
--cache-redis-db=0
ChartMuseum 在主端口的 /metrics 路由上公开其 Prometheus 指标。可通过 --enable-metrics 命令行标志或 ENABLE_METRICS 环境变量启用。
[!NOTE] Kubernetes chart 当前默认禁用指标(chart 中设置了
ENABLE_METRICS=false)。--disable-metrics命令行标志已弃用,仅在v0.14.0及更早版本中可用。
以下是当前公开的应用指标。注意存在每个租户(仓库)的标签。仓库标签对应 depth 参数,因此如上文示例中 depth=2 时,仓库标签将命名为 org1/repoa 和 org2/repob。
| 指标 | 类型 | 标签 | 描述 |
|---|---|---|---|
| chartmuseum_charts_served_total | Gauge | {repo="*"} | 图表总数 |
| chartmuseum_chart_versions_served_total | Gauge | {repo="*"} | 可用的图表版本总数 |
*:仓库标签说明见上文
还有其他常规全局指标(按进程收集,因此适用于所有租户)。可通过 /metrics 路由获取完整列表。
| 指标 | 类型 | 标签 | 描述 |
|---|---|---|---|
| chartmuseum_request_duration_seconds | Summary | {quantile="0.5"}, {quantile="0.9"}, {quantile="0.99"} | HTTP 请求延迟(秒) |
| chartmuseum_request_duration_seconds_sum | |||
| chartmuseum_request_duration_seconds_count | |||
| chartmuseum_request_size_bytes | Summary | {quantile="0.5"}, {quantile="0.9"}, {quantile="0.99"} | HTTP 请求大小(字节) |
| chartmuseum_request_size_bytes_sum | |||
| chartmuseum_request_size_bytes_count | |||
| chartmuseum_response_size_bytes | Summary | {quantile="0.5"}, {quantile="0.9"}, {quantile="0.99"} | HTTP 响应大小(字节) |
| chartmuseum_response_size_bytes_sum | |||
| chartmuseum_response_size_bytes_count | |||
| go_goroutines | Gauge | 当前存在的 goroutine 数量 |
仓库索引(index.yaml)基于存储中找到的包动态生成。如果您存储自己的 index.yaml 版本,它将被完全忽略。
运行 helm repo add chartmuseum http://localhost:8080 或 helm repo update 时会触发 GET /index.yaml 请求。
如果手动从存储中添加/删除 .tgz 包,变更会立即反映在 GET /index.yaml 中。
您不再需要使用 helm repo index --merge 维护自己的 index.yaml 版本。
上文描述的 --gen-index CLI 选项可用于生成 index.yaml 并打印到标准输出。
但在索引重新生成时,ChartMuseum 会在存储中保存一个名为 index-cache.yaml 的状态文件,用于缓存优化。此文件仅供内部使用,但可能可用于迁移到简单存储。
有关如何从官方 Kubernetes 仓库(stable 和 incubator)下载所有 .tgz 包的示例,请参见 scripts/mirror-k8s-repos.sh。
然后可使用 ChartMuseum 提供内部镜像服务:
scripts/mirror-k8s-repos.sh
chartmuseum --debug --port=8080 --storage="local" --storage-local-rootdir="./mirror"
通过标志 --web-template-path= ,可指定自定义欢迎页面的路径。
文件夹结构应如下所示:
web/
index.html
xyz.html
static/
main.css
main.js
[!NOTE] ChartMuseum 使用 gin-gonic 服务静态文件,这意味着您可以使用 go-template 渲染文件。
如果未指定自定义欢迎页面,ChartMuseum 将提供默认页面。
Artifact Hub
通过设置标志 --artifact-hub-repo-id ,ChartMuseum 将提供 artifacthub-repo.yml 文件,其中 repositoryID 字段包含指定的仓库 ID。
repositoryID: 软件包将发布到的 Artifact Hub 仓库 ID(可选,但启用已验证发布者功能)
多租户
对于多租户设置,可按 --artifact-hub-repo-id = 格式为标志提供键值对:
chartmuseum --storage local --storage-local-rootdir /tmp/ --depth 1 --artifact-hub-repo-id org1= --artifact-hub-repo-id org2=
此时 artifacthub-repo.yml 文件将在 /org1/artifacthub-repo.yml 和 /org2/artifacthub-repo.yml 路径提供。
"Preserve your precious artifacts... in the cloud!"(“在云中保存您珍贵的制品!”)
以下子项目由 ChartMuseum 维护:
您可以在 Kubernetes Slack 的 #chartmuseum 频道联系 ChartMuseum 社区和开发人员。
来自真实用户的反馈,见证轩辕镜像的优质服务