الوصول إلى النجوم: إتقان عوامل التشغيل غير المرئية لإدارة التطبيقات في Kubernetes

سنرى كيفية استخدام الأدوار المنشورة في Ansible Galaxy كمشغلين يديرون التطبيقات في Kubernetes ، ولننظر في كيفية إنشاء مشغل يقوم ببساطة بتثبيت التطبيق وضبط سلوكه بمرونة حسب البيئة.



سنستخدم Ansible Operator ووحدة k8s لإظهار كيفية استخدام Ansible لإنشاء تطبيقات Kubernetes.

يعد Ansible Operator جزءًا من SDK للمشغل ويسمح لك بصياغة اللوائح التشغيلية للتطبيق (كيفية تثبيته وصيانته) بلغة الأدوار وكتب التشغيل Ansible. وحدة k8s ، بدورها ، توسع القدرة على إدارة الأشياء في Kubernetes عند إنشاء هذه الأدوار وكتب اللعب.

يتم إنشاء عامل مثل هذا تماما.

FROM quay.io/operator-framework/ansible-operator RUN ansible-galaxy install djzager.hello_world_k8s RUN echo $'--- \n\ - version: v1alpha1\n\ group: examples.djzager.io\n\ kind: HelloWorld\n\ role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml 

مفتاح البدء


أولاً ، بضع كلمات حول وحدة Ansible k8s . ظهرت في Ansible 2.6 وتوسّع إمكانيات العمل مع كائنات Kubernetes من Ansible ، وفي أي توزيعات Kubernetes ، بما في ذلك Red Hat OpenShift. مدونة Ansible لها منشور منفصل عن هذه الوحدة وعميل Python الديناميكي لـ Red Hat OpenShift . في رأينا ، العمل مع كائنات Kubernetes عبر Ansible دون استخدام الوحدة النمطية k8s غير صحيح. تم إنشاء آلية المشغل في الأصل لتشغيل التطبيقات في Kubernetes ، ويوفر مشغل SDK أدوات للتجميع والاختبار وتعبئة مشغلي. بدوره ، هناك حاجة إلى مشغل Ansible من أجل وضع اللوائح التشغيلية للتطبيق بلغة Ansible. يتم تنظيم سير العمل المقابل بكل بساطة: أولاً ننفذ عامل التشغيل - sdk new - نوع = Ansible لإنشاء الملفات اللازمة لمشغل Ansible ، ثم نرسم Ansible ، وأخيراً نقوم ببناء مشغل sdk لإنشاء تطبيق للعمل في Kubernetes. ولكن إذا كان لدينا بالفعل دور في Ansible Galaxy ، الذي يتحكم في التطبيق في Kubernetes ، فإن الأمور تصبح أسهل. أدناه سنفعل ما يلي:

  1. لنقم ببناء دور Ansible لإدارة تطبيق Hello World في Kubernetes ، مما سيساعدنا في إظهار قدرات وحدة Ansible k8s.
  2. سننشر هذا الدور في Ansible Galaxy.

لذلك ، دعونا تجميع المشغل Ansible باستخدام الدور المنشور في Ansible Galaxy. لماذا حتى إنشاء مشغل باستخدام دور من Ansible Galaxy؟ هناك سببان:

  1. حتى لا تتكرر . إذا قمنا بالفعل ببرمجة دور Ansible لإدارة تطبيق Hello World ونشرناه في Ansible Galaxy ، فمن المنطقي استخدامه عند إنشاء مشغل Ansible.
  2. بسبب فصل المسؤوليات . نريد أن يقوم Hello World Ansible بإدارة تطبيق يحمل نفس الاسم في Kubernetes ، وأن يظل المنطق التشغيلي (التشغيلي) داخل المشغل. في مثالنا ، يكون المنطق التشغيلي بسيطًا للغاية: فهو ببساطة يستدعي دور djzager.hello_world_k8s في كل مرة تقوم فيها بإنشاء أو تعديل مورد HelloWorld مخصص. ومع ذلك ، في المستقبل سوف يصبح هذا الفصل أكثر أهمية ، على سبيل المثال ، سنضيف التحقق من الصحة إلى تطبيق Hello World من خلال دور Ansible ، وسننفذ التحكم في حالة الموارد المخصصة لـ HelloWorld من خلال منطق المشغل.

مرحبا Kubernetes ، وتلبية Ansible


ماذا نحتاج


  1. Ansible - راجع دليل التثبيت إذا لم يكن Ansible مثبتًا لديك.
  2. عميل Python لـ OpenShift (اختياري). هناك حاجة فقط لإطلاق المحلية. تعليمات التثبيت هنا .

لنبدأ. أولاً ، قم بإنشاء هيكل عظمي للأدوار باستخدام مجرة ​​غير مرئية:

 # I like clear names on projects. # In meta/main.yml I will make role_name: hello-world-k8s $ ansible-galaxy init ansible-role-hello-world-k8s 

مباشرة بعد إنشاء دور Ansible جديد ، سنقوم بتعيين جميع القيم الافتراضية لتوثيق معاملات التكوين الصالحة في نفس الوقت. علاوة على ذلك ، فإن مثال Hello World ليس معقدًا بشكل خاص في هذا الصدد. هذا ما يبدو عليه ملف الإعدادات الافتراضية / main.yml:

 --- # NOTE: meta.name(space) comes from CR metadata when run with Ansible Operator # deploy/crds has an example CR for reference name: "{{ meta.name | default('hello-world') }}" namespace: "{{ meta.namespace | default('hello-world') }}" image: docker.io/ansibleplaybookbundle/hello-world:latest # To uninstall from the cluster # state: absent state: present # The size of the hello-world deployment size: 1 

بعد تعيين القيم الافتراضية ، من الضروري تحديد الدور الذي ستقوم به. سيتعين على تطبيق Hello World القيام بما يلي:

  1. الحصول على معلومات حول واجهات برمجة التطبيقات المتوفرة في الكتلة.
  2. قم بإنشاء عدة قوالب وتأكد من وجودها أو تغيبها في الكتلة.

لذلك ، يبدو ملف المهام / main.yml لدينا كما يلي:

 --- - name: "Get information about the cluster" set_fact: api_groups: "{{ lookup('k8s', cluster_info='api_groups') }}" - name: 'Set hello-world objects state={{ state }}' k8s: state: '{{ state }}' definition: "{{ lookup('template', item.name) | from_yaml }}" when: item.api_exists | default(True) loop: - name: deployment.yml.j2 - name: service.yml.j2 - name: route.yml.j2 api_exists: "{{ True if 'route.openshift.io' in api_groups else False }}" 

قبل الانتقال إلى القوالب ، انتبه إلى هذا السطر في ملف المهمة:

 api_exists: "{{ True if 'route.openshift.io' in api_groups else False }}" 

باستخدام set_fact ، نحصل على قائمة بجميع واجهات برمجة التطبيقات المتوفرة في الكتلة حتى نتمكن من إنشاء قوالب بشكل انتقائي بناءً على ما إذا كانت واجهة برمجة التطبيقات موجودة - في هذه الحالة ، route.openshift.io. بشكل افتراضي ، في نظام Kubernetes من OpenShift ، لا تتوفر الطرق ، ونحن لا نحتاج إليها ، لذلك نحن نعمل فقط مع كائن Route عندما يكون هناك route.openshift.io في الكتلة.

لا يمكننا فقط إدارة الكائنات في المجموعة بشكل انتقائي اعتمادًا على توفر بعض واجهات برمجة التطبيقات ، ولكن أيضًا استخدام قوالب Jinja2 لاستخدام OpenShift DeploymentConfig في قالب النشر الخاص بنا إذا كانت المجموعة تحتوي على apps.openshift.io API. إليك ما يبدو عليه ملف القوالب / publish.yml.j2:

 --- {% if 'apps.openshift.io' in api_groups %} apiVersion: apps.openshift.io/v1 kind: DeploymentConfig {% else %} apiVersion: apps/v1 kind: Deployment {% endif %} metadata: name: {{ name }} namespace: {{ namespace }} labels: app: {{ name }} service: {{ name }} spec: replicas: {{ size }} {% if 'apps.openshift.io' in api_groups %} selector: app: {{ name }} service: {{ name }} {% else %} selector: matchLabels: app: {{ name }} service: {{ name }} {% endif %} template: metadata: labels: app: {{ name }} service: {{ name }} spec: containers: - image: {{ image }} name: hello-world ports: - containerPort: 8080 protocol: TCP 

قوالب الملفات / service.yml.j2:

 --- apiVersion: v1 kind: Service metadata: name: {{ name }} namespace: {{ namespace }} labels: app: {{ name }} service: {{ name }} spec: ports: - name: web port: 8080 protocol: TCP targetPort: 8080 selector: app: {{ name }} service: {{ name }} 

وأخيرًا ، ملف القوالب / route.yml.j2:

 --- apiVersion: route.openshift.io/v1 kind: Route metadata: name: {{ name }} namespace: {{ namespace }} labels: app: {{ name }} service: {{ name }} spec: port: targetPort: web to: kind: Service name: {{ name }} 

تم حذف ملف التعريف / main.yml ، لكن يمكن العثور عليه هنا .

نتيجة لذلك ، لدينا دور Ansible في إدارة تطبيق Hello World في Kubernetes ، ويمكننا استخدام واجهات برمجة التطبيقات المتوفرة في المجموعة. بمعنى آخر ، تعمل الوحدة النمطية k8s والعميل الديناميكي على تبسيط العمل مع الكائنات في Kubernetes. نأمل أنه مع مثال هذا الدور ، تمكنا من إظهار إمكانات Ansible عند العمل مع Kubernetes.

مرحبا غالاكسي ، وتلبية Kubernetes


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

بعد أن نشرنا دورنا على جيثب ، كل ما تبقى هو:

  1. قم بتسجيل الدخول إلى Ansible Galaxy لإتاحة الوصول إلى مستودعاتنا على GitHub.
  2. استيراد دورنا.

هذا كل شيء ، والآن أصبح دور hello_world_k8s متاحًا للعامة في Ansible Galaxy ، هنا .

مرحبا المشغل Ansible ، لقاء غالاكسي


إذا قمت بدراسة مشروع Hello World بعناية على GitHub ، فستلاحظ أننا قمنا بإضافة العديد من الأشياء الضرورية لإنشاء مشغل Ansible ، وهي:

  1. ملف Watches الذي يعين موارد Kubernetes المخصصة لأدوار أو كتب Ansible.
  2. Dockerfile لبناء المشغل لدينا.
  3. نشر الدليل مع كائنات Kubernetes اللازمة لتشغيل المشغل لدينا.

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

 FROM quay.io/operator-framework/ansible-operator RUN ansible-galaxy install djzager.hello_world_k8s RUN echo $'--- \n\ - version: v1alpha1\n\ group: examples.djzager.io\n\ kind: HelloWorld\n\ role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml 

الآن نجمع المشغل:

 $ docker build -t hello-world-operator -f Dockerfile . Sending build context to Docker daemon 157.2 kB Step 1/3 : FROM quay.io/operator-framework/ansible-operator latest: Pulling from operator-framework/ansible-operator Digest: sha256:1156066a05fb1e1dd5d4286085518e5ce15acabfff10a8145eef8da088475db3 Status: Downloaded newer image for quay.io/water-hole/ansible-operator:latest ---> 39cc1d19649d Step 2/3 : RUN ansible-galaxy install djzager.hello_world_k8s ---> Running in 83ba8c21f233 - downloading role 'hello_world_k8s', owned by djzager - downloading role from https://github.com/djzager/ansible-role-hello-world-k8s/archive/master.tar.gz - extracting djzager.hello_world_k8s to /opt/ansible/roles/djzager.hello_world_k8s - djzager.hello_world_k8s (master) was installed successfully Removing intermediate container 83ba8c21f233 ---> 2f303b45576c Step 3/3 : RUN echo $'--- \n- version: v1alpha1\n group: examples.djzager.io\n kind: HelloWorld\n role: /opt/ansible/roles/djzager.hello_world_k8s' > ${HOME}/watches.yaml ---> Running in cced495a9cb4 Removing intermediate container cced495a9cb4 ---> 5827bc3c1ca3 Successfully built 5827bc3c1ca3 Successfully tagged hello-world-operator:latest 

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

 apiVersion: examples.djzager.io/v1alpha1 kind: HelloWorld metadata: name: example-helloworld namespace: default spec: size: 3 

نطاقات المشغل: مساحة الاسم والكتلة


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

  1. متغير بيئة WATCH_NAMESPACE في ملف المشغل. yaml الذي يخبر المشغل أين يبحث عن الموارد المخصصة
  2. دور
  3. لعب دور

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

  1. إنشاء ClusterRole بدلاً من الدور.
  2. إنشاء عبارة ServiceAccount في مساحة الاسم حيث سيتم نشر البيان.
  3. إنشاء ClusterRoleBinding التي سيتم ربط ServiceAccount من مساحة اسم معينة بـ ClusterRole.
  4. قم بتوسيع العبارة باستخدام متغير بيئة WATCH_NAMESPACE غير معروف (أي ، "").

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

رحلة ستار


لقد أوضحنا كيفية إنشاء دور Ansible للتحكم في تطبيق ما في Kubernetes ، ونشر هذا الدور في Ansible Galaxy واستخدامه في مشغل Ansible. نتمنى لك الان

  1. سوف تستخدم وحدة k8s Ansible .
  2. ابدأ في نشر أدوارك لإدارة تطبيقات Kubernetes على Ansible Galaxy .
  3. اهتم بمشغل SDK واشترك في نشرة المشغل الإخبارية .

تم تصميم تطبيق Hello World بشكل بسيط للغاية ، ولكن هناك أشياء يمكن أن تساعد في جعله أكثر موثوقية ، وإليك بعض:

  1. باستخدام المشغل SDK - لم نقم بذلك عمداً في مثالنا للتأكيد على مدى سهولة التبديل من دور Ansible إلى المشغل. لكن من الأفضل الاستمرار في استخدام هذا الدور مع SDK (أي ، مشغل sdk الجديد) ، علاوة على ذلك ، قد تحتاج إلى ذلك في الخطوات التالية.
  2. التحقق من الصحة - في الإصدار الحالي لدينا ، يمكن للمستخدم إنشاء السجل التجاري بالحجم: abc ، مما سيؤدي حتماً إلى حدوث خطأ في مرحلة النشر. لذلك من الأفضل أن نلاحظ الأخطاء في مرحلة المواصفات ، وليس بعد بدء العمل.
  3. دورة الحياة - في أمثلة أكثر تعقيدًا ، قد يكون نفس تحديث الإصدار. في سيناريوهات مثل السيناريو الخاص بنا ، حيث يوجد إصدار واحد فقط من تطبيق Hello World ، يمكننا تحديد ما إذا كانت صورة حاوية العمل قديمة عن طريق مقارنتها بالصور المتاحة في سجل الحاوية المقابل وتحديث الحالات قيد التشغيل إذا لزم الأمر.
  4. اختبار - جزيء مفيد للغاية عند تطوير واختبار الأدوار Ansible.
  5. مشغل دورة حياة المشغل عبارة عن مجموعة أدوات لإدارة المشغلين. التكامل مع ذلك سيساعد على تثبيت وتحديث المشغل لدينا.
  6. الحالة - يمكننا تنشيط مصدر الحالة الفرعي في Hello World CRD واستخدام الوحدة النمطية k8s_status ، التي تعد جزءًا من صورة Ansible Operator ، لتضمين معلومات الحالة في المورد المخصص.

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


All Articles