Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
858 views
in Technique[技术] by (71.8m points)

kubernetes - Ingress Nginx - how to serve assets to application

I have an issue, I am deploying an application on [hostname]/product/console, but the .css .js files are being requested from [hostname]/product/static, hence they are not being loaded and I get 404.

I have tried nginx.ingress.kubernetes.io/rewrite-target: to no avail.

I also tried using: nginx.ingress.kubernetes.io/location-snippet: | location = /product/console/ { proxy_pass http://[hostname]/product/static/; }

But the latter does not seem to be picked up by the nginx controller at all. This is my 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

-- Can I ask for some pointers? I have been trying to google this out and tried some different variations, but I seem to be doing something wrong. Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

TL;DR

To diagnose the reason why you get error 404 you can check in nginx-ingress controller pod logs. You can do it with below command:

kubectl logs -n ingress-nginx INGRESS_NGINX_CONTROLLER_POD_NAME

You should get output similar to this (depending on your use case):

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 

With above logs you can check if the requests are handled properly by nginx-ingress controller and where they are sent.

Also you can check the Kubernetes.github.io: ingress-nginx: Ingress-path-matching. It's a document describing how Ingress matches paths with regular expressions.


You can experiment with Ingress, by following below example:

  • Deploy nginx-ingress controller
  • Create a pod and a service
  • Run example application
  • Create an Ingress resource
  • Test
  • Rewrite example

Deploy nginx-ingress controller

You can deploy your nginx-ingress controller by following official documentation:

Kubernetes.github.io: Ingress-nginx

Create a pod and a service

Below is an example definition of a pod and a service attached to it which will be used for testing purposes:

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 

Example page

I created a basic index.html with one css to simulate the request process. You need to create this files inside of a pod (manually or copy them to pod).

The file tree looks like this:

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

Please take a specific look on a line:

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

style.css:

h1 {
  color: red;
}

You can run above page with python:

  • $ apt update && apt install -y python3
  • $ python3 -m http.server 8080 where the index.html and assets folder is stored.

Create an Ingress resource

Below is an example Ingress resource configured to use nginx-ingress controller:

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

After applying above resource you can start to test.

Test

You can go to your browser and enter the external IP address associated with your Ingress resource.

As I said above you can check the logs of nginx-ingress controller pod to check how your controller is handling request.

If you run command mentioned earlier python3 -m http.server 8080 you will get logs too:

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

Rewrite example

I've edited the Ingress resource to show you an example of a path rewrite:

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

Changes were made to lines:

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

and:

      - path: /product/(.*)

Steps:

  • The browser sent: /product/
  • Controller got /product/ and had it rewritten to /
  • Pod got / from a controller.

Logs from thenginx-ingress controller:

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 

Logs from the 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 -

Please let me know if you have any questions in that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...