ArgoCD结合ExternalDNS与AWS Load Balancer Controller配置问题
问题:ArgoCD结合ExternalDNS后解析到内部IP而非ALB公网IP
按照ArgoCD文档配置AWS应用负载均衡器(ALB)后,搭配ExternalDNS时,解析argocd.<MyURL>.com得到的是集群内部IP,而非ALB的公网IP。dig命令输出如下:
$ dig argocd.<MyURL>.com ; <<>> DiG 9.10.6 <<>> argocd.<MyURL>.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3362 ;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;argocd.<MyURL>.com. IN A ;; ANSWER SECTION: argocd.<MyURL>.com. 300 IN A 10.0.3.59 argocd.<MyURL>.com. 300 IN A 10.0.2.77 argocd.<MyURL>.com. 300 IN A 10.0.2.166 argocd.<MyURL>.com. 300 IN A 10.0.1.194 ;; Query time: 22 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Wed Jul 26 17:37:38 PDT 2023 ;; MSG SIZE rcvd: 122
当前ArgoCD的两个Service及Ingress配置如下:
apiVersion: v1 kind: Service metadata: annotations: external-dns.alpha.kubernetes.io/hostname: argocd.<MyURL>.com meta.helm.sh/release-name: argo-cd meta.helm.sh/release-namespace: argo-cd creationTimestamp: "2023-07-14T18:26:17Z" labels: app.kubernetes.io/component: server app.kubernetes.io/instance: argo-cd app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: argocd-server app.kubernetes.io/part-of: argocd app.kubernetes.io/version: v2.7.6 helm.sh/chart: argo-cd-5.36.11 name: argo-cd-argocd-server namespace: argo-cd spec: ports: - name: http nodePort: 30080 port: 80 protocol: TCP targetPort: 8080 - name: https nodePort: 30443 port: 443 protocol: TCP targetPort: 8080 selector: app.kubernetes.io/instance: argo-cd app.kubernetes.io/name: argocd-server sessionAffinity: None type: NodePort --- apiVersion: v1 kind: Service metadata: annotations: #This tells AWS to send traffic from the ALB using HTTP2. Can use GRPC as well if you want to leverage GRPC specific features alb.ingress.kubernetes.io/backend-protocol-version: HTTP2 labels: app: argogrpc name: argogrpc spec: ports: - name: "443" port: 443 protocol: TCP targetPort: 8080 selector: app.kubernetes.io/name: argocd-server sessionAffinity: None type: NodePort --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: argocd annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/backend-protocol: HTTPS # Use this annotation (which must match a service name) to route traffic to HTTP2 backends. alb.ingress.kubernetes.io/conditions.argogrpc: | [{"field":"http-header","httpHeaderConfig":{"httpHeaderName": "Content-Type", "values":["application/grpc"]}}] alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' spec: rules: - host: argocd.<MyURL>.com http: paths: - path: / backend: service: name: argo-cd-argocd-server port: name: https pathType: Prefix - path: / backend: service: name: argogrpc port: number: 443 pathType: Prefix
补充说明:EKS集群中ExternalDNS与AWS负载均衡控制器已正常工作,其他应用(如下方纯HTML服务)配置后能正确生成ALB和DNS记录,仅ArgoCD出现问题:
apiVersion: v1 kind: Service metadata: name: feature-flag-tests annotations: external-dns.alpha.kubernetes.io/hostname: fftests.<MyURL>.com spec: type: NodePort ports: - port: 80 name: web protocol: TCP targetPort: web selector: app: feature-flag-tests --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: feature-flag-tests annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]' alb.ingress.kubernetes.io/ssl-redirect: '443' alb.ingress.kubernetes.io/certificate-arn: <My Cert ARN> spec: ingressClassName: alb rules: - host: fftests.<myurl>.com http: paths: - path: / pathType: Prefix backend: service: name: feature-flag-tests port: number: 80
解决方案
1. 调整ExternalDNS注解的位置
ExternalDNS作用在NodePort类型的Service上时,会解析到集群节点的内部IP。需要把external-dns.alpha.kubernetes.io/hostname注解从ArgoCD的Service上移除,添加到Ingress资源中,这样ExternalDNS会自动关联ALB的公网IP生成DNS记录。
2. 为Ingress指定ingressClassName
参考正常工作的应用配置,给ArgoCD的Ingress添加ingressClassName: alb,确保AWS负载均衡控制器能正确识别并管理该Ingress对应的ALB。
修改后的配置示例
调整后的ArgoCD Ingress:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: argocd annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip alb.ingress.kubernetes.io/backend-protocol: HTTPS alb.ingress.kubernetes.io/conditions.argogrpc: | [{"field":"http-header","httpHeaderConfig":{"httpHeaderName": "Content-Type", "values":["application/grpc"]}}] alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' external-dns.alpha.kubernetes.io/hostname: argocd.<MyURL>.com # 新增此注解 spec: ingressClassName: alb # 新增此配置 rules: - host: argocd.<MyURL>.com http: paths: - path: / backend: service: name: argo-cd-argocd-server port: name: https pathType: Prefix - path: / backend: service: name: argogrpc port: number: 443 pathType: Prefix
调整后的ArgoCD Server Service:
apiVersion: v1 kind: Service metadata: annotations: # 移除 external-dns.alpha.kubernetes.io/hostname 注解 meta.helm.sh/release-name: argo-cd meta.helm.sh/release-namespace: argo-cd creationTimestamp: "2023-07-14T18:26:17Z" labels: app.kubernetes.io/component: server app.kubernetes.io/instance: argo-cd app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: argocd-server app.kubernetes.io/part-of: argocd app.kubernetes.io/version: v2.7.6 helm.sh/chart: argo-cd-5.36.11 name: argo-cd-argocd-server namespace: argo-cd spec: ports: - name: http nodePort: 30080 port: 80 protocol: TCP targetPort: 8080 - name: https nodePort: 30443 port: 443 protocol: TCP targetPort: 8080 selector: app.kubernetes.io/instance: argo-cd app.kubernetes.io/name: argocd-server sessionAffinity: None type: NodePort
验证步骤
- 执行
kubectl get ingress argocd -n argo-cd,查看ADDRESS字段是否为ALB的公网域名 - 等待ExternalDNS同步DNS记录(通常数分钟)
- 再次执行
dig argocd.<MyURL>.com,确认解析结果为ALB的公网IP
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

