เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อ

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อ

สวัสดีทุกคน! ฉันชื่อ Oleg Sidorenkov ฉันทำงานที่ DomClick เป็นหัวหน้าทีมโครงสร้างพื้นฐาน เราใช้ Cube เพื่อจำหน่ายมากว่าสามปี และในช่วงเวลานี้ เราได้สัมผัสกับช่วงเวลาที่น่าสนใจต่างๆ มากมายกับมัน วันนี้ผมจะบอกคุณว่า ด้วยแนวทางที่ถูกต้อง คุณจะบีบ vanilla Kubernetes ให้มีประสิทธิภาพมากยิ่งขึ้นสำหรับคลัสเตอร์ของคุณได้อย่างไร พร้อมลุย!

พวกคุณทุกคนรู้ดีว่า Kubernetes เป็นระบบโอเพ่นซอร์สที่ปรับขนาดได้สำหรับการจัดการคอนเทนเนอร์ หรือ 5 ไบนารีที่ร่ายมนตร์ด้วยการจัดการวงจรชีวิตของไมโครเซอร์วิสของคุณในสภาพแวดล้อมเซิร์ฟเวอร์ นอกจากนี้ ยังเป็นเครื่องมือที่ค่อนข้างยืดหยุ่นซึ่งสามารถประกอบได้เหมือนตัวสร้างเลโก้เพื่อการปรับแต่งสูงสุดสำหรับงานต่างๆ

และทุกอย่างดูเหมือนจะดี: โยนเซิร์ฟเวอร์เข้าไปในคลัสเตอร์ เหมือนฟืนในเตาไฟ และไม่รู้ความเศร้าโศก แต่ถ้าคุณทำเพื่อสิ่งแวดล้อม คุณจะคิดว่า: "ฉันจะเก็บไฟไว้ในเตาและเสียดายป่าได้อย่างไร" กล่าวอีกนัยหนึ่งคือการหาวิธีปรับปรุงโครงสร้างพื้นฐานและลดต้นทุน

1. ติดตามทรัพยากรของทีมและแอปพลิเคชัน

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อ

หนึ่งในวิธีที่ซ้ำซากจำเจแต่ได้ผลที่สุดคือการแนะนำคำขอ/ขีดจำกัด แยกแอปพลิเคชันตามเนมสเปซ และเนมสเปซตามทีมพัฒนา ตั้งค่าแอปพลิเคชันก่อนปรับใช้ค่าสำหรับการใช้เวลาของตัวประมวลผล หน่วยความจำ พื้นที่เก็บข้อมูลชั่วคราว

resources:
   requests:
     memory: 2Gi
     cpu: 250m
   limits:
     memory: 4Gi
     cpu: 500m

จากประสบการณ์ เราได้ข้อสรุป: มันไม่คุ้มที่จะขยายคำขอจากขีดจำกัดมากกว่าสองครั้ง ขนาดคลัสเตอร์คำนวณตามคำขอ และหากคุณตั้งค่าแอปพลิเคชันให้มีความแตกต่างในทรัพยากร เช่น 5-10 เท่า ลองจินตนาการว่าจะเกิดอะไรขึ้นกับโหนดของคุณเมื่อเต็มไปด้วยพ็อดและได้รับโหลดอย่างกะทันหัน ไม่มีอะไรดี อย่างน้อยที่สุด การควบคุมปริมาณ และสูงสุด บอกลาผู้ปฏิบัติงานและรับภาระตามรอบในโหนดที่เหลือหลังจากที่พ็อดเริ่มเคลื่อนที่

นอกจากนี้ด้วยความช่วยเหลือ limitranges คุณสามารถตั้งค่าทรัพยากรสำหรับคอนเทนเนอร์เมื่อเริ่มต้น - ต่ำสุด สูงสุด และเริ่มต้น:

➜  ~ kubectl describe limitranges --namespace ops
Name:       limit-range
Namespace:  ops
Type        Resource           Min   Max   Default Request  Default Limit  Max Limit/Request Ratio
----        --------           ---   ---   ---------------  -------------  -----------------------
Container   cpu                50m   10    100m             100m           2
Container   ephemeral-storage  12Mi  8Gi   128Mi            4Gi            -
Container   memory             64Mi  40Gi  128Mi            128Mi          2

อย่าลืมจำกัดทรัพยากรเนมสเปซเพื่อให้คำสั่งเดียวไม่สามารถใช้ทรัพยากรทั้งหมดของคลัสเตอร์ได้:

➜  ~ kubectl describe resourcequotas --namespace ops
Name:                   resource-quota
Namespace:              ops
Resource                Used          Hard
--------                ----          ----
limits.cpu              77250m        80
limits.memory           124814367488  150Gi
pods                    31            45
requests.cpu            53850m        80
requests.memory         75613234944   150Gi
services                26            50
services.loadbalancers  0             0
services.nodeports      0             0

ดังที่คุณเห็นจากคำอธิบาย resourcequotasหากคำสั่ง ops ต้องการปรับใช้พ็อดที่จะใช้อีก 10 cpu ตัวกำหนดตารางเวลาจะไม่อนุญาตให้ดำเนินการและจะแสดงข้อผิดพลาด:

Error creating: pods "nginx-proxy-9967d8d78-nh4fs" is forbidden: exceeded quota: resource-quota, requested: limits.cpu=5,requests.cpu=5, used: limits.cpu=77250m,requests.cpu=53850m, limited: limits.cpu=10,requests.cpu=10

ในการแก้ปัญหาที่คล้ายกัน คุณสามารถเขียนเครื่องมือได้ เช่น นี้ซึ่งสามารถจัดเก็บและคอมมิตสถานะของรีซอร์สคำสั่ง

2. เลือกที่เก็บไฟล์ที่ดีที่สุด

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อ

ที่นี่ฉันต้องการจะกล่าวถึงหัวข้อของไดรฟ์ข้อมูลถาวรและระบบย่อยของดิสก์ของโหนดผู้ปฏิบัติงาน Kubernetes ฉันหวังว่าจะไม่มีใครใช้ "Cube" บน HDD ในการผลิต แต่บางครั้งแม้แต่ SSD ธรรมดาก็ไม่เพียงพอ เราประสบปัญหาดังกล่าวที่บันทึกกำลังทำลายดิสก์โดยการดำเนินการ I / O และไม่มีวิธีแก้ปัญหามากมายที่นี่:

  • ใช้ SSD ประสิทธิภาพสูงหรือเปลี่ยนไปใช้ NVMe (หากคุณจัดการฮาร์ดแวร์ของคุณเอง)

  • ลดระดับของการบันทึก

  • ทำสมดุล "อัจฉริยะ" ของพ็อดที่ข่มขืนดิสก์ (podAntiAffinity).

ภาพหน้าจอด้านบนแสดงสิ่งที่เกิดขึ้นภายใต้ nginx-ingress-controller พร้อมดิสก์เมื่อเปิดใช้งาน access_logs (~12k logs/sec) แน่นอนว่าสถานะดังกล่าวสามารถนำไปสู่การลดลงของแอปพลิเคชันทั้งหมดในโหนดนี้

สำหรับ PV อนิจจาฉันไม่ได้ลองทุกอย่าง ชนิดของ ปริมาณถาวร ใช้ตัวเลือกที่ดีที่สุดที่เหมาะกับคุณ ในอดีตเคยเกิดขึ้นในประเทศของเราที่บริการส่วนเล็กๆ ต้องการโวลุ่ม RWX และนานมาแล้วที่พวกเขาเริ่มใช้ที่เก็บข้อมูล NFS สำหรับงานนี้ ราคาถูกและ ... เพียงพอ แน่นอนว่าเรากินข้าวกับเขา - รักษาสุขภาพให้ดี แต่เราเรียนรู้วิธีปรับเขาและหัวของเขาก็ไม่เจ็บอีกต่อไป และถ้าเป็นไปได้ ให้เปลี่ยนไปใช้ที่จัดเก็บอ็อบเจกต์ S3

3. สร้างภาพที่ปรับให้เหมาะสม

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อ

วิธีที่ดีที่สุดคือใช้อิมเมจที่ปรับคอนเทนเนอร์ให้เหมาะสม เพื่อให้ Kubernetes ดึงข้อมูลได้เร็วขึ้นและดำเนินการได้อย่างมีประสิทธิภาพมากขึ้น 

การเพิ่มประสิทธิภาพหมายความว่าภาพ:

  • มีแอปพลิเคชันเดียวหรือทำหน้าที่เดียวเท่านั้น

  • ขนาดเล็กเนื่องจากภาพขนาดใหญ่ส่งผ่านเครือข่ายได้แย่กว่า

  • มีจุดสิ้นสุดความสมบูรณ์และความพร้อมที่ Kubernetes สามารถใช้เพื่อดำเนินการในกรณีที่หยุดทำงาน

  • ใช้ระบบปฏิบัติการที่เป็นมิตรกับคอนเทนเนอร์ (เช่น Alpine หรือ CoreOS) ที่ทนทานต่อข้อผิดพลาดในการกำหนดค่า

  • ใช้บิลด์หลายขั้นตอนเพื่อให้คุณปรับใช้ได้เฉพาะแอปพลิเคชันที่คอมไพล์แล้ว ไม่ใช่ซอร์สที่มาพร้อมกัน

มีเครื่องมือและบริการมากมายที่ให้คุณตรวจสอบและปรับแต่งภาพได้ทันที สิ่งสำคัญคือต้องอัปเดตให้ทันสมัยและปลอดภัยอยู่เสมอ เป็นผลให้คุณได้รับ:

  1. ลดภาระเครือข่ายในคลัสเตอร์ทั้งหมด

  2. เวลาเริ่มต้นคอนเทนเนอร์ลดลง

  3. รีจิสตรี Docker ทั้งหมดของคุณมีขนาดเล็กลง

4. ใช้แคช DNS

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อ

หากเราพูดถึงการโหลดสูง หากไม่มีการปรับระบบ DNS ของคลัสเตอร์ ชีวิตก็ค่อนข้างแย่ กาลครั้งหนึ่ง นักพัฒนา Kubernetes สนับสนุนโซลูชัน kube-dns ของตน มันถูกนำไปใช้ในประเทศของเราด้วย แต่ซอฟต์แวร์นี้ไม่ได้ปรับแต่งเป็นพิเศษและไม่ได้ให้ประสิทธิภาพที่จำเป็นแม้ว่าดูเหมือนว่างานจะง่าย จากนั้น coredns ก็ปรากฏขึ้นซึ่งเราเปลี่ยนไปและไม่รู้จักความเศร้าโศก ต่อมามันกลายเป็นบริการ DNS เริ่มต้นใน K8s เมื่อถึงจุดหนึ่ง เราเพิ่มสูงถึง 40 rps ในระบบ DNS และโซลูชันนี้ยังไม่เพียงพอ แต่โดยบังเอิญ Nodelocaldns ออกมา หรือที่เรียกว่า node local cache หรือที่รู้จักกันว่า NodeLocal DNSCache.

ทำไมเราถึงใช้มัน? มีข้อผิดพลาดในเคอร์เนลของ Linux ที่เมื่อมีการเข้าถึงหลายรายการผ่าน conntrack NAT บน UDP ทำให้เกิดสภาวะการแย่งชิงสำหรับการเขียนไปยังตาราง conntrack และส่วนหนึ่งของการรับส่งข้อมูลผ่าน NAT จะหายไป (การเดินทางผ่านบริการแต่ละครั้งคือ NAT) Nodelocaldns แก้ปัญหานี้โดยการกำจัด NAT และอัปเกรดการเชื่อมต่อ TCP เป็น DNS อัปสตรีม ตลอดจนแคชการสืบค้น DNS อัปสตรีมในเครื่อง (รวมถึงแคชเชิงลบสั้นๆ 5 วินาที)

5. ปรับขนาดพ็อดในแนวนอนและแนวตั้งโดยอัตโนมัติ

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อ

คุณสามารถพูดด้วยความมั่นใจว่าไมโครเซอร์วิสทั้งหมดของคุณพร้อมสำหรับการโหลดที่เพิ่มขึ้นสองถึงสามเท่าหรือไม่ จะจัดสรรทรัพยากรให้กับแอปพลิเคชันของคุณอย่างเหมาะสมได้อย่างไร? การให้พ็อดสองสามพ็อดทำงานเกินปริมาณงานอาจซ้ำซ้อน และทำให้พ็อดเหล่านั้นกลับมามีความเสี่ยงจากการหยุดทำงานจากปริมาณการใช้ข้อมูลที่เพิ่มขึ้นอย่างกะทันหันไปยังบริการ ค่าเฉลี่ยสีทองช่วยให้บรรลุการสะกดของบริการเช่น ตัวปรับขนาดอัตโนมัติแนวนอน и ตัวปรับขนาดอัตโนมัติพ็อดแนวตั้ง.

VPA ช่วยให้คุณเพิ่มคำขอ/ขีดจำกัดของคอนเทนเนอร์ในพ็อดโดยอัตโนมัติตามการใช้งานจริง จะมีประโยชน์ได้อย่างไร? หากคุณมี Pods ที่ไม่สามารถปรับขนาดตามแนวนอนได้ด้วยเหตุผลบางอย่าง (ซึ่งไม่น่าเชื่อถือทั้งหมด) คุณสามารถลองไว้วางใจ VPA เพื่อเปลี่ยนทรัพยากรได้ คุณสมบัติของมันคือระบบคำแนะนำตามข้อมูลในอดีตและปัจจุบันจากเซิร์ฟเวอร์เมตริก ดังนั้นหากคุณไม่ต้องการเปลี่ยนคำขอ/ขีดจำกัดโดยอัตโนมัติ คุณเพียงแค่ตรวจสอบทรัพยากรที่แนะนำสำหรับคอนเทนเนอร์ของคุณและปรับการตั้งค่าให้เหมาะสมเพื่อประหยัด CPU และหน่วยความจำ ในคลัสเตอร์

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อภาพที่ถ่ายจาก https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231

ตัวกำหนดตารางเวลาใน Kubernetes จะขึ้นอยู่กับคำขอเสมอ ไม่ว่าคุณจะใส่ค่าใดก็ตาม ตัวกำหนดตารางเวลาจะมองหาโหนดที่เหมาะสมตามค่านั้น kublet ต้องการค่าขีดจำกัดเพื่อให้รู้ว่าเมื่อใดควรเร่งความเร็วหรือฆ่าพ็อด และเนื่องจากพารามิเตอร์ที่สำคัญเพียงอย่างเดียวคือค่าคำขอ VPA จึงทำงานร่วมกับพารามิเตอร์นี้ได้ เมื่อใดก็ตามที่คุณปรับขนาดแอปพลิเคชันของคุณในแนวตั้ง คุณจะต้องกำหนดว่าคำขอใดควรเป็นอย่างไร แล้วจะเกิดอะไรขึ้นกับลิมิต? พารามิเตอร์นี้จะถูกปรับขนาดตามสัดส่วนด้วย

ตัวอย่างเช่น นี่คือการตั้งค่าพ็อดทั่วไป:

resources:
   requests:
     memory: 250Mi
     cpu: 200m
   limits:
     memory: 500Mi
     cpu: 350m

เครื่องมือแนะนำระบุว่าแอปพลิเคชันของคุณต้องการ CPU 300m และ 500Mi เพื่อให้ทำงานได้อย่างถูกต้อง คุณจะได้รับการตั้งค่าเหล่านี้:

resources:
   requests:
     memory: 500Mi
     cpu: 300m
   limits:
     memory: 1000Mi
     cpu: 525m

ดังที่กล่าวไว้ข้างต้น นี่คือการปรับขนาดตามสัดส่วนตามอัตราส่วนคำขอ/ขีดจำกัดในไฟล์ Manifest:

  • CPU: 200m → 300m: อัตราส่วน 1:1.75;

  • หน่วยความจำ: 250Mi → 500Mi: อัตราส่วน 1:2

เป็นเรื่องที่เกี่ยวกับ HPAจากนั้นกลไกการทำงานจะโปร่งใสมากขึ้น เกณฑ์กำหนดสำหรับเมตริก เช่น โปรเซสเซอร์และหน่วยความจำ และหากค่าเฉลี่ยของแบบจำลองทั้งหมดเกินเกณฑ์ แอปพลิเคชันจะปรับขนาดตามพ็อด +1 จนกว่าค่าจะต่ำกว่าเกณฑ์ หรือจนกว่าจะถึงจำนวนสูงสุดของแบบจำลอง

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อภาพที่ถ่ายจาก https://levelup.gitconnected.com/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231

นอกเหนือจากเมตริกทั่วไป เช่น CPU และหน่วยความจำแล้ว คุณยังสามารถตั้งค่าเกณฑ์สำหรับเมตริก Prometheus ที่กำหนดเองและทำงานร่วมกับพวกเขาได้ หากคุณรู้สึกว่านี่เป็นวิธีที่แม่นยำที่สุดในการพิจารณาว่าเมื่อใดควรปรับขนาดแอปพลิเคชันของคุณ เมื่อแอปพลิเคชันมีความเสถียรต่ำกว่าเกณฑ์เมตริกที่ระบุ HPA จะเริ่มปรับขนาดพ็อดให้เหลือจำนวนแบบจำลองขั้นต่ำหรือจนกว่าโหลดจะตรงตามเกณฑ์ที่ระบุ

6. อย่าลืมเกี่ยวกับ Node Affinity และ Pod Affinity

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อ

ไม่ใช่ทุกโหนดที่ทำงานบนฮาร์ดแวร์เดียวกัน และไม่ใช่ทุกโหนดที่จำเป็นต้องเรียกใช้แอปพลิเคชันที่ใช้การประมวลผลสูง Kubernetes ช่วยให้คุณระบุความเชี่ยวชาญของโหนดและพ็อดได้โดยใช้ ความเกี่ยวข้องของโหนด и ความเกี่ยวข้องของพ็อด.

หากคุณมีโหนดที่เหมาะสำหรับการดำเนินการที่ใช้คอมพิวเตอร์มาก เพื่อประสิทธิภาพสูงสุด จะเป็นการดีกว่าที่จะผูกแอปพลิเคชันเข้ากับโหนดที่เหมาะสม ในการทำเช่นนี้ให้ใช้ nodeSelector พร้อมป้ายโหนด

สมมติว่าคุณมีสองโหนด: โหนดที่มี CPUType=HIGHFREQ และคอร์ที่รวดเร็วจำนวนมากอีกด้วย MemoryType=HIGHMEMORY หน่วยความจำที่มากขึ้นและประสิทธิภาพที่เร็วขึ้น วิธีที่ง่ายที่สุดคือกำหนดการปรับใช้พ็อดให้กับโหนด HIGHFREQโดยเพิ่มในส่วน spec ตัวเลือกเช่นนี้:

…
nodeSelector:
	CPUType: HIGHFREQ

วิธีที่มีราคาแพงและเฉพาะเจาะจงมากขึ้นคือการใช้ nodeAffinity ในสนาม affinity ราซเดลา spec. มีสองตัวเลือก:

  • requiredDuringSchedulingIgnoredDuringExecution: การตั้งค่ายาก (ตัวจัดกำหนดการจะปรับใช้พ็อดบนโหนดที่ระบุเท่านั้น (และไม่มีที่อื่น));

  • preferredDuringSchedulingIgnoredDuringExecution: การตั้งค่าแบบอ่อน (ตัวกำหนดตารางเวลาจะพยายามปรับใช้กับโหนดเฉพาะ และหากล้มเหลว ก็จะพยายามปรับใช้กับโหนดถัดไปที่พร้อมใช้งาน)

คุณสามารถระบุไวยากรณ์เฉพาะสำหรับการจัดการป้ายชื่อโหนด ตัวอย่างเช่น In, NotIn, Exists, DoesNotExist, Gt หรือ Lt. อย่างไรก็ตาม โปรดจำไว้ว่าวิธีการที่ซับซ้อนในรายการฉลากจำนวนมากจะทำให้การตัดสินใจช้าลงในสถานการณ์ที่สำคัญ กล่าวอีกนัยหนึ่งอย่าซับซ้อน

ตามที่กล่าวไว้ข้างต้น Kubernetes อนุญาตให้คุณตั้งค่าการเชื่อมโยงของพ็อดปัจจุบัน นั่นคือ คุณสามารถทำให้บางพ็อดทำงานร่วมกับพ็อดอื่นๆ ในโซนความพร้อมใช้งานเดียวกัน (เกี่ยวข้องกับคลาวด์) หรือโหนดได้

В podAffinity สาขา affinity ราซเดลา spec มีฟิลด์เดียวกันกับในกรณีของ nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution и preferredDuringSchedulingIgnoredDuringExecution. ข้อแตกต่างเพียงอย่างเดียวคือ matchExpressions จะผูกพ็อดกับโหนดที่กำลังเรียกใช้พ็อดด้วยเลเบลนั้น

Kubernetes เพิ่มเติมเสนอฟิลด์ podAntiAffinityซึ่งตรงกันข้าม ไม่ผูกพ็อดกับโหนดที่มีพ็อดเฉพาะ

เกี่ยวกับการแสดงออก nodeAffinity คุณสามารถให้คำแนะนำแบบเดียวกันได้: พยายามรักษากฎให้เรียบง่ายและมีเหตุผล อย่าพยายามยัดเยียดข้อมูลจำเพาะของพ็อดมากเกินไปด้วยชุดกฎที่ซับซ้อน เป็นเรื่องง่ายมากที่จะสร้างกฎที่ไม่ตรงกับเงื่อนไขของคลัสเตอร์ เพิ่มภาระให้กับตัวกำหนดตารางเวลา และทำให้ประสิทธิภาพโดยรวมลดลง

7. มลทินและความอดทน

มีอีกวิธีหนึ่งในการจัดการตัวกำหนดตารางเวลา หากคุณมีคลัสเตอร์ขนาดใหญ่ที่มีโหนดหลายร้อยโหนดและไมโครเซอร์วิสนับพัน การป้องกันไม่ให้พ็อดบางโหนดถูกโฮสต์โดยโหนดบางโหนดนั้นเป็นเรื่องยากมาก

กลไกของมลทิน - กฎห้าม - ช่วยในเรื่องนี้ ตัวอย่างเช่น คุณสามารถป้องกันไม่ให้บางโหนดเรียกใช้พ็อดในบางสถานการณ์ หากต้องการใช้ taint กับโหนดเฉพาะ ให้ใช้ตัวเลือก taint ใน kubectl ระบุคีย์และค่าแล้วทำให้เสียเปรียบ NoSchedule หรือ NoExecute:

$ kubectl taint nodes node10 node-role.kubernetes.io/ingress=true:NoSchedule

นอกจากนี้ยังเป็นที่น่าสังเกตว่ากลไกความมัวหมองสนับสนุนผลกระทบหลักสามประการ: NoSchedule, NoExecute и PreferNoSchedule.

  • NoSchedule หมายความว่าจนกว่าจะมีรายการที่สอดคล้องกันในข้อมูลจำเพาะของพ็อด tolerationsไม่สามารถปรับใช้กับโหนดได้ (ในตัวอย่างนี้ node10).

  • PreferNoSchedule - รุ่นที่เรียบง่าย NoSchedule. ในกรณีนี้ ตัวกำหนดตารางเวลาจะพยายามไม่จัดสรรพ็อดที่ไม่มีรายการที่ตรงกัน tolerations ต่อโหนด แต่นี่ไม่ใช่ขีดจำกัดที่ตายตัว หากไม่มีทรัพยากรในคลัสเตอร์ พ็อดจะเริ่มปรับใช้บนโหนดนี้

  • NoExecute - เอฟเฟกต์นี้ทำให้เกิดการอพยพของพ็อดที่ไม่มีรายการที่ตรงกันในทันที tolerations.

น่าแปลกที่พฤติกรรมนี้สามารถยกเลิกได้โดยใช้กลไกความคลาดเคลื่อน สิ่งนี้สะดวกเมื่อมีโหนด "ต้องห้าม" และคุณต้องวางเฉพาะบริการโครงสร้างพื้นฐานเท่านั้น ทำอย่างไร? อนุญาตเฉพาะฝักที่มีความคลาดเคลื่อนที่เหมาะสม

ข้อมูลจำเพาะของพ็อดจะมีลักษณะดังนี้:

spec:
   tolerations:
     - key: "node-role.kubernetes.io/ingress"
        operator: "Equal"
        value: "true"
        effect: "NoSchedule"

นี่ไม่ได้หมายความว่าในระหว่างการปรับใช้ครั้งถัดไป พ็อดจะชนโหนดนี้พอดี นี่ไม่ใช่กลไกความเกี่ยวข้องของโหนดและ nodeSelector. แต่ด้วยการรวมคุณลักษณะต่างๆ เข้าด้วยกัน คุณจะสามารถตั้งค่าตัวกำหนดตารางเวลาที่ยืดหยุ่นได้อย่างมาก

8. กำหนดลำดับความสำคัญของการปรับใช้พ็อด

เพียงเพราะคุณได้กำหนดค่าการเชื่อมโยงพ็อดกับโหนดไม่ได้หมายความว่าพ็อดทั้งหมดควรได้รับการปฏิบัติด้วยลำดับความสำคัญเดียวกัน ตัวอย่างเช่น คุณอาจต้องการทำให้พ็อดบางเครื่องใช้งานได้ก่อนเครื่องอื่น

Kubernetes นำเสนอวิธีต่างๆ ในการตั้งค่า Pod Priority และ Preemption การตั้งค่าประกอบด้วยหลายส่วน: วัตถุ PriorityClass และคำอธิบายฟิลด์ priorityClassName ในข้อกำหนดของพ็อด พิจารณาตัวอย่าง:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 99999
globalDefault: false
description: "This priority class should be used for very important pods only"

เราสร้าง PriorityClassตั้งชื่อ คำอธิบาย และค่า ที่สูงกว่า valueลำดับความสำคัญยิ่งสูง ค่าสามารถเป็นจำนวนเต็ม 32 บิตใดๆ ที่น้อยกว่าหรือเท่ากับ 1 ค่าที่สูงกว่าจะถูกสงวนไว้สำหรับพ็อดระบบที่มีความสำคัญต่อภารกิจ การไล่ออกจะเกิดขึ้นก็ต่อเมื่อพ็อดที่มีลำดับความสำคัญสูงไม่มีที่ให้หันกลับ จากนั้นพ็อดบางส่วนจากโหนดหนึ่งๆ จะถูกโยกย้าย หากกลไกนี้เข้มงวดเกินไปสำหรับคุณ คุณสามารถเพิ่มตัวเลือกได้ preemptionPolicy: Neverจากนั้นจะไม่มีใบจอง พ็อดจะเป็นลำดับแรกในคิวและรอให้ตัวกำหนดตารางเวลาค้นหาทรัพยากรฟรีสำหรับพ็อด

ต่อไปเราจะสร้างพ็อดซึ่งเราระบุชื่อ priorityClassName:

apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
 spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
  priorityClassName: high-priority
          

คุณสามารถสร้างคลาสที่มีลำดับความสำคัญได้มากเท่าที่คุณต้องการ แม้ว่าจะไม่แนะนำให้ทำสิ่งนี้มากเกินไป (เช่น จำกัดตัวเองให้มีลำดับความสำคัญต่ำ ปานกลาง และสูง)

ดังนั้น หากจำเป็น คุณสามารถเพิ่มประสิทธิภาพการปรับใช้บริการที่สำคัญ เช่น nginx-ingress-controller, coredns เป็นต้น

9. เพิ่มประสิทธิภาพคลัสเตอร์ ETCD ของคุณ

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อ

ETCD สามารถเรียกได้ว่าเป็นสมองของคลัสเตอร์ทั้งหมด สิ่งสำคัญคือต้องรักษาการทำงานของฐานข้อมูลนี้ให้อยู่ในระดับสูงเนื่องจากความเร็วในการทำงานใน "Cube" ขึ้นอยู่กับมัน แนวทางที่ค่อนข้างเป็นมาตรฐานและในขณะเดียวกัน ทางออกที่ดีคือการเก็บคลัสเตอร์ ETCD ไว้บนโหนดหลักเพื่อให้ kube-apiserver มีความล่าช้าน้อยที่สุด หากเป็นไปไม่ได้ ให้วาง ETCD ให้ใกล้ที่สุดเท่าที่จะเป็นไปได้ โดยมีแบนด์วิธที่ดีระหว่างผู้เข้าร่วม ให้ความสนใจกับจำนวนโหนดจาก ETCD ที่สามารถหลุดออกมาได้โดยไม่เป็นอันตรายต่อคลัสเตอร์

เคล็ดลับประสิทธิภาพ Kubernetes เก้าข้อ

โปรดทราบว่าการเพิ่มจำนวนผู้เข้าร่วมในคลัสเตอร์มากเกินไปสามารถเพิ่มความทนทานต่อข้อผิดพลาดโดยเสียค่าใช้จ่ายในการปฏิบัติงาน ทุกอย่างควรอยู่ในปริมาณที่พอเหมาะ

หากเราพูดถึงการตั้งค่าบริการ มีคำแนะนำเล็กน้อย:

  1. มีฮาร์ดแวร์ที่ดีตามขนาดของคลัสเตอร์ (คุณสามารถอ่าน ที่นี่).

  2. ปรับแต่งพารามิเตอร์เล็กน้อยหากคุณกระจายคลัสเตอร์ระหว่างคู่ของ DC หรือเครือข่ายและดิสก์ของคุณ ปล่อยให้เป็นที่ต้องการอีกมาก (คุณสามารถอ่าน ที่นี่).

ข้อสรุป

บทความนี้อธิบายจุดที่ทีมของเราพยายามปฏิบัติตาม นี่ไม่ใช่คำอธิบายการดำเนินการทีละขั้นตอน แต่เป็นตัวเลือกที่มีประโยชน์ในการเพิ่มประสิทธิภาพโอเวอร์เฮดของคลัสเตอร์ เป็นที่ชัดเจนว่าแต่ละคลัสเตอร์มีลักษณะเฉพาะในแบบของตัวเอง และโซลูชันการปรับแต่งอาจแตกต่างกันไปมาก ดังนั้นจึงเป็นเรื่องน่าสนใจที่จะได้รับความคิดเห็นจากคุณ: คุณจะตรวจสอบคลัสเตอร์ Kubernetes ของคุณอย่างไร คุณจะปรับปรุงประสิทธิภาพได้อย่างไร แบ่งปันประสบการณ์ของคุณในความคิดเห็นมันจะน่าสนใจที่จะรู้

ที่มา: will.com