توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

8 أبريل في المؤتمر سانت هاي لود++ 2019، كجزء من قسم "DevOps and Operations"، تم تقديم تقرير "توسيع واستكمال Kubernetes"، والذي شارك في إنشائه ثلاثة موظفين من شركة Flant. نتحدث فيه عن العديد من المواقف التي أردنا فيها توسيع قدرات Kubernetes واستكمالها، لكننا لم نجد لها حلاً جاهزًا وبسيطًا. لدينا الحلول اللازمة على شكل مشاريع مفتوحة المصدر، وهذا الخطاب مخصص لها أيضًا.

حسب التقاليد ، يسعدنا أن نقدم فيديو مع التقرير (50 دقيقة، أكثر إفادة بكثير من المقالة) والملخص الرئيسي في شكل نص. يذهب!

الأساسية والإضافات في K8s

يعمل Kubernetes على تغيير الصناعة وأساليب الإدارة التي تم تأسيسها منذ فترة طويلة:

  • بفضله التجريدات، لم نعد نعمل بمفاهيم مثل إعداد التكوين أو تشغيل أمر (Chef، Ansible...)، ولكننا نستخدم تجميع الحاويات والخدمات وما إلى ذلك.
  • يمكننا إعداد الطلبات دون التفكير في الفروق الدقيقة موقع محدد، والتي سيتم إطلاقها عليها: المعدن، سحابة أحد مقدمي الخدمة، إلخ.
  • مع K8s، لم يكن الوصول إليك أسهل من أي وقت مضى أفضل الممارسات بشأن تنظيم البنية التحتية: تقنيات القياس، والإصلاح الذاتي، والتسامح مع الأخطاء، وما إلى ذلك.

ومع ذلك، بالطبع، كل شيء ليس سلسًا جدًا: جلبت Kubernetes أيضًا تحدياتها الجديدة.

Kubernetes لا هو الجمع الذي يحل جميع مشاكل جميع المستخدمين. جوهر Kubernetes مسؤول فقط عن مجموعة من الحد الأدنى من الوظائف الضرورية الموجودة فيه كل تَجَمَّع:

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

يحدد جوهر Kubernetes مجموعة أساسية من الأوليات لتجميع الحاويات وإدارة حركة المرور وما إلى ذلك. تحدثنا عنهم بمزيد من التفصيل في تقرير منذ سنتين.

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

من ناحية أخرى، يوفر K8s فرصًا رائعة لتوسيع الوظائف المتاحة، والتي تساعد على إغلاق الوظائف الأخرى - محدد - احتياجات المستخدم. تقع مسؤولية الإضافات إلى Kubernetes على عاتق مسؤولي المجموعة، الذين يجب عليهم تثبيت وتكوين كل ما هو ضروري لجعل مجموعتهم "في الشكل الصحيح" [لحل مشاكلهم المحددة]. ما نوع هذه الإضافات؟ دعونا نلقي نظرة على بعض الأمثلة.

أمثلة على الإضافات

بعد تثبيت Kubernetes، قد نتفاجأ بأن الشبكة الضرورية جدًا لتفاعل القرون داخل العقدة وبين العقد لا تعمل من تلقاء نفسها. لا تضمن نواة Kubernetes الاتصالات الضرورية، بل تحدد الشبكة بدلاً من ذلك السطح البيني (CNI) للوظائف الإضافية التابعة لجهات خارجية. يجب علينا تثبيت إحدى هذه الوظائف الإضافية، والتي ستكون مسؤولة عن تكوين الشبكة.

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

ومن الأمثلة القريبة على ذلك حلول تخزين البيانات (القرص المحلي، جهاز حظر الشبكة، Ceph...). في البداية كانوا في القلب، ولكن مع ظهور سي أيس آئي يتغير الوضع إلى شيء مشابه لما تم وصفه بالفعل: الواجهة موجودة في Kubernetes، ويتم تنفيذها في وحدات الطرف الثالث.

تشمل الأمثلة الأخرى ما يلي:

  • دخول-وحدات التحكم (انظر مراجعتهم في مقالتنا الأخيرة).
  • مدير سيرت:

    توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

  • مشغلي هي فئة كاملة من الوظائف الإضافية (والتي تتضمن مدير الشهادات المذكور)، فهي تحدد العناصر الأولية ووحدات التحكم (وحدات التحكم). إن منطق عملهم محدود فقط بخيالنا ويسمح لنا بتحويل مكونات البنية التحتية الجاهزة (على سبيل المثال، نظام إدارة قواعد البيانات) إلى عناصر أولية، والتي يكون التعامل معها أسهل بكثير (مقارنة بمجموعة الحاويات وإعداداتها). تمت كتابة عدد كبير من المشغلين - حتى لو لم يكن الكثير منهم جاهزين للإنتاج بعد، فهي مسألة وقت فقط:

    توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

  • المقاييس - رسم توضيحي آخر لكيفية فصل Kubernetes للواجهة (Metrics API) عن التنفيذ (الوظائف الإضافية التابعة لجهات خارجية مثل محول Prometheus ووكيل مجموعة Datadog...).
  • إلى الرصد والإحصاءات، حيث لا تكون هناك حاجة في الممارسة العملية فقط بروميثيوس وجرافانا، ولكن أيضًا مقاييس حالة kube ومصدر العقدة وما إلى ذلك.

وهذه ليست قائمة كاملة بالإضافات... على سبيل المثال، في شركة Flant التي نقوم بتثبيتها حاليًا 29 اضافات (كلها تنشئ إجمالي 249 كائن Kubernetes). ببساطة، لا يمكننا أن نرى حياة الكتلة دون إضافات.

الأتمتة

تم تصميم المشغلين لأتمتة العمليات الروتينية التي نواجهها كل يوم. فيما يلي أمثلة واقعية يمكن أن تكون كتابة عامل التشغيل حلاً ممتازًا لها:

  1. يوجد سجل خاص (أي يتطلب تسجيل الدخول) يحتوي على صور للتطبيق. من المفترض أن يتم تعيين سر خاص لكل جراب يسمح بالمصادقة في السجل. مهمتنا هي التأكد من العثور على هذا السر في مساحة الاسم حتى تتمكن القرون من تنزيل الصور. يمكن أن يكون هناك الكثير من التطبيقات (كل منها يحتاج إلى سر)، ومن المفيد تحديث الأسرار نفسها بانتظام، لذلك يتم استبعاد خيار وضع الأسرار يدويًا. هذا هو المكان الذي يأتي فيه المشغل للإنقاذ: نقوم بإنشاء وحدة تحكم تنتظر ظهور مساحة الاسم، وبناءً على هذا الحدث، ستضيف سرًا إلى مساحة الاسم.
  2. السماح افتراضيًا بالوصول من البودات إلى الإنترنت محظور. لكن في بعض الأحيان قد يكون ذلك مطلوبًا: فمن المنطقي أن تعمل آلية إذن الوصول ببساطة، دون الحاجة إلى مهارات محددة، على سبيل المثال، من خلال وجود تسمية معينة في مساحة الاسم. كيف يمكن للمشغل مساعدتنا هنا؟ يتم إنشاء وحدة تحكم تنتظر ظهور التسمية في مساحة الاسم وتضيف السياسة المناسبة للوصول إلى الإنترنت.
  3. موقف مشابه: لنفترض أننا بحاجة إلى إضافة شيء معين تلوث، إذا كان يحتوي على تسمية مشابهة (مع نوع من البادئة). التصرفات مع المشغل واضحة...

في أي مجموعة، يجب حل المهام الروتينية، و بشكل صحيح يمكن القيام بذلك باستخدام عوامل التشغيل.

بتلخيص كل القصص الموصوفة، توصلنا إلى استنتاج مفاده أن للعمل المريح في Kubernetes الذي تحتاجه: أ) تثبيت الإضافات، ب) تطوير المشغلين (لحل المهام الإدارية اليومية).

كيف تكتب بيانًا لـ Kubernetes؟

بشكل عام، المخطط بسيط:

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

...ولكن بعد ذلك اتضح أن:

  • تعد واجهة برمجة تطبيقات Kubernetes أمرًا غير تافه إلى حد ما ويستغرق إتقانه الكثير من الوقت؛
  • البرمجة أيضًا ليست للجميع (تم اختيار لغة Go كلغة مفضلة لوجود إطار خاص لها - مشغل SDK);
  • الوضع مشابه للإطار نفسه.

وخلاصة القول: لكتابة وحدة تحكم (المشغل) عليه إنفاق موارد كبيرة لدراسة المواد. سيكون هذا مبررًا بالنسبة للمشغلين "الكبار" - على سبيل المثال، لنظام MySQL DBMS. لكن إذا تذكرنا الأمثلة الموضحة أعلاه (كشف الأسرار، الوصول إلى البودات على الإنترنت...)، والتي نريد أيضًا القيام بها بشكل صحيح، فسنفهم أن الجهد المبذول سيفوق النتيجة التي نحتاجها الآن:

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

بشكل عام، تنشأ معضلة: إنفاق الكثير من الموارد والعثور على الأداة المناسبة لكتابة البيانات، أو القيام بذلك بالطريقة القديمة (ولكن بسرعة). لحلها - لإيجاد حل وسط بين هذين النقيضين - أنشأنا مشروعنا الخاص: مشغل القشرة (انظر أيضا له الإعلان الأخير على المحور).

مشغل شل

كيف يعمل؟ تحتوي المجموعة على جراب يحتوي على Go ثنائي مع مشغل Shell. بجانبه مجموعة من خطافات (مزيد من التفاصيل عنها - انظر أدناه). مشغل الصدفة نفسه يشترك في بعض أحداث في Kubernetes API، وعند حدوث ذلك يتم تشغيل الخطافات المقابلة.

كيف يعرف مشغل الصدفة الخطافات التي يجب الاتصال بها في أي الأحداث؟ يتم نقل هذه المعلومات إلى مشغل الصدفة عن طريق الخطافات نفسها، ويقومون بذلك بكل بساطة.

الخطاف هو برنامج نصي Bash أو أي ملف قابل للتنفيذ يقبل وسيطة واحدة --config ويستجيب مع JSON. يحدد الأخير الكائنات التي تهمه وأي الأحداث (لهذه الكائنات) يجب الرد عليها:

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

سأوضح التنفيذ على مشغل الصدفة لأحد الأمثلة لدينا - تحليل الأسرار للوصول إلى السجل الخاص باستخدام صور التطبيق. وهو يتألف من مرحلتين.

الممارسة: 1. اكتب خطافًا

بادئ ذي بدء، في الخطاف سنقوم بمعالجة --config، مما يشير إلى أننا مهتمون بمساحات الأسماء، وتحديدًا لحظة إنشائها:

[[ $1 == "--config" ]] ; then
  cat << EOF
{
  "onKubernetesEvent": [
    {
      "kind": "namespace",
      "event": ["add"]
    }
  ]
}
EOF
…

كيف سيبدو المنطق؟ أيضًا بسيط جدًا:

…
else
  createdNamespace=$(jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH)
  kubectl create -n ${createdNamespace} -f - << EOF
Kind: Secret
...
EOF
fi

الخطوة الأولى هي معرفة مساحة الاسم التي تم إنشاؤها، والثانية هي إنشائها باستخدام kubectl سر لمساحة الاسم هذه.

الممارسة: 2. تجميع الصورة

كل ما تبقى هو تمرير الخطاف الذي تم إنشاؤه إلى مشغل الصدفة - كيف يتم ذلك؟ يأتي مشغل الصدفة نفسه كصورة Docker، لذا فإن مهمتنا هي إضافة الخطاف إلى دليل خاص في هذه الصورة:

FROM flant/shell-operator:v1.0.0-beta.1
ADD my-handler.sh /hooks

كل ما تبقى هو تجميعه ودفعه:

$ docker build -t registry.example.com/my-operator:v1 .
$ docker push registry.example.com/my-operator:v1

اللمسة الأخيرة هي نشر الصورة على المجموعة. للقيام بذلك، دعونا نكتب قابل للفتح:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-operator
spec:
  template:
    spec:
      containers:
      - name: my-operator
        image: registry.example.com/my-operator:v1 # 1
      serviceAccountName: my-operator              # 2

هناك نقطتان يجب الانتباه إليهما:

  1. إشارة إلى الصورة التي تم إنشاؤها حديثا؛
  2. هذا أحد مكونات النظام الذي يحتاج (على الأقل) إلى حقوق الاشتراك في الأحداث في Kubernetes وتخصيص الأسرار لمساحات الأسماء، لذلك نقوم بإنشاء حساب خدمة (ومجموعة من القواعد) للربط.

النتيجة - لقد حللنا مشكلتنا الأقارب لـ Kubernetes بطريقة تخلق عاملاً لتحليل الأسرار.

ميزات مشغل الصدفة الأخرى

للحد من الكائنات من النوع الذي اخترته والذي سيعمل الخطاف معه، يمكن تصفيتهاأو الاختيار وفقًا لتسميات معينة (أو استخدام matchExpressions):

"onKubernetesEvent": [
  {
    "selector": {
      "matchLabels": {
        "foo": "bar",
       },
       "matchExpressions": [
         {
           "key": "allow",
           "operation": "In",
           "values": ["wan", "warehouse"],
         },
       ],
     }
     …
  }
]

متاح آلية إلغاء البيانات المكررة، والذي - باستخدام مرشح jq - يسمح لك بتحويل كائنات JSON الكبيرة إلى كائنات صغيرة، حيث تبقى فقط تلك المعلمات التي نريد مراقبتها بحثًا عن التغييرات.

عندما يتم استدعاء الخطاف، يقوم مشغل الصدفة بتمريره بيانات الكائن، والتي يمكن استخدامها لأي حاجة.

لا تقتصر الأحداث التي تؤدي إلى تشغيل الخطافات على أحداث Kubernetes: يوفر مشغل الصدفة الدعم لها استدعاء الخطافات حسب الوقت (على غرار crontab في المجدول التقليدي)، بالإضافة إلى حدث خاص بطريق الانطلاق. يمكن دمج كل هذه الأحداث وتخصيصها لنفس الخطاف.

وميزتان أخريان لمشغل الصدفة:

  1. إنها تعمل بشكل غير متزامن. منذ تلقي حدث Kubernetes (مثل كائن يتم إنشاؤه)، فمن الممكن أن تحدث أحداث أخرى (مثل نفس الكائن الذي يتم حذفه) في المجموعة، وتحتاج الخطافات إلى مراعاة ذلك. إذا تم تنفيذ الخطاف مع وجود خطأ، فسيكون كذلك بشكل افتراضي يتذكر حتى الانتهاء بنجاح (يمكن تغيير هذا السلوك).
  2. انها تصدر المقاييس بالنسبة إلى Prometheus، الذي يمكنك من خلاله فهم ما إذا كان مشغل الصدفة يعمل أم لا، اكتشف عدد الأخطاء لكل خطاف وحجم قائمة الانتظار الحالية.

لتلخيص هذا الجزء من التقرير:

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

تثبيت الإضافات

للعمل المريح مع Kubernetes، تم ذكر الحاجة إلى تثبيت الوظائف الإضافية. سأخبرك بذلك باستخدام مثال مسار شركتنا لكيفية القيام بذلك الآن.

لقد بدأنا العمل مع Kubernetes مع عدة مجموعات، وكانت الإضافة الوحيدة إليها هي Ingress. كان من الضروري تثبيته بشكل مختلف في كل مجموعة، وقمنا بإجراء العديد من تكوينات YAML لبيئات مختلفة: المعدن، AWS...

وبما أن هناك المزيد من المجموعات، كان هناك المزيد من التكوينات. بالإضافة إلى ذلك، قمنا بتحسين هذه التكوينات نفسها، ونتيجة لذلك أصبحت غير متجانسة تمامًا:

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

لترتيب كل شيء، بدأنا بالبرنامج النصي (install-ingress.sh)، والتي اتخذت كوسيطة نوع المجموعة التي سننشرها، وأنشأت تكوين YAML الضروري ونشره على Kubernetes.

باختصار، كان طريقنا الإضافي والمنطق المرتبط به كما يلي:

  • للعمل مع تكوينات YAML، يلزم وجود محرك قالب (في المراحل الأولى، يكون هذا أمرًا بسيطًا)؛
  • مع زيادة عدد المجموعات، ظهرت الحاجة إلى التحديث التلقائي (كان الحل الأول هو وضع البرنامج النصي في Git، وتحديثه باستخدام cron وتشغيله)؛
  • مطلوب نص مماثل لبروميثيوس (install-prometheus.sh)، ومع ذلك، فمن الجدير بالملاحظة أنه يتطلب المزيد من بيانات الإدخال، بالإضافة إلى تخزينها (بطريقة جيدة - مركزية وفي مجموعة)، ويمكن إنشاء بعض البيانات (كلمات المرور) تلقائيًا:

    توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

  • كان خطر طرح شيء خاطئ لعدد متزايد من المجموعات يتزايد باستمرار، لذلك أدركنا أن القائمين على التثبيت (أي نصين: لـ Ingress و Prometheus) كانت هناك حاجة إلى التدريج (عدة فروع في Git، والعديد من crons لتحديثها في مجموعات مستقرة أو مجموعات اختبارية)؛
  • с kubectl apply لقد أصبح من الصعب العمل معه لأنه ليس تصريحيًا ويمكنه فقط إنشاء كائنات، ولكن لا يمكن اتخاذ قرارات بشأن حالتها/حذفها؛
  • لقد افتقدنا بعض الوظائف التي لم ننفذها على الإطلاق في ذلك الوقت:
    • السيطرة الكاملة على نتيجة تحديثات المجموعة،
    • التحديد التلقائي لبعض المعلمات (الإدخال لنصوص التثبيت) بناءً على البيانات التي يمكن الحصول عليها من المجموعة (الاكتشاف)،
    • تطورها المنطقي في شكل اكتشاف مستمر.

قمنا بتنفيذ كل هذه الخبرة المتراكمة في إطار مشروعنا الآخر - عامل إضافي.

عامل إضافي

إنه يعتمد على مشغل الصدفة الذي سبق ذكره. النظام بأكمله يبدو مثل هذا:

تتم إضافة ما يلي إلى خطافات مشغل الصدفة:

  • تخزين القيم,
  • مخطط الخوذة,
  • مكون ذلك يراقب مخزن القيم و- في حالة حدوث أي تغييرات - يطلب من Helm إعادة تشغيل المخطط.

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

وبالتالي، يمكننا الرد على حدث ما في Kubernetes، وإطلاق خطاف، ومن هذا الخطاف إجراء تغييرات على مساحة التخزين، وبعد ذلك سيتم إعادة تنزيل المخطط. في الرسم البياني الناتج، نقوم بفصل مجموعة الخطافات والمخطط إلى مكون واحد، وهو ما نطلق عليه اسم وحدة:

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

يمكن أن يكون هناك العديد من الوحدات، ونضيف إليها خطافات عالمية ومخزن قيم عالمي ومكونًا يراقب هذا المتجر العالمي.

الآن، عندما يحدث شيء ما في Kubernetes، يمكننا الرد عليه باستخدام خطاف عالمي وتغيير شيء ما في المتجر العالمي. ستتم ملاحظة هذا التغيير وسيؤدي إلى طرح كافة الوحدات الموجودة في المجموعة:

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

يلبي هذا المخطط جميع متطلبات تثبيت الوظائف الإضافية المذكورة أعلاه:

  • هيلم هو المسؤول عن القوالب والتصريح.
  • تم حل مشكلة التحديث التلقائي باستخدام خطاف عام، والذي ينتقل إلى السجل وفقًا لجدول زمني، وإذا رأى صورة نظام جديدة هناك، يقوم بطرحها (أي "نفسها").
  • يتم تنفيذ إعدادات التخزين في المجموعة باستخدام خريطة التكوينالذي يحتوي على البيانات الأساسية للمخازن (عند بدء التشغيل يتم تحميلها في المخازن).
  • تم حل مشاكل إنشاء كلمة المرور واكتشافها واكتشافها المستمر باستخدام الخطافات.
  • يتم تحقيق التدريج بفضل العلامات التي يدعمها Docker خارج الصندوق.
  • تتم مراقبة النتيجة باستخدام المقاييس التي يمكننا من خلالها فهم الحالة.

يتم تنفيذ هذا النظام بأكمله في شكل ثنائي واحد في Go، يسمى عامل التشغيل الإضافي. وهذا يجعل الرسم البياني يبدو أبسط:

توسيع واستكمال Kubernetes (نظرة عامة وتقرير فيديو)

المكون الرئيسي في هذا المخطط هو مجموعة من الوحدات (مظللة باللون الرمادي أدناه). الآن يمكننا كتابة وحدة للإضافة المطلوبة بقليل من الجهد والتأكد من تثبيتها في كل مجموعة، وسيتم تحديثها والاستجابة للأحداث التي تحتاجها في المجموعة.

استخدامات "فلانت". عامل إضافي على 70+ مجموعات Kubernetes. الحالة الحالية - نسخة ألفا. نقوم الآن بإعداد الوثائق لإصدار النسخة التجريبية، ولكن في الوقت الحالي في المستودع الأمثلة المتاحة، وعلى أساسه يمكنك إنشاء الملحق الخاص بك.

أين يمكنني الحصول على الوحدات النمطية لمشغل الوظيفة الإضافية؟ إن نشر مكتبتنا هو المرحلة التالية بالنسبة لنا، ونحن نخطط للقيام بذلك في الصيف.

مقاطع الفيديو والشرائح

فيديو من العرض (50 دقيقة تقريبًا):

عرض التقرير:

PS

تقارير أخرى على مدونتنا:

قد تكون مهتمًا أيضًا بالمنشورات التالية:

المصدر: www.habr.com

إضافة تعليق