Lazy loaded image
k8s 部署 Harbor 管理企业容器镜像
Words 2098Read Time 6 min
2025-10-17
2025-11-10
date
related_level
slug
type
relate_date
summary
status
tags
category
last_updated
Nov 10, 2025 10:03 PM
是否已更新
orginal_page
是否推荐
  • 使用 PostgreSQL, redis, garage s3 存储等外部服务,TLS 由 step-ca 外部服务提供
设置外部 redis 有一堆限制和坑
  • 不支持 redis clustering
  • sentinel 不能设置 ACL 和 requirepass
    • protected-mode no
  • redis ACL 设置参考
    • user default on >harborpass ~* +@read +@write +publish +subscribe +select +ping +eval +evalsha +multi +exec
helm 安装 Harbor 配置
参考资料
添加 harbor 官方仓库
  • helm repo add harbor https://helm.goharbor.io
创建密码 Secret
创建 postgres 密码 Secret
  • echo -n "postgres passwd: " && read -s HARBOR_PSQL_PASSWORD; echo
  • kubectl create secret generic ext-psql-passwd-secret \ --namespace=registry \ --from-literal=password="$HARBOR_PSQL_PASSWORD"
  • kubectl get secret -n registry ext-psql-passwd-secret -o yaml
  • kubectl get secret -n registry ext-psql-passwd-secret -o jsonpath='{.data.password}' | base64 --decode
    • 查看解码后的情况
  • unset HARBOR_PSQL_PASSWORD
创建 redis 密码 Secret
  • 另外,4 年了还没有支持 sentinel 密码
  • echo -n "redis passwd: " && read -s HARBOR_REDIS_PASSWORD; echo
  • kubectl create secret generic ext-redis-passwd-secret \ --namespace=registry \ --from-literal=REDIS_USERNAME=harbor\ --from-literal=REDIS_PASSWORD="$HARBOR_REDIS_PASSWORD"
    • 文档没写清楚,还需要提供 REDIS_USERNAME 不然用户名为空
  • kubectl get secret -n registry ext-redis-passwd-secret -o yaml
  • kubectl get secret -n registry ext-redis-passwd-secret -o jsonpath='{.data.REDIS_PASSWORD}' | base64 --decode
    • 查看解码后的情况
  • unset HARBOR_REDIS_PASSWORD
创建 s3 密码 Secret
  • 官方配置没有说明, 参考模板自行配置
  • echo -n "s3 passwd: " && read -s HARBOR_S3_PASSWORD; echo
  • kubectl create secret generic ext-s3-cred-secret \ --namespace=registry \ --from-literal=REGISTRY_STORAGE_S3_ACCESSKEY=<s3-key-id> \ --from-literal=REGISTRY_STORAGE_S3_SECRETKEY="$HARBOR_S3_PASSWORD"
  • kubectl get secret -n registry ext-s3-cred-secret -o yaml
  • kubectl get secret -n registry ext-s3-cred-secret -o jsonpath='{.data.REGISTRY_STORAGE_S3_SECRETKEY}' | base64 --decode
    • 查看解码后的情况
  • unset HARBOR_S3_PASSWORD
创建管理密码 Secret
  • echo -n "admin passwd: " && read -s HARBOR_ADMIN_PASSWORD; echo
  • kubectl create secret generic harbor-passwd-secret \ --namespace=registry \ --from-literal=HARBOR_ADMIN_PASSWORD="$HARBOR_ADMIN_PASSWORD"
  • kubectl get secret -n registry harbor-passwd-secret -o yaml
  • kubectl get secret -n registry harbor-passwd-secret -o jsonpath='{.data.HARBOR_ADMIN_PASSWORD}' | base64 --decode
    • 查看解码后的情况
  • unset HARBOR_ADMIN_PASSWORD
创建 registry htpasswd Secret
  • 内部 core 访问 registry 实例会使用 htpasswd 用户认证
    • which htpasswd || sudo apt install apache2-utils
  • echo -n "registry passwd: " && read -s HARBOR_REGISTRY_PASSWORD; echo
  • kubectl create secret generic harbor-htpasswd \ --namespace=registry \ --from-literal=REGISTRY_HTPASSWD=$(htpasswd -nbBC 10 harbor_registry_user "$HARBOR_REGISTRY_PASSWORD") \ --from-literal=REGISTRY_PASSWD="$HARBOR_REGISTRY_PASSWORD"
    • 用户名必须是 harbor_registry_user,文档也没说
  • kubectl get secret -n registry harbor-htpasswd -o yaml
  • kubectl get secret -n registry harbor-htpasswd -o jsonpath='{.data.REGISTRY_PASSWD}' | base64 --decode
    • 查看解码后的情况
  • unset HARBOR_REGISTRY_PASSWORD && rm /tmp/.htpasswd
创建证书 Secret
  • 使用 step-issuer+certmanager 向外部 step-ca 申请证书
    • 具体部署参考 step-issuer 相关文章
vim ~/.step/cert.harbor.k8s.yaml
  • kubectl apply -f ~/.step/cert.harbor.k8s.yaml
  • kubectl get -n registry secret | grep harbor | grep kubernetes.io/tls
kubectl get -n registry secret/harbor-tls-secret -o yaml
  • 查看证书签发情况
  • data 下的三个文件符合 harbor 相关要求
    • ca.crt
    • tls.crt
    • tls.key
创建 nfs 存储 pvc 存放 registry 镜像
vim ~/.config/k3s/pvc.harbor.registry.yaml
  • kubectl apply -f ~/.config/k3s/pvc.harbor.registry.yaml
  • kubectl get -n registry pvc pvc-harbor-registry
vim ~/.config/helm/value/harbor.yaml
  • ingress 后续通过 k3s traefik ingreeroute 来实现,所以只需要 cluster ip 即可
  • registry 仅当 imageChartStorage 为 filesystem 才需要 PVC
    • 通过 s3 外部存储来提供 registry 持久化
  • 禁用了 trivy 组件来限制资源消耗
  • affinity 和 nodeselector 说明
    • NFS 存储需要主机支持所以限制了 VM 节点
    • 集群存在多架构且 harbor chart 不支持,所以限制了 node
  • helm upgrade --install harbor harbor/harbor \ -n registry --create-namespace \ -f ~/.config/helm/value/harbor.yaml
查看运行情况
  • kubectl get deployment -n registry | grep harbor
  • kubectl get pod -n registry -l app.kubernetes.io/name=harbor
  • kubectl get cm -n registry harbor-core -o yaml | grep REDIS
  • kubectl describe -n registry -l app.kubernetes.io/name=harbor,app.kubernetes.io/component=core
  • kubectl logs --since 1h -n registry $(kubectl get pod -n registry -o jsonpath='{.items[0].metadata.name}' -l app.kubernetes.io/name=harbor,app.kubernetes.io/component=core)
    • 查看对应组件日志,这里是 core
  • kubectl logs --since 1h -n registry $(kubectl get pod -n registry -o jsonpath='{.items[0].metadata.name}' -l app.kubernetes.io/name=harbor,app.kubernetes.io/component=jobservice)
    • 查看对应组件日志,这里是 jobservice
    • nginx 和 portal 没准备好时会报错
创建到 core 和 portal 的 traefik 路由
  • 另外 externalURL https 也会影响认证,报错 405 Method not allowed
  • kubectl describe -n kube-system deploy/traefik | grep namespace
    • 先检查 traefik 是否已经为 registry 命名空间提供路由
vim ~/.config/k3s/IngressRoute.harbor.yaml
  • 需要区分 core 和 portal 两个不同路由
    • /c/login 应该发至 core 而非 portal
  • kubectl apply -f ~/.config/k3s/IngressRoute.harbor.yaml
  • kubectl get IngressRoute -n registry ingress-harbor -o yaml
检查日志
  • kubectl logs --since 1h -n kube-system deploy/traefik
    • 检查 traefik 日志
  • kubectl logs --since 1h -n registry deploy/harbor-core | grep login
  • kubectl logs --since 1h -n registry deploy/harbor-portal | grep login
外部 openssl 测试
添加 DNS 记录到 /etc/hosts
  • 获取 traefik 的 external-ip
    • kubectl get svc -n kube-system traefik -o wide
  • openssl s_client -connect harbor.cluster.local:443 -servername harbor.cluster.local | grep "subject="
curl 测试
  • curl -vk https://harbor.cluster.local
    • 访问 portal 首页
    • 默认管理员账户名为 admin,密码就是创建harbor-passwd-secret 时的值
  • HARBOR_ADMIN_PASS=$(kubectl get secret -n registry harbor-passwd-secret -o jsonpath='{.data.HARBOR_ADMIN_PASSWORD}' | base64 --decode)
  • curl -u admin:$HARBOR_ADMIN_PASS -H "Content-Type: application/json" https://harbor.cluster.local/api/v2.0/systeminfo
    • 查看系统信息,api 测试非 webui 登录
使用命令行管理 harbor 配置
  • 直接查看可用 api
    • https://harbor.cluster.local/devcenter-api-2.0
helm 添加 harbor 作为存储并推送本地 chart
创建 myapp chart
  • mkdir -p ~/project && cd ~/project
  • helm create myapp && cd ./myapp
  • helm package ~/project/myapp
helm 登录 harbor 作为存储
  • HARBOR_ADMIN_PASS=$(kubectl get secret -n registry harbor-passwd-secret -o jsonpath='{.data.HARBOR_ADMIN_PASSWORD}' | base64 --decode)
  • helm registry login https://harbor.cluster.local -u admin -p $HARBOR_ADMIN_PASS
    • login succeeded 则为成功
查看可用 project 并推送 myapp chart
  • curl -u admin:$HARBOR_ADMIN_PASS -H "Content-Type: application/json" https://harbor.cluster.local/api/v2.0/projects
    • 查看所有可用的项目
  • helm push ~/project/myapp/myapp-0.1.0.tgz oci://harbor.cluster.local/library
    • 推送 chart 至默认项目 library
查看推送是否成功
  • helm show all oci://harbor.cluster.local/library/myapp
  • curl -u admin:$HARBOR_ADMIN_PASS -H "Content-Type: application/json" https://harbor.cluster.local/api/v2.0/repositories
    • 查看项目下所有已授权的 repo
  • curl -u admin:$HARBOR_ADMIN_PASS -H "Content-Type: application/json" https://harbor.cluster.local/api/v2.0/projects/library/repositories/myapp
    • 查看具体某个 repo
nerdctl 添加 harbor 作为存储并推送本地 oci 镜像
  • 假设有本地镜像文件 ~/project/hellobuild/hellobuild_v1.0.0.oci.tar
    • 构筑测试 hellobuild 项目详见文章 k8s 部署 buildkit 容器镜像构建服务
nerdctl 加载生成的 oci 文件
  • nerdctl --namespace default load --all-platforms -i ~/project/hellobuild/hellobuild_v1.0.0.oci.tar
  • nerdctl --namespace default image ls | grep hellobuild
  • nerdctl 登录 harbor 作为 oci 存储
    • nerdctl login harbor.cluster.local -u admin -p=$HARBOR_ADMIN_PASS
为镜像添加标签 harbor.cluster.local/library 并推送
  • nerdctl --namespace default tag hellobuild:v1.0.0 \ harbor.cluster.local/library/hellobuild:v1.0.0
    • 仍旧推送到默认项目 library
  • nerdctl --namespace default image ls | grep hellobuild
    • 会多了一个引用
  • nerdctl --namespace default push harbor.cluster.local/hellobuild:v1.0.0
查看推送是否成功
  • curl -u admin:$HARBOR_ADMIN_PASS -H "Content-Type: application/json" https://harbor.cluster.local/api/v2.0/projects/library/repositories/hellobuild
    • 查看具体某个 repo
清理本地镜像并测试重新拉取
  • nerdctl --namespace default rmi -f $(nerdctl --namespace default images --filter "reference=hellobuild:v1.0.0" --format "{{.Digest}}" | sort -u)
  • nerdctl --namespace default image ls | grep hellobuild
  • nerdctl --namespace default pull harbor.cluster.local/library/hellobuild:v1.0.0
  • nerdctl --namespace default image ls | grep hellobuild
 
上一篇
mihomo 配置 tproxy 透明代理
下一篇
Openwrt 系统管理

Comments
Loading...