Docker镜像私有仓库


在Docker中,当我们执行 docker pull xxx 的时候 ,它实际上是从 hub.docker.com 这个地址去查找,这就是 Docker 公司为我们提供的公共仓库。在工作中,我们不可能把企业项目 push 到公有仓库进行管理。所以为了更好的管理镜像,Docker 不仅提供了一个中央仓库,同时也允许我们搭建本地私有仓库。

所谓私有仓库,也就是在本地(局域网)搭建的一个类似公共仓库的东西,搭建好之后,我们可以将镜像提交到私有仓库中。这样我们既能使用 Docker 来运行我们的项目镜像,也避免了商业项目暴露出去的风险。

docker容器镜像仓库分类:

  • 公网仓库:docker hub
  • 私网仓库: registry、harbor

目前比较流行的两个镜像私库是Docker Registry和HarBor。

registry是Docker官方提供的一个镜像,用来搭建私有镜像仓库,存储和管理镜像。

HarBor比较合适企业级应用,提供良好的WEB界面进行管理。

一、registry镜像仓库

1.1、 registry 仓库搭建

搭建步骤

  • 拉取 registry 容器镜像
  • 创建 registry 仓库容器
  • 测试容器应用

搭建过程

a、拉取registry容器镜像

docker pull registry

b、创建registry仓库容器

#1、创建持久化存储,将容器镜像存储目录/var/lib/registry挂载到本地/data/myregistry下:
mkdir -p /data/myregistry

# 2、创建 registry 容器:
docker run -d -p 5000:5000 -v /data/myregistry:/var/lib/registry  --restart=always registry:latest

3、查看容器是否运行
docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
6b20b55fe6f8        registry:latest     "/entrypoint.sh /etc…"   2 minutes ago       Up 2 minutes        0.0.0.0:5000->5000/tcp   busy_mclean

c、测试容器应用

curl http://192.168.8.150:5000/v2/_catalog

{"repositories":[]}

# 显示仓库中没有任何镜像

1.2、registry仓库应用-上传镜像

上传镜像步骤

  • 设置docker仓库为registry本地仓库
  • 给需要存储的镜像打tag
  • 上传镜像到registry仓库

演示案例

将nginx:latest上传到仓库

查看当前本地镜像

docker images

REPOSITORY                             TAG       IMAGE ID       CREATED         SIZE
nginx                                  latest    1ee494ebb83f   8 days ago      192MB
wordpress                              latest    c89b40a25cd1   13 days ago     700MB
tomcat                                 latest    6fe34209851f   3 weeks ago     467MB
ubuntu                                 latest    fec8bfd95b54   7 weeks ago     78.1MB
mysql                                  latest    56a8c14e1404   7 weeks ago     603MB
busybox                                latest    517b897a6a83   2 months ago    4.27MB

a、设置docker仓库为registry本地仓库

#1、修改docker进程启动文件,修改其启动方式,目的是为了让通过docker配置文件启动
sed -i.bak '/^ExecStart=/c\ExecStart=\/usr\/bin\/dockerd' /usr/lib/systemd/system/docker.service

#2、设置docker 守护进程的配置文件 /etc/docker/daemon.json,默认没有该文件
vim /etc/docker/daemon.json
{
 "insecure-registries": ["http://192.168.8.150:5000"]
}

# insecure-registries 指定非安全的仓库地址,多个用逗号隔开

#3、重启docker生效配置文件
systemctl daemon-reload
systemctl restart docker

b、给需要存储的镜像打tag

docker tag nginx:latest 192.168.8.150:5000/nginx:latest

docker images

REPOSITORY                             TAG       IMAGE ID       CREATED         SIZE
192.168.8.150:5000/nginx               latest    1ee494ebb83f   8 days ago      192MB
nginx                                  latest    1ee494ebb83f   8 days ago      192MB
wordpress                              latest    c89b40a25cd1   13 days ago     700MB
tomcat                                 latest    6fe34209851f   3 weeks ago     467MB
ubuntu                                 latest    fec8bfd95b54   7 weeks ago     78.1MB
mysql                                  latest    56a8c14e1404   7 weeks ago     603MB
busybox                                latest    517b897a6a83   2 months ago    4.27MB

c、上传镜像到registry仓库

#1、上传镜像
docker push 192.168.8.150:5000/nginx:latest

The push refers to repository [192.168.8.150:5000/nginx]
1da799aaf1ec: Pushed 
f598357997c6: Pushed 
630012d2d35b: Pushed 
4dcde7ab808a: Pushed 
64dc1b92ebb6: Pushed 
7db2133dafb9: Pushed 
fd05189e6e81: Pushed 
ee645629aa71: Pushed 
v1: digest: sha256:507a5ad9dd5771cdf461a6fa24c3fff6ea9eabd6945abf03e9264d3130fe816b size: 1996

#2、查看上传
curl http://192.168.8.150:5000/v2/_catalog

{"repositories":["nginx"]}

#查看存储文件夹

ls /opt/docker_repos/docker/registry/v2/repositories/nginx/

_layers  _manifests  _uploads

1.3、 registry仓库应用-客户端下载镜像

  • 设置客户端docker仓库为registry仓库
  • 拉取镜像到本地

演示案例

要求192.168.8.241[hostname:node1]机器的容器可以下载registry仓库中的镜像

a、设置182.168.8.150[hostname:node2]机器的docker仓库为registry仓库

#1、设置docker启动文件
sed -i.bak '/^ExecStart=/c\ExecStart=\/usr\/bin\/dockerd' /usr/lib/systemd/system/docker.service

#2、设置docker配置文件
vim  /etc/docker/daemon.json

{
 "insecure-registries": ["http://192.168.8.150:5000"]
}

b、下载镜像 182.168.8.241[hostname:node1]机器上的docker可以拉取registry仓库中的182.168.8.150:5000/centos_nginx:v1容器镜像

docker pull 192.168.8.150:5000/nginx:latest

v1: Pulling from centos_nginx
dcd04d454f16: Pull complete 
5cb2e05aa6e1: Pull complete 
870634eb98b4: Pull complete 
0fae9697ee4b: Pull complete 
18ad57cfcecb: Pull complete 
64dd6f0d85c1: Pull complete 
7178b0b4388e: Pull complete 
34de8795cd41: Pull complete 
Digest: sha256:507a5ad9dd5771cdf461a6fa24c3fff6ea9eabd6945abf03e9264d3130fe816b
Status: Downloaded newer image for 192.168.8.150:5000/nginx:latest
192.168.8.150:5000/nginx:latest

#验证下载
docker images

REPOSITORY                TAG          IMAGE ID     CREATED         SIZE
192.168.8.150:5000/nginx   v1        1ee494ebb83f   8 days ago      192MB

1.4、registry带basic认证的仓库

实现步骤

  • 安装需要认证的包
  • 创建存放认证信息的文件
  • 创建认证信息
  • 创建带认证的registry容器
  • 指定仓库地址
  • 登录认证

实现过程 a、安装需要认证的包

yum -y install httpd-tools

b、创建存放认证信息的文件

mkdir -p /opt/registry-var/auth

c、创建认证信息

htpasswd -Bbn zuolaoshi 123456 >> /opt/registry-var/auth/htpasswd

d、创建带认证的registry容器

docker run -d -p 10000:5000 --restart=always --name registry \
-v  /opt/registry-var/auth:/auth \
-v /opt/myregistry:/var/lib/registry \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
registry:latest

e、指定仓库地址

vim /etc/docker/daemon.json 
{
 "insecure-registries": ["http://192.168.8.150:5000","http://192.168.8.150:10000"]
}

f、登录认证

docker login 192.168.8.150:10000
Username:zuolaoshi
Password:123456

二、 harbor镜像仓库

Harbor 是 VMware 公司开源的企业级 Docker Registry 项目,其目标是帮助用户迅速搭建一个企业级的 Docker Registry (私有仓库)服务。

Harbor以 Docker 公司开源的 Registry 为基础,提供了图形管理 UI 、基于角色的访问控制(Role Based AccessControl) 、AD/LDAP 集成、以及审计日志(Auditlogging) 等企业用户需求的功能,同时还原生支持中文。

Harbor 的每个组件都是以 Docker 容器的形式构建的,使用 docker-compose 来对它进行部署。用于部署 Harbor 的 docker-compose 模板位于 harbor/docker-compose.yml

Harbor的特性

  • 基于角色控制:用户和仓库都是基于项目进行组织的,而用户在项目中可以拥有不同的权限。

  • 基于镜像的复制策略:镜像可以在多个Harbor实例之间进行复制(同步)。

  • 支持 LDAP/AD:Harbor 可以集成企业内部已有的 AD/LDAP(类似数据库的一张表),用于对已经存在的用户认证和管理。

  • 镜像删除和垃圾回收:镜像可以被删除,也可以回收镜像占用的空间。

  • 图形化用户界面:用户可以通过浏览器来浏览,搜索镜像仓库以及对项目进行管理。

  • 审计管理:所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。

  • 支持 RESTful API:RESTful API 提供给管理员对于 Harbor 更多的操控, 使得与其它管理软件集成变得更容易。

  • Harbor和docker registry的关系:Harbor实质上是对docker registry做了封装,扩展了自己的业务模板。

img

如上图所示是 Harbor 2.0 的架构图,从上到下可分为代理层、功能层和数据层。

  • 代理层:代理层实质上是一个 Nginx 反向代理,负责接收不同类型的客户端请求,包括浏览器、用户脚本、Docker 等,并根据请求类型和 URI 转发给不同的后端服务进行处理。

  • 功能层:

    • Portal:是一个基于 Argular 的前端应用,提供 Harbor 用户访问的界面。
    • Core:是 Harbor 中的核心组件,封装了 Harbor 绝大部分的业务逻辑。
    • JobService:异步任务组件,负责 Harbor 中很多比较耗时的功能,比如 Artifact 复制、扫描、垃圾回收等。
    • Docker Distribution:Harbor 通过 Distribution 实现 Artifact 的读写和存取等功能。
    • RegistryCtl:Docker Distribution 的控制组件。
    • Notary(可选):基于 TUF 提供镜像签名管理的功能。
    • 扫描工具(可选):镜像的漏洞检测工具。
    • ChartMuseum(可选):提供 API 管理非 OCI 规范的 Helm Chart,随着兼容 OCI 规范的 Helm Chart 在社区上被更广泛地接受,Helm Chart 能以 Artifact 的形式在 Harbor 中存储和管理,不再依赖 ChartMuseum,因此 Harbor 可能会在后续版本中移除对 ChartMuseum 的支持。
  • 数据层

    • Redis:主要作为缓存服务存储一些生命周期较短的数据,同时对于 JobService 还提供了类似队列的功能。
    • PostgreSQL:存储 Harbor 的应用数据,比如项目信息、用户与项目的关系、管理策略、配置信息、Artifact 的元数据等等。
    • Artifact 存储:存储 Artifact 本身的内容,也就是每次推送镜像、Helm Chart 或其他 Artifact 时,数据最终存储的地方。默认情况下,Harbor 会把 Artifact 写入本地文件系统中。用户也可以修改配置,将 Artifact 存储在外部存储中,例如亚马逊的对象存储S3、谷歌云存储 GCS、阿里云的对象存储 OSS 等等。

Harbor官方项目:https://github.com/goharbor

Harbor官方网站:https://goharbor.io/

Harbor离线安装包下载地址:https://github.com/goharbor/harbor

docker-compose版本选择:https://github.com/docker/compose/releases

2.1 harbor下载

wget https://storage.googleapis.com/harbor-releases/release-1.9.0/harbor-offline-installer-v1.9.2-rc1.tgz

2.2 docker-compose安装

容器编排工具,执行./install.sh时需要。如果不安装,一会重启docker服务,相关的harbor容器会死掉,安装后就会被随着docker重启

curl -L  https://github.com/docker/compose/releases/download/v2.25.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

2.3 harbor安装

tar xf harbor-offline-installer-v1.9.2-rc1.tgz
mv harbor /opt/

# 修改配置文件中的主机名为本机域名或IP
grep "^hostname" /opt/harbor/harbor.yml

hostname: 192.168.8.150

## 安装
bash /opt/harbor/install.sh
✔ ----Harbor has been installed and started successfully.----

Now you should be able to visit the admin portal at http://192.168.8.150. 
For more details, please visit https://github.com/goharbor/harbor .

2.4 docker设置仓库为harbor

1、修改docker守护进程配置文件,由于没有配置https,需要设置insecure-registries,才能正常使用
vim /etc/docker/daemon.json
{
    "insecure-registries": ["http://192.168.8.150"]
}

2、重启docker服务
systemctl daemon-reload
systemctl restart docker

2.5 镜像上传到harbor

#登陆harbor
docker login http://192.168.8.150 -u admin -p Harbor12345

Login Succeeded

#修改镜像name:tag为harbor仓库名
docker tag nginx:latest 192.168.8.150/library/nginx:latest

#上传镜像
docker push 192.168.8.150/library/nginx:latest

The push refers to repository [192.168.8.150/library/nginx]
968786242e9d: Pushed 
v1: digest: sha256:d204253a33c6c2c74273fbd003cf3e14a48bcdd5c7bc10f51ccbad9e4dd39699 size: 528

常见问题

docker-compose命令无法使用

docker-compose ps

ERROR:
Can’t find a suitable configuration file in this directory or any
parent. Are you in the right directory?
Supported filenames: docker-compose.yml, docker-compose.yaml

原因: 当前目录没有配置文件

# 正确执行路径harbor安装目录
docker-compose ps

      Name                     Command                State               Ports          
-----------------------------------------------------------------------------------------
harbor-core         /harbor/harbor_core              Up                                  
harbor-db           /docker-entrypoint.sh            Up         5432/tcp                 
harbor-jobservice   /harbor/harbor_jobservice  ...   Up                                  
harbor-log          /bin/sh -c /usr/local/bin/ ...   Up         127.0.0.1:1514->10514/tcp
harbor-portal       nginx -g daemon off;             Up         8080/tcp                 
nginx               nginx -g daemon off;             Up         0.0.0.0:80->8080/tcp     
redis               redis-server /etc/redis.conf     Up         6379/tcp                 
registry            /entrypoint.sh /etc/regist ...   Up         5000/tcp                 
registryctl         /harbor/start.sh                 Exit 137        
docker tag mysql:5.7 192.168.8.150/library/mysql:5.7
docker push 192.168.8.150/library/mysql:5.7
docker tag centos:7 192.168.8.150/library/centos:7
docker push 192.168.8.150/library/centos:7

初始用户密码: admin Harbor12345

image-20240424212204209