如何在 Kubernetes 部署中使用动态/可变镜像标签?

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

在我们的项目中,也使用 Kustomize,我们的基本

deployment.yaml
文件如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:IMAGE_TAG # <------------------------------
        ports:
        - containerPort: 80

然后我们使用

sed
IMAGE_TAG
替换为我们要部署的镜像版本。

是否有更复杂的方法来执行此操作,而不是使用

sed
编辑文本 yaml 文件?

kubernetes google-kubernetes-engine kustomize
4个回答
12
投票

为此有一个特定的转换器,称为“图像转换器”。 您可以保持部署不变,带或不带标签: apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80

然后在您的自定义文件中:

apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployment.yaml images: - name: nginx newTag: MYNEWTAG

请记住,这将替换 kustomization 文件中包含的所有资源的所有 nginx 映像的标签。如果您需要运行多个版本的 nginx,您可以用占位符替换部署中的映像名称,并在转换器中使用不同的条目。


8
投票

更新:正如DrDol提到的,以下内容依赖于已被证明是错误的行为(请参阅此问题)。因此,我推荐一种替代方案。例如,Skaffold 解决了这个问题,而且总体上还改进了 Kubernetes 工作流程。 可以使用环境变量中的

图像标签

,而无需为每个不同的标签编辑文件。如果您的图像标签需要变化而不更改版本控制文件,这非常有用。 标准

kubectl

足以达到此目的。简而言之,使用

configMapGenerator
 以及从环境变量填充的数据。然后添加引用此 ConfigMap 数据的 
replacements
 来替换相关图像标签。
示例

继续您的示例

deployment.yaml

,您可以在同一文件夹中拥有一个

kustomization.yaml
文件,如下所示:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# Generate a ConfigMap based on the environment variables in the file `.env`.
configMapGenerator:
  - name: my-config-map
    envs:
      - .env

replacements:
  - source:
      # Replace any matches by the value of environment variable `MY_IMAGE_TAG`.
      kind: ConfigMap
      name: my-config-map
      fieldPath: data.MY_IMAGE_TAG
    targets:
      - select:
          # In each Deployment resource …
          kind: Deployment
        fieldPaths:
          # … match the image of container `nginx` …
          - spec.template.spec.containers.[name=nginx].image
        options:
          # … but replace only the second part (image tag) when split by ":".
          delimiter: ":"
          index: 1

resources:
  - deployment.yaml

在同一个文件夹中,您需要一个仅包含环境变量名称的文件
.env

(注意:只是名称,没有分配值):

MY_IMAGE_TAG

现在本地环境中的
MY_IMAGE_TAG

在运行

kubectl kustomize
kubectl apply --kustomize
等时会被集成为图像标签
演示:

MY_IMAGE_TAG=foobar kubectl kustomize .

这将打印生成的图像标签,即所需的
foobar

# …
spec:
  # …
  template:
    # …
    spec:
      containers:
        - image: nginx:foobar
          name: nginx
          ports:
            - containerPort: 80

替代品

请记住

configMapGenerator 文档中的以下内容

注意:

建议谨慎使用本地环境变量填充功能 - 带补丁的覆盖通常更易于维护。当无法轻松预测时,从环境中设置值可能会很有用,例如 git SHA。

如果您只是想在多个文件之间共享
固定

图像标签,请参阅已经建议的images转换器


1
投票

可以动态地将图像转换添加到您的

kustmization

文件中。只需使用

kustomization.yaml
签入目录并致电
kustomize edit set image nginx:your_new_tag

这将导致您的 
kustomization

发生以下变化:

images:
- name: nginx
  newTag: your_new_tag

尝试此解决方案时遇到的唯一问题是,我设法使其仅适用于独立的 
kustomize

,但不适用于

kubectl kustomize
。当前适合我的版本是
kustomize/v4.5.5
    


0
投票
deployment.yaml

并使用

envsubst
命令。
示例:

apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:$IMAGE_TAG ports: - containerPort: 80

IMAGE_TAG=my_image_tag envsubst '${IMAGE_TAG}' < deployment.yaml > final_deployment.yaml
© www.soinside.com 2019 - 2024. All rights reserved.