如何调试 Kubernetes nginx Ingress 从 HTTP 到 HTTPS 的重定向

How to debug Kubernetes nginx Ingress redirection from HTTP to HTTPS

快速提问:我如何调试入口和 Nginx 以了解 HTTP->HTTPS 重定向发生的确切位置?

更多详情:

我们有:我们有 war 文件 + Tomcat,用 Docker 构建它。 运行 它与 AWS 中的 Kubernetes。

我们需要什么:应用程序应该可以通过 HTTP 和 HTTPS 访问。 HTTP 不应 重定向到 HTTPS。

问题:HTTP 总是重定向到 HTTPS。

我们的尝试:我们有 Ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ${some name
  namespace: ${some namespace}
  labels:
    app: ${some app}
    env: ${some env}
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false" #we added this for turn off https redirection
    nginx.ingress.kubernetes.io/force-ssl-redirect: "false" #we added this for turn off https redirection
    nginx.ingress.kubernetes.io/affinity: "cookie" # We use it for sticky sessions
    nginx.ingress.kubernetes.io/affinity-mode: "persistent"
    nginx.ingress.kubernetes.io/session-cookie-name: "some cookie name"
    nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
    nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/whitelist-source-range: ${whitelist of ip adresses}

spec:
  tls:
    - hosts:
        - ${some host}
        - ${some another host}
      secretName: my-ingress-ssl
  rules:
    - host: ${some host}
      http:
        paths:
          - path: /
            backend:
              serviceName: ${some another service name}
              servicePort: 8080
    - host: ${some another host}
      http:
        paths:
          - path: /
            backend:
              serviceName: ${some another service name}
              servicePort: 8080

和configmap

kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    app: ${some app}
    env: ${some env}
  namespace: ${some namespace}
  name: nginx-config
data:
  hsts: "false" #we added this for turn off https redirection
  hsts-max-age: "0" #we added this for turn off https redirection
  ssl-redirect: "false" #we added this for turn off https redirection
  hsts-include-subdomains: "false" #we added this for turn off https redirection

在 Tomcat server.xml 中我们有:

<Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />

...

<!-- Define an AJP 1.3 Connector on port 8009 -->
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

...

以及我们评论过的这个连接器(现在不应该工作):

<!--
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
           maxThreads="150" SSLEnabled="true" >
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
    <SSLHostConfig>
        <Certificate certificateKeyFile="conf/key.pem"
                     certificateFile="conf/cert.pem"
                     certificateChainFile="conf/chain.pem"
                     type="RSA" />
    </SSLHostConfig>
</Connector>
-->

我尝试了所有可能带有入口注释的变体,但没有成功结果。

我想知道的是:我如何 debug 进入 Nginx 以了解 HTTP->HTTPS 重定向的确切位置?

UPD

原来服务器上安装的不是Nginx controller,而是Traefik。由于安全限制,我看不到带有控制器的那个 pod。所以没有 Nginx 注释起作用。 尽管如此,下面对我的问题的回答将帮助有类似问题的人。

  1. 您可以查看当前 nginx-ingress 清单的 nginx 配置并检查那里是否有任何从 http 到 https 重定向的规则,如 here 所述,使用如下:
    kubectl exec -it -n <namespace-of-ingress-controller> <nginx-ingress-controller-pod-name> -- cat /etc/nginx/nginx.conf

  2. 使用命令 curl -LIk http://<domain> 并检查 server: header 重定向。在卷曲中:

    • -L 将遵循重定向
    • -I 只显示 headers
    • -k 将允许不安全的 SSL 请求

在您描述的设置中,处理传入的 http 请求可能至少涉及三个进程

互联网 -> AWS ELB -> Nginx 入口控制器 -> Tomcat

任何进程都可以发出 301 重定向以指示 http 流量使用 https 重试。 tomcat 进程中的重定向可以由 tomcat 配置或应用 tomcat 主机指定。

我会尝试通过尝试绕过更高级别的进程来隔离执行重定向的进程:

  1. 绕过负载均衡器。通过 SSH 连接到 K8s 节点之一,并将入口服务的节点端口卷曲到 URL(查看 nginx-controller 服务描述中的内部端点以获得正确的端口)。如果您收到重定向,您就知道问题不在负载均衡器上。
  2. 通过 'docker exec' 绕过入口控制器进入应用程序容器之一,然后 curl localhost:8080。如果你得到重定向,你就知道问题不在入口控制器上,而必须在 tomcat 配置或应用程序中。

如果 none 由于 ssh 限制、curl 可用性等原因,这是可能的...另一种方法是为每个涉及的进程打开请求日志记录——尽管这不适用于生产工作负载,因为它会导致机密信息输出到不适当的上下文,例如 Web 层日志文件或 cloudwatch 日志。