ในบทความนี้ ฉันต้องการพูดคุยเกี่ยวกับคุณลักษณะสองประการของ NGINX Ingress ที่เกี่ยวข้องกับการแสดงหน้าข้อผิดพลาดส่วนบุคคล ตลอดจนข้อจำกัดที่มีอยู่ในหน้าเหล่านั้นและวิธีแก้ไข
1. การเปลี่ยนแบ็กเอนด์เริ่มต้น
ตามค่าเริ่มต้น NGINX Ingress จะใช้แบ็กเอนด์เริ่มต้นซึ่งทำหน้าที่ที่เกี่ยวข้อง ซึ่งหมายความว่าเมื่อร้องขอ Ingress โดยระบุโฮสต์ที่ไม่ได้อยู่ในทรัพยากร Ingress เราได้รับหน้าต่อไปนี้พร้อมรหัสตอบกลับ 404:
อย่างไรก็ตาม บ่อยครั้งที่ลูกค้าของเราขอให้แสดงเพจของตนพร้อมโลโก้บริษัทและสิ่งอำนวยความสะดวกอื่น ๆ แทนที่จะเป็นมาตรฐาน 404 เมื่อต้องการทำเช่นนี้ NGINX Ingress จึงมี default-backend-service
. เราส่งรายการรูปแบบเป็นอาร์กิวเมนต์ไปยังตัวเลือกที่มีชื่อเดียวกัน namespace/servicename
. พอร์ตของบริการควรเป็น 80
ในการดำเนินการนี้ คุณต้องสร้างพ็อด (ปรับใช้) และบริการของคุณเองด้วยแอปพลิเคชันของคุณ (
นี่เป็นภาพประกอบเล็กๆ น้อยๆ:
~$ 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...) ไปยังแอปพลิเคชันที่ไม่ได้ประมวลผลสถานการณ์ดังกล่าว (ไม่มีการสร้างเพจที่สวยงามที่เกี่ยวข้อง) นี่อาจเป็นเพราะความต้องการของนักพัฒนาที่จะให้บริการหน้าข้อผิดพลาดเดียวกันในหลายแอปพลิเคชัน
หากต้องการใช้กรณีนี้บนฝั่งเซิร์ฟเวอร์ เราต้องการ:
- ปฏิบัติตามคำแนะนำข้างต้นจากย่อหน้าเกี่ยวกับแบ็กเอนด์เริ่มต้น
- เพิ่มคีย์ให้กับการกำหนดค่า nginx-ingress ConfigMap
custom-http-errors
เช่น ด้วยค่า404,503
(เห็นได้ชัดว่าสอดคล้องกับรหัสข้อผิดพลาดที่กฎใหม่ครอบคลุม)
บรรลุผลลัพธ์ที่คาดหวัง: เมื่อแอปพลิเคชันไคลเอนต์กำลังทำงานและได้รับข้อผิดพลาดด้วยรหัสตอบกลับ 404 หรือ 503 คำขอจะถูกเปลี่ยนเส้นทางไปยังแบ็กเอนด์เริ่มต้นใหม่โดยอัตโนมัติ...
อย่างไรก็ตาม เมื่อพัฒนาแอปพลิเคชันสำหรับแบ็กเอนด์เริ่มต้นและข้อผิดพลาด http-error ที่กำหนดเอง คุณจะต้องคำนึงถึงคุณลักษณะที่สำคัญด้วย:
!!! 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 ดั้งเดิม:
- เราสามารถแทนที่ได้
default-backend
สำหรับ แต่ละ ทางเข้าการใช้คำอธิบายประกอบ ; - เราสามารถแทนที่ได้
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 จะถูกเปลี่ยนเส้นทางไปยังบริการหน้าข้อผิดพลาดพร้อมส่วนหัวที่จำเป็นทั้งหมด
В Ingress เวอร์ชันก่อนหน้าไม่มีคุณสมบัตินี้ (
ทางเข้า < 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 เราได้เพิ่ม server-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 แบบกำหนดเอง การใช้ด้วยตนเอง (การคัดลอก) จะทำให้คุณไม่ต้องเปลี่ยนการตั้งค่าส่วนกลาง
ขั้นตอนมีดังนี้ เราสร้าง
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:
- «
การถ่ายโอนทรัพยากรที่ทำงานในคลัสเตอร์ไปยังการจัดการ Helm 2 "; - «
เกี่ยวกับการจัดสรรโหนดและโหลดบนเว็บแอปพลิเคชัน "; - «
เข้าถึงไซต์ dev "; - «
การเร่งความเร็วบูตสแตรปสำหรับฐานข้อมูลขนาดใหญ่ '
อ่านเพิ่มเติมในบล็อกของเรา:
- «
กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 1 "; - «
[ภาพประกอบ] คำแนะนำเกี่ยวกับระบบเครือข่ายใน Kubernetes ส่วนที่ 3 '
ที่มา: will.com