zoukankan      html  css  js  c++  java
  • nginx-ingress-controler改写上下文

    背景:
    由于域名和公网费用昂贵。通常是只有一个域名,但是有多个应用需要上线。通常都会域名+应用名称(www.ecloud.com/app)。原本应用已经开发好的了,访问是在 / 。那就需要改写上下文来实现。

    原应用演示

    $ kubectl get svc app demo
    NAME   TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    app    ClusterIP   10.183.0.36   <none>        8001/TCP   6m13s
    demo   ClusterIP   10.183.0.37   <none>        8002/TCP   2m47s
    
    $  curl 10.183.0.36:8001
    app
    
    $ curl 10.183.0.37:8002/test/demo/
    demo
    

    现在有两个应用分别是 appdemo。分别的访问路径为://test/demo。现在只有一个域名是 www.ecloud.com 且需要把两个网页都放在同一个域名访问。

    添加上下文路径

    现在的目标是把 app 应用,可以通过 www.ecloud.com/app/ 来展示

    创建ingress

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: app
      namespace: default
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$2  # 真实到服务的上下文
    spec:
      ingressClassName: nginx
      rules:
      - host: www.ecloud.com
        http:
          paths:
          - path: /app(/|)(.*)  # 浏览器访问上下文
            backend:
              serviceName: app
              servicePort: 8001
    

    验证

    $ curl www.ecloud.com/app/
    app
    
    $ curl www.ecloud.com/app/index.html
    app
    

    减少上下文路径

    现在的目标是把 demo 应用,可以通过 www.ecloud.com/demo/ 来展示

    创建ingress

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: demo
      namespace: default
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /test/demo/$2 # 真实到服务的上下文
    spec:
      ingressClassName: nginx
      rules:
      - host: www.ecloud.com
        http:
          paths:
          - path: /demo(/|)(.*) # 浏览器访问上下文
            backend:
              serviceName: demo
              servicePort: 8002
    

    验证

    $ curl www.ecloud.com/demo
    demo
    
    $ curl www.ecloud.com/demo/
    demo
    
    $ curl www.ecloud.com/demo/index.html
    demo
    

    修改主域名跳转

    应该给应用设置一个 app-root 的注解,这样当我们访问主域名的时候会自动跳转到我们指定的 app-root 目录下面。如下所示:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: demo
      namespace: default
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /test/demo/$2 # 真实到服务的上下文
        nginx.ingress.kubernetes.io/app-root: /demo/    # 这里写浏览器访问的路径
    spec:
      ingressClassName: nginx
      rules:
      - host: www.ecloud.com
        http:
          paths:
          - path: /demo(/|)(.*) # 浏览器访问上下文
            backend:
              serviceName: demo
              servicePort: 8002
    

    验证

    $ curl www.ecloud.com
    <html>
    <head><title>302 Found</title></head>
    <body>
    <center><h1>302 Found</h1></center>
    <hr><center>nginx</center>
    </body>
    </html>
    
    # nginx-ingress-controller 的日志
    192.168.32.134 - - [16/Sep/2021:08:22:39 +0000] "GET / HTTP/1.1" 302 138 "-" "curl/7.29.0" 78 0.000 [-] [] - - - - 5ba35f028edbd48ff316bd544ae60746
    
    $ curl www.ecloud.com -L
    demo
    
    # nginx-ingress-controller 的日志
    192.168.32.134 - - [16/Sep/2021:08:22:56 +0000] "GET / HTTP/1.1" 302 138 "-" "curl/7.29.0" 78 0.000 [-] [] - - - - 4ffa0129b9fab80b9e904ad9716bd8ca
    192.168.32.134 - - [16/Sep/2021:08:22:56 +0000] "GET /demo/ HTTP/1.1" 200 5 "-" "curl/7.29.0" 83 0.003 [default-demo-8002] [] 20.0.32.159:8002 5 0.002 200 3d17d7cb25f3eacc7eb848955a28675f
    

    注意事项

    不能定义默认的 ingress.spec.backend 字段。否则会发生不符合预期的跳转。

    模拟定义 ingress.spec.backend 字段

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: app
      namespace: default
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$2
    spec:
      ingressClassName: nginx
      backend:  # 设置默认的backend
        serviceName: app
        servicePort: 8001
      rules:
      - host: www.ecloud.com
        http:
          paths:
          - path: /app(/|$)(.*)
            backend:
              serviceName: app
              servicePort: 8001
    

    查看ingress资源情况

    $ kubectl get ingress
    NAME   CLASS   HOSTS            ADDRESS          PORTS   AGE
    app    nginx   www.ecloud.com   192.168.32.138   80      20m
    
    $ kubectl describe ingress app
    Name:             app
    Namespace:        default
    Address:          192.168.32.138
    Default backend:  app:8001 (20.0.32.157:8001)
    Rules:
      Host            Path  Backends
      ----            ----  --------
      www.ecloud.com  
                      /app(/|$)(.*)   app:8001 (20.0.32.157:8001)
    Annotations:      nginx.ingress.kubernetes.io/rewrite-target: /$2
    Events:
      Type    Reason  Age                  From                      Message
      ----    ------  ----                 ----                      -------
      Normal  Sync    7m52s (x5 over 21m)  nginx-ingress-controller  Scheduled for sync
    

    测试访问

    $ curl www.ecloud.com
    app
    
    $ curl www.ecloud.com/fskl/fskf/ajfk
    app
    

    发现不符合 /app 的上下文也可以匹配到 / 的页面,这个是不符合我们的预期的。

    查看nginx的配置文件

    $ kubectl -n ingress-nginx exec -it ingress-nginx-controller-6c979c5b47-bpwf6 -- bash
    $ vi /etc/nginx/nginx.conf
                    # 找到 `server_name` 为设置的域名,找到为 `location ~* "^/"`
                    # 没有匹配到 `/app` 的上下文,则进入该location。
                    # 该location读取app应用的 `/` 。所以访问 `/fskl/fskf/ajfk` 都可以访问到 `/` 的页面
                    # 原本我们的预期是访问错了上下文,应该是报 `404` 的,而不是访问主域名页面
                    location ~* "^/" {                                                                                                             
                            set $namespace      "default";                                                                                         
                            set $ingress_name   "app";                                                                                             
                            set $service_name   "app";                                                                                             
                            set $service_port   "8001";                                                                                            
                            set $location_path  "/"
                            ...
                    }
    

    虽然没有定义默认的 ingress.spec.backend 字段。在 kubectl describe ingress 查看ingress详情时,会有 Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) 提示,但是影响正常使用。

  • 相关阅读:
    Debug和Release区别
    C语言程序_管理系统
    读书的学问
    御姐的含义
    进制的英文书写
    CHM文件无法打开的解决方法
    819代码
    点击链接不跳转或刷新
    MS SqlServer 随机查询并随机排序
    Html背景图
  • 原文地址:https://www.cnblogs.com/mycloudedu/p/15293913.html
Copyright © 2011-2022 走看看