使用 Helm 和 Local-Path StorageClass 部署 Docker Registry 的完整步骤
安装ARM64架构 K8S集群K8S 集群安装本地磁盘 StorageClass2. 创建自定义 Values 文件(创建 registry-values.yaml 文件)3. 安装 Docker Registry4. 验证部署5. 配置客户端访问
·
前提条件
部署步骤
1. 添加 Helm 仓库
helm repo add twuni https://helm.twun.io
helm repo update
2. 创建自定义 Values 文件(创建 registry-values.yaml 文件)
# registry-values.yaml
persistence:
enabled: true
storageClass: "local-path" # 指定使用 local-path
size: 10Gi
deleteEnabled: true # 允许删除镜像
service:
type: NodePort
nodePort: 30500 # 固定 NodePort 端口
# 配置健康检查
probes:
liveness:
enabled: true
path: /
port: 5000
readiness:
enabled: true
path: /
port: 5000
# 资源限制
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
# 配置存储路径(可选,默认为 /var/lib/registry)
configData:
storage:
filesystem:
rootdirectory: /var/lib/registry
3. 安装 Docker Registry
helm install my-registry twuni/docker-registry \
-f registry-values.yaml \
--namespace registry \
--create-namespace
4. 验证部署
# 检查 Pod 状态
kubectl -n registry get pods
# 检查 PVC 绑定情况
kubectl -n registry get pvc
# 检查服务
kubectl -n registry get svc
5. 配置客户端访问
export NODE_PORT=$(kubectl get --namespace registry -o jsonpath="{.spec.ports[0].nodePort}" services my-registry-docker-registry)
export NODE_IP=$(kubectl get nodes --namespace registry -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT

6.配置客户端 Docker 信任私有仓库:
# 在需要访问的机器上执行
sudo tee /etc/docker/daemon.json <<EOF
{
"insecure-registries": ["${NODE_IP}:${NODE_PORT}"]
}
EOF
sudo systemctl restart docker
7. 测试镜像推送
# 拉取测试镜像
docker pull nginx:alpine
# 标记镜像
docker tag nginx:alpine ${NODE_IP}:${NODE_PORT}/my-nginx:v1
# 推送镜像
docker push ${NODE_IP}:${NODE_PORT}/my-nginx:v1
# 验证推送成功
curl http://${NODE_IP}:${NODE_PORT}/v2/_catalog
# 应返回:{"repositories":["my-nginx"]}
8.修改 containerd 配置信任私有仓库
# 编辑配置文件
# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."${NODE_IP}:${NODE_PORT}"]
endpoint = ["${NODE_IP}:${NODE_PORT}"]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."${NODE_IP}:${NODE_PORT}".tls]
insecure_skip_verify = true
# 重启 containerd 服务
sudo systemctl restart containerd
# 验证配置
sudo crictl pull ${NODE_IP}:${NODE_PORT}/my-nginx:v1
可用镜像配置
#/etc/docker/daemon.json
{
"insecure-registries": ["http://10.9.8.223:30500"],
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1panel.live",
"https://hub.rat.dev"
]
}
#/etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = [
"https://docker.m.daocloud.io",
"https://docker.1panel.live",
"https://hub.rat.dev"
]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."10.9.90.31:30500"]
endpoint = ["http://10.9.90.31:30500"]
删除镜像
# 设置环境变量
REGISTRY="10.9.8.223:30500" # 你的Registry地址
IMAGE="my-nginx" # 镜像名称
TAG="v1" # 标签
# 1. 获取镜像的manifest digest
DIGEST=$(curl -I -s \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
"http://${REGISTRY}/v2/${IMAGE}/manifests/${TAG}" | \
grep 'Docker-Content-Digest' | \
awk '{print $2}' | \
tr -d '\r')
echo "Digest: $DIGEST"
# 2. 删除manifest
curl -X DELETE "http://${REGISTRY}/v2/${IMAGE}/manifests/${DIGEST}"
# 3. 验证已删除
curl "http://${REGISTRY}/v2/${IMAGE}/tags/list"
# 应不再显示已删除的标签
磁盘扩容
# push 镜像报错
time="2025-11-05T01:31:19.884338069Z" level=error msg="response completed with error" err.code=unknown err.detail="filesystem: mkdir /var/lib/registry/docker/registry/v2/repositories/openstack.kolla/mariadb-server: no space left on device" err.message="unknown error" go.version=go1.23.7 http.request.host="10.9.8.223:30500" http.request.id=edb135a6-885d-4b23-8066-8e1c688c2d3e http.request.method=POST http.request.remoteaddr="10.9.61.11:40146" http.request.uri="/v2/openstack.kolla/mariadb-server/blobs/uploads/?from=openstack.kolla%2Fnova-ssh&mount=sha256%3Ad6593751883466edbf4bdd7fb18c59b21433df56cae5cb8ecbd660cbef3740d6" http.request.useragent="docker/28.5.1 go/go1.24.8 git-commit/f8215cc kernel/6.8.0-87-generic os/linux arch/amd64 UpstreamClient(Docker-Client/28.5.1 \\(linux\\))" http.response.contenttype=application/json http.response.duration="451.435µs" http.response.status=500 http.response.written=193 instance.id=13608e8d-7b66-4cc6-b9e8-04b62852bc4f service=registry vars.name=openstack.kolla/mariadb-server version=3.0.0
10.9.61.11 - - [05/Nov/2025:01:31:19 +0000] "POST /v2/openstack.kolla/mariadb-server/blobs/uploads/?from=openstack.kolla%2Fnova-ssh&mount=sha256%3Ad6593751883466edbf4bdd7fb18c59b21433df56cae5cb8ecbd660cbef3740d6 HTTP/1.1" 500 193 "" "docker/28.5.1 go/go1.24.8 git-commit/f8215cc kernel/6.8.0-87-generic os/linux arch/amd64 UpstreamClient(Docker-Client/28.5.1 \\(linux\\))"
10.9.61.11 - - [05/Nov/2025:01:31:19 +0000] "POST /v2/openstack.kolla/mariadb-server/blobs/uploads/ HTTP/1.1" 500 193 "" "docker/28.5.1 go/go1.24.8 git-commit/f8215cc kernel/6.8.0-87-generic os/linux arch/amd64 UpstreamClient(Docker-Client/28.5.1 \\(linux\\))"
# 查看磁盘占用
kubectl exec -n registry my-registry-docker-registry-6946c5c45d-jvmfp -- df -h /var/lib/registry
Filesystem Size Used Available Use% Mounted on
/dev/zd0 9.7G 9.7G 0 100% /var/lib/registry
# 查看PVC
kubectl -n registry get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
my-registry-docker-registry Bound pvc-17b9f92a-ec19-4862-91a8-100867a730e3 10Gi RWO openebs-zfspv <unset> 76d
#确认 StorageClass 允许扩容
kubectl get sc openebs-zfspv -o jsonpath='{.allowVolumeExpansion}'
true
#如果返回 true → 继续;
#如果 没有该字段或 false,先补丁:
kubectl patch sc openebs-zfspv -p '{"allowVolumeExpansion":true}'
#修改 PVC
kubectl patch pvc my-registry-docker-registry -n registry --type merge \ge \
-p '{"spec":{"resources":{"requests":{"storage":"50Gi"}}}}'
persistentvolumeclaim/my-registry-docker-registry patched
#等待 ZFS 扩容完成
kubectl describe pvc -n registry my-registry-docker-registry | tail -20
Volume: pvc-17b9f92a-ec19-4862-91a8-100867a730e3
Labels: migration=true
original-storage=local-path
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-provisioner: zfs.csi.openebs.io
volume.kubernetes.io/selected-node: nmdc-server-01
volume.kubernetes.io/storage-provisioner: zfs.csi.openebs.io
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 50Gi
Access Modes: RWO
VolumeMode: Filesystem
Used By: my-registry-docker-registry-6946c5c45d-jvmfp
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning ExternalExpanding 46s volume_expand waiting for an external controller to expand this PVC
Normal Resizing 46s external-resizer zfs.csi.openebs.io External resizer is resizing volume pvc-17b9f92a-ec19-4862-91a8-100867a730e3
Normal FileSystemResizeRequired 46s external-resizer zfs.csi.openebs.io Require file system resize of volume on node
Normal FileSystemResizeSuccessful 11s kubelet MountVolume.NodeExpandVolume succeeded for volume "pvc-17b9f92a-ec19-4862-91a8-100867a730e3" nmdc-server-01
#立即查看:
kubectl get pvc -n registry my-registry-docker-registry
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
my-registry-docker-registry Bound pvc-17b9f92a-ec19-4862-91a8-100867a730e3 50Gi RWO openebs-zfspv <unset> 76d
#进 registry 容器确认
kubectl exec -n registry my-registry-docker-registry-6946c5c45d-jvmfp -- df -h /var/lib/registry
Filesystem Size Used Available Use% Mounted on
/dev/zd0 49.1G 9.7G 39.4G 20% /var/lib/registry
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)