Docker 镜像仓库

970 阅读9分钟

Docker 镜像仓库介绍

  • 定义与作用:Docker镜像仓库是一个集中存储和管理Docker镜像的平台,它允许用户上传、下载和分享镜像。这些镜像包含了运行应用程序所需的操作系统、依赖库、配置文件以及应用程序本身。
  • 公共仓库:如Docker Hub,它是官方提供的公共仓库,包含了大量的官方和社区维护的镜像。用户可以方便地从Docker Hub中拉取所需的镜像。
  • 私有仓库:企业或个人可以搭建自己的私有仓库,用于存储内部使用的镜像,确保镜像的安全性和私密性。

1.注册 Docker hub

  • 注册

官方地址:hub.docker.com/

  • 登录
[root@localhost ~]# docker login --help 
Usage:  docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username
[root@localhost ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: your@gmail.com
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
  • 默认登录信息保存在 /root/.docker/config.json
[root@localhost ~]# cat /root/.docker/config.json 
{
        "auths": {
                "https://index.docker.io/v1/": {
                        "auth": "cm9uZ2FueHUyFpS0VESVNo"
                }
        }
}

# 解码
[root@localhost ~]# echo 'cm9uZ2FueHUyFpS0VESVNo' | base64 -d
  • 搜索镜像
[root@localhost ~]# docker search --help 
Usage:  docker search [OPTIONS] TERM
Search the Docker Hub for images
Options:
  -f, --filter filter   "Filter output based on conditions provided"
      --format string   "Pretty-print search using a Go template"
      --limit int       "Max number of search results (default 25)"
      --no-trunc        "Don't truncate output"
      
# 搜索nginx      
[root@localhost ~]# docker search nginx
  • 拉取镜像
[root@localhost ~]# docker pull --help 

Usage:  docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Pull an image or a repository from a registry

Options:
  -a, --all-tags                Download all tagged images in the repository
      --disable-content-trust   Skip image verification (default true)
      --platform string         Set platform if server is multi-platform capable
  -q, --quiet                   Suppress verbose output

# 拉取nginx
[root@localhost ~]# docker pull nginx
  • 推送镜像
[root@localhost ~]# docker push --help 
Usage:  docker push [OPTIONS] NAME[:TAG]
Push an image or a repository to a registry
Options:
  -a, --all-tags                Push all tagged images in the repository
      --disable-content-trust   Skip image signing (default true)
  -q, --quiet                   Suppress verbose output
  
# 推送到个人账号下
[root@localhost ~]# docker tag nginx:1.22.1 name/nginx:1.22.1
[root@localhost ~]# docker push name/nginx:1.22.1
The push refers to repository [docker.io/name/nginx]
9543dec06aa8: Mounted from library/nginx 
ccf4f419ba49: Mounted from library/nginx 
21f8452ebfb1: Mounted from library/nginx 
25bbf4633bb3: Mounted from library/nginx 
a4f34e6fb432: Mounted from library/nginx 
3af14c9a24c9: Mounted from library/nginx 
1.22.1: digest: sha256:9081064712674ffcff7b7bdf874c75bcb8e5fb933b65527026090dacda36ea8b size: 1570

2.官方 Docker Registry

  • 官网 docs.docker.com/registry/
  • docker-registry 是官方提供的工具,可以用于构建私有的镜像仓库。本文是基于 docker-registry v2.x 版本。
  • 安装 docker-registry
[root@localhost ~]# docker run -d -p 5000:5000 --name registry registry:2
Unable to find image 'registry:2' locally
2: Pulling from library/registry
1cc3d825d8b2: Pull complete
85ab09421e5a: Pull complete
40960af72c1c: Pull complete
e7bb1dbb377e: Pull complete
a538cc9b1ae3: Pull complete
Digest: sha256:ac0192b549007e22998eb74e8d8488dcfe70f1489520c3b144a6047ac5efbe90
Status: Downloaded newer image for registry:2
1bcd340bc270e92d49b3aa2ccb975fa2c74d0ba2b1d371404856f788a30f6a26

# -p xx:xx 端口映射,将容器的5000映射到宿主机的5000端口
# 查看容器运行状态
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED              STATUS              PORTS                                  NAMES
1bcd340bc270   registry:2   "/entrypoint.sh /etc…"   About a minute ago   Up About a minute   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   registry
  • 推送镜像
[root@localhost ~]# docker tag nginx:1.24.0 localhost:5000/nginx:1.24.0
[root@localhost ~]# docker push localhost:5000/nginx:1.24.0
The push refers to repository [localhost:5000/nginx]
bc4a3582faa9: Pushed
29492f82bbc2: Pushed
96c08fed6a4c: Pushed
b9a187a24e19: Pushed
13c8460bfc9a: Pushed
420179ad2efa: Pushed
1.24.0: digest: sha256:47e27097c9c6a7ee3b07d44888a6c441af465cfb79bb6b9d205a1294093bb9d0 size: 1570
[root@localhost ~]# curl localhost:5000/v2/_catalog
{"repositories":["nginx"]}
  • 配置非 https 仓库地址

如果你不想使用 127.0.0.1:5000 作为仓库地址,比如想让本网段的其他主机也能把镜像推送到私有仓库。你就得把例如 192.168.199.100:5000 这样的内网地址作为私有仓库地址,这时你会发现无法成功推送镜像。 这是因为 Docker 默认不允许非 HTTPS 方式推送镜像。我们可以通过 Docker 的配置选项来取消这个限制,或者查看下一节配置能够通过 HTTPS 访问的私有仓库。

[root@localhost ~]# docker tag nginx:1.24.0 172.17.0.2:5000/nginx:1.24.0
[root@localhost ~]# docker push 172.17.0.2:5000/nginx:1.24.0
The push refers to repository [172.17.0.2:5000/nginx]
Get "https://172.17.0.2:5000/v2/": http: server gave HTTP response to HTTPS client
  • 修改 docker 配置文件 /etc/docker/daemon.json
[root@localhost ~]# vim /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://alzgoonw.mirror.aliyuncs.com",
        "https://docker.udayun.com",
        "https://docker.211678.top",
        "https://5nkcn10r.mirror.aliyuncs.com",
        "https://do.nark.eu.org",
        "https://dc.j8.work",
        "https://docker.m.daocloud.io",
        "https://dockerproxy.com",
        "https://docker.mirrors.ustc.edu.cn",
        "https://docker.nju.edu.cn"
    ],
    "insecure-registries": ["172.17.0.2:5000"]
}

3.Harbor镜像管理平台

3.1 部署

  • 准备工作

硬件要求

ResourceMinimumRecommended
CPU2 CPU4 CPU
Mem4 GB8 GB
Disk40 GB160 GB

软件参数

SoftwareVersion
Docker EngineVersion 17.06.0-ce+ or higher
Docker Composedocker-compose (v1.18.0+) or docker compose v2 (docker-compose-plugin)
OpenSSLLatest is preferred
  • 检查 Docker 版本
[root@localhost ~]# docker version 
Client: Docker Engine - Community
 Version:           20.10.24
 API version:       1.41
 Go version:        go1.19.7

[root@localhost ~]# docker compose version 
Docker Compose version v2.21.0
# 下载安装包
[root@localhost ~]# wget https://github.com/goharbor/harbor/releases/download/v2.8.4/harbor-offline-installer-v2.8.4.tgz

# 解压 
[root@localhost ~]# tar xvf harbor-offline-installer-v2.8.4.tgz -C /usr/local/
harbor/harbor.v2.8.4.tar.gz
harbor/prepare
harbor/LICENSE
harbor/install.sh
harbor/common.sh
harbor/harbor.yml.tmpl

# 解压后的文件列表
[root@localhost ~]# cd /usr/local/harbor/
[root@localhost harbor]# ll
total 597540
-rw-r--r-- 1 root root      3639 Aug 15 17:53 common.sh
-rw-r--r-- 1 root root 611834153 Aug 15 17:54 harbor.v2.8.4.tar.gz
-rw-r--r-- 1 root root     12499 Aug 15 17:53 harbor.yml.tmpl
-rwxr-xr-x 1 root root      2725 Aug 15 17:53 install.sh
-rw-r--r-- 1 root root     11347 Aug 15 17:53 LICENSE
-rwxr-xr-x 1 root root      1881 Aug 15 17:53 prepare
  • harbor.v2.8.4.tar.gz 存放的是 harbor 需要的镜像,在线安装包只是少这个压缩包。

  • 修改配置文件

    • 我们先配置一个没有ssl证书的仓库,修改了三处配置
[root@localhost ~]# vim harbor.yml
# 1. 镜像仓库的访问地址,可以使用域名 或 IP 地址
hostname: reg.xinxianghf.cloud

# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
  port: 80

# 2. 注释 https 的配置
# https related config
#https:
  # https port for harbor, default is 443
  #  port: 443
  # The path of cert and key files for nginx
  #  certificate: /your/certificate/path
  # private_key: /your/private/key/path

# 3. 修改 镜像存储位置,生产环境要挂载一块较大的磁盘
# The default data volume
data_volume: /data/harbor-reg
  • 执行安装脚本
[root@localhost harbor]# ./install.sh  --help 

Note: Please set hostname and other necessary attributes in harbor.yml first. DO NOT use localhost or 127.0.0.1 for hostname, because Harbor needs to be accessed by external clients.
Please set --with-notary if needs enable Notary in Harbor, and set ui_url_protocol/ssl_cert/ssl_cert_key in harbor.yml bacause notary must run under https. 
Please set --with-trivy if needs enable Trivy in Harbor.
Please do NOT set --with-chartmuseum, as chartmusuem has been deprecated and removed.

# 安装
[root@localhost harbor]# ./install.sh --with-trivy

# 查看运行的容器
[root@localhost harbor]# docker compose ps

3.2 登录 web UI 界面

默认 用户名: admin 密码:Harbor12345 (注意密码大写,图中输入有误)

image.png

  • 默认会提供一个 library 的公开项目

image.png

3.3 上传镜像

  • 在工作中一般是按环境来创建项目,我们创建一个开发环境的项目 dev-myproject
  • 若仓库不公开可不用勾选访问级别

image.png

  • 登录仓库
[root@localhost harbor]# docker login reg.joelearndocker.com
Username: admin
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

# 常见报错
# 若报错 https 验证不通过(参考下面的 /etc/docker/daemon.json 解决办法)
Error response from daemon: Get "https://reg.joelearndocker.com/v2/": dial tcp: lookup reg.joelearndocker.com on 192.168.6.2:53: no such host
# 修改hosts文件
[root@localhost harbor]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.6.132 reg.joelearndocker.com
  • 上传镜像
[root@localhost harbor]# docker tag centos:7 reg.joelearndocker.com/dev-myproject/centos:7 
[root@localhost harbor]# 
[root@localhost harbor]# docker push reg.joelearndocker.com/dev-myproject/centos:7
The push refers to repository [reg.joelearndocker.com/dev-myproject/centos]
Get "https://reg.joelearndocker.com/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
  • 我们看到一个超时的报错,因为 docker push 默认是通过 https 协议通信的,我们的仓库没有开启 https,所以访问不通,需要修改 docker 配置文件 /etc/docker/daemon.json 添加如下行 。
"insecure-registries": ["reg.joelearndocker.com"]
  • 重启 Docker,重新上传镜像
[root@localhost harbor]# docker push reg.joelearndocker.com/dev-myproject/nginx:1.24.0
The push refers to repository [reg.joelearndocker.com/dev-myproject/nginx]
bc4a3582faa9: Pushed
29492f82bbc2: Pushed
96c08fed6a4c: Pushed
b9a187a24e19: Pushed
13c8460bfc9a: Pushed
420179ad2efa: Pushed
1.24.0: digest: sha256:47e27097c9c6a7ee3b07d44888a6c441af465cfb79bb6b9d205a1294093bb9d0 size: 1570

image.png

3.4 添加证书

[root@localhost ~]# vim /usr/local/harbor/harbor.yml
# https related config
https:
  # https port for harbor, default is 443
    port: 443
  # The path of cert and key files for nginx
    certificate: /usr/local/harbor/certs/reg.joelearndocker.com.crt 
    private_key: /usr/local/harbor/certs/reg.joelearndocker.com.key
  • 重启harbor
 docker-compose down -v
 #进入harbor的安装目录
 #修改配置文件
./prepare
# 重新启动
docker compose up -d

3.5 常用功能

  • 修改配置文件重新加载
 docker compose down -v
 #进入harbor的安装目录
 #修改配置文件
./prepare
# 重新启动
docker compose up -d
  • 定时删除镜像

  • 根据公司要求配置保留最近几个版本的镜像,配置定时执行周期即可。

  • 证书到期后更新证书
# 替换证书后重新生成配置文件
./prepare
docker compose down -v
docker compose up -d

附录

Harbor 提供的第三方插件

  • Notary:Notary 是一套镜像的签名工具, 用来保证镜像层在 pull、push、transfer 过程中的一致性和完整性。避免中间人攻击,阻止非法的镜像更新和运行。镜像层的创建者可以对镜像层做数字签名,生成摘要,保存在 Notary 服务中。开启 Content Trust 机制之后,未签名的镜像无法被拉取。安装Notary后 Harbor必须使用 https 。 弃用
  • Trivy:镜像扫描,提供扫描结果,对镜像做漏洞扫描
  • Chart Museum:用于保存helm chart镜像的组件。 弃用

Harbor架构

  • Data Access Layer 数据访问层

  • Fundamental Services 基础服务层

    • Core: Harbor 核心服务
    • Quota Manager: 配额管理
    • Retention Manager: 镜像保留策略管理
    • Chart Museum: chart 管理 弃用
    • Docker Registry: 存储Docker镜像和处理docker push /pull 命令
  • Consumers 消费者

官网架构图

Harbor 连接 1514 端口拒绝

Error response from daemon: failed to initialize logging driver: dial tcp [::1]:1514: connect: connection refused
  • 修改 /etc/rsyslog.conf
# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 1514
systemctl restart rsyslog.service