如何使用Kubernetes访问带有自签名证书的私有Docker注册表?

时间:2018-11-29 18:51:35

标签: docker kubernetes google-cloud-platform cloud infrastructure

当前,在使用自签名证书进行身份验证的内部网络上运行私有Docker注册表(Artifactory)。

当Kubernetes启动新节点时,它无法通过私有Docker注册表进行身份验证,因为该新节点没有自签名证书。

任何帮助将不胜感激。谢谢!

5 个答案:

答案 0 :(得分:2)

CoreOS在本指南中建议了我进行广泛搜索后发现的最简单的解决方案:https://github.com/coreos/tectonic-docs/blob/master/Documentation/admin/add-registry-cert.md

它包括创建一个包含您的证书和DaemonSet的密钥,以将其填充到群集的所有节点上的/etc/docker/certs.d/my-private-insecure-registry.com/ca.crt中。

我认为这回答了您的问题,因为在添加新节点时,DaemonSet会自动在其上执行。

我在下面提供了详细的解决方案,但所有功劳归功于Kyle Brown(kbrwn),他的指导很酷(参见上面的链接)。

详细解决方案

让我们假设您的证书是工作目录中名为ca.crt的文件。从此文件内容创建秘密:

kubectl create secret generic registry-ca --namespace kube-system --from-file=registry-ca=./ca.crt

然后,使用以下将证书作为文件/home/core/registry-ca装入的DaemonSet,并将其复制到所需的位置:/etc/docker/certs.d/reg.example.com/ca.crt

只需用容器注册表的主机名替换my-private-insecure-registry.com

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: registry-ca
  namespace: kube-system
  labels:
    k8s-app: registry-ca
spec:
  template:
    metadata:
      labels:
        name: registry-ca
    spec:
      containers:
      - name: registry-ca
        image: busybox
        command: [ 'sh' ]
        args: [ '-c', 'cp /home/core/registry-ca /etc/docker/certs.d/my-private-insecure-registry.com/ca.crt && exec tail -f /dev/null' ]
        volumeMounts:
        - name: etc-docker
          mountPath: /etc/docker/certs.d/my-private-insecure-registry.com
        - name: ca-cert
          mountPath: /home/core
      terminationGracePeriodSeconds: 30
      volumes:
      - name: etc-docker
        hostPath:
          path: /etc/docker/certs.d/my-private-insecure-registry.com
      - name: ca-cert
        secret:
          secretName: registry-ca

将文件另存为registry-ca-ds.yaml,然后创建DaemonSet:

kubectl create -f registry-ca-ds.yaml

您现在可以检查您的应用程序是否可以正确地从私有自签名注册表中提取。

如前所述,证书将由registry-ca DaemonSet自动添加到新节点的docker中。如果要避免这种情况,只需删除DaemonSet即可:

kubectl delete ds registry-ca --namespace kube-system

我认为这比设置docker守护进程的insecure-registries标志更安全。而且,它对新节点具有弹性。

答案 1 :(得分:1)

您基本上必须通过告诉Docker守护程序信任您用来签署证书的Certificate Authority(CA)来信任您的自签名证书。您可以在“使用自签名证书”部分找到更多信息here

特别是对于Linux:

  

Linux:将domain.crt文件复制到每个Docker主机上的/etc/docker/certs.d/myregistrydomain.com:5000/ca.crt。您无需重启Docker。

这与通过在您的Pod或docker配置文件中的docker登录凭据上指定ImagePullSecrets进行身份验证不同。

答案 2 :(得分:1)

来自 1.16+ 的 Bichon 接受的答案在评论中说它不适用于端口上的 URL,因为无法安装带有冒号 (:) 的路径。这可以通过挂载父目录并更改命令参数来解决。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: registry-ca
  namespace: kube-system
  labels:
    k8s-app: registry-ca
spec:
  selector:
    matchLabels:
      name: registry-ca
  template:
    metadata:
      labels:
        name: registry-ca
    spec:
      containers:
      - name: registry-ca
        image: busybox
        command: [ 'sh' ]
        args: [ '-c', 'mkdir /etc/docker/certs.d/my-private-insecure-registry.com:5000 && cp /home/core/registry-ca /etc/docker/certs.d/my-private-insecure-registry.com:5000/ca.crt && exec tail -f /dev/null' ]
        volumeMounts:
        - name: etc-docker
          mountPath: /etc/docker/certs.d
        - name: ca-cert
          mountPath: /home/core
      terminationGracePeriodSeconds: 30
      volumes:
      - name: etc-docker
        hostPath:
          path: /etc/docker/certs.d
      - name: ca-cert
        secret:
          secretName: registry-ca

答案 3 :(得分:0)

您可以在$ HOME / .dockercfg或$ HOME / .docker / config.json中访问私有Docker注册表的密钥。如果将其添加到这些搜索路径之一,则kubelet在提取图像时应将其用作凭据。

  • {-root-dir:-/ var / lib / kubelet} /config.json
  • {kubelet的cwd} /config.json
  • $ {HOME} /。docker / config.json
  • /。docker / config.json
  • {-root-dir:-/ var / lib / kubelet} /。dockercfg
  • {kubelet的cwd} /。dockercfg
  • $ {HOME} /。dockercfg
  • /。dockercfg

https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry

“配置节点以对私有注册表进行身份验证”部分为您提供了逐步进行操作的步骤。

答案 4 :(得分:0)

Kubernetes可能在Kubernetes集群节点上使用docker守护程序。 为了让他们信任您的本地注册表,可以将受信任的注册表主机名添加到文件/etc/docker/daemon.json中,如下所示:

{ "insecure-registries":["some.local.registry"] }

其中some.local.registry是注册表的主机名。

您需要重新启动docker进程才能使其生效。 我是针对非公开且没有有效TLD的域执行此操作的,因此无法将cert-manager与letsencrypt结合使用。

您需要在使用docker连接到该注册表的每台机器上执行相同的操作。