成功最有效的方法就是向有经验的人学习!

Ingress-nginx定制错误页面

网站运行过程中难免出现问题,为用户抛出一个错误页面,常见的错误页面包含403、404、500、502、503、504状态码,这些常见的错误页面状态码的含义如下

403 Forbidden
404 Not Found
500 Internal Server Eroor
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout

默认的错误页面是我们经常看到的那样,很素。如下所示:
file
file

出于安全考虑和友好提示,我们一般建议创建默认后端页面。
我们虽然隐藏了Ingress nginx的版本号,但直接返回状态码还是不够友好。一些网站都会有自定义的较友好、美观的错误页面或跳转到公益页面等。

部署默认后端

Ingress nginx提供了默认的自定义后端供用户使用,yaml如下

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-errors
  labels:
    app.kubernetes.io/name: nginx-errors
    app.kubernetes.io/part-of: ingress-nginx
spec:
  selector:
    app.kubernetes.io/name: nginx-errors
    app.kubernetes.io/part-of: ingress-nginx
  ports:
  - port: 80
    targetPort: 8080
    name: http
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-errors
  labels:
    app.kubernetes.io/name: nginx-errors
    app.kubernetes.io/part-of: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: nginx-errors
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: nginx-errors
        app.kubernetes.io/part-of: ingress-nginx
    spec:
      containers:
      - name: nginx-error-server
        image: quay.io/kubernetes-ingress-controller/custom-error-pages-amd64:0.3
        ports:
        - containerPort: 8080
        # Setting the environment variable DEBUG we can see the headers sent 
        # by the ingress controller to the backend in the client response.
        # env:
        # - name: DEBUG
        #   value: "true"

配置启动参数
修改Ingress controller控制器的启动参数,加入以下配置,通过--default-backend标志的值设置为新创建的错误后端的名称

- --default-backend-service=ingress-nginx/nginx-errors

修改ingress-nginx对应的configmap指定要关联到默认后端服务的服务状态码,意味着如果状态码是配置项中的值,那么返回给客户端浏览器的就是默认后端服务

custom-http-errors: 403,404,500,502,503,504

剖析请求与关键
如下图所示,Ingress Controller控制器的工作原理,简单来说,将控制器理解为一个监听器,通过不断地监听 kube-apiserver,实时的感知后端 Service和Pod的变化,当得到这些信息变化后,Ingress Controller再结合Ingress的配置,更新反向代理负载均衡器,从而达到服务发现的作用。Ingress-nginx的最终目标是构造nginx.conf这样的配置文件,主要用途是在配置文件有任何变更后都需要重新加载 nginx。

file

通过上面创建ingress资源,以及配置控制器启动参数和configmap,进入到nginx-ingress-controller的pod中查看配置(文件内容很多,可以导出或过滤查看)。

会看到将状态码关联了自定义的默认后端

# kubectl -n ingress-nginx exec -it nginx-ingress-controller-2rrsw bash
www-data@k8s-node3:/etc/nginx$ grep "error_page" nginx.conf -C 10

        ssl_ecdh_curve auto;

        proxy_intercept_errors on;

        error_page 404 = @custom_upstream-default-backend_404;
        error_page 500 = @custom_upstream-default-backend_500;
        error_page 502 = @custom_upstream-default-backend_502;
        error_page 503 = @custom_upstream-default-backend_503;
        error_page 504 = @custom_upstream-default-backend_504;

        proxy_ssl_session_reuse on;

        upstream upstream_balancer {
                server 0.0.0.1; # placeholder

过滤出上面创建的域名example.bar.com相关配置

    ## start server example.bar.com
    server {
        server_name example.bar.com ;

        listen 80;

        listen [::]:80;

        set $proxy_upstream_name "-";
        set $pass_access_scheme $scheme;
        set $pass_server_port $server_port;
        set $best_http_host $http_host;
        set $pass_port $pass_server_port;
...
        location @custom_upstream-default-backend_404 {
            internal;

            proxy_intercept_errors off;

            proxy_set_header       X-Code             404;
            proxy_set_header       X-Format           $http_accept;
            proxy_set_header       X-Original-URI     $request_uri;
            proxy_set_header       X-Namespace        $namespace;
            proxy_set_header       X-Ingress-Name     $ingress_name;
            proxy_set_header       X-Service-Name     $service_name;
            proxy_set_header       X-Service-Port     $service_port;
            proxy_set_header       X-Request-ID       $req_id;
            proxy_set_header       Host               $best_http_host;

            set $proxy_upstream_name upstream-default-backend;

            rewrite                (.*) / break;

            proxy_pass            http://upstream_balancer;
            log_by_lua_block {

                monitor.call()

            }
        }

        location @custom_upstream-default-backend_500 {
            internal;

            proxy_intercept_errors off;

            proxy_set_header       X-Code             500;
            proxy_set_header       X-Format           $http_accept;
            proxy_set_header       X-Original-URI     $request_uri;
            proxy_set_header       X-Namespace        $namespace;
            proxy_set_header       X-Ingress-Name     $ingress_name;
            proxy_set_header       X-Service-Name     $service_name;
            proxy_set_header       X-Service-Port     $service_port;
            proxy_set_header       X-Request-ID       $req_id;
            proxy_set_header       Host               $best_http_host;

            set $proxy_upstream_name upstream-default-backend;

            rewrite                (.*) / break;

            proxy_pass            http://upstream_balancer;
            log_by_lua_block {

                monitor.call()

            }
        }
...

这个server中关于默认后端的配置内容是关键信息(踩坑发现,后面只有用到这里的相关配置才能达到最终目标,否则无法判断)。

可以看到,在传递默认后端时,设置了多个请求头字段,其中X-Code即状态码正是所需要的,这里意味着将控制器返回的对应状态码,例如500定义在了X-Code中。如果自定义一个默认后端来取代官方的默认后端,就可以通过X-Code这个特定的头部来判断实现不同的状态码从而返回不同的自定义错误页面。

关于X-code早期的版本可能会不生效,参考:https://github.com/kubernetes/ingress-nginx/issues/2281

部署自定义后端
镜像已构建,直接使用。

apiVersion: v1
kind: Service
metadata:
  name: gl-ingress-nginx-errors
  labels:
    app.kubernetes.io/name: gl-ingress-nginx-errors
    app.kubernetes.io/part-of: ingress-nginx
  namespace: ingress-nginx
spec:
  selector:
    app.kubernetes.io/name: gl-ingress-nginx-errors
    app.kubernetes.io/part-of: ingress-nginx
  ports:
  - port: 80
    targetPort: 80
    name: http
您暂时无权查看此隐藏内容!
ports: - containerPort: 80 # Setting the environment variable DEBUG we can see the headers sent # by the ingress controller to the backend in the client response. # env: # - name: DEBUG # value: "true"

修改Ingress controller控制器的启动参数,修改关联的service名称

- --default-backend-service=ingress-nginx/gl-ingress-nginx-errors

file

内容查看本文隐藏内容查看需要消耗10土豆币,请先
土豆币按需购买,不退换,请考虑清楚后购买。
赞(2) 打赏
未经允许不得转载:陈桂林博客 » Ingress-nginx定制错误页面
分享到

大佬们的评论 抢沙发

全新“一站式”建站,高质量、高售后的一条龙服务

微信 抖音 支付宝 百度 头条 快手全平台打通信息流

橙子建站.极速智能建站8折购买虚拟主机

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册