บันทึก. แปล: บทความนี้เป็นส่วนหนึ่งของเอกสารโครงการที่เผยแพร่ในสาธารณสมบัติ
TL; DR: นี่คือไดอะแกรมที่จะช่วยคุณแก้ไขข้อบกพร่องในการปรับใช้ใน Kubernetes:
ผังงานสำหรับการค้นหาและแก้ไขข้อผิดพลาดในคลัสเตอร์ ต้นฉบับ (เป็นภาษาอังกฤษ) มีอยู่ที่
เมื่อปรับใช้แอปพลิเคชันกับ Kubernetes โดยทั่วไปมีองค์ประกอบสามประการที่คุณต้องกำหนด:
- การใช้งาน - นี่เป็นสูตรสำหรับสร้างสำเนาของแอปพลิเคชันที่เรียกว่าพ็อด
- Service — ตัวโหลดบาลานเซอร์ภายในที่กระจายการรับส่งข้อมูลระหว่างพ็อด
- สิทธิในการเข้า — คำอธิบายว่าการรับส่งข้อมูลจะได้รับจากโลกภายนอกสู่บริการอย่างไร
นี่เป็นบทสรุปแบบกราฟิกโดยย่อ:
1) ใน Kubernetes แอปพลิเคชันรับการรับส่งข้อมูลจากโลกภายนอกผ่านโหลดบาลานเซอร์สองชั้น: ภายในและภายนอก
2) บาลานเซอร์ภายในเรียกว่าบริการ ส่วนบาลานเซอร์ภายนอกเรียกว่า Ingress
3) การปรับใช้จะสร้างพ็อดและเฝ้าติดตาม (ไม่ได้สร้างขึ้นด้วยตนเอง)
สมมติว่าคุณต้องการปรับใช้แอปพลิเคชันง่ายๆ a la สวัสดีชาวโลก. การกำหนดค่า YAML จะมีลักษณะดังนี้:
apiVersion: apps/v1
kind: Deployment # <<<
metadata:
name: my-deployment
labels:
track: canary
spec:
selector:
matchLabels:
any-name: my-app
template:
metadata:
labels:
any-name: my-app
spec:
containers:
- name: cont1
image: learnk8s/app:1.0.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service # <<<
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 8080
selector:
name: app
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress # <<<
metadata:
name: my-ingress
spec:
rules:
- http:
paths:
- backend:
serviceName: app
servicePort: 80
path: /
คำจำกัดความค่อนข้างยาวและง่ายต่อการสับสนว่าส่วนประกอบต่างๆ เกี่ยวข้องกันอย่างไร
ตัวอย่างเช่น:
- เมื่อใดที่คุณควรใช้พอร์ต 80 และเมื่อใดที่คุณควรใช้ 8080
- ฉันควรสร้างพอร์ตใหม่สำหรับแต่ละบริการเพื่อไม่ให้ขัดแย้งกันหรือไม่
- ชื่อป้ายกำกับมีความสำคัญหรือไม่? พวกเขาควรจะเหมือนกันทุกที่หรือไม่?
ก่อนที่จะมุ่งเน้นไปที่การแก้ไขจุดบกพร่อง เรามาจำไว้ว่าองค์ประกอบทั้งสามเกี่ยวข้องกันอย่างไร เริ่มต้นด้วยการปรับใช้และบริการ
ความสัมพันธ์ระหว่างการปรับใช้และการบริการ
คุณจะต้องประหลาดใจ แต่การปรับใช้และการบริการไม่เกี่ยวข้องกันแต่อย่างใด บริการจะชี้ไปที่พ็อดโดยตรงแทน โดยข้ามการปรับใช้
ดังนั้นเราจึงสนใจว่าพ็อดและบริการมีความสัมพันธ์กันอย่างไร สามสิ่งที่ควรจำ:
- ตัวเลือก (
selector
) สำหรับบริการจะต้องตรงกับป้ายกำกับ Pod อย่างน้อย XNUMX รายการ -
targetPort
ต้องตรงกันcontainerPort
ภาชนะภายในพ็อด -
port
การบริการจะเป็นอะไรก็ได้ บริการที่แตกต่างกันสามารถใช้พอร์ตเดียวกันได้เนื่องจากมีที่อยู่ IP ที่แตกต่างกัน
แผนภาพต่อไปนี้แสดงถึงสิ่งที่กล่าวมาทั้งหมดในรูปแบบกราฟิก:
1) ลองนึกภาพว่าบริการกำหนดเส้นทางการรับส่งข้อมูลไปยังพ็อดที่แน่นอน:
2) เมื่อสร้างพ็อดคุณต้องระบุ containerPort
สำหรับแต่ละคอนเทนเนอร์ในพ็อด:
3) เมื่อสร้างบริการคุณต้องระบุ port
и targetPort
. แต่อันไหนใช้เชื่อมต่อกับคอนเทนเนอร์ล่ะ?
4) ผ่านทาง targetPort
. มันต้องตรงกัน containerPort
.
5) สมมติว่าพอร์ต 3000 เปิดอยู่ในคอนเทนเนอร์ แล้วค่า targetPort
ควรจะเหมือนกัน
ในไฟล์ YAML ป้ายกำกับและ ports
/ targetPort
ต้องตรงกัน:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
labels:
track: canary
spec:
selector:
matchLabels:
any-name: my-app
template:
metadata:
labels: # <<<
any-name: my-app # <<<
spec:
containers:
- name: cont1
image: learnk8s/app:1.0.0
ports:
- containerPort: 8080 # <<<
---
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 8080 # <<<
selector: # <<<
any-name: my-app # <<<
แล้วฉลากล่ะ track: canary
ที่ด้านบนของส่วนการปรับใช้? มันควรจะเข้ากันไหม?
ป้ายกำกับนี้เป็นแบบเฉพาะการทำให้ใช้งานได้ และไม่ได้ใช้โดยบริการเพื่อกำหนดเส้นทางการรับส่งข้อมูล กล่าวอีกนัยหนึ่ง สามารถลบออกหรือกำหนดค่าอื่นได้
สิ่งที่เกี่ยวกับตัวเลือก matchLabels
?
โดยจะต้องตรงกับป้ายกำกับของพ็อดเสมอเนื่องจาก Deployment ใช้เพื่อติดตามพ็อด
สมมติว่าคุณทำการแก้ไขที่ถูกต้อง จะตรวจสอบได้อย่างไร?
คุณสามารถตรวจสอบฉลากพ็อดได้ด้วยคำสั่งต่อไปนี้:
kubectl get pods --show-labels
หรือหากพ็อดอยู่ในหลายแอปพลิเคชัน:
kubectl get pods --selector any-name=my-app --show-labels
ที่ไหน any-name=my-app
เป็นป้ายกำกับ any-name: my-app
.
มีปัญหาเหลืออยู่บ้างไหม?
คุณสามารถเชื่อมต่อกับพ็อดได้! ในการทำเช่นนี้คุณต้องใช้คำสั่ง port-forward
ในคิวเบคเทิล ช่วยให้คุณสามารถเชื่อมต่อกับบริการและตรวจสอบการเชื่อมต่อได้
kubectl port-forward service/<service name> 3000:80
ที่นี่:
-
service/<service name>
— ชื่อบริการ; ในกรณีของเรามันคือmy-service
; - 3000 คือพอร์ตที่ต้องเปิดบนคอมพิวเตอร์
- 80 - พอร์ตที่ระบุในฟิลด์
port
บริการ.
หากสร้างการเชื่อมต่อแล้ว แสดงว่าการตั้งค่าถูกต้อง
หากการเชื่อมต่อล้มเหลว มีปัญหากับป้ายกำกับหรือพอร์ตไม่ตรงกัน
ความสัมพันธ์ระหว่างการบริการและทางเข้า
ขั้นตอนต่อไปในการให้การเข้าถึงแอปพลิเคชันเกี่ยวข้องกับการตั้งค่า Ingress Ingress จำเป็นต้องรู้วิธีค้นหาบริการ จากนั้นจึงค้นหาพ็อดและกำหนดเส้นทางการรับส่งข้อมูลไปยังบริการเหล่านั้น Ingress ค้นหาบริการที่ต้องการตามชื่อและเปิดพอร์ต
ในคำอธิบายของ Ingress และ Service สองพารามิเตอร์จะต้องตรงกัน:
-
servicePort
ใน Ingress จะต้องตรงกับพารามิเตอร์port
อยู่ในการให้บริการ; -
serviceName
ใน Ingress จะต้องตรงกับสนามname
อยู่ในการให้บริการ.
แผนภาพต่อไปนี้สรุปการเชื่อมต่อพอร์ต:
1) ดังที่คุณทราบแล้วว่า Service รับฟังบางอย่าง port
:
2) Ingress มีพารามิเตอร์ที่เรียกว่า servicePort
:
3) พารามิเตอร์นี้ (servicePort
) จะต้องตรงกันเสมอ port
ในคำจำกัดความของบริการ:
4) หากมีการระบุพอร์ต 80 ในบริการก็จำเป็น servicePort
ก็เท่ากับ 80 เช่นกัน:
ในทางปฏิบัติ คุณต้องใส่ใจกับบรรทัดต่อไปนี้:
apiVersion: v1
kind: Service
metadata:
name: my-service # <<<
spec:
ports:
- port: 80 # <<<
targetPort: 8080
selector:
any-name: my-app
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- http:
paths:
- backend:
serviceName: my-service # <<<
servicePort: 80 # <<<
path: /
จะตรวจสอบได้อย่างไรว่า Ingress กำลังทำงานอยู่?
คุณสามารถใช้วิธีการกับ kubectl port-forward
แต่แทนที่จะใช้บริการ คุณต้องเชื่อมต่อกับตัวควบคุม Ingress
ก่อนอื่นคุณต้องค้นหาชื่อของพ็อดด้วยตัวควบคุม Ingress:
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS
kube-system coredns-5644d7b6d9-jn7cq 1/1 Running
kube-system etcd-minikube 1/1 Running
kube-system kube-apiserver-minikube 1/1 Running
kube-system kube-controller-manager-minikube 1/1 Running
kube-system kube-proxy-zvf2h 1/1 Running
kube-system kube-scheduler-minikube 1/1 Running
kube-system nginx-ingress-controller-6fc5bcc 1/1 Running
ค้นหาพ็อด Ingress (อาจอยู่ในเนมสเปซอื่น) และรันคำสั่ง describe
เพื่อค้นหาหมายเลขพอร์ต:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep Ports
Ports: 80/TCP, 443/TCP, 18080/TCP
สุดท้าย เชื่อมต่อกับพ็อด:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-system
ตอนนี้ทุกครั้งที่คุณส่งคำขอไปยังพอร์ต 3000 บนคอมพิวเตอร์ของคุณ มันจะถูกส่งต่อไปยังพอร์ต 80 ของพ็อดด้วยตัวควบคุม Ingress โดยจะไป
สรุปพอร์ต.
จำอีกครั้งว่าพอร์ตและเลเบลใดต้องตรงกัน:
- ตัวเลือกในคำจำกัดความของบริการจะต้องตรงกับป้ายกำกับของพ็อด
-
targetPort
ในคำจำกัดความ บริการจะต้องตรงกันcontainerPort
ภาชนะภายในฝัก -
port
ในคำจำกัดความของบริการสามารถเป็นอะไรก็ได้ บริการที่แตกต่างกันสามารถใช้พอร์ตเดียวกันได้เนื่องจากมีที่อยู่ IP ที่แตกต่างกัน -
servicePort
ทางเข้าจะต้องตรงกันport
ในคำจำกัดความของการบริการ - ชื่อบริการจะต้องตรงกับฟิลด์
serviceName
ในทางเข้า
น่าเสียดายที่การทราบวิธีจัดโครงสร้างการกำหนดค่า YAML อย่างเหมาะสมนั้นไม่เพียงพอ
จะเกิดอะไรขึ้นเมื่อมีสิ่งที่ผิดพลาด?
พ็อดอาจไม่สตาร์ทหรืออาจพัง
3 ขั้นตอนในการวินิจฉัยปัญหาแอปพลิเคชันใน Kubernetes
ก่อนที่คุณจะเริ่มแก้ไขข้อบกพร่องในการปรับใช้ คุณต้องมีความเข้าใจที่ดีเกี่ยวกับวิธีการทำงานของ Kubernetes
เนื่องจากแต่ละแอปพลิเคชันที่ดาวน์โหลดใน K8 มีองค์ประกอบสามส่วน จึงควรแก้ไขจุดบกพร่องตามลำดับที่แน่นอน โดยเริ่มจากด้านล่างสุด
- ก่อนอื่นคุณต้องแน่ใจว่าพ็อดใช้งานได้ จากนั้น...
- ตรวจสอบว่าบริการให้การรับส่งข้อมูลไปยังพ็อดหรือไม่ จากนั้น...
- ตรวจสอบว่า Ingress ได้รับการกำหนดค่าอย่างถูกต้องหรือไม่
การแสดงภาพ:
1) คุณควรเริ่มมองหาปัญหาจากด้านล่างสุด ตรวจสอบก่อนว่าพ็อดมีสถานะ Ready
и Running
:
2) หากฝักพร้อม (Ready
) คุณควรตรวจสอบว่าบริการกระจายการรับส่งข้อมูลระหว่างพ็อดหรือไม่:
3) สุดท้ายนี้ คุณต้องวิเคราะห์การเชื่อมต่อระหว่างบริการและ Ingress:
1. การวินิจฉัยฝัก
ในกรณีส่วนใหญ่ปัญหาจะเกี่ยวข้องกับพ็อด ตรวจสอบให้แน่ใจว่าพ็อดอยู่ในรายการเป็น Ready
и Running
. คุณสามารถตรวจสอบสิ่งนี้ได้โดยใช้คำสั่ง:
kubectl get pods
NAME READY STATUS RESTARTS AGE
app1 0/1 ImagePullBackOff 0 47h
app2 0/1 Error 0 47h
app3-76f9fcd46b-xbv4k 1/1 Running 1 47h
ในเอาต์พุตคำสั่งด้านบน พ็อดสุดท้ายจะแสดงเป็น Running
и Ready
อย่างไรก็ตาม นี่ไม่ใช่กรณีของอีกสองคน
จะเข้าใจได้อย่างไรว่าเกิดอะไรขึ้น?
มีคำสั่งที่เป็นประโยชน์สี่คำสั่งสำหรับการวินิจฉัยพ็อด:
-
kubectl logs <имя pod'а>
ช่วยให้คุณแยกบันทึกจากคอนเทนเนอร์ในพ็อด -
kubectl describe pod <имя pod'а>
ช่วยให้คุณดูรายการเหตุการณ์ที่เกี่ยวข้องกับพ็อด -
kubectl get pod <имя pod'а>
ช่วยให้คุณรับการกำหนดค่า YAML ของพ็อดที่จัดเก็บไว้ใน Kubernetes -
kubectl exec -ti <имя pod'а> bash
อนุญาตให้คุณเปิดเชลล์คำสั่งแบบโต้ตอบในคอนเทนเนอร์พ็อดตัวใดตัวหนึ่ง
คุณควรเลือกอันไหน?
ความจริงก็คือไม่มีคำสั่งสากล ควรใช้สิ่งเหล่านี้ร่วมกัน
ปัญหาพ็อดทั่วไป
ข้อผิดพลาดของพ็อดมีสองประเภทหลักๆ ได้แก่ ข้อผิดพลาดในการเริ่มต้นและข้อผิดพลาดรันไทม์
ข้อผิดพลาดในการเริ่มต้น:
-
ImagePullBackoff
-
ImageInspectError
-
ErrImagePull
-
ErrImageNeverPull
-
RegistryUnavailable
-
InvalidImageName
ข้อผิดพลาดรันไทม์:
-
CrashLoopBackOff
-
RunContainerError
-
KillContainerError
-
VerifyNonRootError
-
RunInitContainerError
-
CreatePodSandboxError
-
ConfigPodSandboxError
-
KillPodSandboxError
-
SetupNetworkError
-
TeardownNetworkError
ข้อผิดพลาดบางอย่างเกิดขึ้นบ่อยกว่าข้อผิดพลาดอื่นๆ ต่อไปนี้เป็นข้อผิดพลาดที่พบบ่อยที่สุดบางส่วนและวิธีแก้ไข
รูปภาพ PullBackOff
ข้อผิดพลาดนี้เกิดขึ้นเมื่อ Kubernetes ไม่สามารถรับรูปภาพสำหรับคอนเทนเนอร์พ็อดรายการใดรายการหนึ่งได้ ต่อไปนี้คือสาเหตุที่พบบ่อยที่สุดสามประการสำหรับสิ่งนี้:
- ชื่อของรูปภาพไม่ถูกต้อง - ตัวอย่างเช่น คุณทำผิดพลาดหรือไม่มีรูปภาพนั้น
- มีการระบุแท็กที่ไม่มีอยู่จริงสำหรับรูปภาพ
- รูปภาพถูกจัดเก็บไว้ในรีจิสทรีส่วนตัวและ Kubernetes ไม่มีสิทธิ์ในการเข้าถึง
เหตุผลสองประการแรกนั้นง่ายต่อการกำจัด - เพียงแก้ไขชื่อรูปภาพและแท็ก ในกรณีหลัง คุณจะต้องป้อนข้อมูลประจำตัวสำหรับรีจิสทรีที่ปิดใน Secret และเพิ่มลิงก์ไปยังพ็อด ในเอกสาร Kubernetes
Crash Loop กลับปิด
Kubenetes เกิดข้อผิดพลาด CrashLoopBackOff
หากคอนเทนเนอร์ไม่สามารถสตาร์ทได้ ซึ่งมักเกิดขึ้นเมื่อ:
- มีข้อบกพร่องในแอปพลิเคชันที่ทำให้ไม่สามารถเปิดใช้งานได้
- ภาชนะ
กำหนดค่าไม่ถูกต้อง ; - การทดสอบ Liveness ล้มเหลวหลายครั้งเกินไป
คุณต้องพยายามเข้าถึงบันทึกจากคอนเทนเนอร์เพื่อค้นหาสาเหตุของความล้มเหลว หากเข้าถึงบันทึกได้ยากเนื่องจากคอนเทนเนอร์รีสตาร์ทเร็วเกินไป คุณสามารถใช้คำสั่งต่อไปนี้:
kubectl logs <pod-name> --previous
โดยจะแสดงข้อความแสดงข้อผิดพลาดจากการจุติของคอนเทนเนอร์ครั้งก่อน
เรียกใช้คอนเทนเนอร์ข้อผิดพลาด
ข้อผิดพลาดนี้เกิดขึ้นเมื่อคอนเทนเนอร์ไม่สามารถเริ่มทำงานได้ สอดคล้องกับช่วงเวลาก่อนที่จะเปิดตัวแอปพลิเคชัน มักเกิดจากการตั้งค่าที่ไม่ถูกต้อง เช่น:
- พยายามเมานต์โวลุ่มที่ไม่มีอยู่จริง เช่น ConfigMap หรือ Secrets
- ความพยายามที่จะเมานต์โวลุ่มแบบอ่านอย่างเดียวเป็นแบบอ่าน-เขียน
ทีมงานมีความเหมาะสมอย่างยิ่งในการวิเคราะห์ข้อผิดพลาดดังกล่าว kubectl describe pod <pod-name>
.
พ็อดอยู่ในสถานะรอดำเนินการ
เมื่อสร้างแล้ว พ็อดจะยังคงอยู่ในสถานะ Pending
.
ทำไมสิ่งนี้จึงเกิดขึ้น
นี่คือสาเหตุที่เป็นไปได้ (ฉันถือว่าตัวกำหนดเวลาทำงานได้ดี):
- คลัสเตอร์มีทรัพยากรไม่เพียงพอที่จะเรียกใช้พ็อด เช่น พลังการประมวลผลและหน่วยความจำ
- มีการติดตั้งวัตถุในเนมสเปซที่เหมาะสม
ResourceQuota
และการสร้างพ็อดจะทำให้เนมสเปซเกินโควต้า - พ็อดถูกผูกไว้กับรอดำเนินการ
PersistentVolumeClaim
.
ในกรณีนี้แนะนำให้ใช้คำสั่ง kubectl describe
และตรวจสอบส่วน Events
:
kubectl describe pod <pod name>
ในกรณีที่มีข้อผิดพลาดที่เกี่ยวข้องกับ ResourceQuotas
ขอแนะนำให้ดูบันทึกคลัสเตอร์โดยใช้คำสั่ง
kubectl get events --sort-by=.metadata.creationTimestamp
พ็อดไม่พร้อม
หากพ็อดอยู่ในรายการเป็น Running
แต่ไม่ได้อยู่ในสถานะ Ready
หมายถึงการตรวจสอบความพร้อม (การสอบสวนความพร้อม) ล้มเหลว
เมื่อสิ่งนี้เกิดขึ้น พ็อดจะไม่เชื่อมต่อกับบริการและไม่มีการรับส่งข้อมูลเข้ามา ความล้มเหลวในการทดสอบความพร้อมเกิดจากปัญหาในแอปพลิเคชัน ในกรณีนี้ หากต้องการค้นหาข้อผิดพลาด คุณต้องวิเคราะห์ส่วนนั้น Events
ในเอาต์พุตคำสั่ง kubectl describe
.
2. การวินิจฉัยบริการ
หากพ็อดอยู่ในรายการเป็น Running
и Ready
แต่ยังไม่มีการตอบสนองจากแอปพลิเคชัน คุณควรตรวจสอบการตั้งค่าบริการ
บริการมีหน้าที่กำหนดเส้นทางการรับส่งข้อมูลไปยังพ็อดโดยขึ้นอยู่กับป้ายกำกับ ดังนั้นสิ่งแรกที่คุณต้องทำคือตรวจสอบจำนวนพ็อดที่ใช้ได้กับบริการนี้ เมื่อต้องการทำเช่นนี้ คุณสามารถตรวจสอบปลายทางในบริการได้:
kubectl describe service <service-name> | grep Endpoints
Endpoint คือคู่ของค่าของแบบฟอร์ม <IP-адрес:порт>
และต้องมีคู่ดังกล่าวอย่างน้อยหนึ่งคู่ในเอาต์พุต (นั่นคือ อย่างน้อยหนึ่งพ็อดที่ทำงานกับบริการ)
ถ้ามาตรา Endpoins
ว่างเปล่า เป็นไปได้สองตัวเลือก:
- ไม่มีพ็อดที่มีป้ายกำกับที่ถูกต้อง (คำแนะนำ: ตรวจสอบว่าเลือกเนมสเปซถูกต้องหรือไม่)
- มีข้อผิดพลาดในป้ายกำกับบริการในตัวเลือก
หากคุณเห็นรายการตำแหน่งข้อมูลแต่ยังคงไม่สามารถเข้าถึงแอปพลิเคชันได้ แสดงว่าผู้กระทำผิดน่าจะเป็นข้อบกพร่อง targetPort
ในคำอธิบายบริการ
จะตรวจสอบการทำงานของบริการได้อย่างไร?
ไม่ว่าบริการจะเป็นประเภทใดก็ตามคุณสามารถใช้คำสั่งได้ kubectl port-forward
เพื่อเชื่อมต่อกับมัน:
kubectl port-forward service/<service-name> 3000:80
ที่นี่:
-
<service-name>
— ชื่อบริการ; - 3000 คือพอร์ตที่คุณเปิดบนคอมพิวเตอร์
- 80 - พอร์ตด้านบริการ
3. การวินิจฉัยทางเข้า
หากคุณได้อ่านมาไกลขนาดนี้แล้ว:
- พ็อดแสดงเป็น
Running
иReady
; - บริการกระจายการรับส่งข้อมูลระหว่างพ็อดได้สำเร็จ
อย่างไรก็ตาม คุณยังคงไม่สามารถเข้าถึงแอปได้
ซึ่งหมายความว่าตัวควบคุม Ingress มักไม่ได้รับการกำหนดค่าอย่างถูกต้อง เนื่องจากตัวควบคุม Ingress เป็นส่วนประกอบของบริษัทอื่นในคลัสเตอร์ จึงมีวิธีการดีบักที่แตกต่างกันขึ้นอยู่กับประเภทของมัน
แต่ก่อนที่คุณจะหันไปใช้เครื่องมือพิเศษเพื่อกำหนดค่า Ingress คุณสามารถทำสิ่งที่ง่ายมากได้ ทางเข้าใช้ serviceName
и servicePort
เพื่อเชื่อมต่อกับบริการ คุณต้องตรวจสอบว่ามีการกำหนดค่าอย่างถูกต้องหรือไม่ คุณสามารถทำได้โดยใช้คำสั่ง:
kubectl describe ingress <ingress-name>
ถ้าคอลัมน์ Backend
ว่างเปล่า มีความเป็นไปได้สูงที่จะเกิดข้อผิดพลาดในการกำหนดค่า หากมีแบ็กเอนด์อยู่ แต่แอปพลิเคชันยังคงไม่สามารถเข้าถึงได้ ปัญหาอาจเกี่ยวข้องกับ:
- การตั้งค่าการเข้าถึงทางเข้าจากอินเทอร์เน็ตสาธารณะ
- การตั้งค่าการเข้าถึงคลัสเตอร์จากอินเทอร์เน็ตสาธารณะ
คุณสามารถระบุปัญหาเกี่ยวกับโครงสร้างพื้นฐานได้โดยการเชื่อมต่อโดยตรงกับ Ingress pod หากต้องการทำสิ่งนี้ ก่อนอื่นให้ค้นหาพ็อด Ingress Controller (อาจอยู่ในเนมสเปซอื่น):
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS
kube-system coredns-5644d7b6d9-jn7cq 1/1 Running
kube-system etcd-minikube 1/1 Running
kube-system kube-apiserver-minikube 1/1 Running
kube-system kube-controller-manager-minikube 1/1 Running
kube-system kube-proxy-zvf2h 1/1 Running
kube-system kube-scheduler-minikube 1/1 Running
kube-system nginx-ingress-controller-6fc5bcc 1/1 Running
ใช้คำสั่ง describe
เพื่อตั้งค่าพอร์ต:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep Ports
สุดท้าย เชื่อมต่อกับพ็อด:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-system
ตอนนี้คำขอทั้งหมดไปยังพอร์ต 3000 บนคอมพิวเตอร์จะถูกเปลี่ยนเส้นทางไปยังพอร์ต 80 ของพ็อด
มันใช้งานได้ตอนนี้หรือไม่?
- ถ้าใช่ แสดงว่าปัญหาอยู่ที่โครงสร้างพื้นฐาน จำเป็นต้องค้นหาให้แน่ชัดว่าการรับส่งข้อมูลถูกส่งไปยังคลัสเตอร์อย่างไร
- ถ้าไม่เช่นนั้น ปัญหาอยู่ที่ตัวควบคุม Ingress
หากคุณไม่สามารถใช้งาน Ingress controller ได้ คุณจะต้องทำการดีบั๊กมัน
มีตัวควบคุม Ingress หลายประเภท ที่ได้รับความนิยมมากที่สุด ได้แก่ Nginx, HAProxy, Traefik เป็นต้น (สำหรับข้อมูลเพิ่มเติมเกี่ยวกับโซลูชันที่มีอยู่ โปรดดู
การดีบักคอนโทรลเลอร์ Ingress Nginx
โครงการ Ingress-nginx มีอย่างเป็นทางการ kubectl ingress-nginx
สามารถใช้สำหรับ:
- การวิเคราะห์บันทึก แบ็กเอนด์ ใบรับรอง ฯลฯ
- การเชื่อมต่อกับ Ingress;
- ศึกษาการกำหนดค่าปัจจุบัน
คำสั่งสามคำสั่งต่อไปนี้จะช่วยคุณในเรื่องนี้:
-
kubectl ingress-nginx lint
— เช็คnginx.conf
; -
kubectl ingress-nginx backend
— สำรวจแบ็กเอนด์ (คล้ายกับkubectl describe ingress <ingress-name>
); -
kubectl ingress-nginx logs
- ตรวจสอบบันทึก
โปรดทราบว่าในบางกรณีคุณอาจต้องระบุเนมสเปซที่ถูกต้องสำหรับตัวควบคุม Ingress โดยใช้แฟล็ก --namespace <name>
.
สรุป
การแก้ไขปัญหา Kubernetes อาจเป็นเรื่องที่ท้าทายหากคุณไม่รู้ว่าจะเริ่มต้นจากตรงไหน คุณควรแก้ไขปัญหาจากล่างขึ้นบนเสมอ: เริ่มต้นด้วยพ็อด จากนั้นไปที่บริการและ Ingress เทคนิคการดีบักที่อธิบายไว้ในบทความนี้สามารถนำไปใช้กับออบเจ็กต์อื่น เช่น:
- งานที่ไม่ได้ใช้งานและ CronJobs;
- StatefulSets และ DaemonSets
ฉันแสดงความขอบคุณ
ปล.จากผู้แปล
อ่านเพิ่มเติมในบล็อกของเรา:
- «
ปลั๊กอิน kubectl-debug สำหรับการดีบักในพ็อด Kubernetes "; - «
6 ข้อบกพร่องของระบบความบันเทิงในการทำงานของ Kubernetes [และวิธีแก้ปัญหา] "; - «
เครื่องมือสำหรับนักพัฒนาแอปพลิเคชันที่ทำงานบน Kubernetes "; - «
6 เรื่องราวเชิงปฏิบัติจากชีวิตประจำวัน SRE ของเรา '
ที่มา: will.com