Docker入门篇-搭建docker私服(注册表)
在我们开始使用docker之前,我们先把私服搭建起来,这种顺序通常适用于生产级或实际工作的时使用docker的习惯。我们遵循这样的习惯。概念当我们执行docker pusll xxx的时...
在我们开始使用docker之前,我们先把私服搭建起来,这种顺序通常适用于生产级或实际工作的时使用docker的习惯。我们遵循这样的习惯。
概念
当我们执行docker pusll xxx的时候,默认是从docker公共仓库下载镜像到本地,当我们执行docker push xxx的时候,默认是推送到docker公共仓库中,docker 公共仓库地址:
https://hub.docker.com/ 如果想了解的话自行登录注册账号,就可以使用了。
在企业生产级运维中,一般不会随意把公司应用镜像推送到公共仓库中,所以我们需要搭建自己内部的仓库,我们本章就是讲解如何搭建自己的私服。其实笔者认为docker社区版搭建私服的过程还是蛮繁杂的,不过只要读者跟着笔者一步步操作,搭建自己的私服完全不在话下。话不多说,我们直接在创建的虚拟机节点2上进行如下步骤:
安装私服
我们选择在node2机子上安装docker私服。安装步骤如下:
1、卸载docker,主要是检查之前是否安装过,有安装的话把老的卸载掉
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2、安装docker
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
3、配置镜像下载加速
vi /etc/docker/daemon.json
输入以下内容:
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
docker安装后默认没有daemon.json这个配置文件,需要进行手动创建。配置文件的默认路径:/etc/docker/daemon.json
该文件作为 Docker Engine 的配置管理文件, 里面几乎涵盖了所有 docker 命令行启动可以配置的参数。
更多配置可参考官方文档说明:
https://docs.docker.com/engine/reference/commandline/dockerd/#/configuration-reloading
4、启动docker
systemctl start docker
5、下载、运行私服镜像:
docker run -d -p 5000:5000 --restart=always --name registry registry:2
--restart=always意思是只要该容器没有启动,总是尝试重启。
6、查看运行容器列表
docker container ls或docker ps
7、浏览器访问:
http://node2:5000/v2/_catalog 出现{}则表示成功。
笔者这里为了方便,直接停掉防火墙服务:
systemctl stop firewalld
推送镜像到私服
1、拉ubuntu:16.04镜像
docker pull ubuntu:16.04
2、将镜像标记为localhost:5000/my-ubuntu。这会为现有镜像创建一个附加标记。当标记的的第一部分是主机名和端口时,Docker在推送时将其解释为注册表的位置。例如localhost:5000/my-ubuntu中的localhost:5000代表该镜像推送到localhost:5000私服。格式是固定的。官方约定俗成的。
docker images
创建新的镜像,镜像命名前缀指定了推送的私服地址
docker image tag ubuntu:16.04 localhost:5000/myfirstimage
3、将镜像推送到运行于的本地注册表localhost:5000:
docker push localhost:5000/myfirstimage
如果你的私服是在其它机子且非https协议的,push会报错:
http: server gave HTTP response to HTTPS client
你需要在daemon.json配置文件中配置:--insecure-registry如下:
{
"insecure-registries": ["ip:port"],
"registry-mirrors": ["https://registry.docker-cn.com"]
}
4、删除本地镜像
docker image remove ubuntu:16.04 或docker rmi ubuntu:16.04
docker image remove localhost:5000/myfirstimage
5、再从本地私服拉下来
dockder images
docker pull localhost:5000/myfirstimage
6、访问私服地址
http://node2:5000/v2/_catalog
可以看到我们刚才推送的镜像
7、停止注册表。
8、删除容器
docker container rm -v registry
下面我们重启启动私服,并将容器内部镜像的存储路径映射到宿主机外面:
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /var/docker/registry:/var/lib/registry registry:2
-v 选项参数指定将容器内部路径映射到宿主机某个路径,上面命令我们将私服的镜像存在位置到宿主机/var/docker/registry下
测试下载镜像:
docker pull ubuntu:16.04
docker image tag ubuntu:16.04 localhost:5000/myfirstimage
docker push localhost:5000/myfirstimage
cd /var/docker/registry
就可以看到镜像被推送到该目录下,上面我们简单了解了docker私服的使用,搭建起了简单私服,为我们后面实战使用。
更多关于docker私服信息请查看官方文档:
https://docs.docker.com/registry/deploying/
docker知识库地址:https://docs.docker.com/glossary/?term=repository
docker私服安全性
不知读者是否发现,我们私服实在太不安全了,我们直接在浏览器回车就能看到所有的镜像列表,如果公司是内网,虽然至少对外是安全的,但始终对内部还是有可能会暴露我们应用存储的信息,如果是在AWS或阿里云等其他公网上部署,那就更加不安全了,我们开发的应用可能随时被外人发现并pull下来看个遍。对,实际上我们需要设置安全登录账号和密码,这样才稍微放心些,除了配置登录密码外,我们还要保证网络传输过程的安全,所以还要配置tls传输加密。
这里有个细节问题就是当我们配置好tls之后,访问的协议会从http变为https,除此之外,我们push进行时标签前缀以域名替代之前的localhost或ip,上面我们提过的配置项(insecure-registries)可以删除且不会报错。
注:tls是ssl标准的实现,两者之间意思大致相同。事实上我们现在用的都是TLS,但因为历史上习惯了SSL这个称呼平常很多开发同事还是以称呼SSL为多。后面笔者描述TLS或SSL时是同一个意思,不做区分。
话不多说,下面给出私服配置tls传输加密以及配置登录密码步骤:
1、申请个人或公司域名,笔者已经在腾讯云申请好了域名laizhiy.cn
这个很多人都会觉得麻烦,还要花钱去买个域名?哎不学了,放弃了。笔者这里给你打个气,域名不贵,一年才几十块钱。去万网或腾讯云买个吧,其它地方说不定还用得上,如果确实不想买也没关系,就直接跳过这章,不会影响后面的学习哈。
2、解析一个二级域名(registry.laizhiy.cn)到node2的ip上
我们私服是部署到虚拟化的节点2(node2)上的
3、在本地电脑ping registry.laizhiy.cn测试是否解析成功
4、申请ssl证书,笔者这里选择免费ssl证书,有效期一年
阿里云或腾讯云申请免费ssl证书,具体方式可自行查阅网络资料,该文档是针对docker的,其它知识避免过多讲解,知识是讲不完的,我们要抓重点。
5、下载申请通过的证书文件 (分别后缀为.key和.crt两个文件)
笔者文件名为:1_registry.laizhiy.cn_bundle.crt 和 2_registry.laizhiy.cn.key
6、开通node2 443端口防火墙
7、创建目录mkdir -p /opt/etc/docker/registry/ssl/cert
8、将.key和.crt两个文件上传到 /opt/etc/docker/registry/ssl/cert目录下
文件上传下载可以使用lrzsz yum install lrzsz
9、停止运行中的注册表docker stop registry(这里假定你的容器名字为registry)
10、重新启动注册表
docker run -d --rm --name registry \
-v /opt/etc/docker/registry/ssl/certs/:/certs \
-v /var/docker/registry:/var/lib/registry \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/1_registry.laizhiy.cn_bundle.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/2_registry.laizhiy.cn.key \
-p 443:443 registry:2
另外说明下,当同一台服务器安装多个应用且端口发生冲突时,可以通过nginx代理到registry。有兴趣的读者可自行查阅网络资料。
11、查看镜像列表
curl https://registry.laizhiy.cn/v2/_catalog 或浏览器访问:
https://registry.laizhiy.cn/v2/_catalog
能够看到我们之前上传的镜像就证明SSL配置成功了
12、测试使用域名进行上传镜像到私服
docker pull hello-world
docker images
docker tag hello-world registry.laizhiy.cn/hello-world:1.0
docker images
docker push registry.laizhiy.cn/hello-world:1.0
curl https://registry.laizhiy.cn/v2/_catalog
上面演示完了配置SSL的过程,下面我们继续配置密码,步骤如下:
13、创建目录mkdir -p /opt/etc/docker/registry/auth
14、通过docker自带的htpasswd工具生成用户名为:lazy密码:123456文件
docker run --rm --entrypoint htpasswd \
registry:2 -Bbn lazy 123456 > /opt/etc/docker/registry/auth/htpasswd
15、停止私服docker stop registry
16、重启docker registry
docker run -d --rm --name registry \
-v /opt/etc/docker/registry/ssl/certs/:/certs \
-v /var/docker/registry:/var/lib/registry \
-v /opt/etc/docker/registry/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/1_registry.laizhiy.cn_bundle.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/2_registry.laizhiy.cn.key \
-p 443:443 registry:2
17、验证密码有效性
浏览器直接访问:https://registry.laizhiy.cn/v2/_catalog,此时,会弹出登录框,输入lazy 123456即可,或输入读者自己定义的用户名和密码。
docker tag hello-world registry.laizhiy.cn/hello-world:1.1
docker push registry.laizhiy.cn/hello-world:1.1
咋整,现在连基本的push都失败了,没关系,我们下面通过命令行进行登录,其实这才是我们要的效果,安全性得到了保证。
18、登录私服
docker login registry.laizhiy.cn
docker push registry.laizhiy.cn/hello-world:1.1
19、登出私服
有登录自然有登出,命令如下:
docker logout registry.laizhiy.cn
20、补充说明:
读者可能很快发现个问题,就是要运行一个私服太不容易了,光命令行就这么长,其实官方还提供了通过配置文件的方式进行配置,后面在集成ui时笔者会演示一下配置文件的使用方式,这里先给出配置文件的官方文档位置: https://docs.docker.com/registry/configuration/
github上还提供了配置文件起步配置:
https://github.com/docker/distribution/blob/master/cmd/registry/config-example.yml
假定你的配置文件为/opt/etc/docker/registry.yml,配置完成后我们只需要这样启动容器就行了:
docker run -d -p 5000:5000 --name registry \
-v /opt/etc/docker/registry.yml:/etc/docker/registry/config.yml \
registry:2
另外,我们这里用到了-v -e -p这些选项命令,这里暂时简单讲解下含义:
-v :将容器某个目录或文件绑定/映射到宿主机某个目录或文件上
-v /opt/etc/docker/registry/ssl/certs/:/certs代表将容器的/certs目录绑定到宿主机的/opt/etc/docker/registry/ssl/certs这个目录,从Docker 17.06开始,(这里提一下,本篇教程是基于docker18.09版本的)。对于数据绑定或挂载大部分使用--mount方式,更加灵活,关于docker数据管理后面会有专门的章节来讲解。
-e: 通用配置项一般都用-e,大致意思是配置某个变量为什么值,给到docker本身程序使用
-p:将容器内的某个端口绑定到宿主机某个端口。这里涉及到docker网络相关的知识,笔者在后面章节会单独提取出来讲解,这里提前跟读者打个招呼,网络这一块对于学习docker来说至关重要。
-d:以守护进程方式在后台运行,相反前台运行命令为: -t -i
--rm:容器退出时,删除容器,如果容器比较稳定,建议不加--rm,下次直接docker start 容器ID/容器名称即可,方便很多。
21、告一段落
OK,至此,私服安全性已经得到正常的保障,接下来我们还要继续完善私服,想要搭好一个安全且好用的私服,真可谓千里迢迢啊,没办法,谁让咱们用的是社区版的呢,企业版的docker私服就没那么多麻烦事了,不过麻烦也好,可以多学习动手能力和解决问题的耐心,不但省钱还能学习东西,哈哈。
docker私服ui
从上面我们看到,官方社区版的私服毫无界面可言,直接返回json结果,下面我们继续在上面的基础上搭建一个带ui界面的docker私服,开源github地址为:https://github.com/mkuchin/docker-registry-web,这里多说一句,目前开源的docker registry ui项目有多个,详细有哪些读者可以自行查阅网络资料,都是非docker 官方开源的,我们这里选择的是docker-registry-web
玩docker无非就是知道大概原理,懂得敲命令,命令如下:
1、下载镜像
docker pull hyper/docker-registry-web
1、启动私服
启动ui容器之前需要先启动实际的私服,按上面启动命令启动私服:
docker run -d --rm --name registry \
-v /opt/etc/docker/registry/ssl/certs/:/certs \
-v /var/docker/registry:/var/lib/registry -v /opt/etc/docker/registry/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/1_registry.laizhiy.cn_bundle.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/2_registry.laizhiy.cn.key \
-p 443:443 registry:2
2、启动ui
docker run -d -p 8080:8080 \
--rm --name registry-web \
-e REGISTRY_URL=https://registry.laizhiy.cn/v2 \
-e REGISTRY_NAME=localhost:5000 \
-e REGISTRY_TRUST_ANY_SSL=true \
-e REGISTRY_BASIC_AUTH="bGF6eToxMjM0NTY=" \
hyper/docker-registry-web
这里着重讲解下下面两个配置含义:
-e REGISTRY_TRUST_ANY_SSL=true : 注册表使用了可信任的任何ssl证书
-e REGISTRY_BASIC_AUTH="bGF6eToxMjM0NTY=" :用户名:密码经过base64编码后的值,这里笔者直接从浏览器登录私服后的请求报文header auth baisc中复制过来
启动后浏览器直接访问:http://node2:8080/ 或http://registry.laizhiy.cn:8080/
OK, 我们终于有个简单的ui界面可以看到我们的镜像列表了。但是,还不够,因为这个ui界面只能查看,当然对应这个不用登录直接就可以进去的web ui来说,只能查询可以保证镜像的安全,但是有时候我们自己想通过ui删除镜像时就显得力不从心了,所以,接下来我们继续完善这个ui,使之支持删除功能,但可以想象,支持删除功能的ui一定是需要登录密码的。
我们这里将兑现上面对读者的承诺,使用配置文件进行配置,而不是使用命令行。但是笔者不会给出每一项配置的含义,请读者自行翻阅官方文档:
https://docs.docker.com/registry/configuration/
话不多说,步骤如下:
1、创建注册表配置文件/opt/etc/docker/registry/conf/registry.yml,内容如下:
version: 0.1
storage:
filesystem:
rootdirectory: /var/lib/registry
http:
addr: 0.0.0.0:443
tls:
certificate: /certs/1_registry.laizhiy.cn_bundle.crt
key: /certs/2_registry.laizhiy.cn.key
auth:
token:
realm: http://registry.laizhiy.cn:8080/api/auth
service: https://registry.laizhiy.cn
issuer: lazy
rootcertbundle: /etc/docker/registry/auth.cert
log:
level: info
上面配置需要注意的是我们将注册表从密码htpasswd方式转为token鉴权auth的方式,这种方式更适合应用之间的安全访问控制。auth和htpasswd只能使用其中一种。
2、重启启动私服
docker stop registry
docker run -d --rm --name registry-srv \
-v /opt/etc/docker/registry/ssl/certs/:/certs \
-v /opt/etc/docker/registry/conf/registry.yml:/etc/docker/registry/config.yml:ro \
-v /var/docker/registry:/var/lib/registry \
-v /opt/etc/docker/registry/ssl/certs/1_registry.laizhiy.cn_bundle.crt:/etc/docker/registry/auth.cert:ro \
-p 443:443 registry:2
注意了,这里有坑,就是容器名称不能为registry,随便改一个,这里笔者改为registry-srv。这是个很细节的坑,务必注意。
3、创建注册表ui配置文件/opt/etc/docker/registry/conf/registry-web.yml,内容如下:
registry:
url: https://registry.laizhiy.cn/v2
name: https://registry.laizhiy.cn
readonly: false
trust_any_ssl: true
auth:
enabled: true
issuer: 'lazy'
key: /conf/auth.key
log:
level: info
4、重启注册表ui
docker stop registry-web
docker run -d -p 8080:8080 \
--rm --name registry-web \
-v /opt/etc/docker/registry/conf/registry-web.yml:/conf/config.yml:ro \
-v /var/docker/registry-web:/data \
-v /opt/etc/docker/registry/ssl/certs/2_registry.laizhiy.cn.key:/conf/auth.key:ro \
hyper/docker-registry-web
5、浏览器访问:http://registry.laizhiy.cn:8080/
输入admin admin登录进去后,可以查看到我们之前推送上去的镜像。ui是搭起来了,后面教下大家怎么用。
1、admin账号是默认账号,该账号角色不要去操作它
2、创建一个账号,比如笔者这里为:账号:lazy 密码:lazy
3、按需分配角色给账号,笔者这里直接分配所有角色给账号lazy
4、登出admin账号,登入lazy账号测试是否可以登录
5、回到节点2服务器执行如下命令:
docker images
docker tag hello-world registry.laizhiy.cn/hello-world:1.2
docker push registry.laizhiy.cn/hello-world:1.2
提示没有权限,我们登录一下,登录用户名和密码是多少呢?没错,是ui创建的用户lazy或admin,我们知道admin没有只有后台ui_admin角色,这个角色是不能push的,因为我们没有分配对应权限的角色给admin,当然我们可以分配权限给admin但强烈不建议这么做。
我们先用admin登录然后push,看是否跟我们预期一样,没有推送权限。
可以看到admin是没有push权限的,现在我们登出admin,然后再登录lazy,再push
OK,至此,我们完成了docke私服接近生产级的搭建,是否有感受到笔者前面说的繁杂了吗?
当然还可以继续完善,比如通过命令docker create network xxx自定义网络、通过swarm集群方式部署、通过docker-compose在单个服务器或集群中批量部署所有相关的服务等等。这些知识后面笔者会将一一讲解。不过,目前的部署方式已经基本满足生产级部署。
想要深入学好任何一门技术,都是这样,任重而道远。当然也有很多技术人是蜻蜓点水,通过某些博客直接复制跑起来就完事,这种方式适合入门时的快速体验,不能做到熟练使用。
更多推荐
所有评论(0)