10 ข้อผิดพลาดทั่วไปเมื่อใช้ Kubernetes

บันทึก. แปล: ผู้เขียนบทความนี้เป็นวิศวกรจากบริษัทเล็กๆ ในเช็ก ชื่อ Pipetail พวกเขาสามารถรวบรวมรายการที่ยอดเยี่ยมของปัญหาเร่งด่วนและความเข้าใจผิดที่เกี่ยวข้องกับการทำงานของคลัสเตอร์ Kubernetes [บางครั้งก็ซ้ำซาก แต่ยังคง] ได้

10 ข้อผิดพลาดทั่วไปเมื่อใช้ Kubernetes

ตลอดหลายปีที่ผ่านมาของการใช้ Kubernetes เราได้ทำงานร่วมกับคลัสเตอร์จำนวนมาก (ทั้งที่มีการจัดการและไม่มีการจัดการ - บน GCP, AWS และ Azure) เมื่อเวลาผ่านไป เราเริ่มสังเกตเห็นว่ามีข้อผิดพลาดบางอย่างเกิดขึ้นซ้ำๆ อยู่เสมอ อย่างไรก็ตามไม่มีความละอายในเรื่องนี้: เราทำเองส่วนใหญ่แล้ว!

บทความนี้ประกอบด้วยข้อผิดพลาดที่พบบ่อยที่สุดและยังกล่าวถึงวิธีการแก้ไขอีกด้วย

1. ทรัพยากร: คำขอและขีดจำกัด

รายการนี้สมควรได้รับความสนใจใกล้เคียงที่สุดและเป็นอันดับหนึ่งในรายการอย่างแน่นอน

โดยปกติแล้วคำขอ CPU ไม่ได้ระบุเลยหรือมีค่าต่ำมาก (เพื่อวางพ็อดในแต่ละโหนดให้ได้มากที่สุด) ดังนั้นโหนดจึงมีการโอเวอร์โหลด ในช่วงเวลาที่มีภาระงานสูง พลังการประมวลผลของโหนดจะถูกใช้อย่างเต็มที่ และปริมาณงานเฉพาะจะได้รับเฉพาะสิ่งที่ "ร้องขอ" โดย การควบคุมปริมาณ CPU. สิ่งนี้นำไปสู่เวลาแฝงของแอปพลิเคชันที่เพิ่มขึ้น การหมดเวลา และผลลัพธ์ที่ไม่พึงประสงค์อื่นๆ (อ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ในการแปลล่าสุดของเรา: “ขีดจำกัดของ CPU และการควบคุมปริมาณเชิงรุกใน Kubernetes" - ประมาณ แปล)

ความพยายามที่ดีที่สุด (อย่างที่สุด ไม่ ที่แนะนำ):

resources: {}

คำขอ CPU ต่ำมาก (extremely ไม่ ที่แนะนำ):

   resources:
      Requests:
        cpu: "1m"

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

การเลือกมากเกินไป (มีความมุ่งมั่นมากเกินไป) ปัญหาหน่วยความจำอาจนำไปสู่ปัญหาที่ใหญ่กว่าได้ การถึงขีดจำกัดของ CPU จะต้องข้ามรอบสัญญาณนาฬิกา ในขณะที่การถึงขีดจำกัดของหน่วยความจำจะต้องทำลายพ็อด คุณเคยสังเกต OOMkill? ใช่นั่นคือสิ่งที่เรากำลังพูดถึง

คุณต้องการลดโอกาสที่จะเกิดเหตุการณ์เช่นนี้ให้เหลือน้อยที่สุดหรือไม่? อย่าจัดสรรหน่วยความจำมากเกินไปและใช้ QoS ที่รับประกัน (คุณภาพของบริการ) โดยตั้งค่าคำขอหน่วยความจำให้ถึงขีดจำกัด (ดังตัวอย่างด้านล่าง) อ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ใน การนำเสนอของเฮนนิ่งจาคอบส์ (หัวหน้าวิศวกรที่ Zalando)

ระเบิดได้ (มีโอกาสสูงที่จะโดน OOMkilled):

   resources:
      requests:
        memory: "128Mi"
        cpu: "500m"
      limits:
        memory: "256Mi"
        cpu: 2

รับประกัน:

   resources:
      requests:
        memory: "128Mi"
        cpu: 2
      limits:
        memory: "128Mi"
        cpu: 2

สิ่งใดที่อาจช่วยได้เมื่อตั้งค่าทรัพยากร

ด้วย เซิร์ฟเวอร์เมตริก คุณสามารถดูปริมาณการใช้ทรัพยากร CPU ปัจจุบันและการใช้หน่วยความจำตามพ็อด (และคอนเทนเนอร์ที่อยู่ภายใน) เป็นไปได้มากว่าคุณใช้งานมันอยู่แล้ว เพียงรันคำสั่งต่อไปนี้:

kubectl top pods
kubectl top pods --containers
kubectl top nodes

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

VerticalPodตัวปรับขนาดอัตโนมัติ ช่วยให้ อัตโนมัติ กระบวนการนี้ ติดตามประวัติการใช้งาน CPU และหน่วยความจำ และตั้งค่าคำขอและขีดจำกัดใหม่ตามข้อมูลนี้

การใช้พลังการประมวลผลอย่างมีประสิทธิภาพไม่ใช่เรื่องง่าย มันเหมือนกับการเล่น Tetris ตลอดเวลา หากคุณจ่ายเงินมากเกินไปสำหรับพลังการประมวลผลโดยสิ้นเปลืองเฉลี่ยต่ำ (ประมาณ 10%) เราขอแนะนำให้ดูผลิตภัณฑ์ที่ใช้ AWS Fargate หรือ Virtual Kubelet สร้างขึ้นจากรูปแบบการเรียกเก็บเงินแบบไร้เซิร์ฟเวอร์/แบบจ่ายต่อการใช้งาน ซึ่งอาจกลายเป็นว่าราคาถูกกว่าในเงื่อนไขดังกล่าว

2. การสอบสวนความมีชีวิตชีวาและความพร้อม

ตามค่าเริ่มต้น การตรวจสอบความพร้อมใช้งานและความพร้อมจะไม่เปิดใช้งานใน Kubernetes และบางครั้งก็ลืมเปิดเครื่อง...

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

การทดสอบเหล่านี้มักสับสนระหว่างกัน:

  • ความเป็นอยู่ — การตรวจสอบ “ความอยู่รอด” ซึ่งจะรีสตาร์ทพ็อดหากล้มเหลว
  • การเตรียมความพร้อม — การตรวจสอบความพร้อม หากล้มเหลว จะตัดการเชื่อมต่อพ็อดจากบริการ Kubernetes (สามารถตรวจสอบได้โดยใช้ kubectl get endpoints) และการจราจรจะไม่มาถึงจนกว่าการตรวจสอบครั้งถัดไปจะเสร็จสมบูรณ์

การตรวจสอบทั้งสองนี้ ดำเนินการตลอดวงจรชีวิตของ POD. มันสำคัญมาก.

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

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

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

การตรวจสอบทั้งสองประเภทไม่ควรล้มเหลวเมื่อการขึ้นต่อกันทั่วไปล้มเหลว มิฉะนั้นจะนำไปสู่ความล้มเหลวแบบเรียงซ้อน (คล้ายหิมะถล่ม) ของพ็อดทั้งหมด กล่าวอีกนัยหนึ่ง อย่าทำร้ายตัวเอง.

3. LoadBalancer สำหรับบริการ HTTP แต่ละรายการ

เป็นไปได้มากว่าคุณมีบริการ HTTP ในคลัสเตอร์ที่คุณต้องการส่งต่อไปยังโลกภายนอก

หากเปิดใช้บริการเป็น type: LoadBalancerตัวควบคุม (ขึ้นอยู่กับผู้ให้บริการ) จะจัดเตรียมและเจรจา LoadBalancer ภายนอก (ไม่จำเป็นต้องทำงานบน L7 แต่จะทำงานบน L4 ด้วยซ้ำ) และอาจส่งผลต่อต้นทุน (ที่อยู่ IPv4 แบบคงที่ภายนอก พลังการประมวลผล การเรียกเก็บเงินต่อวินาที ) เนื่องจากจำเป็นต้องสร้างทรัพยากรดังกล่าวจำนวนมาก

ในกรณีนี้ การใช้โหลดบาลานเซอร์ภายนอกตัวเดียวโดยเปิดบริการจะมีเหตุผลมากกว่ามาก type: NodePort. หรือดีกว่านั้น ขยายความประมาณว่า ตัวควบคุม nginx ทางเข้า (หรือ Traefik) ซึ่งจะเป็นคนเดียวเท่านั้น โหนดพอร์ต ตำแหน่งข้อมูลที่เกี่ยวข้องกับโหลดบาลานเซอร์ภายนอก และจะกำหนดเส้นทางการรับส่งข้อมูลในคลัสเตอร์โดยใช้ สิทธิในการเข้า- ทรัพยากรของ Kubernetes

บริการภายในคลัสเตอร์ (ไมโคร) อื่นๆ ที่มีปฏิสัมพันธ์ระหว่างกันสามารถ “สื่อสาร” โดยใช้บริการต่างๆ เช่น คลัสเตอร์ไอพี และกลไกการค้นหาบริการในตัวผ่าน DNS เพียงอย่าใช้ DNS/IP สาธารณะ เนื่องจากอาจส่งผลกระทบต่อเวลาแฝงและเพิ่มต้นทุนของบริการคลาวด์

4. การปรับขนาดคลัสเตอร์อัตโนมัติโดยไม่คำนึงถึงคุณสมบัติของคลัสเตอร์

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

ลองนึกภาพว่าควรกำหนดเวลาพ็อดบางตัว แต่พลังงาน CPU ที่มีอยู่ทั้งหมดได้รับการร้องขอ/แยกชิ้นส่วนและพ็อด ติดอยู่ในสถานะ Pending. ตัวปรับขนาดอัตโนมัติภายนอกจะเห็นโหลด CPU โดยเฉลี่ยในปัจจุบัน (ไม่ใช่โหลดที่ร้องขอ) และไม่เริ่มต้นการขยาย (ขยายขนาดออก) - ไม่เพิ่มโหนดอื่น ด้วยเหตุนี้ พ็อดนี้จะไม่ถูกกำหนดเวลา

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

ได้รับความนิยมอย่างมากในชุมชน Kubernetes คลัสเตอร์ autoscaler. ทำงานบนคลัสเตอร์ รองรับ API จากผู้ให้บริการคลาวด์รายใหญ่ คำนึงถึงข้อจำกัดทั้งหมด และสามารถปรับขนาดได้ในกรณีข้างต้น นอกจากนี้ยังสามารถขยายขนาดได้ในขณะที่ยังคงรักษาขีดจำกัดที่ตั้งไว้ทั้งหมด จึงช่วยประหยัดเงิน (ซึ่งหากไม่เช่นนั้นจะถูกนำไปใช้กับความจุที่ไม่ได้ใช้)

5. ละเลยความสามารถของ IAM/RBAC

ระวังการใช้ผู้ใช้ IAM ที่มีความลับถาวรสำหรับ เครื่องจักรและแอพพลิเคชั่น. จัดระเบียบการเข้าถึงชั่วคราวโดยใช้บทบาทและบัญชีบริการ (บัญชีบริการ).

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

10 ข้อผิดพลาดทั่วไปเมื่อใช้ Kubernetes

ลืมเรื่อง kube2iam แล้วตรงไปที่บทบาท IAM สำหรับบัญชีบริการ (ตามที่อธิบายไว้ใน บันทึกที่มีชื่อเดียวกัน ชเตปัน วรานี):

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-app-role
  name: my-serviceaccount
  namespace: default

คำอธิบายประกอบหนึ่งรายการ ไม่ยากขนาดนั้นใช่ไหม?

นอกจากนี้ อย่าให้สิทธิ์แก่บัญชีบริการและโปรไฟล์อินสแตนซ์ admin и cluster-adminถ้าพวกเขาไม่ต้องการมัน การดำเนินการนี้ยากขึ้นเล็กน้อย โดยเฉพาะใน RBAC K8 แต่ก็คุ้มค่ากับความพยายามอย่างแน่นอน

6. อย่าพึ่งพาการต่อต้านความสัมพันธ์แบบอัตโนมัติกับพ็อด

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

น่าเสียดายที่ตัวกำหนดเวลา Kubernetes ด้วยความคิดริเริ่มของตัวเองไม่สอดคล้องกับกฎของการมีอยู่ที่แยกจากกัน (ต่อต้านความสัมพันธ์) สำหรับฝัก จะต้องระบุไว้อย่างชัดเจน:

// опущено для краткости
      labels:
        app: zk
// опущено для краткости
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: "app"
                    operator: In
                    values:
                    - zk
              topologyKey: "kubernetes.io/hostname"

นั่นคือทั้งหมดที่ ตอนนี้พ็อดจะถูกกำหนดเวลาบนโหนดที่แตกต่างกัน (เงื่อนไขนี้จะถูกตรวจสอบในระหว่างการกำหนดเวลาเท่านั้น แต่ไม่ใช่ในระหว่างการดำเนินการ - ดังนั้น requiredDuringSchedulingIgnoredDuringExecution).

ที่นี่เรากำลังพูดถึง podAntiAffinity บนโหนดที่แตกต่างกัน: topologyKey: "kubernetes.io/hostname", - และไม่เกี่ยวกับโซนความพร้อมใช้งานที่แตกต่างกัน หากต้องการใช้ HA เต็มรูปแบบ คุณจะต้องเจาะลึกในหัวข้อนี้

7. การเพิกเฉยต่อ PodDisruptionBudgets

ลองจินตนาการว่าคุณมีโหลดการผลิตบนคลัสเตอร์ Kubernetes โหนดและคลัสเตอร์จะต้องได้รับการอัปเดต (หรือเลิกใช้งาน) เป็นระยะๆ PodDisruptionBudget (PDB) เป็นเหมือนข้อตกลงการรับประกันบริการระหว่างผู้ดูแลระบบคลัสเตอร์และผู้ใช้

PDB ช่วยให้คุณหลีกเลี่ยงการหยุดชะงักของบริการที่เกิดจากการไม่มีโหนด:

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: zk-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: zookeeper

ในตัวอย่างนี้ คุณซึ่งเป็นผู้ใช้คลัสเตอร์ กล่าวกับผู้ดูแลระบบว่า “เฮ้ ฉันมีบริการผู้ดูแลสัตว์ และไม่ว่าคุณจะทำอะไรก็ตาม ฉันอยากให้มีแบบจำลองของบริการนี้อย่างน้อย 2 รายการอยู่เสมอ”

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ ที่นี่.

8. ผู้ใช้หลายคนหรือสภาพแวดล้อมในคลัสเตอร์ทั่วไป

เนมสเปซ Kubernetes (เนมสเปซ) อย่าให้ฉนวนที่แข็งแกร่ง.

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

ผู้ที่ต้องการรวมปริมาณงานทั้งสองประเภทไว้ในคลัสเตอร์เดียวกันจะต้องจัดการกับความซับซ้อน หากไม่มีความจำเป็นดังกล่าวและคุณสามารถมีได้ อีกหนึ่งคลัสเตอร์ (เช่น ในระบบคลาวด์สาธารณะ) จะดีกว่าถ้าทำเช่นนั้น สิ่งนี้จะทำให้ได้ฉนวนในระดับที่สูงขึ้นมาก

9. externalTrafficPolicy: คลัสเตอร์

บ่อยครั้งที่เราสังเกตเห็นว่าการรับส่งข้อมูลทั้งหมดภายในคลัสเตอร์มาผ่านบริการ เช่น NodePort ซึ่งมีการตั้งค่านโยบายเริ่มต้นไว้ externalTrafficPolicy: Cluster... หมายความว่า โหนดพอร์ต เปิดอยู่บนทุกโหนดในคลัสเตอร์ และคุณสามารถใช้โหนดใดก็ได้เพื่อโต้ตอบกับบริการที่ต้องการ (ชุดพ็อด)

10 ข้อผิดพลาดทั่วไปเมื่อใช้ Kubernetes

ในเวลาเดียวกัน พ็อดจริงที่เกี่ยวข้องกับบริการ NodePort ที่กล่าวมาข้างต้นมักจะใช้ได้เฉพาะในบางพื้นที่เท่านั้น เซตย่อยของโหนดเหล่านี้. กล่าวอีกนัยหนึ่ง ถ้าฉันเชื่อมต่อกับโหนดที่ไม่มีพ็อดที่ต้องการ มันจะส่งต่อการรับส่งข้อมูลไปยังโหนดอื่น เพิ่มการกระโดด และเวลาแฝงที่เพิ่มขึ้น (หากโหนดตั้งอยู่ในโซนความพร้อมใช้งาน/ศูนย์ข้อมูลที่แตกต่างกัน เวลาแฝงอาจค่อนข้างสูง นอกจากนี้ ค่าใช้จ่ายในการรับส่งข้อมูลขาออกก็จะเพิ่มขึ้น)

ในทางกลับกัน หากบริการ Kubernetes บางอย่างมีการกำหนดนโยบายไว้ externalTrafficPolicy: Localจากนั้น NodePort จะเปิดเฉพาะบนโหนดที่พ็อดที่ต้องการกำลังทำงานอยู่เท่านั้น เมื่อใช้โหลดบาลานเซอร์ภายนอกที่ตรวจสอบสถานะ (การตรวจสุขภาพ) จุดสิ้นสุด (ทำอย่างไร AWS ELB), เขา จะส่งทราฟฟิกไปยังโหนดที่จำเป็นเท่านั้นซึ่งจะส่งผลดีต่อความล่าช้า ความต้องการด้านการประมวลผล บิลค่าทางออก (และสามัญสำนึกก็กำหนดเช่นเดียวกัน)

มีโอกาสสูงที่คุณจะใช้สิ่งที่ชอบอยู่แล้ว Traefik หรือ ตัวควบคุม nginx ทางเข้า เป็นจุดสิ้นสุด NodePort (หรือ LoadBalancer ซึ่งใช้ NodePort ด้วย) เพื่อกำหนดเส้นทางการรับส่งข้อมูลขาเข้า HTTP และการตั้งค่าตัวเลือกนี้สามารถลดเวลาแฝงสำหรับคำขอดังกล่าวได้อย่างมาก

В สิ่งพิมพ์นี้ คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับ externalTrafficPolicy รวมถึงข้อดีและข้อเสียได้

10. อย่าผูกติดอยู่กับกลุ่มและอย่าใช้ระนาบควบคุมในทางที่ผิด

ก่อนหน้านี้ เป็นเรื่องปกติที่จะเรียกเซิร์ฟเวอร์ด้วยชื่อที่ถูกต้อง: Anton, HAL9000 และ Colossus... ปัจจุบันถูกแทนที่ด้วยตัวระบุที่สร้างขึ้นแบบสุ่ม อย่างไรก็ตาม นิสัยยังคงอยู่ และตอนนี้ชื่อที่ถูกต้องก็ตกเป็นของกลุ่ม

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

การที่กลุ่มกลายเป็นสัตว์เลี้ยงไม่ใช่เรื่องสนุก ดังนั้นเราขอแนะนำให้เอาพวกมันออกเป็นระยะๆ ในขณะที่ฝึกซ้อม การกู้คืนระบบ (นี่จะช่วย. วิศวกรรมความโกลาหล - ประมาณ แปล.). นอกจากนี้ การทำงานบนเลเยอร์ควบคุมก็ไม่เสียหายอะไร (เครื่องบินควบคุม). การกลัวที่จะสัมผัสเขาไม่ใช่สัญญาณที่ดี ฯลฯ ตาย? พวกคุณเดือดร้อนจริงๆ!

ในทางกลับกัน คุณไม่ควรหลงไปกับการบงการมัน กับเวลา ชั้นควบคุมอาจทำงานช้า. เป็นไปได้มากว่านี่เป็นเพราะออบเจ็กต์จำนวนมากถูกสร้างขึ้นโดยไม่มีการหมุน (เป็นสถานการณ์ทั่วไปเมื่อใช้ Helm ด้วยการตั้งค่าเริ่มต้น ซึ่งเป็นสาเหตุที่สถานะใน configmaps/ความลับไม่ได้รับการอัพเดต - ส่งผลให้มีออบเจ็กต์นับพันสะสมใน เลเยอร์ควบคุม) หรือด้วยการแก้ไขออบเจ็กต์ kube-api อย่างต่อเนื่อง (สำหรับการปรับขนาดอัตโนมัติ สำหรับ CI/CD สำหรับการตรวจสอบ บันทึกเหตุการณ์ ตัวควบคุม ฯลฯ)

นอกจากนี้ เราขอแนะนำให้ตรวจสอบข้อตกลง SLA/SLO กับผู้ให้บริการ Kubernetes ที่มีการจัดการ และให้ความสำคัญกับการรับประกัน แม่ค้ารับประกันได้ ความพร้อมใช้งานของเลเยอร์ควบคุม (หรือส่วนประกอบย่อย) แต่ไม่ใช่ความล่าช้า p99 ของคำขอที่คุณส่งไป กล่าวอีกนัยหนึ่งคุณสามารถเข้าได้ kubectl get nodesและรับคำตอบหลังจากผ่านไป 10 นาทีเท่านั้น ซึ่งจะไม่ถือเป็นการละเมิดข้อกำหนดของข้อตกลงการบริการ

11. โบนัส: ใช้แท็กล่าสุด

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

ECR รักษาความไม่เปลี่ยนรูปของแท็กรูปภาพ; เราขอแนะนำให้คุณทำความคุ้นเคยกับคุณสมบัติที่โดดเด่นนี้

สรุป

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

คุณสามารถทำความคุ้นเคยกับประสบการณ์ที่ไม่ประสบความสำเร็จของทีมต่างๆค่ะ รวบรวมเรื่องราวนี้ โดยเฮนนิ่งจาคอบส์

ผู้ที่ต้องการเพิ่มรายการข้อผิดพลาดที่ระบุในบทความนี้สามารถติดต่อเราทาง Twitter (@มาเร็กบาร์ติก, @MstrsObserver).

ปล.จากผู้แปล

อ่านเพิ่มเติมในบล็อกของเรา:

ที่มา: will.com

เพิ่มความคิดเห็น