最佳镜像搬运工 Skopeo 指南

news2024/10/7 6:38:39

最佳镜像搬运工 Skopeo 指南


文章目录

  • 最佳镜像搬运工 Skopeo 指南
    • 1. 概述
    • 2. Skopeo 是如何工作的?
    • 3. 为什么要用 Skopeo?
      • 3.1 灵活性
      • 3.2 安全性和可访问性
      • 3.3 功能多样性
    • 4. 安装
      • 4.1 Fedora
      • 4.2 RHEL / CentOS Stream ≥ 8
      • 4.3 RHEL/CentOS ≤ 7.x
      • 4.4 Ubuntu
      • 4.5 容器安装
    • 5. 命令参数
    • 6. 查询(skopeo inspect)
      • 6.1 查询镜像 fedora:latest 的属性
      • 6.2 查询镜像配置
      • 6.3 查询镜像摘要
      • 6.4 免登陆查询
    • 7. 显示镜像标签(skopeo list-tags)
    • 8. 登陆(skopeo login)
      • 8.1 配置私有仓库证书
      • 8.2 podman 登陆各个仓库
      • 8.3 skopeo 多种方式登陆仓库
    • 9. 复制镜像(skopeo copy)
      • 9.1 本地镜像推送仓库
      • 9.2 两仓库进行复制
      • 9.3 仓库镜像拷贝到本地目录
    • 10. 同步镜像(Skopeo sync)
      • 10.1 仓库镜像同步至本地
      • 10.2 本地同步至仓库镜像
      • 10.3 两仓库同步
      • 10.4 以配置文件方式进行同步
    • 11. 删除镜像(skopeo delete)
      • 11.1 skopeo 删除镜像
      • 11.2 curl 方式删除

1. 概述

Skopeo 是一款用来操作、检查、签署和传输容器镜像及镜像存储库的工具,支持 Linux® 系统、Windows 和 MacOS。与 Podman 和 Buildah 一样,Skopeo 也是一个由开源社区推动的项目,也不需要运行容器守护进程。

Skopeo 是一个能操作不同格式(包括开放容器计划(OCI)和 Docker 镜像)容器镜像的轻量级模块化解决方案,您无需下载包含所有层的完整镜像,就可检查远程镜像仓库中的镜像。

2. Skopeo 是如何工作的?

Skopeo(希腊语"远程查看"的意思)是红帽工程师与开源社区携手开发的第一款容器工具。Skopeo 可与 Podman 和 Buildah 搭配来管理 OCI 容器。简而言之,Podman 负责运行容器,Buildah 负责构建容器,而 Skopeo 则负责传输容器,同时也提供其他功能。我们可以把这些工具看成是用于容器环境的一把瑞士军刀。Skopeo 是其中最万能的那把刀,任由您支配。

Skopeo 使用 skopeo inspect 命令来检查镜像。在 Skopeo 面世之前,您必须拉取完整镜像才能检查这个镜像,即使您只是打算检查一些元数据而已。而 Skopeo 的 inspect 命令可显示镜像的各种属性,如层、镜像标记和标签等,因此您不必将镜像拉取到主机上。这样,您无需占用任何容量,就能收集关于存储库或标记的信息。

Skopeo 也允许您从存储库删除镜像,并将外部镜像存储库同步到内部镜像仓库,以实现更为安全的断网(也称为气隙系统)部署。当存储库需要时,Skopeo 可以传递相应的凭据和证书来进行身份验证。

Skopeo sync 允许进行镜像仓库到镜像仓库的直接复制,以便联网使用,也允许进行镜像仓库到文件和文件到镜像仓库的复制,以便为断网环境做准备。skopeo copy 会假定所请求的复制要求操作;而 skopeo sync 则不同,它已经过调优,能够更快地完成定期重新同步极少改动的大型存储库。除了直接使用命令行外,同步操作也可在 config 文件中配置,而这可以仅同步大型存储库中的一个标记子集。

如果检查结果表明需要在不同位置或不同存储类型之间复制容器镜像,您可以通过 Skopeo copy 命令来操作。此工具可以让您在不同的镜像仓库(例如 docker.io、quay.io)、您的内部容器镜像仓库或您的本地系统上的各种存储机制之间复制容器镜像。Skopeo 的镜像仓库间直接复制功能速度很快,可在目标镜像仓库允许时保留未修改的形式(以及镜像的清单摘要)。在镜像仓库间复制不需要使用本地磁盘,也不要求本地磁盘上有可用的空间。Skopeo 也可在不同容器引擎存储甚至不同目录之间移动镜像。它常常用于持续集成/持续交付(CI/CD)系统中,以便使容器镜像仓库保持最新,并且维护容器服务器上的存储。

3. 为什么要用 Skopeo?

3.1 灵活性

Skopeo 是一套容器模块化工具的一部分,具有许多优势。将重要变更引入到单体式架构的工具中,而且不影响现有用户的使用,这绝非易事。Skopeo、Podman 和 Buildah 等尺寸更小巧、用途更专一的工具会以更快的速度更新换代。成套使用工具的话,可以使每个工具专注于单一用途,并且可以添加新的工具来增加功能,或者尝试与现有工具不兼容的想法和架构。工具的尺寸越小巧、模块化程度越高,保证安全也更加容易。
Podman 的部分功能源自于 libpod 库,允许与其他工具共享代码;Skopeo 与之相似,其功能也是在库中实施的。Skopeo 的容器/镜像库可由 Podman、Buildah 和 CRI-O 等其他容器工具共享,并且与 Docker 命令行界面(CLI)兼容。

3.2 安全性和可访问性

PodmanSkopeoBuildah 组合使用主要有以下优势:

  • 无根容器管理。用户无需使用具有管理员特权的进程,就能创建、运行和管理容器,不仅使容器环境变得更易访问,又可降低安全风险。
  • 无守护进程架构。守护进程需要管理员访问权限(同时无需进行管理员验证)来读取文件、安装程序、编辑应用和执行其他操作。如此一来,对于企图控制您的容器并渗透主机系统的黑客而言,守护进程是他们的理想攻击目标。
  • 原生 systemd 集成。通过使用 Podman 和相关的容器工具,您可以创建 systemd 单元文件并将容器作为系统服务来运行。

Understanding root inside and outside a container

3.3 功能多样性

  • Skopeo 与 API V2 容器镜像仓库一起工作,例如docker.io和quay.io仓库、私有仓库、本地目录和本地 OCI 布局目录。Skopeo 可以执行的操作包括:

    • 从和向各种存储机制复制镜像。例如,您可以将镜像从一个仓库复制到另一个仓库,而无需特权。
    • 检查显示其属性(包括图层)的远程镜像,而无需将镜像拉到主机。
    • 从镜像存储库中删除镜像。
    • 将外部镜像存储库同步到内部仓库以进行气隙部署。
    • 当存储库需要时,skopeo 可以传递适当的凭据和证书进行身份验证。
  • Skopeo 对以下镜像和存储库类型进行操作:

    • containers-storage:docker-reference 位于本地 containers/storage镜像存储中的镜像。位置和镜像存储都在 /etc/containers/storage.conf 中指定。(这是Podman、CRI-O、Buildah和朋友的后端)

    • dir:path 一个现有的本地目录路径,将清单、层 tarball 和签名存储为单独的文件。这是一种非标准化格式,主要用于调试或非侵入式容器检查。

    • docker://docker-reference 实现“Docker Registry HTTP API V2”的仓库中的镜像。默认情况下,使用 中的授权状态$XDG_RUNTIME_DIR/containers/auth.json,这是使用 设置的skopeo login

    • docker-archive:path[:docker-reference] 镜像存储在 - 格式的docker save文件中。docker-reference 仅在创建此类文件时使用,并且不得包含摘要。

    • docker-daemon:docker-reference 存储在 docker 守护程序内部存储中的镜像 docker-referencedocker-reference 必须包含标签或摘要。或者,在读取镜像时,格式也可以是 docker-daemon:algo:digest(镜像 ID)。

    • oci:path:tag 路径中​​符合“Open Container Image Layout Specification”的目录中的镜像标签。

废话少说,我们开始 Skopeo 之旅。

4. 安装

4.1 Fedora

sudo dnf -y install skopeo

Package Info and Bugzilla

4.2 RHEL / CentOS Stream ≥ 8

sudo dnf -y install skopeo

CentOS Stream 9: Package Info

CentOS Stream 8: Package Info

  • 更多 skopeo 安装方式看这里

4.3 RHEL/CentOS ≤ 7.x

sudo yum -y install skopeo

CentOS 7: Package Repo

4.4 Ubuntu

skopeo包在Ubuntu 20.10及更新版本的官方存储库中可用。

# Ubuntu 20.10 and newer
sudo apt-get -y update
sudo apt-get -y install skopeo

Ubuntu: Package Info

4.5 容器安装

$ podman run docker://quay.io/skopeo/stable:latest copy --help

5. 命令参数

skopeo --help
Various operations with container images and container image registries

Usage:
  skopeo [command]

Available Commands:
  copy                                          Copy an IMAGE-NAME from one location to another
  delete                                        Delete image IMAGE-NAME
  help                                          Help about any command
  inspect                                       Inspect image IMAGE-NAME
  list-tags                                     List tags in the transport/repository specified by the REPOSITORY-NAME
  login                                         Login to a container registry
  logout                                        Logout of a container registry
  manifest-digest                               Compute a manifest digest of a file
  standalone-sign                               Create a signature using local files
  standalone-verify                             Verify a signature using local files
  sync                                          Synchronize one or more images from one location to another

Flags:
      --command-timeout duration   timeout for the command execution
      --debug                      enable debug output
  -h, --help                       help for skopeo
      --insecure-policy            run the tool without any policy check
      --override-arch ARCH         use ARCH instead of the architecture of the machine for choosing images
      --override-os OS             use OS instead of the running OS for choosing images
      --override-variant VARIANT   use VARIANT instead of the running architecture variant for choosing images
      --policy string              Path to a trust policy file
      --registries.d DIR           use registry configuration files in DIR (e.g. for container signature storage)
      --tmpdir string              directory used to store temporary files
  -v, --version                    Version for Skopeo

Use "skopeo [command] --help" for more information about a command.
命令描述
skopeo-copy(1)将镜像(清单、文件系统层、签名)从一个位置复制到另一个位置。
skopeo-delete(1)标记镜像名称以便稍后由仓库的垃圾收集器删除。
skopeo-inspect(1)返回有关仓库中镜像名称的低级信息。
skopeo-list-tags(1)返回特定于传输的镜像存储库的标签列表。
skopeo-login(1)登录容器仓库。
skopeo-logout(1)注销容器仓库。
skopeo-manifest-digest(1)计算清单文件的清单摘要并将其写入标准输出。
skopeo-standalone-sign(1)调试工具 - 一步发布和签署镜像。
skopeo-standalone-verify(1)验证镜像签名。
skopeo-sync(1)

6. 查询(skopeo inspect)

skopeo inspect 能够检查容器 Registry 上的存储库并获取镜像层。检查命令获取存储库的清单,它能够向您显示有关整个存储库或标签的类似 docker inspect 的 json 输出。与 docker inspect 相比,此工具可帮助您在拉取存储库或标签之前收集有用的信息(使用磁盘空间), 检查命令可以向您显示给定存储库可用的标签、映像具有的标签、映像的创建日期和操作系统等。

支持传输的类型 : containers-storage, dir, docker, docker-archive, docker-daemon, oci, oci-archive, ostree, tarball。

6.1 查询镜像 fedora:latest 的属性

$ podman images
REPOSITORY  TAG         IMAGE ID    CREATED     SIZE

$ skopeo inspect docker://docker.io/alpine:latest
{
    "Name": "docker.io/library/alpine",
    "Digest": "sha256:b95359c2505145f16c6aa384f9cc74eeff78eb36d308ca4fd902eeeb0a0b161b",
    "RepoTags": [
        "2.6",
        "2.7",
        "20190228",
        "20190408",
        "20190508",
        "20190707",
        "20190809",
        "20190925",
        "20191114",
        "20191219",
        "20200122",
        "20200319",
        "20200428",
        "20200626",
        "20200917",
        "20201218",
        "20210212",
        "20210730",
        "20210804",
        "20220316",
        "20220328",
        "20220715",
        "20221110",
        "3",
        "3.1",
        "3.10",
        "3.10.0",
        "3.10.1",
        "3.10.2",
        "3.10.3",
        "3.10.4",
        "3.10.5",
        "3.10.6",
        "3.10.7",
        "3.10.8",
        "3.10.9",
        "3.11",
        "3.11.0",
        "3.11.10",
        "3.11.11",
        "3.11.12",
        "3.11.13",
        "3.11.2",
        "3.11.3",
        "3.11.5",
        "3.11.6",
        "3.11.7",
        "3.11.8",
        "3.11.9",
        "3.12",
        "3.12.0",
        "3.12.1",
        "3.12.10",
        "3.12.11",
        "3.12.12",
        "3.12.2",
        "3.12.3",
        "3.12.4",
        "3.12.5",
        "3.12.6",
        "3.12.7",
        "3.12.8",
        "3.12.9",
        "3.13",
        "3.13.0",
        "3.13.1",
        "3.13.10",
        "3.13.11",
        "3.13.12",
        "3.13.2",
        "3.13.3",
        "3.13.4",
        "3.13.5",
        "3.13.6",
        "3.13.7",
        "3.13.8",
        "3.13.9",
        "3.14",
        "3.14.0",
        "3.14.1",
        "3.14.2",
        "3.14.3",
        "3.14.4",
        "3.14.5",
        "3.14.6",
        "3.14.7",
        "3.14.8",
        "3.15",
        "3.15.0",
        "3.15.0-rc.4",
        "3.15.1",
        "3.15.2",
        "3.15.3",
        "3.15.4",
        "3.15.5",
        "3.15.6",
        "3.16",
        "3.16.0",
        "3.16.1",
        "3.16.2",
        "3.16.3",
        "3.17",
        "3.17.0_rc1",
        "3.2",
        "3.3",
        "3.4",
        "3.5",
        "3.6",
        "3.6.5",
        "3.7",
        "3.7.3",
        "3.8",
        "3.8.4",
        "3.8.5",
        "3.9",
        "3.9.2",
        "3.9.3",
        "3.9.4",
        "3.9.5",
        "3.9.6",
        "edge",
        "latest"
    ],
    "Created": "2022-11-12T04:19:23.199716539Z",
    "DockerVersion": "20.10.12",
    "Labels": null,
    "Architecture": "amd64",
    "Os": "linux",
    "Layers": [
        "sha256:ca7dd9ec2225f2385955c43b2379305acd51543c28cf1d4e94522b3d94cce3ce"
    ],
    "Env": [
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ]
}

6.2 查询镜像配置

$ skopeo inspect --config docker://docker.io/alpine:latest  | jq
{
  "created": "2022-11-12T04:19:23.199716539Z",
  "architecture": "amd64",
  "os": "linux",
  "config": {
    "Env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ],
    "Cmd": [
      "/bin/sh"
    ]
  },
  "rootfs": {
    "type": "layers",
    "diff_ids": [
      "sha256:e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd"
    ]
  },
  "history": [
    {
      "created": "2022-11-12T04:19:23.05154209Z",
      "created_by": "/bin/sh -c #(nop) ADD file:ceeb6e8632fafc657116cbf3afbd522185a16963230b57881073dad22eb0e1a3 in / "
    },
    {
      "created": "2022-11-12T04:19:23.199716539Z",
      "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]",
      "empty_layer": true
    }
  ]
}

6.3 查询镜像摘要

$ skopeo inspect docker://docker.io/alpine:latest | jq '.Digest'
"sha256:655721ff613ee766a4126cb5e0d5ae81598e1b0c3bcf7017c36c4d72cb092fe9"

或者

$ skopeo inspect --format "Name: {{.Name}} Digest: {{.Digest}}" docker://docker.io/alpine:latest
Name: docker.io/library/alpine Digest: sha256:b95359c2505145f16c6aa384f9cc74eeff78eb36d308ca4fd902eeeb0a0b161b
  • 关于 inspect 用法更多细节请看这里

6.4 免登陆查询

  • –creds=testuser:testpassword
skopeo inspect   --creds=admin:Harbor12345 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"
    ]
}

7. 显示镜像标签(skopeo list-tags)

skopeo list-tags显示镜像存储库的标签列表,期待已久的功能了。

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

$ skopeo list-tags docker://docker.io/alpine
{
    "Repository": "docker.io/library/alpine",
    "Tags": [
        "2.6",
        "2.7",
        "20190228",
        "20190408",
        "20190508",
        "20190707",
        "20190809",
        "20190925",
        "20191114",
        "20191219",
        "20200122",
        "20200319",
        "20200428",
        "20200626",
        "20200917",
        "20201218",
        "20210212",
        "20210730",
        "20210804",
        "20220316",
        "20220328",
        "20220715",
        "20221110",
        "3",
        "3.1",
        "3.10",
        "3.10.0",
        "3.10.1",
        "3.10.2",
        "3.10.3",
        "3.10.4",
        "3.10.5",
        "3.10.6",
        "3.10.7",
        "3.10.8",
        "3.10.9",
        "3.11",
        "3.11.0",
        "3.11.10",
        "3.11.11",
        "3.11.12",
        "3.11.13",
        "3.11.2",
        "3.11.3",
        "3.11.5",
        "3.11.6",
        "3.11.7",
        "3.11.8",
        "3.11.9",
        "3.12",
        "3.12.0",
        "3.12.1",
        "3.12.10",
        "3.12.11",
        "3.12.12",
        "3.12.2",
        "3.12.3",
        "3.12.4",
        "3.12.5",
        "3.12.6",
        "3.12.7",
        "3.12.8",
        "3.12.9",
        "3.13",
        "3.13.0",
        "3.13.1",
        "3.13.10",
        "3.13.11",
        "3.13.12",
        "3.13.2",
        "3.13.3",
        "3.13.4",
        "3.13.5",
        "3.13.6",
        "3.13.7",
        "3.13.8",
        "3.13.9",
        "3.14",
        "3.14.0",
        "3.14.1",
        "3.14.2",
        "3.14.3",
        "3.14.4",
        "3.14.5",
        "3.14.6",
        "3.14.7",
        "3.14.8",
        "3.15",
        "3.15.0",
        "3.15.0-rc.4",
        "3.15.1",
        "3.15.2",
        "3.15.3",
        "3.15.4",
        "3.15.5",
        "3.15.6",
        "3.16",
        "3.16.0",
        "3.16.1",
        "3.16.2",
        "3.16.3",
        "3.17",
        "3.17.0_rc1",
        "3.2",
        "3.3",
        "3.4",
        "3.5",
        "3.6",
        "3.6.5",
        "3.7",
        "3.7.3",
        "3.8",
        "3.8.4",
        "3.8.5",
        "3.9",
        "3.9.2",
        "3.9.3",
        "3.9.4",
        "3.9.5",
        "3.9.6",
        "edge",
        "latest"
    ]
}

8. 登陆(skopeo login)

我这里有三个仓库地址

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

在使用 skopeo 前,如果 srcdest 镜像是在 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 的练习就到此结束了。

参考:

  • 如何使用 Skopeo 做一个优雅的镜像搬运工
  • https://github.com/containers/skopeo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/28025.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GPU显存占满但利用率却很低

来帕多瓦联培已经一个多月了&#xff0c;最近调代码跑实验又发现了这个问题。这里提供另外一个解决思路。一个原因还是 cpu没跟上gpu节奏。 通常我们都会用尽可能大的 batch 来占满显存。但是如果cpu的读取和传输跟不上的话就会导致gpu利用率时上时下&#xff0c;而且训练时间…

2022.3IDEA配置grep console

首先安装Grep Console (这个大家都会吧) 安装之后 打开File 选项的Setting→Other Settings→Grep Console 3. 打开之后默认的样式是下图&#xff08;我做了一下标识&#xff09; whole line:是否一整行都是这个样式。用于区分一个关键字和一行字case insensitive: 不勾选就行…

spring cache (ehcache方式)

目录前置pom: jar配置文件:ehcache.xmlapplication.ymlMyEhCacheCacheConfiguration.java效果图禁用 MyEhCacheCacheConfiguration.java启用 MyEhCacheCacheConfiguration.java前置 会演示springcache的使用方式 项目地址: https://gitee.com/xmaxm/test-code/blob/master/cha…

第五章 神经网络(上)

5.1 神经元模型 神经网络目前使用的最广泛的定义为“神经网络是由具有适应性的简单单元组成的广泛并行互联的网络&#xff0c;它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应。神经网络中最基本的成分是神经元模型&#xff0c;即上述定义的简单单元。 在生物神经…

离线安装Redis集群(redis-6.2.4)

记录&#xff1a;326 场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;使用redis-6.2.4版本&#xff0c;在三台机器上&#xff0c;离线安装Redis集群。 版本&#xff1a; 操作系统&#xff1a;CentOS 7.9 Redis版本&#xff1a;redis-6.2.4 1.主机规划 目标&#xff…

物联网僵尸网络再次发起大规模攻击事件回顾

执行摘要 随着物联网的不断发展&#xff0c;物联网安全也被越来越多的人所关注。我们于 2016 年发布《物联网安全 白皮书》&#xff0c;进行物联网安全的科普介绍&#xff1b;于 2017 年发布《2017 物联网安全年报》&#xff0c;关注物联网资产 在互联网上的暴露情况、物联网设…

预训练模型相对位置编码和绝对位置编码的通俗理解

1 transformer最经典的理解&#xff1a; http://jalammar.github.io/illustrated-transformer/ 2 位置编码 相对位置编码(relative position representation)&#xff1a;https://zhuanlan.zhihu.com/p/397269153 Transformer中的相对位置编码(Relative Position Embedding)…

基于物联网的花卉养殖监控设计系统与研究

目 录 1、绪论 1 1.1课题背景 1 1.2 本课题研究意义 2 2、 系统总体方案设计 3 2.1、传感器部分 3 2.2、主控制部分 4 3、系统硬件设计 6 3.1 STC89C52RC单片机主控模块设计 6 3.2单片机最小系统 9 3.2.1时钟电路 9 3.2.2复位电路 10 3.2.3 STC89C52RC中断技术概述 10 3.3 温度…

基于最小误差阈值法的特定医学图像分割算法研究-含Matlab代码

⭕⭕ 目 录 ⭕⭕✳️ 一、引言✳️ 二、阈值分割原理✳️ 三、最小误差阈值法✳️ 四、基于最小误差阈值法图像分割的实验分析✳️ 4.1 图像分割结果✳️ 4.2 边缘曲线提取结果✳️ 五、参考文献✳️ 六、Matlab代码获取✳️ 一、引言 图像是人们所熟悉的&#xff0c;但是图像…

服务器稳定性测试-LTP压力测试方法及工具下载

简介 LTP&#xff08;LinuxTest Project&#xff09;是SGI、IBM、OSDL和Bull合作的项目&#xff0c;目的是为开源社区提供一个测试套件&#xff0c;用来验证Linux系统可靠性、健壮性和稳定性。LTP测试套件是测试Linux内核和内核相关特性的工具的集合。 该工具的目的是通过把测…

【HMS Core】构建SplitBill应用集成多个HMS Core服务,助力您更好的了解华为生态组成

一、介绍 Duration: 3:00 总览 通过构建本次的SplitBill应用&#xff0c;您可以更好地了解华为生态的组成部分&#xff0c;包括认证服务、云存储和云数据库等Serverless服务。此外您还可以了解如何使用近距离数据通信服务的Nearby Connection功能分享文件。无需使用现金&…

重回synchronized(源码解读与实战解析篇)

读前必知 文中锁&#xff0c;也称为对象锁&#xff0c;而锁对象就是指的承载这个锁的对象&#xff0c;如下面&#xff0c;用法中所指的Object o&#xff0c;在print3中就是锁对象。 以下源码分析仅适用于jdk8&#xff0c;版本未知&#xff0c;因为源码提供者的源码版本访问地址…

金仓数据库KingbaseES GIN 索引

目录 一、索引的逻辑结构 二、索引的物理结构 三、GIN索引使用例子 1、前后模糊查询 2、全文检索 四、gin 索引可用于超长的字段 GIN(Generalized Inverted Index, 通用倒排索引) 是一个存储对(key, posting list)集合的索引结构&#xff0c;其中key是一个键值&#xff0c…

【uniapp】利用Vuex实现购物车功能

实战项目名称&#xff1a;实现购物车功能 文章目录一、实战步骤1. 先编辑store.js文件2. 定义方法和基本的结构3. 编写SETSHPPING二、在项目中调用1. 触发相应的mutations2. 利用computed计算数量和总价的方法提示&#xff1a;本实战内容大部分为具体实现的思路&#xff0c;界面…

C语言 2 —— 常量

常量是什么&#xff1f; 常量就是在程序运行过程中&#xff0c;值不会发生改变&#xff0c;而且一眼可以辨识出值的量。 如&#xff1a; 20&#xff0c;‘a’ , 3.1415926 , "helloworld" 常量的分类&#xff1a; 整形&#xff0c;浮点型&#xff0c;字符型&#…

成电860考研专业课考前划重点-学长课程音频转文字-用科大讯飞花钱买的-三万五千字

成电860考研专业课考前划重点-学长课程音频转文字。 这个是我2021年把视频的音频扒下来后用科大讯飞音频转文字网站上花了几十块钱买的。 说话人1 03:04 对有回放&#xff0c;我这边开回放了&#xff0c;大家可以让大家下载&#xff0c;然后我怕这边回放有问题&#xff0c;大家…

Airtest poco 入门小结

目录 一、poco介绍 1、poco能做什么 2、三种定位方式 1&#xff09;基本选择器 2&#xff09;相对选择器 3&#xff09;空间顺序选择器 4&#xff09;正则表达式方式 3、poco支持平台 二、Airtest介绍 1、Airtest能做什么 2、Airtest不能做什么 3、Airtest的图像识别…

发挥数字化平台优势,电子元器件采购商城系统助力企业改变固有低效流程

我国是全球最大的电子元器件生产国&#xff0c;电子元器件在国民经济发展中占据着重要地位。近年来&#xff0c;随着数字经济的快速发展&#xff0c;电子元器件的需求量也在不断升高&#xff0c;但疫情与国际环境对电子元器件产业要素流通仍然造成了一定困扰。在此背景下&#…

win10系统下使用onnxruntime部署yolov5模型

文章目录前言一、环境1、硬件2、软件二、YOLO模型三、新建Qt项目1、pro文件2、mainwindow.h3、mainwindow.cpp四、YOLO 类封装1、yolov5.h2、yolov5.cpp3、class.names五、效果前言 上一篇介绍过使用opencv-dnn模块实现模型推理部署&#xff0c;但视频效果较差&#xff0c;本篇…

ps2023最新版免费滤镜插件Exposure安装下载教程

滤镜插件是ps的重要功能之一&#xff0c;它主要是用来制作不同的图片特效。那么&#xff0c;ps滤镜插件哪些好用&#xff0c;ps滤镜插件如何获取&#xff0c;下面我们一起来学习这些内容。 ps滤镜插件是比较多的&#xff0c;下面对几款常见的ps滤镜插件进行讲解&#xff0c;看…