如何为 Kubernetes yaml 中的所有图像获取已解析的 sha 摘要?

How to get resolved sha digest for all images within Kubernetes yaml?

Docker 图像标签是可变的,因为 image:latestimage:1.0 都可以指向 image@sha256:.....,但是当版本 1.1 发布时,image:latest 存储在注册表中的可以指向具有不同 sha 摘要的图像。现在拉取带有特定标签的镜像并不意味着下次会拉取相同的镜像。

如果 Kubernetes YAMl 资源定义通过标签(而不是摘要)引用图像,在部署资源定义之前,是否有一种方法可以确定每个图像实际解析的 sha 摘要?使用 kustomizekubectl 是否支持此功能?

用例想要在部署到另一个环境之前确定在一个环境中实际部署了什么(我想对已解析的资源定义进行哈希处理,然后可以使用它来了解是否 image:1.0部署到 PROD 指的是部署到 UAT 的同一个 image:1.0

是否有任何工具可用于支持此功能?

例如,给定以下 YAML,是否有一种方法可以将所有图像替换为已解析的摘要?

apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
    - name: image1
      image: image1:1.1
      command:
        - /bin/sh -c some command
    - name: image2
      image: image2:2.2
      command:
        - /bin/sh -c some other command

要得到这样的东西:

apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
    - name: image1
      image: image1@sha:....
      command:
        - /bin/sh -c some command
    - name: image2
      image: image2@sha:....
      command:
        - /bin/sh -c some other command

我希望能够通过工具执行类似 pipe yaml(可能来自 catkustomizekubectl ... --dry-run)的操作,然后传递给 kubectl apply -f:

cat mydeployment.yaml | some-tool | kubectl apply -f -

编辑:

背景是需要能够向 auditors/regulators 证明即将部署到一个环境 (PROD) 的 正是 已成功部署到另一个环境(UAT)。我想在部署模板中使用普通标签,并在部署到 UAT 时,拍摄模板快照,并将标签替换为已解析图像的摘要。该快照将是部署的内容(通过 kubectl 或类似方式)。部署到 PROD 时,将使用相同的快照。

is there a means of determining what sha digest each image will actually resolve to, before the resource definition is deployed?

不,在您描述的情况下,它可能因节点而异。 Deployment 将创建一定数量的 Pods,每个 Pod 将被安排在某个节点上,并且那里的 Kubelet 只会在没有带有该标签的东西时拉取图像。如果你有两个副本,并且你已经更改了标签指向的图像,那么在节点 A 上它可以使用已经存在的旧图像,但是在没有图像的节点 B 上,它将拉取并获取较新的版本。

此处的最佳做法是避免更改标记指向的图像。为来自 CI 系统的每个构建提供一个唯一的标签(例如日期戳或源代码控制提交 ID),并在您的 Kubernetes 对象规范中使用它。这样就完全避免了这个问题。

解决方法是设置

imagePullPolicy: Always

在您的 pod 规范中,这将强制节点拉取更新的版本,但在大多数情况下这是不必要的开销。

此工具正是您所需要的支持...

kbld: https://get-kbld.io/

Resolves name-tag pair reference (nginx:1.17) into digest reference (index.docker.io/library/nginx@sha256:2539d4344...)

Looks 与 Kustomize 甚至 Helm 等模板工具集成得很好

您可以使用此命令查看所有容器使用的信息。这将列出所有名称空间、pod 名称、容器映像名称和映像的 sha256。

kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.namespace}{","}{.metadata.name}{","}{range .status.containerStatuses[*]}{.image}{", "}{.imageID}{", "}{end}{end}' | sort

这是 google 人在 k8s-digester 上发表的另一篇文章。从某种意义上说,它与主要关注集群端更改(通过 Adm Controller)有点不同,尽管客户端 KRM 功能似乎也是可能的。

总体而言,kbld 似乎更多是关于您的 cli/CICD/orchestration 的开发经验和采用,而 k8s-digester 更多是关于集群端的管理。