最佳镜像搬运工 Skopeo 指南(2)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 最佳镜像搬运工 Skopeo 指南(2)

8. 登陆(skopeo login)

我这里有三个仓库地址

  • Docker 官方 hub 仓库: docker.io
  • Harbor 私有仓库:harbor.fumai.com
  • Registry 私有仓库:192.168.10.80:5000

在使用 skopeo 前,如果 src 或 dest 镜像是在 registry 仓库中的并且配置了非 public 的镜像需要相应的 auth 认证, 此时我们可以使用 docker login 或者 skopeo login 的方式登录到 registry 仓库,然后默认会在~/.docker目录下生成 registry 登录配置文件 config.json ,该文件里保存了登录需要的验证信息,skopeo 拿到该验证信息才有权限往 registry push 镜像。


skopeo 使用来自 --creds(对于 skopeo inspect|delete)或 --src-creds|--dest-creds(对于 skopeo copy)标志的凭据,如果已设置;否则它使用由 skopeo 登录、podman 登录、buildah 登录或 docker 登录设置的配置。

8.1 配置私有仓库证书

由于我是使用 podman 容器工具,它的默认仓库认证证书存放位置是/etc/containers/certs.d

  1. 配置 registry 证书
    registry 仓库部署在我的本机容器中,证书挂载于本机/opt/registry/certs/目录。
install -d  /etc/containers/certs.d/192.168.10.80\:5000/
install /opt/registry/certs/* /etc/containers/certs.d/192.168.10.80\:5000/

install 是一个既能创建目录又能复制的命令。

2. 配置 harbor 证书

harbor 仓库在另一台机器

$ cat <<EOF >> vim /etc/hosts
192.168.10.81 harbor.fumai.com
EOF
install -d /etc/containers/certs.d/harbor.fumai.com
rsync root@192.168.10.81:/etc/docker/certs.d/harbor.fumai.com/* /etc/containers/certs.d/harbor.fumai.com/

8.2 podman 登陆各个仓库

登陆 docker.io 仓库

$ podman login -u ghostwritten docker.io
Password:
Login Succeeded!

登陆 registry 仓库

$ podman login -u registryuser -p registryuserpassword 192.168.10.80:5000
Login Succeeded!

登陆 harbor 仓库

$ podman login harbor.fumai.com -u admin -p Harbor12345
Login Succeeded!

Podman 登陆仓库生成的auth文件在这里

$ cat /run/user/0/containers/auth.json
{
        "auths": {
                "192.168.10.80:5000": {
                        "auth": "cmVnaXN0cnl1c2VyOnJlZ2lzdHJ5dXNlcnBhc3N3b3Jk"
                },
                "docker.io": {
                        "auth": "Z2hvc3R3cml0dGVuOjEyMzQ1bXRyLg=="
                },
                "harbor.fumai.com": {
                        "auth": "YWRtaW46SGFyYm9yMTIzNDU="
                }
        }
}

skopeo 登陆 registry 仓库

8.3 skopeo 多种方式登陆仓库

skopeo login -u ghostwritten docker.io
Password:
Login Succeeded!
$ skopeo login  -u registryuser -p registryuserpassword 192.168.10.80:5000
Login Succeeded!
$ skopeo login --cert-dir /etc/containers/certs.d/192.168.10.80\:5000 -u registryuser -p registryuserpassword 192.1
68.10.80:5000
Login Succeeded!
$ skopeo login --authfile /run/user/0/containers/auth.json harbor.fumai.com
$ echo 'Harbor12345' | skopeo login -u admin --password-stdin harbor.fumai.com
Login Succeeded!

9. 复制镜像(skopeo copy)

skopeo copy 可以在各种存储机制之间复制容器镜像,包括:


Container registries


The Quay, Docker Hub, OpenShift, GCR, Artifactory …

Container Storage backends


github.com/containers/storage (Backend for Podman, CRI-O, Buildah and friends)


Docker daemon storage


Local directories


Local OCI-layout directories

9.1 本地镜像推送仓库

将本地镜像拷贝至192.168.10.80:5000仓库

$ docker images localhost/busybox:latest
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
busybox      latest    9d5226e6ce3f   4 days ago   1.24MB
如果你得容器以podman为引擎。
$ skopeo copy containers-storage:localhost/busybox:latest docker://192.168.10.80:5000/busybox:latest
INFO[0000] Not using native diff for overlay, this may cause degraded performance for building images: kernel has CONFIG_OVERLAY_FS_REDIRECT_DIR enabled
Getting image source signatures
Copying blob 40cf597a9181 [--------------------------------------] 0.0b / 0.0b
Copying config 9d5226e6ce [======================================] 1.4KiB / 1.4KiB
Writing manifest to image destination
Storing signatures
#如果你得容器以docker为引擎。
$ skopeo copy docker-daemon:localhost/busybox:latest docker://192.168.10.80:5000/busybox:latest
# 没有tls安全的registry的情况下这样操作。
$ skopeo copy --insecure-policy --dest-tls-verify=false --dest-authfile /root/.docker/config.json docker-daemon:localhost/busybox:latest docker://192.168.10.80:5000/busybox:latest

9.2 两仓库进行复制

192.168.10.80:5000仓库的 alpine 镜像同步至 harbor.fumai.com仓库

#两个仓库进行查询当前镜像内容
$ curl  -k -u "registryuser:registryuserpassword" https://192.168.10.80:5000/v2/_catalog
{"repositories":["alpine"]}
$ curl  -k -u "admin:Harbor12345" https://harbor.fumai.com/v2/_catalog
{"repositories":[]}
#镜像开始复制
$ skopeo copy docker://192.168.10.80:5000/alpine:latest docker://harbor.fumai.com/library/alpine:latest
Getting image source signatures
Copying blob 60f8044dac9f done
Copying config bfe296a525 done
Writing manifest to image destination
Storing signatures
#查询复制结果
$ curl  -k -u "admin:Harbor12345" https://harbor.fumai.com/v2/_catalog
{"repositories":["library/alpine"]}
#查询镜像信息
$ skopeo inspect docker://harbor.fumai.com/library/alpine:latest
{
    "Name": "harbor.fumai.com/library/alpine",
    "Digest": "sha256:39ec5d12ef5a81b29b26d756f6b9c11d8d454fc4158e3dac1e13240125558461",
    "RepoTags": [
        "latest"
    ],
    "Created": "2022-11-12T04:19:23.199716539Z",
    "DockerVersion": "20.10.12",
    "Labels": null,
    "Architecture": "amd64",
    "Os": "linux",
    "Layers": [
        "sha256:60f8044dac9f779802600470f375c7ca7a8f7ad50e05b0ceb9e3b336fa5e7ad3"
    ],
    "Env": [
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ]
}

其它仓库同步方法:

#  docker://quay.io的buildah 同步到docker://registry.internal.company.com
$ skopeo copy docker://quay.io/buildah/stable docker://harbor.fumai.com/library/buildah
#如果 registry 是一个没有tls验证的仓库并且以 docker 为容器引擎。
$ skopeo copy --insecure-policy --dest-tls-verify=false --dest-authfile /root/.docker/config.json docker://192.168.10.80:5000/alpine:latest docker://harbor.fumai.com/library/alpine:latest
#如果 registry 是一个没有tls验证的仓库并且以 podman 为容器引擎。
 $ skopeo copy --insecure-policy --dest-tls-verify=false --dest-authfile /run/user/0/containers/auth.json docker://192.168.10.80:5000/alpine:latest docker://harbor.fumai.com/library/alpine:latest

9.3 仓库镜像拷贝到本地目录

创建images目录,从harbor.fumai.com仓库复制至images目录

$ install -d images
$ skopeo copy docker://harbor.fumai.com/library/alpine:latest dir:images
Getting image source signatures
Copying blob 60f8044dac9f done
Copying config bfe296a525 done
Writing manifest to image destination
Storing signatures
$ ll images
total 2864
-rw-r--r-- 1 root root 2918987 Nov 21 23:08 60f8044dac9f779802600470f375c7ca7a8f7ad50e05b0ceb9e3b336fa5e7ad3
-rw-r--r-- 1 root root    1471 Nov 21 23:08 bfe296a525011f7eb76075d688c681ca4feaad5afe3b142b36e30f1a171dc99a
-rw-r--r-- 1 root root     428 Nov 21 23:08 manifest.json
-rw-r--r-- 1 root root      33 Nov 21 23:08 version

保存OCI格式

$ install -d images_OCI
skopeo copy docker://harbor.fumai.com/library/alpine:latest oci:images_OCI
$ tree images_OCI/
images_OCI/
├── blobs
│   └── sha256
│       ├── 096fca2180271e60f199e3bc1c3544dc0175e7e6abd9dbdd0e2058b17d96e8b7
│       ├── 60f8044dac9f779802600470f375c7ca7a8f7ad50e05b0ceb9e3b336fa5e7ad3
│       └── e9daf8b695a6e3c0c566a2e25b328ba25afbdd52a80d28198b9fbf5058130f09
├── index.json
└── oci-layout
2 directories, 5 files

或者如果没有登陆条件可以这样执行:

$ skopeo copy --src-creds=admin:harbor12345 docker://harbor.fumai.com/library/alpine:latest oci:local_oci_image

10. 同步镜像(Skopeo sync)

Skopeo sync可以在容器仓库和本地目录之间同步镜像,其功能类似于阿里云的 image-syncer 工具, 实际上其比 image-syncer 更强大、灵活性更强一些

$ skopeo sync --src docker --dest dir registry.example.com/busybox /media/usb

10.1 仓库镜像同步至本地

将仓库中所有 busybox 镜像版本同步到本地目录

查询当前harbor.fumai.com仓库 busybox版本

skopeo list-tags docker://harbor.fumai.com/library/busybox
{
    "Repository": "harbor.fumai.com/library/busybox",
    "Tags": [
        "latest",
        "stable"
    ]
}

busybox镜像所有版本同步至本地

$ skopeo sync  --src docker --dest dir harbor.fumai.com/library/busybox images_busybox
INFO[0000] Tag presence check                            imagename=harbor.fumai.com/library/busybox tagged=false
INFO[0000] Getting tags                                  image=harbor.fumai.com/library/busybox
INFO[0000] Copying image ref 1/2                         from="docker://harbor.fumai.com/library/busybox:latest" to="dir:/images_busybox/busybox:latest"
Getting image source signatures
Copying blob 405fecb6a2fa done
Copying config 9d5226e6ce done
Writing manifest to image destination
Storing signatures
INFO[0000] Copying image ref 2/2                         from="docker://harbor.fumai.com/library/busybox:stable" to="dir:/images_busybox/busybox:stable"
Getting image source signatures
Copying blob 405fecb6a2fa done
Copying config 9d5226e6ce done
Writing manifest to image destination
Storing signatures
INFO[0001] Synced 2 images from 1 sources
$ tree images_busybox
/images_busybox
├── busybox:latest
│   ├── 405fecb6a2fa4f29683f977e7e3b852bf6f8975a2aba647d234d2371894943da
│   ├── 9d5226e6ce3fb6aee2822206a5ef85f38c303d2b37bfc894b419fca2c0501269
│   ├── manifest.json
│   └── version
└── busybox:stable
    ├── 405fecb6a2fa4f29683f977e7e3b852bf6f8975a2aba647d234d2371894943da
    ├── 9d5226e6ce3fb6aee2822206a5ef85f38c303d2b37bfc894b419fca2c0501269
    ├── manifest.json
    └── version
2 directories, 8 files

其他方式:

skopeo sync --src-creds=admin:Harbor12345  --src docker --dest dir harbor.fumai.com/library/busybox /images_busybox
skopeo sync --src-authfile=/run/user/0/containers/auth.json  --src docker --dest dir harbor.fumai.com/library/busybox /images_busybox

10.2 本地同步至仓库镜像

这次颠倒过来,从本地目录/images_busybox同步至registry:192.168.10.80:5000仓库

skopeo 登陆

skopeo login  -u registryuser -p registryuserpassword 192.168.10.80:5000

开始同步

$ skopeo sync  --src dir --dest docker  /images_busybox 192.168.10.80:5000
INFO[0000] Copying image ref 1/2                         from="dir:/images_busybox/busybox:latest" to="docker://192.168.10.80:5000/busybox:latest"
Getting image source signatures
Copying blob 405fecb6a2fa done
Copying config 9d5226e6ce done
Writing manifest to image destination
Storing signatures
INFO[0001] Copying image ref 2/2                         from="dir:/images_busybox/busybox:stable" to="docker://192.168.10.80:5000/busybox:stable"
Getting image source signatures
Copying blob 405fecb6a2fa [--------------------------------------] 0.0b / 0.0b
Copying config 9d5226e6ce [======================================] 1.4KiB / 1.4KiB
Writing manifest to image destination
Storing signatures
INFO[0001] Synced 2 images from 1 sources

查询结果

$ skopeo list-tags docker://192.168.10.80:5000/busybox
{
    "Repository": "192.168.10.80:5000/busybox",
    "Tags": [
        "latest",
        "stable"
    ]
}

成功。

其他同步方式:

skopeo sync --dest-creds=registryuser:registryuserpassword  --src dir --dest docker /images_busybox 192.168.10.80:5000 
skopeo sync --src-authfile=/run/user/0/containers/auth.json  --src dir --dest docker /images_busybox 192.168.10.80:5000 
#如果 registry 是一个没有tls验证的仓库
skopeo sync --insecure-policy --dest-tls-verify=false --src dir --dest docker /images_busybox 192.168.10.80:5000

10.3 两仓库同步

harbor( harbor.fumai.com)仓库的busybox所有版本同步至registry(192.168.10.80:5000)仓库

skopeo sync   --src docker --dest docker harbor.fumai.com/library/busybox 192.168.10.80:5000

其他方式:

skopeo sync --src-creds=admin:Harbor12345 --dest-creds=registryuser:registryuserpassword  --src docker --dest docker harbor.fumai.com/library/busybox 192.168.10.80:5000 
skopeo sync --dest-authfile=/run/user/0/containers/auth.json --src-authfile=/run/user/0/containers/auth.json --src docker --dest docker harbor.fumai.com/library/busybox 192.168.10.80:5000 

10.4 以配置文件方式进行同步

准备一个需要同步的资源清单

$ cat skopeo-sync.yml
192.168.10.80:5000:
 images:
   busybox: [stable]
   redis:
     - "latest"
     - "7.0.5"
 credentials:
     username: registryuser
     password: registryuserpassword
 tls-verify: true
 cert-dir: /etc/containers/certs.d/192.168.10.80:5000
docker.io:
 tls-verify: false
 images:
   httpd:
     - "latest"
quay.io:
 tls-verify: false
 images:
   coreos/etcd:
     - latest

开始同步

$ skopeo sync --src yaml --dest docker skopeo-sync.yml harbor.fumai.com/library
INFO[0000] Processing repo                               registry=docker.io repo=httpd
INFO[0000] Processing repo                               registry=quay.io repo=coreos/etcd
INFO[0000] Processing repo                               registry="192.168.10.80:5000" repo=busybox
INFO[0000] Processing repo                               registry="192.168.10.80:5000" repo=redis
INFO[0000] Copying image ref 1/1                         from="docker://httpd:latest" to="docker://harbor.fumai.com/library/httpd:latest"
Getting image source signatures
Copying blob ff7b0b8c417a done
Copying blob 4691bd33efec done
Copying blob a603fa5e3b41 done
Copying blob b1c114085b25 done
Copying blob 9df1012343c7 done
Copying config 8653efc8c7 done
Writing manifest to image destination
Storing signatures
INFO[0015] Copying image ref 1/1                         from="docker://quay.io/coreos/etcd:latest" to="docker://harbor.fumai.com/library/etcd:latest"
Getting image source signatures
Copying blob a3ed95caeb02 done
Copying blob 96b0e24539ea done
Copying blob d1eca4d01894 done
Copying blob ff3a5c916c92 done
Copying blob 8bc526247b5c done
Copying blob ad732d7a61c2 done
Copying blob a3ed95caeb02 skipped: already exists
Copying blob a3ed95caeb02 skipped: already exists
Copying blob 5f56944bb51c done
Writing manifest to image destination
Storing signatures
INFO[0022] Synced 2 images from 2 sources
INFO[0007] Copying image ref 1/1                         from="docker://192.168.10.80:5000/busybox:stable" to="docker://harbor.fumai.com/library/busybox:stable"
Getting image source signatures
Skipping: image already present at destination
INFO[0007] Copying image ref 1/2                         from="docker://192.168.10.80:5000/redis:latest" to="docker://harbor.fumai.com/library/redis:latest"
Getting image source signatures
Copying blob a0056c8a01e3 done
Copying blob 87b7cd6612f6 done
Copying blob 656160ba04b8 done
Copying blob a08cc0270959 done
Copying blob d14ed0f181ce done
Copying blob 39e3d9efeaec skipped: already exists
Copying config 3358aea34e done
Writing manifest to image destination
Storing signatures
INFO[0009] Copying image ref 2/2                         from="docker://192.168.10.80:5000/redis:7.0.5" to="docker://harbor.fumai.com/library/redis:7.0.5"
Getting image source signatures
Copying blob a08cc0270959 skipped: already exists
Copying blob d14ed0f181ce skipped: already exists
Copying blob a0056c8a01e3 skipped: already exists
Copying blob 87b7cd6612f6 skipped: already exists
Copying blob 656160ba04b8 skipped: already exists
Copying blob 39e3d9efeaec [--------------------------------------] 0.0b / 0.0b
Copying config 3358aea34e [======================================] 7.5KiB / 7.5KiB
Writing manifest to image destination
Storing signatures

11. 删除镜像(skopeo delete)

11.1 skopeo 删除镜像

使用skopeo delete命令我们可以删除镜像 Tag,注意此处仅仅只是通过 registry API 来删除镜像的 tag(即删除了 tag 对 manifests 文件的引用)并非真正将镜像删除掉,如果想要删除镜像的 layer 还是需要通过 registry GC 的方式。

$ curl  -k -u "admin:Harbor12345" https://harbor.fumai.com/v2/_catalog
{"repositories":["library/alpine"]}
#开始删除
$ skopeo delete docker://harbor.fumai.com/library/alpine:latest
$ curl  -k -u "admin:Harbor12345" https://harbor.fumai.com/v2/_catalog
{"repositories":[]}

--debug 模式:

skopeo delete docker://harbor.fumai.com/library/busybox:latest --debug
DEBU[0000] Loading registries configuration "/etc/containers/registries.conf"
DEBU[0000] Loading registries configuration "/etc/containers/registries.conf.d/000-shortnames.conf"
DEBU[0000] Loading registries configuration "/etc/containers/registries.conf.d/001-rhel-shortnames.conf"
DEBU[0000] Loading registries configuration "/etc/containers/registries.conf.d/002-rhel-shortnames-overrides.conf"
DEBU[0000] Found credentials for harbor.fumai.com in credential helper containers-auth.json
DEBU[0000] Using registries.d directory /etc/containers/registries.d for sigstore configuration
DEBU[0000]  Using "default-docker" configuration
DEBU[0000]   Using file:///var/lib/containers/sigstore
DEBU[0000] Looking for TLS certificates and private keys in /etc/containers/certs.d/harbor.fumai.com
DEBU[0000]  crt: /etc/containers/certs.d/harbor.fumai.com/ca.crt
DEBU[0000]  cert: /etc/containers/certs.d/harbor.fumai.com/harbor.fumai.com.cert
DEBU[0000]  key: /etc/containers/certs.d/harbor.fumai.com/harbor.fumai.com.key
DEBU[0000] GET https://harbor.fumai.com/v2/
DEBU[0000] Ping https://harbor.fumai.com/v2/ status 401
DEBU[0000] GET https://harbor.fumai.com/service/token?account=admin&scope=repository%3Alibrary%2Fbusybox%3A%2A&service=harbor-registry
DEBU[0000] GET https://harbor.fumai.com/v2/library/busybox/manifests/latest
DEBU[0000] DELETE https://harbor.fumai.com/v2/library/busybox/manifests/sha256:f75f3d1a317fc82c793d567de94fc8df2bece37acd5f2bd364a0d91a0d1f3dab
DEBU[0000] Deleting /var/lib/containers/sigstore/library/busybox@sha256=f75f3d1a317fc82c793d567de94fc8df2bece37acd5f2bd364a0d91a0d1f3dab/signature-1

11.2 curl 方式删除

$ curl -k -u "registryuser:registryuserpassword" --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I
 -X GET https://192.168.10.80:5000/v2/busybox/manifests/latest
HTTP/2 200
content-type: application/vnd.docker.distribution.manifest.v2+json
docker-content-digest: sha256:f75f3d1a317fc82c793d567de94fc8df2bece37acd5f2bd364a0d91a0d1f3dab
docker-distribution-api-version: registry/2.0
etag: "sha256:f75f3d1a317fc82c793d567de94fc8df2bece37acd5f2bd364a0d91a0d1f3dab"
x-content-type-options: nosniff
content-length: 527
date: Tue, 22 Nov 2022 10:51:14 GMT
$ curl -s -k -u "registryuser:registryuserpassword" --header "Accept: application/vnd.docker.distribution.manifest.v2+json"
 -I -X GET https://192.168.10.80:5000/v2/busybox/manifests/latest | grep -i "Docker-Content-Digest" | cut -d ' ' -f 2
sha256:f75f3d1a317fc82c793d567de94fc8df2bece37acd5f2bd364a0d91a0d1f3dab
$ curl -u 'registryuser:registryuserpassword' -k -X DELETE https://192.168.10.80:5000/v2/busybox/manifests/sha256:f75f3d1a317fc82c793d567de94fc8df2bece37acd5f2bd364a0d91a0d1f3dab

我写了一个关于通过 API 删除仓库镜像的delete_images.sh脚本,当然你的仓库需要配置REGISTRY_STORAGE_DELETE_ENABLED=true,才能执行删除操作,否则不支持。

#!/bin/bash
default() {
 Images=${1-'busybox:latest'}
 Registry_Url=${2-'192.168.10.80:5000'}
 Registry_Username=${3-'registryuser'}
 Registry_Password=${4-'registryuserpassword'}
}
help() {
    echo "Usage:"
    echo "test.sh [-i Images] [-h Registry_Url] [-u Registry_Username] [-p Registry_Password] [-d]"
    echo "Description:"
    echo "  Images,One or more mirror images,exmple: (busybox:latest alpine:latest)."
    echo "  Registry_Url, registry name,exmaple: docker.io."
    echo "  Registry_Username, registry username,exmaple: 'admin'."
    echo "  Registry_Password, registry password,exmaple: 'Harbor12345'."
    echo "  -d, Indicates the deletion action."
    exit -1
}
delete() {
for Image in ${Images}
do
  Image_Name=`echo $Image | cut -d ':' -f 1 `
  Image_Version=`echo $Image | cut -d ':' -f 2`
  echo " Starting delete ${Registry_Url}/$Image_Name:$Image_Version..."
DockerContentDigest=$(curl -s -k -u "$Registry_Username:$Registry_Password" --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -I -X GET "https://${Registry_Url}/v2/${Image_Name}/manifests/${Image_Version}" | grep -i "Docker-Content-Digest" | cut -d ' ' -f 2 )
DockerContentDigest=${DockerContentDigest%$'\r'}
  if [[ $DockerContentDigest != '' ]];then
    curl -u ${Registry_Username}:${Registry_Password} -k -X DELETE  https://${Registry_Url}/v2/${Image_Name}/manifests/${DockerContentDigest} && [ $? == 0 ] && echo "Ok, $Registry_Url/$Image delete sucessful!"
   else
     echo "Sorry, $Registry_Url/$Image not find!"
   fi
done
}
#[ $# == 0 ] && help
[ $# == 0 ] &&  default && delete && exit 0
while getopts 'i:h:u:p:d' OPT; do
    case $OPT in
        i) Images="$OPTARG";;
        h) Registry_Url="$OPTARG";;
        u) Registry_Username="$OPTARG";;
        p) Registry_Password="$OPTARG";;
        d) delete;;
        h) help;;
        ?) help;;
    esac
done

执行效果:我们尝试删除仓库192.168.10.80:5000busybox:latest镜像。

$ skopeo list-tags docker://192.168.10.80:5000/alpine
{
    "Repository": "192.168.10.80:5000/alpine",
    "Tags": [
        "latest"
    ]
}
$ bash   delete_images.sh  -i alpine:latest -h 192.168.10.80:5000 -u registryuser -p registryuserpassword -d
 Starting delete 192.168.10.80:5000/alpine:latest...
Ok, 192.168.10.80:5000/alpine:latest delete sucessful!
$ skopeo list-tags docker://192.168.10.80:5000/alpine
{
    "Repository": "192.168.10.80:5000/alpine",
    "Tags": []
}

关于skopeo 的练习就到此结束了。

参考:

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
12月前
|
Kubernetes jenkins 持续交付
膜拜!阿里内部爆款K8s+Docker+Jenkins实战笔记,不能再详细了!
膜拜!阿里内部爆款K8s+Docker+Jenkins实战笔记,不能再详细了!
|
存储 Ubuntu 安全
最佳镜像搬运工 Skopeo 指南(1)
最佳镜像搬运工 Skopeo 指南(1)
最佳镜像搬运工 Skopeo 指南(1)
|
Cloud Native 应用服务中间件 nginx
【云原生Docker系列第十篇】搭建本地私有仓库(我问青山何时老,青山问我几时闲)
【云原生Docker系列第十篇】搭建本地私有仓库(我问青山何时老,青山问我几时闲)
120 0
【云原生Docker系列第十篇】搭建本地私有仓库(我问青山何时老,青山问我几时闲)
|
网络协议 Cloud Native Shell
【云原生Docker系列第二篇】Docker容器管理(我在人间贩卖黄昏,只为带着星光照耀你)(一)
【云原生Docker系列第二篇】Docker容器管理(我在人间贩卖黄昏,只为带着星光照耀你)(一)
118 0
【云原生Docker系列第二篇】Docker容器管理(我在人间贩卖黄昏,只为带着星光照耀你)(一)
|
Cloud Native Shell 网络安全
【云原生Docker系列第二篇】Docker容器管理(我在人间贩卖黄昏,只为带着星光照耀你)(二)
【云原生Docker系列第二篇】Docker容器管理(我在人间贩卖黄昏,只为带着星光照耀你)(二)
227 0
【云原生Docker系列第二篇】Docker容器管理(我在人间贩卖黄昏,只为带着星光照耀你)(二)
|
Cloud Native Shell Apache
【云原生Docker系列第六篇】基于Dockerfile创建镜像(你与星光同样浪漫)(二)
【云原生Docker系列第六篇】基于Dockerfile创建镜像(你与星光同样浪漫)(二)
156 0
【云原生Docker系列第六篇】基于Dockerfile创建镜像(你与星光同样浪漫)(二)
|
存储 缓存 Cloud Native
【云原生Docker系列第六篇】基于Dockerfile创建镜像(你与星光同样浪漫)(一)
【云原生Docker系列第六篇】基于Dockerfile创建镜像(你与星光同样浪漫)(一)
160 0
【云原生Docker系列第六篇】基于Dockerfile创建镜像(你与星光同样浪漫)(一)
|
Cloud Native Linux Serverless
【云原生Docker系列第一篇】Docker镜像管理(生活本来就是一场浪漫革命)(一)
【云原生Docker系列第一篇】Docker镜像管理(生活本来就是一场浪漫革命)(一)
115 0
【云原生Docker系列第一篇】Docker镜像管理(生活本来就是一场浪漫革命)(一)
|
存储 Cloud Native Linux
【云原生Docker系列第一篇】Docker镜像管理(生活本来就是一场浪漫革命)(二)
【云原生Docker系列第一篇】Docker镜像管理(生活本来就是一场浪漫革命)(二)
149 0
【云原生Docker系列第一篇】Docker镜像管理(生活本来就是一场浪漫革命)(二)
|
存储 消息中间件 Cloud Native
【云原生Docker系列第一篇】Docker镜像管理(生活本来就是一场浪漫革命)(三)
【云原生Docker系列第一篇】Docker镜像管理(生活本来就是一场浪漫革命)(三)
188 0
【云原生Docker系列第一篇】Docker镜像管理(生活本来就是一场浪漫革命)(三)