ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

ในปีนี้ การประชุม Kubernetes หลักแห่งยุโรป - KubeCon + CloudNativeCon Europe 2020 - เป็นแบบเสมือนจริง อย่างไรก็ตาม การเปลี่ยนแปลงรูปแบบดังกล่าวไม่ได้ขัดขวางเราจากการส่งรายงานที่วางแผนไว้ระยะยาว “ไปเหรอ? ทุบตี! พบกับผู้ดำเนินการเชลล์” ที่อุทิศให้กับโครงการโอเพ่นซอร์สของเรา ตัวดำเนินการเชลล์.

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

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

แนะนำตัว วิดีโอของรายงาน (ประมาณ 23 นาทีเป็นภาษาอังกฤษ มีข้อมูลมากกว่าบทความอย่างเห็นได้ชัด) และเนื้อหาหลักจากบทความในรูปแบบข้อความ ไป!

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

อย่างไรก็ตาม เรามาเริ่มด้วยบริบทที่เกิดเหตุการณ์ทั้งหมดนี้กันก่อน: Kubernetes

Kubernetes API และตัวควบคุม

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

  • รับ ทรัพยากรตามชนิดและชื่อ
  • เปลี่ยน ทรัพยากร (ในกรณีนี้เซิร์ฟเวอร์จะเก็บเฉพาะวัตถุที่ "ถูกต้อง" เท่านั้น - วัตถุที่มีรูปแบบไม่ถูกต้องหรือมีไว้สำหรับไดเรกทอรีอื่นทั้งหมดจะถูกละทิ้ง)
  • ติดตาม สำหรับทรัพยากร (ในกรณีนี้ ผู้ใช้จะได้รับเวอร์ชันปัจจุบัน/อัปเดตทันที)

ดังนั้น Kubernetes จึงทำหน้าที่เป็นเซิร์ฟเวอร์ไฟล์ประเภทหนึ่ง (สำหรับรายการ YAML) โดยมีวิธีการพื้นฐานสามวิธี (ใช่ จริงๆ แล้วยังมีวิธีอื่นๆ อยู่ แต่ตอนนี้เราจะละเว้นไว้)

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

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

คอนโทรลเลอร์มีสองประเภทหลัก รายการแรกรับข้อมูลจาก Kubernetes ประมวลผลตามตรรกะที่ซ้อนกัน และส่งคืนไปยัง K8 ส่วนที่สองรับข้อมูลจาก Kubernetes แต่ต่างจากประเภทแรกตรงที่เปลี่ยนสถานะของทรัพยากรภายนอกบางส่วน

มาดูกระบวนการสร้าง Deployment ใน Kubernetes กันดีกว่า:

  • ตัวควบคุมการปรับใช้ (รวมอยู่ใน kube-controller-manager) รับข้อมูลเกี่ยวกับการปรับใช้และสร้าง ReplicaSet
  • ReplicaSet สร้างแบบจำลองสองรายการ (สองพ็อด) โดยอิงตามข้อมูลนี้ แต่ยังไม่ได้กำหนดเวลาพ็อดเหล่านี้
  • ตัวกำหนดเวลากำหนดเวลาพ็อดและเพิ่มข้อมูลโหนดให้กับ YAML
  • Kubelets ทำการเปลี่ยนแปลงทรัพยากรภายนอก (พูด Docker)

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

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

ผู้ประกอบการเชลล์

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

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

ตัวอย่างง่ายๆ: การคัดลอกความลับ

ลองดูตัวอย่างง่ายๆ

สมมติว่าเรามีคลัสเตอร์ Kubernetes มันมีเนมสเปซ default พร้อมความลับบางอย่าง mysecret. นอกจากนี้ ยังมีเนมสเปซอื่นๆ ในคลัสเตอร์อีกด้วย บางส่วนมีป้ายกำกับเฉพาะติดอยู่ด้วย เป้าหมายของเราคือการคัดลอก Secret ลงในเนมสเปซด้วยป้ายกำกับ

งานมีความซับซ้อนเนื่องจากเนมสเปซใหม่อาจปรากฏในคลัสเตอร์และบางส่วนอาจมีป้ายกำกับนี้ ในทางกลับกัน เมื่อลบป้ายกำกับแล้ว ข้อมูลลับก็ควรถูกลบไปด้วย นอกจากนี้ ข้อมูลลับยังสามารถเปลี่ยนแปลงได้: ในกรณีนี้ ข้อมูลลับใหม่จะต้องถูกคัดลอกไปยังเนมสเปซทั้งหมดที่มีป้ายกำกับ หาก Secret ถูกลบในเนมสเปซใดๆ โดยไม่ได้ตั้งใจ โอเปอเรเตอร์ของเราควรกู้คืนทันที

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

วิธีการทำงานของตัวดำเนินการเชลล์

เช่นเดียวกับปริมาณงานอื่นๆ ใน Kubernetes ตัวดำเนินการเชลล์จะทำงานในพ็อดของตัวเอง ในพ็อดนี้ในไดเร็กทอรี /hooks ไฟล์ปฏิบัติการจะถูกจัดเก็บ สิ่งเหล่านี้อาจเป็นสคริปต์ใน Bash, Python, Ruby ฯลฯ เราเรียกไฟล์ปฏิบัติการดังกล่าวว่า hooks (ตะขอ).

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

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

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

Shell-Operator รู้ได้อย่างไรว่า hook ใดที่จะรันและเมื่อใด? ประเด็นก็คือตะขอทุกอันมีสองขั้นตอน ในระหว่างการเริ่มต้น ตัวดำเนินการเชลล์จะรัน hooks ทั้งหมดพร้อมอาร์กิวเมนต์ --config นี่คือขั้นตอนการกำหนดค่า และหลังจากนั้น hooks จะถูกปล่อยในลักษณะปกติ - เพื่อตอบสนองต่อเหตุการณ์ที่ติดอยู่ ในกรณีหลัง hook ได้รับบริบทการผูก (บริบทที่มีผลผูกพัน) - ข้อมูลในรูปแบบ JSON ซึ่งเราจะพูดถึงรายละเอียดเพิ่มเติมด้านล่าง

สร้างโอเปอเรเตอร์ใน Bash

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

  • สิ่งแรกจำเป็นสำหรับขั้นตอนการกำหนดค่า - จะแสดงบริบทการเชื่อมโยง
  • ส่วนที่สองประกอบด้วยตรรกะหลักของเบ็ด

#!/bin/bash

source /shell_lib.sh

function __config__() {
  cat << EOF
    configVersion: v1
    # BINDING CONFIGURATION
EOF
}

function __main__() {
  # THE LOGIC
}

hook::run "$@"

ขั้นตอนต่อไปคือการตัดสินใจว่าเราต้องการวัตถุอะไร ในกรณีของเรา เราต้องติดตาม:

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

สมัครสมาชิกแหล่งความลับ

การกำหนดค่าการเชื่อมโยงนั้นค่อนข้างง่าย เราระบุว่าเราสนใจ Secret ด้วยชื่อ mysecret ในเนมสเปซ default:

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

function __config__() {
  cat << EOF
    configVersion: v1
    kubernetes:
    - name: src_secret
      apiVersion: v1
      kind: Secret
      nameSelector:
        matchNames:
        - mysecret
      namespace:
        nameSelector:
          matchNames: ["default"]
      group: main
EOF

เป็นผลให้ฮุกจะถูกทริกเกอร์เมื่อความลับของแหล่งที่มาเปลี่ยนแปลง (src_secret) และรับบริบทการผูกต่อไปนี้:

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

อย่างที่คุณเห็น มันมีชื่อและวัตถุทั้งหมด

การติดตามเนมสเปซ

ตอนนี้คุณต้องสมัครสมาชิกเนมสเปซ เมื่อต้องการทำเช่นนี้ เราระบุการกำหนดค่าการผูกต่อไปนี้:

- name: namespaces
  group: main
  apiVersion: v1
  kind: Namespace
  jqFilter: |
    {
      namespace: .metadata.name,
      hasLabel: (
       .metadata.labels // {} |  
         contains({"secret": "yes"})
      )
    }
  group: main
  keepFullObjectsInMemory: false

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

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

มันมีอาร์เรย์ filterResults สำหรับแต่ละเนมสเปซในคลัสเตอร์ ตัวแปรบูลีน hasLabel บ่งชี้ว่ามีการแนบป้ายกำกับกับเนมสเปซที่กำหนดหรือไม่ ตัวเลือก keepFullObjectsInMemory: false แสดงว่าไม่จำเป็นต้องเก็บวัตถุที่สมบูรณ์ไว้ในหน่วยความจำ

ติดตามความลับของเป้าหมาย

เราสมัครรับข้อมูลลับทั้งหมดที่มีการระบุคำอธิบายประกอบ managed-secret: "yes" (นี่คือเป้าหมายของเรา dst_secrets):

- name: dst_secrets
  apiVersion: v1
  kind: Secret
  labelSelector:
    matchLabels:
      managed-secret: "yes"
  jqFilter: |
    {
      "namespace":
        .metadata.namespace,
      "resourceVersion":
        .metadata.annotations.resourceVersion
    }
  group: main
  keepFullObjectsInMemory: false

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

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

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

จากข้อมูลทั้งหมดนี้ สามารถพัฒนาอัลกอริธึมพื้นฐานได้ มันวนซ้ำเนมสเปซทั้งหมดและ:

  • ถ้า hasLabel เรื่อง true สำหรับเนมสเปซปัจจุบัน:
    • เปรียบเทียบความลับระดับโลกกับความลับในท้องถิ่น:
      • ถ้าเหมือนกันก็ไม่ทำอะไรเลย
      • หากแตกต่าง - ดำเนินการ kubectl replace หรือ create;
  • ถ้า hasLabel เรื่อง false สำหรับเนมสเปซปัจจุบัน:
    • ตรวจสอบให้แน่ใจว่า Secret ไม่ได้อยู่ในเนมสเปซที่กำหนด:
      • หากมีความลับในเครื่องอยู่ ให้ลบออกโดยใช้ kubectl delete;
      • หากตรวจไม่พบข้อมูลลับในเครื่อง ก็จะไม่ทำอะไรเลย

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

การใช้อัลกอริทึมใน Bash คุณสามารถดาวน์โหลดได้ในของเรา ที่เก็บพร้อมตัวอย่าง.

นั่นคือวิธีที่เราสามารถสร้างคอนโทรลเลอร์ Kubernetes ง่ายๆ โดยใช้การกำหนดค่า YAML 35 บรรทัดและโค้ด Bash ในจำนวนที่เท่ากัน! หน้าที่ของผู้ปฏิบัติงานเชลล์คือการเชื่อมโยงพวกมันเข้าด้วยกัน

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

ตัวอย่างที่ 1: การเปลี่ยนแปลง ConfigMap

มาดู Deployment ที่ประกอบด้วย 1 พ็อดกัน พ็อดใช้ ConfigMap เพื่อจัดเก็บการกำหนดค่าบางอย่าง เมื่อพ็อดถูกเปิดใช้งาน ConfigMap อยู่ในสถานะหนึ่ง (ขอเรียกว่าเวอร์ชัน XNUMX) ดังนั้น พ็อดทั้งหมดจึงใช้ ConfigMap เวอร์ชันเฉพาะนี้

ตอนนี้ สมมติว่า ConfigMap มีการเปลี่ยนแปลง (v.2) อย่างไรก็ตาม พ็อดจะใช้ ConfigMap เวอร์ชันก่อนหน้า (v.1):

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

ฉันจะทำให้พวกเขาเปลี่ยนไปใช้ ConfigMap (v.2) ใหม่ได้อย่างไร คำตอบนั้นง่าย: ใช้เทมเพลต มาเพิ่มคำอธิบายประกอบการตรวจสอบในส่วนนี้กัน template การกำหนดค่าการปรับใช้:

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

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

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

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

ตัวอย่างที่ 2: การทำงานกับคำจำกัดความทรัพยากรที่กำหนดเอง

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

apiVersion: example.com/v1alpha1
kind: MysqlDatabase
metadata:
  name: foo
  namespace: bar

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

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

ตัวอย่างที่ 3: การตรวจสอบเครือข่ายคลัสเตอร์

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

ก่อนอื่น คุณจะต้องสมัครสมาชิกโหนดก่อน ตัวดำเนินการเชลล์ต้องการชื่อและที่อยู่ IP ของแต่ละโหนด ด้วยความช่วยเหลือของพวกเขา เขาจะ ping โหนดเหล่านี้

configVersion: v1
kubernetes:
- name: nodes
  apiVersion: v1
  kind: Node
  jqFilter: |
    {
      name: .metadata.name,
      ip: (
       .status.addresses[] |  
        select(.type == "InternalIP") |
        .address
      )
    }
  group: main
  keepFullObjectsInMemory: false
  executeHookOnEvent: []
schedule:
- name: every_minute
  group: main
  crontab: "* * * * *"

พารามิเตอร์ executeHookOnEvent: [] ป้องกันไม่ให้ hook ทำงานเพื่อตอบสนองต่อเหตุการณ์ใดๆ (นั่นคือ เพื่อตอบสนองต่อการเปลี่ยนแปลง เพิ่ม และการลบโหนด) อย่างไรก็ตามเขา จะวิ่ง (และอัพเดตรายการโหนด) กำหนดเวลาแล้ว - ทุกนาทีตามที่สนามกำหนด schedule.

ตอนนี้คำถามเกิดขึ้น เราจะรู้ได้อย่างไรเกี่ยวกับปัญหาเช่นการสูญหายของแพ็คเก็ต? มาดูโค้ดกัน:

function __main__() {
  for i in $(seq 0 "$(context::jq -r '(.snapshots.nodes | length) - 1')"); do
    node_name="$(context::jq -r '.snapshots.nodes['"$i"'].filterResult.name')"
    node_ip="$(context::jq -r '.snapshots.nodes['"$i"'].filterResult.ip')"
    packets_lost=0
    if ! ping -c 1 "$node_ip" -t 1 ; then
      packets_lost=1
    fi
    cat >> "$METRICS_PATH" <<END
      {
        "name": "node_packets_lost",
        "add": $packets_lost,
        "labels": {
          "node": "$node_name"
        }
      }
END
  done
}

เราวนซ้ำรายการโหนด รับชื่อและที่อยู่ IP ของพวกเขา ping และส่งผลลัพธ์ไปยัง Prometheus ผู้ปฏิบัติงานเชลล์สามารถส่งออกหน่วยวัดไปยัง Prometheus ได้โดยบันทึกลงในไฟล์ที่อยู่ในเส้นทางที่ระบุในตัวแปรสภาพแวดล้อม $METRICS_PATH.

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

กลไกการเข้าคิว

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

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

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

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

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

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

คุณสามารถสร้างคิว/ฮุคและชุดค่าผสมต่างๆ ได้จำนวนเท่าใดก็ได้ ตัวอย่างเช่น หนึ่งคิวสามารถทำงานกับสอง hooks หรือในทางกลับกัน

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

สิ่งที่คุณต้องทำคือกำหนดค่าฟิลด์ให้เหมาะสม queue ในการกำหนดค่าการผูก หากไม่ได้ระบุชื่อคิว hook จะทำงานบนคิวเริ่มต้น (default). กลไกการจัดคิวนี้ช่วยให้คุณแก้ไขปัญหาการจัดการทรัพยากรทั้งหมดได้อย่างสมบูรณ์เมื่อทำงานกับ hooks

ข้อสรุป

เราได้อธิบายว่าตัวดำเนินการเชลล์คืออะไร แสดงให้เห็นว่าสามารถใช้ตัวดำเนินการดังกล่าวเพื่อสร้างตัวดำเนินการ Kubernetes ได้อย่างรวดเร็วและง่ายดายได้อย่างไร และยกตัวอย่างการใช้งานหลายตัวอย่าง

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

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

ไป? ทุบตี! พบกับผู้ดำเนินการเชลล์ (รีวิวและรายงานวิดีโอจาก KubeCon EU'2020)

วิดีโอและสไลด์

วิดีโอจากการแสดง (~23 นาที):


การนำเสนอรายงาน:

PS

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

ที่มา: will.com

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