Lazy loaded image
K8s 部署轻量级私有制品库
Words 1354Read Time 4 min
2025-10-14
2025-11-10
date
related_level
slug
k8s_light_artifact
type
Post
relate_date
summary
通过 ChartMuseum 或 Zot 存储 Chart 和 OCI image
status
Published
tags
k8s
版本管理
最新推荐
category
运维管理
last_updated
Nov 10, 2025 10:02 PM
是否已更新
orginal_page
是否推荐
参考资料
创建 myapp chart
  • mkdir -p ~/project && cd ~/project
  • helm create myapp && cd ./myapp
  • helm package ~/project/myapp
 

Helm chart 存储 chartmuseum

helm 安装 chartmuseum, 部署 s3 存储桶作为存储
  • helm repo add chartmuseum https://chartmuseum.github.io/charts
vim ~/.config/helm/value/chartmuseum.yaml
  • 这里使用了 truenas 部署的兼容 amazon s3 的 Garage 存储桶
  • helm install chartmuseum chartmuseum/chartmuseum \ --namespace chartmuseum --create-namespace \ --set env.open.DISABLE_API=false \ --set env.secret.BASIC_AUTH_USER=admin \ --set env.secret.BASIC_AUTH_PASS=secret \ -f ~/.config/helm/value/chartmuseum.yaml
    • basic_auth 可选, 用户名和密码自行修改
查看运行情况
  • kubectl get pods -n chartmuseum -l app.kubernetes.io/name=chartmuseum -o wide
  • kubectl get svc -n chartmuseum -l app.kubernetes.io/name=chartmuseum -o wide
  • kubectl logs -n chartmuseum $(kubectl get pod -n chartmuseum -l app.kubernetes.io/name=chartmuseum -o jsonpath='{.items[0].metadata.name}') --tail 50
配置 chartmuseum 路由访问
配置 traefik 路由和 DNS 记录
vim ~/.config/k3s/IngressRoute.chartmuseum.yaml
  • kubectl apply -f ~/.config/k3s/IngressRoute.chartmuseum.yaml
添加对应域名的 DNS 记录到 /etc/hosts
  • kubectl -n kube-system get svc -l app.kubernetes.io/name=traefik -o wide
    • 获取 external-ip
  • kubectl logs -n kube-system -l app.kubernetes.io/name=traefik --since=1h --tail=100
  • kubectl -n kube-system describe deploy traefik | grep namespaces
    • 检查是否仅代理特定 namespace
    • 如果不含 chartmuseum 需要修改 providers
      • vim /var/lib/rancher/k3s/server/manifests/traefik-config.yaml
        • k3s 的 traefik 需要修改这个配置, helm 安装的只需要 upgrade
        • 检测到更改后会重新加载
curl 测试
  • 有 basic_auth 需要通过 Authorization 提供
    • -H "Authorization: Basic $(echo -n 'admin:secret' | base64)"
  • curl -vk https://chartmuseum.traefik.cluster.local/health
    • 返回 true 则为正常
  • curl -vk https://chartmuseum.traefik.cluster.local/info
创建 myapp chart 并推送到私有库 myrepo
  • helm repo add myrepo https://chartmuseum.traefik.cluster.local
    • --username <admin> --password <secret>
    • 添加 chartmuseum 作为 myrepo
  • helm cm-push ~/project/myapp/myapp-0.1.0.tgz myrepo
    • 需要安装 helm-push 插件
      • helm plugin install https://github.com/chartmuseum/helm-push
  • helm repo update
  • 后续可以通过 helm install myapp myrepo/myapp 使用
 

OCI 注册表 zot

  • zot 兼容 OCI Chart,还可以镜像一个或多个上游 OCI 镜像仓库
helm 安装 zot, 部署 s3 存储桶作为存储
  • helm repo add project-zot http://zotregistry.dev/helm-charts --force-update
配置 zot
创建 htpasswd secret
  • 使用 htpasswd 用户认证
    • which htpasswd || sudo apt install apache2-utils
  • echo -n "admin passwd: " && read -s HTPW_ADMIN; echo
  • echo -n "metrics passwd: " && read -s HTPW_METRICS; echo
  • printf "%s\n%s\n" \ "$(htpasswd -bBn admin "$HTPW_ADMIN")" \ "$(htpasswd -bBn metrics "$HTPW_METRICS")" \ > /tmp/.htpasswd
  • kubectl create secret generic zot-htpasswd \ --namespace=registry \ --from-file=htpasswd=/tmp/.htpasswd
  • kubectl get secret -n registry zot-htpasswd -o yaml
  • kubectl get secret -n registry zot-htpasswd -o jsonpath='{.data.htpasswd}' | base64 --decode
    • 查看解码后的情况
  • unset HTPW_ADMIN && unset HTPW_METRICS && rm /tmp/.htpasswd
vim ~/.config/helm/value/zot.yaml
vim ~/.config/zot-config.json
  • 样例参考
可用配置项
  • extensions 仅在使用完整镜像时生效,其他会忽略
与 chartmuseum 一样使用 s3 存储桶
  • 通过环境变量传递 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
  • 缓存使用外部 redis cluster
    • ACL SETUSER zotuser on >password ~zot:* +get +set +del +expire +incr +hset +hget +publish +subscribe -@admin -@dangerous
配置用户认证
  • 启用了 ui 和定时清理镜像 scrub
如果要同步镜像需要配置 extensions.sync
  • 检查 Json 格式
    • jq empty ~/.config/zot-config.json
      • 出错会提示错误位置
  • helm upgrade --install zot project-zot/zot \ -n registry --create-namespace \ --set-file configFiles."config\.json"="$HOME/.config/zot-config.json" \ --set secretFiles.htpasswd="$(kubectl get secret -n registry zot-htpasswd -o jsonpath='{.data.htpasswd}' | base64 --decode)" \ -f $HOME/.config/helm/value/zot.yaml
    • 或者通过 --set-json
      • --set-json configFiles="$(jq -n --arg content "$(cat ~/.config/zot-config.json)" '{ "config.json": $content }')"
  • helm get values zot -n registry
查看运行情况
  • kubectl get pod -n registry -l app.kubernetes.io/name=zot
  • kubectl get svc -n registry -l app.kubernetes.io/name=zot
  • kubectl logs --since 1h --tail 50 -n registry $(kubectl get pod -n registry -l app.kubernetes.io/name=zot -o jsonpath='{.items[0].metadata.name}')
配置 zot 路由访问
配置 traefik 路由和 DNS 记录
vim ~/.config/k3s/IngressRoute.zot.yaml
  • kubectl apply -f ~/.config/k3s/IngressRoute.zot.yaml
添加对应域名的 DNS 记录到 /etc/hosts
  • kubectl -n kube-system get svc -l app.kubernetes.io/name=traefik -o wide
    • 获取 external-ip
  • kubectl logs -n kube-system -l app.kubernetes.io/name=traefik --since=1h --tail=100
  • kubectl -n kube-system describe deploy traefik | grep namespaces
    • 检查是否仅代理特定 namespace
    • 如果不含 chartmuseum 需要修改 providers
      • vim /var/lib/rancher/k3s/server/manifests/traefik-config.yaml
        • k3s 的 traefik 需要修改这个配置, helm 安装的只需要 upgrade
        • 检测到更改后会重新加载
curl 测试
  • 有 basic_auth 需要通过 Authorization 提供
    • -H "Authorization: Basic $(echo -n 'admin:secret' | base64)"
  • curl -vk https://zot.traefik.cluster.local/readyz
    • 返回 true 则为正常
  • curl -vk https://zot.traefik.cluster.local/explore 
    • web页面查看镜像
helm 添加 zot 作为存储并推送本地 chart
  • helm registry login https://zot.traefik.cluster.local -u admin -p <password>
    • login succeeded 则为成功
  • helm push ~/project/myapp/myapp-0.1.0.tgz oci://zot.traefik.cluster.local/helm-charts
    • 推送 chart
  • 查看推送是否成功
    • helm show all oci://zot.traefik.cluster.local/helm-charts/myapp
    • curl -s https://zot.traefik.cluster.local/v2/_catalog | jq
  • 开启了 ui 可以直接访问 https://zot.traefik.cluster.local 查看
nerdctl 添加 zot 作为存储并推送本地 oci 镜像
  • 假设有本地镜像文件 ~/project/hellobuild/hellobuild_v1.0.0.oci.tar
    • 构筑测试 hellobuild 项目详见文章 k8s 部署 buildkit 容器镜像构建服务
  • nerdctl login zot.traefik.cluster.local -u admin --password-stdin
  • nerdctl --namespace default load --all-platforms -i ~/project/hellobuild/hellobuild_v1.0.0.oci.tar
  • nerdctl --namespace default image ls | grep hellobuild
  • nerdctl --namespace default tag hellobuild:v1.0.0 \ zot.traefik.cluster.local/hellobuild:v1.0.0
    • 为镜像添加标签
  • nerdctl --namespace default push zot.traefik.cluster.local/hellobuild:v1.0.0
    • 推送
  • 查看是否推送成功
    • curl -s https://zot.traefik.cluster.local/v2/_catalog | jq
清理并测试重新拉取
  • nerdctl --namespace default image rm hellobuild:v1.0.0 \ zot.traefik.cluster.local/hellobuild:v1.0.0
  • nerdctl --namespace default pull zot.traefik.cluster.local/hellobuild:v1.0.0
  • nerdctl --namespace default image ls | grep hellobuild
上一篇
k3s 配置 traefik 等内置 AddOn
下一篇
K8s cert-manager 搭配 step-issuer 签发 step-ca 证书

Comments
Loading...