云原生容器化-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: close

HTTP/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-world

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

docker 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: close

HTTP/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: close

HTTP/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容器中也会提到分层的概念,说明分层对降低计算机资源占用率的重要意义。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【牛客面试必刷TOP101】Day19.BM24 二叉树的中序遍历和BM26 求二叉树的层序遍历

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;牛客面试必刷TOP101 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&…

寒假作业-day11

1>编程实现二维数组的杨辉三角 2>编程实现二维数组计算每一行的和以及列和 3>编程实现二维数计算第二大值 代码&#xff1a; #include<stdio.h> #include<stdlib.h> #include<string.h>void yanghui(int n){int arr[n][n];for (int i 0; i <…

【力扣】5.最长回文子串

这道题我主要是通过动态规划来进行解题&#xff0c;看了我好久&#xff08;解析&#xff09;&#xff0c;生疏了呀。 首先就是判断一个字符串是不是回文&#xff0c;我们可以设置两个指针&#xff0c;从前往后进行判断即可&#xff0c;运用暴力解题法&#xff0c;这里运用的动…

C语言:详解操作符(下)

上一篇链接&#xff1a;C语言&#xff1a;详解操作符&#xff08;上&#xff09;摘要&#xff1a; 在上篇文章中&#xff0c;我们已经讲过位操作符等涉及二进制的操作符&#xff0c;这些有助于帮助我们后期理解数据如何在计算机中运算并存储&#xff0c;接下来本篇将更多的讲述…

不要告诉我爸妈!三省吾身!保持健康的习惯——“早”读

三省吾身了? 引言代码第一篇 人民日报 不要告诉我爸妈第二篇 人民日报 【夜读】新的一年&#xff0c;保持健康的5个好习惯第三篇&#xff08;跳&#xff09; 人民日报 来啦 新闻早班车要闻社会政策 结尾 引言 我想我需要给我的文章再来点规范性的东西 让大家能够更好地阅读 比…

【java苍穹外卖项目实战三】nginx反向代理和负载均衡

文章目录 1、nginx反向代理2、nginx 反向代理的好处3、nginx 反向代理的配置方式5、nginx 负载均衡的配置方式6、nginx 负载均衡策略 我们思考一个问题&#xff1a; 前端发送的请求&#xff0c;是如何请求到后端服务的&#xff1f; 前端请求地址&#xff1a;http://localhost/…

猫头虎分享已解决Bug || 任务调度失败(Cron Job Failure):CronJobError, ScheduledTaskFailure

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

输出用“*”组成的X形图案。

输出用“*”组成的X形图案 输入描述&#xff1a; 多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;&#xff0c;表示输出的行数&#xff0c;也表示组成“X”的反斜线和正斜线的长度。 输出描述&#xff1a; 针对每行输入&#xff0c;输出用“*”组成的X形图案。 …

typescript中的Omit排除类型及Pick取想要的属性

Omit 的使用:排除类型 type OmitUser {name: string,age: number,sex:string } type newOmit Omit<OmitUser, sex>// 定义一个对象并将其类型设置为 newOmit const example: newOmit {name: "John",age: 30 };console.log( Omit 的使用:排除类型 , example…

黑色响应式全屏滚动主页源码

html5黑色大气的个人博客全屏滚动个人主页源码下载&#xff0c;右键记事本即可修改。HTMLJSCSS https://wfr.lanzout.com/iFmRe1o7csyh

svg基础(十)滤镜-feMerge(多滤镜叠加滤镜)

feMerge:多滤镜叠加滤镜 允许同时应用滤镜效果而不是按顺序应用滤镜效果。利用result存储别的滤镜的输出可以实现这一点&#xff0c;然后在一个 <feMergeNode>子元素中访问它 1 语法 <feMerge><feMergeNode in""></feMergeNode> </feM…

使用文件读取的open 函数,让你的csv pandas 尾部插入快如闪电

文章目录 简介1. pandas loc 尾部插入方法loc 尾部插入的速度 2. open 方法open方法 处理csv的速度open方法 处理csv代码 简介 笔者在处理稍大型(几十万条)的csv文件时&#xff0c;发现在csv文件中&#xff0c;使用panda的loc方法进行拼接&#xff0c;速度太过于缓慢。 笔者提…

深刻反思现代化进程:20世纪与21世纪的比较分析及东西方思想家的贡献

深刻反思现代化进程&#xff1a;20世纪与21世纪的比较分析及东西方思想家的贡献 摘要&#xff1a;随着人类社会的快速发展&#xff0c;现代化已成为全球范围内的普遍追求。然而&#xff0c;20世纪至21世纪的现代化进程并非一帆风顺&#xff0c;它伴随着环境破坏、社会不平等和文…

【leetcode热题100】不同的二叉搜索树

给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;5示例 2&#xff1a; 输入&#xff1a;n 1 输出&#xff1a;1 …

安装 NVIDIA Chat with RTX

安装 NVIDIA Chat with RTX 0. NVIDIA Chat with RTX 是什么&#xff1f;1. 安装 NVIDIA Chat with RTX2. 使用 NVIDIA Chat with RTX3. NVIDIA Chat with RTX 下载地址 0. NVIDIA Chat with RTX 是什么&#xff1f; Chat With RTX 是一款演示应用程序&#xff0c;可让您个性化…

第8集《佛说四十二章经》

请大家打开讲议第九面&#xff0c;第十二章、举难劝修。 佛陀在这一章共举出二十种困难事情&#xff0c;以劝勉我们修学。一般人的生命没有目标&#xff0c;一天过一天&#xff0c;做事遇到困难就放弃了。这段经文的难是有主动的正面意义&#xff0c;所谓的难能可贵&#xff1…

【Linux学习】生产者-消费者模型

目录 22.1 什么是生产者-消费者模型 22.2 为什么要用生产者-消费者模型? 22.3 生产者-消费者模型的特点 22.4 BlockingQueue实现生产者-消费者模型 22.4.1 实现阻塞队列BlockQueue 1) 添加一个容器来存放数据 2)加入判断Blocking Queue情况的成员函数 3)实现push和pop方法 4)完…

Vue3快速上手(五)ref之对象类型的响应式数据

一、ref之对象类型的响应式数据 1.1 基本语法 import { ref } from vuelet x ref(初始值)console.log(xxx --> , x.value);x为一个RefImpl对象&#xff0c;该对象的value属性为实际值&#xff0c;在script里需要操作x.value来改变数据的值&#xff0c;在页面里则可以直接…

常用算法介绍-->快速排序

本篇文章我们来介绍一下快速排序的算法 1.简介 快速排序是对冒泡排序的一种改进&#xff0c; 它是不稳定的。由C. A. R. Hoare在1962年提出的一种划分交换排序&#xff0c;采用的是分治策略&#xff08;一般与递归结合使用&#xff09;&#xff0c;以减少排序过程中的比较次数…

PHP脉聊交友系统网站源码,可通过广告变现社交在线聊天交友即时通讯APP源码,附带视频搭建教程

探索全新社交体验&#xff1a;一站式PHP交友网站解决方案 &#x1f310; 全球化交友&#xff0c;无界沟通 在数字化的浪潮下&#xff0c;社交已不再受地域限制。我们的PHP交友网站不仅支持多国语言&#xff0c;还配备了即时翻译功能&#xff0c;让您轻松跨越语言障碍&#xff…