نکات و ترفندهای Kubernetes: صفحات خطای سفارشی در NGINX Ingress

نکات و ترفندهای Kubernetes: صفحات خطای سفارشی در NGINX Ingress

در این مقاله می‌خواهم در مورد دو ویژگی NGINX Ingress مربوط به نمایش صفحات خطای شخصی‌سازی شده و همچنین محدودیت‌های موجود در آن‌ها و راه‌های رفع آنها صحبت کنم.

1. تغییر backend پیش فرض

به طور پیش فرض، NGINX Ingress از backend پیش فرض استفاده می کند که عملکرد مربوطه را انجام می دهد. این بدان معناست که هنگام درخواست Ingress که میزبانی را مشخص می کند که در منابع Ingress نیست، صفحه زیر را با کد پاسخ 404 دریافت می کنیم:

نکات و ترفندهای Kubernetes: صفحات خطای سفارشی در NGINX Ingress

با این حال، بیشتر و بیشتر مشتریان ما با درخواست نشان دادن صفحه خود با آرم شرکت و سایر امکانات به جای استاندارد 404 مراجعه می کنند. برای انجام این کار، NGINX Ingress دارد قابلیت داخلی دوباره تعریف کند default-backend-service. ورودی قالب را به عنوان آرگومان به گزینه ای با همین نام منتقل می کنیم namespace/servicename. پورت سرویس باید 80 باشد.

برای انجام این کار، باید پاد (استقرار) و سرویس خود را با برنامه خود ایجاد کنید (اجرای مثال در YAML از مخزن ingress-nginx)، که به جای backend پیش فرض داده می شود.

در اینجا یک تصویر کوچک وجود دارد:

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

بنابراین تمام دامنه هایی که به صراحت از طریق YAML با ایجاد نشده اند kind: Ingress، در قسمت پیش فرض پیش فرض قرار می گیرند. در لیست بالا، این دامنه تبدیل شد sadsdasdas.

2. مدیریت خطاهای HTTP در برنامه با استفاده از باطن پیش فرض

وضعیت دیگر درخواست هایی است که به خطاهای HTTP (404، 500، 502...) ختم می شوند به برنامه ای که چنین موقعیت هایی را پردازش نمی کند (صفحات زیبای مربوطه ایجاد نمی شوند). این ممکن است به دلیل تمایل توسعه دهندگان به ارائه صفحات خطای مشابه در چندین برنامه باشد.

برای پیاده سازی این مورد در سمت سرور ما نیاز داریم:

  1. دستورالعمل های بالا را از پاراگراف مربوط به پیش فرض پیش فرض دنبال کنید.
  2. یک کلید به پیکربندی nginx-ingress ConfigMap اضافه کنید custom-http-errorsبه عنوان مثال، با مقدار 404,503 (بدیهی است که مربوط به کدهای خطا است که توسط قانون جدید پوشش داده شده است).

نتیجه مورد انتظار به دست آمده است: هنگامی که برنامه مشتری در حال اجرا است و خطایی با کد پاسخ 404 یا 503 دریافت می کند، درخواست به طور خودکار به پشتیبان پیش فرض جدید هدایت می شود.

با این حال، هنگام توسعه یک برنامه برای خطاهای پیش فرض پشتیبان و سفارشی-http، باید یک ویژگی مهم را در نظر بگیرید:

!!! 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.

واقعیت این است که وقتی یک درخواست هدایت می شود، هدرها حاوی اطلاعات مفیدی با کد پاسخ قبلی و اطلاعات اضافی هستند (لیست کامل آنها موجود است اینجا).

این بدان معنی است که شما خودتان باید مراقب کد پاسخ صحیح باشید. در اینجا یک مثال است. از مستندات نحوه کار آن

برنامه های مختلف دارای پشتیبان های پیش فرض متفاوتی هستند

برای اطمینان از اینکه راه حل برای کل خوشه جهانی نیست، بلکه فقط برای برنامه های خاص اعمال می شود، ابتدا باید نسخه Ingress را بررسی کنید. اگر مطابقت داشته باشد 0.23 یا بالاتر، از یادداشت های بومی Ingress استفاده کنید:

  1. ما می توانیم نادیده بگیریم default-backend برای از هر کدام مال ورودی با استفاده از حاشیه نویسی;
  2. ما می توانیم نادیده بگیریم custom-http-errors برای از هر کدام مال ورودی با استفاده از حاشیه نویسی.

در نتیجه، منبع Ingress چیزی شبیه به این خواهد بود:

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

در این صورت، خطاهای 404 و 502 با تمام هدرهای لازم به سرویس error-pages هدایت می شوند.

В نسخه های قبلی Ingress این ویژگی را نداشتند (ارتکاب سرنوشت ساز در 0.23). و اگر 2 برنامه کاملاً متفاوت در کلاستر خود دارید و می‌خواهید یک سرویس پیش‌فرض و پردازش کدهای خطای مختلف برای هر یک از آنها مشخص کنید، برای این کار باید از راه‌حل‌هایی استفاده کنید که ما دو مورد از آن‌ها را داریم.

ورودی < 0.23: رویکرد یک

این گزینه ساده تر است. به عنوان برنامه ای که صفحات خود را ارائه می دهد، HTML معمولی داریم که نمی داند چگونه به سربرگ ها نگاه کند و کدهای پاسخ صحیح را برگرداند. چنین برنامه ای با Ingress از url منتشر می شود /error-pages، و در کاتالوگ ws HTML برگشتی خواهد بود.

تصویر در 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

سرویس این استقرار باید از نوع ClusterIP باشد.

در همان زمان، در برنامه‌ای که خطا را پردازش می‌کنیم، در Ingress یک سرور-snippet یا configuration-snippet با محتوای زیر اضافه می‌کنیم:

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;
      }

ورودی <0.23: رویکرد دوم

گزینه ای برای برنامه ای که می تواند هدرها را پردازش کند... و به طور کلی این روش صحیح تری است که از خطاهای سفارشی-http- قرض گرفته شده است. استفاده از آن به صورت دستی (کپی) به شما امکان می دهد تنظیمات جهانی را تغییر ندهید.

مراحل به شرح زیر است. ما ایجاد می کنیم همان استقرار با اپلیکیشنی که بتواند سرفصل های لازم را گوش کند و به درستی پاسخ دهد. یک قطعه سرور با محتوای زیر به برنامه Ingress اضافه کنید:

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;
      }

همانطور که می بینید، برای هر خطایی که می خواهیم پردازش کنیم، باید مکان خود را بسازیم، جایی که تمام هدرهای لازم مانند هدر "بومی" درج می شود. صفحات خطای سفارشی. به این ترتیب می توانیم صفحات خطای شخصی متفاوتی را حتی برای مکان ها و سرورهای جداگانه ایجاد کنیم.

PS

موارد دیگر از سری نکات و ترفندهای K8s:

در وبلاگ ما نیز بخوانید:

منبع: www.habr.com

اضافه کردن نظر