我已将 ingress-nginx helm chart ( 3.20.1 , https://github.com/kubernetes/ingress-nginx/tree/master/charts/ingress-nginx ) 部署到 k8s 集群中。
为应用程序配置的一些 Ingress 使用基本身份验证 - 它按预期工作。 IE。我可以在没有基本身份验证的情况下访问集群中的一些应用程序(如配置) 并且某些应用程序需要专用的基本身份验证凭据(如配置)。
但是尝试一个未知/不受支持的 URL/路径在默认后端处理很尴尬。 不知何故,默认后端现在也需要基本身份验证(作为 basic-auth 的入口之一)?
我如何才能找出为什么/在不应该进行此基本身份验证的地方? 我确实希望默认后端在没有基本身份验证的情况下为 404 提供错误页面!
$ kubectl -n ingress get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.0.235.5 xx.yy.zzz.zzz 80:31294/TCP,443:31732/TCP 39d
ingress-nginx-controller-admission ClusterIP 10.0.190.204 <none> 443/TCP 39d
ingress-nginx-controller-metrics ClusterIP 10.0.21.184 <none> 9913/TCP 12d
ingress-nginx-defaultbackend ClusterIP 10.0.109.195 <none> 80/TCP 39d
当前部署的 Ingress:
$ kubectl get ingress -A
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
dev-app-a app-a <none> my-host.com xx.yy.zzz.zzz 80, 443 46d
dev-jaeger jaeger <none> my-host.com xx.yy.zzz.zzz 80, 443 47d
dev-app-b app-b <none> my-host.com xx.yy.zzz.zzz 80, 443 17d
dev-app-c app-c <none> my-host.com xx.yy.zzz.zzz 80, 443 12d
dev-app-d app-d <none> my-host.com xx.yy.zzz.zzz 80, 443 4d22h
prom prometheus-grafana <none> my-other-host.com xx.yy.zzz.zzz 80, 443 20d
prom prometheus-kube-prometheus-alertmanager <none> my-other-host.com xx.yy.zzz.zzz 80, 443 20d
prom prometheus-kube-prometheus-prometheus <none> my-other-host.com xx.yy.zzz.zzz 80, 443 20d
stage-app-a app-a <none> my-third-host.com xx.yy.zzz.zzz 80, 443 39d
stage-jaeger jaeger <none> my-third-host.com xx.yy.zzz.zzz 80, 443 39d
入口详细信息:
apiVersion: v1
items:
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/enable-cors: "false"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
labels:
app.kubernetes.io/name: app-a
name: app-a
namespace: foo-app-a
spec:
rules:
- host: my-host.com
http:
paths:
- backend:
serviceName: app-a-http
servicePort: http
path: /abc/
pathType: ImplementationSpecific
tls:
- hosts:
- my-host.com
secretName: app-a-tls
status:
loadBalancer:
ingress:
- ip: xx.xx.xx.xx
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/add-base-url: "true"
nginx.ingress.kubernetes.io/auth-realm: Authentication Required - Jaeger UI
nginx.ingress.kubernetes.io/auth-secret: jaeger-basic-auth
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/enable-cors: "false"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
labels:
app.kubernetes.io/name: jaeger
name: jaeger
namespace: dev-jaeger
spec:
rules:
- host: my-host.com
http:
paths:
- backend:
serviceName: jaeger
servicePort: http-ui
path: /jaeger/
pathType: ImplementationSpecific
tls:
- hosts:
- my-host.com
secretName: jaeger-tls
status:
loadBalancer:
ingress:
- ip: xx.xx.xx.xx
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/enable-cors: "false"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/rewrite-target: /$1
labels:
app.kubernetes.io/name: app-b
name: app-b
namespace: dev-app-b
spec:
rules:
- host: my-host.com
http:
paths:
- backend:
serviceName: app-b
servicePort: http
path: /app-b/(.*)
pathType: ImplementationSpecific
tls:
- hosts:
- my-host.com
secretName: app-b-tls
status:
loadBalancer:
ingress:
- ip: xx.xx.xx.xx
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/enable-cors: "false"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/rewrite-target: /$1
labels:
app.kubernetes.io/name: app-c
name: app-c
namespace: dev-app-c
spec:
rules:
- host: my-host.com
http:
paths:
- backend:
serviceName: app-c
servicePort: http
path: /app-c/(.*)
pathType: ImplementationSpecific
tls:
- hosts:
- my-host.com
secretName: app-c-tls
status:
loadBalancer:
ingress:
- ip: xx.xx.xx.xx
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
meta.helm.sh/release-name: prometheus
meta.helm.sh/release-namespace: prom
nginx.ingress.kubernetes.io/add-base-url: "true"
nginx.ingress.kubernetes.io/auth-realm: Authentication Required - Grafana UI
nginx.ingress.kubernetes.io/auth-secret: monitoring-basic-auth
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/enable-cors: "false"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
labels:
app.kubernetes.io/instance: prometheus
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: grafana
app.kubernetes.io/version: 7.4.2
helm.sh/chart: grafana-6.4.8
name: prometheus-grafana
namespace: prom
spec:
rules:
- host: my-other-host.com
http:
paths:
- backend:
serviceName: prometheus-grafana
servicePort: 80
path: /monitoring/grafana/
pathType: ImplementationSpecific
tls:
- hosts:
- my-other-host.com
secretName: prometheus-general-tls
status:
loadBalancer:
ingress:
- ip: xx.xx.xx.xx
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
meta.helm.sh/release-name: prometheus
meta.helm.sh/release-namespace: prom
nginx.ingress.kubernetes.io/auth-realm: Authentication Required - AlertManager UI
nginx.ingress.kubernetes.io/auth-secret: monitoring-basic-auth
nginx.ingress.kubernetes.io/auth-type: basic
labels:
app: kube-prometheus-stack-alertmanager
app.kubernetes.io/managed-by: Helm
chart: kube-prometheus-stack-14.0.1
heritage: Helm
release: prometheus
name: prometheus-kube-prometheus-alertmanager
namespace: prom
spec:
rules:
- host: my-other-host.com
http:
paths:
- backend:
serviceName: prometheus-kube-prometheus-alertmanager
servicePort: 9093
path: /monitoring/alertmanager/
pathType: ImplementationSpecific
tls:
- hosts:
- my-other-host.com
secretName: prometheus-general-tls
status:
loadBalancer:
ingress:
- ip: xx.xx.xx.xx
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
meta.helm.sh/release-name: prometheus
meta.helm.sh/release-namespace: prom
nginx.ingress.kubernetes.io/auth-realm: Authentication Required - Prometheus UI
nginx.ingress.kubernetes.io/auth-secret: monitoring-basic-auth
nginx.ingress.kubernetes.io/auth-type: basic
labels:
app: kube-prometheus-stack-prometheus
app.kubernetes.io/managed-by: Helm
chart: kube-prometheus-stack-14.0.1
heritage: Helm
release: prometheus
name: prometheus-kube-prometheus-prometheus
namespace: prom
spec:
rules:
- host: my-other-host.com
http:
paths:
- backend:
serviceName: prometheus-kube-prometheus-prometheus
servicePort: 9090
path: /monitoring/prometheus/
pathType: ImplementationSpecific
tls:
- hosts:
- my-other-host.com
secretName: prometheus-general-tls
status:
loadBalancer:
ingress:
- ip: xx.xx.xx.xx
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/enable-cors: "false"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
labels:
app.kubernetes.io/managed-by: terraform
app.kubernetes.io/name: app-a
name: app-a
namespace: stage-app-a
spec:
rules:
- host: my-third-host.com
http:
paths:
- backend:
serviceName: app-a-http
servicePort: http
path: /controller/
pathType: ImplementationSpecific
tls:
- hosts:
- my-third-host.com
secretName: app-a-tls
status:
loadBalancer:
ingress:
- ip: xx.xx.xx.xx
- apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/add-base-url: "true"
nginx.ingress.kubernetes.io/auth-realm: Authentication Required - Jaeger UI
nginx.ingress.kubernetes.io/auth-secret: jaeger-basic-auth
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/enable-cors: "false"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
labels:
app.kubernetes.io/name: jaeger
name: jaeger
namespace: stage-jaeger
spec:
rules:
- host: my-third-host.com
http:
paths:
- backend:
serviceName: jaeger
servicePort: http-ui
path: /jaeger/
pathType: ImplementationSpecific
tls:
- hosts:
- my-third-host.com
secretName: jaeger-tls
status:
loadBalancer:
ingress:
- ip: xx.xx.xx.xx
例如在未知路径上尝试一个简单的 curl(我希望默认后端给出 404 响应)返回来自我的 Prometheus 端点的数据,这些数据受基本身份验证保护:
(真实的主机名/ip 已经被我混淆了!)
$ curl -v "https://my-other-host.com/bar"
* Trying xx.xx.xx.xx...
* TCP_NODELAY set
* Connected to my-other-host.com (xx.xx.xx.xx) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=my-other-host.com
* start date: Apr 6 14:28:20 2021 GMT
* expire date: Jul 5 14:28:20 2021 GMT
* subjectAltName: host "my-other-host.com" matched cert's "my-other-host.com"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fec1300d600)
> GET /bar HTTP/2
> Host: my-other-host.com
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 401
< date: Wed, 21 Apr 2021 15:37:24 GMT
< content-type: text/html
< content-length: 172
< www-authenticate: Basic realm="Authentication Required - Prometheus UI"
< strict-transport-security: max-age=15724800; includeSubDomains
<
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host my-other-host.com left intact
* Closing connection 0
或类似的,当在另一台主机上尝试时,我会从看起来像我的 Jaeger 端点而不是默认后端 404 的东西中得到 401:
$ curl -v "https://my-host.com/foo"
* Trying xx.xx.xx.xx...
* TCP_NODELAY set
* Connected to my-host.com (xx.xx.xx.xx) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=my-host.com
* start date: Mar 18 06:37:40 2021 GMT
* expire date: Jun 16 06:37:40 2021 GMT
* subjectAltName: host "my-host.com" matched cert's "my-host.com"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f968480d600)
> GET /foo HTTP/2
> Host: my-host.com
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 401
< date: Wed, 21 Apr 2021 15:59:21 GMT
< content-type: text/html
< content-length: 172
< www-authenticate: Basic realm="Authentication Required - Jaeger UI"
< strict-transport-security: max-age=15724800; includeSubDomains
<
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx</center>
</body>
</html>
* Connection #0 to host my-host.com left intact
* Closing connection 0
答案 0 :(得分:1)
通过为集群中提供服务的每个主机显式添加 Ingress 路由来修复(或解决该问题):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
name: default-route-per-host
namespace: ingress
spec:
rules:
- host: my-host.com
http:
paths:
- backend:
service:
name: ingress-nginx-defaultbackend
port:
name: http
path: /
pathType: Prefix
- host: my-other-host.com
http:
paths:
- backend:
service:
name: ingress-nginx-defaultbackend
port:
name: http
path: /
pathType: Prefix
- host: my-third-host.com
http:
paths:
- backend:
service:
name: ingress-nginx-defaultbackend
port:
name: http
path: /
pathType: Prefix