使用 Amazon EKS 容器组身份和 KEDA 在 Amazon EKS 中设置事件驱动的自动扩缩
Dipen Desai、Abhay Diwan、Kamal Joshi 和 Mahendra Revanasiddappa,Amazon Web Services
摘要
诸如 Amazon Elastic Kubernetes Service(Amazon EKS)之类的编排平台简化了基于容器的应用程序的生命周期管理。这有助于组织专注于构建、保护、操作和维护基于容器的应用程序。随着事件驱动的部署变得越来越普遍,组织也越来越频繁地根据各种事件源扩展 Kubernetes 部署。将这种方法与自动扩缩相结合后,通过提供按需计算资源和针对应用程序逻辑量身定制的高效扩缩,即可实现成本的大幅节省。
KEDA 是一款基于 Kubernetes 的事件驱动型自动扩缩器。KEDA 可帮助您根据需要处理的事件数量来扩缩 Kubernetes 中的任何容器。它是轻量级的,并且可以与任何 Kubernetes 集群集成。这款扩缩器还可与标准的 Kubernetes 组件,例如水平容器组(pod)自动扩缩(HPA),搭配使用。KEDA 还提供 TriggerAuthentication 功能,可帮助您委派身份验证。它允许您描述与 ScaledObject 和部署容器分开的身份验证参数。
AWS 提供了可支持各种 Kubernetes 部署选项的 AWS Identity and Access Management(IAM)角色,包括 Amazon EKS、Amazon EKS Anywhere、AWS 云端 Red Hat OpenShift 服务(ROSA)和 Amazon Elastic Compute Cloud(Amazon EC2)上的自管理 Kubernetes 集群。这些角色使用 IAM 构造,例如 OpenID Connect(OIDC)身份提供者和 IAM 信任策略,在不同的环境中运行,而无需直接依赖 Amazon EKS 服务或 API。有关更多信息,请参阅 Amazon EKS 文档中的服务账户的 IAM 角色。
Amazon EKS 容器组身份可简化 Kubernetes 服务账户在不需要 OIDC 提供商的情况下代入 IAM 角色的流程。因此,能够管理应用程序凭证。您可以将 IAM 角色与 Kubernetes 服务账户关联并配置容器组(pod)来使用服务账户,而不是创建 AWS 凭证并将其分配到容器或使用 Amazon EC2 实例的角色。这可以帮助您跨多个集群使用 IAM 角色,并允许在 IAM 角色之间重复使用权限策略,从而简化策略管理。
通过使用 Amazon EKS 容器组身份实施 KEDA,企业可以实现高效的事件驱动型自动扩缩和简化的凭证管理。应用程序可根据需求进行扩缩,从而优化资源利用率以及降低成本。
此模式可以帮助您将 Amazon EKS 容器组身份与 KEDA 进行集成。它展示了如何使用 keda-operator 服务账户以及通过 TriggerAuthentication 委派身份验证。此模式还描述了如何建立 KEDA 运算符的 IAM 角色和应用程序的 IAM 角色之间的信任关系。这种信任关系允许 KEDA 监控事件队列中的消息并调整目标 Kubernetes 对象的扩缩。
先决条件和限制
先决条件
AWS Command Line Interface(AWS CLI)2.13.17 或更高版本,已安装
Python 3.11.5 或更高版本,已安装
适用于 Python (Boto3) 的 AWS SDK 版本 1.34.135 或更高版本,已安装
Helm 版本 3.12.3 或更高版本,已安装
kubectl 版本 1.25.1 或更高版本,已安装。
Docker Engine 版本 26.1.1 或更高版本,已安装
Amazon EKS 集群版本 1.24 或更高版本,已创建
创建 Amazon EKS 容器组身份代理的先决条件,已满足
限制
架构
在此模式中,您将创建以下 AWS 资源:
Amazon Elastic Container Registry(Amazon ECR)存储库 – 在此模式中,此存储库名为 keda-pod-identity-registry。此私有存储库可用于存储示例应用程序的 Docker 映像。
Amazon Simple Queue Service(Amazon SQS)队列 – 在此模式中,此队列名为 event-messages-queue。队列充当消息缓冲区,可用于收集和存储传入的消息。KEDA 监控队列指标,例如消息计数或队列长度,并根据这些指标自动扩缩应用程序。
应用程序的 IAM 角色 – 在此模式中,此角色名为 keda-identity。keda-operator 角色会代入此角色。此角色允许访问 Amazon SQS 队列。
KEDA 运算符的 IAM 角色 – 在此模式中,此角色名为 keda-operator。KEDA 运算符使用此角色进行必要的 AWS API 调用。此角色具有代入 keda-identity 角色的权限。由于 keda-operator 和 keda-identity 角色之间存有信任关系,keda-operator 角色具有 Amazon SQS 权限。
通过 TriggerAuthentication 和 ScaledObject Kubernetes 自定义资源,运算符会使用 keda-identity 角色与 Amazon SQS 队列连接。根据队列大小,KEDA 会自动扩缩应用程序部署。它会根据队列中未读消息的数量,每 5 条新增 1 条。在默认配置中,如果 Amazon SQS 队列中没有未读消息,则应用程序会缩减到 0 个容器组(pod)。KEDA 运算符按照您指定的时间间隔监控队列。
下图显示了您如何使用 Amazon EKS 容器组身份为 keda-operator 角色提供对 Amazon SQS 队列的安全访问权限。
下图显示了如下工作流:
您在 Amazon EKS 集群中安装 Amazon EKS 容器组身份代理。
您在 Amazon EKS 集群的 KEDA 命名空间中部署 KEDA 运算符。
您可在目标 AWS 账户中创建 keda-operator 和 keda-identity IAM 角色。
建立 IAM 角色之间的信任关系。
您在 security 命名空间中部署应用程序。
KEDA 运算符将对 Amazon SQS 队列中的消息进行轮询。
KEDA 启动 HPA,而后者会根据队列大小自动扩缩应用程序。
AWS 服务
其他工具
代码存储库
此模式的代码可在 GitHub 使用 EKS 容器组身份和 KEDA 的事件驱动型自动扩缩存储库中找到。
最佳实践
我们建议您遵循以下最佳实践:
操作说明
| 任务 | 描述 | 所需技能 |
|---|
创建 KEDA 运算符的 IAM 角色。 | 登录 AWS 管理控制台,然后打开 IAM 控制台。 在导航窗格中,选择角色。 选择创建角色。 选择 Custom trust policy(自定义信任策略)角色类型。 在自定义信任策略部分中,输入该角色的以下自定义信任策略: {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
在添加权限页面上,选择下一步。您不会向该角色添加任何策略。 对于 Role name(角色名称),输入 keda-operator。 请选择 Create role(创建角色)。
| AWS 管理员 |
为示例应用程序创建 IAM 角色。 | 在 IAM 控制台的导航窗格中,选择角色。 选择创建角色。 选择 Custom trust policy(自定义信任策略)角色类型。 在自定义信任策略部分中,输入该角色的以下自定义信任策略。将 <account number> 替换为您的目标账号: {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com",
"AWS": "arn:aws:iam::<account number>:role/keda-operator"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
在添加权限页面上,向角色添加以下 AWS 托管策略: 选择下一步。 对于 Role name(角色名称),输入 keda-identity。 请选择 Create role(创建角色)。
| AWS 管理员 |
创建 Amazon SQS 队列。 | 打开 Amazon SQS 控制台。 选择创建队列。 对于 Type(类型),选择 Standard(标准)。 在创建队列页面上,对于名称,输入 event-messages-queue。 选择创建队列。您无需更改此队列的任何默认设置。
| 常规 AWS |
创建 Amazon ECR 存储库。 | 打开 Amazon ECR 控制台。 选择创建存储库。 对于存储库名称,输入 keda-pod-identity-registry。 选择创建存储库。您无需更改此存储库的任何默认设置。
| 常规 AWS |
| 任务 | 描述 | 所需技能 |
|---|
部署 Amazon EKS 容器组身份代理。 | 对于目标 Amazon EKS 集群,安装 Amazon EKS 容器组身份代理。按照 Amazon EKS 文档中设置 Amazon EKS 容器组身份代理的说明进行操作。 | AWS DevOps |
部署 KEDA。 | 输入以下命令,以在目标 Amazon EKS 集群上部署 KEDA: # Add Helm Repo for Keda
helm repo add kedacore https://kedacore.github.io/charts
# Update Helm repo
helm repo update
# Install Keda
helm install keda kedacore/keda --namespace keda --create-namespace
有关更多信息,请参阅 KEDA 文档中的使用 Helm 进行部署。 成功部署后,在输出中,验证是否为 KEDA 运算符创建了三个部署。以下内容为示例输出: NAME READY UP-TO-DATE AVAILABLE AGE
keda-admission-webhooks 1/1 1 1 89s
keda-operator 1/1 1 1 89s
keda-operator-metrics-apiserver 1/1 1 1 89s
| DevOps 工程师 |
为 Kubernetes 服务账户分配 IAM 角色。 | 按照 Amazon EKS 文档中向 Kubernetes 服务账户分配 IAM 角色中的说明进行操作。使用以下值: 对于 IAM 角色,请输入 keda-operator。 对于 Kubernetes 命名空间,请输入 keda 对于 Kubernetes 服务账户,请输入。keda-operator
| AWS DevOps |
创建命名空间。 | 输入以下命令,以在目标 Amazon EKS 集群中创建 security 命名空间: kubectl create ns security
| DevOps 工程师 |
| 任务 | 描述 | 所需技能 |
|---|
克隆应用程序文件。 | 输入以下命令,以从 GitHub 克隆使用 EKS 容器组身份和 KEDA 的事件驱动型自动扩缩存储库: git clone https://github.com/aws-samples/event-driven-autoscaling-using-podidentity-and-keda.git
| DevOps 工程师 |
构建 Docker 映像。 | 输入以下命令,以导航到克隆的存储库: cd event-driven-autoscaling-using-podidentity-and-keda
输入以下命令,为示例应用程序构建 Docker 映像: docker build -t keda-pod-identity-registry .
| DevOps 工程师 |
将 Docker 映像推送到 Amazon ECR。 | 在构建 Docker 映像的终端中,输入以下命令,以登录 Amazon ECR。请将 <AWS_REGION> 和 <AWS_ACCOUNT_ID> 替换为 AWS 环境的值: aws ecr get-login-password \
--region <AWS_REGION> | docker login \
--username AWS \
--password-stdin <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com
输入以下命令,以标记映像。请将 <AWS_REGION> 和 <AWS_ACCOUNT_ID> 替换为 AWS 环境的值: docker tag keda-pod-identity-registry:latest <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/keda-pod-identity-registry:latest
输入以下命令,以将映像推送至 Amazon ECR 请将 <AWS_REGION> 和 <AWS_ACCOUNT_ID> 替换为 AWS 环境的值: docker push <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/keda-pod-identity-registry:latest
您可以导航到 Amazon ECR 存储库页面,然后选择查看推送命令,进而找到推送命令。 | DevOps 工程师 |
部署示例应用程序。 | 在克隆的存储库中,打开 deploy.yaml 文件。 将 <AWS_REGION> 和 <AWS_ACCOUNT_ID> 替换为环境的值。 保存并关闭 deploy.yaml 文件。 输入以下命令,以在目标 Amazon EKS 集群上部署示例应用程序: kubectl apply -f deploy.yaml
此命令会在集群中创建部署和服务账户。
| DevOps 工程师 |
为应用程序服务账户分配 IAM 角色。 | 执行以下任一操作,将 keda-identity IAM 角色与示例应用程序的服务账户进行关联: 按照 Amazon EKS 文档中向 Kubernetes 服务账户分配 IAM 角色中的说明进行操作。使用以下值: 对于 IAM 角色,请输入 keda-identity。 对于 Kubernetes 命名空间,请输入 security 对于 Kubernetes 服务账户,请输入。my-sqs-read-msgs
输入以下 AWS CLI 命令。将 <cluster-name> 替换为目标 Amazon EKS 集群的名称,并将 <role-ARN> 替换为 keda-identity 角色的 Amazon 资源名称(ARN): aws eks create-pod-identity-association \
--cluster-name <cluster-name> \
--role-arn <role-ARN> \
--namespace security \
--service-account my-sqs-read-msgs
| DevOps 工程师 |
部署 ScaledObject 和 TriggerAuthentication。 | 在克隆的存储库中,打开 keda.yaml 文件。 将 {{AWS_ACCOUNT_ID}} 替换为目标 AWS 账户 的 ID。 将 {{AWS_REGION}} 替换为目标 AWS 区域。 (可选)在第 21—24 行中,更新 ScaledObject 扩缩策略的参数。有关这些参数的更多信息,请参阅以下内容: 保存并关闭 keda.yaml 文件。 输入以下命令,以部署 ScaledObject 和 TriggerAuthentication 资源: kubectl -n security apply -f keda.yaml
| DevOps 工程师 |
| 任务 | 描述 | 所需技能 |
|---|
向 Amazon SQS 队列发送消息。 | 输入以下命令,以导航到克隆的存储库: cd event-driven-autoscaling-using-podidentity-and-keda
输入以下命令,以向 Amazon SQS 队列发送测试消息: python sqs_send_msg.py
sqs_send_msg.py 脚本充当生成用于测试自动扩缩的消息的应用程序。 如果运行的是 Python 3,请使用 python3 sqs_send_msg.py。
| DevOps 工程师 |
监控应用程序容器组(pod)。 | 在不同的终端上,输入以下命令以监控容器组(pod): kubectl -n security get po
对于 Amazon SQS 队列中的每 5 条未读消息,KEDA 会添加一个容器组(pod)。在上一条命令的输出中,确认正在添加新的容器组(pod)。以下内容为示例输出: kubectl -n security get po
NAME READY STATUS RESTARTS AGE
q-read-797f4c7589-2bj76 1/1 Running 0 2s
q-read-797f4c7589-4zxph 1/1 Running 0 49s
q-read-797f4c7589-cg9dt 1/1 Running 0 18s
q-read-797f4c7589-slc69 1/1 Running 0 33s
完成测试后,在原始终端中输入 CTRL + C(Windows)或 CMD + C(macOS)。这会停止 python sqs_send_msg.py 脚本。
| DevOps 工程师 |
故障排除
| 问题 | 解决方案 |
|---|
KEDA 运算符无法扩缩应用程序。 | 输入以下命令,以检查 keda-operator IAM 角色的日志: kubectl logs -n keda -l app=keda-operator -c keda-operator
如果有 HTTP 403 响应码,则应用程序和 KEDA 扩缩器没有足够的权限来访问 Amazon SQS 队列。完成以下步骤: 查看 keda-identity 角色的 IAM 策略和声明,确认已授予该队列读取权限。 验证 IAM 角色之间的信任关系。以下是示例: {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}
如果出现 Assume-Role 错误,则 Amazon EKS 节点 IAM 角色将无法代入为 TriggerAuthentication 定义的 IAM 角色。完成以下步骤: 输入以下命令,以删除 keda-operator 容器组(pod)并创建新的容器组(pod): kubectl delete pod keda-operator-<alphenumeric-value> --namespace keda
输入以下命令,以检查容器组(pod)所代入的身份: kubectl describe pod <keda-operator-pod-name> --namespace keda
当容器组(pod)成功重启后,请确认在容器组(pod)描述中添加了以下两个变量:
|
相关资源