使用亚马逊 Cognito 保护 Kubecost 的访问权限

简介

Kubecost 为使用 Kubernetes 的团队提供实时成本可见性和见解。它具有直观的仪表板,可帮助您了解和分析在 Kubernetes 集群中运行工作负载的成本。Kubecost 建立在 Open Cost 的基础上 ,该项目最近被接受为云原生计算基金会 (CNCF) 沙盒项目,并得到了 亚马逊云科技 的积极支持。

亚马逊 EKS 优化的 Kubecost 捆绑包

去年早些时候,亚马逊弹性Kubernetes服务(Amazon EK S )宣布推出经过 亚马逊 EK S优化的Kub ecost捆绑包,以提高集群成本可见 性。该捆绑包免费提供给客户,包括 Kubecost 故障排除支持。Kubernetes 平台管理员和财务主管可以使用 Kubecost 来可视化其 Amazon EKS 费用明细、分配成本和退款组织单位(例如应用程序团队)。Kubecost 根据 亚马逊云科技 账单为内部团队和业务部门提供透明而准确 的成本数据。 客户还可以获得针对其基础架构环境和使用模式量身定制的个性化成本优化建议。

使用 Kubecost 的直观仪表板,客户可以监控、分析和分配集群成本。当客户在集群中部署 Kubecost 时,仪表板由 NGINX 基本身份验证 保护 ,在生产环境中不建议这样做。这篇文章介绍如何使用Amazon Cognito让外部受众(例如财务领袖)访问控制面板,以及如何使用 Amazon Cognito 进行安全访问。

解决方案概述

我们使用使用应用程序负载均衡器 (ALB) 的入口公开 Kubecost 仪表板,从而使 Kubecost 仪表板可在集群外部访问。该解决方案将Amazon Cognito与ALB集成在一起,增加了对用户在Kubecost控制面板进行身份验证和授权的支持。要了解有关 ALB 和 Cognito 如何集成的更多信息,请参阅 如何使用应用程序负载均衡器和 Amazon Cognito 对您的 Kubernetes 网络应用程序的用户进行身份验证

在这篇文章中,我们使用 安全的入口认证认知 EKS 蓝图模式来设置

  • 应用程序负载均衡器 Amazon Cognito 和 带有 亚马逊 Route 53 托 管区域的 亚马逊云科技 证书管理器 (ACM) 上的传输层安全 (TLS) 证书,用于对 Kubecost 的用户进行身份验证
  • 使用适用于 EKS CDK 蓝图的 Kubecost 插件部署 Kubecost 应用程序
  • Kubernetes Ingress 带有亚马逊 Cognito 的注解和用于安全地向 Kubecost 验证用户身份的 TLS 证书(使用 亚马逊证书管理器

客户可以使用这种模式通过 GitOps 管理跨环境的多个集群。 请参阅 使用亚马逊 EKS 蓝图和 ArgoCD 进行 持续部署和 GitOps 交付,了解如何使用 EKS 蓝图 模式进行 GitOps 驱动的交付。

安全的入口认证认知 云开发套件 (CDK) 模式包括 Amazon EKS 集群配置、计算容量配置和 Kubecos t 所需的插件。

Architecture Showing how to Secure Ingress with Cognito for Kubecost application.

先决条件

您需要以下内容才能完成本文中的步骤:

  • 亚马逊云科技 命令行接口 ( 亚马逊云科技 CLI) 版本 2
  • 亚马逊云科技 CDK 版本 2.80.0 或更高版本
  • 节点 版本 20.0.0 或更高版本
  • NPM 版本 8.19.2 或更高版本
  • kubectl 版本 1.24 或更高版本
  • Git
  • 亚马逊 Route 53 公共托管区域

让我们首先设置一些环境变量:

ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
export AWS_REGION=${AWS_REGION:=us-west-2}

克隆 cdk-eks-blueprints-patterns 存储库并安装依赖包 。这个存储库包含用 TypeScript 编写的 CDK v2 代码。

git clone https://github.com/aws-samples/cdk-eks-blueprints-patterns.git
cd cdk-eks-blueprints-patterns
npm install
make build

安全 ingress-auth-cognito E KS Blueprints 模式位于 lib/secure-ingress-auth-cognito /index.ts。 在此文件中,你可以使用 blueprints.eksBlueprint.Builder () 方法找到包含上述所有配置的蓝图定义。

Bootstrap CDK

任何 CDK 部署的第一步都是引导环境。 引导 是在 亚马逊云科技 环境中部署 亚马逊云科技 CDK 应用程序之前为 亚马逊云科技 CDK 预置资源的过程 (亚马逊云科技 环境 是 亚马逊云科技 账户和区域的组合)。如果您已经 在某个地区使用了 CDK ,则无需重复引导过程。

执行以下命令以引导您所在地区的 亚马逊云科技 环境:

cdk bootstrap aws://$ACCOUNT_ID/$AWS_REGION

使用安全访问权限部署 Kubecost

在此解决方案中,我们将允许根据用户电子邮件地址访问 Kubecost 仪表板。您可以通过将整个域名或个人电子邮件地址列入许可名单来控制对仪表板的访问权限。

用户必须先注册,然后才能访问 Kubecost 控制面板。 注册 前 Lambda 触发器 仅允许在用户的电子邮件域与允许列表的域名匹配时进行注册。当用户注册时,Amazon Cognito 会向他们的电子邮件地址发送验证码。用户必须先验证其电子邮件的访问权限(使用一次性的有效代码),然后才能访问控制面板。

首先,我们将创建一个 亚马逊云科技 Systems Manager (SSM) 参数来存储用户注册时使用的电子邮件域的值。接下来,我们将创建一个环境变量来存储托管 Kubecost 仪表板的域名。电子邮件域名和用于托管 Kubecost 仪表板的域名可以相同也可以不同。 例如,你可以选择在 kubecost.myorg.mycompany.com 上托管仪表板,然后使用 email@mycompany.org 登录仪表 板。

亚马逊云科技 Systems Manager 参数存储中使用允许的电子邮件地址和域名创建以下参数

export SSM_PARAMETER_KEY="/secure-ingress-auth-cognito/ALLOWED_DOMAINS"
export SSM_PARAMETER_VALUE="emaildomain1.com,emaildomain2.com"

aws ssm put-parameter \
  --name "$SSM_PARAMETER_KEY" \
  --value "$SSM_PARAMETER_VALUE" \
  --type "String" \
  --region $AWS_REGION

如果您想限制通过电子邮件地址访问控制面板,则还可以创建参数来存储允许的电子邮件地址,并为 预身份验证 Lambda 触发器 添加逻辑, 如下所示 。

接下来,在 亚马逊云科技 Secrets Manager 中创建一个用于访问 ArgoCD 的密钥。argo-admin-password 密钥必须定义为纯文本(不是密钥/值):

aws secretsmanager create-secret --name argo-admin-secret \
    --description "Admin Password for ArgoCD" \
    --secret-string "password123$" \
    --region $AWS_REGION

CDK 代码要求 CDK 上下文文件 (cdk.json) 中包含允许的域名和子域名。

创建两个环境变量。PARENT_HOSTED_ZONE 变量包含您的 Route 53 公共托管区域的名称。DEV_SUBZONE_NAME 将是你的 Kubecost 控制面板的地址。

生成 cdk.json 文件:

PARENT_HOSTED_ZONE=mycompany.a2z.com
DEV_SUBZONE_NAME=kubecost.mycompany.a2z.com
cat << EOF > cdk.json
{
    "app": "npx ts-node dist/lib/common/default-main.js",
    "context": {
        "parent.hostedzone.name": "${PARENT_HOSTED_ZONE}",
        "dev.subzone.name": "${DEV_SUBZONE_NAME}"
      }
}
EOF

从该存储库的根目录运行以下命令来部署解决方案:

make pattern secure-ingress-cognito deploy secure-ingress-blueprint

该蓝图将部署以下内容:

  • 具有公有和@@ 私有子网的亚马逊虚拟私有云 (Azon VPC) 、每个可用区 (AZ) 中的网络地址转换 (NAT) 网关以及互联网网关
  • 带有以下 Kubernetes 插件的亚马逊 EKS 集群
  • 指标服务器
  • 集群自动扩缩
  • 亚马逊弹性区块存储 (亚马逊 EBS) 容器存储接口 (CSI) 驱动程序亚马逊 EKS 亚马逊云科技 负载均衡器控制器 Amazon VPC CN
  • I
  • ExternalDNS
  • Kub
  • ecost Argo C
  • Amazon Cognito 用户池、用户池客户端、域以及 预注册和预身份验证 lambda 触发器 ,用于在允许用户注册或认证之前运行自定义逻辑来验证用户。

部署完成后,您将在终端中看到类似于如下所示的输出:

Outputs:
secure-ingress-blueprint.secureingressblueprintClusterNameD6A1BE5C = secure-ingress-blueprint
secure-ingress-blueprint.secureingressblueprintConfigCommandD0275968 =  aws eks update-kubeconfig —name secure-ingress-blueprint —region us-west-2 —role-arn arn:aws:iam::<ACCOUNT ID>:role/secure-ingress-blueprint-secureingressblueprintMas-XXXXXXXXXX
secure-ingress-blueprint.secureingressblueprintGetTokenCommand21BE2184 =  aws eks get-token —cluster-name secure-ingress-blueprint —region us-west-2 —role-arn arn:aws:iam::<ACCOUNT ID>:role/secure-ingress-blueprint-secureingressblueprintMas-XXXXXXXXXX

Stack ARN:
arn:aws:cloudformation:us-west-2:<ACCOUNT ID>:stack/secure-ingress-blueprint/XXXXXXXXXX

要更新新集群的 Kubernetes 配置,请在终端中复制并运行 aws eks update-kubeconfig 命令(输出中的第二条命令)。

export EKS_KUBECONFIG=$(aws cloudformation describe-stacks \
  --stack-name secure-ingress-blueprint \
  --query "Stacks[0].Outputs[?starts_with(OutputKey, 'secureingressblueprintConfigCommand')].OutputValue" \
  --region $AWS_REGION \
  --output text)

eval $EKS_KUBECONFIG

使用下面列出所有命名空间的 kubectl 验证对您的 Amazon EKS 集群的访问权限:

kubectl get namespace

您应该在集群中看到以下命名空间:

NAME              STATUS   AGE
argocd            Active   30m
default           Active   39m
external-dns      Active   30m
kube-node-lease   Active   39m
kube-public       Active   39m
kube-system       Active   39m
kubecost          Active   30m

该堆栈在 kubecost 命名空间中部署 Kubecost 资源。

kubectl -n kubecost get all
NAME                                                             READY   STATUS    RESTARTS   AGE
pod/kubecost-cost-analyzer-84d5775f7b-zg8mq                      2/2     Running   0          88m
pod/kubecost-cost-analyzer-grafana-69d77ccd6d-9r8rc              2/2     Running   0          88m
pod/kubecost-cost-analyzer-kube-state-metrics-789fc978c8-ch8lb   1/1     Running   0          88m
pod/kubecost-cost-analyzer-prometheus-node-exporter-w9w75        1/1     Running   0          88m
pod/kubecost-cost-analyzer-prometheus-server-6dc99564bf-mz9nw    2/2     Running   0          88m

NAME                                                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
service/kubecost-cost-analyzer-cost-analyzer              ClusterIP   172.20.193.130   <none>        9003/TCP,9090/TCP   88m
service/kubecost-cost-analyzer-grafana                    ClusterIP   172.20.143.32    <none>        80/TCP              88m
service/kubecost-cost-analyzer-kube-state-metrics         ClusterIP   172.20.165.147   <none>        8080/TCP            88m
service/kubecost-cost-analyzer-prometheus-node-exporter   ClusterIP   None             <none>        9100/TCP            88m
service/kubecost-cost-analyzer-prometheus-server          ClusterIP   172.20.54.102    <none>        80/TCP              88m

NAME                                                             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/kubecost-cost-analyzer-prometheus-node-exporter   1         1         1       1            1           <none>          88m

NAME                                                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kubecost-cost-analyzer                      1/1     1            1           88m
deployment.apps/kubecost-cost-analyzer-grafana              1/1     1            1           88m
deployment.apps/kubecost-cost-analyzer-kube-state-metrics   1/1     1            1           88m
deployment.apps/kubecost-cost-analyzer-prometheus-server    1/1     1            1           88m

测试身份验证

将浏览器指向你在 CDK 上下文中与 DEV_SUBZONE_NAME 密钥关联的网址,即可访问 Kubecost 控制面板。

该值也存储为环境变量:

echo $DEV_SUBZONE_NAME

您的浏览器将被重定向到亚马逊 Cognito 托管的用户界面 (UI) 登录页面。由于这是您第一次访问该应用程序,请选择 注册

Amazon Cognito 用户池的注册前 亚马逊云科技 Lambda 触发器配置为仅允许用户从某些列入许可名单的电子邮件域进行注册。在 亚马逊云科技 Lambda 函数中,列入许可名单的电子邮件域被配置为环境变量。让我们尝试使用电子邮件 ID 注册新用户,该用户的域名不在允许列表中。

Screenshot of sign-in page

由于该域名未列入许可名单,因此您会收到一条错误消息。 Screenshot of error message

让我们以新用户身份使用一个列入许可名单的电子邮件域名进行注册。这次,系统会提示您确认您的账户。将验证码发送到您的电子邮件并确认您的帐户。

Screenshot of account verification page

验证电子邮件地址后,登录访问 Kubecost 控制面板

登录后,ALB 会将你重定向到 Kubecost 控制面板:

Kubecost dashboard

正在清理

在删除为这篇文章创建的基础架构之前,您将继续承担费用。使用以下命令删除在这篇文章中创建的资源:

make pattern secure-ingress-cognito destroy secure-ingress-blueprint

结论

在这篇文章中,我们向您展示了如何保护 Kubecost 仪表板,同时让用户无需访问 Kubernetes 集群即可访问该仪表板。我们使用 ALB 来公开仪表板并使用 Cognito 进行安全访问。我们还在 Route 53 中创建了一条记录,以便用户可以轻松访问仪表板。

我们使用 Cognito 用户池 来存储用户信息。如果你已经有了提供 OpenID Connect (OIDC) SAML 2.0 支持的身份提供商,那么你可以 将其与 Cognito 集成 ,跳过注册和登录 Kubecost 仪表板的操作。

Elamaran Shanmugam

Elamaran Shanmugam Elam

aran (Ela) Shanmugam 是 亚马逊云科技 的高级容器专家解决方案架构师。Ela 是一家容器、可观测性和多账户架构中小企业,帮助客户在 亚马逊云科技 上设计和构建可扩展、安全和优化的容器工作负载。他热衷于构建和自动化基础架构,让客户能够更多地专注于他们的业务。他的总部设在佛罗里达州的坦帕,你可以通过推特联系他 @IamElaShan。

Jayaprakash Alawala

Jayaprakash Alawala J ayaprakash Alawala 是 AW

S 的高级容器专家解决方案架构师。他帮助客户进行应用程序现代化并利用各种 亚马逊云科技 服务构建大规模应用程序。他在容器、微服务、开发运营、安全、成本优化(包括EC2 Spot)、技术培训等领域拥有专业知识。工作之余,他喜欢花时间阅读和旅行。你可以在推特上联系他 @JP_Alawala

Ramesh Kumar Venkatraman

拉梅什·库马尔·文卡特拉曼 Ramesh Kumar Venkatr aman

是 亚马逊云科技 的解决方案架构师,他对容器和数据库充满热情。他与 亚马逊云科技 客户合作设计、部署和管理他们的 亚马逊云科技 工作负载和架构。在业余时间,他喜欢和两个孩子一起玩,喜欢打板球。

Re Alvarez-Parmar

回复 Alvarez-Parmar

在亚马逊网络服务担任容器专家解决方案架构师期间,Re 为工程团队提供在云端实现分布式服务现代化和构建的建议。在加入 亚马逊云科技 之前,他曾担任企业和软件架构师超过 15 年。他的总部设在西雅图。在 Linkedin 上连接,网址为:linkedin.com/in/realvar

ez

*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。