EKS-Pod中运行Go程序并调用S3存储桶(无需 AK/SK)
1.Pod中运行Go程序并调用S3存储桶(无需 AK/SK)
1.1 创建 IAM 角色并授予 S3 访问权限
1.2 配置 IAM 角色的信任关系
1.3 创建 EKS 服务账户并绑定 IAM 角色
1.4 配置 Pod 使用该服务账户
1.5 在 Go 程序中调用 S3
1.6 测试和验证
参考
1.Pod中运行Go程序并调用S3存储桶(无需 AK/SK)
Kubernetes中运行 Go 程序并调用 AWS S3 存储桶.
而无需使用硬编码的 Access Key (AK) 和 Secret Key (SK).
通过使用 AWS IAM Roles for Service Accounts (IRSA) 功能
可以安全地将 AWS 权限分配给 Pod 中运行的应用程序.
1.1 创建 IAM 角色并授予 S3 访问权限
#需要在 AWS IAM 控制台中创建一个 IAM 角色,并为其附加一个允许访问 S3 存储桶的策略.
登录到 AWS 控制台并导航到 IAM 服务.
创建一个新的 IAM 角色.选择“另一个 AWS 服务”作为受信任实体.并选择“EC2”作为服务.
将以下 JSON 策略附加到角色中,以授予对指定 S3 存储桶的访问权限
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::your-bucket-name/*"
}
]
}
#注意
创建角色后记下角色的 ARN 信息
例如:`arn:aws:iam::<your-aws-account-id>:role/<your-role-name>`
1.2 配置 IAM 角色的信任关系
#要使EKS服务账户能够使用此 IAM 角色,需要修改角色的信任关系.
在 IAM 控制台中选择刚创建的 IAM 角色
编辑角色的信任关系,并添加以下内容
#假设OIDC提供商ARN
arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/EXAMPLE
#命名空间
demo
#服务账号名称
s3-access-demo
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-west-2.amazonaws.com/id/EXAMPLE:sub": "system:serviceaccount:demo:s3-access-demo"
}
}
}
]
}
1.3 创建 EKS 服务账户并绑定 IAM 角色
#在 Kubernetes 集群中,需要创建一个服务账户,并将其与上述 IAM 角色绑定.
#创建YAML文件
vim demo-service-account.yaml
...
apiVersion: v1
kind: ServiceAccount
metadata:
name: s3-access-sa
namespace: your-namespace
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/s3-dev-demo
#创建
kubectl apply -f demo-service-account.yaml
#查看
kubectl get serviceaccount -n demo
1.4 配置 Pod 使用该服务账户
#创建一个Pod定义文件
...
apiVersion: v1
kind: Pod
metadata:
name: s3-access-pod
namespace: your-namespace
spec:
serviceAccountName: s3-access-demo #指定服务账号
containers:
- name: your-container
image: your-java-image
#创建
kubectl apply -f pod.yaml
1.5 在 Go 程序中调用 S3
#示例代码
package main
import (
"fmt"
"log"
"os"
"path/filepath"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
// Config holds the configuration for the S3 upload
type Config struct {
BucketName string
Region string
FilePath string
}
// NewConfig creates a new Config with the provided values
func NewConfig(bucketName, region, filePath string) *Config {
return &Config{
BucketName: bucketName,
Region: region,
FilePath: filePath,
}
}
// UploadFileToS3 uploads a file to the specified S3 bucket
func (c *Config) UploadFileToS3() error {
// Initialize AWS session
sess, err := session.NewSession(&aws.Config{
Region: aws.String(c.Region),
})
if err != nil {
return fmt.Errorf("failed to create AWS session: %w", err)
}
// Create S3 service client
svc := s3.New(sess)
// Open the file
file, err := os.Open(c.FilePath)
if err != nil {
return fmt.Errorf("failed to open file %s: %w", c.FilePath, err)
}
defer file.Close()
// Get the file name to use as the S3 key
key := filepath.Base(c.FilePath)
// Upload the file to S3
_, err = svc.PutObject(&s3.PutObjectInput{
Bucket: aws.String(c.BucketName),
Key: aws.String(key),
Body: file,
})
if err != nil {
return fmt.Errorf("failed to upload file to S3: %w", err)
}
log.Printf("Successfully uploaded %s to s3://%s/%s", c.FilePath, c.BucketName, key)
return nil
}
func main() {
// Replace these values with your S3 bucket name, AWS region, and the file path you want to upload
bucketName := "your-bucket-name" //存储桶名称
region := "your-region" //存储桶地区
filePath := "file.txt" //实际要上传的文件路径
// Create configuration
config := NewConfig(bucketName, region, filePath)
// Upload the file to S3
if err := config.UploadFileToS3(); err != nil {
log.Fatalf("Error: %v", err)
}
}
1.6 测试和验证
构建您的 Go 应用程序并将其打包为 Docker 镜像.
将镜像推送到您的镜像仓库.
在 Kubernetes 中部署 Pod 并验证是否能够成功访问 S3 存储桶.
通过以上步骤,可以在 Kubernetes Pod 中运行 Go 程序并安全地访问 AWS S3 存储桶,而无需硬编码 AK/SK.
AWS SDK 将自动使用与服务账户绑定的 IAM 角色来获取临时凭证,从而简化安全管理.
评论区