(0)什么是仓库
Docker 仓库是用来存储镜像的位置,Docker提供一个注册服务器(Register)来保存多个仓库。每个仓库又可以包含多个具备不同tag(版本)的镜像,Docker运行中使用的默认仓库是 Docker Hub 公共仓库。我们可以从仓库(Repository)中下载镜像,而仓库又保存在Registry中,Docker Hub是Docker官方提供的Registry。即可以从Docker Hub的顶层仓库中免费获取官方提供的基于镜像,又可以将自已构建的镜像存放于Docker Hub的用户仓库中
(1)引入
## docker search nginx # 官方镜像和普通用户镜像的一个区别-->前缀
nginx Official build of Nginx. # 官方的没有前缀!
jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… # 第三方都有前缀
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable of…
(2)共有镜像仓库的构建
方式:网易蜂巢、Docker官方、网易云、阿里云
1)Docker官方
Docker官方维护的仓库,默认用户访问就是指向Docker的官方的仓库
# (0)注册
# 注意:用户名是一个任何的数字
# 登陆之后-->创建一个repo(仓库)-->可以给仓库一些描述-->create-->右上角有push的提示!
# (1)根据界面的提示修改-->tag为指定格式的-->镜像名字指定!
# 原因:docker hub为了区分不同用户的同名镜像,要求镜像的格式是:[username]/xxx.tag
docker tag nginx:v1 170510/nginx:v1
docker rmi nginx:v1
# (2)进行认证-->否则 deny
docker login # 不写地址,默认是Docker官方的帐号
# user和password
# 结果:创建/root/.docker目录,并生成config.json的认证信息(加密)!
docker push 170510/nginx:v1 # 过程特别慢!!!
说明:docker hub是docker公司维护的公共仓库,用户可以免费使用,也可以购买私有仓库。
docker hub虽然方便,但是有很多限制
1)需要internet连接,速度慢
2)所有人都可以访问
3)由于安全原因企业不允许将镜像放到外网
# 仓库删除------>Settings-->填写仓库的名称--->删除!
docker rmi 170510/busybox:v1 # 删除的是本地的镜像
# tag时-->镜像层是没有变化的!
2)阿里云加速器
# 阿里云加速器:阿里巴巴作为反向代理帮助我们加速(传输)!
# 登陆--->控制台--->容器镜像服务-->镜像加速器-->复制加速器地址
# vim /etc/docker/daemon.json -->根据版本(Centos)把相应的加速地址复制进去!
# 测试前提:把nginx(最新删除),再下载!-->以便能看到实验现象
# 测试:看下载速度以及nginx镜像的构建历史的版本(NGINX VERSION)!
原则:尽量使用仓库已有的镜像,不要重复的造轮子!
(3)搭建私有仓库
思考:为什么要搭建私有仓库
# 核心:安全原因,每个公司业务不一样(有可能涉及机密),不能把资源放在外网!
docker hub虽然方便,但是还是有限制
1)需要internet连接,速度慢-->网络原因
2)所有人都可以访问-->安全原因
3)由于安全原因企业不允许将镜像放到外网-->安全原因
1)节省网络带宽,针对于每个镜像不用每个人都去中央仓库上面去下载,只需要从私有仓库中下载即可;
2)提供镜像资源利用,针对于公司内部使用的镜像,推送到本地的私有仓库中,以供公司内部相关人员使用。
好消息:docker公司已经将registry开源,我们可以快速构建企业私有仓库!
(1)下载
docker pull registry # 官方拉取(阿里云加速)
docker history registry:latest # 查看构建过程
IMAGE CREATED CREATED BY SIZE COMMENT
f32a97de94e1 4 months ago /bin/sh -c #(nop) CMD ["/etc/docker/registr… 0B
<missing> 4 months ago /bin/sh -c #(nop) ENTRYPOINT ["/entrypoint.… 0B
<missing> 4 months ago /bin/sh -c #(nop) COPY file:507caa54f88c1f38… 155B
<missing> 4 months ago /bin/sh -c #(nop) EXPOSE 5000 0B
<missing> 4 months ago /bin/sh -c #(nop) VOLUME [/var/lib/registry] 0B
<missing> 4 months ago /bin/sh -c #(nop) COPY file:4544cc1555469403… 295B
<missing> 4 months ago /bin/sh -c #(nop) COPY file:21256ff7df5369f7… 20.1MB
<missing> 4 months ago /bin/sh -c set -ex && apk add --no-cache… 1.29MB
<missing> 4 months ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 4 months ago /bin/sh -c #(nop) ADD file:38bc6b51693b13d84… 4.41MB
docker run -d --name registry -p 5000:5000 registry
# 最好采用如下的方式-->不要默认的挂载点(方便查看数据)
# docker run -d --name registry -v /opt/registry:/var/lib/registry -p 5000:5000 registry
docker inspect registry # 看运行后的相关信息是否与构建的匹配
docker volume ls
关注
# VOLUME 和EXPOSE(5000) 信息
# volum ls -->信息
# "IPAddress": "172.17.0.2", -->如果是以此IP访问,默认是走TLS加密!
# 默认是桥接的方式,端口是5000,容器启动会有一个内网段!
# 测试:所以用本地访问
需求:默认上传到hub上,如何上传到自己本地仓库(5000)
docker tag busybox:v1 localhost:5000/busybox:v1 # IP+Port
# 修改:镜像的标签:IP:端口的形式!-->由于IP走TLS(加密),等网络部分再讲解!
docker push localhost:5000/busybox
curl localhost:5000/v2/_catalog #测试
# 信息默认是v2版本{"repositories":["busybox"]}
# 也可以通过mounts来查看!
生产环境
# 命令行操作不方便,可能手残,最好有个图形,并且没有加密(明文)和认证!
# 走域名或者IP地址,一定会走加密,安全!
查找官方文档,进行配置
https://docs.docker.com/ -->搜索registry-->Glossary -->Test an insecure registry
生产环境下:远程主机,必须走TLS加密,可以强行走非加密的方式,不安全
实验环境
docker1:registry
docker2:registry client
非加密的演示如下
# 做好密名解析或者DNS---> /etc/hosts172.25.2.21 docker1 wzj.com
[root@docker2 ~]# docker pull wzj.com:5000/busybox
Using default tag: latest
Error response from daemon: Get https://wzj.com:5000/v2/: http: server gave HTTP response to HTTPS client
# 默认是加密的,所以错误,必须告诉它(配置文件)走非加密的方式(不是localhost)!
注意
# client做的!
vim /etc/docker/daemon.json #自己私有仓库的域名-->IP
# 核心:IP+Port作为用户身份的标示进行上传和下载-->注意修改!
{
"insecure-registries" : ["wzj.com:5000"]
}
重新测试
systemctl daemon-reload # 必须重载
systemctl restart docker # 配置文件编写好,没有重启服务,是不会读取配置文件的!
##实验现象
[root@docker2 ~]# docker pull wzj.com:5000/busybox:v1
v1: Pulling from busybox
8e674ad76dce: Pull complete
Digest: sha256:7ce9ba44328870daa03770114e3fb701335223ce07be54cdf10d93a97f6585b7
Status: Downloaded newer image for wzj.com:5000/busybox:v1
[root@docker2 ~]#
使用自签名证书
mkdir -p certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/wzj.com.key -x509 -days 365 -out certs/wzj.com.crt
# 注意:修改成自己的域名-->证书和私钥!
# docs.docker.com(官方文档)-->registry(搜索)-->repository(点击-->一片空白之处)-->Test insecure
证书只是在此目录中,必须让仓库(registry)去读取它!
如何部署!
# 前提删除之前正在运行的registry容器
docker rm -f registry
[root@docker1 docker]# docker run -d \ # 后台
> --restart=always \ # 随着docker服务的启动而启动
> --name registry \ # 容器名字
> -v "$(pwd)"/certs:/certs \ # 挂载点的映射
> -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \ # -e就是编辑相关信息!
> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/wzj.com.crt \ # 修改成自己的
> -e REGISTRY_HTTP_TLS_KEY=/certs/wzj.com.key \ # 同上!
> -p 443:443 \ # 端口映射
> registry # 镜像的名字(默认是latest)
docker run -d --restart=always --name registry -v "$(pwd)"/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/wzj.com.crt -e REGISTRY_HTTP_TLS_KEY=/certs/wzj.com.key -p 443:443 registry:2
# 536f5153e498b5f0c11401a9f50b24f76b541fb7b0d743b267d93776b41fe3a6
#######查看443端口是否开启(很重要)-->如果没有开启说明参数配置错误!
[root@docker1 docker]# netstat -antlupe
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 20823 619/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 21727 872/master
tcp 0 0 172.25.2.21:22 172.25.2.250:35908 ESTABLISHED 0 24743 2187/sshd: root@pts
tcp6 0 0 :::22 :::* LISTEN 0 20832 619/sshd
tcp6 0 0 ::1:25 :::* LISTEN 0 21728 872/master
tcp6 0 0 :::443 :::* LISTEN 0 46665 5494/docker-proxy
Server端加密仓库构建完毕,此时Server端跑起来!
配置的machine
docker-machine create --driver generic --engine-install-url="http://172.25.2.250" --generic-ip-address=172.25.2.4 --engine-insecure-registry wzj.com server4
mkdir /etc/docker/certs.d/wzj.com -p # 创建目录!
cp wzj.com.crt /etc/docker/certs.d/wzj.com/ca.crt # 证书的命名要求的位置和格式
# 说明:默认时5000端口,可以不写
# myregistrydomain--->wzj.com
# 配置好后,不需要重启服务!
# 不同的操作系统配置不一样
# 注意:一定要做好解析!
测试1:server(docker1)自测上传
# 前提:修改tag名字(固定格式)-->
docker tag rhel7:v6 wzj.com/rhel7:v1
[root@docker1 wzj.com]# docker push wzj.com/rhel7:v1
The push refers to repository [wzj.com/rhel7]
303745186e43: Pushed
668afdbd4462: Pushed
v1: digest: sha256:a6ec56c9fc45895621c412775f066e89f1c68d9d54f179072e946f97a0e1f07e size: 739
测试2:server2(client)测试,是否能下载!
########未分发的情况#########
# 会说:未授权!
#######证书分发(加密)########
pwd --> /etc/docker
scp -r certs.d/ root@172.25.2.22:`pwd`
###############说明:拉取的是远程的的仓库######################
[root@docker2 docker]# docker pull wzj.com/rhel7:v1
v1: Pulling from rhel7
269521def953: Pull complete
d2a322ba952c: Pull complete
Digest: sha256:a6ec56c9fc45895621c412775f066e89f1c68d9d54f179072e946f97a0e1f07e
Status: Downloaded newer image for wzj.com/rhel7:v1
## 删除的是本地的仓库,无法删除远程仓库-->涉及(后续远程仓库镜像的删除)!
# certs.d key.json -->/etc/docker (文件)
说明:Docker客户端做TLS连接时,也必须得有证书,部署客户端的加密
###############################(
思考:为什么认证需要加密
原因:如果不加密,则是明文传输,被别人抓包获取,不安全!
(1)为Docker用户添加用户认证的功能
# (1)容器生成认证文件(由于只需要生成所需要的文件,生成后删除即可)
# 用户名 密码 -->basic auth -->注意如果是多个用户要>>来追加,不要覆盖了!
docker run --rm --entrypoint htpasswd registry -Bbn admin wzj110 > auth/htpasswd
# (2)加密+认证!
docker run -d \
--restart=always \
--name registry \
-v "$(pwd)"/auth:/auth \ # 挂载
-e "REGISTRY_AUTH=htpasswd" \ # 授权方式
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ # 固定格式
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ # 认证路径
-v "$(pwd)"/certs:/certs \ # 下面几条的加密!
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-p 443:443 \ # 如果不使用默认的500.必须加上(这两行)
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/wzj.com.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/wzj.com.key \
registry
# 说明:参考官方文档
补充:官方默认使用5000,如果是443,必须指定端口!
注意:一定要验证443端口是否开启!
本地测试
测试2:远程主机连接server(docker)的仓库
#(1)解析
172.25.2.21 docker1 wzj.com
#(2)加密证书-->ok
# 所有的docker客户端都必须放置证书,才能拉取!
#####################################
[root@docker2 docker]# docker login wzj.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
## vim /root/.docker/config.json认证信息!
[root@docker2 docker]# docker rmi wzj.com/busybox:v1
Untagged: wzj.com/busybox:v1
Untagged: wzj.com/busybox@sha256:bf510723d2cd2d4e3f5ce7e93bf1e52c8fd76831995ac3bd3f90ecc866643aff
Deleted: sha256:e4db68de4ff27c2adfea0c54bbb73a61a42f5b667c326de4d7d5b19ab71c6a3b
(3)图形管理
需求:创建私有仓库,为私有仓库添加web界面
docker run -it -p 8080:8080 --name registry-web \ # 端口映射
--link registry:wzj.com \ # 容器互联(访问wzj.com就是访问registry仓库)
-e REGISTRY_URL=https://wzj.com/v2 \ # url参数-->如何连接仓库
-e REGISTRY_TRUST_ANY_SSL=true \ # 信任所有SSL连接(加密)
-e REGISTRY_BASIC_AUTH="YWRtaW46d3pqMTEw" \ # /etc/.docker/config.json查看
-e REGISTRY_NAME=wzj.com:443 \ # 仓库的名字(一般是域名:端口)
hyper/docker-registry-web # 镜像
信息
[root@docker1 docker]# docker run -it -p 8080:8080 --name registry-web --link registry:westos.org -e REGISTRY_URL=https://westos.org/v2 -e REGISTRY_TRUST_ANY_SSL=true -e REGISTRY_BASIC_AUTH="cGVuZzp3ZXN0b3M=" -e REGISTRY_NAME=westos.org -e REGISTRY_READONLY=false docker-registry-web^C
[root@docker1 docker]# docker run -it -p 8080:8080 --name registry-web \
> --link registry:wzj.com \
> -e REGISTRY_URL=https://wzj.com/v2 \
> -e REGISTRY_TRUST_ANY_SSL=true \
> -e REGISTRY_BASIC_AUTH="YWRtaW46d3pqMTEw" \
> -e REGISTRY_NAME=wzj.com:443 \
> hyper/docker-registry-web
CATALINA_OPTS: -Djava.security.egd=file:/dev/./urandom -Dcontext.path=
Using CATALINA_BASE: /var/lib/tomcat7
Using CATALINA_HOME: /usr/share/tomcat7
Using CATALINA_TMPDIR: /var/lib/tomcat7/temp
Using JRE_HOME: /usr/lib/jvm/java-7-openjdk-amd64
Using CLASSPATH: /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar
Jul 12, 2019 5:58:13 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Jul 12, 2019 5:58:13 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 2146 ms
Jul 12, 2019 5:58:13 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Jul 12, 2019 5:58:13 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.52 (Ubuntu)
2019-07-12 05:59:16,787 [localhost-startStop-1] INFO hibernate4.HibernatePluginSupport - Set db generation strategy to 'update' for datasource DEFAULT
Configuring Spring Security Core ...
... finished configuring Spring Security Core
2019-07-12 05:59:21,254 [localhost-startStop-1] INFO cache.CacheBeanPostProcessor - postProcessBeanDefinitionRegistry start
2019-07-12 05:59:21,290 [localhost-startStop-1] INFO cache.CacheBeanPostProcessor - postProcessBeanFactory
2019-07-12 05:59:25,755 [localhost-startStop-1] WARN config.ConfigurationFactory - No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/var/lib/tomcat7/webapps/ROOT/WEB-INF/lib/ehcache-2.9.0.jar!/ehcache-failsafe.xml
2019-07-12 05:59:29,350 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: access_control
2019-07-12 05:59:29,359 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: event
2019-07-12 05:59:29,361 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: role
2019-07-12 05:59:29,377 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: role_access
2019-07-12 05:59:29,382 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: user
2019-07-12 05:59:29,390 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: user_role
2019-07-12 05:59:29,393 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: access_control
2019-07-12 05:59:29,395 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: event
2019-07-12 05:59:29,400 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: role
2019-07-12 05:59:29,403 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: role_access
2019-07-12 05:59:29,405 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: user
2019-07-12 05:59:29,412 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: user_role
2019-07-12 05:59:29,414 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: access_control
2019-07-12 05:59:29,421 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: event
2019-07-12 05:59:29,424 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: role
2019-07-12 05:59:29,426 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: role_access
2019-07-12 05:59:29,428 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: user
2019-07-12 05:59:29,432 [localhost-startStop-1] INFO sql.DatabaseMetaData - HHH000262: Table not found: user_role
2019-07-12 05:59:30,619 [localhost-startStop-1] INFO ehcache.GrailsEhCacheManagerFactoryBean - Initializing EHCache CacheManager
2019-07-12 05:59:37,892 [localhost-startStop-1] WARN web.TokenService - Authorization disabled
2019-07-12 05:59:39,063 [localhost-startStop-1] INFO web.RestService - Setting basic auth header: YWRtaW46d3pqMTEw
2019-07-12 05:59:48,576 [localhost-startStop-1] INFO filter.AnnotationSizeOfFilter - Using regular expression provided through VM argument net.sf.ehcache.pool.sizeof.ignore.pattern for IgnoreSizeOf annotation : ^.*cache\..*IgnoreSizeOf$
2019-07-12 05:59:48,647 [localhost-startStop-1] INFO sizeof.AgentLoader - Located valid 'tools.jar' at '/usr/lib/jvm/java-7-openjdk-amd64/jre/../lib/tools.jar'
2019-07-12 05:59:48,730 [localhost-startStop-1] INFO sizeof.JvmInformation - Detected JVM data model settings of: 64-Bit OpenJDK JVM with Compressed OOPs
2019-07-12 05:59:49,252 [localhost-startStop-1] INFO sizeof.AgentLoader - Extracted agent jar to temporary file /var/lib/tomcat7/temp/ehcache-sizeof-agent7365426072507464459.jar
2019-07-12 05:59:49,252 [localhost-startStop-1] INFO sizeof.AgentLoader - Trying to load agent @ /var/lib/tomcat7/temp/ehcache-sizeof-agent7365426072507464459.jar
2019-07-12 05:59:49,272 [localhost-startStop-1] INFO impl.DefaultSizeOfEngine - using Agent sizeof engine
2019-07-12 05:59:49,377 [localhost-startStop-1] INFO impl.DefaultSizeOfEngine - using Agent sizeof engine
2019-07-12 05:59:49,650 [localhost-startStop-1] INFO context.GrailsConfigUtils - [GrailsContextLoader] Grails application loaded.
2019-07-12 05:59:50,021 [localhost-startStop-1] INFO conf.BootStrap - Starting registry-web ver. 0.1.3-SNAPSHOT-bededf47611365f0a6d2bb87942e3b86c1e92d9f
2019-07-12 05:59:50,194 [localhost-startStop-1] INFO web.ConfigService - [environmentProperties, localProperties]
2019-07-12 05:59:50,213 [localhost-startStop-1] INFO web.ConfigService - resolved config:
2019-07-12 05:59:50,219 [localhost-startStop-1] INFO web.ConfigService - registry.url: https://wzj.com/v2
2019-07-12 05:59:50,220 [localhost-startStop-1] INFO web.ConfigService - registry.auth.key: /config/auth.key
2019-07-12 05:59:50,220 [localhost-startStop-1] INFO web.ConfigService - registry.readonly: true
2019-07-12 05:59:50,220 [localhost-startStop-1] INFO web.ConfigService - registry.trust_any_ssl: true
2019-07-12 05:59:50,220 [localhost-startStop-1] INFO web.ConfigService - registry.basic_auth: YWRtaW46d3pqMTEw
2019-07-12 05:59:50,220 [localhost-startStop-1] INFO web.ConfigService - registry.auth.enabled: false
2019-07-12 05:59:50,220 [localhost-startStop-1] INFO web.ConfigService - registry.context_path:
2019-07-12 05:59:50,220 [localhost-startStop-1] INFO web.ConfigService - registry.auth.issuer: test-issuer
2019-07-12 05:59:50,220 [localhost-startStop-1] INFO web.ConfigService - registry.name: wzj.com:443
2019-07-12 05:59:50,226 [localhost-startStop-1] INFO conf.BootStrap - auth enabled: false
2019-07-12 05:59:51,183 [localhost-startStop-1] INFO conf.BootStrap - Trusting any SSL certificate
Jul 12, 2019 5:59:51 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Jul 12, 2019 5:59:51 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 98088 ms
信息展示
说明:这个UI界面比较简单,后续讲解一个更加复杂的UI界面!
Vmware提供的界面,不属于docker原生的