如何在 DigitalOcean Spaces 上建立私有 Docker 注册表并与 DigitalOcean Kubernetes 结合使用

作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。

介绍

一个 Docker 注册表是名为 Docker 图像的存储和内容交付系统,这是集装箱应用程序的行业标准。一个私人 Docker 注册表允许您在团队或组织中安全地共享图像,与公共图像相比具有更大的灵活性和控制性。

默认存储系统是本地文件系统,但您可以用基于云的存储驱动程序进行交换。 DigitalOcean Spaces 是为开发团队和企业设计的 S3 兼容的对象存储器,他们想要一个可扩展、简单且负担得起的方式来存储和服务大量数据,并且非常适合存储 Docker 图像。

在本教程中,您将部署您的私人 Docker 注册表到您的 DigitalOcean Kubernetes集群使用 Helm),由 DigitalOcean Spaces 备份以存储数据. 您将为指定空间创建 API 密钥,安装 Docker 注册表到您的集群以自定义配置,配置 Kubernetes 以正确身份验证,并通过在集群上运行示例部署来测试它。

如果您正在寻找一个管理的Kubernetes托管服务,请查看我们的简单的,用于增长的管理的Kubernetes服务(https://www.digitalocean.com/products/kubernetes)。

前提条件

在您开始本教程之前,您将需要:

  • Docker安装在您将从中访问集群的机器上. 对于Ubuntu 18.04,访问[如何在Ubuntu 18.04上安装和使用多克 (https://andsky.com/tech/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04). 您只需完成 ** 第 1 段 ** 和 ** 第 2 段 ** 。 否则,访问多克的website以进行其他发行.
  • 在 [Docker Hub] (https://hub.docker.com] 为您在此教程中创建的 Docker 图像存储的账户 。
  • Git 安装在您访问集群所使用的机器上. 对于Ubuntu 18.04,请遵循 [如何在Ubuntu 18.04上安装 Git] (https://andsky.com/tech/tutorials/how-to-install-git-on-ubuntu-18-04) 教程的 ** 第 1 ** 步. 其他平台请访问[官方网站] (https://git-scm.com/downloads).
  • 数字海洋库伯内兹集群,您的连接配置为 kubectl 默认 。 关于如何配置 kubectl 的指令, 将显示在您的集群** 步骤的 ** 下。 要学习如何在 DigitalOcean 上创建库伯内特斯集群,请参见 [Kubernetes Quickstart] (https://www.digitalocean.com/docs/kubernetes/quickstart/).
  • 数字海洋空间 有 API 密钥(访问和秘密). 要学习如何创建数字海洋空间和API密钥,请参见[如何创建数字海洋空间和API密钥] (https://andsky.com/tech/tutorials/how-to-create-a-digitalocean-space-and-api-key).
  • 在您本地机器上安装的 Helm 包管理器 。 要做到这一点,请使用 Helm 3 软件包管理器完成 [如何在 Kubernetes 集群上安装软件] (https://andsky.com/tech/tutorials/how-to-install-software-on-kubernetes-clusters-with-the-helm-3-package-manager) 教程中的 ** 第 1 ** 个步骤。
  • Nginx 入侵控制器和 Cert-Manager 安装在集群上. 关于如何做到这一点的指南,见[如何在使用Helm的数字海洋库伯内特斯上设置Nginx入侵 (https://andsky.com/tech/tutorials/how-to-set-up-an-nginx-ingress-on-digitalocean-kubernetes-using-helm).
  • 一个有2个DNS A记录的域名指向了入侵者所使用的数字海洋负载平衡器. 如果您正在使用 DigitalOcean 来管理您的域名的 DNS 记录,请查看[如何管理 DNS 记录 (https://www.digitalocean.com/docs/networking/dns/how-to/manage-records/) 创建 A 记录. 在这个教程中,我们将将 A 记录称为 'registry. your_domain' 和 'k8s-test. your_domain'. <$>[注] ** 注:** 您在此教程中使用的域名必须与 ** How to Set up a Nginx Ingress on Digital Ocean Kubernetes** 中所使用的域名不同. < $ >

步骤 1 – 配置和安装 Docker 注册表

在此步骤中,您将创建注册表部署的配置文件,并使用 Helm 包管理器将注册表安装到您的集群中。

在本教程的过程中,您将使用名为 `chart_values.yaml’ 的配置文件来取代 Docker 注册表的某些默认设置 Helm chart. Helm 调用其包,图表;这些是描述 Kubernetes 资源的相关选择的文件集。

作为 Nginx Ingress 控制器的前提条件的一部分,您创建了示例服务和 Ingress. 在本教程中您不需要它们,因此您可以通过运行以下命令来删除它们:

1kubectl delete -f hello-kubernetes-first.yaml
2kubectl delete -f hello-kubernetes-second.yaml
3kubectl delete -f hello-kubernetes-ingress.yaml

kubectl删除命令接受文件在通过-f参数时删除。

而不是使用官方的Docker注册表,该注册表与S3存储提供商有问题,我们将使用GitLab的 容器注册表叉子,您需要下载和构建。

创建一个将作为您的工作空间的文件夹:

1mkdir ~/k8s-registry

通过运行导航:

1cd ~/k8s-registry

使用git下载集装箱注册表存储,运行以下命令:

1git clone https://gitlab.com/gitlab-org/container-registry.git

结果将类似于此:

1[secondary_label Output]
2Cloning into 'container-registry'...
3remote: Enumerating objects: 1706, done.
4...
5Resolving deltas: 100% (13955/13955), done.

存储库现在位于集装箱注册表目录中. 导航到它:

1cd container-registry

要从集群中使用它,您需要从集群中构建一个 Docker 图像,然后将其推到公共注册表,例如 Docker Hub。

切换到最新稳定版本的分支,运行:

1git checkout v2.13.1-gitlab

运行以下命令来构建注册表的 Docker 图像,将 your_dockerhub_username 替换为您的 Docker Hub 用户名:

1docker build -t your_dockerhub_username/registry:dev .

这个命令可能需要一段时间才能完成,输出将很长,并且应该类似于以下:

1[secondary_label Output]
2...
3Successfully built 27322ec15cf7
4Successfully tagged your_dockerhub_username/registry:dev

现在已经构建了图像,要将其推到您的帐户,您需要先登录:

1docker login

请在提示时输入您的 Docker Hub 用户名和密码。

1[secondary_label Output]
2...
3Login Succeeded

您现在可以按下图像:

1docker push your_dockerhub_username/registry:dev

最终的结果将看起来像:

1[secondary_label Output]
2The push refers to repository [docker.io/your_dockerhub_username/registry]
3c3baf7582a54: Pushed
4bc49969a328b: Pushed
50694fbf8288a: Pushed
63e207b409db3: Mounted from library/alpine
7dev: digest: sha256:02399157107a1d72312fb4f383f4c8c53a08f3e206d787a9c9380f446b008184 size: 1156

现在您已经构建并推移了注册表,然后返回您的工作区:

1cd ~/k8s-registry

使用您最喜欢的文本编辑器创建您的 chart_values.yaml 文件:

1nano chart_values.yaml

添加以下行,确保您用您的细节取代突出的行:

 1[label chart_values.yaml]
 2ingress:
 3  enabled: true
 4  hosts:
 5    - registry.your_domain
 6  annotations:
 7    kubernetes.io/ingress.class: nginx
 8    cert-manager.io/cluster-issuer: letsencrypt-prod
 9    nginx.ingress.kubernetes.io/proxy-body-size: "30720m"
10  tls:
11    - secretName: docker-registry-prod
12      hosts:
13        - registry.your_domain
14
15storage: s3
16
17secrets:
18  htpasswd: ""
19  s3:
20    accessKey: "your_space_access_key"
21    secretKey: "your_space_secret_key"
22
23s3:
24  region: your_space_region
25  regionEndpoint: your_space_region.digitaloceanspaces.com
26  secure: true
27  bucket: your_space_name
28
29image:
30  repository: your_dockerhub_username/registry
31  tag: dev

第一块,‘ingress’,配置了Kubernetes Ingress,将作为Helm图表部署的一部分创建。Ingress对象使外部HTTP/HTTPS路线指向集群中的内部服务,从而允许从外部进行通信。

  • enabled:设置为 true以启用 Ingress.
  • hosts:由 Ingress 接收流量的主机列表.
  • annotations:为 Kubernetes 其他部分提供进一步的指南,以便如何处理 Ingress. 你将 Ingress 控制器设置为 nginx, Let's Encrypt 集群发行器到生产变体( letsencrypt-prod),并告诉 'nginx' 控制器接受最多大小 30 GB 的文件,这对于即使是最大的 Docker 图像来说也是合理的限制。 tls:此子类别配置 Let's Encrypt HTTPS. 你将填写定义的 hosts列表,

然后,您将文件系统存储设置为s3 - 另一个可用的选项将是filesystem。这里s3表示使用与行业标准的Amazon S3 API兼容的远程存储系统,而DigitalOcean Spaces满足了这一要求。

在下一个区块秘密中,您在s3子类别下配置了访问您的DO空间的密钥,最后在s3区块中,您配置了指定您的空间的参数。

在文件的末尾,您将您刚刚推出的注册表图像指定为将部署的注册表,而不是官方的Docker注册表。

保存并关闭文件。

现在,如果您尚未这样做,请设置您的 A 记录以指向您在先决性教程中创建的 Nginx Ingress Controller 安装的一部分的负载平衡器。

将Docker注册表部署的图表位于 twuni存储库中,通过运行将其添加到Helm:

1helm repo add twuni https://helm.twun.io

在安装任何东西之前,您需要更新其缓存。这将更新图表存储的最新信息。 要做到这一点,运行以下命令:

1helm repo update

现在,您将通过运行Helm来部署此自定义配置的Docker注册表图:

1helm install docker-registry twuni/docker-registry -f chart_values.yaml

您将看到以下输出:

 1[secondary_label Output]
 2NAME: docker-registry
 3LAST DEPLOYED: ...
 4NAMESPACE: default
 5STATUS: deployed
 6REVISION: 1
 7TEST SUITE: None
 8NOTES:
 91. Get the application URL by running these commands:
10  https://registry.your_domain/

注册表现在可以从您之前指定的域名访问。

您已在您的 Kubernetes 集群上配置并部署了 Docker 注册表,接下来,您将测试新部署的 Docker 注册表的可用性。

步骤2 - 测试推和拉

在此步骤中,您将通过将图像推到并从新部署的Docker注册表进行测试。当前,注册表是空的。 要有东西要推,您需要在您正在工作的机器上有可用图像。

首先,从 Docker Hub 中拖出mysql:

1docker pull mysql

你的输出将看起来像这样:

1[secondary_label Output]
2Using default tag: latest
3latest: Pulling from library/mysql
427833a3ba0a5: Pull complete
5...
6e906385f419d: Pull complete
7Digest: sha256:9643e9fbd6330d10686f8922292dcb20995e7b792c17d4e94ddf95255f1d5449
8Status: Downloaded newer image for mysql:latest
9docker.io/library/mysql:latest

现在您有本地可用的图像. 要告知 Docker 将其推到哪里,您需要用主机名称标记它,如下:

1docker tag mysql registry.your_domain/mysql

然后将图像推到新注册表:

1docker push registry.your_domain/mysql

此命令将成功运行,并表示您的新注册表已正确配置并接受流量,包括推新图像。

要测试清晰地从注册表中抽取,首先用以下命令删除本地 mysql 图像:

1docker rmi registry.your_domain/mysql && docker rmi mysql

然后从注册表中提取它:

1docker pull registry.your_domain/mysql

此命令需要几秒钟才能完成. 如果成功运行,则意味着您的注册表正在正确运行. 如果显示错误,请对您输入的命令进行双重检查。

您可以通过运行以下命令列出本地可用的 Docker 图像:

1docker images

您将看到输出列出可在本地机器上使用的图像,以及它们的 ID 和创建日期。

您的 Docker 注册表已配置,您已将图像推到它,并验证您可以将其拖下来,现在让我们添加身份验证,这样只有某些人才能访问图像。

步骤 3 – 添加帐户身份验证和配置 Kubernetes 访问

在此步骤中,您将使用htpasswd实用程序为注册表设置用户名和密码身份验证。

htpasswd的实用程序来自Apache网页服务器,您可以使用它来创建存储用户名和密码的文件,用于基本的HTTP用户身份验证。

您将使用一个 Dockerized 变体的 htpasswd' 来简化操作。 运行以下命令,将登录组合附加到 htpasswd_file,以您所需的身份证代替 usernamepassword`:

1docker run --rm -ti xmartlabs/htpasswd username password >> htpasswd_file

Docker 需要使用 bcrypt 算法对密码进行哈希化,此算法默认地在这里使用。 bcrypt 算法是一种基于 Blowfish 区块加密的密码哈希功能,具有 work factor 参数,该参数指定了哈希函数的成本。

您可以对您想要添加的用户重复此命令。

完成后,通过运行以下命令来显示 `htpasswd_file' 的内容:

1cat htpasswd_file

选择并复制显示的内容。

要将身份验证添加到您的 Docker 注册表中,您需要编辑 chart_values.yaml 并在 htpasswd 变量中添加 htpasswd_file 的内容。

打开chart_values.yaml来编辑:

1nano chart_values.yaml

找到看起来像这样的线条:

1[label chart_values.yaml]
2  htpasswd: ""

编辑它以匹配下列情况,用您从htpasswd_file复制的内容代替htpasswd\_file\_contents:

1[label chart_values.yaml]
2  htpasswd: |-
3    htpasswd_file_contents

要小心插头,每个字符串的文件内容必须有四个空间,你可以删除空行,如果有。

一旦你添加了你的内容,保存并关闭文件。

若要将更改传播到您的集群中,请运行以下命令:

1helm upgrade docker-registry twuni/docker-registry -f chart_values.yaml

输出将类似于您第一次部署 Docker 注册表时所显示的输出:

 1[secondary_label Output]
 2Release "docker-registry" has been upgraded. Happy Helming!
 3NAME: docker-registry
 4LAST DEPLOYED: ...
 5NAMESPACE: default
 6STATUS: deployed
 7REVISION: 2
 8TEST SUITE: None
 9NOTES:
101. Get the application URL by running these commands:
11  https://registry.your_domain/

这个命令呼叫Helm并指示它升级现有版本,在您的情况下是docker-registry,其图表定义为稳定/docker-registry在图表存储库中,应用了chart_values.yaml文件后。

现在,您将再次尝试从注册表中拉出图像:

1docker pull registry.your_domain/mysql

结果将看起来如下:

1[secondary_label Output]
2Using default tag: latest
3Error response from daemon: Get https://registry.your_domain/v2/mysql/manifests/latest: no basic auth credentials

它正确失败了,因为您没有提供任何凭据,这意味着您的 Docker 注册表正确授权请求。

要登录注册表,请执行以下命令:

1docker login registry.your_domain

请记住,用您的域名代替registry.your_domain。它会提示您使用户名和密码。如果显示出错误,请双重检查您的htpasswd_file包含了什么。您必须从您在此步骤中创建的htpasswd_file中指定用户名和密码组合。

要测试登录,您可以尝试通过运行以下命令再次拖动:

1docker pull registry.your_domain/mysql

结果将类似于以下:

1[secondary_label Output]
2Using default tag: latest
3latest: Pulling from mysql
4Digest: sha256:f2dc118ca6fa4c88cde5889808c486dfe94bccecd01ca626b002a010bb66bcbe
5Status: Image is up to date for registry.your_domain/mysql:latest

现在您已经配置了 Docker 并可以安全地登录. 若要将 Kubernetes 配置为登录您的注册表,请执行以下命令:

1sudo kubectl create secret docker-registry regcred --docker-server=registry.your_domain --docker-username=your_username --docker-password=your_password

此命令在您的集群中创建了一个名为regcred的秘密,该秘密将包含您的注册表的登录信息,并将其解析为dockerconfigjson,该秘密在Kubernetes中定义了一个注册表凭据。

请记住,用您的注册表域代替registry.your_domain,并将您之前创建的登录证件置于your_usernameyour_password

您将看到以下结果:

1[secondary_label Output]
2secret/regcred created

您使用「htpasswd」创建了登录配置文件,配置了注册表以验证请求,并创建了一个包含登录凭证的Kubernetes秘密。

步骤 4 — 通过运行样本部署来测试 Kubernetes 集成

在此步骤中,您将使用存储在集群内注册表中的图像运行样本部署,以测试您的Kubernetes集群和注册表之间的连接。

在最后一步中,您创建了一个秘密,名为regcred,其中包含您的私人注册表的登录凭证,它可能包含多个注册表的登录凭证,在这种情况下,您需要相应地更新秘密。

您可以通过指定imagePullSecrets来指定在 pod 定义中拉取容器时应该使用哪些秘密 Kubernetes。

您现在将从您的私人 Docker 注册表部署一个样本 Hello World 图像到您的集群。

1docker pull paulbouwer/hello-kubernetes:1.8

然后,通过跑步来标记它:

1docker tag paulbouwer/hello-kubernetes:1.8 registry.your_domain/paulbouwer/hello-kubernetes:1.8

最后,把它推到你的注册表:

1docker push registry.your_domain/paulbouwer/hello-kubernetes:1.8

将其从您的机器中删除,因为您不再需要本地:

1docker rmi registry.your_domain/paulbouwer/hello-kubernetes:1.8

现在,你将部署样本 Hello World 应用程序. 首先,使用你的文本编辑器创建一个新的文件, hello-world.yaml:

1nano hello-world.yaml

接下来,您将定义一个服务和一个 Ingress,以使应用程序能够访问群集之外的用户。

 1[label hello-world.yaml]
 2apiVersion: networking.k8s.io/v1
 3kind: Ingress
 4metadata:
 5  name: hello-kubernetes-ingress
 6  annotations:
 7    kubernetes.io/ingress.class: nginx
 8spec:
 9  rules:
10  - host: k8s-test.your_domain
11    http:
12      paths:
13      - pathType: Prefix
14        path: "/"
15        backend:
16          service:
17            name: hello-kubernetes
18            port:
19              number: 80
20---
21apiVersion: v1
22kind: Service
23metadata:
24  name: hello-kubernetes
25spec:
26  type: NodePort
27  ports:
28  - port: 80
29    targetPort: 8080
30  selector:
31    app: hello-kubernetes
32---
33apiVersion: apps/v1
34kind: Deployment
35metadata:
36  name: hello-kubernetes
37spec:
38  replicas: 3
39  selector:
40    matchLabels:
41      app: hello-kubernetes
42  template:
43    metadata:
44      labels:
45        app: hello-kubernetes
46    spec:
47      containers:
48      - name: hello-kubernetes
49        image: registry.your_domain/paulbouwer/hello-kubernetes:1.8
50        ports:
51        - containerPort: 8080
52      imagePullSecrets:
53      - name: regcred

首先,您定义了 Hello World 的 Ingress 部署,您将通过 Nginx Ingress Controller 所拥有的 Load Balancer 路由,然后,您定义了一个可以访问部署中创建的 pods 的服务。在实际的部署规格中,您将图像指定为位于您的注册表中,并将imagePullSecrets设置为您在上一步创建的regcred

保存和关闭文件. 要将此部署到您的集群中,请运行以下命令:

1kubectl apply -f hello-world.yaml

您将看到以下输出:

1[secondary_label Output]
2ingress.extensions/hello-kubernetes-ingress created
3service/hello-kubernetes created
4deployment.apps/hello-kubernetes created

您现在可以导航到您的测试域 - 在本教程中第二个 A 记录, k8s-test.your_domain. 您将看到Kubernetes **Hello world!**页面。

Hello World page

Hello World 页面列出了一些环境信息,如 Linux 内核版本和所请求的 pod 的内部 ID. 您还可以通过 Web 界面访问您的空间,以查看您在本教程中工作的图像。

如果您想在测试后删除此 Hello World 部署,请运行以下命令:

1kubectl delete -f hello-world.yaml

在此步骤中,您创建了一个示例的Hello World部署,以测试Kubernetes是否正确从您的私人注册表中提取图像。

结论

您现在已经成功地在您的 DigitalOcean Kubernetes 集群上部署了自己的私人 Docker 注册表,使用 DigitalOcean Spaces 作为底部的存储层。 您可以存储的图像数量没有限制,Spaces 可以无限扩展,同时提供相同的安全性和可靠性。

Published At
Categories with 技术
comments powered by Disqus