AlexeyLedenev翻译
天道酬勤,责编
Carol出品
CSDN云计算(ID:CSDNcloud)随着企业与各种云提供商合作,多云场景已经变得十分常见。在谷歌Kubernetes引擎(GKE)上运行的应用程序需要访问亚马逊网络服务(AWS)API时,这种情况也会出现。任何应用程序都有需求,也许它需要在AmazonRedshift上运行分析查询,访问存储在AmazonS3存储桶中的数据,使用AmazonPolly将文本转换为语音或使用任何其他AWS服务。跨云访问带来了新挑战:如何管理云凭据。这是从一个云提供商访问另一个提供商运行的服务所必需解决的问题。如果用不成熟的方法来分发和保存云提供商的机密是非常不安全的。将长期凭证分配给需要访问AWS服务的每个服务管理起来具有挑战性,并且存在潜在的安全风险。当前解决方案实际上,每个云服务商都提供了自己独特的解决方案来克服这一挑战,和其中一个云服务商合作就可以解决。谷歌云(GoogleCloud)推出了WorkloadIdentity,这是GKE应用程序认证和使用其他谷歌云服务的推荐方式。WorkloadIdentity通过绑定Kubernetes服务帐户和CloudIAM服务帐户来工作,因此你可以使用本地Kubernetes概念来定义哪些工作负载以哪些身份运行,并允许你的工作负载自动访问其他谷歌云服务,而无需管理Kubernetes秘密或IAM服务帐户密钥。AWS通过“IAM服务帐户角色”功能支持类似的功能。使用AmazonEKS集群上服务帐户的IAM角色,可以将IAM角色与Kubernetes服务帐户关联。然后该服务帐户可以向使用该服务帐户任何Pod中的容器提供AWS权限。使用此功能不再需要为工作节点IAM角色提供扩展权限,以便该节点上的Pod可以调用AWSAPI。但是,如果你在GKE集群上运行应用程序工作负载,并且希望在不影响安全性的情况下访问AWS服务该怎么办?定义一个使用案例假设你已经有一个AWS账户和一个GKE集群,并且你的公司已决定在GKE集群上运行基于微服务的应用程序,但仍想使用AWS账户中的资源(AmazonS3和SNS服务)与在AWS上部署的其他系统。例如,在GKE集群中运行业务流程作业(部署为KubernetesJob),需要将数据文件上传到S3存储桶中并向AmazonSNS主题发送消息。等效的命令行如下:这是一个很简单的例子。为了能使这些命令成功执行,业务流程作业必须具有可用的AWS凭证,并且这些凭证必须能够进行相关的API调用。不成熟的(非安全的)方法:IAM的长期凭据导出某些AWSIAM用户的AWS访问密钥和保密密钥,并将AWS凭证作为凭证文件或环境变量注入到业务流程作业中。可能不是直接执行此操作,而是使用RBAC授权策略保护的KubernetesSecrets资源。这里的风险是这些凭据永远不会过期。必须将它们从AWS环境转移到GCP环境,并且在大多数情况下,人们希望将它们存储在某个位置,以便在以后需要时可用于重新创建业务流程作业。使用长期AWS凭证时,可以通过多种方式来破坏你的AWS账户。无意中将AWS凭证提交到GitHub存储库中、将其保存在Wiki系统中、针对不同的服务和应用程序重复使用凭证和允许无限制访问等等。尽管可以为已发布的IAM用户凭据设计适当的凭据管理解决方案,但是如果你永远不会一开始就创建这些长期凭据,则不需要此解决方案。作者提出的方法基本思想是将AWSIAM角色分配给GKEPod,类似于针对服务帐户云特定功能的工作负载身份和EKSIAM角色。对我们来说很幸运的是,AWS允许为开放ID连接联盟(OpenIDConnectFederation,OIDC)身份提供者而不是IAM用户创建IAM角色。另一方面,谷歌实现了OIDC提供程序,并通过工作负载身份功能将其与GKE紧密集成。为GKEPod提供有效的OIDC令牌,该令牌在链接到谷歌云服务帐户的Kubernetes服务帐户下运行。所有这些都可以有助于实现GKE-to-AWS的安全访问。将OIDC访问令牌转换为ID令牌需要完成该方法还缺少一点东西。通过正确设置工作负载身份,GKEPod会获得OIDC访问令牌,该令牌允许访问谷歌云服务。为了从AWS安全令牌服务(STS)获取临时AWS凭证,你需要提供有效的OIDCID令牌。正确设置以下环境变量后,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将gtokeninitContainer注入目标Pod和一个附加的gtokensidekick容器(以在到期前刷新OIDCID令牌),安装令牌量并注入三个AWS特定的环境变量。gtoken容器会生成有效的GCPOIDCID令牌,并将其写入令牌卷。它还会注入必需的AWS环境变量。AWSSDK将代表你自动对AWSSTS进行相应的AssumeRoleWithWebIdentity调用。它将处理内存中的缓存以及根据需要刷新凭据。配置流程指南1)部署gtoken-webhook要部署gtoken-webhook服务器,我们需要在Kubernetes集群中创建一个webhook服务和部署。这很简单,只需配置服务器的TLS。如果你想检查deploy.yaml文件,则会发现从命令行参数中读取了证书和相应的私钥文件,并且这些文件的路径来自指向Kubernetes机密的卷安装:要记住的最重要的事情是稍后在webhook配置中设置相应的CA证书,因此apiserver将知道应接受该证书。现在,我们将重用Istio团队最初编写的脚本来生成证书签名请求。然后,我们会将请求发送到KubernetesAPI,获取证书,然后从结果中创建所需的秘密。首先,运行webhook-create-signed-cert.sh脚本,并检查是否已创建包含证书和密钥的机密:一旦创建了秘密,我们就可以创建部署和服务。这些是标准的Kubernetes部署和服务资源。到目前为止,我们只生成了HTTP服务器,该服务器通过端口上的服务接受请求: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——AWSIAM角色名称(由用户提供)AWS_POLICY_NAME——分配给IAM角色的AWSIAM策略(由用户提供)AWS_ROLE_ARN——AWSIAM角色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角色策略:获取要在K8sSA注释中使用的AWSRoleARN:8)GKE:创建一个Kubernetes服务帐户创建K8s命名空间:创建K8s服务帐户:使用GKE工作负载身份(GCP服务帐户电子邮件)注释K8s服务帐户:使用AWSRoleARN注释K8s服务帐户:9)运行一个演示样例使用K8s${KSA_NAME}服务帐户运行新的K8sPod:好啦,希望这篇文章对你有用,如果你对此有意见和任何问题,欢迎在评论区和我们交流。原文: