Ubuntu EC2实例中Nordstrom Lambda Sink Connector无法读取AWS凭证
我看到你已经在Ubuntu EC2实例上设置了AWS凭证环境变量,但Nordstrom Kafka Lambda Sink Connector还是抛出了凭证加载失败的错误。咱们一步步来排查和解决这个问题:
首先,确认环境变量是否被Kafka Connect进程继承
你在shell中执行export命令设置的环境变量,只有当前shell会话中的进程才能读取到。如果Kafka Connect是在另一个会话启动的,或者用系统服务(比如systemd)运行的,它可能无法获取到这些变量。
你可以这样验证:
- 找到Kafka Connect的进程ID:
ps aux | grep connect - 查看该进程的环境变量:
cat /proc/<你的Connect进程ID>/environ | tr '\0' '\n' | grep AWS
如果看不到AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY,说明进程没读到这些变量。
解决方法:
- 修改Kafka Connect的启动脚本(比如
connect-distributed.sh),在脚本开头添加这两行:export AWS_ACCESS_KEY_ID=XXXXXXXXXX export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXX - 或者如果用systemd管理Connect服务,在服务配置文件的
[Service]块中添加:
然后重启服务生效。Environment="AWS_ACCESS_KEY_ID=XXXXXXXXXX" Environment="AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXX"
临时测试:直接在连接器配置中添加凭证
虽然生产环境不推荐,但可以先在connector.json中直接配置凭证来验证是否是环境变量的问题:
{ "name": "example-lambda-connector", "config": { "tasks.max": "1", "connector.class": "com.nordstrom.kafka.connect.lambda.LambdaSinkConnector", "topics": "example-stream", "key.converter": "org.apache.kafka.connect.storage.StringConverter", "value.converter": "org.apache.kafka.connect.storage.StringConverter", "aws.region": "ap-south-1", "aws.lambda.function.arn": "arn:aws:lambda:ap-south-1:111111111:function:example-function", "aws.lambda.invocation.timeout.ms": "60000", "aws.lambda.invocation.mode": "SYNC", "aws.lambda.batch.enabled": "false", // 添加以下两行 "aws.access.key.id": "XXXXXXXXXX", "aws.secret.access.key": "XXXXXXXXXXXXXXXXXX" } }
更新连接器后如果能正常工作,说明之前的环境变量传递有问题。
检查IAM凭证的权限
确保你使用的AWS用户有调用目标Lambda函数的权限。可以在IAM控制台给该用户添加以下权限策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:ap-south-1:111111111:function:example-function" } ] }
权限不足也可能导致凭证验证失败(虽然错误信息没明确说,但这是常见坑)。
更安全的替代方案:使用EC2 IAM角色
既然你是在EC2实例上运行Connect,最佳实践是给EC2实例附加一个IAM角色,而不是手动配置凭证:
- 在IAM控制台创建一个角色,给它添加上述的Lambda调用权限
- 在EC2控制台,找到你的实例,选择“Actions”→“Security”→“Modify IAM role”,附加刚创建的角色
- 重启Kafka Connect进程,它会自动通过EC2元数据服务获取凭证,不需要任何手动配置
这样既安全又避免了环境变量传递的问题。
你遇到的错误信息:
Caused by: java.util.concurrent.ExecutionException: com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [EnvironmentVariableCredentialsProvider: Unable to load AWS credentials from environment variables (AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY)), SystemPropertiesCredentialsProvider: Unable to load AWS credentials from Java system properties (aws.accessKeyId and aws.secretKey), com.amazonaws.auth.profile.ProfileCredentialsProvider@503af16e: profile file cannot be null, WebIdentityTokenCredentialsProvider: You must specify a value for roleArn and roleSessionName, com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@76a59f2c: The requested metadata is not found at http://169.254.169.254/latest/meta-data/iam/security-credentials/]
内容的提问来源于stack exchange,提问作者Mohan Rajan K

