部署 Amazon EKS Windows 托管节点组和 Fargate 节点

通过 Windows 容器迁移应用最小化风险和延迟
发布时间:2023 年 11 月 30 日
EKS 集群设置
EKS
Kubernetes
教程
亚马逊云科技
Olawale Olaleye
亚马逊云科技使用经验
200 - 中级
完成所需时间
30 分钟
前提条件

注册 / 登录 亚马逊云科技账户

上次更新时间
2023 年 11 月 30 日

Kubernetes Windows 容器可以帮助企业轻松将现有的 Windows 工作负载迁移到 Amazon EKS。以部署传统的 .NET 单体框架应用程序为例,您需要考虑应用程序与运行环境的依赖问题,进行配置调整,以及执行托管服务器间的数据迁移。这些任务及其他任务会为新部署带来安全风险,并导致软件发布延迟。您可以使用 Kubernetes Windows 容器将现有的传统 .NET 应用程序进行容器化,然后迁移、部署到 Amazon EKS 中。这种方法已经帮助多个组织部署和维护 Windows 应用。使用这种方法,无需手动操作,并且节省时间和费用。应用打包和部署过程全程自动化,这使开发人员有更多时间专注于代码开发,而不是运维任务。

此外,许多公司希望可以通过可靠的方式提高敏捷性,加速上市时间并提高部署速度。Kubernetes Windows 容器的出现使这些成为可能。使用 Kubernetes Windows 容器,您可以采用 GitOps 方法为 Windows 应用构建持续部署管道,将应用部署到 Amazon EKS 中。GitOps 是一种部署管理方法,将应用程序及其基础设施的部署通过 Git 仓库中的声明式描述来实现。

前提条件

开始本教程学习之前,您需要:

  • 安装最新版本的 kubectl。运行以下命令检查您的 kubectl 版本:kubectl version。
  • 安装最新版本的 eksctl。运行以下命令检查您的 eksctl 版本:eksctl info。

概述

您可以使用下面章节提供的 eksctl 集群模板创建一个 Amazon EKS Windows 集群。该集群将混合运行在 EC2 上的 Windows 节点和运行在 Fargate 上的 Linux 节点。集群包含以下组件:

  • 托管节点组:使用 Amazon EKS 托管节点组,您无需单独预配或注册 Amazon EC2 实例来提供运行 Kubernetes 应用所需的计算能力。在 Kubernetes V1.28 中,Windows 节点(和 Pod)兼容的操作系统包括 Windows Server 2019 和 Windows Server 2022。Windows Server 2022 在 Windows Server 2019 的坚实基础上又增加了许多管理和安全方面的创新升级。本次课程学习中,我们将通过eksctl 使用 Amazon EKS 优化后的 Windows Server 2022 完全镜像 WINDOWS_FULL_2022_x86_64 创建一个 Windows 托管节点组.该节点组将提供在集群中运行 Windows 工作负载的计算能力。这个 Amazon EKS 优化镜像基于 Windows Server 2022 创建,并包含 containerd、 kubelet 和 Amazon IAM Authenticator,提供开箱即用的 Amazon EKS 服务。
  • Fargate Profile:Amazon Fargate 是一个适用于 EKS 的计算引擎。启用 Amazon Fargate 后,您无需配置、管理和扩缩容您的 EC2 实例。Fargate 确保可用区扩展的同时,还帮您免去了复杂的 EC2 基础设施管理和实现跨可用区均衡 Replica Service 中的 Pod 负载的负杂工作。每一个运行在 Fargate 上的 Pod 都有对应的 worker 节点。当 Kubernetes Pod 扩缩时,Fargate 自动扩缩 worker 节点。此教程中,我们将使用 Fargate 来提供运行核心集群组件(如 kube-system 命名空间中的 CoreDNS)所需的计算能力。这样,我们就能轻松保证集群中的 CoreDNS Pod 的可用性和弹性。
  • 控制面板日志:您可以启用 Amazon EKS 控制面板日志 功能。该功能直接从 Amazon EKS 控制面板获取审计日志和诊断日志,并提供给 CloudWatch Logs。此教程中,我们已启用了可用 Kubernetes 控制面板组件对应的所有可用的控制日志类型。

要在 Amazon EKS 上运行 Windows 工作负载,您需要一个同时包含 Windows 节点和 Linux 节点的集群。目前,Fargate 上运行的 Amazon EKS Pod 不支持 Windows 容器。因此,Windows 容器必须运行在 Amazon EC2 上。Linux 节点对于集群运行至关重要,它们运行核心集群的组件。因此,对于生产集群,必须使其中的 Linux 节点架构满足高可用需求。

Amazon EKS 集群必须包含一个或多个 Linux 或 Fargate 节点,用于运行只能在 Linux 运行上的核心系统 Pod,如 CoreDNS。尽管如此,企业也希望能利用托管节点组管理 Windows 容器和利用 Fargate 管理 Linux 容器,从而减少管理 Windows EKS 集群的操作消耗。

步骤 1:配置集群

配置满足需求的 Amazon EKS Windows 集群。创建定义 Fargate profile 和 Windows 托管节点组的cluster-config.yaml 文件。

创建集群配置:

复制粘贴以下内容到您的终端上,创建一个 cluster-config.yaml 文件。请务必将 region 值替换为您要使用的服务地域。

cat << EOF > cluster-config.yaml
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
 name: eks-windows-mng-fg-mix
 region: us-west-2
 version: '1.28'
 
managedNodeGroups:
 - name: windows-managed-ng-2022
 amiFamily: WindowsServer2022FullContainer
 instanceType: m5.large
 volumeSize: 50
 minSize: 2
 maxSize: 4
 taints:
 - key: os
 value: "windows"
 effect: NoSchedule

fargateProfiles:
 - name: fargate
 selectors:
 - namespace: default
 - namespace: kube-system

cloudWatch:
 clusterLogging:
 enableTypes: ["*"]
 # Sets the number of days to retain the logs for (see [CloudWatch docs](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutRetentionPolicy.html#API_PutRetentionPolicy_RequestSyntax)).
 # By default, log data is stored in CloudWatch Logs indefinitely.
 logRetentionInDays: 60 
EOF

通过 cluster-config.yaml 文件,我们创建了两个节点池,分别是 Linux 节点池和 Windows 节点池。Linux 节点池由名为 fargate 的 Fargate profile 提供,Windows 节点池由名为 windows-managed-ng-2022 的托管节点组提供。要运行 Windows 容器,就必须在 Windows 节点池中调度。因为我们需要运行 Linux 和 Windows 节点,所以我们在 Windows 托管节点组上配置了 NoSchedule taint,以确保 Linux pod 不会被调度到 Windows 节点上,反之亦然。所有 Linux pod 将会调用到默认的 或 kube-system 命名空间中的 Fargate 节点上。

步骤 2:创建集群

现在,我们已做好创建 Amazon EKS 集群的准备。整个集群创建过程需要几分钟才能完成。如果您想监测集群创建状态,可以登录 Amazon CloudFormation 控制台

运行以下命令,使用 cluster-config.yaml 创建 EKS 集群:

eksctl create cluster -f cluster-config.yaml

创建完成后,输出结果应该如下所示:

2023-11-13 14:19:14 [ℹ] nodegroup "windows-managed-ng-2022" has 2 node(s)
2023-11-13 14:19:14 [ℹ] node "ip-192-168-14-166.us-west-2.compute.internal" is ready
2023-11-13 14:19:14 [ℹ] node "ip-192-168-58-84.us-west-2.compute.internal" is ready
2023-11-13 14:19:15 [✔] EKS cluster "eks-windows-mng-fg-mix" in "us-west-2" region is ready

创建集群的命令运行完成后,运行以下命令检查是否所有的节点都处于 Ready 状态:

kubectl get nodes -o=custom-columns=NODE:.metadata.name,OS-Image:.status.nodeInfo.osImage,OS:.status.nodeInfo.operatingSystem

输出结果应该如下所示:

NODE OS-Image OS
fargate-ip-192-168-114-130.us-west-2.compute.internal Amazon Linux 2 linux
fargate-ip-192-168-146-30.us-west-2.compute.internal Amazon Linux 2 linux
ip-192-168-14-166.us-west-2.compute.internal Windows Server 2022 Datacenter windows
ip-192-168-58-84.us-west-2.compute.internal Windows Server 2022 Datacenter windows

运行以下命令确认核心集群组件:

kubectl get pods -n kube-system -o wide

输出结果应该如下所示:

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-56666498f9-lx8xj 1/1 Running 0 66m 192.168.114.130 fargate-ip-192-168-114-130.us-west-2.compute.internal <none><none>
coredns-56666498f9-xqqlz 1/1 Running 0 66m 192.168.146.30 fargate-ip-192-168-146-30.us-west-2.compute.internal <none><none>

为了确保在发生干扰事件时集群中的 CoreDNS 应用仍能保持高可用,Kubernetes 提供一个叫做 Pod Disruption Budget (PDB) 的功能。创建集群时,自动为 CoreDNS 创建一个 PDB,用于控制集群中可以同时停机的 pod 数量。

运行以下命令检查 PDB 是否存在:

kubectl get PodDisruptionBudget -A

输出结果应该如下所示:

NAMESPACE NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
kube-system coredns N/A 1 1 12m

步骤 3:部署示例 Windows 应用

示例 Windows 应用是一个基于 Internet Information Services (IIS) Web 服务器的基础的前端 Windows Web 应用。其部署清单使用了 IIS 基础镜像。

  • 复制粘贴以下代码内容,创建一个 windows-workload.yaml 文件。

apiVersion: v1
kind: Namespace
metadata:
 labels:
 kubernetes.io/metadata.name: windows
 name: windows
--- 
apiVersion: apps/v1
kind: Deployment
metadata:
 name: windows-server-iis-ltsc2022
 namespace: windows
spec:
 selector:
 matchLabels:
 app: windows-server-iis-ltsc2022
 tier: backend
 track: stable
 replicas: 2
 template:
 metadata:
 labels:
 app: windows-server-iis-ltsc2022
 tier: backend
 track: stable
 spec:
 containers:
 - name: windows-server-iis-ltsc2022
 image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022
 ports:
 - name: http
 containerPort: 80
 imagePullPolicy: IfNotPresent
 command:
 - powershell.exe
 - -command
 - "Add-WindowsFeature Web-Server; Invoke-WebRequest -UseBasicParsing -Uri 'https://dotnetbinaries.blob.core.windows.net/servicemonitor/2.0.1.6/ServiceMonitor.exe' -OutFile 'C:\\ServiceMonitor.exe'; echo '<html><body><br/><br/><center><h1>Amazon EKS cluster with Windows managed nodegroup and Fargate linux nodes!</h1></center></body><html>' > C:\\inetpub\\wwwroot\\iisstart.htm; C:\\ServiceMonitor.exe 'w3svc'; "
 nodeSelector:
 kubernetes.io/os: windows
 tolerations:
 - key: "os"
 operator: "Equal"
 value: "windows"
 effect: "NoSchedule"
---
apiVersion: v1
kind: Service
metadata:
 name: windows-server-iis-ltsc2022-service
 namespace: windows
spec:
 ports:
 - port: 80
 protocol: TCP
 targetPort: 80
 selector:
 app: windows-server-iis-ltsc2022
 tier: backend
 track: stable
 sessionAffinity: None
 type: LoadBalancer
  • 对于调度到 Windows 节点上的 Windows Pod, 需要配置 nodeSelector 和合适的匹配 toleration 以便选择 Windows 节点。我们在 Windows 负载部署清单里配置了 nodeSelector (kubernetes.io/os=windows) 和 toleration (os=windows),以确保 Windows Pod 只会被部署到 Windows 节点上。运行以下命令部署实例应用:
kubectl apply -f windows-workload.yaml
  • 运行以下命令检查 Windows 工作负载部署:
kubectl get pods -o wide -n windows

输出结果应该如下所示:

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
windows-server-iis-ltsc2022-ddd54677b-hsgxk 1/1 Running 0 116s 192.168.4.69 ip-192-168-14-166.us-west-2.compute.internal <none><none>
windows-server-iis-ltsc2022-ddd54677b-hvbqg 1/1 Running 0 116s 192.168.34.153 ip-192-168-58-84.us-west-2.compute.internal <none><none>

我们通过 LoadBalancer 服务类型对外公开了此部署。运行以下命令获取服务 URL:

kubectl get svc -n windows

输出结果应该如下所示:

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
windows-server-iis-ltsc2022-service LoadBalancer 10.100.134.219 af25ec7b2cb504I4c8a36c5cIb189b07-1100871459.us-west-2.elb.amazonaws.com 80:30267/TCP 13m

将 EXTERNAL-IP 对应的 URL 复制到您的浏览器地址栏,您应该能看到一个基础的 HTML 网页。

步骤 4:(可选)在 Fargate 上创建工作负载

如果您想在这个集群中部署一个实例 Linux 工作负载,您需要设置 Fargate profile 配置并指定 kube-system 或默认命令空间。

运行以下命令在默认命名空间中创建一个示例 nginx pod:

kubectl run test --image=nginx

系统需要大约一分钟时间将该 pod 调度到 Fargate 节点上。运行以下命令检查该 pod 是否处于运行状态:

kubectl get pods -o wide

输出结果应该如下所示:

NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test 1/1 Running 0 11m 192.168.103.37 fargate-ip-192-168-103-37.us-west-2.compute.internal <none><none>

清理资源

为避免持续产生费用,建议您删除在学习本教程的过程中创建的资源。运行以下命令删除示例部署:

kubectl delete -f windows-workload.yaml

运行以下命令删除 EKS 集群

eksctl delete cluster -f cluster-config.yaml

删除成功后,输出结果应该如下所示:

2023-11-13 15:27:19 [✔] all cluster resources were deleted

总结

您已成功创建一个包含 Windows 托管节点和 Fargate 节点的 Amazon EKS Windows 集群。使用这样的集群,可以减少您的 Amazon EKS Windows 集群的管理操作任务这个集群能提供部署 Windows 应用所需的基础设施。