使用 kustomize 图像转换器为所有图像添加注册表前缀

Cra*_*ger 5 kubernetes kustomize

将 Kubernetes 清单部署到集群时的一个常见要求是为容器名称添加镜像允许镜像的可信注册表前缀。通常与准入控制器一起使用。

有没有一种明智的方法可以使用 Kustomize 来执行此操作,而不必在kustomization.yaml images:转换器节中按名称列出每个图像?

鉴于这种kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - "https://github.com/prometheus-operator/kube-prometheus"
Run Code Online (Sandbox Code Playgroud)

如果我想为其引用的所有图像添加前缀,mytrusted.registry/我需要将其附加到我的kustomization.yaml

images:
- name: grafana/grafana
  newName: mytrusted.registry/grafana/grafana
- name: jimmidyson/configmap-reload
  newName: mytrusted.registry/jimmidyson/configmap-reload
- name: k8s.gcr.io/kube-state-metrics/kube-state-metrics
  newName: mytrusted.registry/k8s.gcr.io/kube-state-metrics/kube-state-metrics
- name: k8s.gcr.io/prometheus-adapter/prometheus-adapter
  newName: mytrusted.registry/k8s.gcr.io/prometheus-adapter/prometheus-adapter
- name: quay.io/brancz/kube-rbac-proxy
  newName: mytrusted.registry/quay.io/brancz/kube-rbac-proxy
- name: quay.io/prometheus/alertmanager
  newName: mytrusted.registry/quay.io/prometheus/alertmanager
- name: quay.io/prometheus/blackbox-exporter
  newName: mytrusted.registry/quay.io/prometheus/blackbox-exporter
- name: quay.io/prometheus/node-exporter
  newName: mytrusted.registry/quay.io/prometheus/node-exporter
- name: quay.io/prometheus-operator/prometheus-operator
  newName: mytrusted.registry/quay.io/prometheus-operator/prometheus-operator
- name: quay.io/prometheus/prometheus
  newName: mytrusted.registry/quay.io/prometheus/prometheus
Run Code Online (Sandbox Code Playgroud)

这是我用这个腐烂的、脆弱的怪物生成的(如果你的容器是通过哈希指定的,或者你的注册表前缀中有一个端口,它就会崩溃):

kustomize build | \
  grep 'image:' | \
  awk '$2 != "" { print $2}' | \
  sort -u | \
  cut -d : -f 1 | \
  jq --raw-input '{ name: ., newName: ("mytrusted.registry/" + .) }' | \
  faq -s -fjson -oyaml '{ images: .}' 
Run Code Online (Sandbox Code Playgroud)

(请注意,上述内容也不会完全起作用,因为 Kustomize 无法识别PodTemplates 之外的图像,例如 或 中的图像kind: Alertmanager spec.imagekind: Prometheus spec.image它仍然比当前情况更好)。

我想要的是能够在图像转换器中表达这一点,而无需生成和维护图像列表,例如虚数,不起作用示例

images:
  - name: "(*)"
    newName: "mytrusted.registry/$1"
Run Code Online (Sandbox Code Playgroud)

即使用捕获组。或者功能类似的东西,比如图像转换器“prependName”选项或类似的东西。

这肯定是一个常见的问题,但我一生都找不到一种完善的方法,这是 k8s 世界中的惯例。只是很多 DIY 脆弱的 hack。

小智 4

这个答案可能已经太晚了,无法帮助最初的提问者,但也许它会帮助像我一样通过谷歌偶然发现这个问题的其他人。

Kustomize 有一个内置功能PrefixTransformer,可以为所有图像添加前缀,甚至可以为规范中的任意字段添加前缀。

image-prefix.yaml创建一个包含以下内容的文件:

apiVersion: builtin
kind: PrefixTransformer
metadata:
  name: image-prefix

prefix: mytrusted.registry/

fieldSpecs:
- path: spec/template/spec/containers/image
- path: spec/template/spec/initContainers/image
- path: spec/image  # for kind Prometheus and Alertmanager
Run Code Online (Sandbox Code Playgroud)

然后将此变压器添加到您的变压器中,kustomization.yaml如下所示:

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

resources:
- "https://github.com/prometheus-operator/kube-prometheus"

transformers:
- image-prefix.yaml
Run Code Online (Sandbox Code Playgroud)

应该可以做到这一点。

当你构建这个时,你应该看到你的前缀自动添加到所有图像中:

$ kubectl kustomize | grep image:
...
        image: mytrusted.registry/quay.io/prometheus/blackbox-exporter:v0.22.0
        image: mytrusted.registry/jimmidyson/configmap-reload:v0.5.0
        image: mytrusted.registry/quay.io/brancz/kube-rbac-proxy:v0.13.0
        image: mytrusted.registry/grafana/grafana:my-tag
        image: mytrusted.registry/k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.6.0
...
Run Code Online (Sandbox Code Playgroud)

我使用kubectl1.25 以及与其捆绑的 Kustomize 版本对此进行了测试:

$ kubectl version --short --client
...
Client Version: v1.25.0
Kustomize Version: v4.5.7
Run Code Online (Sandbox Code Playgroud)

PrefixTransformer您可以使用 GVK(组/版本/种类)三元组进一步限制。例如,如果出于某种原因您只想将映像前缀应用于 Deployment,而不应用于 DaemonSet、StatefulSet 或其他,则可以在文件中添加如下内容image-prefix.yaml

fieldSpecs:
- kind: Deployment
  path: spec/template/spec/containers/image
- kind: Deployment
  path: spec/template/spec/initContainers/image
Run Code Online (Sandbox Code Playgroud)

另请注意,ImageTransformer运行在 之前PrefixTransformer,因此如果您想覆盖 中特定图像的标签kustomization.yaml,您应该使用不带前缀的原始图像名称:

images:
- name: grafana/grafana
  newTag: my-tag
Run Code Online (Sandbox Code Playgroud)

不幸的是,PrefixTransformer我找不到明确的文档,否则我会在此处链接它。我通过挖掘 Kustomize 源代码发现了这一切。

还有很多其他可能感兴趣的内置转换器,您可以通过查看*_test.go此处每个子文件夹中的文件来收集它们的用法:

https://github.com/kubernetes-sigs/kustomize/tree/master/plugin/builtin