Mẹo & thủ thuật Kubernetes: các trang lỗi tùy chỉnh trong NGINX Ingress

Mẹo & thủ thuật Kubernetes: các trang lỗi tùy chỉnh trong NGINX Ingress

Trong bài viết này, tôi muốn nói về hai tính năng của NGINX Ingress liên quan đến việc hiển thị các trang lỗi được cá nhân hóa, cũng như những hạn chế tồn tại trong chúng và cách khắc phục chúng.

1. Thay đổi phần phụ trợ mặc định

Theo mặc định, NGINX Ingress sử dụng chương trình phụ trợ mặc định, thực hiện chức năng tương ứng. Điều này có nghĩa là khi yêu cầu Ingress chỉ định một máy chủ không có trong tài nguyên Ingress, chúng tôi nhận được trang sau có mã phản hồi 404:

Mẹo & thủ thuật Kubernetes: các trang lỗi tùy chỉnh trong NGINX Ingress

Tuy nhiên, ngày càng có nhiều khách hàng của chúng tôi yêu cầu hiển thị trang của họ có logo công ty và các tiện ích khác thay vì 404 tiêu chuẩn. Để làm điều này, NGINX Ingress có khả năng tích hợp xác định lại default-backend-service. Chúng tôi chuyển mục nhập định dạng làm đối số cho tùy chọn có cùng tên namespace/servicename. Cổng của dịch vụ phải là 80.

Để làm điều này, bạn cần tạo nhóm (triển khai) và dịch vụ của riêng mình với ứng dụng của bạn (ví dụ triển khai trong YAML từ kho lưu trữ ingress-nginx), sẽ được cung cấp thay vì phần phụ trợ mặc định.

Đây là một minh họa nhỏ:

~$ curl -i -XGET http://sadsdasdas.kube-cloud.my/
HTTP/1.1 404 Not Found
Date: Mon, 11 Mar 2019 05:38:15 GMT
Content-Type: */*
Transfer-Encoding: chunked
Connection: keep-alive

<span>The page you're looking for could not be found.</span>

Vì vậy, tất cả các miền không được tạo rõ ràng thông qua YAML với kind: Ingress, rơi vào phần phụ trợ mặc định. Trong danh sách trên, tên miền này đã trở thành sadsdasdas.

2. Xử lý lỗi HTTP trong ứng dụng bằng backend mặc định

Một tình huống khác là các yêu cầu kết thúc bằng lỗi HTTP (404, 500, 502...) đối với một ứng dụng không xử lý các tình huống như vậy (các trang đẹp tương ứng không được tạo). Điều này cũng có thể là do mong muốn của các nhà phát triển là cung cấp cùng một trang lỗi trong nhiều ứng dụng.

Để thực hiện trường hợp này ở phía máy chủ, chúng ta cần:

  1. Thực hiện theo các hướng dẫn ở trên từ đoạn về chương trình phụ trợ mặc định;
  2. Thêm khóa vào cấu hình nginx-ingress ConfigMap custom-http-errors, ví dụ, với giá trị 404,503 (rõ ràng tương ứng với các mã lỗi được quy định trong quy tắc mới).

Kết quả như mong đợi đã đạt được: khi ứng dụng khách đang chạy và nhận được lỗi mã phản hồi 404 hoặc 503, yêu cầu sẽ tự động được chuyển hướng đến backend mặc định mới...

Tuy nhiên, khi phát triển một ứng dụng dành cho phần phụ trợ mặc định và lỗi http tùy chỉnh, bạn cần tính đến một tính năng quan trọng:

!!! Important The custom backend is expected to return the correct HTTP status code instead of 200. NGINX does not change the response from the custom default backend.

Thực tế là khi một yêu cầu được chuyển hướng, các tiêu đề sẽ chứa thông tin hữu ích với mã phản hồi trước đó và thông tin bổ sung (danh sách đầy đủ của chúng có sẵn đây).

Điều này có nghĩa là bản thân bạn phải chăm sóc mã phản hồi chính xác. Đây là một ví dụ. từ tài liệu về cách nó hoạt động.

Các ứng dụng khác nhau có phần phụ trợ mặc định khác nhau

Để đảm bảo rằng giải pháp không mang tính chung cho toàn bộ cụm mà chỉ áp dụng cho các ứng dụng cụ thể, trước tiên bạn cần kiểm tra phiên bản Ingress. Nếu nó khớp 0.23 trở lên, hãy sử dụng các chú thích Ingress gốc:

  1. Chúng ta có thể ghi đè default-backend cho môi xâm nhập sử dụng chú thích;
  2. Chúng ta có thể ghi đè custom-http-errors cho môi xâm nhập sử dụng chú thích.

Kết quả là tài nguyên Ingress sẽ trông giống như thế này:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ .Chart.Name }}-app2
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/custom-http-errors: "404,502"
    nginx.ingress.kubernetes.io/default-backend: error-pages
spec:
  tls:
  - hosts:
    - app2.example.com
    secretName: wildcard-tls
  rules:
  - host: app2.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: {{ .Chart.Name }}-app2
          servicePort: 80

Trong trường hợp này, lỗi 404 và 502 sẽ được chuyển hướng đến dịch vụ trang lỗi với tất cả các tiêu đề cần thiết.

В các phiên bản trước của Ingress không có tính năng này (cam kết định mệnh ở mức 0.23). Và nếu bạn có 2 ứng dụng hoàn toàn khác nhau đang chạy trong cụm của mình và bạn muốn chỉ định một dịch vụ phụ trợ mặc định khác và xử lý các mã lỗi khác nhau cho mỗi ứng dụng đó, thì bạn sẽ phải sử dụng các giải pháp thay thế, trong đó chúng tôi có hai giải pháp.

Xâm nhập < 0.23: tiếp cận một

Tùy chọn này đơn giản hơn. Là một ứng dụng phục vụ các trang của nó, chúng tôi có HTML thông thường, không biết cách xem các tiêu đề và trả về mã phản hồi chính xác. Một ứng dụng như vậy được triển khai với Ingress từ url /error-pages, và trong danh mục ws sẽ là HTML được trả về.

Minh họa trong YAML:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ .Chart.Name }}-app2
  annotations:
    kubernetes.io/ingress.class: "nginx"
    ingress.kubernetes.io/server-snippet: |
      proxy_intercept_errors on;
      error_page 500 501 502 503 504 @error_pages;
      location @error_pages {
        rewrite ^ /error-pages/other/index.html break;
        proxy_pass http://error-pages.prod.svc.cluster.local;
      }
spec:
  tls:
  - hosts:
    - app2.example.com
    secretName: wildcard-tls
  rules:
  - host: app2.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: {{ .Chart.Name }}-app2
          servicePort: 80

Dịch vụ cho việc triển khai này phải thuộc loại ClusterIP.

Đồng thời, trong ứng dụng mà chúng tôi sẽ xử lý lỗi, trong Ingress, chúng tôi thêm đoạn mã máy chủ hoặc đoạn mã cấu hình với nội dung sau:

nginx.ingress.kubernetes.io    /server-snippet: |
      proxy_intercept_errors on;
      error_page 500 501 502 503 504 @error_pages;
      location @error_pages {
        rewrite ^ /error-pages/ws/index.html break;
        proxy_pass http://error-pages.prod.svc.cluster.local;
      }

Xâm nhập < 0.23: cách tiếp cận thứ hai

Một tùy chọn cho một ứng dụng có thể xử lý các tiêu đề... Và nói chung đây là một cách chính xác hơn, được mượn từ các lỗi http tùy chỉnh. Sử dụng thủ công (sao chép) sẽ cho phép bạn không thay đổi cài đặt chung.

Các bước thực hiện như sau. Chúng tôi tạo ra triển khai tương tự với một ứng dụng có thể nghe các tiêu đề cần thiết và phản hồi chính xác. Thêm server-snippet vào ứng dụng Ingress với nội dung sau:

nginx.ingress.kubernetes.io    /server-snippet: |
      proxy_intercept_errors off;
      error_page 404 = @custom_404;
      error_page 503 = @custom_503;
      location @custom_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       Host               $best_http_host;
        rewrite ^ /error-pages/ws/index.html break;
        proxy_pass http://error-pages.prod.svc.cluster.local;
      }
      location @custom_503 {
        internal;
        proxy_intercept_errors off;
        proxy_set_header       X-Code             503;
        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       Host               $best_http_host;
        rewrite ^ /error-pages/ws/index.html break;
        proxy_pass http://error-pages.prod.svc.cluster.local;
      }

Như bạn có thể thấy, đối với mỗi lỗi mà chúng tôi muốn xử lý, chúng tôi cần tạo một vị trí của riêng mình, nơi tất cả các tiêu đề cần thiết sẽ được chèn vào, như trong tiêu đề “gốc”. trang lỗi tùy chỉnh. Bằng cách này, chúng tôi có thể tạo các trang lỗi được cá nhân hóa khác nhau ngay cả đối với các vị trí và máy chủ riêng lẻ.

PS

Khác với loạt mẹo & thủ thuật K8s:

Đọc thêm trên blog của chúng tôi:

Nguồn: www.habr.com

Thêm một lời nhận xét