如何使用 Kubernetes 使用自签名证书访问私有 Docker 注册表? [英] How do I access a private Docker registry with a self signed certificate using Kubernetes?

查看:47
本文介绍了如何使用 Kubernetes 使用自签名证书访问私有 Docker 注册表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Currently, running a private Docker registry (Artifactory) on an internal network that uses a self signed certificate for authentication.

当 Kubernetes 启动一个新节点时,它无法使用私有 Docker 注册表进行身份验证,因为这个新节点没有自签名证书.

When Kubernetes starts up a new node, it is unable to auth with the private Docker registry because this new node does not have the self signed certificate.

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

Any help would be much appreciated. Thanks!

推荐答案

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

The simplest solution I found after an extensive search is suggested in this guide by 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集群的所有节点.

It consists to create a secret that contains your certificate and a DaemonSet to populate it to /etc/docker/certs.d/my-private-insecure-registry.com/ca.crt on all the nodes of your cluster.

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

I think this answers your question because, when adding a new node, the DaemonSet is automatically executed on it.

我在下面给出了详细的解决方案,但所有的功劳都归功于 Kyle Brown (kbrwn) 的非常酷的指南(参见上面的链接).

I give the detailed solution below but all the credits goes to Kyle Brown (kbrwn) for his very cool guide (cf. link above).

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

Lets suppose that your certificate is a file named ca.crt in your working directory. Create a secret from this file content :

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

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

Then, use the following DaemonSet that mounts the certificate as the file /home/core/registry-ca and copy it to the desired location : /etc/docker/certs.d/reg.example.com/ca.crt.

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

Simply replace my-private-insecure-registry.com with the hostname of your container registry.

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', '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:

Save the file as registry-ca-ds.yaml and then create the DaemonSet :

kubectl create -f registry-ca-ds.yaml

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

You can now check that your application correctly pulls from your private self-signed registry.

如前所述,证书将通过 registry-ca DaemonSet 以自动方式添加到新节点的 docker.如果你想避免这种情况,只需删除 DaemonSet :

As mentioned, the certificate will be added to new nodes' docker in an automatic fashion by the registry-ca DaemonSet. If you want to avoid this, simply delete the DaemonSet :

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

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

I think this is more secure than setting the insecure-registries flag of the docker daemon. Also, it is resilient to new nodes.

正如@MarcusMaxwell 所建议的,这个答案已经过编辑,以考虑到 Kubernetes 1.16+ 集群的 API extensions/v1beta1 的弃用.如果您仍然使用 1.16 之前的版本运行 Kubernetes 集群,则应改用此代码:

As suggested by @MarcusMaxwell, this answer has been edited to take into account the deprecation of the API extensions/v1beta1 for Kubernetes 1.16+ clusters. If you still run a Kubernetes cluster with version prior to 1.16, you should adapt this code instead:

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

已知限制(编辑 2021)

根据这些 Kubernetes 答案(此处此处)到相关的 github 问题,Kubernetes 卷路径不能包含冒号.因此,此解决方案对于使用特定端口(例如 5000)上的自签名证书进行安全通信的注册表无效.

Known limitations (edit 2021)

According to these Kubernetes answers (here and here) to related github issues, a Kubernetes volume path cannot contain a colon. Therefore, this solution is not valid for registries that communicate securely with a self-signed certificate on specific ports (for example 5000).

在这种情况下,请参阅 Gary Plattenburg 的回答,在 shell 命令中创建目录,而不是在挂载期间使用 Kubernetes 来处理它.

In such case, please see Gary Plattenburg's answer to create the directory in the shell command instead of using Kubernetes to handle it during the mount.

这篇关于如何使用 Kubernetes 使用自签名证书访问私有 Docker 注册表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆