文章目录
1. Docker Registry
网上有很多的Registry服务器都支持第三方用户注册,而后基于用户名去做自己的仓库,但是使用互联网上的Registry有一个缺陷,那就是我们去推送和下载镜像时都不会很快,而在生产环境中很可能并行启动的容器将达到几十、上百个,而且很有可能每个服务器本地是没有镜像的,此时如果通过互联网去下载镜像会有很多问题,比如下载速度会很慢、带宽会用很多等等,如果带宽不够的话,下载至启动这个过程可能要持续个几十分钟,这已然违背了使用容器会更加轻量、快速的初衷和目的。因此,很多时候我们很有可能需要去做自己的私有Registry。
Registry用于保存docker镜像,包括镜像的层次结构和元数据。用户可以自建Registry,也可以使用官方的Docker Hub。
Docker Registry分类:
- Sponsor Registry:第三方的Registry,供客户和Docker社区使用
- Mirror Registry:第三方的Registry,只让客户使用
- Vendor Registry:由发布docker镜像的供应商提供的registry
- Private Registry:通过设有防火墙和额外的安全层的私有实体提供的registry
事实上,如果运维的系统环境托管在云计算服务上,比如阿里云,那么用阿里云的Registry则是最好的选择。很多时候我们的生产环境不会在本地,而是托管在数据中心机房里,如果我们在数据中心机房里的某台主机上部署Registry,因为都在同一机房,所以属于同一局域网,此时数据传输走内网,效率会极大的提升。
所有的Registry默认情况下都是基于https工作的,这是Docker的基本要求,而我自建Registry时很可能是基于http工作的,但是Docker默认是拒绝使用http提供Registry服务的,除非明确的告诉它,我们就是要用http协议的Registry。
2. Docker Private Registry
为了帮助我们快速创建私有Registry,Docker专门提供了一个名为Docker Distribution的软件包,我们可以通过安装这个软件包快速构建私有仓库。
问:既然Docker是为了运行程序的,Docker Distribution能否运行在容器中?
容器时代,任何程序都应该运行在容器中,除了Kernel和init。而为了能够做Docker Private Registry,Docker Hub官方直接把Registry做成了镜像,我们可以直接将其pull到本地并启动为容器即可快速实现私有Registry。
Registry的主要作用是托管镜像,Registry运行在容器中,而容器自己的文件系统是随着容器的生命周期终止和删除而被删除的,所以当我们把Registry运行在容器中时,客户端上传了很多镜像,随着Registry容器的终止并删除,所有镜像都将化为乌有,因此这些镜像应该放在存储卷上,而且这个存储卷最好不要放在Docker主机本地,而应该放在一个网络共享存储上,比如NFS。不过,镜像文件自己定义的存储卷,还是一个放在Docker本地、Docker管理的卷,我们可以手动的将其改成使用其它文件系统的存储卷。
这就是使用容器来运行Registry的一种简单方式。自建Registry的另一种方式,就是直接安装docker-distribution软件。
3. 使用docker-distribution自建Registry
在node02上自建Registry
[root@node02 ~]# yum -y install docker-distribution
[root@node02 ~]# vim /etc/docker-distribution/registry/config.yml
version: 0.1
log:
fields:
service: registry
storage:
cache:
layerinfo: inmemory
filesystem:
rootdirectory: /var/lib/registry # 修改此处为一个容量大的磁盘分区目录
http:
addr: :5000
[root@node02 ~]# systemctl start docker-distribution
[root@node02 ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 [::1]:25 [::]:*
LISTEN 0 128 [::]:5000 [::]:*
LISTEN 0 128 [::]:22 [::]:*
在node01上使用自建的Registry去上传镜像
# 使用insecure-registries参数添加http支持
[root@node01 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://j3m2itm3.mirror.aliyuncs.com","https://registry.docker-cn.com"],
"insecure-registries": ["node02-linux.example.com:5000"]
}
[root@node01 ~]# systemctl restart docker
[root@node01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
seancheng1002/b1 v0.2 42a777e26541 2 weeks ago 1.22MB
seancheng1002/b1 v0.1 bb54705dfd51 2 weeks ago 1.22MB
nginx latest 2073e0bcb60e 2 weeks ago 127MB
centos latest 470671670cac 5 weeks ago 237MB
busybox latest 6d5fcfe5ff17 8 weeks ago 1.22MB
[root@node01 ~]# docker tag nginx:latest node02-linux.example.com:5000/nginx:latest
[root@node01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
seancheng1002/b1 v0.2 42a777e26541 2 weeks ago 1.22MB
seancheng1002/b1 v0.1 bb54705dfd51 2 weeks ago 1.22MB
nginx latest 2073e0bcb60e 2 weeks ago 127MB
node02-linux.example.com:5000/nginx latest 2073e0bcb60e 2 weeks ago 127MB
centos latest 470671670cac 5 weeks ago 237MB
busybox latest 6d5fcfe5ff17 8 weeks ago 1.22MB
[root@node01 ~]# docker push node02-linux.example.com:5000/nginx
The push refers to repository [node02-linux.example.com:5000/nginx]
22439467ad99: Pushed
b4a29beac87c: Pushed
488dfecc21b1: Pushed
latest: digest: sha256:62f787b94e5faddb79f96c84ac0877aaf28fb325bfc3601b9c0934d4c107ba94 size: 948
3. 自己上传的镜像自己可以下载下来使用
- 先创建一个镜像仓库
2. 给镜像改个名字,名字必须跟docker官网个人账户的名字一样
[root@localhost ~]# docker images
test v0.9 98b6e064cbe6 3 days ago 66.5MB
[root@localhost ~]# docker tag test:v0.9 maqiang988198/httpd:latest
[root@localhost ~]# docker images
maqiang988198/httpd latest 98b6e064cbe6 3 days ago 66.5MB
3. 把镜像上传到仓库
先认证
[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: maqiang988198
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@localhost ~]# docker push maqiang988198/httpd:latest
The push refers to repository [docker.io/maqiang988198/httpd]
14907bf10593: Pushed
69b779902764: Pushed
777b2c648970: Mounted from library/alpine
latest: digest: sha256:0d2b63101dd6616440d29585da79199d1e4b73f2a5006d995cba78a52721acaa size: 947
- 此时可以查看镜像已被上传上去
- 此时可以将上传的镜像拉下来
[root@localhost ~]# docker pull maqiang988198/httpd
Using default tag: latest
latest: Pulling from maqiang988198/httpd
Digest: sha256:0d2b63101dd6616440d29585da79199d1e4b73f2a5006d995cba78a52721acaa
Status: Downloaded newer image for maqiang988198/httpd:latest
docker.io/maqiang988198/httpd:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx 3.0 0fa51e8ac169 10 minutes ago 8.77MB
maqiang988198/httpd latest 0fa51e8ac169 10 minutes ago 8.77MB
nginx maqiang abbf49ab220b 15 minutes ago 8.77MB
httpd v0.1 def105017b12 12 days ago 1.24MB
busybox latest a77dce18d0ec 2 weeks ago 1.24MB
alpine latest 389fef711851 4 weeks ago 5.58MB
httpd latest dd85cdbb9987 5 weeks ago 138MB
centos latest 300e315adb2f 5 weeks ago 209MB
- 使用该镜像运行容器
[root@localhost ~]# docker run -d --name web maqiang988198/httpd:latest
222a2247084d572f653eac8cdc29dbf7917d6b3442365e2e45e9727817ab28f8
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
222a2247084d maqiang988198/httpd:latest "nginx" 8 seconds ago Up 7 seconds web
4. 使用官方镜像自建Registry
1. 拉镜像
[root@localhost ~]# docker run -d -p 5000:5000 --restart=always registry always是重启服务后使容器继续运行
85796ced94b192d2a1d7d0746585b4d41fd473296f3a8bbf3fcb5415b199c3d4
2. 此时会出现一个5000d端口
[root@localhost ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 0.0.0.0:5000 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
容器正在运行
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
531d47eec7df registry "/entrypoint.sh /etc…" 23 seconds ago Up 21 seconds 0.0.0.0:5000->5000/tcp nervous_hamilton
3. 修改配置文件
[root@localhost ~]# vim /etc/docker/daemon.json
{
"bip":"192.168.100.1/24",
"dns":["114.114.114.114","8.8.8.8"],
"registry-mirrors": ["https://registry.docker-cn.com","https://11vuihex.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.50.154:5000"] 添加此行
}
刷新配置文件并重启服务
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
更改镜像名字
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
maqiang988198/httpd latest 0fa51e8ac169 22 minutes ago 8.77MB
更改
[root@localhost ~]# docker tag maqiang988198/httpd:latest 192.168.50.154:5000/httpd:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.50.154:5000/httpd latest 0fa51e8ac169 23 minutes ago 8.77MB
4. 因为刚才我们已经登陆进去了,传不进去,现在需要登出
[root@localhost ~]# docker logout
Removing login credentials for https://index.docker.io/v1/
5. 上传
[root@localhost ~]# docker push 192.168.50.154:5000/httpd:latest
The push refers to repository [192.168.50.154:5000/httpd]
14907bf10593: Pushed
69b779902764: Pushed
777b2c648970: Pushed
latest: digest: sha256:0d2b63101dd6616440d29585da79199d1e4b73f2a5006d995cba78a52721acaa size: 947
5. Harbor
无论是使用Docker-distribution去自建仓库,还是通过官方镜像跑容器的方式去自建仓库,通过前面的演示我们可以发现其是非常的简陋的,还不如直接使用官方的Docker Hub去管理镜像来得方便,至少官方的Docker Hub能够通过web界面来管理镜像,还能在web界面执行搜索,还能基于Dockerfile利用Webhooks和Automated Builds实现自动构建镜像的功能,用户不需要在本地执行docker build,而是把所有build上下文的文件作为一个仓库推送到github上,让Docker Hub可以从github上去pull这些文件来完成自动构建。
但无论官方的Docker Hub有多强大,它毕竟是在国外,所以速度是最大的瓶颈,我们很多时候是不可能去考虑使用官方的仓库的,但是上面说的两种自建仓库方式又十分简陋,不便管理,所以后来就出现了一个被 CNCF 组织青睐的项目,其名为Harbor。
5.1 Harbor简介
Harbor是由VMWare在Docker Registry的基础之上进行了二次封装,加进去了很多额外程序,而且提供了一个非常漂亮的web界面。
Project Harbor is an open source trusted cloud native registry project that stores, signs, and scans context.
Harbor extends the open source Docker Distribution by adding the functionalities usually required by users such as security, identity and management.
Harbor supports advanced features such as user management, access control, activity monitoring, and replication between instances.
5.2 Harbor的功能
Feathers:
- Multi-tenant content signing and validation
- Security and vulnerability analysis
- Audit logging
- Identity integration and role-based access control
- Image replication between instances
- Extensible API and graphical UI
- Internationalization(currently English and Chinese)
5.3 Docker compose
Harbor在物理机上部署是非常难的,而为了简化Harbor的应用,Harbor官方直接把Harbor做成了在容器中运行的应用,而且这个容器在Harbor中依赖类似redis、mysql、pgsql等很多存储系统,所以它需要编排很多容器协同起来工作,因此VMWare Harbor在部署和使用时,需要借助于Docker的单机编排工具(Docker compose)来实现。
Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.
5.4 Harbor部署
安装
[root@localhost ~]# yum -y install python38
[root@localhost ~]# pip3 install docker-compose
[root@localhost ~]# which docker-compose
/usr/local/bin/docker-compose
下载包
[root@localhost ~]# ls
! mq
anaconda-ks.cfg nginx
harbor-offline-installer-v2.1.3.tgz
解压
[root@localhost ~]# tar xf harbor-offline-installer-v2.1.3.tgz -C /usr/local/
[root@localhost ~]# cd /usr/local/
[root@localhost local]# ls
bin games include lib64 sbin src
etc harbor lib libexec share
[root@localhost local]# cd harbor/
[root@localhost harbor]# ls
common.sh harbor.yml.tmpl LICENSE
harbor.v2.1.3.tar.gz install.sh prepare
修改配置文件
[root@localhost harbor]# vim harbor.yml.tmpl
......
hostname: 192.168.50.154 修改成主机Ip
......
#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
......
harbor_admin_password: Harbor12345 登陆密码
......
password: root123 数据库密码
执行脚本
[root@localhost harbor]# cp harbor.yml.tmpl harbor.yml 复制该文件
[root@localhost harbor]# ./install.sh
[root@localhost harbor]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:1514 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
- 此时能访问Harbor
- 登陆
- 启动、停止容器
停止容器,必须要有docker-compose.yml文件才能启动停止容器
[root@localhost harbor]# docker-compose stop
Stopping nginx ... done
Stopping harbor-jobservice ... done
Stopping harbor-core ... done
Stopping redis ... done
Stopping harbor-portal ... done
Stopping harbor-db ... done
Stopping registry ... done
Stopping registryctl ... done
Stopping harbor-log ... done
[root@localhost harbor]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
[root@localhost harbor]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
启动容器
[root@localhost ~]# cd /usr/local/harbor/
[root@localhost harbor]# docker-compose start
Starting log ... done
Starting registry ... done
Starting registryctl ... done
Starting postgresql ... done
Starting portal ... done
Starting redis ... done
Starting core ... done
Starting jobservice ... done
Starting proxy ... done
[root@localhost harbor]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:1514 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
使用Harbor的注意事项:
- 在客户端上传镜像时一定要记得执行docker login进行用户认证,否则无法直接push
- 在客户端使用的时候如果不是用的https则必须要在客户端的/etc/docker/daemon.json配置文件中配置insecure-registries参数
- 数据存放路径应在配置文件中配置到一个容量比较充足的共享存储中
- Harbor是使用docker-compose命令来管理的,如果需要停止Harbor也应用docker-compose stop来停止,其他参数请–help
[root@localhost ~]# cd /etc/docker/
[root@localhost docker]# ls
daemon.json key.json
[root@localhost docker]# vim daemon.json
{
"bip":"192.168.100.1/24",
"dns":["114.114.114.114","8.8.8.8"],
"registry-mirrors": ["https://registry.docker-cn.com","https://11vuihex.mirror.aliyuncs.com"],
"insecure-registries": ["http://192.168.50.154"] 添加此行
}
5.5 如何使用Harbor
5.5.1 上传
此时有这样一个镜像
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
maqiang988198/httpd latest 0fa51e8ac169 2 hours ago 8.77MB
1. 给这个镜像换个名字
[root@localhost ~]# docker tag maqiang988198/httpd:latest 192.168.50.154/web/httpd:latest
2. 登陆,需要先退出登陆,再进行登陆
[root@localhost ~]# docker logout
Removing login credentials for https://index.docker.io/v1/
3. 登陆
[root@localhost ~]# docker login 192.168.50.154
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
4. 推送镜像
[root@localhost ~]# docker push 192.168.50.154/web/httpd:latest
The push refers to repository [192.168.50.154/web/httpd]
14907bf10593: Pushed
69b779902764: Pushed
777b2c648970: Pushed
latest: digest: sha256:0d2b63101dd6616440d29585da79199d1e4b73f2a5006d995cba78a52721acaa size: 947
- 此时就能看到一个镜像
5.5.2 下载
[root@localhost ~]# docker pull 192.168.50.154/web/httpd
Using default tag: latest
latest: Pulling from web/httpd
Digest: sha256:0d2b63101dd6616440d29585da79199d1e4b73f2a5006d995cba78a52721acaa
Status: Downloaded newer image for 192.168.50.154/web/httpd:latest
192.168.50.154/web/httpd:latest
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.50.154/web/httpd latest 0fa51e8ac169 2 hours ago 8.77MB