同一VPC及子网中Lambda无法连接RDS的技术问题咨询
问题描述
我通过SST的Script和Function构造创建Lambda,用于对RDS实例执行数据库迁移。尽管SST配置显示Lambda与RDS集群处于同一VPC及PRIVATE_ISOLATED子网,但Lambda始终无法连接RDS,约130秒后出现连接超时错误。
相关配置代码
function VpcStack({stack, app}: StackContext) { const vpc = new Vpc(stack, `myapp-${app.stage}-vpc`, { subnetConfiguration: [ { name: 'private', subnetType: SubnetType.PRIVATE_ISOLATED } ] }) return {vpc} } function DatabaseStack({stack, app}: StackContext) { dependsOn(VpcStack) const database = new RDS(stack, 'database', { engine: 'postgresql13.9', scaling: { autoPause: false, minCapacity: 'ACU_2', maxCapacity: app.stage === 'production' ? undefined : 'ACU_2' }, defaultDatabaseName: 'myapp', cdk: { cluster: { clusterIdentifier: `myapp-cluster-${app.stage}`, vpc: use(VpcStack).vpc, vpcSubnets: { subnetType: SubnetType.PRIVATE_ISOLATED } } } }) return {database} } function DatabaseMigrationStack({stack}: StackContext) { dependsOn(VpcStack) dependsOn(DatabaseStack) // Perform database migrations new Script(stack, 'migrations', { onUpdate: new Function(stack, 'migrate', { handler: 'sst/migrations/src/index.migrate', nodejs: { format: 'esm', install: ['pg', 'postgres-migrations'], minify: false }, copyFiles: [{from: 'packages/schema/migrations'}], runtime: 'nodejs18.x', environment: getDatabaseEnvironment(), timeout: '5 minutes', vpc: use(VpcStack).vpc, vpcSubnets: { subnetType: SubnetType.PRIVATE_ISOLATED }, enableLiveDev: false }) }) } function getDatabaseEnvironment() { const {database} = use(DatabaseStack) return { DB_HOST: database.clusterEndpoint.hostname, DB_PORT: database.clusterEndpoint.port.toString(), DB_NAME: database.defaultDatabaseName, DB_USER: database.cdk.cluster.secret ?.secretValueFromJson('username') .toString() ?? '', DB_PASS: database.cdk.cluster.secret ?.secretValueFromJson('password') .toString() ?? '' } }
迁移代码(转译前)
import path from 'path' import {migrate as pgmigrate, type MigrateDBConfig} from 'postgres-migrations' import url from 'url' declare const process: { env: { DB_HOST: string DB_PORT: string DB_NAME: string DB_USER: string DB_PASS: string } } export async function migrate() { const dbConfig = { host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT), database: process.env.DB_NAME, user: process.env.DB_USER, password: process.env.DB_PASS, ensureDatabaseExists: true, defaultDatabase: 'postgres' } satisfies MigrateDBConfig await pgmigrate( dbConfig, path.resolve( path.dirname(url.fileURLToPath(import.meta.url)), '../../../packages/schema/migrations' ) ) }
报错信息
{ "errorType": "Error", "errorMessage": "connect ETIMEDOUT 10.0.142.195:5432", "trace": [ "Error: connect ETIMEDOUT 10.0.142.195:5432", " at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1495:16)" ] }
问题原因分析
- PRIVATE_ISOLATED子网的网络限制:PRIVATE_ISOLATED子网是完全无出站访问的隔离子网,既没有NAT网关访问互联网,也默认没有配置AWS内部服务的VPC端点。即使Lambda和RDS在同一子网,RDS集群端点的DNS解析可能依赖AWS内部DNS服务,而该子网无法访问该服务,导致无法正确解析端点地址,或者无法发起连接。
- 安全组规则缺失:
- RDS的安全组未开放5432端口给Lambda所在的安全组:SST会自动为Lambda创建专属安全组,但需要确保RDS的安全组添加入站规则,允许来自Lambda安全组的5432端口流量。
- Lambda的安全组缺少出站规则:Lambda的安全组需要允许出站到5432端口的流量,否则无法发起对RDS的连接请求。
- VPC DNS配置问题:如果VPC的
enableDnsSupport或enableDnsHostnames参数被禁用,会导致RDS集群端点的域名无法解析为内部IP,Lambda只能尝试连接错误的地址,最终超时。
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

