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>) 提示,但是影响正常使用。

  • 相关阅读:
    HDU 1102 Constructing Roads
    HDU 1285 确定比赛名次。
    最小生成树 HDU 各种畅通工程的题,prim和kru的模板题
    HDU Jungle Roads 1301 最小生成树、
    并查集小结(转)
    HDU hdu 2094 产生冠军 拓扑排序 判定环
    模运算(转)
    拓扑排序(主要是确定环和加法) HDU 2647 Reward
    HDU 1372 Knight Moves 简单BFS
    用计算机模型浅析人与人之间沟通方式 (一)如何谈话
  • 原文地址:https://www.cnblogs.com/mycloudedu/p/15293913.html
Copyright © 2011-2022 走看看