Nginx 配置存在一些问题(OpenShift 入口网关的反向代理)

问题描述 投票:0回答:2

我有一个无法解决的问题。任务是配置外部 nginx(裸机)以使用 Istio 平衡 OpenShift 的入口网关主机。 我做了一个简单的 nginx 配置:

upstream RobotBalance {
    server ingress-robot.apps.gen1.com:443;
    }

log_format basic '$remote_addr - $remote_user [$time_local] '
                 '"$request"   $status   $bytes_sent '
                 '"$upstream_addr" '
                 '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
server {
    listen 443 ssl http2;
    # listen 80;

    ssl on;
    ssl_certificate /opt/nginx/ssl/cert.crt;
    ssl_certificate_key /opt/nginx/ssl/cert.key;
    ssl_session_timeout 10m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
    server_name ingress-robot.apps.gen1.com;

    location / {
        # return 301 https://$server_name$request_uri; #

        proxy_pass https://RobotBalance;
    
        access_log logs/robot_balance.log basic;
        error_log logs/robot_balance_error.log debug;

        proxy_set_header Host               $http_host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Port   $server_port;
        proxy_set_header X-Forwarded-Proto  $scheme;
        add_header X-Upstream $upstream_addr always;
    }

}

我正在尝试通过我的 nginx 向在 ingress-robot.apps.gen1.com 运行的应用程序发送一个空请求。但是从 openshift 的 istio 收到一条关于给定路径上应用程序无法访问的消息。

curl --cacert /opt/nginx/ssl/root_ca_united.pem --cert /opt/nginx/ssl/published.pem --key /opt/nginx/ssl/private.key --request POST https://my-ngnix-hostname-here/engine-dream/validate -i --verbose -d '{}'
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 10.55.11.22...
* TCP_NODELAY set
* Connected to my-ngnix-hostname-here (10.55.11.22) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /opt/nginx/ssl/root_ca_united.pem
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=EU; O=MY ORG; OU=99CA; CN=my-ngnix-hostname-here
*  start date: Jun  9 07:34:08 2022 GMT
*  expire date: Jun  9 07:34:08 2023 GMT
*  subjectAltName: host "my-ngnix-hostname-here" matched cert's "my-ngnix-hostname-here"
*  issuer: DC=ru; DC=org; DC=gamma; CN=My-Org
*  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
* TLSv1.3 (OUT), TLS app data, [no content] (0):
* TLSv1.3 (OUT), TLS app data, [no content] (0):
* TLSv1.3 (OUT), TLS app data, [no content] (0):
* Using Stream ID: 1 (easy handle 0x56254b3bf690)
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> POST /engine-dream/validate HTTP/2
> Host: my-ngnix-hostname-here
> User-Agent: curl/7.61.1
> Accept: */*
> Content-Length: 2
> Content-Type: application/x-www-form-urlencoded
> 
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
* TLSv1.3 (OUT), TLS app data, [no content] (0):
* TLSv1.3 (OUT), TLS app data, [no content] (0):
* We are completely uploaded and fine
* TLSv1.3 (IN), TLS app data, [no content] (0):
* TLSv1.3 (IN), TLS app data, [no content] (0):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/2 503 
HTTP/2 503 
< server: nginx
server: nginx
< date: Wed, 13 Jul 2022 09:01:33 GMT
date: Wed, 13 Jul 2022 09:01:33 GMT
< content-type: text/html
content-type: text/html
< pragma: no-cache
pragma: no-cache
< cache-control: private, max-age=0, no-cache, no-store
cache-control: private, max-age=0, no-cache, no-store
< x-upstream: 10.55.111.245:443
x-upstream: 10.55.111.245:443

< 
<html>
...
  <body>
    <div>
      <h1>Application is not available</h1>
      <p>The application is currently not serving requests at this endpoint. It may not have been started or is still starting.</p>

      <div class="alert alert-info">
        <p class="info">
          Possible reasons you are seeing this page:
        </p>
        <ul>
          <li>
            <strong>The host doesn't exist.</strong>
            Make sure the hostname was typed correctly and that a route matching this hostname exists.
          </li>
          <li>
            <strong>The host exists, but doesn't have a matching path.</strong>
            Check if the URL path was typed correctly and that the route was created using the desired path.
          </li>
          <li>
            <strong>Route and path matches, but all pods are down.</strong>
            Make sure that the resources exposed by this route (pods, services, deployment configs, etc) have at least one pod running.
          </li>
        </ul>
      </div>
    </div>
  </body>
...
</html>
* TLSv1.3 (IN), TLS app data, [no content] (0):
* Connection #0 to host my-ngnix-hostname-here left intact

但是当我直接向 ingress 发送请求时,从应用程序中得到了正确的答案。

curl --cacert /opt/nginx/ssl/root_ca_united.pem --cert /opt/nginx/ssl/published.pem --key /opt/nginx/ssl/private.key --request POST https://ingress-robot.apps.gen1.com/engine-dream/validate -i --verbose -d '{}'
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 10.55.111.245...
* TCP_NODELAY set
* Connected to ingress-robot.apps.gen1.com (10.55.111.245) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /opt/nginx/ssl/root_ca_united.pem
  CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Request CERT (13):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, CERT verify (15):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: C=EU; O=MY ORG; OU=99CA; CN=ingress-robot.apps.gen1.com
*  start date: Jun  7 10:32:57 2022 GMT
*  expire date: Jun  7 10:32:57 2023 GMT
*  subjectAltName: host "ingress-robot.apps.gen1.com" matched cert's "ingress-robot.apps.gen1.com"
*  issuer: DC=ru; DC=org; DC=gamma; CN=My-Org
*  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
* TLSv1.3 (OUT), TLS app data, [no content] (0):
* TLSv1.3 (OUT), TLS app data, [no content] (0):
* TLSv1.3 (OUT), TLS app data, [no content] (0):
* Using Stream ID: 1 (easy handle 0x5594f7b31690)
* TLSv1.3 (OUT), TLS app data, [no content] (0):
> POST /dsl-engine-dream/validate HTTP/2
> Host: ingress-robot.apps.gen1.com
> User-Agent: curl/7.61.1
> Accept: */*
> Content-Length: 2
> Content-Type: application/x-www-form-urlencoded
> 
* TLSv1.3 (OUT), TLS app data, [no content] (0):
* We are completely uploaded and fine
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS app data, [no content] (0):
* Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
* TLSv1.3 (OUT), TLS app data, [no content] (0):
* TLSv1.3 (IN), TLS app data, [no content] (0):
< HTTP/2 400 
HTTP/2 400 
< content-type: application/json; charset=utf-8
content-type: application/json; charset=utf-8
< content-length: 100
content-length: 100
< access-control-allow-origin: *
access-control-allow-origin: *
< server: istio-envoy
server: istio-envoy
< date: Wed, 13 Jul 2022 09:02:40 GMT
date: Wed, 13 Jul 2022 09:02:40 GMT
< x-envoy-upstream-service-time: 4
x-envoy-upstream-service-time: 4

< 
{
  "error": " Hello from robot. Robot.app got the empty request!"
* Connection #0 to host ingress-robot.apps.gen1.com left intact

请帮忙。我的 nginx 配置有什么问题?或者也许有一些功能可以平衡 Istio 的入口?

nginx openshift nginx-config
2个回答
0
投票

这“很可能”是因为 Ingress Gateway 正在执行 SNI 路由,即基于 HOST 标头的路由。因此,当您

curl
“https://ingress-robot.apps.gen1.com/engine-dream/validate”时,Ingress Gateway 能够根据“ingress-robot.apps.gen1.com”找到应用程序“
HOST
标题。
然而,当您

curl

ing“https://my-ngnix-hostname-here/engine-dream/validate”时,您只是通过“my-ngnix-hostname-here”

HOST
头,Ingress Gateway 说:“我没有与该主机名 ́\_(ツ)_/́ 匹配的应用程序”,然后它放弃。

打赌

如果你尝试了这个curl,Ingress 网关就能工作

$ curl -H "Host: ingress-robot.apps.gen1.com" --cacert /opt/nginx/ssl/root_ca_united.pem --cert /opt/nginx/ssl/published.pem --key /opt/nginx/ssl/private.key --request POST https://my-ngnix-hostname-here/engine-dream/validate -i --verbose -d '{}'

(注意我传递的 
-H "Host: ingress-robot.apps.gen1.com"

标头)

在我看来,你

应该

做什么(好吧,实际上,我不认为你应该反向代理另一个反向代理,Ingress Gateway,但无论如何......如果这是你的要求,那就是它是),想出一个新的域名,“apps2.gen1.com”之类的。使用 server_name *.apps2.gen1.com". Then when you expose your applications in OpenShift, you can *pick* the hostname that they get exposed as. So expose your application as "ingress-robot.apps2.gen1.com", and you would still point your Upstream server` 将 Nginx 设置为“ingress-robot.apps.gen1.com”。

这样,当您使用 apps2 访问 Nginx 盒子时,它会向 OpenShift 发送相同的 apps2 

HOST

标头,并且 OpenShift 能够根据 apps2 路由/入口找到应用程序。

上面感觉像是一个更“正确”的解决方案,但是如果您想“破解”它,您可以在 Nginx 配置中硬编码 

HOST

标头以匹配 Ingress Gateway 期望的

HOST
标头。这感觉有点僵化,难以保持动态,但根据您的要求,它可能“足够好”。
    


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.