【Docker】镜像仓库(Registry)

文章目录

  • [1. 什么是 Docker Registry](#1. 什么是 Docker Registry)
  • [2. 镜像仓库分类](#2. 镜像仓库分类)
  • [3. 镜像仓库工作机制](#3. 镜像仓库工作机制)
    • [3.1 镜像仓库使用流程](#3.1 镜像仓库使用流程)
    • [3.2 实际研发中镜像仓库如何使用](#3.2 实际研发中镜像仓库如何使用)
    • [3.3 镜像仓库的拉取机制](#3.3 镜像仓库的拉取机制)
  • [4. 常用的镜像仓库](#4. 常用的镜像仓库)
    • [4.1 DockerHub](#4.1 DockerHub)
    • [4.2 国内镜像源](#4.2 国内镜像源)
    • [4.3 私有仓库](#4.3 私有仓库)
  • [5. 镜像仓库命令](#5. 镜像仓库命令)
    • [5.1 命令清单](#5.1 命令清单)
    • [5.2 docker login](#5.2 docker login)
    • [5.3 docker pull](#5.3 docker pull)
    • [5.4 docker push](#5.4 docker push)
    • [5.5 docker search](#5.5 docker search)
    • [5.6 docker logout](#5.6 docker logout)
  • [6. 镜像命令](#6. 镜像命令)
    • [6.1 docker images](#6.1 docker images)
    • [6.2 docker image inspect](#6.2 docker image inspect)
    • [6.3 docker tag](#6.3 docker tag)
  • [7. 容器命令](#7. 容器命令)
    • [7.1 docker run](#7.1 docker run)
    • [7.2 docker ps](#7.2 docker ps)
  • [8. 综合实战一:搭建一个 Nginx 服务](#8. 综合实战一:搭建一个 Nginx 服务)
    • [8.1 查找 nginx 镜像](#8.1 查找 nginx 镜像)
    • [8.2 拉取 Nginx 镜像(启动 Nginx 站点)](#8.2 拉取 Nginx 镜像(启动 Nginx 站点))
    • [8.3 修改 Nginx 首页](#8.3 修改 Nginx 首页)
  • [9. 综合实战二:阿里云创建自己的私有仓库](#9. 综合实战二:阿里云创建自己的私有仓库)
    • [9.1 创建仓库](#9.1 创建仓库)
    • [9.2 推送镜像到仓库](#9.2 推送镜像到仓库)
      • [9.2.1 打包并推送 Redis 镜像](#9.2.1 打包并推送 Redis 镜像)
      • [9.2.2 打包并推送 Nginx 镜像](#9.2.2 打包并推送 Nginx 镜像)
      • [9.2.3 打包并推送 MySQL 镜像](#9.2.3 打包并推送 MySQL 镜像)
    • [9.3 查看服务器镜像](#9.3 查看服务器镜像)
    • [9.4 退出仓库登录](#9.4 退出仓库登录)
    • [9.5 总结](#9.5 总结)

1. 什么是 Docker Registry

镜像仓库(Docker Registry)负责存储、管理和分发镜像,并且提供了登录认证能力,建立了仓库的索引。

镜像仓库管理多个 Repository, Repository 通过命名来区分。每个 Repository 包含一个或多个镜像,镜像通过镜像名称和标签(Tag)来区分。

整体视图如下:

镜像仓库(Registry):

  • 要从哪一个镜像仓库拉取镜像,通常通过 DNS 或 IP 地址来确定一个镜像仓库,如 hub.docker.com
  • 一个 Registry 中可以存在多个 Repository,而 Repository 可分为 "顶层仓库" 和 "用户仓库",用户仓库名称格式为 "用户名/仓库名"。每个仓库可以包含多个 Tag(标签),每个标签对应一个镜像。

Repository:

  • 由某特定的 docker 镜像的所有迭代版本组成的镜像仓库。

镜像名称(name)+标签(tag):

  • nginx:latest

认证能力:

  • 提供用户注册,登录、登出能力。

索引:

  • 提供镜像的索引信息,方便检索。

一个容器镜像包含了两个部分,一个是元数据,其实就是由 dockerfile 构建出来的描述文件,这个描述文件会说这个容器镜像有多少层,每一层里面有什么内容,它的 checksum 这些信息都会记录下来,还有最终的可执行文件在哪就是在存储数据里面,就是在一个一个的 blob 里面,真正占有空间的就是这些 blob。

大家可以类比超市,一个 Repository 就是一个货架,白象就是组织者,货架上放的产品打的不同标签就是对应的 tag。

2. 镜像仓库分类

按是否对外开放划分,也是研发人员常说的:

  • 公有仓库:像阿里云、dockerhub 等放到公有网络上,不用登录就可以下载镜像,供大家访问使用。
  • 私有仓库:不对外开放,往往位于私有网络,只有公司内部人员可以使用。

按供应商和面向群体划分:

  • sponsor(赞助) registry:第三方的 registry,供客户和 docker 社区版使用。
  • mirror(镜像) registry:第三方的 registry,只让客户使用,例如阿里云必须注册才能使用。
  • vendor(供应商) registry:由发布 docker 镜像的供应商提供的 registry,例如像 Google 和 Redhat 提供了镜像仓库服务。
  • private registry:通过没有防火墙和额外的安全层的私有实体提供的 registry,仅供内部使用。

3. 镜像仓库工作机制

3.1 镜像仓库使用流程

流程如下:

  • 通过 docker login 登录仓库;
  • Docker pull 拉取需要的镜像;
  • 通过 dockerfile 或者 commit 等方式制作完镜像,通过 docker push 上传到仓库

3.2 实际研发中镜像仓库如何使用

Docker Registry 中的镜像通常由开发人员制作,而后推送至 "公共" 或 "私有" Registry 上保存,供其他人员使用,例如 "部署" 到生产环境。

如下图所示:

名词解释:

  • 开发环境:开发人员使用的一套环境;
  • 测试环境:需求开发完成后,发布到供测试人员进行测试的环境;
  • 预发布环境:版本测试完成后,发布到和生产类似的环境,提前模拟生产发布;
  • 生产环境:真正面向客户的环境。

3.3 镜像仓库的拉取机制

启动容器时,docker daemon 会试图从本地获取相关的镜像;

如果本地镜像不存在时,其将从 Registry 中下载该镜像并保存到本地。

4. 常用的镜像仓库

4.1 DockerHub

Docker Hub 是 Docker 提供的托管存储库服务,用于查找容器映像并与您的团队共享。

具有以下功能:

  • 个人可以注册私有仓库,能够发布自己的镜像;
  • 提供镜像检索能力;
  • 提供海量官方和认证组织的镜像;
  • 从 GitHub 和 Bitbucket 自动构建容器镜像并将它们推送到 Docker Hub;
  • 支持 webhook(webhook 是一种基于 HTTP 的回调函数,发生指定的事件时,服务器会自动将相关的有效负载发送到客户端的 webhook URL)

咱们可以浏览器访问 Docker Hub,然后搜索镜像 Nginx:

可以进行 镜像的 tag 查找:

对应的版本拉取命令:同时还会显示镜像的大小、ID、以及 cpu 架构

4.2 国内镜像源

国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内镜像加速器服务,例如:

复制代码
阿里云加速器(点击管理控制台 -> 登录账号(淘宝账号)-> 右侧镜像工具 -> 镜像加速器 -> 复制加速器地址)
网易云加速器地址:https://hub-mirror.c.163.com
百度云加速器地址:https://mirror.baidubce.com

可以在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件):

json 复制代码
{
  # 注意如果最外层以及你给有了配置,不要直接覆盖,而是将下面的内容添加,然后确保 json 的格式正确
  "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}

添加完成后需要重新加载配置,重启 Docker:

shell 复制代码
# 加载配置
sudo systemctl daemon-reload
# 重启 docker
sudo systemctl restart docker
# 查看 docker 状态
sudo systemctl status docker

4.3 私有仓库

私有镜像仓库则是指部署在公司或组织内部,用于自身应用 Docker 镜像存储、分发的镜像仓库。在构建公司内部使用的自动化发布系统的过程中,从安全的角度出发,应用的打包镜像一般情况下只会被存储在私有镜像仓库中,CI/CD 流程的衔接点也是通过向私有镜像仓库上传镜像和拉取镜像的操作来完成的。

常见的私有仓库工具:

  • Harbor:Harbor 是 VMware 公司开源的企业级 Docker Registry 项目,其目标是帮助用户迅速搭建一个企业级的 Docker registry 服务。它以 Docker 公司开源的 registry 为基础,提供了管理 UI、基于角色的访问控制(Role Based Access Control)、AD/LDAP 集成、以及审计日志(Audit logging)等企业用户需求的功能,同时还原生支持中文。Harbor 的每个组件都是以 Docker 容器的形式构建的,使用 Docker Compose 来对它进行部署。
  • Nexus:Nexus 是 Sonatype 公司发布的一款仓库(Repository)管理软件,目前常被用来作为 Maven 私服、Docker 私服。
  • Docker registry:由 docker 官方提供的私服,类似于 docker hub。用于保存公司内部上传的 Docker 镜像。

5. 镜像仓库命令

5.1 命令清单

如下表所示:

命令 别名 功能 备注
docker login 登录仓库 必须掌握
docker pull docker image pull 拉取镜像 必须掌握
docker push docker image push 推送镜像 必须掌握
docker search 查找镜像
docker logout 登出仓库 必须掌握

5.2 docker login

功能:

  • 登录到一个 Docker 镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub,因 docker 网站被封,该命令可以用阿里云或者腾讯云的练习。

语法:

shell 复制代码
docker login [OPTIONS] [SERVER]

关键参数:

  • -u:登录的用户名
  • -p:登录的密码

代码样例:

shell 复制代码
docker login -u 用户名 -p 密码

5.3 docker pull

功能:

  • 从镜像仓库中拉取或者更新指定镜像。

语法:

shell 复制代码
docker pull [OPTIONS] NAME[:TAG|@DIGEST]

别名:

shell 复制代码
docker image pull

关键参数:

  • -a:拉取所有 tagged 镜像
  • --disable-content-trust:忽略镜像的校验,默认开启

代码样例:

shell 复制代码
docker pull nginx:1.23.3

5.4 docker push

功能:

  • 将本地的镜像上传到镜像仓库,要先登录到镜像仓库。

语法:

shell 复制代码
docker push [OPTIONS] NAME[:TAG]

别名:

shell 复制代码
docker image push

关键参数:

  • -a:推送所有 tagged 镜像。
  • --disable-content-trust:忽略镜像的校验,默认开启。

代码样例:

shell 复制代码
docker push myapache:v1

功能:

  • 从 Docker Hub 查找镜像,因 docker 网站被封,该命令暂时国内无法实操,需要国外网络联系。

语法:

shell 复制代码
docker search [OPTIONS] TERM

关键参数:

  • --no-trunc:显示完整的镜像描述;
  • -f <过滤条件>:列出收藏数不小于指定值的镜像。

代码样例:

shell 复制代码
# 从 Docker Hub 查找所有镜像名包含 nginx,并且 star 数大于 10 的镜像
docker search -f stars=10 nginx

5.6 docker logout

功能:

  • 登出一个 Docker 镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub,因 docker 网站被封,该命令可以用阿里云或者腾讯云的镜像仓库练习,参考后面实战部分。

语法:

shell 复制代码
docker logout [SERVER]

代码样例:

shell 复制代码
docker logout

6. 镜像命令

学习仓库前我们需要提前了解一部分的镜像命令,为后续的实战做准备。

6.1 docker images

功能:

  • 列出本地镜像。

语法:

shell 复制代码
docker images [OPTIONS] [REPOSITORY[:TAG]]

别名:

shell 复制代码
docker image ls, docker image list

关键参数:

  • -a:列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);
  • --digests:显示镜像的摘要信息;
  • -f:显示满足条件的镜像;
  • --format:指定返回值的模板文件;
  • --no-trunc:显示完整的镜像信息;
  • -q:只显示镜像 ID。

代码样例:

shell 复制代码
#列出本地全部镜像
docker images
#列出本地镜像中 REPOSITORY 为 ubuntu 的镜像列表。
docker images ubuntu

6.2 docker image inspect

功能:

  • 查看镜像详细信息。

语法:

shell 复制代码
docker image inspect [OPTIONS] IMAGE [IMAGE...]

代码样例:

shell 复制代码
#查看镜像详细信息
docker image inspect nginx:1.23.3

6.3 docker tag

功能:

  • 标记本地镜像,将其归入某一仓库。

语法:

shell 复制代码
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

别名:

shell 复制代码
docker image tag

代码样例:

shell 复制代码
docker tag ubuntu:22.04 myregistry.com/myubuntu:22.04

7. 容器命令

学习仓库前我们需要提前了解一部分的容器命令,为后续的实战做准备。

7.1 docker run

功能:

  • 创建一个新的容器并运行一个命令。

语法:

shell 复制代码
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

别名:

shell 复制代码
docker container run

关键参数:

  • -d:后台运行容器,并返回容器 ID;
  • -i:以交互模式运行容器,通常与 -t 同时使用;
  • -P:随机端口映射,容器内部端口随机映射到主机的端口;
  • -p:指定端口映射,格式为:主机(宿主)端口:容器端口;
  • -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
  • --name="nginx-lb":为容器指定一个名称;
  • -h "mars":指定容器的 hostname;
  • -e username="ritchie":设置环境变量;
  • --cpuset-cpus="0-2" or --cpuset-cpus="0,1,2":绑定容器到指定 CPU 运行;
  • -m:设置容器使用内存最大值;
  • --network="bridge":指定容器的网络连接类型;
  • --link=[]:添加链接到另一个容器;
  • --volume, -v:绑定一个卷;
  • --rm:shell 退出的时候自动删除容器。

代码样例:

shell 复制代码
#使用 docker 镜像 nginx:latest 以后台模式启动一个容器,并将容器命名为 mynginx。
docker run --name mynginx -d nginx:latest

#使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。
docker run -p 80:80 -v /data:/data -d nginx:latest

7.2 docker ps

功能:

  • 列出容器。

语法:

shell 复制代码
docker ps [OPTIONS]

别名:

shell 复制代码
docker container ls, docker container list, docker container ps

关键参数:

  • -a:显示所有的容器,包括未运行的;
  • -f:根据条件过滤显示的内容;
  • --format:指定返回值的模板文件。如 json 或者 table;
  • -l:显示 latest 的容器;
  • -n:列出最近创建的 n 个容器;
  • --no-trunc:不截断输出;
  • -q:静默模式,只显示容器编号;
  • -s:显示总的文件大小。

代码样例:

shell 复制代码
docker ps -a

8. 综合实战一:搭建一个 Nginx 服务

8.1 查找 nginx 镜像

使用 docker search 可以查找,但是 nginx 的详细的 tag 我们看不见,所以建议直接去 Docker Hub 网页上搜索

这里选用 1.25.0 版本即可

8.2 拉取 Nginx 镜像(启动 Nginx 站点)

(1)拉取 nginx 镜像

shell 复制代码
# 拉取
docker pull nginx:1.25.0

结果如下所示:

(2)查看本地是否有该镜像

shell 复制代码
# 查看
docker images nginx

# 或者查看镜像的详细信息
docker image inspect nginx:1.25.0

结果如下所示:

(3)运行镜像

shell 复制代码
# 运行
docker run -p 8081:80 --name myNginx1 -h myNginx1.com -e myenv=test nginx:1.25.0

官方的 nginx:1.25.0 镜像,默认内部监听的端口是 80,但是我的 80 端口已经被 nginx:1.24.0 给占用了,所以我改成了把宿主机的 8081 端口映射到了容器内部默认的 80 端口。现在,只要访问宿主机的 8081,流量就会被完美转发给 Nginx。

如下所示:

但此时咱们的服务是在前台运行的,一旦关闭这个终端窗口,或者按下 Ctrl + C,这个 Nginx 容器就会立刻停止运行。

为了让它在服务器后台安静地长久运行,建议在 run 后面加上 -d(Daemon,后台运行):

shell 复制代码
docker run -d -p 8081:80 --name myNginx1 -h myNginx1.com -e myenv=test nginx:1.25.0

运行结果如下所示:

这个报错意思是:myNginx1 这个容器名字已经被占用了。

这是因为上一条没有加 -d 的命令虽然被终止了(或者报错了),但那个配置错误的旧容器依然残留在系统里,占着坑不走。Docker 不允许同时存在两个同名的容器。

先把那个占坑的旧容器删掉:

shell 复制代码
# 运行以下命令,强制删除那个死掉的同名容器
docker rm -f myNginx1

然后重新运行正确命令:

shell 复制代码
# 现在坑位空出来了,再次运行你写对的那条命令
docker run -d -p 8081:80 --name myNginx1 -h myNginx1.com -e myenv=test nginx:1.25.0

结果如下所示:成功返回了容器的 ID。

在浏览器里输入 http://你的Ubuntu服务器IP:8081 即可访问

8.3 修改 Nginx 首页

现在重新不要运行 Nginx 服务,直接给我打开这个容器内部的 Linux 命令行(Bash)。

shell 复制代码
# 创建容器并进入其内部
docker run -p 8082:80 --name myNginx2 -h myNginx2.com -e myenv=test -it nginx:1.25.0 bash

此时进入了 myNginx2 这个隔离的容器小世界里。

然后启动 nginx

shell 复制代码
# 直接输入nginx 即可启动成功
nginx

运行结果如下所示:

然后修改 /usr/share/nginx/html/ 的内容:

shell 复制代码
# 进入到目录
cd /usr/share/nginx/html/

# 修改nginx页面
echo "hello, I am in docker, my port is 8082" > index.html

此时再去网页上刷新即可:

9. 综合实战二:阿里云创建自己的私有仓库

9.1 创建仓库

创建好账号以后,登录你的阿里云控制台添加链接描述,开通【容器镜像服务个人版】(完全免费)。

然后点击【个人版示例】,选择【创建命名空间】

然后选择【创建镜像仓库】

然后设置仓库为本地仓库,完成创建

9.2 推送镜像到仓库

先登录阿里云 Container Registry

shell 复制代码
# 登录
docker login --username=阿里云ID crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com

结果如下所示:

接下来,我要把当前运行的这三个镜像(redis:7.0.15、nginx:1.24.0、mysql:8.4.2)全部上传到阿里云,那么需要遵循 "先打标签(tag),再推送(push)" 的标准流程。

我的仓库名是 edison_wear,命名空间是 aiwear,那么你的阿里云专属镜像路径规则就是:

shell 复制代码
crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com/aiwear/edison_wear:[镜像版本号]

因为我要把三个不同的服务(Redis、Nginx、MySQL)都推送到同一个仓库 edison_wear 中,最规范的做法是通过 Tag(标签/版本号) 来区分它们,例如:redis-7.0.15、nginx-1.24.0、mysql-8.4.2。

9.2.1 打包并推送 Redis 镜像

命令如下所示:

shell 复制代码
# 1. 打标签
docker tag redis:7.0.15 crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com/aiwear/edison_wear:redis-7.0.15

# 2. 推送
docker push crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com/aiwear/edison_wear:redis-7.0.15

运行结果如下所示:

9.2.2 打包并推送 Nginx 镜像

命令如下所示:

shell 复制代码
# 1. 打标签
docker tag nginx:1.24.0 crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com/aiwear/edison_wear:nginx-1.24.0

# 2. 推送
docker push crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com/aiwear/edison_wear:nginx-1.24.0

运行结果如下所示:

9.2.3 打包并推送 MySQL 镜像

命令如下所示:

shell 复制代码
# 1. 打标签
docker tag mysql:8.4.2 crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com/aiwear/edison_wear:mysql-8.4.2

# 2. 推送
docker push crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com/aiwear/edison_wear:mysql-8.4.2

运行结果如下所示:

9.3 查看服务器镜像

如下所示:

9.4 退出仓库登录

为了服务器的安全(特别是公共服务器或测试机),操作完成后建议随手退出登录,清除本地的认证凭证。

退出登录非常简单,使用 logout 命令,后面加上你的 阿里云仓库域名即可:

bash 复制代码
docker logout crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com

结果如下所示:

终端会提示 Removing login credentials for ...(正在移除登录凭证)。此时,原本保存在 /root/.docker/config.json 里的明文加密凭证就会被自动删掉。后续如果没有重新 login,这台服务器就无法再往你的私有仓库里推拉镜像了。

9.5 总结

以后如果你在其他服务器上,或者本地重装了系统,想要把这些镜像下载下来,只需要两步:

第一步:先登录(如果是私有仓库)

如果你的阿里云仓库设置的是 "私有"(默认一般是私有,只有你能看),拉取前必须先执行登录命令:

bash 复制代码
docker login --username=阿里云ID crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com

💡 注意:如果你的仓库在阿里云后台被你改成了 "公开(Public)",那就可以跳过登录,任何人都能直接拉取。*

第二步:执行拉取命令

直接用推送时的 完整长路径 + 对应的 Tag 即可。例如:

拉取 Redis

bash 复制代码
docker pull crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com/aiwear/edison_wear:redis-7.0.15

拉取 Nginx

bash 复制代码
docker pull crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com/aiwear/edison_wear:nginx-1.24.0

拉取 MySQL

bash 复制代码
docker pull crpi-z8ulxt5cu2ysgj9k.cn-chengdu.personal.cr.aliyuncs.com/aiwear/edison_wear:mysql-8.4.2
相关推荐
小则又沐风a1 小时前
今日算法----一篇文章学会背包问题
运维·服务器·算法
IT策士1 小时前
第 41 篇 k8s之监控:Metrics Server 与 Prometheus 快速上手
容器·kubernetes·prometheus
梦梦代码精1 小时前
从源码到上线:实测开源电商系统的技术选型与部署落地
docker·开源
William Dawson1 小时前
2核2G服务器优化指南
运维·服务器
Junsir大斗师2 小时前
rocky9.7搭建grafana+loki+prometheus+alloy+node_exporter运维监控平台
linux·运维·grafana·prometheus
snow@li2 小时前
Java:Java后端开发,本地开发环境,服务器部署环境,运维支撑环境 都需要哪些类别的工具或技术 / Java后端三大环境完整清单 202606
java·运维·服务器
呆萌的代Ma2 小时前
解决docker网络问题,通过GitHub Actions打包dockerfile
docker·容器·github
草莓熊Lotso2 小时前
【Linux网络】深入理解 HTTP 协议(三):静态资源服务、状态码与重定向实战
linux·运维·服务器·网络·c++·http
我命由我123452 小时前
Excel - Excel 查看当前单元格格式
运维·学习·职场和发展·excel·求职招聘·职场发展·学习方法