无需安装aws-cli,获取Docker镜像中AWS SSM参数的简便方法
无需安装aws-cli获取AWS SSM参数的简便方案
针对你在Docker镜像entrypoint中获取SSM参数并注入环境变量的需求,以下是几个轻量、简便的替代方案,避免安装完整aws-cli带来的体积膨胀:
1. 使用Go编译的轻量单二进制工具
Go语言编译的程序是单文件、无依赖的,体积通常只有几MB,非常适合嵌入Docker镜像。你可以自己写一个极简的SSM参数获取工具,或者用现成的开源实现。
示例:多阶段构建Dockerfile
# 第一阶段:编译Go工具 FROM golang:alpine AS builder RUN apk add --no-cache git WORKDIR /app # 编写极简SSM参数获取程序 RUN echo 'package main; import ("github.com/aws/aws-sdk-go/aws"; "github.com/aws/aws-sdk-go/aws/session"; "github.com/aws/aws-sdk-go/service/ssm"; "fmt"; "os")' > main.go RUN echo 'func main() { sess, _ := session.NewSession(&aws.Config{Region: aws.String(os.Getenv("AWS_REGION"))}); svc := ssm.New(sess); input := &ssm.GetParameterInput{Name: aws.String(os.Args[1]), WithDecryption: aws.Bool(true)};' >> main.go RUN echo 'result, _ := svc.GetParameter(input); fmt.Println(*result.Parameter.Value) }' >> main.go RUN go build -ldflags="-s -w" -o ssm-get-param main.go # 第二阶段:构建最终镜像 FROM alpine:latest COPY --from=builder /app/ssm-get-param /usr/local/bin/ COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh中使用
#!/bin/sh # 获取SSM参数并注入环境变量 export DB_PASSWORD=$(ssm-get-param /prod/db/password) export API_KEY=$(ssm-get-param /prod/api/key) # 执行应用程序 exec "$@"
2. 使用精简Python依赖(比aws-cli轻量)
如果你的镜像已经包含Python,或者可以安装最小化的Python环境,只安装boto3核心依赖即可,体积远小于完整aws-cli。
安装依赖(Dockerfile中)
FROM alpine:latest RUN apk add --no-cache python3 py3-pip RUN pip install --no-cache-dir boto3==1.28.0 COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh中的Python脚本片段
#!/bin/sh # 封装SSM参数获取函数 get_ssm_param() { python3 -c " import boto3 import os ssm = boto3.client('ssm', region_name=os.getenv('AWS_REGION')) resp = ssm.get_parameter(Name='$1', WithDecryption=True) print(resp['Parameter']['Value']) " } # 注入环境变量 export DB_PASSWORD=$(get_ssm_param /prod/db/password) export API_KEY=$(get_ssm_param /prod/api/key) exec "$@"
3. 基于curl的简化签名方案(适合无额外依赖场景)
如果不想添加任何二进制工具或Python,可利用AWS IAM角色的临时凭证(适用于EC2、ECS、EKS等AWS托管环境),通过curl调用SSM API,配合简化的签名逻辑。
entrypoint.sh示例(利用ECS/EC2元数据获取凭证)
#!/bin/sh AWS_REGION="us-east-1" # 获取IAM角色临时凭证(EC2/ECS环境) ROLE_NAME=$(curl -s http://169.254.170.2/v2/metadata/iam/security-credentials/ | jq -r '.') CREDS=$(curl -s http://169.254.170.2/v2/metadata/iam/security-credentials/$ROLE_NAME) ACCESS_KEY=$(echo $CREDS | jq -r '.AccessKeyId') SECRET_KEY=$(echo $CREDS | jq -r '.SecretAccessKey') SESSION_TOKEN=$(echo $CREDS | jq -r '.Token') # 封装SSM参数获取函数 get_ssm_param() { PARAM_NAME=$1 SERVICE="ssm" DATE=$(date -u +"%Y%m%dT%H%M%SZ") DATE_SHORT=$(date -u +"%Y%m%d") # 构造规范请求和待签名字符串 CANONICAL_REQUEST="GET /$SERVICE/$AWS_REGION/parameter$PARAM_NAME host:ssm.$AWS_REGION.amazonaws.com x-amz-date:$DATE x-amz-security-token:$SESSION_TOKEN host;x-amz-date;x-amz-security-token $(echo -n "GET\n/$SERVICE/$AWS_REGION/parameter$PARAM_NAME\n\nhost:ssm.$AWS_REGION.amazonaws.com\nx-amz-date:$DATE\nx-amz-security-token:$SESSION_TOKEN\n\nhost;x-amz-date;x-amz-security-token" | sha256sum | awk '{print $1}')" STRING_TO_SIGN="AWS4-HMAC-SHA256 $DATE $DATE_SHORT/$AWS_REGION/$SERVICE/aws4_request $(echo -n "$CANONICAL_REQUEST" | sha256sum | awk '{print $1}')" # 生成签名 KEY=$(echo -n "AWS4$SECRET_KEY" | openssl dgst -sha256 -binary -hmac "$DATE_SHORT") KEY=$(echo -n "$KEY" | openssl dgst -sha256 -binary -hmac "$AWS_REGION") KEY=$(echo -n "$KEY" | openssl dgst -sha256 -binary -hmac "$SERVICE") KEY=$(echo -n "$KEY" | openssl dgst -sha256 -binary -hmac "aws4_request") SIGNATURE=$(echo -n "$STRING_TO_SIGN" | openssl dgst -sha256 -hex -hmac "$KEY" | awk '{print $2}') # 发起请求并返回参数值 curl -s "https://ssm.$AWS_REGION.amazonaws.com/$SERVICE/$AWS_REGION/parameter$PARAM_NAME?WithDecryption=true" \ -H "x-amz-date: $DATE" \ -H "x-amz-security-token: $SESSION_TOKEN" \ -H "Authorization: AWS4-HMAC-SHA256 Credential=$ACCESS_KEY/$DATE_SHORT/$AWS_REGION/$SERVICE/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=$SIGNATURE" | jq -r '.Parameter.Value' } # 注入环境变量 export DB_PASSWORD=$(get_ssm_param /prod/db/password) export API_KEY=$(get_ssm_param /prod/api/key) exec "$@"
注意:此方案需要镜像中安装curl、jq和openssl(alpine中可通过apk add --no-cache curl jq openssl安装),但这些工具的体积远小于aws-cli。
内容的提问来源于stack exchange,提问作者PGT
相关产品推荐
相关产品推荐

