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

EKS使用IRSA访问Glue Schema Registry报AccessDenied异常

EKS IRSA接入Glue Schema Registry访问被拒问题排查

问题背景

我们在EKS集群中使用IAM Roles for Service Accounts(IRSA)实现安全的AWS资源访问,近期计划接入MSK与Glue Schema Registry服务,使用的SDK为aws-glue-schema-registry。
目前IRSA对接Secrets Manager等其他AWS服务均运行正常,但尝试连接Glue Schema Registry时出现如下报错:

software.amazon.awssdk.services.glue.model.AccessDeniedException: User: arn:aws:sts::****************:assumed-role/NODE_ROLE/i-833fu7203a782371 is not authorized to perform: glue:GetSchemaByDefinition on resource: arn:aws:glue:us-east-1:****************:registry/schema-registry because no identity-based policy allows the glue:GetSchemaByDefinition action (Service: Glue, Status Code: 400, Request ID: 74269899-8eaf-48dc-831b-7j271209231j71)

现有配置

IAM权限配置

当前给IRSA绑定的角色配置了如下权限策略:

{
    "Statement": [
        {
            "Action": [
                "glue:*",
                "kafka:*",
                "secretsmanager:ListSecretVersionIds",
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret"
            ],
            "Effect": "Allow",
            "Resource": "*",
            "Sid": ""
        }
    ],
    "Version": "2012-10-17"
}

pom.xml依赖配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.kafka</groupId>
    <artifactId>msk-poc-with-schema-reg</artifactId>
    <version>2022.24.36</version>
    <name>msk-poc-with-schema-reg</name>
    <description>demo project for demo with glue</description>
    <properties>
        <java.version>15</java.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-aws-secrets-manager-config</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
            <version>3.0.5</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.glue</groupId>
            <artifactId>schema-registry-serde</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-core</artifactId>
            <version>1.12.238</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-context</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.avro</groupId>
            <artifactId>avro</artifactId>
            <version>1.8.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>

    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

            <plugin>
                <groupId>org.apache.avro</groupId>
                <artifactId>avro-maven-plugin</artifactId>
                <version>1.8.2</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>schema</goal>
                        </goals>
                        <configuration>
                            <sourceDirectory>src/main/resources/avro</sourceDirectory>

                            <outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
                            <stringType>String</stringType>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

Glue配置类

package com.kafka.gluedemo.config.msk;

import com.amazonaws.services.schemaregistry.serializers.GlueSchemaRegistryKafkaSerializer;
import com.amazonaws.services.schemaregistry.utils.AWSSchemaRegistryConstants;
import com.amazonaws.services.schemaregistry.utils.AvroRecordType;
import com.kafka.gluedemo.config.glue.GlueProperties;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

@Configuration
public class MskConfig {
    private final GlueProperties glueProperties;
    private final MskProperties mskProperties;

    public MskConfig(final GlueProperties glueProperties,
                     final MskProperties mskProperties) {
        this.glueProperties = glueProperties;
        this.mskProperties = mskProperties;
    }

    @Bean
    public Properties mskConfigProperties() {
        //producer config for MSK
        Properties props = new Properties();
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, mskProperties.getProducer().getBootstrapServers());
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, GlueSchemaRegistryKafkaSerializer.class.getName());

        props.put(AWSSchemaRegistryConstants.DATA_FORMAT, glueProperties.getDataFormat());
        props.put(AWSSchemaRegistryConstants.AWS_REGION, glueProperties.getRegion());
        props.put(AWSSchemaRegistryConstants.REGISTRY_NAME, glueProperties.getRegistryName());
        props.put(AWSSchemaRegistryConstants.AVRO_RECORD_TYPE, AvroRecordType.GENERIC_RECORD.getName());
        props.put(AWSSchemaRegistryConstants.SCHEMA_AUTO_REGISTRATION_SETTING, true);
        props.put(AWSSchemaRegistryConstants.SCHEMA_NAMING_GENERATION_CLASS, CustomAWSSchemaNamingStrategy.class.getName());
        return props;
    }

    @Bean("producer")
    public KafkaProducer<String, Object> kafkaProducer(final Properties mskConfigProperties) {
        return new KafkaProducer<String, Object>(mskConfigProperties);
    }
}

根因定位

从报错信息可以直接定位核心问题:发起Glue API调用的身份是EKS工作节点的EC2实例角色NODE_ROLE,而非预期绑定了Glue全量权限的IRSA角色。这说明Glue Schema Registry SDK没有正确加载IRSA注入的Web Identity凭证,默认凭证链回退到了EC2元数据服务拿到的节点角色,而节点角色未配置Glue操作权限,最终触发访问拒绝。

排查与修复步骤

  • 先验证IRSA环境变量注入是否正常:进入业务Pod执行env | grep AWS,确认存在AWS_WEB_IDENTITY_TOKEN_FILE、AWS_ROLE_ARN两个环境变量。如果不存在,检查ServiceAccount上的eks.amazonaws.com/role-arn注解是否配置正确,注解配置后需要重启Pod才能生效。
  • 排除Spring Cloud AWS的凭证覆盖问题:引入的spring-cloud-starter-aws-secrets-manager-config会自动配置全局AWS凭证提供者,默认优先拉取EC2实例元数据的节点角色凭证,会覆盖SDK默认的IRSA凭证链。可以在Spring配置中关闭自动凭证配置,或者直接给Glue SDK显式指定凭证提供者,避免全局配置干扰。
  • 显式给Glue Schema Registry传入IRSA凭证提供者:不要依赖SDK自动发现凭证,在MSK配置中新增凭证提供者配置,直接读取Pod内的IRSA token文件构建凭证,示例代码:
import com.amazonaws.auth.STSAssumeRoleWithWebIdentityCredentialsProvider;
import java.nio.file.Paths;

// 构建适配IRSA的凭证提供者
STSAssumeRoleWithWebIdentityCredentialsProvider irsaCredentialsProvider = STSAssumeRoleWithWebIdentityCredentialsProvider.builder()
        .roleArn(System.getenv("AWS_ROLE_ARN"))
        .roleSessionName("glue-sr-access-session")
        .webIdentityTokenFile(Paths.get(System.getenv("AWS_WEB_IDENTITY_TOKEN_FILE")))
        .build();
// 传入Glue配置
props.put(AWSSchemaRegistryConstants.AWS_CREDENTIALS_PROVIDER, irsaCredentialsProvider);
  • 对齐SDK版本避免类冲突:当前使用的schema-registry-serde 1.1.10和aws-java-sdk-core 1.12.238存在版本不匹配问题,建议引入com.amazonaws:aws-java-sdk-bom统一管理所有AWS SDK版本,避免内部类冲突导致凭证加载逻辑失效。
  • 兜底验证:临时给EKS节点角色NODE_ROLE加上glue:GetSchemaByDefinition权限,如果加完后访问立刻恢复,可100%确认是凭证加载逻辑错误,SDK始终在使用节点角色而非IRSA角色。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:54:25