平台支持(Platforms Supported)

Kubebuilder 生成的方案默认可在多平台或特定平台运行,取决于你对工作负载的构建与配置方式。本文指导你按需正确配置项目。

概览(Overview)

要支持特定或多种平台,需确保工作负载所用镜像已针对目标平台构建。注意,目标平台未必与开发环境一致,而是你的方案实际运行与发布的目标环境。建议构建多平台镜像,以便在不同操作系统与架构的集群中通用。

如何声明/支持目标平台

以下说明为单平台或多平台/多架构提供支持需要做的工作。

1)构建支持目标平台的工作负载镜像

用于 Pod/Deployment 的镜像必须支持目标平台。可用 docker manifest inspect 查看镜像的多平台 ManifestList,例如:

$ docker manifest inspect myregistry/example/myimage:v0.0.1
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 739,
         "digest": "sha256:a274a1a2af811a1daf3fd6b48ff3d08feb757c2c3f3e98c59c7f85e550a99a32",
         "platform": {
            "architecture": "arm64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 739,
         "digest": "sha256:d801c41875f12ffd8211fffef2b3a3d1a301d99f149488d31f245676fa8bc5d9",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 739,
         "digest": "sha256:f4423c8667edb5372fb0eafb6ec599bae8212e75b87f67da3286f0291b4c8732",
         "platform": {
            "architecture": "s390x",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 739,
         "digest": "sha256:621288f6573c012d7cf6642f6d9ab20dbaa35de3be6ac2c7a718257ec3aff333",
         "platform": {
            "architecture": "ppc64le",
            "os": "linux"
         }
      },
   ]
}

2)(最佳实践)配置与平台匹配的 nodeAffinity 表达式

Kubernetes 提供了 nodeAffinity 机制,用于限定 Pod 可调度到的节点集合。在多平台(异构)集群中,这对于保证正确的调度行为尤为重要。

Kubernetes 清单示例

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/arch
          operator: In
          values:
          - amd64
          - arm64
          - ppc64le
          - s390x
        - key: kubernetes.io/os
            operator: In
            values:
              - linux

Golang 示例

Template: corev1.PodTemplateSpec{
    ...
    Spec: corev1.PodSpec{
        Affinity: &corev1.Affinity{
            NodeAffinity: &corev1.NodeAffinity{
                RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
                    NodeSelectorTerms: []corev1.NodeSelectorTerm{
                        {
                            MatchExpressions: []corev1.NodeSelectorRequirement{
                                {
                                    Key:      "kubernetes.io/arch",
                                    Operator: "In",
                                    Values:   []string{"amd64"},
                                },
                                {
                                    Key:      "kubernetes.io/os",
                                    Operator: "In",
                                    Values:   []string{"linux"},
                                },
                            },
                        },
                    },
                },
            },
        },
        SecurityContext: &corev1.PodSecurityContext{
            ...
        },
        Containers: []corev1.Container{{
            ...
        }},
    },

产出支持多平台的项目

可使用 docker buildx 结合仿真(QEMU)来构建 manager 的多平台镜像。Kubebuilder 新版本脚手架默认包含 docker-buildx 目标。

使用示例

$ make docker-buildx IMG=myregistry/myoperator:v0.0.1

注意:需确保项目中所有镜像与工作负载均满足上述多平台支持要求,并为所有工作负载正确配置 nodeAffinity。因此请在 config/manager/manager.yaml 中取消注释如下示例:

# TODO(user): Uncomment the following code to configure the nodeAffinity expression
# according to the platforms which are supported by your solution.
# It is considered best practice to support multiple architectures. You can
# build your manager image using the makefile target docker-buildx.
# affinity:
#   nodeAffinity:
#     requiredDuringSchedulingIgnoredDuringExecution:
#       nodeSelectorTerms:
#         - matchExpressions:
#           - key: kubernetes.io/arch
#             operator: In
#             values:
#               - amd64
#               - arm64
#               - ppc64le
#               - s390x
#           - key: kubernetes.io/os
#             operator: In
#             values:
#               - linux

默认会创建哪些(工作负载)镜像?

Projects created with the Kubebuilder CLI have two workloads which are:

Manager

运行 manager 的容器定义在 config/manager/manager.yaml。该镜像由脚手架生成的 Dockerfile 构建,包含本项目的二进制,默认通过 go build -a -o manager main.go 生成。

注意:执行 make docker-buildmake docker-build IMG=myregistry/myprojectname:<tag> 时,会在本机构建镜像,其平台通常为 linux/amd64 或 linux/arm64。