如何部署一个 docker registry

2016-03-28 15:51:38 +08:00
 Mush

Deploy a secure docker registry

啊! 部署一个 Docker registry 好麻烦, 所以我部署完之后撸了一个文档, 奈何我的博客太丑不想在上面发(又没有时间撸个新博客), 所以就在这里发出来给大家看看, 希望能帮你们省点时间.

获取 SSL 证书

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --help
./letsencrypt-auto certonly --standalone -d <HOST>

letsencrypt 会将证书生成到/etc/letsencrypt/live/<HOST>/目录下, 我们可以将其复制到一个 docker 数据卷专用的目录下方便挂载.

letsencrypt 生成的证书是.pem 格式的, docker 文档上给的例子是.crt 的, 但是经我测试直接使用 letsencrypt 生成的证书就可以了.

生成 http 密码文件

docker run --entrypoint htpasswd registry -Bbn <username> <password> > auth/htpasswd

或者

htpasswd -Bbn <USERNAME> <PASSWORD>

Run registry

#!/bin/bash
docker run \
    -d --net='host' \
    --restart=always \
    --name registry \
    -v /fs1/dsr/auth/:/auth \
    -e "REGISTRY_AUTH=htpasswd" \
    -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
    -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
    -v /fs1/dsr/crets/:/certs \
    -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/fullchain.pem \
    -e REGISTRY_HTTP_TLS_KEY=/certs/privkey.pem \
    -e REGISTRY_STORAGE_DELETE_ENABLED=true \
    -v /fs1/dsr/registry/:/var/lib/registry registry:2.3.1

这个东西坑太多了, 需要注意一点是, registry 默认没有启用删除镜像的功能, 而且当你上传镜像版本过多的情况下, 会把你硬盘塞满的, 所以需要在启动时增加一个-e REGISTRY_STORAGE_DELETE_ENABLED=true参数来开启删除镜像的功能. 至于怎么删除镜像, 那就更坑了, 放心下面会写的.

客户机执行的操作

要想 push 到一个安全的 docker registry 或者上面 pull 下一个 image, 我们需要先 login.

 docker login <HOST>:<PORT>

push 的话, 需要先 tag 一下

docker tag <image>:<tag> <HOST>:<PORT>/<image>:<tag>

pull 的话, 直接 pull 一个完整的路径

docker pull <HOST>:<PORT>/<image>:<tag>

HTTP API V2

docker registry 的管理需要通过 API 进行, 其 API 设计非常规范, 但是巨难用. 下面使用 Python 的 requests 库来简单写下调用方式

登陆

import requests

url = "https://<username>:<password>@<registry-host>:<port>/v2/"

headers = {
    'cache-control': "no-cache",
    'postman-token': "83e67d92-5abe-33f0-0f0b-3f887401dbb6"
    }

response = requests.request("GET", url, headers=headers)

print(response.text)

镜像列表

import requests

url = "https://<HOST>:<PORT>/v2/_catalog"

headers = {
    'cache-control': "no-cache",
    'postman-token': "44940e36-b98a-da5e-daed-935df752f28c"
    }

response = requests.request("GET", url, headers=headers)

print(response.text)
{
  "repositories": [
    "mush/ss-server",
    "solo/dev",
    "solo/jenkins",
    "solo/live-api-runtime",
    "solo/pingstart-runtime",
    "solo/warehouse-runtime",
    "ubuntu"
  ]
}

获取镜像的 tag

import requests

url = "https://<HOST>:<PORT>/v2/solo/live-api-runtime/tags/list"

headers = {
    'cache-control': "no-cache",
    'postman-token': "a9bdb73e-6beb-2ca1-44c2-08572054c994"
    }

response = requests.request("GET", url, headers=headers)

print(response.text)
{
  "name": "solo/live-api-runtime",
  "tags": [
    "21",
    "84",
    "20"
  ]
}

获取 manifests

import requests

url = "https://<HOST>:<PORT>/v2/solo/live-api-runtime/manifests/6"

headers = {
    'cache-control': "no-cache",
    'postman-token': "2376f1a6-91a3-fc00-1c42-e498ceecfc93"
    }

response = requests.request("GET", url, headers=headers)

print(response.text)

这里, 在响应头里会有Docker-Content-Digest →sha256:fcd95bdae75d558ba53bd6f660003f6ba90d95c18ddb483d2d0ad7d6166034ab, 这个很重要, 是一个 image 的唯一标识.

删除一个镜像

import requests

url = "https://<HOST>:<PORT>/v2/solo/live-api-runtime/manifests/sha256:fcd95bdae75d558ba53bd6f660003f6ba90d95c18ddb483d2d0ad7d6166034ab"

headers = {
    'cache-control': "no-cache",
    'postman-token': "edad64ad-38c3-e363-581e-5028ba14c48a"
    }

response = requests.request("DELETE", url, headers=headers)

print(response.text)

response code 为 202 就是 OK 了. 然而这个删除并不能将文件从硬盘上删除掉, 所以我也不造官方是怎么想的, 做了一个如此无用的接口......

要想将文件从硬盘上删除可以看看burnettk/delete-docker-registry-image

其他事项

更新 SSL 证书

#!/bin/sh
systemctl stop nginx
if ! /opt/letsencrypt/letsencrypt-auto renew -nvv --standalone --force-renewal > /var/log/letsencrypt/renew.log 2>&1 ; then
    echo Automated renewal failed:
    cat /var/log/letsencrypt/renew.log
    exit 1
fi
systemctl start nginx

注意: 记得将证书复制到你需要的地方

如何查看 registry 上有哪些镜像

直接浏览器访问registry 的接口即可

参考文档

生成有效的 ssl 证书: letsencrypt

部署 docker registry: docker 官方文档

API 文档: Docker Registry HTTP API V2

6604 次点击
所在节点    分享发现
7 条回复
wujunze
2016-03-28 16:04:36 +08:00
沙发 好久不见你在群里冒泡了
Mush
2016-03-28 16:06:54 +08:00
@wujunze 最近累的要死....
wujunze
2016-03-28 16:08:37 +08:00
@Mush 你在新公司 还好吧?
imxieke
2016-03-28 17:00:56 +08:00
我记得官方有直接部署的镜像吧?
https://hub.docker.com/_/registry/
Mush
2016-03-28 17:06:29 +08:00
@imxieke 是的, 但是其中有坑, 比如说 https 证书还有日后维护什么的

@wujunze 很好
iappled
2017-11-16 11:02:08 +08:00
rootcertbundle 这个怎么配置
huixia0010
2018-05-17 18:02:31 +08:00
谢谢楼主分享经验

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/266876

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX