本地 Docker Registry 的安装与使用
安装 Docker 环境之后, 可以开始下载和运行 Docker 镜像了, 比如要下载一个 nginx 服务器, 只要输入下面的命令:
docker pull nginx:alpine
就能下载到基于 alpine 的最新版本的 nginx 服务器镜像, 然后再输入:
docker run \
--detach \
--name nginx \
--volume $(pwd)/nginx/conf.d:/etc/nginx/conf.d:ro \
--volume $(pwd)/nginx/html:/usr/share/nginx/html \
--volume $(pwd)/nginx/log:/var/log/nginx \
--publish 80:80 \
--restart unless-stopped \
nginx:alpine
就可以开始运行 nginx 服务器了, 使用起来非常方便。
作为开发者, 自然会自己制作一些镜像, 在公司内网分发, 或者开发团队制作镜像, 然后交付给测试团队进行测试, 这就需要一个内部分发镜像的服务器, 这个 Docker 团队自然也想到了, 并且提供了一个镜像 retistry , 先把这个镜像拉倒本地:
docker pull registry:latest
等待下载完成之后, 运行这个镜像:
docker run \
--detach \
--name registry \
--hostname registry \
--volume $(pwd)/registry:/var/lib/registry/docker/registry \
--publish 5000:5000 \
--restart unless-stopped \
registry:latest
-itd:在容器中打开一个伪终端进行交互操作,并在后台运行
-v:把宿主机的/data/registry目录绑定到容器/var/lib/registry目录(这个目录是registry容器中存放镜像文件的目录),来实现数据的持久化;
-p:映射端口;访问宿主机的5000端口就访问到registry容器的服务了
–restart=always: 这是重启的策略,在容器退出时总是重启容器
–name registry: 创建容器命名为registry
registry:latest:这个是刚才pull下来的镜像.
Docker容器的重启策略如下:
no:默认策略,在容器退出时不重启容器
on- failure:在容器非正常退出时(退出状态非0),才会重启容器
on- failure:3 :在容器非正常退出时重启容器,最多重启3次
always:在容器退出时总是重启容器
unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
在地址栏输入 https://127.0.0.1:5000/v2/_catalog , 将会看到类似下面的输出:
{"repositories":[]}
接下来我们尝试将上面的 nginx:alpine 上传到本地的 registry 服务器, 首先为这个镜像定义一个新的标签:
docker tag nginx:alpine 127.0.0.1:5000/nginx:alpine
然后确认存在这个标签
docker images
输出如下:
REPOSITORY TAG IMAGE ID CREATED SIZE
127.0.0.1:5000/nginx alpine 0ae090dba3ab 3 months ago 54.3 MB
nginx alpine 0ae090dba3ab 3 months ago 54.3 MB
现在可以上传这个镜像:
docker push 127.0.0.1:5000/nginx:alpine
输出如下
The push refers to a repository [127.0.0.1:5000/nginx]
4a8d9a67e458: Pushed
c0ab80890b7f: Pushed
d4930e247b49: Pushed
9f8566ee5135: Pushed
alpine: digest: sha256:bf63c02f35f7f8d0a95af4904d38ea17ef3f0c86e6b95d716200bdd9963f5ec5 size: 1154
现在来浏览 https://127.0.0.1:5000/v2/_catalog
, 将会看到这样的结果:
{"repositories":["nginx"]}
表示已经有了 nginx 这个镜像, 如果要看这个镜像有什么版本, 需要输入地址 https://127.0.0.1:5000/v2/nginx/tags/list
, 结果如下:
{"name":"nginx","tags":["alpine"]}
如果要在其它装了 docker 的电脑上获取这个镜像, 或者下载局域网其它 registry 服务器上的镜像,直接使用http是不被允许。
虽然强烈建议使用由已知 CA 颁发 TLS 证书保护您的仓库 ,也可以选择使用自签名证书,或使用 通过未加密的 HTTP 连接进行的仓库。涉及安全,权衡以下任一选择。
部署纯HTTP连接的仓库
- 编辑
daemon.json
文件,没有则创建它
Linux 位于:/etc/docker/daemon.json
windows位于:C:\ProgramData\docker\config\daemon.json
{
"insecure-registries" : ["myregistrydomain.com:5000"]
}
将不安全仓库(insecure registries
)的地址替换为示例中的地址。myregistrydomain.com
是仓库服务器的域名,如果没有域名也可以直接使用IP地址
启用不安全仓库后,Docker 将执行以下步骤:
首先,尝试使用 HTTPS。
如果 HTTPS 可用但证书无效,请忽略该关于证书错误 。
如果 HTTPS 不可用,则回退到 HTTP。
- 重新启动 Docker 以使更改生效
service docker restart
在要访问仓库的每个引擎主机上重复这些步骤,就可以push
、pull
镜像了
使用自签名证书
这比设置不安全仓库的解决方案更安全。
警告:对于某些版本的docker,将此功能与基本身份验证结合使用还需要将证书信任到操作系统证书存储中
- 生成您自己的证书
mkdir -p certs
openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-addext "subjectAltName = DNS:myregistry.domain.com" \
-x509 -days 365 -out certs/domain.crt
早期的openssl版本可能不支持-addext
,不过无所谓
$ sudo openssl req -newkey rsa:4096 -nodes -sha256 -keyout docker-certs/domain.key -x509 -days 36500 -out docker-certs/domain.crt
Generating a 4096 bit RSA private key
............................................................++
..................................................................++
writing new private key to 'docker-certs/domain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:myregistry.domain.com
Email Address []:
国家Country Name
填CN
,hostname
填你仓库的域名。只填这两个就好了
2. 启动仓库服务
docker run -d \
--restart=always \
--name registry \
-v "$(pwd)"/certs:/certs \
-v /data/docker/registry:/var/lib/registry \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-p 443:443 \
registry:latest
-
再需要使用该仓库的机器上做如下操作
- 将registry证书域名及对应ip地址配置到hosts
/etc/hosts
192.168.0.8 myregistry.domain.com
- 拷贝证书到指定目录,使docker信任该证书 (该路径与证书域名有关,请按实际域名创建证书拷贝路径)
mkdir -p /etc/docker/certs.d/myregistry.domain.com cp certs/domain.crt /etc/docker/certs.d/myregistry.domain.com/ca.crt
- 验证一下
$ docker push myregistry.domain.com/nginx:alpine The push refers to a repository [myregistry.domain.com/nginx] Get https://myregistry.domain.com/v1/_ping: dial tcp: lookup myregistry.domain.com: no such host [slp@iZj6cbgby11gq5ja7c7jz1Z myregistry.domain.com]$ sudo vim /etc/hosts [slp@iZj6cbgby11gq5ja7c7jz1Z myregistry.domain.com]$ sudo docker push myregistry.domain.com/nginx:alpine The push refers to a repository [myregistry.domain.com/nginx] bdea7c663e86: Pushed 1b22827e15b4: Pushed d9f50eaf56fa: Pushed 2530717ff0bb: Pushed e7766bc830a8: Pushed cb411529b86f: Pushed bc09720137db: Pushed 3dab9f8bf2d2: Pushed alpine: digest: sha256:2d4efe74ef541248b0a70838c557de04509d1115dec6bfc21ad0d66e41574a8a size: 1989
- 将registry证书域名及对应ip地址配置到hosts
这样就算好了