วิธีเข้าถึงทรัพยากร Kubernetes Pod

วิธีเข้าถึงทรัพยากร Kubernetes Podรางวัลโดย Tohad

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

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

ทีม Kubernetes aaS จาก Mail.ru แปลบทความเกี่ยวกับทรัพยากรคอนเทนเนอร์ (CPU & MEM) คำขอ และข้อจำกัดของทรัพยากร คุณจะได้เรียนรู้ถึงประโยชน์ของการตั้งค่าเหล่านี้ และจะเกิดอะไรขึ้นหากคุณไม่ได้ตั้งค่า

ทรัพยากรคอมพิวเตอร์

เรามีทรัพยากรสองประเภทโดยมีหน่วยต่อไปนี้:

  • หน่วยประมวลผลกลาง (CPU) - คอร์;
  • หน่วยความจำ (MEM) - ไบต์

มีการระบุทรัพยากรสำหรับแต่ละคอนเทนเนอร์ ในไฟล์ Pod YAML ต่อไปนี้ คุณจะเห็นส่วนทรัพยากรที่มีทรัพยากรที่ร้องขอและจำกัด:

  • ทรัพยากรพ็อดที่ร้องขอ = ผลรวมของทรัพยากรที่ร้องขอของคอนเทนเนอร์ทั้งหมด
  • ขีดจำกัดทรัพยากรพ็อด = ผลรวมของขีดจำกัดทรัพยากรพ็อดทั้งหมด

apiVersion: v1
kind: Pod
metadata:
  name: backend-pod-name
  labels:
    application: backend
spec:
  containers:
    — name: main-container
      image: my-backend
      tag: v1
      ports:
      — containerPort: 8080
      resources:
        requests:
          cpu: 0.2 # REQUESTED CPU: 200m cores
          memory: "1Gi" # REQUESTED MEM: 1Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi
    — name: other-container
      image: other-app
      tag: v1
      ports:
      — containerPort: 8000
      resources:
        requests:
          cpu: "200m" # REQUESTED CPU: 200m cores
          memory: "0.5Gi" # REQUESTED MEM: 0.5Gi
        limits:
          cpu: 1 # MAX CPU USAGE: 1 core
          memory: "1Gi" # MAX MEM USAGE:  1Gi

ตัวอย่างทรัพยากรที่ได้รับการร้องขอและจำกัด

สนาม resources.requested จากสเปค Pod เป็นหนึ่งในองค์ประกอบที่ใช้ในการค้นหาโหนดที่ต้องการ คุณสามารถวางแผนการใช้งาน Pod ได้แล้ว คุณจะค้นหาโหนดที่เหมาะสมได้อย่างไร?

Kubernetes ประกอบด้วยองค์ประกอบหลายอย่าง รวมถึงโหนดหลักหรือโหนดหลัก (Kubernetes Control Plane) โหนดหลักมีหลายกระบวนการ: kube-apiserver, kube-controller-manager และ kube-scheduler

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

วิธีเข้าถึงทรัพยากร Kubernetes Podพ็อดสีม่วงจะวางไว้ที่ไหน?

ในภาพคุณจะเห็นว่า kube-scheduler ควรกำหนดเวลา Pod สีม่วงใหม่ คลัสเตอร์ Kubernetes มีสองโหนด: A และ B อย่างที่คุณเห็น kube-scheduler ไม่สามารถกำหนดเวลา Pod บนโหนด A ได้ - ทรัพยากรที่มีอยู่ (ไม่ได้รับการร้องขอ) ไม่ตรงกับคำขอของ Pod สีม่วง ดังนั้น หน่วยความจำ 1 GB ที่ร้องขอโดย Pod สีม่วงจะไม่พอดีกับโหนด A เนื่องจากหน่วยความจำที่มีอยู่คือ 0,5 GB แต่โหนด B มีทรัพยากรเพียงพอ เป็นผลให้ kube-scheduler ตัดสินใจว่าปลายทางของ Pod สีม่วงคือโหนด B

ตอนนี้เรารู้แล้วว่าทรัพยากรที่ร้องขอส่งผลต่อการเลือกโหนดเพื่อรัน Pod อย่างไร แต่ผลกระทบของทรัพยากรส่วนเพิ่มคืออะไร?

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

ทรัพยากรที่ร้องขอและสูงสุดโดยละเอียด

วิธีเข้าถึงทรัพยากร Kubernetes Podการสื่อสารทรัพยากรระหว่าง Docker และ Kubernetes

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

หน่วยความจำ: คำขอและข้อจำกัด

containers:
...
 resources:
   requests:
     memory: "0.5Gi"
   limits:
     memory: "1Gi"

ตามที่กล่าวไว้ข้างต้น หน่วยความจำมีหน่วยเป็นไบต์ ขึ้นอยู่กับ เอกสาร Kubernetesเราสามารถระบุหน่วยความจำเป็นตัวเลขได้ โดยปกติแล้วจะเป็นจำนวนเต็ม เช่น 2678 ซึ่งก็คือ 2678 ไบต์ คุณยังสามารถใช้คำต่อท้ายได้ G и Giสิ่งสำคัญคือต้องจำไว้ว่ามันไม่เท่ากัน อันแรกเป็นทศนิยม และอันที่สองเป็นไบนารี เช่นเดียวกับตัวอย่างที่กล่าวถึงในเอกสารของ k8s: 128974848, 129e6, 129M, 123Mi - พวกมันเทียบเท่ากันในทางปฏิบัติ

ตัวเลือก Kubernetes limits.memory ตรงกับธง --memory จากนักเทียบท่า ในกรณีที่ request.memory ไม่มีลูกศรสำหรับ Docker เนื่องจาก Docker ไม่ได้ใช้ฟิลด์นี้ คุณอาจถามว่าสิ่งนี้จำเป็นหรือไม่? ใช่ต้อง. ดังที่ได้กล่าวไปแล้ว ฟิลด์นี้มีความสำคัญสำหรับ Kubernetes จากข้อมูลดังกล่าว kube-scheduler จะตัดสินใจว่าโหนดใดที่จะกำหนดเวลา Pod

จะเกิดอะไรขึ้นหากคุณตั้งค่าหน่วยความจำไม่เพียงพอสำหรับคำขอ

หากคอนเทนเนอร์ถึงขีดจำกัดของหน่วยความจำที่ร้องขอ พ็อดจะถูกวางในกลุ่มของพ็อดที่หยุดเมื่อมีหน่วยความจำไม่เพียงพอในโหนด

จะเกิดอะไรขึ้นหากคุณตั้งค่าขีดจำกัดหน่วยความจำต่ำเกินไป

หากคอนเทนเนอร์เกินขีดจำกัดหน่วยความจำ คอนเทนเนอร์จะถูกยกเลิกเนื่องจาก OOM-Killed และจะรีสตาร์ทถ้าเป็นไปได้ตาม RestartPolicy โดยที่ค่าเริ่มต้นคือ Always.

จะเกิดอะไรขึ้นถ้าคุณไม่ระบุหน่วยความจำที่ร้องขอ

Kubernetes จะใช้ค่าขีดจำกัดและตั้งเป็นค่าเริ่มต้น

จะเกิดอะไรขึ้นถ้าคุณไม่ระบุขีดจำกัดหน่วยความจำ

คอนเทนเนอร์ไม่มีข้อจำกัด สามารถใช้หน่วยความจำได้มากเท่าที่ต้องการ หากเขาเริ่มใช้หน่วยความจำที่มีอยู่ทั้งหมดของโหนด OOM จะฆ่าเขา คอนเทนเนอร์จะถูกรีสตาร์ทถ้าเป็นไปได้ตาม RestartPolicy

จะเกิดอะไรขึ้นถ้าคุณไม่ระบุขีดจำกัดหน่วยความจำ

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

หากหน่วยความจำที่ร้องขอมีมากกว่าที่โหนดสามารถให้ได้ พ็อดจะไม่ถูกกำหนดเวลา สิ่งสำคัญคือต้องจำไว้ว่า Requests.memory - ไม่ใช่ค่าขั้นต่ำ นี่คือคำอธิบายจำนวนหน่วยความจำที่เพียงพอเพื่อให้คอนเทนเนอร์ทำงานอย่างต่อเนื่อง

โดยปกติจะแนะนำให้ตั้งค่าเดียวกันสำหรับ request.memory и limit.memory. เพื่อให้แน่ใจว่า Kubernetes จะไม่กำหนดเวลา Pod บนโหนดที่มีหน่วยความจำเพียงพอที่จะเรียกใช้ Pod แต่ไม่เพียงพอที่จะเรียกใช้ โปรดทราบว่า: การวางแผน Kubernetes Pod จะคำนึงถึงเท่านั้น requests.memoryและ limits.memory ไม่ได้คำนึงถึง

CPU: คำขอและขีดจำกัด

containers:
...
 resources:
   requests:
     cpu: 1
   limits:
     cpu: "1200m"

ด้วย CPU ทุกอย่างจะซับซ้อนขึ้นเล็กน้อย เมื่อกลับมาที่ภาพความสัมพันธ์ระหว่าง Kubernetes และ Docker คุณจะเห็นได้ว่า request.cpu สอดคล้องกับ --cpu-sharesในขณะที่ limit.cpu ตรงกับธง cpus ในนักเทียบท่า

CPU ที่ Kubernetes ร้องขอจะถูกคูณด้วย 1024 ซึ่งเป็นสัดส่วนของรอบ CPU หากต้องการขอเต็ม 1 คอร์ ต้องบวกเพิ่ม cpu: 1ดังที่แสดงด้านบน

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

วิธีเข้าถึงทรัพยากร Kubernetes Pod
คำขอ CPU - ระบบแกนเดี่ยว

สมมติว่าคุณมีระบบโฮสต์แบบคอร์เดียวที่ใช้งานคอนเทนเนอร์ คุณแม่ (Kubernetes) อบพาย (CPU) แล้วอยากแบ่งให้ลูกๆ (ตู้คอนเทนเนอร์) เด็กสามคนต้องการพายทั้งชิ้น (สัดส่วน = 1024) เด็กอีกคนต้องการครึ่งพาย (512) แม่ต้องการความยุติธรรมและคำนวณง่ายๆ

# Сколько пирогов хотят дети?
# 3 ребенка хотят по целому пирогу и еще один хочет половину пирога
cakesNumberKidsWant = (3 * 1) + (1 * 0.5) = 3.5
# Выражение получается так:
3 (ребенка/контейнера) * 1 (целый пирог/полное ядро) + 1 (ребенок/контейнер) * 0.5 (половина пирога/половина ядра)
# Сколько пирогов испечено?
availableCakesNumber = 1
# Сколько пирога (максимально) дети реально могут получить?
newMaxRequest = 1 / 3.5 =~ 28%

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

วิธีเข้าถึงทรัพยากร Kubernetes Pod
คำขอ CPU - ระบบมัลติคอร์ (4)

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

การคำนวณข้างต้นทำให้เข้าใจได้ง่ายขึ้นว่า CPU มีการกระจายระหว่างคอนเทนเนอร์อย่างไร แน่นอนว่านอกจากตัวคอนเทนเนอร์แล้ว ยังมีกระบวนการอื่นๆ ที่ใช้ทรัพยากร CPU ด้วยเช่นกัน เมื่อกระบวนการในคอนเทนเนอร์หนึ่งไม่ได้ใช้งาน ผู้อื่นจะสามารถใช้ทรัพยากรได้ CPU: "200m" สอดคล้องกับ CPU: 0,2ซึ่งหมายถึงประมาณ 20% ของหนึ่งคอร์

ตอนนี้เรามาพูดถึง limit.cpu. CPU ที่ Kubernetes จำกัดจะถูกคูณด้วย 100 ผลลัพธ์คือระยะเวลาที่คอนเทนเนอร์สามารถใช้ได้ทุกๆ 100 µs (cpu-period).

limit.cpu ตรงกับธงนักเทียบท่า --cpus. นี่คือการผสมผสานระหว่างความเก่า --cpu-period и --cpu-quota. โดยการตั้งค่า เราจะระบุจำนวนทรัพยากร CPU ที่พร้อมใช้งานที่คอนเทนเนอร์สามารถใช้ได้สูงสุดก่อนที่จะเริ่มการควบคุมปริมาณ:

  • ซีพียู - การผสมผสาน cpu-period и cpu-quota. cpus = 1.5 เทียบเท่ากับการตั้งค่า cpu-period = 100000 и cpu-quota = 150000;
  • ช่วงเวลา CPU - ระยะเวลา ตัวกำหนดเวลา CPU CFS, ค่าเริ่มต้น 100 ไมโครวินาที;
  • cpu-โควต้า - จำนวนไมโครวินาทีภายใน cpu-periodซึ่งถูกล้อมรอบด้วยคอนเทนเนอร์

จะเกิดอะไรขึ้นหากคุณติดตั้ง CPU ที่ร้องขอไม่เพียงพอ

หากคอนเทนเนอร์ต้องการมากกว่าที่ติดตั้งไว้ คอนเทนเนอร์จะขโมย CPU จากกระบวนการอื่น

จะเกิดอะไรขึ้นหากคุณตั้งค่าขีดจำกัด CPU ต่ำเกินไป

เนื่องจากทรัพยากร CPU สามารถปรับเปลี่ยนได้ การควบคุมปริมาณจึงจะเปิดขึ้น

จะเกิดอะไรขึ้นถ้าคุณไม่ระบุคำขอ CPU

เช่นเดียวกับหน่วยความจำ ค่าคำขอจะเท่ากับขีดจำกัด

จะเกิดอะไรขึ้นถ้าคุณไม่ระบุขีดจำกัด CPU

คอนเทนเนอร์จะใช้ CPU มากเท่าที่ต้องการ หากมีการกำหนดนโยบาย CPU เริ่มต้น (LimitRange) ในเนมสเปซ ขีดจำกัดนี้จะใช้สำหรับคอนเทนเนอร์ด้วย

จะเกิดอะไรขึ้นถ้าคุณไม่ระบุคำขอหรือขีดจำกัด CPU

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

ข้อควรจำ: หากคุณขอ CPU มากกว่าที่โหนดสามารถให้ได้ พ็อดจะไม่ถูกกำหนดเวลา Requests.cpu - ไม่ใช่ค่าต่ำสุด แต่เป็นค่าที่เพียงพอที่จะสตาร์ท Pod และทำงานโดยไม่มีข้อผิดพลาด หากแอปพลิเคชันไม่ได้ทำการคำนวณที่ซับซ้อน ตัวเลือกที่ดีที่สุดคือการติดตั้ง request.cpu <= 1 และเปิดตัวแบบจำลองได้มากเท่าที่จำเป็น

จำนวนทรัพยากรที่ร้องขอหรือขีดจำกัดทรัพยากรที่เหมาะสมที่สุด

เราได้เรียนรู้เกี่ยวกับข้อจำกัดของทรัพยากรการประมวลผล ตอนนี้ถึงเวลาตอบคำถาม: “Pod ของฉันต้องใช้ทรัพยากรจำนวนเท่าใดในการรันแอปพลิเคชันโดยไม่มีปัญหาใดๆ? ปริมาณในอุดมคติคืออะไร?

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

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

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

ข้อสรุป

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

กล่าวโดยสรุป มีบางสิ่งที่ควรคำนึงถึง:

  1. ทรัพยากรที่ร้องขอคือการกำหนดค่าที่นำมาพิจารณาเมื่อเริ่มต้นระบบ (เมื่อ Kubernetes วางแผนที่จะโฮสต์แอปพลิเคชัน) ในทางตรงกันข้าม การจำกัดทรัพยากรเป็นสิ่งสำคัญในขณะรันไทม์ เมื่อแอปพลิเคชันทำงานบนโหนดอยู่แล้ว
  2. เมื่อเปรียบเทียบกับหน่วยความจำแล้ว CPU เป็นทรัพยากรที่ได้รับการควบคุม หากมี CPU ไม่เพียงพอ Pod ของคุณจะไม่ปิดตัวลงและกลไกการควบคุมปริมาณจะเปิดขึ้น
  3. ทรัพยากรที่ร้องขอและขีดจำกัดของทรัพยากรไม่ใช่ค่าต่ำสุดและสูงสุด! ด้วยการกำหนดทรัพยากรที่ร้องขอ คุณมั่นใจได้ว่าแอปพลิเคชันจะทำงานได้โดยไม่มีปัญหา
  4. แนวปฏิบัติที่ดีคือการตั้งค่าคำขอหน่วยความจำให้เท่ากับขีดจำกัดหน่วยความจำ
  5. ตกลงขอติดตั้งแล้ว CPU <=1หากแอปพลิเคชันไม่ได้ทำการคำนวณที่ซับซ้อน
  6. หากคุณร้องขอทรัพยากรมากกว่าที่มีอยู่บนโหนด Pod จะไม่ถูกกำหนดตารางเวลาให้กับโหนดนั้น
  7. หากต้องการกำหนดจำนวนทรัพยากรที่ร้องขอ/ขีดจำกัดทรัพยากรที่ถูกต้อง ให้ใช้การทดสอบและติดตามโหลด

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

โชคดี!

มีอะไรให้อ่านอีก:

  1. ความสามารถในการสังเกต SRE: เนมสเปซและโครงสร้างเมตริก.
  2. เครื่องมือที่มีประโยชน์มากกว่า 90 รายการสำหรับ Kubernetes: การปรับใช้ การจัดการ การตรวจสอบ ความปลอดภัย และอื่นๆ.
  3. ช่องของเราเกี่ยวกับ Kubernetes ใน Telegram.

ที่มา: will.com

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