Kiat & trik Kubernetes: halaman kesalahan khusus di NGINX Ingress

Kiat & trik Kubernetes: halaman kesalahan khusus di NGINX Ingress

Pada artikel ini, saya ingin berbicara tentang dua fitur NGINX Ingress terkait dengan menampilkan halaman kesalahan yang dipersonalisasi, serta batasan yang ada di dalamnya dan cara mengatasinya.

1. Mengubah backend default

Secara default, NGINX Ingress menggunakan backend default, yang menjalankan fungsi terkait. Ini berarti bahwa ketika meminta Ingress yang menentukan host yang tidak ada dalam sumber daya Ingress, kami menerima halaman berikut dengan kode respons 404:

Kiat & trik Kubernetes: halaman kesalahan khusus di NGINX Ingress

Namun, semakin sering klien kami datang dengan permintaan untuk menampilkan halaman mereka dengan logo perusahaan dan fasilitas lainnya, bukan standar 404. Untuk melakukan ini, NGINX Ingress punya kemampuan bawaan mendefinisikan kembali default-backend-service. Kami meneruskan entri format sebagai argumen ke opsi dengan nama yang sama namespace/servicename. Port layanan harus 80.

Untuk melakukan ini, Anda perlu membuat pod (penerapan) dan layanan Anda sendiri dengan aplikasi Anda (contoh implementasi di YAML dari repositori ingress-nginx), yang akan diberikan sebagai ganti backend default.

Berikut ilustrasi kecilnya:

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

Jadi semua domain yang tidak dibuat secara eksplisit melalui YAML dengan kind: Ingress, termasuk dalam backend default. Dalam daftar di atas, domain ini menjadi sadsdasdas.

2. Menangani error HTTP pada aplikasi menggunakan backend default

Situasi lainnya adalah permintaan yang berakhir dengan kesalahan HTTP (404, 500, 502...) ke aplikasi yang tidak memproses situasi seperti itu (halaman indah yang sesuai tidak dihasilkan). Hal ini mungkin juga disebabkan oleh keinginan pengembang untuk menyajikan halaman kesalahan yang sama di beberapa aplikasi.

Untuk mengimplementasikan kasus ini di sisi server kita memerlukan:

  1. Ikuti instruksi di atas dari paragraf tentang backend default;
  2. Tambahkan kunci ke konfigurasi nginx-ingress ConfigMap custom-http-errors, misalnya dengan nilai 404,503 (jelas sesuai dengan kode kesalahan yang tercakup dalam aturan baru).

Hasil yang diharapkan telah tercapai: ketika aplikasi klien berjalan dan menerima kesalahan dengan kode respons 404 atau 503, permintaan akan secara otomatis dialihkan ke backend default baru...

Namun, saat mengembangkan aplikasi untuk backend default dan kesalahan http khusus, Anda perlu mempertimbangkan fitur penting:

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

Faktanya adalah ketika permintaan dialihkan, header akan berisi informasi berguna dengan kode respons sebelumnya dan informasi tambahan (daftar lengkapnya tersedia di sini).

Ini berarti Anda sendiri yang harus melakukannya jaga kode respons yang benar. Berikut ini sebuah contoh dari dokumentasi cara kerjanya.

Aplikasi yang berbeda memiliki backend default yang berbeda

Untuk memastikan bahwa solusinya tidak bersifat global untuk seluruh cluster, tetapi hanya berlaku untuk aplikasi tertentu, Anda perlu memeriksa versi Ingress terlebih dahulu. Jika cocok 0.23 atau lebih tinggi, gunakan anotasi asli Ingress:

  1. Kita bisa menimpanya default-backend untuk dari masing-masing masuknya menggunakan anotasi;
  2. Kita bisa menimpanya custom-http-errors untuk dari masing-masing masuknya menggunakan anotasi.

Hasilnya, sumber daya Ingress akan terlihat seperti ini:

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

Dalam hal ini, kesalahan 404 dan 502 akan dialihkan ke layanan halaman kesalahan dengan semua header yang diperlukan.

Π’ versi Ingress sebelumnya tidak memiliki fitur ini (komit yang menentukan di 0.23). Dan jika Anda memiliki 2 aplikasi berbeda yang berjalan di cluster Anda dan Anda ingin menentukan layanan backend default yang berbeda dan pemrosesan kode kesalahan yang berbeda untuk masing-masing aplikasi, untuk ini Anda harus menggunakan solusi, yang kami punya dua.

Ingress <0.23: pendekatan satu

Opsi ini lebih sederhana. Sebagai aplikasi yang melayani halaman-halamannya, kami memiliki HTML biasa, yang tidak tahu cara melihat header dan mengembalikan kode respons yang benar. Aplikasi semacam itu diluncurkan dengan Ingress dari url /error-pages, dan di katalog ws akan menjadi HTML yang dikembalikan.

Ilustrasi di 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

Layanan untuk penerapan ini harus bertipe ClusterIP.

Pada saat yang sama, dalam aplikasi tempat kami akan memproses kesalahan, di Ingress kami menambahkan cuplikan server atau cuplikan konfigurasi dengan konten berikut:

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

Ingress <0.23: pendekatan kedua

Opsi untuk aplikasi yang dapat memproses header... Dan secara umum ini adalah cara yang lebih tepat, dipinjam dari custom-http-errors. Menggunakannya secara manual (menyalin) akan memungkinkan Anda untuk tidak mengubah pengaturan global.

Langkah-langkahnya adalah sebagai berikut. Kami menciptakan penerapan yang sama dengan aplikasi yang dapat mendengarkan berita utama yang diperlukan dan merespons dengan benar. Tambahkan cuplikan server ke aplikasi Ingress dengan konten berikut:

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

Seperti yang Anda lihat, untuk setiap kesalahan yang ingin kita proses, kita perlu membuat lokasi kita sendiri, di mana semua header yang diperlukan akan disisipkan, seperti pada header "asli". halaman kesalahan khusus. Dengan cara ini kami dapat membuat halaman kesalahan yang dipersonalisasi berbeda bahkan untuk masing-masing lokasi dan server.

PS

Lainnya dari seri tips & trik K8s:

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komentar