启用TLS的反向代理(Traefik)后的Docker注册表-远程错误:错误的证书

TyR*_*den 1 ssl reverse-proxy docker docker-registry traefik

所以我在这里做所有被Docker化的工作。Traefik和我的docker Registry实例一样都在容器中运行。如果我在注册表中单击,则可以从注册表中正常进行推/拉操作mydomain.com:5000/myimage

问题出在我尝试使用443击打它时mydomain.com/myimage。我在这里设置的是Traefik反向代理,在侦听443 mydomain.com,并将内部请求转发到:5000我的Registry实例。

当我从Traefik网址进行推/拉时,它挂起并倒数,等待在循环上重试。当我查看注册表的日志时,每一个我都可以看到实例IS实际上与反向代理Traefik通信,但是,我一遍又一遍地(在客户端的每次重试中)都遇到此错误:

2018/05/31 21:10:43 http: TLS handshake error from proxy_container_ip:port: remote error: tls: bad certificate

关于TLS问题,Docker Registry确实非常严格。由于我仍在开发中,因此我在这里使用所有自签名证书。知道是什么原因导致此错误吗?我假设Traefik代理检测到注册表提供的证书不可信(自签名),因此没有完成“推送”请求,反之亦然-发送注册表时,注册表返回到Traefik代理会检测到它不受信任。

如果需要,我可以提供其他信息。当前设置是Traefik和Registry都有自己的.crt和.key文件集。这两个(当然)都启用了TLS。

谢谢。

mai*_*mic 6

这是带有自签名证书的有效解决方案,您可以在https://labs.play-with-docker.com上试用

服务器

node1在您的Docker游乐场中添加一个新实例。我们将其配置为服务器。创建证书目录:

mkdir /root/certs
Run Code Online (Sandbox Code Playgroud)

创建通配符证书*.domain.local

$ openssl req -newkey rsa:2048 -nodes -keyout /root/certs/domain.local.key -x509 -days 365 -out /root/certs/domain.local.crt
Generating a 2048 bit RSA private key
...........+++
...........+++
writing new private key to '/root/certs/domain.local.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) []:
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:*.domain.local
Email Address []:
Run Code Online (Sandbox Code Playgroud)

在directory中创建两个文件docker-compose.ymltraefik.toml/root。您可以使用以下方法下载它们:

wget https://gist.github.com/maiermic/cc9c9aab939f7ea791cff3d974725e4a/raw/8c5d787998d33c752f2ab369a9393905780d551c/docker-compose.yml
wget https://gist.github.com/maiermic/cc9c9aab939f7ea791cff3d974725e4a/raw/8c5d787998d33c752f2ab369a9393905780d551c/traefik.toml
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml

mkdir /root/certs
Run Code Online (Sandbox Code Playgroud)

traefik.toml

$ openssl req -newkey rsa:2048 -nodes -keyout /root/certs/domain.local.key -x509 -days 365 -out /root/certs/domain.local.crt
Generating a 2048 bit RSA private key
...........+++
...........+++
writing new private key to '/root/certs/domain.local.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) []:
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:*.domain.local
Email Address []:
Run Code Online (Sandbox Code Playgroud)

初始化Docker Swarm(以替换<ip-of-node1>为IP地址node1,例如192.168.0.13):

wget https://gist.github.com/maiermic/cc9c9aab939f7ea791cff3d974725e4a/raw/8c5d787998d33c752f2ab369a9393905780d551c/docker-compose.yml
wget https://gist.github.com/maiermic/cc9c9aab939f7ea791cff3d974725e4a/raw/8c5d787998d33c752f2ab369a9393905780d551c/traefik.toml
Run Code Online (Sandbox Code Playgroud)

部署traefik和Docker注册表:

version: '3'

services:
  frontproxy:
    image: traefik
    command: --api --docker --docker.swarmmode
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./certs:/etc/ssl:ro
      - ./traefik.toml:/etc/traefik/traefik.toml:ro
      - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events
    deploy:
      labels:
        - traefik.port=8080
        - traefik.frontend.rule=Host:traefik.domain.local
  docker-registry:
    image: registry:2
    deploy:
      labels:
        - traefik.port=5000 # default port exposed by the registry
        - traefik.frontend.rule=Host:registry.domain.local
        - traefik.frontend.auth.basic=user:$$apr1$$9Cv/OMGj$$ZomWQzuQbL.3TRCS81A1g/ # user:password, see https://docs.traefik.io/configuration/backends/docker/#on-containers
Run Code Online (Sandbox Code Playgroud)

客户

由于没有DNS服务器,因此我们进行了更改/etc/hosts(例如,以服务器<ip-of-node1>的IP地址代替): node1192.168.0.13

defaultEntryPoints = ["http", "https"]

# Redirect HTTP to HTTPS and use certificate, see https://docs.traefik.io/configuration/entrypoints/
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      certFile = "/etc/ssl/domain.local.crt"
      keyFile = "/etc/ssl/domain.local.key"

# Docker Swarm Mode Provider, see https://docs.traefik.io/configuration/backends/docker/#docker-swarm-mode
[docker]
endpoint = "tcp://127.0.0.1:2375"
domain = "docker.localhost"
watch = true
swarmMode = true
Run Code Online (Sandbox Code Playgroud)

您现在应该可以从traefik请求健康状况

docker swarm init --advertise-addr <ip-of-node1>
Run Code Online (Sandbox Code Playgroud)

并且您应该能够从我们的注册表中请求所有图像(无)

docker stack deploy myregistry -c ~/docker-compose.yml
Run Code Online (Sandbox Code Playgroud)

让我们docker在客户端上进行配置。创建注册表证书的目录:

echo "<ip-of-node1>   registry.domain.local traefik.domain.local" >> /etc/hosts
Run Code Online (Sandbox Code Playgroud)

从我们的服务器获取证书:

$ curl -ksS https://traefik.domain.local/health | jq .
{
  "pid": 1,
  "uptime": "1m37.501499911s",
  "uptime_sec": 97.501499911,
  "time": "2018-07-19 07:30:35.137546789 +0000 UTC m=+97.600568916",
  "unixtime": 1531985435,
  "status_code_count": {},
  "total_status_code_count": {},
  "count": 0,
  "total_count": 0,
  "total_response_time": "0s",
  "total_response_time_sec": 0,
  "average_response_time": "0s",
  "average_response_time_sec": 0
}
Run Code Online (Sandbox Code Playgroud)

现在您应该能够登录到我们的注册表并添加图像:

$ curl -ksS -u user:password https://registry.domain.local/v2/_catalog | jq .
{
  "repositories": []
}
Run Code Online (Sandbox Code Playgroud)

如果之后您要求我们的注册中心提供所有图片,您应该会看到

mkdir -p /etc/docker/certs.d/registry.domain.local/
Run Code Online (Sandbox Code Playgroud)