启动本地仓库
Docker 官方提供了开源的镜像仓库 Distribution,并且镜像存放在 Docker Hub 的 Registry 仓库下供我们下载。
我们可以使用以下命令启动一个本地镜像仓库:
$ docker run -d -p 5000:5000 --name registry registry:2.7 Unable to find image 'registry:2.7' locally 2.7: Pulling from library/registry cbdbe7a5bc2a: Pull complete 47112e65547d: Pull complete 46bcb632e506: Pull complete c1cc712bcecd: Pull complete 3db6272dcbfa: Pull complete Digest: sha256:8be26f81ffea54106bae012c6f349df70f4d5e7e2ec01b143c46e2c03b9e551d Status: Downloaded newer image for registry:2.7 d7e449a8a93e71c9a7d99c67470bd7e7a723eee5ae97b3f7a2a8a1cf25982cc3
使用docker ps命令查看一下刚才启动的容器:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d7e449a8a93e registry:2.7 "/entrypoint.sh /etc…" 50 seconds ago Up 49 seconds 0.0.0.0:5000->5000/tcp registry
此时我们就拥有了一个私有镜像仓库,访问地址为localhost,端口号为 5000。
推送镜像到本地仓库
我们依旧使用 busybox 镜像举例。首先我们使用docker tag命令把 busybox 镜像"重命名"为localhost:5000/busybox
$ docker tag busybox localhost:5000/busybox
此时 Docker 为busybox镜像创建了一个别名localhost:5000/busybox,localhost:5000为主机名和端口,Docker 将会把镜像推送到这个地址。
使用docker push推送镜像到本地仓库:
$ docker push localhost:5000/busybox The push refers to repository [localhost:5000/busybox] 514c3a3e64d4: Layer already exists latest: digest: sha256:400ee2ed939df769d4681023810d2e4fb9479b8401d97003c710d0e20f7c49c6 size: 527
这里可以看到,我们已经可以把busybox推送到了本地镜像仓库。
此时,我们验证一下从本地镜像仓库拉取镜像。首先,我们删除本地的busybox和localhost:5000/busybox镜像。
查看一下本地busybox镜像:
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE
可以看到此时本地已经没有busybox这个镜像了。下面,我们从本地镜像仓库拉取busybox镜像:
$ docker pull localhost:5000/busybox Using default tag: latest latest: Pulling from busybox Digest: sha256:400ee2ed939df769d4681023810d2e4fb9479b8401d97003c710d0e20f7c49c6 Status: Downloaded newer image for localhost:5000/busybox:latest localhost:5000/busybox:latest
然后再使用docker images命令,这时可以看到我们已经成功从私有镜像仓库拉取busybox镜像到本地了。
持久化镜像存储
以下部分涉及到docker卷的操作,不理解的可以看这篇:Docker 卷与持久化数据存储的底层原理 。
我们知道,容器是无状态的。上面私有仓库的启动方式可能会导致镜像丢失,因为我们并没有把仓库的数据信息持久化到主机磁盘上,这在生产环境中是无法接受的。下面我们使用以下命令将镜像持久化到主机目录:
$ docker run -v /var/lib/registry/data:/var/lib/registry -d -p 5000:5000 --name registry registry:2.7
我们在上面启动registry的命令中加入了-v /var/lib/registry/data:/var/lib/registry,-v的含义是把 Docker 容器的某个目录或文件挂载到主机上,保证容器被重建后数据不丢失。-v参数冒号前面为主机目录,冒号后面为容器内目录。
事实上,registry 的持久化存储除了支持本地文件系统还支持很多种类型,例如 S3、Google Cloud Platform、Microsoft Azure Blob Storage Service 等多种存储类型。
到这里我们的镜像仓库虽然可以本地访问和拉取,但是如果你在另外一台机器上是无法通过 Docker 访问到这个镜像仓库的,因为 Docker 要求非localhost访问的镜像仓库必须使用 HTTPS,这时候就需要构建外部可访问的镜像仓库。
构建外部可访问的镜像仓库
要构建一个支持 HTTPS 访问的安全镜像仓库,需要满足以下两个条件:
- 拥有一个合法的域名,并且可以正确解析到镜像服务器;
- 从证书颁发机构(CA)获取一个证书。
在准备好域名和证书后,就可以部署我们的镜像服务器了。这里我以regisry.lagoudocker.io这个域名为例。首先准备存放证书的目录/var/lib/registry/certs,然后把申请到的证书私钥和公钥分别放到该目录下。 假设我们申请到的证书文件分别为regisry.lagoudocker.io.crt和regisry.lagoudocker.io.key。
如果上一步启动的仓库容器还在运行,我们需要先停止并删除它。
$ docker stop registry && docker rm registry
然后使用以下命令启动新的镜像仓库:
$ docker run -d --name registry -v "/var/lib/registry/data:/var/lib/registry -v "/var/lib/registry/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/regisry.lagoudocker.io.crt -e REGISTRY_HTTP_TLS_KEY=/certs/regisry.lagoudocker.io.key -p 443:443 registry:2.7
这里,我们使用 -v 参数把镜像数据持久化在/var/lib/registry/data目录中,同时把主机上的证书文件挂载到了容器的 /certs 目录下,同时通过 -e 参数设置 HTTPS 相关的环境变量参数,最后让仓库在主机上监听 443 端口。
仓库启动后,我们就可以远程推送镜像了。
$ docker tag busybox regisry.lagoudocker.io/busybox $ docker push regisry.lagoudocker.io/busybox
本文源自:拉勾教育课程:由浅入深吃透 Docker,讲师:郭少 前 360 高级容器技术专家