从Kubernetes安全地访问AWS服务,告诉你多云场景下如何管理云凭据!
随着企业与各种云提供商合作,多云场景已经变得十分常见。
在谷歌Kubernetes引擎(GKE)上运行的应用程序需要访问亚马逊网络服务(AWS)API时,这种情况也会出现。任何应用程序都有需求,也许它需要在AmazonRedshift上运行分析查询,访问存储在Amazon S3存储桶中的数据,使用Amazon Polly将文本转换为语音或使用任何其他AWS服务。
跨云访问带来了新挑战:如何管理云凭据。这是从一个云提供商访问另一个提供商运行的服务所必需解决的问题。如果用不成熟的方法来分发和保存云提供商的机密是非常不安全的。将长期凭证分配给需要访问AWS服务的每个服务管理起来具有挑战性,并且存在潜在的安全风险。
当前解决方案
实际上,每个云服务商都提供了自己独特的解决方案来克服这一挑战,和其中一个云服务商合作就可以解决。
谷歌云(Google Cloud)推出了Workload Identity,这是GKE应用程序认证和使用其他谷歌云服务的推荐方式。Workload Identity 通过绑定Kubernetes服务帐户和Cloud IAM服务帐户来工作,因此你可以使用本地Kubernetes概念来定义哪些工作负载以哪些身份运行,并允许你的工作负载自动访问其他谷歌云服务,而无需管理Kubernetes秘密或IAM服务帐户密钥。
AWS通过“ IAM服务帐户角色”功能支持类似的功能。使用Amazon EKS集群上服务帐户的IAM角色,可以将IAM角色与Kubernetes服务帐户关联。然后该服务帐户可以向使用该服务帐户任何Pod中的容器提供AWS权限。使用此功能不再需要为工作节点IAM角色提供扩展权限,以便该节点上的Pod可以调用AWS API。
但是,如果你在GKE集群上运行应用程序工作负载,并且希望在不影响安全性的情况下访问AWS服务该怎么办?
定义一个使用案例
假设你已经有一个AWS账户和一个GKE集群,并且你的公司已决定在GKE集群上运行基于微服务的应用程序,但仍想使用AWS账户中的资源(Amazon S3和SNS服务)与在AWS上部署的其他系统。
例如,在GKE集群中运行业务流程作业(部署为Kubernetes Job),需要将数据文件上传到S3存储桶中并向Amazon SNS主题发送消息。等效的命令行如下:
这是一个很简单的例子。为了能使这些命令成功执行,业务流程作业必须具有可用的AWS凭证,并且这些凭证必须能够进行相关的API调用。
不成熟的(非安全的)方法:IAM的长期凭据
导出某些AWS IAM用户的AWS访问密钥和保密密钥,并将AWS凭证作为凭证文件或环境变量注入到业务流程作业中。可能不是直接执行此操作,而是使用RBAC授权策略保护的Kubernetes Secrets资源。
这里的风险是这些凭据永远不会过期。必须将它们从AWS环境转移到GCP环境,并且在大多数情况下,人们希望将它们存储在某个位置,以便在以后需要时可用于重新创建业务流程作业。
使用长期AWS凭证时,可以通过多种方式来破坏你的AWS账户。无意中将AWS凭证提交到GitHub存储库中、将其保存在Wiki系统中、针对不同的服务和应用程序重复使用凭证和允许无限制访问等等。
尽管可以为已发布的IAM用户凭据设计适当的凭据管理解决方案,但是如果你永远不会一开始就创建这些长期凭据,则不需要此解决方案。
作者提出的方法
基本思想是将AWS IAM角色分配给GKE Pod,类似于针对服务帐户云特定功能的工作负载身份和EKS IAM角色。
对我们来说很幸运的是,AWS允许为开放ID连接联盟(OpenID Connect Federation,OIDC)身份提供者而不是IAM用户创建IAM角色。另一方面,谷歌实现了OIDC提供程序,并通过工作负载身份功能将其与GKE紧密集成。为GKE Pod提供有效的OIDC令牌,该令牌在链接到谷歌云服务帐户的Kubernetes服务帐户下运行。所有这些都可以有助于实现GKE-to-AWS的安全访问。
将OIDC访问令牌转换为ID令牌
需要完成该方法还缺少一点东西。通过正确设置工作负载身份,GKE Pod会获得OIDC访问令牌,该令牌允许访问谷歌云服务。为了从AWS安全令牌服务(STS)获取临时AWS凭证,你需要提供有效的OIDC ID令牌。
正确设置以下环境变量后,AWS开发工具包(和aws-cli工具)将自动从STS服务请求临时AWS凭证:
AWS_WEB_IDENTITY_TOKEN_FILE——Web身份令牌文件的路径(OIDCID令牌); AWS_ROLE_ARN——Pod容器承担的角色的ARN; AWS_ROLE_SESSION_NAME——应用于此假定角色会话的名称。
一旦创建了秘密,我们就可以创建部署和服务。这些是标准的Kubernetes部署和服务资源。到目前为止,我们只生成了HTTP服务器,该服务器通过端口443上的服务接受请求:
PROJECT_ID——GCP项目ID(由用户提供) CLUSTER_NAME——GKE群集名称(由用户提供) GSA_NAME——谷歌云帐户名(由用户提供) GSA_ID——谷歌云服务帐户的唯一ID(由谷歌生成) KSA_NAME——Kubernetes服务帐户名(由用户提供) KSA_NAMESPACE——Kubernetes命名空间(由用户提供) AWS_ROLE_NAME——AWS IAM角色名称(由用户提供) AWS_POLICY_NAME——分配给IAM角色的AWS IAM策略(由用户提供) AWS_ROLE_ARN——AWS IAM角色ARN标识符(由AWS生成)
role / iam.workloadIdentityUser——模拟来自GKE 工作负载的服务帐户 role / iam.serviceAccountTokenCreator——模拟服务帐户以创建OAuth2访问令牌,签署Blob或签署JWT令牌
原文:https://hackernoon.com/access-aws-services-from-google-kubernetes-engine-securely-a-how-to-guide-x8an3b5y
本文为 CSDN 云计算翻译,转载请经授权。