云原生容器化-4 Docker仓库

1.Docker仓库

1.1 Docker Hub

docker仓库用于存放docker镜像,可以分为公用和私有两种。Docker Hub是全球公用的仓库,因服务器在国外,国内基本不可以;一般需要配置阿里、腾讯等加速器。公司内部而言,可以搭建私有的Docker仓库(如Harbor)。

说明:使用Docker Hub下载镜像时,不需要登录;但是推送、删除、修改时需要登录。
登录与注销涉及如下命令:

#登录时携带用户名、密码、仓库地址信息
docker login --username test --password test@123 192.168.0.22:8000
docker login --username seong --password 3er4#ER$ 192.168.0.22:8000
#注销时需要仓库信息
docker logout 192.168.0.22:8000

注册成功后,在/root/.docker/config.json文件中记录仓库登录成功信息:

{"auths": {"192.168.0.22:8000": {"auth": "c2Vvbmc6M2VyNCNFUiQ="}}
}

注销命令执行时,将删除文件中对应信息(可以重复注销)。

1.2 常见的本地仓库:Registory和Harbor

Docker提供了registry镜像,可以较为方便地搭建仓库。Harbor提供了对用户更为友好的UI界面,推荐使用Harbor。需要注意: Harbor通过docker-compose管理,因此安装Harbor是需要先安装/docker-compose,详细的安装流程请参考服务器环境搭建-2 Docker与Harbor。

1.3 配置docker仓库

docker的配置文件路径为/etc/docker/daemon.json,可以通过registry-mirrors属性添加docker仓库。改动配置文件后,需要重启docker(执行service docker restart)生效。如可以配置腾讯的docker仓库镜像:

{"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}

默认情况下,docker使用https协议与仓库通信。将上述搭建的Harbor仓库配置为docker的仓库地址时会报错: http: server gave HTTP response to HTTPS client.
可以通过在insecure-registries属性中添加白名单地址来规避。如Harbor仓库的地址为:“http://192.168.0.22:8000”, 可以配置为:

{"registry-mirrors": ["https://mirror.ccs.tencentyun.com"],       "insecure-registries": ["192.168.0.22:8000"]    
} 

除了在daemon.json配置文件中修改外,还可以再docker的service文件(/usr/lib/systemd/system/docker.service)中进行配置:

[Service]
Type=notify
ExecStart=/usr/bin/dockerd --insecure-registry=192.168.0.22:8000  -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always

ExecStart表示进程启动命令,通过–insecure-registry参数设置允许通过http访问的仓库地址。

说明:修改docker.service文件后,需要执行systemctl daemon-reload使得配置文件生效;然后执行service docker restart使用新的service文件重启docker.

2. Docker Registry v2 API介绍和案例分析

Docker Registry v2 API是Docker引擎与Docker Registry进行交互时的接口规范。Docker引擎进行镜像的下拉、删除、推送和修改时需要调用Docker Registry提供的接口。
Docker对容器和镜像进行了分层设计,API也以分层为基础。Docker镜像数据包括:数据(blob)和元数据(manifest)两个部分,前者是实际的二进制数据,后者是镜像的描述数据,V2 API为这两部分分别提供了接口。
本文介绍推送和下拉镜像相关的API,其他API请参考: Distribution Registry / Reference Overview / HTTP API V2。

2.1 API接口版本协商

2.1.1 API接口版本协商

url: GET /v2/
参数:无
响应: 返回200 OK表示请求成功; 返回401未经授权.

2.1.2 案例:

GET /v2/ HTTP/1.1
Host: 192.168.0.22:8000
User-Agent: docker/24.0.4 go/go1.20.5 git-commit/4ffc614 kernel/3.10.0-1160.92.1.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/24.0.4 \(linux\))
Accept-Encoding: gzip
Connection: closeHTTP/1.1 200 OK
Content-Length: 2
Content-Type: application/json; charset=utf-8
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Date: Mon, 05 Feb 2024 01:48:16 GMT
Connection: close{}

说明:Docker引擎与仓库交互前,会使用该接口进行协议确认。收到 200 OK表示仓库支持V2版本API,即Docker引擎可继续使用V2 API与仓库交互。

2.2 推送镜像

2.2.1 推送镜像的 manifests

url: PUT /v2/<name>/manifests/<reference>
参数:
[1] name: 镜像名称
[2] reference: 标签/摘要
响应: 返回 201 Created表示已成功推送。

2.2.2 推送镜像的 blobs

url: PUT /v2//blobs/uploads/?digest=
参数:
[1] name: 镜像仓库名称
[2] uuid: 唯一ID标识
[3] digest: blob 的摘要
响应: 返回 201Created表示已成功推送。

2.2.3 案例:

执行如下命令将从Docker Hub仓库下载的hello-world镜像,上传到本地仓库192.168.0.22:8000上:

docker pull hello-worlddocker tag hello-world 192.168.0.22:8000/hello-worlddocker push 192.168.0.22:8000/hello-world

在本地通过docker history命令可以看出hello-world包含两个镜像层, 其中一层镜像ID为d2c94e258dcb:

[root@VM-4-6-centos ~]# docker history hello-world
IMAGE          CREATED        CREATED BY                SIZE      COMMENT
d2c94e258dcb   9 months ago   CMD ["/hello"]            0B        buildkit.dockerfile.v0
<missing>      9 months ago   COPY hello / # buildkit   13.3kB    buildkit.dockerfile.v0

同时在环境上抓包,如下所示:
在这里插入图片描述
整个流程可以分为两个部分:上传各个镜像层的blobs数据和上传整个镜像的manifests数据;
[1] 上传各个镜像层的blobs数据
由于hello-world包含两个镜像层c1ec31e和d2c94e,因此分别进行镜像层数据的推送。在每次推送过程会经过校验和传输两个阶段: (1)通过HEAD请求携带镜像的ID信息查询镜像层在仓库是否存在,收到200表示已存在,不需要上传,收到404表示不存在,(2)上传镜像层数据。
上传完成后,还会再次通过HEAD请求校验是否上传完成。

[2] 上传整个镜像的manifests数据
上述上传hello-world:latest镜像元数据的抓包信息如下:

PUT /v2/hello-world/manifests/latest HTTP/1.1
Host: 192.168.0.22:8000
User-Agent: docker/24.0.4 go/go1.20.5 git-commit/4ffc614 kernel/3.10.0-1160.92.1.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/24.0.4 \(linux\))
Content-Length: 524
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Accept-Encoding: gzip
Connection: close{"schemaVersion": 2,"mediaType": "application/vnd.docker.distribution.manifest.v2+json","config": {"mediaType": "application/vnd.docker.container.image.v1+json","size": 581,"digest": "sha256:d2c94e258dcb3c5ac2798d32e1249e42ef01cba4841c2234249495f87264ac5a"},"layers": [{"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip","size": 2459,"digest": "sha256:c1ec31eb59444d78df06a974d155e597c894ab4cda84f08294145e845394988e"}]
}HTTP/1.1 201 Created
Docker-Content-Digest: sha256:d37ada95d47ad12224c205a938129df7a3e52345828b4fa27b03a98825d1e2e7
Docker-Distribution-Api-Version: registry/2.0
Location: http://192.168.0.22:8000/v2/hello-world/manifests/sha256:d37ada95d47ad12224c205a938129df7a3e52345828b4fa27b03a98825d1e2e7
X-Content-Type-Options: nosniff
Date: Mon, 05 Feb 2024 01:48:16 GMT
Content-Length: 0
Connection: close

进一步测试将hello-world打包成beta版本,然后推送到本地192.168.0.22:8000仓库:

docker tag hello-world 192.168.0.22:8000/hello-world:beta2
docker push 192.168.0.22:8000/hello-world:beta2

同时在环境上抓包:
在这里插入图片描述
通过HEAD请求携带镜像的ID信息查询镜像层在仓库是否存在,收到200表示已存在,不需要上传镜像层数据,只需上传镜像的manifests即可。
由此也可以看出,Docker仓库将镜像层与镜像的元数据是分开存储的。镜像层可以被不同的镜像重复使用。

2.3 拉取镜像

2.3.1 获取镜像的manifests(元数据)

url: GET /v2/<name>/manifests/<reference>
参数:
[1] name: 镜像名称
[2] reference: 标签/摘要

响应: 包含manifest信息的JSON 对象。

2.3.2 获取镜像的blobs(二进制数据)

url: GET /v2/<name>/blobs/<digest>

参数:
[1] name: 镜像名称
[2] digest: blob 的摘要
响应: 返回镜像的 二进制数据

2.3.3 案例

将本地的hello-world:latest镜像删除,然后执行 docker pull 192.168.0.22:8000/hello-world从仓库拉重新拉取hello-world:latest镜像时,具体执行过程如下:
[1] 通过HEAD请求获取hello-world:latest版本镜像的摘要sha256,如果返回404表示镜像不存在

HEAD /v2/hello-world/manifests/latest HTTP/1.1
Host: 192.168.0.22:8000
User-Agent: docker/24.0.4 go/go1.20.5 git-commit/4ffc614 kernel/3.10.0-1160.92.1.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/24.0.4 \(linux\))
Accept: application/vnd.oci.image.manifest.v1+json
Accept: application/vnd.docker.distribution.manifest.v2+json
Accept: application/vnd.docker.distribution.manifest.list.v2+json
Accept: application/vnd.oci.image.index.v1+json
Accept: application/vnd.docker.distribution.manifest.v1+prettyjws
Accept: application/json
Connection: closeHTTP/1.1 200 OK
Content-Length: 524
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:d37ada95d47ad12224c205a938129df7a3e52345828b4fa27b03a98825d1e2e7
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:d37ada95d47ad12224c205a938129df7a3e52345828b4fa27b03a98825d1e2e7"
X-Content-Type-Options: nosniff
Date: Mon, 05 Feb 2024 03:43:16 GMT
Connection: close

[2] 得到sha256信息为d37ada95d47ad12224c205a938129df7a3e52345828b4fa27b03a98825d1e2e7,
然后将得到的摘要作为参数调用GET方法获取镜像的元数据:

GET /v2/hello-world/manifests/sha256:d37ada95d47ad12224c205a938129df7a3e52345828b4fa27b03a98825d1e2e7 HTTP/1.1
Host: 192.168.0.22:8000
User-Agent: docker/24.0.4 go/go1.20.5 git-commit/4ffc614 kernel/3.10.0-1160.92.1.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/24.0.4 \(linux\))
Accept: application/json
Accept: application/vnd.oci.image.manifest.v1+json
Accept: application/vnd.docker.distribution.manifest.v2+json
Accept: application/vnd.docker.distribution.manifest.list.v2+json
Accept: application/vnd.oci.image.index.v1+json
Accept: application/vnd.docker.distribution.manifest.v1+prettyjws
Accept-Encoding: gzip
Connection: closeHTTP/1.1 200 OK
Content-Length: 524
Content-Type: application/vnd.docker.distribution.manifest.v2+json
Docker-Content-Digest: sha256:d37ada95d47ad12224c205a938129df7a3e52345828b4fa27b03a98825d1e2e7
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:d37ada95d47ad12224c205a938129df7a3e52345828b4fa27b03a98825d1e2e7"
X-Content-Type-Options: nosniff
Date: Mon, 05 Feb 2024 03:43:16 GMT
Connection: close{"schemaVersion": 2,"mediaType": "application/vnd.docker.distribution.manifest.v2+json","config": {"mediaType": "application/vnd.docker.container.image.v1+json","size": 581,"digest": "sha256:d2c94e258dcb3c5ac2798d32e1249e42ef01cba4841c2234249495f87264ac5a"},"layers": [{"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip","size": 2459,"digest": "sha256:c1ec31eb59444d78df06a974d155e597c894ab4cda84f08294145e845394988e"}]
}

[3] 从镜像的 manifests信息得知: hello-world:latest镜像由上下(d2c94e258dcb…)和(c1ec31eb5944…)两层组成。
Docker引擎判断本地是否有对应的镜像层,如果没有,会依次向仓库发送/v2//blobs/请求获取镜像层数据。此时本地环境不存在这两个镜像层,因此分别发送了两次请求:
请求c1ec31eb5944层镜像:

GET /v2/hello-world/blobs/sha256:c1ec31eb59444d78df06a974d155e597c894ab4cda84f08294145e845394988e HTTP/1.1
Host: 192.168.0.22:8000
User-Agent: docker/24.0.4 go/go1.20.5 git-commit/4ffc614 kernel/3.10.0-1160.92.1.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/24.0.4 \(linux\))
Accept-Encoding: gzip
Connection: close.....数据....

请求d2c94e258dcb层镜像:

GET /v2/hello-world/blobs/sha256:d2c94e258dcb3c5ac2798d32e1249e42ef01cba4841c2234249495f87264ac5a HTTP/1.1
Host: 192.168.0.22:8000
User-Agent: docker/24.0.4 go/go1.20.5 git-commit/4ffc614 kernel/3.10.0-1160.92.1.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/24.0.4 \(linux\))
Accept-Encoding: gzip
Connection: close.....数据....

上述流程的抓包信息如下:
在这里插入图片描述
此时,再次执行docker pull 192.168.0.22:8000/hello-world指令,抓包信息如下:
在这里插入图片描述
此时Docker引擎判断本地已有对应的镜像,无需再从仓库下载。

3.总结

Docker仓库的搭建、配置、使用较为简单,上手操作就能掌握,重点在于理解分层的概念。从上述镜像的推送和拉取过程可以看出,Docker容器的镜像以层为颗粒度,从而减少了不必要的数据存储和传输。后续在介绍Docker容器中也会提到分层的概念,说明分层对降低计算机资源占用率的重要意义。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CPU-GPU异构并行化APSP算法

一、Floyd-Warshall算法 介绍 Floyd-Warshall算法&#xff08;英语&#xff1a;Floyd-Warshall algorithm&#xff09;&#xff0c;中文亦称弗洛伊德算法或佛洛依德算法&#xff0c;是解决任意两点间的最短路径的一种算法&#xff0c;可以正确处理有向图或负权&#xff08;但…

VUE学习——表单的输入绑定

使用【v-model】。 输入框 <template><h1>表单输入绑定</h1><input type"text" v-model"message"><p>输入的值&#xff1a;{{ message }}</p> </template> <script>export default{data(){return{messa…

【开源】JAVA+Vue.js实现天然气工程业务管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、使用角色3.1 施工人员3.2 管理员 四、数据库设计4.1 用户表4.2 分公司表4.3 角色表4.4 数据字典表4.5 工程项目表4.6 使用材料表4.7 使用材料领用表4.8 整体E-R图 五、系统展示六、核心代码6.1 查询工程项目6.2 工程物资…

春节专题|产业7问:区块链厂商的现在和未来——基础设施厂商

2023转瞬即逝&#xff0c;不同于加密领域沉寂一整年后在年末集中爆发&#xff0c;对于我国的区块链厂商而言&#xff0c;稳中求胜才是关键词&#xff0c;在平稳发展的基调下&#xff0c;产业洗牌也悄无声息的到来。 从产业总体而言&#xff0c;在经过了接近3年的快速发展后&…

Android ·移动应用开发 创建第一个Android项目

文章目录 一、创建第一个Android项目1.1 准备好Android Studio1.2 运行程序1.3 程序结构是什么app下的结构res - 子目录&#xff08;所有图片、布局、字符串等资源&#xff09;AndroidManifest.xml 有四大组件&#xff0c;程序添加权限声明 Project下的结构 二、开发android时&…

【日常聊聊】新年新征程:迎接学习的挑战

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 结语 我的其他博客 前言 随着新的一年的到来&#xff0c;程序员们站在了全新的起点。这是一个充满机遇和挑战的时刻&#xff0…

Hive的Join连接、谓词下推

前言 Hive-3.1.2版本支持6种join语法。分别是&#xff1a;inner join&#xff08;内连接&#xff09;、left join&#xff08;左连接&#xff09;、right join&#xff08;右连接&#xff09;、full outer join&#xff08;全外连接&#xff09;、left semi join&#xff08;左…

寒假 day13

1.请编程实现二维数组的杨慧三角 #include<stdio.h> #include<string.h> int main(int argc, const char *argv[]) { int n,i,j;printf("please enter n:");scanf("%d",&n);int arr[n][n];for(i0;i<n;i){for(j0;j<i;j){if(j0 || ij…

红队打靶练习:Alfa:1

下载连接点击此处即可&#xff01; 目录 信息收集 1、arp 2、nmap 3、gobuster WEB web信息收集 FTP登录 smaba服务 crunch密码生成 提权 系统信息收集 权限提升 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, …

设计模式3-责任链模式

责任链模式是一种行为设计模式&#xff0c;它允许你创建一个对象链。请求沿着这条链传递&#xff0c;直到有一个对象处理它为止。这种模式通常用于需要以某种方式动态地决定处理请求的顺序或方式的情况。 类图&#xff1a; 从图中可见最大的特点是AbstractHandler它自己聚合了自…

SAP MM学习笔记42 - 特殊调达流程 - 受托品(寄售)

上一章讲了 外注加工的知识。 详细可以参考如下链接。 SAP MM学习笔记41 - 特殊调达流程 - 外注加工-CSDN博客 咱们继续学习特殊调达流程。 本章主要讲受托品。 1&#xff0c;什么是受托品 &#xff08;寄售&#xff09; 仕入先提供的商品&#xff0c;商品是放在你公司了&a…

【十八】【C++】deque双端队列简单使用和deque底层实现探究(部分代码)

deque简单使用 在C中&#xff0c;双端队列&#xff08;Double-Ended Queue, deque&#xff09;是一种具有动态大小的序列容器&#xff0c;允许在两端快速插入和删除元素。与std::vector相比&#xff0c;std::deque提供了更加灵活的数据结构&#xff0c;特别是在需要频繁在序列…