如何配置 Kubernetes Ingress Nginx 白名单只适用于 http

How to config Kubernetes Ingress Nginx anontations whitelist only apply to http

我配置了我的入口支持 SSL:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: "service"
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: "x.x.x.x/xx"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  tls:
  - hosts:
    - "example.com"
    secretName: example.name
  rules:
  - host: "example.com"
    http:
      paths:
      - path: /
        backend:
          serviceName: service
          servicePort: 80

在我上面的配置中,只有白名单中的 IP 可以访问 HTTP 和 HTTPS 的域。但我想配置所有 IP 地址都可以访问 https://example.com (HTTPS) 并且白名单中的一些 IP 地址可以在没有 SSL 的情况下访问 - http://example.com.

whitelist-source-range 注释将始终影响整个 Ingress 资源。但是,您可能(未经测试!)尝试使用两个单独的 Ingress 资源:一个用于 HTTP 访问(使用源白名单且没有 tls 配置)和一个用于 HTTPS(使用使用 kubernetes.io/ingress.allow-http 注释禁用纯 HTTP):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: service-https
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - hosts:
    - "example.com"
    secretName: example.name
  rules:
  - host: "example.com"
    http:
      paths:
      - path: /
        backend:
          serviceName: service
          servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: service-http
  annotations:
    nginx.ingress.kubernetes.io/whitelist-source-range: "x.x.x.x/xx"
spec:
  rules:
  - host: "example.com"
    http:
      paths:
      - path: /
        backend:
          serviceName: service
          servicePort: 80

我认为目前仅使用 nginx-ingress 是不可能的。
当您为 Ingress 设置 HTTPS 方案时,它开始侦听端口 443 和 continues to listen on port 80.

但是,您可以通过使用本地 Nginx 实例作为外部负载平衡器来实现。
按照此 link 获取详细说明:"Kubernetes TCP load balancer service on premise (non-cloud)"

作为另一种选择,您可能想尝试 Istio Ingress

我已经通过使用 nginx.ingress.kubernetes.io/configuration-snippet 注释向 nginx 位置添加更多配置(同时收听 http 和 https)解决了我的问题。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: "service"
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    # The configs to allow all IPs access via https and allow some IPs in
    # security whitelist access via http
    nginx.ingress.kubernetes.io/configuration-snippet: |

      if ($https) {
        set $allow_ip true;
      }

      if ($remote_addr ~ (x.x.x.x|y.y.y.y) {
        set $allow_ip true;
      }

      if ($allow_ip != true) {
        return 403;
      }
spec:
  tls:
  - hosts:
    - "example.com"
    secretName: example.name
  rules:
  - host: "example.com"
    http:
      paths:
      - path: /
        backend:
          serviceName: service
          servicePort: 80