AWS Load Balancer Controller 在部署 Ingress 时成功创建 ALB,但无法在 CDK 代码中获取 DNS Name

AWS Load Balancer Controller successfully creates ALB when Ingress is deployed, but unable to get DNS Name in CDK code

我最初将此问题作为 AWS Load Balancer Controller GitHub 项目上的一个问题发布在这里:https://github.com/kubernetes-sigs/aws-load-balancer-controller/issues/2069

在尝试从控制器创建的 ALB 中获取 loadBalacnerDnsName 时,我看到一些我无法追踪或解释的奇怪行为。我在 CDK 项目中使用 AWS Load Balancer Controller v2.2.0。我部署的入口触发了 ALB 的供应,并且该 ALB 可以连接到我在 EKS 中的 K8s 工作负载 运行。

这是我的问题:我正在尝试自动创建指向负载均衡器 loadBalancerDnsName 的 Route53 A 记录,但我在 CDK 脚本中得到的 loadBalancerDnsName与堆栈部署完成后 AWS 控制台中显示的 loadBalancerDnsName 不同。控制台中的值是正确的,我可以从那个 URL 得到响应。我的 CDK 脚本将 DnsName 的值输出为 CfnOutput 值,但是 URL 没有指向任何东西。

在 CDK 中,我尝试使用 KubernetesObjectValue 从负载均衡器获取 DNS 名称。这不起作用(请参阅此相关问题:https://github.com/aws/aws-cdk/issues/14933),因此我尝试使用 CDK 的 .fromLookup 查找负载均衡器并使用我通过入口注释添加的标签:

    const alb = elbv2.ApplicationLoadBalancer.fromLookup(this, 'appAlb', {
      loadBalancerTags: {
        Environment: 'test',
      },
    });

这是我 运行 参与的项目:https://github.com/briancaffey/django-cdk

以下是一些相关文件:

使用 CDK 安装 AWS 负载均衡器控制器:https://github.com/briancaffey/django-cdk/blob/main/src/eks/awslbc/index.ts

入口对象定义: https://github.com/briancaffey/django-cdk/tree/main/src/eks/resources/ingress

ALB fromLookup 生成错误 DnsName 的方法: https://github.com/briancaffey/django-cdk/blob/main/src/django-eks.ts#L297

是否有人对可能导致此问题的原因或我如何进行调试有任何想法?如果在我的调试过程中还有其他有助于收集的信息,请告诉我。

我不确定这是否可行,但似乎负载均衡器可能已创建,分配了一个 DnsName,然后可能在某个时候配置失败并尝试创建另一个 ALB,该 ALB 具有另一个 DnsName成功。

更新:以下是来自 AWS 负载均衡器控制器部署的日志:

~/git/github/django-cdk$ kubectl logs deployment/goeksstackdjangoekssamplealbingresscontroller48a16415-aws-load -n kube-system
Found 2 pods, using pod/goeksstackdjangoekssamplealbingresscontroller48a16415-aws-c6d8h
{"level":"info","ts":1623379830.094481,"msg":"version","GitVersion":"v2.2.0","GitCommit":"68c417a7ea37ff153f053d9ffef1cc5c70d7e211","BuildDate":"2021-05-14T21:49:05+0000"}
{"level":"info","ts":1623379830.1275837,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":8080"}
{"level":"info","ts":1623379830.1310954,"logger":"setup","msg":"adding health check for controller"}
{"level":"info","ts":1623379830.1312613,"logger":"controller-runtime.webhook","msg":"registering webhook","path":"/mutate-v1-pod"}
{"level":"info","ts":1623379830.131368,"logger":"controller-runtime.webhook","msg":"registering webhook","path":"/mutate-elbv2-k8s-aws-v1beta1-targetgroupbinding"}
{"level":"info","ts":1623379830.131444,"logger":"controller-runtime.webhook","msg":"registering webhook","path":"/validate-elbv2-k8s-aws-v1beta1-targetgroupbinding"}
{"level":"info","ts":1623379830.1315207,"logger":"controller-runtime.webhook","msg":"registering webhook","path":"/validate-networking-v1beta1-ingress"}
{"level":"info","ts":1623379830.1316643,"logger":"setup","msg":"starting podInfo repo"}
I0611 02:50:32.131767       1 leaderelection.go:242] attempting to acquire leader lease  kube-system/aws-load-balancer-controller-leader...
{"level":"info","ts":1623379832.1318467,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
I0611 02:50:32.150030       1 leaderelection.go:252] successfully acquired lease kube-system/aws-load-balancer-controller-leader
{"level":"info","ts":1623379832.2321155,"logger":"controller-runtime.webhook.webhooks","msg":"starting webhook server"}
{"level":"info","ts":1623379832.2321231,"logger":"controller","msg":"Starting EventSource","reconcilerGroup":"elbv2.k8s.aws","reconcilerKind":"TargetGroupBinding","controller":"targetGroupBinding","source":"kind source: /, Kind="}
{"level":"info","ts":1623379832.2321854,"logger":"controller","msg":"Starting EventSource","reconcilerGroup":"elbv2.k8s.aws","reconcilerKind":"TargetGroupBinding","controller":"targetGroupBinding","source":"kind source: /, Kind="}
{"level":"info","ts":1623379832.2322075,"logger":"controller","msg":"Starting EventSource","reconcilerGroup":"elbv2.k8s.aws","reconcilerKind":"TargetGroupBinding","controller":"targetGroupBinding","source":"kind source: /, Kind="}
{"level":"info","ts":1623379832.2323742,"logger":"controller","msg":"Starting EventSource","controller":"ingress","source":"channel source: 0xc00053a820"}
{"level":"info","ts":1623379832.2324347,"logger":"controller","msg":"Starting EventSource","controller":"ingress","source":"channel source: 0xc00053a870"}
{"level":"info","ts":1623379832.2324626,"logger":"controller","msg":"Starting EventSource","controller":"ingress","source":"kind source: /, Kind="}
{"level":"info","ts":1623379832.2324827,"logger":"controller","msg":"Starting EventSource","controller":"ingress","source":"kind source: /, Kind="}
{"level":"info","ts":1623379832.2325017,"logger":"controller","msg":"Starting EventSource","controller":"ingress","source":"kind source: /, Kind="}
{"level":"info","ts":1623379832.232624,"logger":"controller","msg":"Starting EventSource","controller":"service","source":"kind source: /, Kind="}
{"level":"info","ts":1623379832.2326622,"logger":"controller","msg":"Starting Controller","controller":"service"}
{"level":"info","ts":1623379832.232741,"logger":"controller-runtime.certwatcher","msg":"Updated current TLS certificate"}
{"level":"info","ts":1623379832.2328286,"logger":"controller-runtime.webhook","msg":"serving webhook server","host":"","port":9443}
{"level":"info","ts":1623379832.2332337,"logger":"controller-runtime.certwatcher","msg":"Starting certificate watcher"}
{"level":"info","ts":1623379832.3324778,"logger":"controller","msg":"Starting EventSource","reconcilerGroup":"elbv2.k8s.aws","reconcilerKind":"TargetGroupBinding","controller":"targetGroupBinding","source":"kind source: /, Kind="}
{"level":"info","ts":1623379832.3327508,"logger":"controller","msg":"Starting workers","controller":"service","worker count":3}
{"level":"info","ts":1623379832.332836,"logger":"controller","msg":"Starting EventSource","controller":"ingress","source":"channel source: 0xc00053a8c0"}
{"level":"info","ts":1623379832.3328674,"logger":"controller","msg":"Starting EventSource","controller":"ingress","source":"kind source: /, Kind="}
{"level":"info","ts":1623379832.4330835,"logger":"controller","msg":"Starting Controller","reconcilerGroup":"elbv2.k8s.aws","reconcilerKind":"TargetGroupBinding","controller":"targetGroupBinding"}
{"level":"info","ts":1623379832.4333706,"logger":"controller","msg":"Starting workers","reconcilerGroup":"elbv2.k8s.aws","reconcilerKind":"TargetGroupBinding","controller":"targetGroupBinding","worker count":3}
{"level":"info","ts":1623379832.433311,"logger":"controller","msg":"Starting EventSource","controller":"ingress","source":"kind source: /, Kind="}
{"level":"info","ts":1623379832.4334028,"logger":"controller","msg":"Starting Controller","controller":"ingress"}
{"level":"info","ts":1623379832.433451,"logger":"controller","msg":"Starting workers","controller":"ingress","worker count":3}
{"level":"info","ts":1623379851.8822243,"logger":"controllers.ingress","msg":"successfully built model","model":"{\"id\":\"app/app-ingress\",\"resources\":{\"AWS::EC2::SecurityGroup\":{\"ManagedLBSecurityGroup\":{\"spec\":{\"groupName\":\"k8s-app-appingre-64b5836d2b\",\"description\":\"[k8s] Managed SecurityGroup for LoadBalancer\",\"tags\":{\"Environment\":\"test\"},\"ingress\":[{\"ipProtocol\":\"tcp\",\"fromPort\":80,\"toPort\":80,\"ipRanges\":[{\"cidrIP\":\"0.0.0.0/0\"}]}]}}},\"AWS::ElasticLoadBalancingV2::Listener\":{\"80\":{\"spec\":{\"loadBalancerARN\":{\"$ref\":\"#/resources/AWS::ElasticLoadBalancingV2::LoadBalancer/LoadBalancer/status/loadBalancerARN\"},\"port\":80,\"protocol\":\"HTTP\",\"defaultActions\":[{\"type\":\"fixed-response\",\"fixedResponseConfig\":{\"contentType\":\"text/plain\",\"statusCode\":\"404\"}}],\"tags\":{\"Environment\":\"test\"}}}},\"AWS::ElasticLoadBalancingV2::ListenerRule\":{\"80:1\":{\"spec\":{\"listenerARN\":{\"$ref\":\"#/resources/AWS::ElasticLoadBalancingV2::Listener/80/status/listenerARN\"},\"priority\":1,\"actions\":[{\"type\":\"forward\",\"forwardConfig\":{\"targetGroups\":[{\"targetGroupARN\":{\"$ref\":\"#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/app/app-ingress-api-http:80/status/targetGroupARN\"}}]}}],\"conditions\":[{\"field\":\"path-pattern\",\"pathPatternConfig\":{\"values\":[\"/*\"]}}],\"tags\":{\"Environment\":\"test\"}}}},\"AWS::ElasticLoadBalancingV2::LoadBalancer\":{\"LoadBalancer\":{\"spec\":{\"name\":\"k8s-app-appingre-df49e963f5\",\"type\":\"application\",\"scheme\":\"internet-facing\",\"ipAddressType\":\"ipv4\",\"subnetMapping\":[{\"subnetID\":\"subnet-0257383f56bbc4810\"},{\"subnetID\":\"subnet-0b8b2e282788f64bc\"}],\"securityGroups\":[{\"$ref\":\"#/resources/AWS::EC2::SecurityGroup/ManagedLBSecurityGroup/status/groupID\"}],\"tags\":{\"Environment\":\"test\"}}}},\"AWS::ElasticLoadBalancingV2::TargetGroup\":{\"app/app-ingress-api-http:80\":{\"spec\":{\"name\":\"k8s-app-apihttp-ee37d33f98\",\"targetType\":\"instance\",\"port\":30867,\"protocol\":\"HTTP\",\"protocolVersion\":\"HTTP1\",\"healthCheckConfig\":{\"port\":\"traffic-port\",\"protocol\":\"HTTP\",\"path\":\"/\",\"matcher\":{\"httpCode\":\"200\"},\"intervalSeconds\":15,\"timeoutSeconds\":5,\"healthyThresholdCount\":2,\"unhealthyThresholdCount\":2},\"tags\":{\"Environment\":\"test\"}}}},\"K8S::ElasticLoadBalancingV2::TargetGroupBinding\":{\"app/app-ingress-api-http:80\":{\"spec\":{\"template\":{\"metadata\":{\"name\":\"k8s-app-apihttp-ee37d33f98\",\"namespace\":\"app\",\"creationTimestamp\":null},\"spec\":{\"targetGroupARN\":{\"$ref\":\"#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/app/app-ingress-api-http:80/status/targetGroupARN\"},\"targetType\":\"instance\",\"serviceRef\":{\"name\":\"api-http\",\"port\":80},\"networking\":{\"ingress\":[{\"from\":[{\"securityGroup\":{\"groupID\":{\"$ref\":\"#/resources/AWS::EC2::SecurityGroup/ManagedLBSecurityGroup/status/groupID\"}}}],\"ports\":[{\"protocol\":\"TCP\"}]}]}}}}}}}}"}
{"level":"info","ts":1623379852.083325,"logger":"controllers.ingress","msg":"creating securityGroup","resourceID":"ManagedLBSecurityGroup"}
{"level":"info","ts":1623379852.2566178,"logger":"controllers.ingress","msg":"created securityGroup","resourceID":"ManagedLBSecurityGroup","securityGroupID":"sg-080bffd697dc0ab27"}
{"level":"info","ts":1623379852.4109924,"msg":"authorizing securityGroup ingress","securityGroupID":"sg-080bffd697dc0ab27","permission":[{"FromPort":80,"IpProtocol":"tcp","IpRanges":[{"CidrIp":"0.0.0.0/0","Description":""}],"Ipv6Ranges":null,"PrefixListIds":null,"ToPort":80,"UserIdGroupPairs":null}]}
{"level":"info","ts":1623379852.5575335,"msg":"authorized securityGroup ingress","securityGroupID":"sg-080bffd697dc0ab27"}
{"level":"info","ts":1623379852.6474898,"logger":"controllers.ingress","msg":"creating targetGroup","stackID":"app/app-ingress","resourceID":"app/app-ingress-api-http:80"}
{"level":"info","ts":1623379852.9693868,"logger":"controllers.ingress","msg":"created targetGroup","stackID":"app/app-ingress","resourceID":"app/app-ingress-api-http:80","arn":"arn:aws:elasticloadbalancing:us-east-1:111111111111:targetgroup/k8s-app-apihttp-ee37d33f98/8e8cf427880a005f"}
{"level":"info","ts":1623379853.0108032,"logger":"controllers.ingress","msg":"creating loadBalancer","stackID":"app/app-ingress","resourceID":"LoadBalancer"}
{"level":"info","ts":1623379853.6124952,"logger":"controllers.ingress","msg":"created loadBalancer","stackID":"app/app-ingress","resourceID":"LoadBalancer","arn":"arn:aws:elasticloadbalancing:us-east-1:111111111111:loadbalancer/app/k8s-app-appingre-df49e963f5/e1e08ff54e34da78"}
{"level":"info","ts":1623379853.6379986,"logger":"controllers.ingress","msg":"creating listener","stackID":"app/app-ingress","resourceID":"80"}
{"level":"info","ts":1623379853.7017045,"logger":"controllers.ingress","msg":"created listener","stackID":"app/app-ingress","resourceID":"80","arn":"arn:aws:elasticloadbalancing:us-east-1:111111111111:listener/app/k8s-app-appingre-df49e963f5/e1e08ff54e34da78/7896e4ee12889f1d"}
{"level":"info","ts":1623379853.7323081,"logger":"controllers.ingress","msg":"creating listener rule","stackID":"app/app-ingress","resourceID":"80:1"}
{"level":"info","ts":1623379853.7993383,"logger":"controllers.ingress","msg":"created listener rule","stackID":"app/app-ingress","resourceID":"80:1","arn":"arn:aws:elasticloadbalancing:us-east-1:111111111111:listener-rule/app/k8s-app-appingre-df49e963f5/e1e08ff54e34da78/7896e4ee12889f1d/2fc270d382a475d1"}
{"level":"info","ts":1623379853.7995286,"logger":"controllers.ingress","msg":"creating targetGroupBinding","stackID":"app/app-ingress","resourceID":"app/app-ingress-api-http:80"}
{"level":"info","ts":1623379853.836185,"logger":"controllers.ingress","msg":"created targetGroupBinding","stackID":"app/app-ingress","resourceID":"app/app-ingress-api-http:80","targetGroupBinding":{"namespace":"app","name":"k8s-app-apihttp-ee37d33f98"}}
{"level":"info","ts":1623379853.989902,"logger":"controllers.ingress","msg":"successfully deployed model","ingressGroup":"app/app-ingress"}
{"level":"info","ts":1623379854.0531545,"msg":"authorizing securityGroup ingress","securityGroupID":"sg-03aa126eb1aaeacc5","permission":[{"FromPort":0,"IpProtocol":"tcp","IpRanges":null,"Ipv6Ranges":null,"PrefixListIds":null,"ToPort":65535,"UserIdGroupPairs":[{"Description":"elbv2.k8s.aws/targetGroupBinding=shared","GroupId":"sg-080bffd697dc0ab27","GroupName":null,"PeeringStatus":null,"UserId":null,"VpcId":null,"VpcPeeringConnectionId":null}]}]}
{"level":"info","ts":1623379854.1990266,"msg":"authorized securityGroup ingress","securityGroupID":"sg-03aa126eb1aaeacc5"}
{"level":"info","ts":1623379854.3660266,"msg":"registering targets","arn":"arn:aws:elasticloadbalancing:us-east-1:111111111111:targetgroup/k8s-app-apihttp-ee37d33f98/8e8cf427880a005f","targets":[{"AvailabilityZone":null,"Id":"i-08b9e38bcf885a07a","Port":30867},{"AvailabilityZone":null,"Id":"i-0cdcd5bd12476c990","Port":30867}]}
{"level":"info","ts":1623379854.5757735,"msg":"registered targets","arn":"arn:aws:elasticloadbalancing:us-east-1:111111111111:targetgroup/k8s-app-apihttp-ee37d33f98/8e8cf427880a005f"}

以下是 AWS 负载均衡器控制器部署中另一个 pod 的日志:

~/git/github/django-cdk$ kubectl logs -n kube-system goeksstackdjangoekssamplealbingresscontroller48a16415-aws-q9nmg
{"level":"info","ts":1623379840.7888832,"msg":"version","GitVersion":"v2.2.0","GitCommit":"68c417a7ea37ff153f053d9ffef1cc5c70d7e211","BuildDate":"2021-05-14T21:49:05+0000"}
{"level":"info","ts":1623379840.8260994,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":8080"}
{"level":"info","ts":1623379840.8316746,"logger":"setup","msg":"adding health check for controller"}
{"level":"info","ts":1623379840.8317719,"logger":"controller-runtime.webhook","msg":"registering webhook","path":"/mutate-v1-pod"}
{"level":"info","ts":1623379840.8318048,"logger":"controller-runtime.webhook","msg":"registering webhook","path":"/mutate-elbv2-k8s-aws-v1beta1-targetgroupbinding"}
{"level":"info","ts":1623379840.83182,"logger":"controller-runtime.webhook","msg":"registering webhook","path":"/validate-elbv2-k8s-aws-v1beta1-targetgroupbinding"}
{"level":"info","ts":1623379840.831849,"logger":"controller-runtime.webhook","msg":"registering webhook","path":"/validate-networking-v1beta1-ingress"}
{"level":"info","ts":1623379840.8319223,"logger":"setup","msg":"starting podInfo repo"}
I0611 02:50:42.832101       1 leaderelection.go:242] attempting to acquire leader lease  kube-system/aws-load-balancer-controller-leader...
{"level":"info","ts":1623379842.8324547,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
{"level":"info","ts":1623379842.9327362,"logger":"controller-runtime.webhook.webhooks","msg":"starting webhook server"}
{"level":"info","ts":1623379842.9332633,"logger":"controller-runtime.certwatcher","msg":"Updated current TLS certificate"}
{"level":"info","ts":1623379842.9333658,"logger":"controller-runtime.webhook","msg":"serving webhook server","host":"","port":9443}
{"level":"info","ts":1623379842.9334989,"logger":"controller-runtime.certwatcher","msg":"Starting certificate watcher"}

我用 111111111111 替换了我的帐户 ID。

这是来自我的 CDK 堆栈的 CfnOutput 的 ALB DNS 名称:

k8s-app-appingre-a5bb1f9208-1217069225.us-east-1.elb.amazonaws.com

这是来自 EC2 > 负载均衡器控制台的 ALB 的 DNS 名称:

k8s-app-appingre-df49e963f5-842078657.us-east-1.elb.amazonaws.com

我认为答案是使用 external-dns

ExternalDNS allows you to control DNS records dynamically via Kubernetes resources in a DNS provider-agnostic way.

以这个“Ingress.yaml”为例:

# Annotations Reference:  https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: eks-microservices-demo
  labels:
    app: usermgmt-restapp
  annotations:
    # Ingress Core Settings  
    kubernetes.io/ingress.class: "alb"
    alb.ingress.kubernetes.io/scheme: internet-facing
    # Health Check Settings
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTP 
    alb.ingress.kubernetes.io/healthcheck-port: traffic-port
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
    alb.ingress.kubernetes.io/success-codes: '200'
    alb.ingress.kubernetes.io/healthy-threshold-count: '2'
    alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
    ## SSL Settings
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:ddddddddddddd
    #alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS-1-1-2017-01 #Optional (Picks default if not used)    
    # SSL Redirect Setting
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'   
    # External DNS - For creating a Record Set in Route53
    external-dns.alpha.kubernetes.io/hostname: users.skycomposer.net       
spec:
  rules:
    - http:
        paths:
          - path: /* # SSL Redirect Setting
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation            
          - path: /*
            backend:
              serviceName: usermgmt-restapp-nodeport-service
              servicePort: 8095                                   
# Important Note-1: In path based routing order is very important, if we are going to use  "/*", try to use it at the end of all rules. 

P.S。警告!它仅适用于托管 AWS EKS 集群,或任何其他支持 ALB Ingress Controller 的集群。

P.P.S。对于 K3S Kubernetes 集群,我使用 Traefik Ingress Controller 并且必须使用域名和 Load Balancer DNS 名称的值手动创建 Route 53 CNAME 记录。不幸的是,我不知道如何自动执行此过程。

带有 Traefik 入口控制器的 AWS K3S Kuberneter 集群的完整源代码示例,以及分步说明,可在此处找到: https://github.com/skyglass/customer-management-keycloak