5

我想在一个自我修复的 AWS ECS 集群上运行一个私有的、安全的、经过身份验证的 docker 注册表。集群设置已完成并且工作正常,但我很难registry:latest运行。问题是,每次我推送图像时,推送 blob 都会失败,除非我超时,否则会进入重试周期。

为了确保我的 ECS 设置不是障碍,我尝试使用 Docker4Mac 1.12.0-a 在本地设置所有内容。

首先,非常基本的设置有效。我创建了我自己版本的注册表映像,在那里我将我的 TLS 证书包和密钥以及必要的htpasswd文件直接放入映像中。[我知道,这是不安全的,我只是为了测试目的而这样做]。所以这是我的Dockerfile

FROM registry:latest

COPY htpasswd /etc/docker
COPY server_bundle.pem /etc/docker
COPY server_key.pem /etc/docker

server_bundle.pem我的域(CN=*.mydomain.com)有一个通配符证书mydomain.com作为第一个,然后是中间 CA 证书,所以客户应该很高兴。我的htpasswd文件是使用推荐的方法创建的:

docker run --entrypoint htpasswd registry:2 -Bbn heyitsme mysupersecurepassword > htpasswd

我建立我的形象:

docker build -t heyitsme/registry .

然后我运行一个非常基本的版本,没有 TLS 和身份验证:

docker run --restart=always -p 5000:5000 heyitsme/registry

我实际上可以拉、标记和重新推送图像:

docker pull alpine
docker tag alpine localhost:5000/alpine
docker push localhost:5000/alpine

这行得通。接下来,我通过环境变量使 TLS 和基本身份验证工作:

docker run -h registry.mydomain.com --name registry --restart=always -p 5000:5000 \ 
  -e REGISTRY_HTTP_HOST=http://registry.mydomain.com:5000 \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/etc/docker/server_bundle.pem \
  -e REGISTRY_HTTP_TLS_KEY=/etc/docker/server_key.pem \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM=Registry-Realm \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/etc/docker/htpasswd heyitsme/registry

暂时我创建一个条目,/etc/hosts其中说:

127.0.0.1 registry.mydomain.com

然后我登录:

docker login registry.mydomain.com:5000
Username: heyitsme
Password: ***********
Login Succeeded

所以现在,让我们在此处标记并推送图像:

docker tag alpine registry.mydomain.com:5000/alpine
docker push registry.mydomain.com:5000/alpine

The push refers to a repository [registry.mydomain.com:5000/alpine]
4fe15f8d0ae6: Retrying in 4 seconds

发生的情况是,docker 客户端尝试推送片段并失败。然后它重试并再次失败,直到我超时。所以接下来检查V2API 是否正常工作:

curl -i -XGET https://registry.mydomain.com:5000/v2/
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Docker-Distribution-Api-Version: registry/2.0
Www-Authenticate: Basic realm="Registry-Realm"
X-Content-Type-Options: nosniff
Date: Thu, 15 Sep 2016 10:06:04 GMT
Content-Length: 87

{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":null}]}

好的,正如预期的那样。所以让我们下次进行身份验证:

curl -i -XGET https://heyitsme:mysupersecretpassword@registry.mydomain.com:5000/v2/
HTTP/1.1 200 OK
Content-Length: 2
Content-Type: application/json; charset=utf-8
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Date: Thu, 15 Sep 2016 10:06:16 GMT

{}%

作品。但是推动仍然失败。

日志说:

time="2016-09-15T10:24:34Z" level=warning msg="error authorizing context: basic authentication challenge for realm \"Registry-Realm\": invalid authorization credential" go.version=go1.6.3 http.request.host="registry.mydomain.com:5000" http.request.id=6d2ec080-6824-4bf7-aac2-5af31db44877 http.request.method=GET http.request.remoteaddr="172.17.0.1:40878" http.request.uri="/v2/" http.request.useragent="docker/1.12.0 go/go1.6.3 git-commit/8eab29e kernel/4.4.15-moby os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.0 \\(darwin\\))" instance.id=be3a8877-de64-4574-b47a-70ab036e7b79 version=v2.5.1
172.17.0.1 - - [15/Sep/2016:10:24:34 +0000] "GET /v2/ HTTP/1.1" 401 87 "" "docker/1.12.0 go/go1.6.3 git-commit/8eab29e kernel/4.4.15-moby os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.0 \\(darwin\\))"
time="2016-09-15T10:24:34Z" level=info msg="response completed" go.version=go1.6.3 http.request.host="registry.mydomain.com:5000" http.request.id=8f81b455-d592-431d-b67d-0bc34155ddbf http.request.method=POST http.request.remoteaddr="172.17.0.1:40882" http.request.uri="/v2/alpine/blobs/uploads/" http.request.useragent="docker/1.12.0 go/go1.6.3 git-commit/8eab29e kernel/4.4.15-moby os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.0 \\(darwin\\))" http.response.duration=30.515131ms http.response.status=202 http.response.written=0 instance.id=be3a8877-de64-4574-b47a-70ab036e7b79 version=v2.5.1
172.17.0.1 - - [15/Sep/2016:10:24:34 +0000] "POST /v2/alpine/blobs/uploads/ HTTP/1.1" 202 0 "" "docker/1.12.0 go/go1.6.3 git-commit/8eab29e kernel/4.4.15-moby os/linux arch/amd64 UpstreamClient(Docker-Client/1.12.0 \\(darwin\\))"
2016/09/15 10:24:34 http: TLS handshake error from 172.17.0.1:40886: tls: first record does not look like a TLS handshake

我还测试了原始registry图像的不同版本,尤其是上面的几个版本2。都产生相同的错误。如果有人可以在这个问题上帮助我,那就太棒了。

4

2 回答 2

9

解决了:

-e REGISTRY_HTTP_HOST=https://registry.mydomain.com:5000 \

作为环境变量做了滴答声。只是先前的使用http反而https使连接失败。

于 2016-09-19T08:04:44.713 回答
2

非常感谢,它现在正在工作!

我在我的 kubernetes 部署清单中添加了变量:

(...)
      - env:
        - name: REGISTRY_STORAGE_DELETE_ENABLED
          value: "true"
        - name: REGISTRY_HTTP_HOST
          value: "https://registry.k8sprod.acme.domain:443"
(...)

对于那些在前面使用 nginx ingress 的人,如果你有推送大小错误,你必须在你的 ingress 清单文件中设置额外的属性:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-registry
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/proxy-body-size: "8192m"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "10"
    nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
  labels:
    k8s-app: kube-registry
    app: kube-registry
spec:
  rules:
    - host: registry.k8sprod.acme.domain
      http:
        paths:
        - path: /
          backend:
            serviceName: svc-kube-registry
            servicePort: 5000

于 2020-02-18T13:43:07.047 回答