【问题标题】:Ingress Nginx - how to serve assets to applicationIngress Nginx - 如何将资产提供给应用程序
【发布时间】:2020-08-15 21:40:49
【问题描述】:

我有一个问题,我正在 [hostname]/product/console 上部署一个应用程序,但是正在从 [hostname]/product/static 请求 .css .js 文件,因此它们没有被加载,我得到了404.

我已经尝试nginx.ingress.kubernetes.io/rewrite-target: 无济于事。

我也尝试过使用:nginx.ingress.kubernetes.io/location-snippet: | location = /product/console/ { proxy_pass http://[hostname]/product/static/; }

但后者似乎根本没有被 nginx 控制器拾取。这是我的 ingress.yaml

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-resource
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
    # nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/location-snippet: |
      location = /product/console/ {
        proxy_pass http://[hostname]/product/static/;
        }
spec:
  rules:
    - host: {{.Values.HOSTNAME}}
      http:
        paths:
        - path: /product/console
          backend:
            serviceName: product-svc
            servicePort: prod ##25022
        - path: /product/
          backend:
            serviceName: product-svc
            servicePort: prod #25022

-- 可以请教一些指点吗?我一直在尝试用谷歌搜索并尝试了一些不同的变体,但我似乎做错了什么。谢谢!

【问题讨论】:

  • 您是否尝试过在 Kubernetes 之外运行您的应用程序?它在那里工作吗?您是否尝试过使用像 kubernetes.io/ingress.class: "nginx" 这样没有其他注释的基本解决方案和像:"path: /*" 这样的基本路径?
  • 嘿@DawidKruk 谢谢!我试过了,但还是一样。问题似乎是,当我使用公共 dns dns/product/console/ 时,资产位于 dns/product/static。请求的 URL 似乎是 IP Address:80。我想添加代理通行证,但似乎对我不起作用。不知道是不是和具体版本有关,我也在GKE上。
  • 我从您的配置中看到,/product/console/product/static/your_files 在同一个服务中(因此是 pod)。当rewrite-target 不存在时,这不会产生任何问题,nginx-ingress 上没有进行额外的配置,并且路径在/* 上设置,假设它在 Kubernetes 之外工作。我没有听说你在 Kubernetes 之外尝试过它。你能澄清一下吗?我用index.html 和一些css 做了一个简单的例子。我可以发布它以供参考,但我不确定这是否有助于解决您遇到的这个确切问题。
  • @DawidKruk 嘿,是的,我确实尝试在本地运行它,它工作得很好。例外是当我在 localhost 上运行它时,我使用的是 localhost:port 而不是公共 dns。我认为重写应用程序以使静态资产可配置可能是一种方式。但是,如果您有一个可能有帮助的示例,我仍然会很感激。干杯
  • 在这种情况下使用HOSTNAME/localhost:port 如果您没有类似nginx 之类的东西在localhost 上重写您的请求,则不会有什么不同。根据您对Ingress 的配置,您能否确认您要实现的目标是:1)向/product 请求/product 传递请求时 2)向/product/static 请求/product/console 传递请求时。我将发布我的示例以及一些故障排除步骤。

标签: nginx kubernetes kubernetes-ingress nginx-config nginx-ingress


【解决方案1】:

TL;DR

要诊断您收到错误 404 的原因,您可以查看 nginx-ingress 控制器 pod 日志。你可以用下面的命令来做:

kubectl logs -n ingress-nginx INGRESS_NGINX_CONTROLLER_POD_NAME

你应该得到类似这样的输出(取决于你的用例):

CLIENT_IP - - [12/May/2020:11:06:56 +0000] "GET / HTTP/1.1" 200 238 "-" "REDACTED" 430 0.003 [default-ubuntu-service-ubuntu-port] [] 10.48.0.13:8080 276 0.003 200 
CLIENT_IP - - [12/May/2020:11:06:56  +0000] "GET /assets/styles/style.css HTTP/1.1" 200 22 "http://SERVER_IP/" "REDACTED" 348 0.002 [default-ubuntu-service-ubuntu-port] [] 10.48.0.13:8080 22 0.002 200 

通过以上日志,您可以检查请求是否由nginx-ingress 控制器正确处理以及它们的发送位置。

您也可以查看Kubernetes.github.io: ingress-nginx: Ingress-path-matching。这是一个描述Ingress 如何将路径与正则表达式匹配的文档。


您可以通过以下示例来试验Ingress

  • 部署nginx-ingress控制器
  • 创建一个pod 和一个service
  • 运行示例应用程序
  • 创建Ingress资源
  • 测试
  • 重写示例

部署nginx-ingress控制器

您可以通过以下官方文档部署您的nginx-ingress 控制器:

Kubernetes.github.io: Ingress-nginx

创建一个pod 和一个service

下面是一个 pod 的示例定义和附加到它的服务,将用于测试目的:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ubuntu-deployment
spec:
  selector:
    matchLabels:
      app: ubuntu
  replicas: 1 
  template:
    metadata:
      labels:
        app: ubuntu
    spec:
      containers:
      - name: ubuntu
        image: ubuntu
        command:
        - sleep
        - "infinity" 
---
apiVersion: v1
kind: Service
metadata:
  name: ubuntu-service
spec:
  selector:
    app: ubuntu
  ports:
    - name: ubuntu-port
      port: 8080
      targetPort: 8080
      nodePort: 30080
  type: NodePort 

示例页面

我创建了一个基本的index.html 和一个css 来模拟请求过程。您需要在 pod 内创建这些文件(手动或将它们复制到 pod)。

文件树如下所示:

  • index.html
  • assets/styles/style.css

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="assets/styles/style.css">
  <title>Document</title>
</head>
<body>
  <h1>Hi</h1>
</body>

请具体看一行:

  <link rel="stylesheet" href="assets/styles/style.css">

style.css

h1 {
  color: red;
}

您可以使用python 运行以上页面:

  • $ apt update &amp;&amp; apt install -y python3
  • $ python3 -m http.server 8080 存储 index.htmlassets 文件夹的位置。

创建一个Ingress 资源

以下是配置为使用nginx-ingress 控制器的Ingress 资源示例:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress-example
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: 
    http:
      paths:
      - path: /
        backend:
          serviceName: ubuntu-service 
          servicePort: ubuntu-port

应用上述资源后,您可以开始测试。

测试

您可以转到浏览器并输入与您的 Ingress 资源关联的外部 IP 地址。

正如我上面所说,您可以查看 nginx-ingress 控制器 pod 的日志,以检查您的控制器如何处理请求。

如果你运行前面提到的命令python3 -m http.server 8080 你也会得到日志:

$ python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
10.48.0.16 - - [12/May/2020 11:06:56] "GET / HTTP/1.1" 200 -
10.48.0.16 - - [12/May/2020 11:06:56] "GET /assets/styles/style.css HTTP/1.1" 200 -

重写示例

我编辑了 Ingress 资源,向您展示了路径重写的示例:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress-example
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - host: 
    http:
      paths:
      - path: /product/(.*)
        backend:
          serviceName: ubuntu-service 
          servicePort: ubuntu-port

对行进行了更改:

    nginx.ingress.kubernetes.io/rewrite-target: /$1

和:

      - path: /product/(.*)

步骤:

  • 浏览器发送:/product/
  • 控制器获得/product/ 并将其重写为/
  • Pod 从控制器获得/

来自nginx-ingress 控制器的日志:

CLIENT_IP - - [12/May/2020:11:33:23 +0000] "GET /product/ HTTP/1.1" 200 228 "-" "REDACTED" 438 0.002 [default-ubuntu-service-ubuntu-port] [] 10.48.0.13:8080 276 0.001 200 fb0d95e7253335fc82cc84f70348683a
CLIENT_IP - - [12/May/2020:11:33:23 +0000] "GET /product/assets/styles/style.css HTTP/1.1" 200 22 "http://SERVER_IP/product/" "REDACTED" 364 0.002 [default-ubuntu-service-ubuntu-port] [] 10.48.0.13:8080 22 0.002 200 

来自 pod 的日志:

10.48.0.16 - - [12/May/2020 11:33:23] "GET / HTTP/1.1" 200 -
10.48.0.16 - - [12/May/2020 11:33:23] "GET /assets/styles/style.css HTTP/1.1" 200 -

如果您对此有任何疑问,请告诉我。

【讨论】:

  • 哦,哇,谢谢@david.kruk。一旦我被分配到其他地方,我一定会尝试一下。不过我真的很感激!干杯
猜你喜欢
  • 2021-01-22
  • 2017-08-14
  • 2018-07-17
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 2021-01-17
  • 2014-12-19
  • 2015-06-12
相关资源
最近更新 更多