Spring Boot Sping Boot ECS服务无法连接到DocumentDB群集

sigwle7e  于 2023-04-20  发布在  Spring
关注(0)|答案(2)|浏览(140)

在AWS中,我有一个Sping Boot 应用程序在Docker容器中的ECS Fargate中运行,我使用CloudFormation部署了它。在同一个VPC(具有两个子网)中,我部署了一个带有单个示例的DocumentDB集群。当使用MongoDB(内存中和Docker映像)在本地运行时,Spring Boot应用程序连接良好(分别在IDE和使用Docker Compose)。
在CloudFormation中,我将DocumentDB示例作为Sping Boot 环境参数注入ECS容器定义中:

- Name: SPRING_DATA_MONGODB_HOST
  Value: !GetAtt DbCluster.Endpoint
- Name: SPRING_DATA_MONGODB_PORT
  Value: !GetAtt DbCluster.Port

当我部署CloudFormation堆栈时,我可以在控制台中转到DocumentDB集群,并看到它显示数据库集群主机如下所示:
foo-bar-xxxxxxxxxxxx.us-east-1.docdb.amazonaws.com
密码存储在Secrets Manager中并附加到数据库;该密钥显示相同的主机名。
我可以转到同一VPC中的Cloud9示例,并使用mongosh连接到foo-bar-xxxxxxxxxxxx.us-east-1.docdb.amazonaws.com
当我的Sping Boot 示例启动时,它的日志显示:
2023-04-11T23:18:39.610Z INFO 1 --- [ main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "4.8.2"}, "os": {"type": "Linux", "name": "Linux", "architecture": "amd64", "version": "5.10.173-154.642.amzn2.x86_64"}, "platform": "Java/Eclipse Adoptium/17.0.6+10"} created with settings MongoClientSettings{… clusterSettings={hosts=[foo-bar-xxxxxxxxxxxx.us-east-1.docdb.amazonaws.com:27017], srvServiceName=mongodb, mode=SINGLE, …
请注意,数据库集群主机Sping Boot 使用的是我从Cloud9连接到的同一个。
但最终Sping Boot 应用程序超时:
org.springframework.dao.DataAccessResourceFailureException: Timed out after 30000 ms while waiting to connect. Client view of cluster state is {type=UNKNOWN, servers=[{address=foo-bar-xxxxxxxxxxxx.us-east-1.docdb.amazonaws.com:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message}, caused by {java.net.SocketTimeoutException: Read timed out}}]
我甚至重新启动了ECS任务,以为数据库可能还没有初始化,但结果还是一样。
在Cloud 9中,nslookup foo-bar-xxxxxxxxxxxx.us-east-1.docdb.amazonaws.com解析为VPC内的IP地址。与ECS服务关联的安全组(AWS::EC2::SecurityGroup)没有定义出口,因此默认允许所有出口在任何端口上的任何位置(我刚刚通过控制台确认)。

如果Sping Boot 、Document DB和Cloud9都在同一个VPC中运行,那么为什么Cloud9可以很好地连接到foo-bar-xxxxxxxxxxxx.us-east-1.docdb.amazonaws.com,但Spring Boot ECS Fargate示例却不能?我应该在哪里寻找?

我还应该提到我正在使用Service Connect,其中,我设置了Cloud Map命名空间example.internal,并为ECS服务启用了Service Connect,端口名称为my-service。我知道Service Connect设置了某种sidecar“代理”容器,与我的任务容器一起运行。此Service Connect代理是否以某种方式阻止了我的服务传出请求?我是否需要做进一步的操作来允许服务连接到数据库集群?

1l5u6lss

1l5u6lss1#

超时错误表示ECS无法连接到DocumentDB,因此需要检查DocumentDB安全组的Ingress规则是否允许ECS连接

mum43rcc

mum43rcc2#

简单的答案是DocumentDB示例被配置为使用SSL/TLS,但Sping Boot Data MongoDB显然默认不支持SSL/TLS。(我很感谢https://stackoverflow.com/a/66807514提醒我这种可能性。)
最好的办法是在Sping Boot 中启用SSL/TLS,但我不知道如何在AWS中使用CloudFormation以完全自动化的方式做到这一点。(如果你知道如何做到这一点,请让我知道,但我想我必须花几天时间自己研究它,因为到目前为止我看到的例子都是“手动做这个做那个”,这是不可接受的。因此,在此期间,您可以使用CloudFormation在DocumentDB集群上关闭SSL/TLS。

如果你走这条路,请确保你的DocumentDB集群没有公共入口。(没有双关语。)最好是将Sping Boot 应用程序和DocumentDB集群放在私有子网中。(当然,更好的是在Spring Boot应用程序中启用SSL/TLS。)

首先,你不能使用自动创建的default.docdb4.0,因为它启用了TLS。创建一个自定义的AWS::DocDB::DBClusterParameterGroup

DbClusterNoTls:
    Type: AWS::DocDB::DBClusterParameterGroup
    Properties: 
      Name: docdb-4.0-no-tls
      Family: docdb4.0
      Parameters:
        # whatever other parameters you want to set here
        tls: disabled

然后在AWS::DocDB::DBCluster中引用它:

DbCluster:
    Type: AWS::DocDB::DBCluster
    Properties: 
      DBClusterIdentifier: db-cluster
      EngineVersion: 4.0.0
      DBClusterParameterGroupName: !Ref DbClusterNoTls
      …

相关问题