简介
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 所需的插件。
先决条件
您需要以下内容才能完成本文中的步骤:
-
亚马逊云科技 命令行接口 (
亚马逊云科技 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 集群的访问权限:
您应该在集群中看到以下命名空间:
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 控制面板。
该值也存储为环境变量:
您的浏览器将被重定向到亚马逊 Cognito 托管的用户界面 (UI) 登录页面。由于这是您第一次访问该应用程序,请选择
注册
。
Amazon Cognito 用户池的注册前 亚马逊云科技 Lambda 触发器配置为仅允许用户从某些列入许可名单的电子邮件域进行注册。在 亚马逊云科技 Lambda 函数中,列入许可名单的电子邮件域被配置为环境变量。让我们尝试使用电子邮件 ID 注册新用户,该用户的域名不在允许列表中。
由于该域名未列入许可名单,因此您会收到一条错误消息。
让我们以新用户身份使用一个列入许可名单的电子邮件域名进行注册。这次,系统会提示您确认您的账户。将验证码发送到您的电子邮件并确认您的帐户。
验证电子邮件地址后,登录访问 Kubecost 控制面板
登录后,ALB 会将你重定向到 Kubecost 控制面板:
正在清理
在删除为这篇文章创建的基础架构之前,您将继续承担费用。使用以下命令删除在这篇文章中创建的资源:
make pattern secure-ingress-cognito destroy secure-ingress-blueprint
结论
在这篇文章中,我们向您展示了如何保护 Kubecost 仪表板,同时让用户无需访问 Kubernetes 集群即可访问该仪表板。我们使用 ALB 来公开仪表板并使用 Cognito 进行安全访问。我们还在 Route 53 中创建了一条记录,以便用户可以轻松访问仪表板。
我们使用
Cognito 用户池
来存储用户信息。如果你已经有了提供
OpenID Connect (OIDC)
或
SAML 2.0
支持的身份提供商,那么你可以
将其与 Cognito 集成
,跳过注册和登录 Kubecost 仪表板的操作。