带有自签名证书的 Docker 注册表失败

问题描述 投票:0回答:2

我的目标是在树莓派上运行一个 docker registry(在

rpi
主机名后面),我能够从同一网络上的 linux PC 推送图像。我正在关注本指南:https://docs.docker.com/registry/insecure/#use-self-signed-certificates

我在我的 rpi 上做了以下步骤:

  1. mkdir -p certs
  2. openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -addext "subjectAltName = DNS:rpi" -x509 -days 365 -out certs/domain.crt
  3. docker run -d --restart=always --name registry -v $HOME/certs:/certs -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

我电脑上的步骤:

  1. scp pi@rpi:certs/domain.crt ca.crt
  2. sudo mkdir -p /etc/docker/certs.d/rpi:5000/
  3. sudo mv ca.crt /etc/docker/certs.d/rpi:5000/

现在,当我尝试推送图像

docker push rpi:5000/test-image
时,它失败并显示以下内容:
Get "https://rpi:5000/v2/": dialing rpi:5000 with direct connection: connecting to 192.168.1.201:5000: dial tcp 192.168.1.201:5000: connect: connection refused

如果我用 443 端口标记图像

docker push rpi:443/test-image
我得到这个错误:
Get "https://rpi:443/v2/": x509: certificate is valid for 227b7008fe5910b8b4b0563bb8ebcb9e.708221ab4c2f3a622587d123822b2328.traefik.default, not rpi

如何使用自签名证书将 docker 镜像推送到远程?

docker docker-registry self-signed-certificate
2个回答
0
投票

您似乎正在侦听端口 443。要使其正常工作,您需要更改一些内容:

  1. 向网络上的主机名添加一个域,即使它是本地域。这需要解决,因此请确保您可以连接到像
    rpi.localdomain
    这样的东西。如果图像路径的开头没有域,也没有端口(443 不需要),那么它将被视为 Docker Hub 上的用户名。
  2. 用那个名字重建你的证书。
  3. 确保以该名称存储证书,而不是
    /etc/docker/certs.d/rpi:5000/
    而是
    /etc/docker/certs.d/rpi.localdomain/
    或任何域名。放在名为5000的目录中,但连接到443意味着它没有被使用。
  4. 设置一个自签名的 CA,与密钥分开。

对于第 4 步,这是我自己设置证书的脚本示例:

certdir="certs"
cert_host="registry"
cert_san="DNS:localhost,DNS:$(hostname)"
for ip in $(ip a | grep inet | awk '{print $2}' | cut -f1 -d/); do
  cert_san="${cert_san},IP:$ip"
done

if [ ! -d "$certdir" ]; then
  mkdir -p "$certdir"
fi

# setup a CA key
if [ ! -f "$certdir/ca-key.pem" ]; then
  openssl genrsa -out "${certdir}/ca-key.pem" 4096
fi

# setup a CA cert
openssl req -new -x509 -days 365 \
  -subj "/CN=Local CA" \
  -key "${certdir}/ca-key.pem" \
  -sha256 -out "${certdir}/ca.pem"

# setup a host key
if [ ! -f "${certdir}/key.pem" ]; then
  openssl genrsa -out "${certdir}/key.pem" 2048
fi

# create a signing request
extfile="${certdir}/extfile"
openssl req -subj "/CN=${cert_host}" -new -key "${certdir}/key.pem" \
   -out "${certdir}/${cert_host}.csr"
echo "subjectAltName = ${cert_san}" >${extfile}

# create the host cert
openssl x509 -req -days 365 \
   -in "${certdir}/${cert_host}.csr" -extfile "${certdir}/extfile" \
   -CA "${certdir}/ca.pem" -CAkey "${certdir}/ca-key.pem" -CAcreateserial \
   -out "${certdir}/cert.pem"

在上面的脚本中,

ca.pem
是被复制到
/etc/docker/certs.d/${registry}/ca.crt
的内容。


0
投票

在我的树莓派上运行的另一个软件(

k3s
)接管了443端口。

docker push
首先向 https://rpi.home/v2/ 发出请求并验证证书,该证书通常由
registry
容器提供。但是,如果
k3s
服务器正在运行,它会提供
/v2
url 并提供完全不同的证书。

解决方案是将不同的端口映射到容器的 443。

© www.soinside.com 2019 - 2024. All rights reserved.