[TOC]
0x00 记一次k8s集群搭建的Harbor私有仓库无法进行镜像拉取迁移恢复实践 描述: Harbor 是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源 Docker Distribution。作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。
前置知识了解:
环境说明: 由于Harbor是安装在Kubernetes集群内部,由于在调整集群的网络通信插件时, 无法通过浏览器访问工作节点+nodePort方式访问集群中的Harbor服务,同时外部也不能通过ingress来代理转发harbor,所以为了尽快的恢复镜像仓库,采用Skopeo工具以及如下方式进行镜像的迁移。
[TOC]
0x00 记一次k8s集群搭建的Harbor私有仓库无法进行镜像拉取迁移恢复实践 描述: Harbor 是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源 Docker Distribution。作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。
前置知识了解:
环境说明: 由于Harbor是安装在Kubernetes集群内部,由于在调整集群的网络通信插件时, 无法通过浏览器访问工作节点+nodePort方式访问集群中的Harbor服务,同时外部也不能通过ingress来代理转发harbor,所以为了尽快的恢复镜像仓库,采用Skopeo工具以及如下方式进行镜像的迁移。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Kubernetes 版本: v1.22.2 kubeadm version: &version.Info{Major:"1" , Minor:"22" , GitVersion:"v1.22.2" , GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2" , GitTreeState:"clean" , BuildDate:"2021-09-15T21:37:34Z" , GoVersion:"go1.16.8" , Compiler:"gc" , Platform:"linux/amd64" } skopeo 版本: 1.5.3-dev commit: df4d82b960572c19e9333381a203c0ac475766d7 Harbor 版本: v2.1.3-b6de84c5 $ kubectl get deploy -n harbor
操作步骤:
Step 1.在工作节点上执行如下命令,查看仓库中存在的镜像信息。1 2 3 4 5 6 7 8 9 10 11 USER="admin" TOKEN="Harbor12345" curl --insecure -u ${USER} :${TOKEN} https://harbor.cloud/v2/_catalog 2>/dev/null|jq .repositories[]|tr -d '"' >> image_names.txt devops/bianmin devops/bitnami-redis-cluster devops/bmcx
Step 2.利用for循环获取Tags并拼接镜像与tag信息1 2 3 4 5 6 7 8 9 10 11 12 for name in $(cat image_names.txt);do tags=`curl -u admin:Harbor12345 --insecure https://harbor.cloud/v2/${name} /tags/list 2>/dev/null|jq ".tags[]" |tr -d '"' ` for tag in $tags ;do echo $name :$tag >>image_tags.txt; done done devops/bianmin:1.0.7-SNAPSHOT devops/bianmin:stress devops/bitnami-redis-cluster:6.0.10-debian-10-r5 devops/bmcx:1.0.7-SNAPSHOT devops/bmcx:1.1.0-SNAPSHOT devops/bmcx:latest
Step 3.例如,我们找一个devops/bmcx:1.1.0-SNAPSHOT
镜像分析其路径特征。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 REPO_DIR="docker/registry/v2/repositories" BLOB_DIR="docker/registry/v2/blobs/sha256" cd /storage/pvc/devops/harbor-harbor-harbor-registry-pvc-151479ef-44f1-44dd-960c-afcbf12ba8a8/for image in $(find ${REPO_DIR} -type d -name "current" ); do echo ${image} >> repo_current.txtdone grep "1.1.0-SNAPSHOT" repo_current.txt echo 'docker/registry/v2/repositories/devops/bmcx/_manifests/tags/1.1.0-SNAPSHOT/current' | awk -F '/' '{print $5"/"$6":"$9}' cat 'docker/registry/v2/repositories/devops/bmcx/_manifests/tags/1.1.0-SNAPSHOT/current/link' | sed 's/sha256://' link=68acf0f6c61b11bb79d6787146ed3bd88850b9071b3b59d86439d55ae5e31928 cat docker/registry/v2/blobs/sha256/${link:0:2} /${link} /data { "schemaVersion" : 2, "mediaType" : "application/vnd.docker.distribution.manifest.v2+json" , "config" : { "mediaType" : "application/vnd.docker.container.image.v1+json" , "size" : 2429, "digest" : "sha256:b938271c3bd17a187e5c95508adf49093f042cb176a3652c74a76e6d9770eb5b" }, "layers" : [ { "mediaType" : "application/vnd.docker.image.rootfs.diff.tar.gzip" , "size" : 723146, "digest" : "sha256:07a152489297fc2bca20be96fab3527ceac5668328a30fd543a160cd689ee548" }, { "mediaType" : "application/vnd.docker.image.rootfs.diff.tar.gzip" , "size" : 132, "digest" : "sha256:8142e84f0be01a60008360c5d5592e3f02507968b548797513ef7d5080dd5d0c" }, { "mediaType" : "application/vnd.docker.image.rootfs.diff.tar.gzip" , "size" : 43984533, "digest" : "sha256:702d51e3f3237c8ffbabeefec12934cc2a9e5b6f01fc414cf17f708ec1c09d0f" } ] } images_layer=docker/registry/v2/blobs/sha256/${link:0:2} /${link} /data layers=$(grep -Eo "\b[a-f0-9]{64}\b" ${images_layer} | sort -n | uniq) b938271c3bd17a187e5c95508adf49093f042cb176a3652c74a76e6d9770eb5b 07a152489297fc2bca20be96fab3527ceac5668328a30fd543a160cd689ee548 702d51e3f3237c8ffbabeefec12934cc2a9e5b6f01fc414cf17f708ec1c09d0f 8142e84f0be01a60008360c5d5592e3f02507968b548797513ef7d5080dd5d0c layer=07a152489297fc2bca20be96fab3527ceac5668328a30fd543a160cd689ee548 ls ${BLOB_DIR} /${layer:0:2} /${layer} /data
Step 4.将registry-v2存储的镜像转换为skopeo工具可以识别的目录架构, 即将 harbor 中的镜像导出为 skopeo dir 的形式。1 2 3 4 5 6 7 8 9 10 11 12 13 mkdir ./docker/skopeo/devops/bmcx:1.1.0-SNAPSHOT ln ./docker/registry/v2/blobs/sha256/${link:0:2} /${link} /data ./docker/skopeo/devops/bmcx:1.1.0-SNAPSHOT/manifest.json ln ./docker/registry/v2/blobs/sha256/b9/b938271c3bd17a187e5c95508adf49093f042cb176a3652c74a76e6d9770eb5b/data ./docker/skopeo/devops/bmcx:1.1.0-SNAPSHOT/b938271c3bd17a187e5c95508adf49093f042cb176a3652c74a76e6d9770eb5b ln ./docker/registry/v2/blobs/sha256/07/ 07a152489297fc2bca20be96fab3527ceac5668328a30fd543a160cd689ee548/data ./docker/skopeo/devops/bmcx:1.1.0-SNAPSHOT/07a152489297fc2bca20be96fab3527ceac5668328a30fd543a160cd689ee548 ln ./docker/registry/v2/blobs/sha256/70/702d51e3f3237c8ffbabeefec12934cc2a9e5b6f01fc414cf17f708ec1c09d0f/data ./docker/skopeo/devops/bmcx:1.1.0-SNAPSHOT/702d51e3f3237c8ffbabeefec12934cc2a9e5b6f01fc414cf17f708ec1c09d0f ln ./docker/registry/v2/blobs/sha256/81/8142e84f0be01a60008360c5d5592e3f02507968b548797513ef7d5080dd5d0c
Step 5.最后利用如下skopeo copy
命令将将 dir 格式的镜像复制到harbor中。1 skopeo sync --insecure-policy --src-tls-verify=false --dest-tls-verify=false --src dir --dest docker ./docker/skopeo/devops/bmcx:1.1.0-SNAPSHOT harbor.weiyigeek.top/devops/bmcx:1.1.0-SNAPSHOT
Step 6.最后采用木子提供的shell脚本进行将k8s中harbor的registry数据进行批量同步操作。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #!/bin/bash REGISTRY_DOMAIN="harbor.weiyigeek.top" REGISTRY_PATH="/storage/pvc/devops/harbor-harbor-harbor-registry-pvc-151479ef-44f1-44dd-960c-afcbf12ba8a8" cd ${REGISTRY_PATH} gen_skopeo_dir () { BLOB_DIR="docker/registry/v2/blobs/sha256" REPO_DIR="docker/registry/v2/repositories" SKOPEO_DIR="docker/skopeo" for image in $(find ${REPO_DIR} -type d -name "current" ); do name=$(echo ${image} | awk -F '/' '{print $5"/"$6":"$9}' ) link=$(cat ${image} /link | sed 's/sha256://' ) flag=1 if [ $flag -ne 1 ];then echo "${name} " >> /tmp/not_push_image_tags.txt continue ; else mkdir -vp "${SKOPEO_DIR} /${name} " mfs="${BLOB_DIR} /${link:0:2} /${link} /data" ln ${mfs} ${SKOPEO_DIR} /${name} /manifest.json layers=$(grep -Eo "\b[a-f0-9]{64}\b" ${mfs} | sort -n | uniq) for layer in ${layers} ; do ln ${BLOB_DIR} /${layer:0:2} /${layer} /data ${SKOPEO_DIR} /${name} /${layer} done fi done } sync_image () { for project in $(ls ${SKOPEO_DIR} ); do skopeo sync --insecure-policy --src-tls-verify=false --dest-tls-verify=false --src dir --dest docker ${SKOPEO_DIR} /${project} ${REGISTRY_DOMAIN} /${project} done } gen_skopeo_dir sync_image
执行结果如下:
weiyigeek.top-skopeo 镜像同步
Step 7.镜像同步完成后,我们可以通过访问harbor前端UI界面进行查看同步后的镜像以及其tags信息。
weiyigeek.top-Harbor-UI
参考地址: https://blog.k8s.li/select-registry-images.html