仓库(Repository)是存储和分发 Docker 镜像的地方。镜像仓库类似于代码仓库,Docker Hub 的命名来自 GitHub,Github 是我们常用的代码存储和分发的地方。同样 Docker Hub 是用来提供 Docker 镜像存储和分发的地方。
服务器(Registry)和仓库(Repository)有啥区别?可以解释下这两个概念的区别:注册服务器是存放仓库的实际服务器,而仓库则可以被理解为一个具体的项目或者目录;注册服务器可以包含很多个仓库,每个仓库又可以包含多个镜像。例如我的镜像地址为 docker.io/centos,docker.io 是注册服务器,centos 是仓库名。
按照类型,我们将镜像仓库分为公共镜像仓库和私有镜像仓库。
公共镜像仓库
公共镜像仓库一般是 Docker 官方或者其他第三方组织(阿里云,腾讯云,网易云等)提供的,允许所有人注册和使用的镜像仓库。
Docker Hub 是全球最大的镜像市场,目前已经有超过 10w 个容器镜像,这些容器镜像主要来自软件供应商、开源组织和社区。大部分的操作系统镜像和软件镜像都可以直接在 Docker Hub 下载并使用。
使用Docker Hub首先需要官网注册账号,然后命令行里docker login
登陆(默认请求docker hub服务器),本地构建了某个镜像xxx/xxxx后,用docker push
命令就可以推送镜像到自己创建的仓库docker push xxx/xxxx
持久化镜像存储
我们知道,容器是无状态的。普通私人仓库的启动方式可能会导致镜像丢失,因为我们并没有把仓库的数据信息持久化到主机磁盘上,这在生产环境中是无法接受的。下面我们使用以下命令将镜像持久化到主机目录:
$ 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