مدير الحزم لـ Kubernetes - Helm: الماضي والحاضر والمستقبل

ملاحظة perev. : في هذه المقالة نفتح سلسلة من المنشورات حول مدير الحزم لـ Kubernetes ، والتي نستخدمها بنشاط في العمل اليومي ، - Helm. المؤلف الأصلي لهذه المادة هو مات باتشر ، أحد مؤسسي مشروع هيلم ، الذي يعمل على مشاريع مفتوحة المصدر في مايكروسوفت ويكتب 8 كتب فنية (على وجه الخصوص ، "اذهب في الممارسة"). ومع ذلك ، يتم استكمال المقالة بتعليقاتنا (المكثفة في بعض الأحيان) ، وسيتم توسيعها قريبًا بملاحظات جديدة حول Helm مع تركيز عملي أكثر. تحديث (09/03/2018): ظهرت التكملة - " التعارف العملي مع مدير الحزم لـ Kubernetes - Helm ".



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

تاريخ موجز هيلم


ظهر هيلم في الأصل كمشروع Deis مفتوح المصدر. تم تصميمه على غرار Homebrew (مدير الحزم لنظام macOS - Translations تقريبًا ) ، وكانت مهمة Helm 1 فرصة سهلة للمستخدمين لتثبيت أحمال عملهم الأولى بسرعة على Kubernetes. تم الإعلان الرسمي عن Helm في مؤتمر KubeCon San Francisco الأول في عام 2015.

ملاحظة عبر: من الإصدار الأول ، الذي كان يسمى dm (مدير النشر) ، تم اختيار بناء جملة YAML لوصف موارد Kubernetes ، وتم دعم قوالب Jinja ونصوص Python النصية عند كتابة التكوينات.

قد يبدو قالب تطبيق الويب البسيط كما يلي:

Yaml
resources: - name: frontend type: github.com/kubernetes/application-dm-templates/common/replicatedservice:v1 properties: service_port: 80 container_port: 80 external_service: true replicas: 3 image: gcr.io/google_containers/example-guestbook-php-redis:v3 - name: redis type: github.com/kubernetes/application-dm-templates/storage/redis:v1 properties: null 

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

بالفعل في هذا الإصدار ، يمكنك استخدام الموارد من قاعدة معارف مشتركة ، وإنشاء مستودعات القوالب الخاصة بك وبناء تطبيقات معقدة بسبب المعلمات وتداخل القوالب.

تتكون هندسة Helm 1 من ثلاثة مكونات. يوضح الرسم البياني التالي العلاقة بينهما:



  1. يقوم Manager بوظيفة خادم الويب (يحدث التواصل مع العملاء عبر REST API) ، ويدير عمليات النشر في مجموعة Kubernetes ويستخدم كمخزن للبيانات.
  2. يجلب المكون expandybird تكوينات المستخدم إلى شكل مسطح ، أي يطبق قوالب جينجا وينفذ نصوص بايثون.
  3. بعد تلقي تكوين مسطح ، يقوم مورد resourcifier بإجراء المكالمات اللازمة إلى kubectl وإرجاع رسائل الحالة ورسائل الخطأ ، إن وجدت ، إلى manager .

لفهم إمكانيات الإصدار الأول من Helm ، سأقدم المساعدة في الأمر dm :
مساعدة الإخراج من DM
 Usage: ./dm [<flags>] <command> [(<template-name> | <deployment-name> | (<configuration> [<import1>...<importN>]))] Commands: expand Expands the supplied configuration(s) deploy Deploys the named template or the supplied configuration(s) list Lists the deployments in the cluster get Retrieves the supplied deployment manifest Lists manifests for deployment or retrieves the supplied manifest in the form (deployment[/manifest]) delete Deletes the supplied deployment update Updates a deployment using the supplied configuration(s) deployed-types Lists the types deployed in the cluster deployed-instances Lists the instances of the named type deployed in the cluster templates Lists the templates in a given template registry (specified with --registry) registries Lists the registries available describe Describes the named template in a given template registry getcredential Gets the named credential used by a registry setcredential Sets a credential used by a registry createregistry Creates a registry that holds charts Flags: -apitoken string Github api token that overrides GITHUB_API_TOKEN environment variable -binary string Path to template expansion binary (default "../expandybird/expansion/expansion.py") -httptest.serve string if non-empty, httptest.NewServer serves on this address and blocks -name string Name of deployment, used for deploy and update commands (defaults to template name) -password string Github password that overrides GITHUB_PASSWORD environment variable -properties string Properties to use when deploying a template (eg, --properties k1=v1,k2=v2) -regex string Regular expression to filter the templates listed in a template registry -registry string Registry name (default "application-dm-templates") -registryfile string File containing registry specification -service string URL for deployment manager (default "http://localhost:8001/api/v1/proxy/namespaces/dm/services/manager-service:manager") -serviceaccount string Service account file containing JWT token -stdin Reads a configuration from the standard input -timeout int Time in seconds to wait for response (default 20) -username string Github user name that overrides GITHUB_USERNAME environment variable --stdin requires a file name and either the file contents or a tar archive containing the named file. a tar archive may include any additional files referenced directly or indirectly by the named file. 

والآن نعود إلى النص الأصلي حول تاريخ هيلم ...

بعد بضعة أشهر ، انضممنا إلى فريق Kubernetes Deployment Manager من Google وبدأنا العمل في Helm 2. وكان الهدف هو إبقاء Helm سهل الاستخدام بإضافة ما يلي:

  1. قوالب المخططات ("مخطط" - نظير لحزمة في نظام هيلم البيئي - ترجمة تقريبًا ) للتخصيص ؛
  2. إدارة المجموعات للفرق ؛
  3. مستودع مخطط كامل
  4. تنسيق حزمة مستقرة وموقعة ؛
  5. التزام قوي بالإصدار الدلالي والحفاظ على التوافق العكسي من إصدار إلى آخر.

لتحقيق هذه الأهداف ، تمت إضافة مكون ثانٍ إلى النظام البيئي Helm. أصبحت المجموعة الداخلية تيلر ، والتي قدمت تركيب خرائط هيلم وإدارتها.

ملاحظة perev. وبالتالي ، في الإصدار الثاني من Helm ، يكون المكون الوحيد المتبقي في المجموعة مسؤولاً عن دورة حياة التثبيت ( الإصدار ) ، ويتم إرسال إعداد التكوين إلى عميل Helm.

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

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

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

تحياتي لوا


في Helm 2 ، قدمنا ​​قوالب. في المرحلة المبكرة من تطوير Helm 2 ، دعمنا قوالب Go و Jinja ورمز Python النظيف ، وكان لدينا حتى نموذج أولي لدعم ksonnet. لكن وجود العديد من محركات القوالب أدى إلى مشاكل أكثر مما تم حلها. لذلك ، وصلنا إلى نقطة اختيار واحد.

تتميز قوالب Go بأربع مزايا:

  1. تم بناء المكتبة في Go .
  2. يتم تنفيذ القوالب في بيئة رمل محدودة للغاية ؛
  3. يمكننا إدراج وظائف وأشياء تعسفية في المحرك ؛
  4. عملوا بشكل جيد مع YAML.

على الرغم من أننا احتفظنا بالواجهة في Helm لدعم محركات القوالب الأخرى ، أصبحت قوالب Go معيارنا الافتراضي. وأظهرت السنوات القليلة القادمة من الخبرة كيف أن المهندسين من العديد من الشركات قاموا بإنشاء آلاف الرسوم البيانية باستخدام قوالب Go.

وتعلمنا عن خيبات أملهم:

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

الأهم من ذلك ، باستخدام لغة القالب ، قمنا "باقتطاع" كائنات Kubernetes لتمثيل خطها. (بعبارة أخرى ، كان على مطوري النماذج إدارة موارد Kubernetes كمستندات نصية بتنسيق YAML.)

اعمل على الأشياء وليس قطع YAML


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

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

في عام 1993 ، أنشأت مجموعة من مهندسي تكنولوجيا المعلومات البرازيليين لغة برمجة خفيفة الوزن للتضمين في أدواتهم. تحتوي Lua على بنية بسيطة ، وهي مدعومة على نطاق واسع وظهرت في قائمة أفضل 20 لغة لفترة طويلة. وهو مدعوم من قبل IDE ومحرري النصوص ، وهناك العديد من الكتيبات والبرامج التعليمية. في مثل هذا النظام البيئي الحالي ، نود تطوير حلنا.

لا يزال عملنا في Helm Lua في مرحلة الإثبات المفاهيمي ، ونتوقع بناء جملة مألوف ومرن. بمقارنة النهجين القديم والجديد ، يمكنك أن ترى أين نتجه.

فيما يلي مثال على قالب الموقد مع Alpine في Helm 2:

 apiVersion: v1 kind: Pod metadata: name: {{ template "alpine.fullname" . }} labels: heritage: {{ .Release.Service }} release: {{ .Release.Name }} chart: {{ .Chart.Name }}-{{ .Chart.Version }} app: {{ template "alpine.name" . }} spec: restartPolicy: {{ .Values.restartPolicy }} containers: - name: waiter image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} command: ["/bin/sleep", "9000"] 

في هذا النموذج {{ .Chart.Name }} ، يمكنك أن ترى على الفور جميع توجيهات القالب المضمنة ، مثل {{ .Chart.Name }} .

وإليك تعريف الموقد نفسه في النسخة الأولية من قانون لوا:

 unction create_alpine_pod(_) local pod = { apiVersion = "v1", kind = "Pod", metadata = { name = alpine_fullname(_), labels = { heritage = _.Release.Service or "helm", release = _.Release.Name, chart = _.Chart.Name .. "-" .. _.Chart.Version, app = alpine_name(_) } }, spec = { restartPolicy = _.Values.restartPolicy, containers = { { name = waiter, image = _.Values.image.repository .. ":" .. _.Values.image.tag, imagePullPolicy = _.Values.image.pullPolicy, command = { "/bin/sleep", "9000" } } } } } _.resources.add(pod) end 

ليست هناك حاجة للنظر في كل سطر من هذا المثال لفهم ما يحدث. من الواضح على الفور أنه في التعليمات البرمجية يتم تعريفه تحت. ولكن بدلاً من استخدام سلاسل YAML مع توجيهات القالب المضمنة ، فإننا نعرّفها ككائن في Lua.

دعونا نختصر هذا الرمز


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

 local pods = require("mylib.pods"); function create_alpine_pod(_) myPod = pods.new("alpine:3.7", _) myPod.spec.restartPolicy = "Always" -- set any other properties _.Manifests.add(myPod) end 

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

قوالب ... لوا ... لماذا لا نجمعها معًا؟


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

بدلاً من ذلك ، نريد السماح باستخدام كل من القوالب ولوا في نفس الوقت. سيتمكن نصوص Lua من الوصول إلى قوالب Helm قبل وبعد عرضها ، مما سيسمح لمطوري المخططات المتقدمة بإجراء تحويلات معقدة على الرسوم البيانية الحالية ، مع الاحتفاظ بالقدرة البسيطة على إنشاء مخططات Helm باستخدام القوالب.

يشجعنا للغاية دعم النصوص على Lua ، ولكن في نفس الوقت نتخلص من جزء كبير من هندسة Helm ...

وداعا لتيلير


أثناء تطوير Helm 2 ، قدمنا ​​Tiller كعنصر تكامل مع مدير النشر. لعب Tiller دورًا مهمًا للفرق التي تعمل على نفس المجموعة: فقد جعل من الممكن التفاعل مع نفس مجموعة الإصدارات للعديد من المسؤولين المختلفين.

ومع ذلك ، عمل Tiller كخادم sudo عملاق ، مما يمنح مجموعة واسعة من الحقوق لكل من لديه حق الوصول إلى Tiller. وكان نظام التثبيت الافتراضي الخاص بنا هو التكوين المسموح به. لذلك ، كان على مهندسي DevOps و SRE تعلم الخطوات الإضافية لتثبيت Tiller في مجموعات متعددة المستأجرين.

علاوة على ذلك ، مع ظهور CRD ، لم يعد بإمكاننا الاعتماد بشكل موثوق على Tiller للحفاظ على الحالة أو العمل كمحور مركزي لمعلومات إصدار Helm. يمكننا فقط تخزين هذه المعلومات كإدخالات منفصلة في Kubernetes.

يمكن تحقيق الهدف الرئيسي من تيلر دون تيلر نفسه. لذلك ، كان أحد القرارات الأولى التي تم اتخاذها خلال مرحلة تخطيط Helm 3 هو التخلي تمامًا عن Tiller.

تحسين الأمان


بدون Tiller ، تم تبسيط نموذج الأمان Helm بشكل جذري. يتم تفويض مصادقة المستخدم من قبل Kubernetes. والتفويض أيضا. تُعرف حقوق Helm بأنها حقوق Kubernetes (عبر RBAC) ، ويمكن لمسؤولي المجموعات تقييد حقوق Helm بأي مستوى مطلوب من التفاصيل.

الإصدارات ، إصدارات الإصدار ، وتخزين الدولة


في حالة عدم وجود Tiller ، للحفاظ على حالة الإصدارات المختلفة داخل المجموعة ، نحتاج إلى طريقة جديدة لجميع العملاء للتفاعل (في إدارة الإصدار).

للقيام بذلك ، قدمنا ​​إدخالين جديدين:

  1. Release - لتثبيت معين لمخطط معين. إذا قمنا بتشغيل helm install my-wordpress stable/wordpress ، فسيتم إنشاء إصدار يسمى my-wordpress والحفاظ عليه طوال فترة تثبيت WordPress هذا.
  2. ReleaseVersion - في كل مرة تقوم فيها بتحديث مخطط Helm ، تحتاج إلى النظر في ما تغير وما إذا كان التغيير ناجحًا. ReleaseVersion مرتبط بإصدار ولا يخزن إلا السجلات التي تحتوي على معلومات حول التحديث والتراجع والحذف. عندما نقوم بتشغيل helm upgrade my-wordpress stable/wordpress ، يظل كائن Release الأصلي كما هو ، ولكن ReleaseVersion كائن ReleaseVersion بمعلومات حول عملية التحديث.

سيتم تخزين Releases ReleaseVersions في نفس مساحات الأسماء مثل كائنات المخطط.

باستخدام هذه الميزات ، ستتمكن فرق مستخدمي Helm من تتبع سجلات منشآت Helm في المجموعة دون الحاجة إلى Tiller.

لكن انتظر ، هذا ليس كل شيء!


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

ملاحظة perev. : إنها مفارقة ، ولكن مدير حزم Helm 2 ، عندما يكون install أو upgrade ناجحًا ، أي لا يضمن وجود إصدار في حالة success أن موارد التطبيق قد تم طرحها بنجاح (على سبيل المثال ، لا توجد أخطاء مثل ImagePullError ). ربما يسمح لك نموذج الحدث الجديد بإضافة خطافات إضافية للموارد والتحكم بشكل أفضل في عملية الطرح - سنكتشف ذلك قريبًا.

مع انضمام Helm إلى CNCF ، ليس فقط Helm 3 مصدر إلهام لنا ، ولكن أيضًا متحف Chart ، وأداة اختبار المخططات الرائعة ، ومستودع المخططات الرسمي والمشاريع الأخرى تحت رعاية Helm في CNCF. نحن واثقون من أن إدارة الحزم الجيدة لـ Kubernetes لا تقل أهمية للنظام البيئي السحابي الأصلي مثل مديري الحزم الجيدين لنظام Linux.

ملاحظة من المترجم


اقرأ أيضا في مدونتنا:

Source: https://habr.com/ru/post/ar417079/


All Articles