6 Docker仓库管理

6.1 Docker仓库介绍

Docker仓库,类似于yum仓库,是用来保存镜像的仓库。为了方便的管理和使用docker镜像,可以将镜像集中保存至Docker仓库中,将制作好的镜像push到仓库集中保存,在需要镜像时,从仓库中pull镜像即可。

Docker 仓库分为公有云仓库和私有云仓库

公有云仓库:由互联网公司对外公开的仓库

  • 官方
  • 阿里云等第三方仓库

私有云仓库:组织内部搭建的仓库,一般只为组织内部使用,常使用下面软件搭建仓库

  • docker registory
  • docker harbor

6.1.1 官方 docker 仓库

将自制的镜像上传至docker仓库;https://hub.docker.com/

6.1.2 注册账户

访问hub.docker.com注册账户,并登录

image-20240216155545369

登录成功

image-20240216155554745

6.1.3 使用用户仓库管理镜像

每个注册用户都可以上传和管理自已的镜像

6.1.3.1 用户登录

上传镜像前需要执行docker login命令登录,登录后生成~/.docker/config.json文件保存验证信息

格式

docker login [OPTIONS] [SERVER]
选项:  
-p, --password string   Password
    --password-stdin   Take the password from stdin
-u, --username string   Username

范例:

#登录docker官方仓库方法1
[root@centos7 ~]#docker login -u everycool -ppassword docker.io
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
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

image-20240216155606574

#登录docker官方仓库方法2
[root@centos7 ~]#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: everycool
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

image-20240216155616081

#登录成功后,自动生成验证信息,下次会自动登录,而无需手动登录
[root@centos7 ~]#cat .docker/config.json 
{
	"auths": {
		"https://index.docker.io/v1/": {
			"auth": "ZXZlcnljb29sOnF3ZTEyMy4uemg="
		}
	}
}
[root@centos7 ~]#

6.1.3.2 给本地镜像打标签

上传本地镜像前必须先给上传的镜像用docker tag 命令打标签

标签格式: docker.io/用户帐号/镜像名:TAG

范例:

[root@centos7 ~]#docker images | grep alpine
nginx-alpine        1.16.1           4c159179047a   2 days ago      207MB
alpine-base         3.11             032345eab77e   2 days ago      184MB
alpine              3.11             c059bfaa849c   5 weeks ago     5.59MB
alpine              latest           c059bfaa849c   5 weeks ago     5.59MB
nginx               1.21.1-alpine    1318bf5f63b4   4 months ago    22.8MB

[root@centos7 ~]#docker tag alpine:3.11 docker.io/everycool/alpine:3.11-v1

6.1.3.3 上传本地镜像至官网

#如tag省略,将上传指定REPOSITORY的所有版本,如下示例
#[root@ubuntu1804 ~]#docker push docker.io/everycool/alpine

[root@centos7 ~]#docker push docker.io/everycool/alpine:3.11-v1
The push refers to repository [docker.io/everycool/alpine]
8d3ac3489996: Mounted from library/alpine 
3.11-v1: digest: sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3 size: 528

6.1.3.4 在官网验证上传的镜像

image-20240216155628942

image-20240216155636840

6.1.3.5 下载上传的镜像并创建容器

在另一台主机上下载镜像

[root@centos7 ~]#docker pull everycool/alpine:3.11-v1
3.11-v1: Pulling from everycool/alpine
59bf1c3509f3: Pulling fs layer 
3.11-v1: Pulling from everycool/alpine
59bf1c3509f3: Pull complete 
Digest: sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3
Status: Downloaded newer image for everycool/alpine:3.11-v1
docker.io/everycool/alpine:3.11-v1

[root@centos7 ~]#docker images
REPOSITORY         TAG       IMAGE ID       CREATED       SIZE
everycool/alpine   3.11-v1   c059bfaa849c   5 weeks ago   5.59MB

[root@centos7 ~]#docker run -it --rm everycool/alpine:3.11-v1 sh

/ # 
/ # cat /etc/issue 
Welcome to Alpine Linux 3.15
Kernel \r on an \m (\l)

/ # df -h
/ # exit

6.1.4 使用组织管理镜像

组织类似于名称空间,每个组织的名称全网站唯一,一个组织可以有多个用户帐户使用,并且可以指定不同用户对组织内的仓库不同的权限

三种不同权限

  • Read-only: Pull and view repository details and builds
  • Read &Write: Pull, push, and view a repository; view, cancel, retry or trigger builds
  • Admin: Pull, push, view, edit, and delete a repository; edit build settings; update the repository description

6.1.4.1 创建组织

image-20240216155648337

image-20240216155656452

需要收费

image-20240216155703789

image-20240216155710914

6.1.4.2 创建组织内的团队,并分配权限

image-20240216155717891

image-20240216155725201

6.2 阿里云镜像仓库

image-20240216155734200

6.2.1 注册和登录阿里云仓库

用浏览器访问http://cr.console.aliyun.com,输入注册的用户信息登录网站

image-20240216155745368

image-20240216155754226

image-20240216155801534

image-20240216155809863

6.2.2 设置仓库专用管理密码

image-20240216155817592

image-20240216155825554

image-20240216155834588

image-20240216155842312

image-20240216155851691

image-20240216155902878

6.2.3 创建仓库

此步可不事先执行,docker push 时可以自动创建私有仓库

image-20240216155911498

image-20240216155920981

image-20240216155934570

image-20240216155944980

image-20240216155952425

查看仓库的路径用于上传镜像使用

6.2.4 上传镜像前先登录阿里云

[root@centos7 ~]#docker login --username=156****8892 registry.cn-hangzhou.aliyuncs.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

#登录密码保存在~/.docker/config.json文件中,下次将不会需要再输入密码登录
[root@centos7 ~]#cat .docker/config.json 
{
	"auths": {
		"registry.cn-hangzhou.aliyuncs.com": {
			"auth": "MTU2MjM3Mjg4OTI6cXdlMTIzLi56aA=="
		}
	}
}
[root@centos7 ~]#

6.2.5 给上传的镜像打标签

[root@centos7 ~]#docker images 
REPOSITORY         TAG       IMAGE ID       CREATED       SIZE
everycool/alpine   3.11-v1   c059bfaa849c   5 weeks ago   5.59MB


[root@centos7 ~]#docker tag everycool/alpine:3.11-v1 registry.cn-hangzhou.aliyuncs.com/zhlinux/alpine:3.11-v1

[root@centos7 ~]#docker images 
REPOSITORY                                         TAG       IMAGE ID       CREATED       SIZE
everycool/alpine                                   3.11-v1   c059bfaa849c   5 weeks ago   5.59MB
registry.cn-hangzhou.aliyuncs.com/zhlinux/alpine   3.11-v1   c059bfaa849c   5 weeks ago   5.59MB

6.2.6 上传镜像至阿里云

[root@centos7 /etc/sysconfig/network-scripts]#docker push registry.cn-hangzhou.aliyuncs.com/zhlinux/alpine:3.11-v1
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/zhlinux/alpine]
8d3ac3489996: Pushed 
3.11-v1: digest: sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3 size: 528

6.2.7 在网站查看上传的镜像

image-20240216160002956

6.2.8 从另一台主机上下载刚上传的镜像并运行容器

[root@centos7 ~]#docker images 
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
[root@centos7 ~]#docker pull registry.cn-hangzhou.aliyuncs.com/zhlinux/alpine:3.11-v1
3.11-v1: Pulling from zhlinux/alpine
59bf1c3509f3: Pull complete 
Digest: sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/zhlinux/alpine:3.11-v1
registry.cn-hangzhou.aliyuncs.com/zhlinux/alpine:3.11-v1

6.2.9 拉取私有镜像

[root@centos7 ~]#docker pull centos:7
7: Pulling from library/centos
2d473b07cdd5: Pull complete 
Digest: sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987
Status: Downloaded newer image for centos:7
docker.io/library/centos:7
[root@centos7 ~]#docker images 
REPOSITORY                                         TAG       IMAGE ID       CREATED        SIZE
registry.cn-hangzhou.aliyuncs.com/zhlinux/alpine   3.11-v1   c059bfaa849c   5 weeks ago    5.59MB
centos                                             7         eeb6ee3f44bd   3 months ago   204MB
[root@centos7 ~]#docker tag centos:7 registry.cn-hangzhou.aliyuncs.com/zhlinux/centos:7
[root@centos7 ~]#docker push registry.cn-hangzhou.aliyuncs.com/zhlinux/centos:7 
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/zhlinux/centos]
174f56854903: Pushed 
7: digest: sha256:dead07b4d8ed7e29e98de0f4504d87e8880d4347859d839686a31da35a3b532f size: 529

#先登录仓库,否则会报错如下
[root@centos7 ~]#docker pull registry.cn-hangzhou.aliyuncs.com/zhlinux/centos:7
Error response from daemon: pull access denied for registry.cn-hangzhou.aliyuncs.com/zhlinux/centos, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

[root@centos7 ~]#docker login registry.cn-hangzhou.aliyuncs.com
Username: ****
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@centos7 ~]#docker pull registry.cn-hangzhou.aliyuncs.com/zhlinux/centos:7
7: Pulling from zhlinux/centos
2d473b07cdd5: Pull complete 
Digest: sha256:dead07b4d8ed7e29e98de0f4504d87e8880d4347859d839686a31da35a3b532f
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/zhlinux/centos:7
registry.cn-hangzhou.aliyuncs.com/zhlinux/centos:7

6.3 私有云单机仓库Docker Registry

6.3.1 Docker Registry 介绍

Docker Registry作为Docker的核心组件之一负责镜像内容的存储与分发,客户端的docker pull以及push命令都将直接与registry进行交互,最初版本的registry 由Python实现,由于设计初期在安全性,性能以及API的设计上有着诸多的缺陷,该版本在0.9之后停止了开发,由新项目distribution(新的docker register被称为Distribution)来重新设计并开发下一代registry,新的项目由go语言开发,所有的API,底层存储方式,系统架构都进行了全面的重新设计已解决上一代registry中存在的问题,2016年4月份registry 2.0正式发布,docker 1.6版本开始支持registry 2.0,而八月份随着docker 1.8 发布,docker hub正式启用2.1版本registry全面替代之前版本 registry,新版registry对镜像存储格式进行了重新设计并和旧版不兼容,docker 1.5和之前的版本无法读取2.0的镜像,另外,Registry 2.4版本之后支持了回收站机制,也就是可以删除镜像了,在2.4版本之前是无法支持删除镜像的,所以如果你要使用最好是大于Registry 2.4版本的

官方文档地址:https://docs.docker.com/registry/

官方 github 地址:https://github.com/docker/distribution

官方部署文档:https://github.com/docker/docker.github.io/blob/master/registry/deploying.md

6.3.2 环境规划

以下介绍通过官方提供的docker registry 镜像来简单搭建本地私有仓库环境

环境: 三台主机

宿主机IP地址服务
registry10.0.0.100docker registry 仓库
client110.0.0.200docker客户端
client210.0.0.201docker客户端

6.3.3 下载 docker registry 镜像

#下载registry镜像
[root@registry ~ ]# docker pull registry:2.7.1

#查看
[root@registry ~ ]# docker images registry:2.7.1
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
registry            2.7.1               b2cb11db9d3d        2 days ago          26.2MB

6.3.4 创建授权的registry用户和密码

创建registry用户,用于上传和下载镜像

#创建授权用户密码使用目录
[root@registry ~ ]# mkdir /etc/docker/auth

#创建授权的registry用户和密码
--ubuntu
[root@registry ~ ]# apt install -y apache2
--centos
[root@registry ~]# yum install httpd-tools -y
[root@registry ~]# htpasswd -Bbn test "123456" > /etc/docker/auth/registry
    -b 命令行中一并输入用户名和密码而不是根据提示输入密码,可以看见明文,不需要交互
    -n 不更新passwordfile,只将加密后的用户名密码显示在屏幕上
    -B 强制对密码进行bcrypt加密(非常安全)

[root@registry ~]# cat /etc/docker/auth/registry
test:$2y$05$sFJ0i5HExl9TfFI0Z4ZuFOq6DyskNSIggSv3JeRb2riXQQBS5.s1

6.3.5 启动docker registry 仓库容器

#启动运行docker registry仓库容器
docker run -d -p 5000:5000 --restart=always --name registry -v /etc/docker/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/registry registry:2.7.1

#REGISTRY_AUTH=htpasswd	指定认证用户密码加密格式
#REGISTRY_AUTH_HTPASSWD_PATH=/auth/registry	指定认证用户文件,默认以/auth/htpasswd文件中docker认证用户

[root@registry ~ ]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
1633d10918e9        registry:2.7.1      "/entrypoint.sh /etc…"   5 seconds ago       Up 3 seconds        0.0.0.0:5000->5000/tcp   registry

[root@registry ~ ]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      1064/systemd-resolv
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1373/sshd
tcp6       0      0 :::22                   :::*                    LISTEN      1373/sshd
tcp6       0      0 :::5000                 :::*                    LISTEN      4644/docker-proxy

6.3.6 登录仓库

客户端直接登录报错

[root@client1 ~ ]# docker login 10.0.0.100:5000
Username: test
Password:
Error response from daemon: Get https://10.0.0.100:5000/v2/: http: server gave HTTP response to HTTPS client

运行的registry仓库容器自带是有 http服务,docker login登录以 https协议登录,我们需要docker服务配置指定 http协议的仓库地址

#方法一: 修改docker服务启动service文件
[root@client1 ~ ]# vim /lib/systemd/system/docker.service
[Service]
#下面一行最后添加 --insecure-registry <仓库宿主机地址:端口> 
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 10.0.0.100:5000

#方法二:修改docker配置文件
[root@client1 ~ ]# vim /etc/docker/daemon.json
{
        "registry-mirrors": ["https://n0g7070z.mirror.aliyuncs.com"],
		"insecure-registries": ["10.0.0.100:5000"]
}

#重启docker服务
[root@client1 ~ ]# systemctl daemon-reload
[root@client1 ~ ]# systemctl restart docker.socket

#再次尝试登录仓库
[root@client1 ~ ]# docker login 10.0.0.100:5000
Username: test
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@client1 ~ ]# cat .docker/config.json
{
	"auths": {
		"10.0.0.100:5000": {
			"auth": "eHVhbjoxMjM0NTY="
		}
	},
	"HttpHeaders": {
		"User-Agent": "Docker-Client/19.03.15 (linux)"
	}
}

6.3.6 客户端打标签并上传镜像

搭建私有仓库上传镜像标签格式

<仓库IP:port>/<项目或者用户>/<镜像标签>:<镜像版本>

范例:打标签上传镜像

#添加仓库并登录
[root@client1 ~]#vim  /etc/docker/daemon.json
{
"registry-mirrors":["https://rsbud4vc.mirror.aliyuncs.com","https://registry.dockercn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hubmirror.c.163.com","http://qtid6917.mirror.aliyuncs.com","https://rncxm540.mirror.aliyuncs.com","https://e9yneuy4.mirror.aliyuncs.com"],
"insecure-registries": ["10.0.0.100:5000"]
} 

[root@client1 ~]#systemctl restart docker
[root@client1 ~]#docker login 10.0.0.100:5000
Username: test
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

#准备镜像,可以是官方拉取镜像,也可以dockerfile创建的镜像
[root@client1 ~ ]# docker pull alpine:3.11
[root@client1 ~ ]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine              3.11                d2bcc698e2fc        2 days ago          5.62MB

#给镜像打标签
[root@client1 ~ ]# docker tag alpine:3.11 10.0.0.100:5000/test/alpine:v3.11
[root@client1 ~ ]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
10.0.0.100:5000/test/alpine   v3.11               d2bcc698e2fc        2 days ago          5.62MB
alpine                        3.11                d2bcc698e2fc        2 days ago          5.62MB

#上传镜像
[root@client1 ~ ]# docker push 10.0.0.100:5000/test/alpine:v3.11
The push refers to repository [10.0.0.100:5000/test/alpine]
39982b2a789a: Pushed
v3.11: digest: sha256:c3d45491770c51da4ef58318e3714da686bc7165338b7ab5ac758e75c7455efb size: 528

image-20240216160025244

6.3.7 下载镜像并启动容器

client2 10.0.0.201下载私有仓库中镜像到本地运行容器

#第一步:修改docker配置,指定仓库地址
[root@client2 ~ ]# cat /etc/docker/daemon.json
{
	"insecure-registries": ["10.0.0.100:5000"]
}
[root@client2 ~ ]# systemctl daemon-reload
[root@client2 ~ ]# systemctl restart docker

#第二步:登录registry仓库服务器,不登录私有仓库服务无法拉取进行
[root@client2 ~ ]# docker pull 10.0.0.100:5000/test/alpine:v3.11
Error response from daemon: Get http://10.0.0.100:5000/v2/test/alpine/manifests/v3.11: no basic auth credentials

[root@client2 ~ ]# docker login 10.0.0.100:5000
Username: test
Password:
Login Succeeded

#第三步:拉取镜像
[root@client2 ~ ]# docker pull 10.0.0.100:5000/test/alpine:v3.11
v3.11: Pulling from test/alpine
6a428f9f83b0: Pull complete
Digest: sha256:c3d45491770c51da4ef58318e3714da686bc7165338b7ab5ac758e75c7455efb
Status: Downloaded newer image for 10.0.0.100:5000/test/alpine:v3.11
10.0.0.100:5000/test/alpine:v3.11
[root@client2 ~ ]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
10.0.0.100:5000/test/alpine   v3.11               d2bcc698e2fc        2 days ago          5.62MB

#第四步:运行容器
[root@client2 ~ ]# docker run -it 10.0.0.100:5000/test/alpine:v3.11 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

6.3.8 查看registry仓库镜像列表

以方便观察到结果,再向registry仓库上传镜像

#拉取不同版本的busybox镜像
[root@registry ~ ]# docker pull busybox:1.34.0
[root@registry ~ ]# docker pull busybox:1.33.1

#上传到registry仓库
[root@registry ~ ]# docker tag busybox:1.34.0 10.0.0.100:5000/test/busybox:1.34.0
[root@registry ~ ]# docker push 10.0.0.100:5000/test/busybox:1.34.0

[root@registry ~ ]# docker tag busybox:1.33.1 10.0.0.100:5000/test/busybox:1.33.1
[root@registry ~ ]# docker push 10.0.0.100:5000/test/busybox:1.33.1

查看registry仓库镜像列表

#以GET方法请求  http://<认证用户>:<密码>@<仓库地址>:<端口>/v2/_catalog
[root@client2 ~ ]# curl -XGET http://test:123456@10.0.0.100:5000/v2/_catalog
{"repositories":["test/alpine","test/busybox"]}		#访问结果显示仓库中存在俩个镜像

查看具体镜像的版本信息

#格式
curl -XGET http://test:123456@10.0.0.100:5000/v2/<镜像标签>/tags/list

#registry仓库中的alpine版本信息
[root@client2 ~ ]# curl -XGET http://test:123456@10.0.0.100:5000/v2/test/alpine/tags/list
{"name":"test/alpine","tags":["v3.11"]}

#registry仓库中的busxboy版本信息
[root@client2 ~ ]# curl -XGET http://test:123456@10.0.0.100:5000/v2/test/busybox/tags/list
{"name":"test/busybox","tags":["1.34.0","1.33.1"]}

6.4 分布式仓库 Harbor

image-20240216160039264

6.4.1 Harbor介绍

Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,由vmware开源,其通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源Docker Distribution。作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。Harbor支持安装在多个Registry节点的镜像资源复制,镜像全部保存在私有Registry中, 确保数据和知识产权在公司内部网络中管控,另外,Harbor也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等

vmware官方开源服务:https://vmware.github.io/

harbor 官方github 地址:https://github.com/vmware/harbor

harbor 官方网址:https://goharbor.io/

harbor官方文档:https://goharbor.io/docs/

6.4.2 Harbor功能

  • 基于角色的访问控制:用户与Docker镜像仓库通过“项目”进行组织管理,一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限
  • 镜像复制:镜像可在多个Registry实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景
  • 图形化用户界面:用户可以通过浏览器来浏览,检索当前Docker镜像仓库,管理项目和命名空间
  • AD/LDAP 支:Harbor可以集成企业内部已有的AD/LDAP,用于鉴权认证管理
  • 审计管理:所有针对镜像仓库的操作都可以被记录追溯,用于审计管理
  • 国际化:已拥有英文、中文、德文、日文和俄文的本地化版本。更多的语言将会添加进来
  • RESTful API:提供给管理员对于Harbor更多的操控, 使得与其它管理软件集成变得更容易
  • 部署简单:提供在线和离线两种安装工具, 也可以安装到vSphere平台(OVA方式)虚拟设备

6.4.3 Harbor架构

image-20240216160050131

  • Proxy:对应启动组件nginx。它是一个nginx反向代理,代理Notary client(镜像认证)、Docker client(镜像上传下载等)和浏览器的访问请求(Core Service)给后端的各服务
  • UI(Core Service):对应启动组件harbor-ui。底层数据存储使用mysql数据库,主要提供了四个子功能:
    • UI:一个web管理页面ui
    • API:Harbor暴露的API服务
    • Auth:用户认证服务,decode后的token中的用户信息在这里进行认证;auth后端可以接db、ldap、uaa三种认证实现
    • Token服务(上图中未体现):负责根据用户在每个project中的role来为每一个docker push/pull命令issuing一个token,如果从docker client发送给registry的请求没有带token,registry会重定向请求到token服务创建token
  • Registry:对应启动组件registry。负责存储镜像文件,和处理镜像的pull/push命令。Harbor对镜像进行强制的访问控制,Registry会将客户端的每个pull、push请求转发到token服务来获取有效的token
  • Admin Service:对应启动组件harbor-adminserver。是系统的配置管理中心附带检查存储用量,ui和jobserver启动时候需要加载adminserver的配置
  • replication Job Sevice:对应启动组件harbor-jobservice。负责镜像复制工作的,他和registry通信,从一个registry pull镜像然后push到另一个registry,并记录job_log
  • Log Collector:对应启动组件harbor-log。日志汇总组件,通过docker的log-driver把日志汇总到一起
  • DB:对应启动组件harbor-db,负责存储project、 user、 role、replication、image_scan、access等的metadata数据

6.4.4 安装Harbor

下载地址:https://github.com/vmware/harbor/releases

安装文档:https://github.com/vmware/harbor/blob/master/docs/installation_guide.md

6.4.4.1 安装docker compose

安装部署Harbor需要通过docker官方提供的编排工具,docker compose 必须先于harbor安装

方法一:通过过 pip3安装,版本较新 docker_compose版本,推荐使用

apt -y install python3-pip
pip3 install --upgrade pip
pip3 install --upgrade -i  https://pypi.tuna.tsinghua.edu.cn/simple/ setuptools_rust
pip3 install -i  https://pypi.tuna.tsinghua.edu.cn/simple/ docker-compose

[root@harbor ~ ]# docker-compose version
docker-compose version 1.29.2, build unknown
docker-py version: 5.0.2
CPython version: 3.6.9
OpenSSL version: OpenSSL 1.1.1  11 Sep 2018

方法二:直接从github下载安装对应版本

#下载地址:https://github.com/docker/compose/releases
curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64  -o /usr/bin/docker-compose
chmod +x /usr/bin/docker-compose

方法三:直接安装,版本较旧,不推荐使用

[root@ubuntu1804 ~ ]# apt -y install docker-compose
[root@ubuntu1804 ~ ]# docker-compose version
docker-compose version 1.17.1, build unknown
docker-py version: 2.5.1
CPython version: 2.7.17
OpenSSL version: OpenSSL 1.1.1  11 Sep 2018

6.4.4.2 下载Harbor安装包并解压缩

下载Harbor地址:https://github.com/goharbor/harbor/tags

Harbor安装包分为俩种

  • 离线安装包:harbor-offline-installer-<version>.tgz
  • 在线安装包:harbor-online-installer-<version>.tgz

使用 harbor 稳定版本1.7.8 离线完整安装包

wget https://ghproxy.com/https://github.com/goharbor/harbor/releases/download/v1.7.8/harbor-offline-installer-v1.7.8.tgz

#解压缩离线包
mkdir /app
tar xf harbor-offline-installer-v1.7.8.tgz -C /app/

6.4.4.3 编辑Harbor配置文件 harbor.cfg

最新文档: https://github.com/goharbor/harbor/blob/master/docs/install-config/configure-yml-file.md

[root@harbor ~ ]# vim /app/harbor/harbor.cfg
#修改下面俩行信息
hostname = 10.0.0.100		 		#修改此行,指向harbor宿主机IP 或 FQDN
harbor_admin_password = 123456		#修改此行指定harbor登录用户admin的密码,默认用户/密码:admin/Harbor12345

#HTTPS安全协议配置项
ui_url_protocol = http 				#默认即可,如果修改为https,需要指定下面证书路径
ssl_cert = /data/cert/server.crt 	#默认即可,https时,需指定下面证书文件路径
ss_cert_key = /data/cert/server.key #默认即可,https时,需指定下面私钥文件路径

6.4.4.4 安装Harbor

安装harbor注意点

  • harbor提供web界面映射宿主机的80端口,宿主机上不能占用80端口
  • 删除之前启动的registry
#安装python环境,harbor-v1.7.8 较低版本需要安装python2环境
apt install -y python

#执行harbor安装脚本
[root@harbor ~ ]# /app/harbor/install.sh
[Step 0]: checking installation environment ...
Note: docker version: 19.03.15
Note: docker-compose version: 1.29.2

[Step 1]: loading Harbor images ...
Loaded image: goharbor/harbor-adminserver:v1.7.8
Loaded image: goharbor/harbor-jobservice:v1.7.8
Loaded image: goharbor/harbor-registryctl:v1.7.8
.................

[Step 2]: preparing environment ...
Clearing the configuration file: ./common/config/adminserver/env
Clearing the configuration file: ./common/config/core/env
................
The configuration files are ready, please use docker-compose to start the service.

[Step 3]: checking existing instance of Harbor ...

[Step 4]: starting Harbor ...
Creating harbor-log ... done
Creating redis              ... done
Creating harbor-db          ... done
Creating registryctl        ... done
Creating harbor-adminserver ... done
Creating registry           ... done
Creating harbor-core        ... done
Creating harbor-portal      ... done
Creating harbor-jobservice  ... done
Creating nginx              ... done

✔ ----Harbor has been installed and started successfully.----

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

安装harbor后会自动开启很多相关容器

image-20240216160105612

  • Proxy: 对应启动组件nginx。它是一个nginx反向代理,代理Notary client(镜像认证)、Docker client(镜像上传下载等)和浏览器的访问请求(Core Service)给后端的各服务

  • UI(Core Service): 对应启动组件harbor-ui。底层数据存储使用mysql数据库,主要提供了四个 子功能:

    • UI: 一个web管理页面ui
    • API: Harbor暴露的API服务
    • Auth: 用户认证服务,decode后的token中的用户信息在这里进行认证;auth后端可以接db、ldap、uaa三种认证实现
    • Token服务(上图中未体现): 负责根据用户在每个project中的role来为每一个docker push/pull命令发布一个token,如果从docker client发送给registry的请求没有带token,registry会重定向请求到token服务创建token
  • Registry: 对应启动组件registry。负责存储镜像文件,和处理镜像的pull/push命令。Harbor对镜像进行强制的访问控制,Registry会将客户端的每个pull、push请求转发到token服务来获取有效的token

  • Admin Service: 对应启动组件harbor-adminserver。是系统的配置管理中心附带检查存储用量,ui和jobserver启动时候需要加载adminserver的配置

  • Job Sevice: 对应启动组件harbor-jobservice。负责镜像复制工作的,他和registry通信,从一个registry pull镜像然后push到另一个registry,并记录job_log

  • Log Collector: 对应启动组件harbor-log。日志汇总组件,通过docker的log-driver把日志汇总到一起

  • DB: 对应启动组件harbor-db,负责存储project、 user、 role、replication、image_scan、access等的metadata数据

6.4.5 登录 harbor 主机网站

用浏览器访问: http://10.0.0.101

  • 用户名: admin
  • 密码: 即前面harbor.cfg中指定的密码 123456

image-20240216160114224

6.4.6 管理harbor容器

harbor利用 docker-compose编排工具启动管理 harbor相关容器,并且 docker-compose脚本设置了容器自动启动 --restart=always

停止 harbor仓库容器,将删除容器

[root@harbor ~ ]# docker-compose -f /app/harbor/docker-compose.yml down
Stopping nginx              ... done
Stopping harbor-jobservice  ... done
Stopping harbor-portal      ... done
Stopping harbor-core        ... done
Stopping harbor-adminserver ... done
Stopping registryctl        ... done
Stopping harbor-db          ... done
Stopping registry           ... done
Stopping redis              ... done
Stopping harbor-log         ... done
Removing nginx              ... done
Removing harbor-jobservice  ... done
Removing harbor-portal      ... done
Removing harbor-core        ... done
Removing harbor-adminserver ... done
Removing registryctl        ... done
Removing harbor-db          ... done
Removing registry           ... done
Removing redis              ... done
Removing harbor-log         ... done
Removing network harbor_harbor

启动 harbor仓库容器,默认是前台指定

[root@harbor ~ ]# docker-compose -f /app/harbor/docker-compose.yml up -d
Starting harbor-log ... done
Starting redis              ... done
Starting harbor-adminserver ... done
Starting harbor-db          ... done
Starting registryctl        ... done
Starting registry           ... done
Starting harbor-core        ... done
Starting harbor-jobservice  ... done
Starting harbor-portal      ... done
Starting nginx              ... done

6.4.7 利用service文件实现管理harbor容器

[root@harbor ~ ]# vim /lib/systemd/system/harbor.service
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f /app/harbor/docker-compose.yml up -d
ExecStop=/usr/bin/docker-compose -f /app/harbor/docker-compose.yml down -d
[Install]
WantedBy=multi-user.target

#启动harbor容器
systemctl daemon-reload
systemctl start harbor

#停止删除harbor容器
systemctl stop harbor

6.4.8 安装Harbor v2.3

#安装docker-compose
curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64  -o /usr/bin/docker-compose
chmod +x /usr/bin/docker-compose

#下载harbor软件包
wget https://ghproxy.com/https://github.com/goharbor/harbor/releases/download/v2.3.2/harbor-offline-installer-v2.3.2.tgz
mkdir /app
tar xf harbor-offline-installer-v2.3.2.tgz -C /app/

#编辑Harbor配置文件 harbor.cfg
mv /app/harbor/harbor.yml.tmpl /app/harbor/harbor.yml
vim /app/harbor/harbor.yml
#设置harbor宿主机IP地址
hostname: 10.0.0.100
#没有https证书需要注释下面几行
#https:
  #port: 443
  #certificate: /your/certificate/path
  #private_key: /your/private/key/path
#harbor管理员admin密码
harbor_admin_password: 123456

#安装harbor
apt install -y python3
/app/harbor/install.sh

image-20240216160126832

6.4.5 管理harbor

6.4.5.1 创建harbor项目

harbor上必须先建立项目,才能上传镜像

  • 公开项目:表示不需要 docker login登录harbor仓库既可下载镜像
  • 私有项目:需要登录harbor仓库

image-20240216160143609

6.4.5.2 创建harbor用户管理项目

创建harbor用户

image-20240216160159240

设置harbor用户管理项目

image-20240216160207537

6.4.5.3 命令行登录 harbor

#修改docker配置文件指向harbor仓库地址
[root@ubuntu1804 ~ ]# vim /etc/docker/daemon.json
{
        "registry-mirrors": ["https://n0g7070z.mirror.aliyuncs.com"],
        "insecure-registries": ["10.0.0.100"]
}
[root@ubuntu1804 ~ ]# systemctl restart docker

#登录harbor
[root@ubuntu1804 ~ ]# docker login 10.0.0.100 -u 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

[root@ubuntu1804 ~ ]# cat .docker/config.json
{
	"auths": {
		"10.0.0.100": {
			"auth": "YWRtaW46MTIzNDU2"
		}
	},
	"HttpHeaders": {
		"User-Agent": "Docker-Client/19.03.15 (linux)"
	}
}

6.4.5.4 向harbor仓库上传镜像

准备上传镜像

[root@ubuntu1804 ~ ]# docker pull alpine:3.11
[root@ubuntu1804 ~ ]# docker pull busybox:1.33.1
[root@ubuntu1804 ~ ]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine              3.11                d2bcc698e2fc        3 days ago          5.62MB
busybox             1.33.1              42b97d3c2ae9        2 weeks ago         1.24MB

alpine:3.11镜像打上标签,上传到harbor仓库的 test公开项目中

[root@ubuntu1804 ~ ]# docker tag alpine:3.11 10.0.0.100/test/alpine:v3.11
[root@ubuntu1804 ~ ]# docker push 10.0.0.100/test/alpine:v3.11
The push refers to repository [10.0.0.100/test/alpine]
39982b2a789a: Pushed
v3.11: digest: sha256:c3d45491770c51da4ef58318e3714da686bc7165338b7ab5ac758e75c7455efb size: 528

busybox:1.33.1镜像打上标签,上传到harbor仓库的 linux私有项目中

[root@ubuntu1804 ~ ]# docker tag busybox:1.33.1 10.0.0.100/test/busybox:v1.33.1
[root@ubuntu1804 ~ ]# docker push 10.0.0.100/test/busybox:v1.33.1
The push refers to repository [10.0.0.100/linux/busybox]
0fd05bf2930d: Pushed
v1.33.1: digest: sha256:b862520da7361ea093806d292ce355188ae83f21e8e3b2a3ce4dbdba0a230f83 size: 527

image-20240216160221352

6.4.5.5 下载harbor的镜像

修改docker配置文件指向harbor仓库地址

[root@client ~ ]# vim /etc/docker/daemon.json
{
        "registry-mirrors": ["https://n0g7070z.mirror.aliyuncs.com"],
        "insecure-registries": ["10.0.0.100"]
}
[root@client ~ ]# systemctl restart docker

下载 harbor公开镜像仓库不需要 docker login登录

[root@client ~ ]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
[root@client ~ ]# docker pull 10.0.0.100/test/alpine:v3.11
v3.11: Pulling from test/alpine
6a428f9f83b0: Pull complete
Digest: sha256:c3d45491770c51da4ef58318e3714da686bc7165338b7ab5ac758e75c7455efb
Status: Downloaded newer image for 10.0.0.100/test/alpine:v3.11
10.0.0.100/test/alpine:v3.11

[root@client ~ ]# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
10.0.0.100/test/alpine   v3.11               d2bcc698e2fc        3 days ago          5.62MB

下载私有镜像仓库需要 docker login登录

#无法直接下载私有仓库镜像
[root@client ~ ]# docker pull 10.0.0.100/linux/busybox:v1.33.1
Error response from daemon: pull access denied for 10.0.0.100/linux/busybox, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

#登录harbor仓库
[root@client ~ ]# docker login 10.0.0.100 -u test
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@client ~ ]# docker pull 10.0.0.100/linux/busybox:v1.33.1
v1.33.1: Pulling from linux/busybox
8ec32b265e94: Pull complete
Digest: sha256:b862520da7361ea093806d292ce355188ae83f21e8e3b2a3ce4dbdba0a230f83
Status: Downloaded newer image for 10.0.0.100/linux/busybox:v1.33.1
10.0.0.100/linux/busybox:v1.33.1

6.4.6 harbor 高可用

Harbor支持基于策略的Docker镜像复制功能,这类似于MySQL的主从同步,其可以实现不同的数据中心、不同的运行环境之间同步镜像,并提供友好的管理界面,大大简化了实际运维中的镜像管理工作,已经有用很多互联网公司使用harbor搭建内网docker仓库的案例,并且还有实现了双向复制功能

image-20240216160232768

6.4.6.1 搭建规划

harbor宿主机宿主机IP地址docker版本harbor
node110.0.0.100docker-ce-19.03.15
node210.0.0.200docker-ce-19.03.15

6.4.6.2 node1节点创建仓库管理目标

创建仓库管理目标是指把本机项目仓库复制到哪个其他harbor上

image-20240216160242565

image-20240216160249639

image-20240216160256590

6.4.6.3 node1节点创建复制规则

创建复制规则:指定本地harbor项目中哪些镜像允许复制到目标harbor,本地多个项目仓库需要复制,每个项目仓库创建复制规则即可

image-20240216160304985

image-20240216160316463

6.4.6.4 查看node2节点复制镜像情况

image-20240216160323826

6.4.6.5 node2节点创建复制规则,实现双主复制

image-20240216160333203

image-20240216160339967

6.4.6.6 上传镜像观察是否可以双高同步

[root@harbor ~ ]# docker login 10.0.0.200
[root@harbor ~ ]# docker tag nginx:1.21.1-alpine 10.0.0.200/test/nginx:v1.21.1-alpine
[root@harbor ~ ]# docker push 10.0.0.200/test/nginx:v1.21.1-alpine

查看10.0.0.200节点仓库镜像列表

image-20240216160348593

查看10.0.0.100节点仓库镜像列表

image-20240216160357944

6.4.7 harbor 安全 https 配置

6.4.7.1 配置 https

第一步:创建CA证书

[root@harbor ~ ]# mkdir /app/harbor/certs
[root@harbor ~ ]# cd /app/harbor/certs
[root@harbor /app/harbor/certs ]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -subj "/CN=ca.xiaotestzi.org" -days 365 -out ca.crt

[root@harbor /app/harbor/certs ]# ll
-rw-r--r-- 1 root root 1830 Sep  5 02:01 ca.crt
-rw------- 1 root root 3272 Sep  5 02:01 ca.key

第二步:生成harbor主机的证书申请

openssl req -newkey rsa:4096 -nodes -sha256 -subj "/CN=harbor.xiaotestzi.org" -keyout harbor.xiaotestzi.org.key -out harbor.xiaotestzi.org.csr

[root@harbor /app/harbor/certs ]# ll
-rw-r--r-- 1 root root 1830 Sep  5 02:01 ca.crt
-rw------- 1 root root 3272 Sep  5 02:01 ca.key
-rw-r--r-- 1 root root 1602 Sep  5 02:03 harbor.xiaotestzi.org.csr
-rw------- 1 root root 3272 Sep  5 02:03 harbor.xiaotestzi.org.key

第三步:CA给harbor主机颁发证书

openssl x509 -req -in harbor.xiaotestzi.org.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out harbor.xiaotestzi.org.crt

[root@harbor /app/harbor/certs ]# ll
-rw-r--r-- 1 root root 1830 Sep  5 02:01 ca.crt
-rw------- 1 root root 3272 Sep  5 02:01 ca.key
-rw-r--r-- 1 root root   41 Sep  5 02:05 ca.srl
-rw-r--r-- 1 root root 1712 Sep  5 02:05 harbor.xiaotestzi.org.crt
-rw-r--r-- 1 root root 1602 Sep  5 02:03 harbor.xiaotestzi.org.csr
-rw------- 1 root root 3272 Sep  5 02:03 harbor.xiaotestzi.org.key

第四步:harbor配置https 安全协议

[root@harbor ~ ]# vim /app/harbor/harbor.cfg
#修改harbor主机名必须申请证书填写域名一致
hostname = harbor.xiaotestzi.org
#修改为https协议
ui_url_protocol = https
ssl_cert = /app/harbor/certs/harbor.xiaotestzi.org.crt
ssl_cert_key = /app/harbor/certs/harbor.xiaotestzi.org.key

第五步:harbor配置生效

docker-compose -f /app/harbor/docker-compose.yml down
docker-compose -f /app/harbor/docker-compose.yml up -d

第五步:浏览器访问

在Windows的hosts做域名解析

# C:\Windows\System32\drivers\etc\hosts
10.0.0.100 harbor.xiaotestzi.org

image-20240216160411355

image-20240216160420609

6.4.7.2 客户端上传下载镜像

harbor配置https安全协议之后,客户端需要把harbor服务器的CA证书下载到客户端本地,否则直接登录和上传下载镜像会报错

[root@ubuntu1804 ~ ]# vim /etc/hosts
10.0.0.100 harbor.xiaotestzi.org

[root@ubuntu1804 ~ ]# docker login harbor.xiaotestzi.org
Username: admin
Password:
Error response from daemon: Get https://harbor.xiaotestzi.org/v2/: x509: certificate signed by unknown authority

客户端下载ca的证书

#注意目录结构:/etc/docker/certs.d/<harbor域名>
[root@ubuntu1804 ~ ]# mkdir -pv /etc/docker/certs.d/harbor.xiaotestzi.org/
[root@ubuntu1804 ~ ]# scp -r harbor.xiaotestzi.org:/app/harbor/certs/ca.crt /etc/docker/certs.d/harbor.xiaotestzi.org/ 
[root@ubuntu1804 ~ ]# ll /etc/docker/certs.d/harbor.xiaotestzi.org/
-rw-r--r-- 1 root root 1830 Sep  5 02:53 ca.crt

[root@ubuntu1804 ~ ]# docker login harbor.xiaotestzi.org
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

客户端上传镜像

[root@ubuntu1804 ~ ]# docker tag alpine:3.11 harbor.xiaotestzi.org/test/alpine:v2.0
[root@ubuntu1804 ~ ]# docker push harbor.xiaotestzi.org/test/alpine:v2.0
The push refers to repository [harbor.xiaotestzi.org/test/alpine]
39982b2a789a: Layer already exists
v2.0: digest: sha256:c3d45491770c51da4ef58318e3714da686bc7165338b7ab5ac758e75c7455efb size: 528