You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在VPC内通过aws-sdk-go从Lambda访问S3?无需NAT网关

在VPC内的Lambda中使用aws-sdk-go无需NAT访问S3

嘿,我刚好处理过一模一样的场景,完全可以实现!和Node.js的AWS SDK一样,Go版本的SDK也支持通过VPC网关端点来访问S3,不用依赖NAT网关,走的是AWS内部私有网络,速度更快还不用额外付费。下面是具体的实现步骤和注意事项:

1. 先配置VPC S3网关端点

这是核心前提,没有这个的话Lambda还是会走公网(需要NAT)。你需要在你的VPC里创建一个S3的网关类型端点:

  • 登录AWS控制台,进入VPC服务,找到「端点」→「创建端点」
  • 服务类型选「网关」,然后选S3对应的服务(格式一般是com.amazonaws.<region>.s3)
  • 选择Lambda所在的VPC,然后关联到Lambda运行的子网对应的路由表
  • 配置端点策略(默认是允许所有VPC内的资源访问S3,如果你需要更细粒度的权限可以调整)

创建完成后,检查子网的路由表,会自动添加一条目标为S3服务前缀(比如pl-xxxxxx)、下一跳为网关端点的路由条目,这样所有发往S3的请求都会走内部网络。

2. 配置aws-sdk-go客户端(无需特殊改动)

Go的AWS SDK(不管是v1还是v2)会自动识别VPC端点的存在,只要你的Lambda在配置了网关端点的VPC内,SDK会自动路由请求到内部端点,不用额外代码配置。

举个v2版本的代码示例:

package main

import (
    "context"
    "fmt"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "io"
    "os"
)

func handler(ctx context.Context) {
    // 加载默认配置:自动读取Lambda的环境变量、IAM角色、VPC端点信息
    cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-east-1")) // 替换成你的区域
    if err != nil {
        fmt.Printf("加载SDK配置失败: %v\n", err)
        return
    }

    // 创建S3客户端
    s3Client := s3.NewFromConfig(cfg)

    // 读取S3对象
    getObjInput := &s3.GetObjectInput{
        Bucket: aws.String("your-bucket-name"), // 替换成你的桶名
        Key:    aws.String("path/to/your/object"), // 替换成对象键
    }

    resp, err := s3Client.GetObject(ctx, getObjInput)
    if err != nil {
        fmt.Printf("获取S3对象失败: %v\n", err)
        return
    }
    defer resp.Body.Close()

    // 示例:将对象内容输出到控制台
    _, err = io.Copy(os.Stdout, resp.Body)
    if err != nil {
        fmt.Printf("读取对象内容失败: %v\n", err)
    }
}

如果是用v1版本的SDK,代码逻辑类似:

package main

import (
    "fmt"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
    "io"
    "os"
)

func handler() {
    // 创建会话,自动加载配置
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("us-east-1"), // 替换成你的区域
    })
    if err != nil {
        fmt.Printf("创建会话失败: %v\n", err)
        return
    }

    s3Client := s3.New(sess)

    // 读取对象逻辑和v2类似...
}

3. 权限配置要点

  • Lambda的IAM角色必须具备访问目标S3桶的权限,比如添加s3:GetObject的权限策略
  • 确保S3网关端点的策略允许该Lambda角色访问(默认策略是允许所有VPC内资源,如果你修改过策略,要确认没有限制)

为什么Node.js可以而你觉得Go用的是HTTP/HTTPS?

其实不管是Node.js还是Go的SDK,访问S3都是用HTTP/HTTPS协议,S3本身没有所谓的「S3协议」——你提到的S3协议可能是指内部的私有访问路径?实际上SDK都是通过HTTPS和S3通信,区别只是在有VPC网关端点的情况下,请求会被路由到AWS内部的私有IP,而不是公网IP,这个过程是SDK自动处理的,不用你手动指定协议。

内容的提问来源于stack exchange,提问作者kkesley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:26:00