【发布时间】:2022-01-10 15:51:33
【问题描述】:
我正在尝试在 GKE 集群上添加一个 NGINX 入口控制器,以及现有的 HAProxy 入口控制器(在重写规则方面存在一些问题)
首先我尝试将控制器的服务暴露给LoadBalancer 类型。流量可以到达入口和后端,但它不适用于托管证书。
所以我尝试使用 L7 负载均衡器(URL 映射)将流量转发到 GKE 集群 IP,并为我的入口控制器本身创建一个入口对象。
问题是,这个 Ingress 对象似乎没有绑定到外部 IP。并且路由到域会产生“默认后端 - 404”响应。
$ kubectl -n ingress-controller get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
haproxy-ingress NodePort 172.16.xxx.xxx <none> 80:31579/TCP,443:31769/TCP 595d
ingress-default-backend ClusterIP 172.16.xxx.xxx <none> 8080/TCP 595d
nginx-ingress-svc NodePort 172.16.xxx.xxx <none> 80:32416/TCP,443:31299/TCP 2d17h
$ kubectl -n ingress-controller get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
haproxy-l7-ing <none> * 34.xxx.xxx.aaa 80 594d
ingress-nginx-ing nginx * 172.xxx.xxx.xxx 80 2d16h
$ gcloud compute addresses list --global --project my-project
NAME ADDRESS/RANGE TYPE PURPOSE NETWORK REGION SUBNET STATUS
my-ext-ip 34.xxx.xxx.aaa EXTERNAL IN_USE
my-test-ext-ip 34.xxx.xxx.bbb EXTERNAL IN_USE
在这种情况下,我认为ingress-nginx-ing 应该绑定到34.xxx.xxx.bbb (my-test-ext-ip),就像haproxy-l7-ing 绑定到34.xxx.xxx.aaa (my-ext-ip) 但它没有。
负载平衡器:
$ gcloud compute forwarding-rules list --global --project my-project
NAME REGION IP_ADDRESS IP_PROTOCOL TARGET
haproxy-http-fwdrule 34.xxx.xxx.aaa TCP haproxy-http-proxy
haproxy-https-fwdrule 34.xxx.xxx.aaa TCP haproxy-https-proxy
nginx-http-fwdrule 34.xxx.xxx.bbb TCP nginx-http-proxy
nginx-https-fwdrule 34.xxx.xxx.bbb TCP nginx-https-proxy
$ gcloud compute target-http-proxies list --global --project my-project
NAME URL_MAP
haproxy-http-proxy haproxy-http-urlmap
nginx-http-proxy nginx-https-urlmap
$ gcloud compute target-https-proxies list --global --project my-project
NAME SSL_CERTIFICATES URL_MAP
haproxy-https-proxy default-cert,mcrt-xxxxxx-xxxxxx haproxy-https-urlmap
nginx-https-proxy mcrt-xxxxxx-xxxxxx nginx-https-urlmap
$ gcloud compute url-maps list --global --project my-project
NAME DEFAULT_SERVICE
haproxy-https-urlmap backendServices/k8s-be-xxxxxx--xxxxxx
haproxy-http-urlmap
nginx-https-urlmap backendServices/nginx-lb-backendservice
$ gcloud compute backend-services list --global --project my-project
NAME BACKENDS PROTOCOL
k8s-be-xxxxxx--xxxxxx asia-southeast1-a/instanceGroups/k8s-ig--xxxxxx HTTP
nginx-lb-backendservice asia-southeast1-a/instanceGroups/k8s-ig--xxxxxx HTTP
后端:asia-southeast1-a/instanceGroups/k8s-ig--xxxxxx 指向 GKE 集群。
K8S YAML 是这样的:
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
namespace: ingress-controller
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
controller: k8s.io/ingress-nginx
---
kind: Service
apiVersion: v1
metadata:
name: nginx-ingress-svc
namespace: ingress-controller
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
externalTrafficPolicy: Local
type: NodePort
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
ports:
- name: http
port: 80
targetPort: http
protocol: TCP
appProtocol: http
- name: https
port: 443
targetPort: https
protocol: TCP
appProtocol: https
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx-ing
namespace: ingress-controller
labels:
app: ingress-nginx
tier: ingress
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
# kubernetes.io/ingress.allow-http: 'false'
kubernetes.io/ingress.global-static-ip-name: 'my-test-ext-ip'
ingress.kubernetes.io/url-map: nginx-https-urlmap
networking.gke.io/managed-certificates: 'my-managed-cert'
ingress.gcp.kubernetes.io/pre-shared-cert: 'default-cert'
spec:
ingressClassName: nginx
defaultBackend:
service:
name: nginx-ingress-svc
port:
number: 80
知道我在这里可能缺少什么吗? 谢谢!
更新
我已经调整了负载均衡器的一些配置,创建了我自己的后端和运行状况检查,如下所示:
$ gcloud compute backend-services describe nginx-lb-backendservice --global
affinityCookieTtlSec: 0
backends:
- balancingMode: RATE
capacityScaler: 1.0
group: https://www.googleapis.com/compute/v1/projects/my-project/zones/asia-southeast1-a/instanceGroups/k8s-ig--xxxxxx
maxRatePerInstance: 1.0
cdnPolicy:
cacheKeyPolicy:
includeHost: true
includeProtocol: true
includeQueryString: false
cacheMode: USE_ORIGIN_HEADERS
negativeCaching: false
requestCoalescing: true
serveWhileStale: 0
signedUrlCacheMaxAgeSec: '0'
connectionDraining:
drainingTimeoutSec: 0
creationTimestamp: '2022-01-07T00:48:38.900-08:00'
description: '{"kubernetes.io/service-name":"ingress-controller/nginx-ingress-svc","kubernetes.io/service-port":"80"}'
enableCDN: true
fingerprint: ****
healthChecks:
- https://www.googleapis.com/compute/v1/projects/mtb-development-project/global/healthChecks/nginx-lb-backend-healthcheck
id: '7699213954898870409'
kind: compute#backendService
loadBalancingScheme: EXTERNAL
logConfig:
enable: true
sampleRate: 1.0
name: nginx-lb-backendservice
port: 31579
portName: port31579
protocol: HTTP
selfLink: https://www.googleapis.com/compute/v1/projects/my-project/global/backendServices/nginx-lb-backendservice
sessionAffinity: NONE
timeoutSec: 30
然后,我在 Ingress 中添加了这个注解ingress-nginx-ing:
ingress.kubernetes.io/url-map: nginx-https-urlmap
后端状态为 HEALTHY,但不知何故 ingress-nginx-ing 仍然不会绑定到保留的外部 IP。
而且也没有附加这些注释:ingress.kubernetes.io/backends、ingress.kubernetes.io/https-forwarding-rule、ingress.kubernetes.io/https-target-proxy,与 HAProxy 不同。
向 myhost.mydomain/whatever 发送 HTTP(S)(解析为 IP:34.xxx.xxx.bbb)仍然得到“默认后端 - 404”响应。
更新#2(工作!)
我尝试了boredabdel 的答案here,从ingress-nginx-ing 中删除了ingressClassName: nginx,它似乎有效。
根据新警告删除手动创建的 LB 对象并调整自动生成的健康检查后,流量可以按预期到达 API。
(混淆的来源来自示例中的kubernetes.io/ingress.class 注释和ingressClassName。)
【问题讨论】:
标签: google-kubernetes-engine kubernetes-ingress nginx-ingress