Ingress Nginx - 如何为应用程序提供资产

Ingress Nginx - how to serve assets to application

我有一个问题,我正在 [hostname]/product/console 上部署一个应用程序,但是 .css .js 文件是从 [hostname]/product/static 请求的,因此它们没有被加载,我得到 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: /
    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

-- 我可以请教一些指点吗?我一直在尝试 google 解决这个问题并尝试了一些不同的变体,但我似乎做错了什么。谢谢!

TL;DR

要诊断您收到错误 404 的原因,您可以查看 nginx-ingress controller 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 && 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: /
spec:
  rules:
  - host: 
    http:
      paths:
      - path: /product/(.*)
        backend:
          serviceName: ubuntu-service 
          servicePort: ubuntu-port

对行进行了更改:

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

和:

      - 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 -

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