

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 运行异构工作负载
<a name="windows-scheduling"></a>

Kubernetes 支持异构集群，你可以在同一个集群中混合使用 Linux 和 Windows 节点。在该集群中，你可以混合使用在 Linux 上运行的 Pod 和在 Windows 上运行的 Pod。你甚至可以在同一个集群中运行多个版本的 Windows。但是，在做出此决定时，需要考虑几个因素（如下所述）。

## 分配 PODs 给节点最佳实践
<a name="_assigning_pods_to_nodes_best_practices"></a>

为了将 Linux 和 Windows 工作负载保留在各自的操作系统特定节点上，您需要使用节点选择器和污点/容忍度的某种组合。在异构环境中调度工作负载的主要目标是避免破坏与现有 Linux 工作负载的兼容性。

## 确保特定于操作系统的工作负载落在相应的容器主机上
<a name="_ensuring_os_specific_workloads_land_on_the_appropriate_container_host"></a>

用户可以确保可以使用 NodeSelectors 在相应的主机上调度 Windows 容器。如今，所有 Kubernetes 节点都有以下默认标签：

```
kubernetes.io/os = [windows|linux]
kubernetes.io/arch = [amd64|arm64|...]
```

如果 Pod 规范不包含类似 NodeSelector 的 NodeSelector`"kubernetes.io/os": windows`，则可以在任何主机（Windows 或 Linux）上调度该 Pod。这可能会出现问题，因为 Windows 容器只能在 Windows 上运行，而 Linux 容器只能在 Linux 上运行。

在企业环境中，有大量预先存在的 Linux 容器部署以及 off-the-shelf配置生态系统（例如 Helm charts）的情况并不少见。在这些情况下，您可能对更改部署的 NodeSelectors 犹豫不决。**另一种方法是使用 Taints。**

例如：`--register-with-taints='os=windows:NoSchedule'`

如果你使用的是 EKS，eksctl 提供了通过 ClusterConfig 应用污点的方法：

```
NodeGroups:
  - name: windows-ng
    amiFamily: WindowsServer2022FullContainer
    ...
    labels:
      nodeclass: windows2022
    taints:
      os: "windows:NoSchedule"
```

为所有 Windows 节点添加污点，调度器不会在这些节点上调度 pod，除非它们能容忍污点。Pod 清单示例：

```
nodeSelector:
    kubernetes.io/os: windows
tolerations:
    - key: "os"
      operator: "Equal"
      value: "windows"
      effect: "NoSchedule"
```

## 在同一个集群中处理多个 Windows 构建
<a name="_handling_multiple_windows_build_in_the_same_cluster"></a>

每个 Pod 使用的 Windows 容器基础镜像必须与节点相同的内核编译版本相匹配。**如果你想在同一个集群中使用多个 Windows Server 版本，那么你应该设置额外的节点标签、NodeSelectors 或者利用一个名为 windows-build 的标签。**

Kubernetes 1.17 会自动添加一个新标签 node.kuber **netes.io/windows-build，以简化对同一个集群中多个 Windows** 版本的管理。如果你运行的是旧版本，则建议手动将此标签添加到 Windows 节点。

此标签反映了兼容性需要匹配的 Windows 主版本、次要版本号和内部版本号。以下是当今每个 Windows 服务器版本使用的值。

值得注意的是，Windows Server 正在转向长期服务渠道 (LTSC) 作为主要发布渠道。Windows 服务器半年度频道 (SAC) 已于 2022 年 8 月 9 日停用。未来不会有 Windows Server 的 SAC 版本。


| 产品名称 | 内部版本号 | 
| --- | --- | 
|  服务器已满 2022 LTSC  |  10.0.20348  | 
|  2019 年服务器核心 LTSC  |  10.0.17763  | 

可以通过以下命令检查操作系统版本号：

```
kubectl get nodes -o wide
```

内核版本输出与 Windows 操作系统的内部版本相匹配。

```
NAME                          STATUS   ROLES    AGE   VERSION                INTERNAL-IP   EXTERNAL-IP     OS-IMAGE                         KERNEL-VERSION                  CONTAINER-RUNTIME
ip-10-10-2-235.ec2.internal   Ready    <none>   23m   v1.24.7-eks-fb459a0    10.10.2.235   3.236.30.157    Windows Server 2022 Datacenter   10.0.20348.1607                 containerd://1.6.6
ip-10-10-31-27.ec2.internal   Ready    <none>   23m   v1.24.7-eks-fb459a0    10.10.31.27   44.204.218.24   Windows Server 2019 Datacenter   10.0.17763.4131                 containerd://1.6.6
ip-10-10-7-54.ec2.internal    Ready    <none>   31m   v1.24.11-eks-a59e1f0   10.10.7.54    3.227.8.172     Amazon Linux 2                   5.10.173-154.642.amzn2.x86_64   containerd://1.6.19
```

以下示例将额外的 NodeSelector 应用于容器清单，以便在运行不同的 Windows 节点组操作系统版本时匹配正确的 Windows-build 版本。

```
nodeSelector:
    kubernetes.io/os: windows
    node.kubernetes.io/windows-build: '10.0.20348'
tolerations:
    - key: "os"
    operator: "Equal"
    value: "windows"
    effect: "NoSchedule"
```

## Pod 清单中的简 NodeSelector 化和容忍度使用 RuntimeClass
<a name="_simplifying_nodeselector_and_toleration_in_pod_manifests_using_runtimeclass"></a>

您还可以利用 RuntimeClass 来简化使用污点和容差的过程。这可以通过创建一个用于封装这些污点和容忍度的 RuntimeClass 对象来实现。

 RuntimeClass 通过运行以下清单来创建：

```
apiVersion: node.k8s.io/v1beta1
kind: RuntimeClass
metadata:
  name: windows-2022
handler: 'docker'
scheduling:
  nodeSelector:
    kubernetes.io/os: 'windows'
    kubernetes.io/arch: 'amd64'
    node.kubernetes.io/windows-build: '10.0.20348'
  tolerations:
  - effect: NoSchedule
    key: os
    operator: Equal
    value: "windows"
```

创建 Runtimeclass 后，在 Pod 清单上将其作为规范进行分配：

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: iis-2022
  labels:
    app: iis-2022
spec:
  replicas: 1
  template:
    metadata:
      name: iis-2022
      labels:
        app: iis-2022
    spec:
      runtimeClassName: windows-2022
      containers:
      - name: iis
```

## 托管节点组 Support
<a name="_managed_node_group_support"></a>

为了帮助客户以更简化的方式运行他们的 Windows 应用程序，AWS 于 2022 年 12 月 15 日启动了对亚马逊 [EKS 托管节点组 (MNG) 支持 Windows 容器的](https://aws.amazon.com/about-aws/whats-new/2022/12/amazon-eks-automated-provisioning-lifecycle-management-windows-containers/)支持。为了帮助协调运营团队，使用与 [Linux](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) 相同的工作流程和工具启用 [Windows MNGs](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) MNGs。支持 Windows Server 2019 和 2022 的完整版和核心 AMI（亚马逊机器映像）系列版本。

托管节点组 (MNG) 支持以下 AMI 系列。


| AMI 家族 | 
| --- | 
|  Windows\$1core\$12019\$1x86\$164  | 
|  Windows\$1full\$12019\$1x86\$164  | 
|  Windows\$1core\$12022\$1x86\$164  | 
|  Windows\$1full\$12022\$1x86\$164  | 

## 其他文档
<a name="_additional_documentations"></a>

AWS 官方文档：https://docs.aws.amazon.com/eks/latest/userguide/windows-support.html

要更好地了解 Pod Networking (CNI) 的工作原理，请查看以下链接：-networking.html https://docs.aws.amazon.com/eks/ latest/userguide/pod

关于在 EKS 上部署适用于 Windows 的托管节点组的 AWS 博客：conta https://aws.amazon.com/blogs/ iners/-/deploying-amazon-eks-windowsmanaged-node-groups