EC2上Docker容器内Go应用无法连接ElastiCache与RDS
问题解决:Docker容器内Go应用无法连接AWS RDS和ElastiCache
PostgreSQL连接错误(pq: no pg_hba.conf entry...)
问题1:用户名被错误追加逗号
看你的数据库连接字符串拼接代码:
DBstring := fmt.Sprintf("host =%v port=%d database=%s sslmode=%s user=%v", conf.Database.IP, conf.Database.Port, conf.Database.Name, conf.Database.SSLMode, conf.Database.Username) if conf.Database.Password != "" { DBstring = fmt.Sprintf("%s, password=%s", DBstring, conf.Database.Password) }
这段代码会生成类似host=xxx port=5432 database=postgres sslmode=disable user=postgres, password=xxx的字符串,用户名被错误加上了逗号(变成postgres,),导致RDS识别到无效用户名,触发pg_hba.conf错误。
修复方法:拼接密码时在逗号前添加空格,或直接用空格分隔参数:
// 方案1:用空格分隔参数 DBstring = fmt.Sprintf("%s password=%s", DBstring, conf.Database.Password) // 方案2:逗号前加空格避免截断用户名 DBstring = fmt.Sprintf("%s , password=%s", DBstring, conf.Database.Password)
问题2:SSL加密设置不匹配
错误提示no encryption,说明你的Go应用关闭了SSL连接,但AWS RDS PostgreSQL默认要求启用SSL。检查conf.Database.SSLMode的值,若为disable需改为require(或更高安全级别):
DBstring := fmt.Sprintf("host=%v port=%d database=%s sslmode=require user=%v", conf.Database.IP, conf.Database.Port, conf.Database.Name, conf.Database.Username)
Redis连接错误(i/o timeout)
检查ElastiCache安全组入站规则
虽然EC2、ElastiCache同属一个安全组,仍需确认ElastiCache的安全组入站规则允许同安全组的TCP 6379端口流量:
- 登录AWS控制台,进入ElastiCache实例关联的安全组
- 添加入站规则:类型选
Redis (6379),源选择当前安全组ID(格式为sg-xxxxxx)
确认Redis地址正确性
检查Go代码中conf.Redis.IP是否为ElastiCache的私有IP地址(单节点实例直接用私有IP,集群实例用配置端点),确保端口为6379。可在EC2本机执行telnet 172.x.y.z 6379验证连通性,能通则地址无误,否则检查地址是否写错。
容器内网络连通性测试
进入容器内直接测试Redis连通性,排查容器内部网络限制:
docker exec -it test telnet 172.x.y.z 6379
若容器内telnet也超时,需检查EC2本机iptables规则或容器镜像是否自带防火墙限制(EC2本机能连则此可能性较低)。
额外验证步骤
- 启动容器后查看日志输出的数据库连接字符串和Redis地址,确认参数无错误(用户名无多余符号、IP/端口正确、SSL模式匹配)
- 检查RDS控制台的"连接"设置,确认是否允许EC2实例IP访问,且SSL要求已开启
内容的提问来源于stack exchange,提问作者nrs16
相关产品推荐
相关产品推荐

