在多个注册中心托管 Docker 镜像,但以相同的方式引用它们,例如在 k8s 部署中

在多个注册中心托管 Docker 镜像,但以相同的方式引用它们,例如在 k8s 部署中

自从我开始使用docker以来,就有一个问题困扰着我,到目前为止我还没有得到很好的答案。

假设我有一个指定 k8s 部署的 .yaml 文件。我们在本地构建服务器上构建我们的 docker 镜像,并将它们推送到本地注册表(例如 registry.mycompany.com),该注册表只能在我们本地公司网络中访问。因此,在我的 .yaml 中,我将使用“image:registry.mycompany.com/myrepo/myimage:1.0”引用该镜像。

现在,当我在本地 k8s 集群上部署它时,它可以正常工作,因为域名已解析并且可以提取映像。现在我想在任何云中部署相同的内容。好吧,它无法工作,因为注册表不可用。如果我想在我的某个客户处部署相同的 .yaml,情况也是如此,因为他们出于某种原因也无法访问我的本地注册表。

这种事情通常如何解决?现在,我在客户处或云帐户中设置另一个注册表,重新标记我的所有图像并将它们推送到该注册表,并在客户处或云中部署时更改 .yaml 中的所有图像引用。因此必须维护大量 99% 相同的文件集。这不是应该的工作方式,对吧?

我的“愿望”是,我可以只指定镜像名称和标签“myimage:1.0”,如果 k8s 集群可以找到镜像并提取它,它就会检查所有可用的注册表。但我也知道没有“知名注册表列表”,你要么在镜像名称中指定注册表,要么省略它,docker hub 将被查询。然而,如果我可以只指定,那就太酷了

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: MyDeployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: myimage
    spec:
      containers:
        - name: myimage
          image: 'myimage:1.0'
          ports: []

以及注册表列表:

registries:
    - registry.mycompany.com
    - registry.cloud.com
    - registry.localcustomer.com

但没有那样的东西,对吧?

我能想到的唯一其他解决方案是将所有内容构建到 Helm Charts 中,使图像的第一部分引用变量,并将注册表作为变量传递给图表。

欢迎提供任何想法和信息。提前致谢 :)

答案1

有一些解决方法可以实现您在问题中描述的结果:

  • Helm Chart
  • Kustomize
  • 註冊

Helm Chart

正如你在问题中所说的那样:

我能想到的唯一其他解决方案是将所有内容构建到 Helm Charts 中,使图像的第一部分引用变量,并将注册表作为变量传递给图表。

从主观上来说,这是指定存储库最方便的方法Deployment

它的示例如下:

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ubuntu
spec:
  selector:
    matchLabels:
      app: ubuntu
  replicas: 1
  template:
    metadata:
      labels:
        app: ubuntu
    spec:
      containers:
      - name: "{{ .Values.image.repo }}{{ .Values.image.name }}:{{ .Values.image.tag }}"  
        image: 
        command:
        - sleep 
        - "infinity"

内部的值template可以通过以下方式提供:

  • values.yaml文件:
image: 
  repo: gcr.io/ # <-- only an example
  name: ubuntu
  tag: latest
  • $ helm命令如下:

$ helm install ubuntu . --set=image.repo=eu.gcr.io/

一个提示!

指定--set已存在值的参数values.yaml将会覆盖它(在此示例中)!


Kustomize

您还可以使用各自的存储库和图像来kustomize“渲染” 。Deployment

以下博客文章对如何做到这一点进行了相当详细的解释:

此类解决方案的示例(通过以下链接)可以归结为:

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sl-demo-app
spec:
  selector:
    matchLabels:
      app: sl-demo-app
  template:
    metadata:
      labels:
        app: sl-demo-app
    spec:
      containers:
      - name: app
        image: foo/bar:latest
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP

custom-image.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sl-demo-app
spec:
  template:
    spec:
      containers:
        - name: app # IMPORTANT 
          image: eu.gcr.io/ubuntu:latest

kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml

patchesStrategicMerge:
- custom-image.yaml

运行上述示例后:

  • kustomize build

您应该看到图像的变化:

  • 从:image: foo/bar:latest
  • 到:image: eu.gcr.io/ubuntu:latest

你也可以看看这个 StackOverflow 答案:


註冊

您还可以查看注册表项目,例如港口

你可以在他们的 github 页面上阅读:

Harbor 是一个开源的可信云原生注册中心项目,用于存储、签名和扫描内容。Harbor 通过添加用户通常需要的功能(例如安全性、身份和管理)扩展了开源 Docker 发行版。

特征

  • 云原生注册中心:Harbor 支持容器镜像和 Helm 图表,可作为容器运行时和编排平台等云原生环境的注册中心。

  • 基于角色的访问控制:用户通过‘项目’访问不同的存储库,并且用户可以对项目下的图像或Helm图表拥有不同的权限。

  • 基于策略的复制:可以使用过滤器(存储库、标记和标签)根据策略在多个注册表实例之间复制(同步)图像和图表。如果遇到任何错误,Harbor 会自动重试复制。这可用于协助负载平衡、实现高可用性,并促进混合和多云场景中的多数据中心部署。

...

--Github.com: Goharbor:港口

有了它你可以:


除此之外,您还可以查看如下所示的 Docker Registry 代理:


其他资源:

相关内容