继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

五步搞定服务访问配置:坐标、凭证、配置、同意、连接性

一只名叫tom的猫
关注TA
已关注
手记 500
粉丝 62
获赞 330

双子星生成的图像

你想让你的应用程序访问一个数据库,这有多难呢?

如果同一个服务提供商同时托管了你的应用程序和数据库,并且它们都使用该提供商的身份,而且它们连接到同一个网络上,同一个账户同时拥有它们,而你拥有该账户,那么这可能比较简单。这些因素中的差异越大,情况可能就越复杂。

通常应用程序需要三种信息——3个"C"——才能访问后端服务

  1. 坐标:网络详情,如 IP 地址或 DNS 名称,协议,和端口(如果端口不是众所周知的(如 此处 所列)),或者服务发现的详情,例如账号、区域和资源
  2. 凭据:身份证明
  3. 配置:其他参数,比如数据库名称或 pubsub 话题

通常需要手动将这些信息从服务复制到应用配置,如环境变量,不过处理凭证通常要复杂得多,我在关于机密的文章中详细描述过。

许多平台提供了一种自动注入信息的功能,类似地,如Kubernetes服务环境变量

例如,在 Heroku 中,连接详情注入到环境变量中,例如 HEROKU_POSTGRESQL_RED_URL 这样的。

使用基础设施即代码(IaC)时,一般来说,这些属性通常会被定义为输出变量,然后通过远程状态数据或参数存储(由于影响范围的考虑)在输入变量定义中引用,用于应用程序配置。因为出于影响范围的考虑,这些配置应当放在单独的模块里。这些变量会被用来生成环境变量的值。

一个完整的 Terraform 示例会比较长一些,但输出定义大致如下:

    output "instance_address" {  
      value       = module.rds_instance.instance_address  
      description = "实例地址 (Instance Address)"  
    } // 实例地址

在没有定义输入变量时,引用远程状态会像这样:

    资源定义 "aws_ecs_task_definition" "my_task" {  
    ...  
    容器定义 = jsonencode([  
        {  
          ...  

          环境变量 = [  
            {  
              变量名  = "DB_ADDRESS"  
              变量值 = data.terraform_remote_state.rds.outputs.instance_address  
            },  
    ...

那对于如此常见的情况来说,这种做法相当高级,特别是对于那些可能不是IaC和基础设施API专家的应用程序开发人员来说。与通常需要的处理密钥的操作相比,这已经算简单了。特别是如果它还涉及到像Terraform和Helm这样的配置工具时,情况会更加复杂。

我还没见过这种信息自动写回Git以促进GitOps的示例,这可能是个好事。这更适合放在服务发现系统里。在Kubernetes早期,我们希望用户能用Kubernetes Services来实现这一点,为此添加了诸如[ExternalName](https://kubernetes.io/docs/concepts/services-networking/service/#externalname)这样的功能。但是,DNS名称或IP地址需要以某种方式写入Service或EndpointSlice中,而现在还没有开箱即用的方法来实现。

正如你可能已经经历过的,相对于上述提到的平台,在IaC和Kubernetes中配置服务访问更加手动和复杂。依赖人工编写的事实来源相当有限。

除了应用中注入的信息之外,还需要解决两个额外的C项(问题),以访问服务。

  1. 许可授权
  2. 网络连接性:包括出站和入站网络,防火墙,允许的IP范围等。

当通过自助服务机制(如模板目录)提供配置或当服务由其他角色或团队拥有时,通常需要授权给应用程序访问该服务所使用的身份。

此外,可能还需要配置网络访问,比如通过 AWS 安全组,这取决于服务和需要访问该服务的应用程序之间的相对位置关系。在 CloudFormation 中,这可能如下所示:

    "Properties": {  
       "GroupDescription": "允许访问 RDS PostgreSQL",  
       "SecurityGroupIngress": [  
       {  
           "CidrIp": "0.0.0.0/0",  
           "FromPort": 5432,  
           "IpProtocol": "tcp",  
           "ToPort": 5432  
       }  
       ],  
       "VpcId": { "Ref": "VPCId" }  
    },

这两种访问配置都可以自动化,但在实际操作中,使用基础设施即代码时,通常不会将这些配置自动化。最好的情况下,你可能会找到一个现成的模板或模块,足够接近你的需求,也不会太复杂。

连接到服务可以像在Heroku一样简单。但是,我们需要改变手动配置这些细节的想法。

你觉得配置服务访问有时是不是很困难,或者可能过于繁琐?你觉得哪一部分最难处理?是否对接各种服务(比如生产环境和服务开发环境中的服务)感到复杂?你是否更希望有一种自动化的方式来处理?你是否希望这里有一个事实上的标准

随时可以在这里回复,或者在我的 LinkedInX/TwitterBluesky 上给我发消息,我打算在这几个平台上分享这条信息。

如果你觉得这很有趣,,你可能会对我的《基础设施即代码和声明式配置系列文章》中的其他帖子感兴趣。在我的Infrastructure as Code and Declarative Configuration系列中可以找到更多相关内容。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP