通过Kubernetes创建AWS NLB时遭遇403权限错误求助
排查AWS Load Balancer Controller创建NLB时的403权限错误
尝试通过Kubernetes Service创建AWS Network Load Balancer(NLB),已按AWS官方文档部署AWS Load Balancer Controller,部署流程无异常,但应用带注解的Service时触发以下403权限错误:
"error":"UnauthorizedOperation: You are not authorized to perform this operation.\n\tstatus code: 403"
相关配置文件
1. ServiceAccount配置(aws-load-balancer-controller-service-account.yaml)
apiVersion: v1 kind: ServiceAccount metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: aws-load-balancer-controller name: aws-load-balancer-controller namespace: kube-system annotations: eks.amazonaws.com/role-arn: arn:aws:iam::588213647772:role/AmazonEKSLoadBalancerControllerRole
2. IAM角色信任策略(load-balancer-role-trust-policy.json)
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::acc_id:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/oidc_id" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.us-east-1.amazonaws.com/id/oidc_id:aud": "sts.amazonaws.com", "oidc.eks.us-east-1.amazonaws.com/id/oidc_id:sub": "system:serviceaccount:kube-system:aws-load-balancer-controller" } } } ] }
3. IAM权限策略(iam-policy.json)
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iam:CreateServiceLinkedRole" ], "Resource": "*", "Condition": { "StringEquals": { "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com" } } }, { "Effect": "Allow", "Action": [ "ec2:DescribeAccountAttributes", "ec2:DescribeAddresses", "ec2:DescribeAvailabilityZones", "ec2:DescribeInternetGateways", "ec2:DescribeVpcs", "ec2:DescribeVpcPeeringConnections", "ec2:DescribeSubnets", "ec2:DescribeSecurityGroups", "ec2:DescribeInstances", "ec2:DescribeNetworkInterfaces", "ec2:DescribeTags", "ec2:GetCoipPoolUsage", "ec2:DescribeCoipPools", "elasticloadbalancing:DescribeLoadBalancers", "elasticloadbalancing:DescribeLoadBalancerAttributes", "elasticloadbalancing:DescribeListeners", "elasticloadbalancing:DescribeListenerCertificates", "elasticloadbalancing:DescribeSSLPolicies", "elasticloadbalancing:DescribeRules", "elasticloadbalancing:DescribeTargetGroups", "elasticloadbalancing:DescribeTargetGroupAttributes", "elasticloadbalancing:DescribeTargetHealth", "elasticloadbalancing:DescribeTags" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "cognito-idp:DescribeUserPoolClient", "acm:ListCertificates", "acm:DescribeCertificate", "iam:ListServerCertificates", "iam:GetServerCertificate", "waf-regional:GetWebACL", "waf-regional:GetWebACLForResource", "waf-regional:AssociateWebACL", "waf-regional:DisassociateWebACL", "wafv2:GetWebACL", "wafv2:GetWebACLForResource", "wafv2:AssociateWebACL", "wafv2:DisassociateWebACL", "shield:GetSubscriptionState", "shield:DescribeProtection", "shield:CreateProtection", "shield:DeleteProtection" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "ec2:AuthorizeSecurityGroupIngress", "ec2:RevokeSecurityGroupIngress" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "ec2:CreateSecurityGroup" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "ec2:CreateTags" ], "Resource": "arn:aws:ec2:*:*:security-group/*", "Condition": { "StringEquals": { "ec2:CreateAction": "CreateSecurityGroup" }, "Null": { "aws:RequestTag/elbv2.k8s.aws/cluster": "false" } } }, { "Effect": "Allow", "Action": [ "ec2:CreateTags", "ec2:DeleteTags" ], "Resource": "arn:aws:ec2:*:*:security-group/*", "Condition": { "Null": { "aws:RequestTag/elbv2.k8s.aws/cluster": "true", "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" } } }, { "Effect": "Allow", "Action": [ "ec2:AuthorizeSecurityGroupIngress", "ec2:RevokeSecurityGroupIngress", "ec2:DeleteSecurityGroup" ], "Resource": "*", "Condition": { "Null": { "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" } } }, { "Effect": "Allow", "Action": [ "elasticloadbalancing:CreateLoadBalancer", "elasticloadbalancing:CreateTargetGroup" ], "Resource": "*", "Condition": { "Null": { "aws:RequestTag/elbv2.k8s.aws/cluster": "false" } } }, { "Effect": "Allow", "Action": [ "elasticloadbalancing:CreateListener", "elasticloadbalancing:DeleteListener", "elasticloadbalancing:CreateRule", "elasticloadbalancing:DeleteRule" ], "Resource": "*" }, { "Effect": "Allow", "Action": [ "elasticloadbalancing:AddTags", "elasticloadbalancing:RemoveTags" ], "Resource": [ "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" ], "Condition": { "Null": { "aws:RequestTag/elbv2.k8s.aws/cluster": "true", "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" } } }, { "Effect": "Allow", "Action": [ "elasticloadbalancing:AddTags", "elasticloadbalancing:RemoveTags" ], "Resource": [ "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*", "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*", "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*", "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*" ] }, { "Effect": "Allow", "Action": [ "elasticloadbalancing:AddTags" ], "Resource": [ "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" ], "Condition": { "StringEquals": { "elasticloadbalancing:CreateAction": [ "CreateTargetGroup", "CreateLoadBalancer" ] }, "Null": { "aws:RequestTag/elbv2.k8s.aws/cluster": "false" } } }, { "Effect": "Allow", "Action": [ "elasticloadbalancing:ModifyLoadBalancerAttributes", "elasticloadbalancing:SetIpAddressType", "elasticloadbalancing:SetSecurityGroups", "elasticloadbalancing:SetSubnets", "elasticloadbalancing:DeleteLoadBalancer", "elasticloadbalancing:ModifyTargetGroup", "elasticloadbalancing:ModifyTargetGroupAttributes", "elasticloadbalancing:DeleteTargetGroup" ], "Resource": "*", "Condition": { "Null": { "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" } } }, { "Effect": "Allow", "Action": [ "elasticloadbalancing:RegisterTargets", "elasticloadbalancing:DeregisterTargets" ], "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" }, { "Effect": "Allow", "Action": [ "elasticloadbalancing:SetWebAcl", "elasticloadbalancing:ModifyListener", "elasticloadbalancing:AddListenerCertificates", "elasticloadbalancing:RemoveListenerCertificates", "elasticloadbalancing:ModifyRule" ], "Resource": "*" } ] }
4. aws-auth ConfigMap配置
apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes rolearn: arn:aws:iam::acc_id:role/ROLE-FOR-STAGE-ME-DS-EKS-WORKER username: system:node:{{EC2PrivateDNSName}} - groups: - system:serviceaccounts:kube-system rolearn: arn:aws:iam::acc_id:role/AmazonEKSLoadBalancerControllerRole username: system:serviceaccount:kube-system:aws-load-balancer-controller kind: ConfigMap metadata: creationTimestamp: "2022-10-05T12:18:19Z" name: aws-auth namespace: kube-system resourceVersion: "36251668" uid: b83e4116-ff0c-41e9-8507-2ba68c11f1dd
策略使用情况截图

排查方向
- 验证OIDC提供商一致性:对比信任策略中的OIDC提供商ARN与EKS集群实际OIDC issuer(通过
aws eks describe-cluster --name <集群名> --query "cluster.identity.oidc.issuer"获取),确保完全匹配,包括账号ID、区域、OIDC ID。 - 检查IAM角色与策略绑定:确认
AmazonEKSLoadBalancerControllerRole已正确关联AWSLoadBalancerControllerIAMPolicy,且策略权限覆盖NLB创建全流程(如elasticloadbalancing:CreateLoadBalancer、ec2:CreateSecurityGroup等核心操作)。 - 校验ServiceAccount与IAM角色映射:检查ServiceAccount的
eks.amazonaws.com/role-arn注解是否指向正确的IAM角色ARN,同时确认信任策略中sub字段与ServiceAccount的system:serviceaccount:kube-system:aws-load-balancer-controller完全一致,无命名空间或名称拼写错误。 - 查看Controller日志定位具体操作:执行
kubectl logs -n kube-system deployment/aws-load-balancer-controller获取详细错误日志,明确触发403的具体API操作,针对性检查对应权限是否缺失。 - 确认服务链接角色权限:若为首次创建NLB,需确保IAM角色有权限创建
AWSServiceRoleForElasticLoadBalancing服务链接角色,可手动执行创建命令后重试:aws iam create-service-linked-role --aws-service-name elasticloadbalancing.amazonaws.com。 - 统一账号ID配置:检查所有配置文件中的AWS账号ID(
acc_id、588213647772)是否一致,避免混用不同账号的资源。
内容的提问来源于stack exchange,提问作者Muhammed Adil
相关产品推荐
相关产品推荐

