查看原文
其他

从Kubernetes安全地访问AWS服务,告诉你多云场景下如何管理云凭据!

Alexey Ledenev CSDN云计算 2020-10-16

作者| Alexey Ledenev
翻译 | 天道酬勤,责编 | Carol
出品 | CSDN云计算(ID:CSDNcloud)

随着企业与各种云提供商合作,多云场景已经变得十分常见。


在谷歌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——应用于此假定角色会话的名称。

听起来可能有点复杂,但是作者将提供分步指南并支持开源项目dointl / gtoken来简化该设置。


gtoken-webhook可变流

gtoken-webhook将gtoken initContainer注入目标Pod和一个附加的gtoken sidekick容器(以在到期前刷新OIDC ID令牌),安装令牌量并注入三个AWS特定的环境变量。gtoken容器会生成有效的GCP OIDC ID令牌,并将其写入令牌卷。它还会注入必需的AWS环境变量。

AWS SDK将代表你自动对AWS STS进行相应的AssumeRoleWithWebIdentity调用。它将处理内存中的缓存以及根据需要刷新凭据。



配置流程指南

1)部署gtoken-webhook

要部署gtoken-webhook服务器,我们需要在Kubernetes集群中创建一个webhook服务和部署。这很简单,只需配置服务器的TLS。如果你想检查deploy.yaml文件,则会发现从命令行参数中读取了证书和相应的私钥文件,并且这些文件的路径来自指向Kubernetes机密的卷安装:


要记住的最重要的事情是稍后在webhook配置中设置相应的CA证书,因此apiserver将知道应接受该证书。现在,我们将重用Istio团队最初编写的脚本来生成证书签名请求。然后,我们会将请求发送到KubernetesAPI,获取证书,然后从结果中创建所需的秘密。

首先,运行webhook-create-signed-cert.sh脚本,并检查是否已创建包含证书和密钥的机密:


一旦创建了秘密,我们就可以创建部署和服务。这些是标准的Kubernetes部署和服务资源。到目前为止,我们只生成了HTTP服务器,该服务器通过端口443上的服务接受请求:



2)配置可变的webhook

现在我们的webhook服务器正在运行,它可以接受来自apiserver的请求。但是,我们应该首先在Kubernetes中创建一些配置资源。让我们从验证webhook开始,然后再配置可变的webhook。如果查看一下webhook配置,你会注意到它包含CA_BUNDLE的占位符:


有一个小的脚本用此CA替换配置中的CA_BUNDLE占位符。在创建验证webhook配置之前运行以下命令:


创建一个可变的webhook配置:


3)为gtoken-webhook配置RBAC

创建与gtoken-webhook一起使用的Kubernetes服务帐户:


定义webhook服务帐户的RBAC权限:


4)配置流程变量

用户应提供以下某些变量,其他变量将自动生成并在以下步骤中重复使用。

  • 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生成)

5)谷歌云:启用GKE工作负载身份

创建一个启用了工作负载标识的新GKE集群:


或更新现有集群:


6)谷歌云:创建一个谷歌云服务账户

创建一个谷歌云服务帐户:


使用以下角色更新GSA_NAME谷歌服务帐户:
  • role / iam.workloadIdentityUser——模拟来自GKE 工作负载的服务帐户
  • role / iam.serviceAccountTokenCreator——模拟服务帐户以创建OAuth2访问令牌,签署Blob或签署JWT令牌



7)AWS:使用谷歌OIDC联盟创建AWSIAM角色

为谷歌 OIDC提供者准备角色信任策略文档:



使用谷歌网络身份创建AWSIAM角色:


分配所需的AWS角色策略:


获取要在K8s SA注释中使用的AWS Role ARN:


8)GKE:创建一个Kubernetes服务帐户

创建K8s命名空间:


创建K8s服务帐户:


使用GKE工作负载身份(GCP服务帐户电子邮件)注释K8s服务帐户:


使用AWS Role ARN注释K8s服务帐户:


9)运行一个演示样例

使用K8s ${KSA_NAME}服务帐户运行新的K8s Pod:


好啦,希望这篇文章对你有用,如果你对此有意见和任何问题,欢迎在评论区和我们交流。

参考文献
l GitHub: Securely access AWS services from GKE cluster with doitintl/gtoken
l AWS Docs: Creating aRole for Web Identity or OpenID Connect Federation
l Blog: Kubernetes GKE Workload Identity link
l AWS Blog: Introducing fine-grained IAM roles for service accounts link
l GitHub: AWS Auth using Web IdentityFederation from Google Cloud shrikant0013/gcp-aws-webidentityfederation GitHubproject
l Blog: Using GCP Service Accounts to access AWS IAM Roles blog post byColin Panisset
 

原文:https://hackernoon.com/access-aws-services-from-google-kubernetes-engine-securely-a-how-to-guide-x8an3b5y

本文为 CSDN 云计算翻译,转载请经授权。


在中国企业与「远程办公」正面相遇满月之际,2月29日,CSDN 联合广大「远程办公」工具服务企业共同举办【抗击疫情,科技公司在行动】系列之【远程办公】专题线上峰会活动:中国「远程办公」大考。

扫下方二维码或点击阅读原文免费报名直播+抽取奖品+与大牛交流。想提前了解峰会详情,可加小助手微信csdnai,回复远程办公,进直播群。

推荐阅读:真香,朕在看了!点击“阅读原文”,参与报名

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存