نصائح وحيل Kubernetes: حول التنمية المحلية والتواجد عن بعد

نصائح وحيل Kubernetes: حول التنمية المحلية والتواجد عن بعد

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

في أوقات مختلفة جربنا حلولاً مختلفة للمشكلة. وسأبدأ بالحلول المتراكمة أو ببساطة "العكازات".

1. العكازات

تتمتع معظم IDEs بالقدرة على تحرير التعليمات البرمجية مباشرة على الخادم باستخدام FTP/SFTP. هذا المسار واضح جدًا وقررنا استخدامه على الفور. ويتلخص جوهرها في ما يلي:

  1. في مجموعة بيئات التطوير (التطوير/المراجعة)، يتم إطلاق حاوية إضافية مع وصول SSH وإعادة توجيه مفتاح SSH العام للمطور الذي سيقوم بتنفيذ/نشر التطبيق.
  2. في المرحلة الأولية (داخل الحاوية prepare-app) قم بنقل الرمز إلى emptyDirللوصول إلى التعليمات البرمجية من حاويات التطبيق وخادم SSH.

نصائح وحيل Kubernetes: حول التنمية المحلية والتواجد عن بعد

لفهم التنفيذ الفني لمثل هذا المخطط بشكل أفضل، سأقدم أجزاء من تكوينات YAML المعنية في Kubernetes.

التكوينات

1.1. value.yaml

ssh_pub_key:
  vasya.pupkin: <ssh public key in base64> 

ومن vasya.pupkin هي قيمة المتغير ${GITLAB_USER_LOGIN}.

1.2. نشر.yaml

...
{{ if eq .Values.global.debug "yes" }}
      volumes:
      - name: ssh-pub-key
        secret:
          defaultMode: 0600
          secretName: {{ .Chart.Name }}-ssh-pub-key
      - name: app-data
        emptyDir: {}
      initContainers:
      - name: prepare-app
{{ tuple "backend" . | include "werf_container_image" | indent 8 }}
        volumeMounts:
        - name: app-data
          mountPath: /app-data
        command: ["bash", "-c", "cp -ar /app/* /app-data/" ]
{{ end }}
      containers:
{{ if eq .Values.global.debug "yes" }}
      - name: ssh
        image: corbinu/ssh-server
        volumeMounts:
        - name: ssh-pub-key
          readOnly: true
          mountPath: /root/.ssh/authorized_keys
          subPath: authorized_keys
        - name: app-data
          mountPath: /app
        ports:
        - name: ssh
          containerPort: 22
          protocol: TCP
{{ end }}
      - name: backend
        volumeMounts:
{{ if eq .Values.global.debug "yes" }}
        - name: app-data
          mountPath: /app
{{ end }}
        command: ["/usr/sbin/php-fpm7.2", "--fpm-config", "/etc/php/7.2/php-fpm.conf", "-F"]
...

1.3. Secret.yaml

{{ if eq .Values.global.debug "yes" }}
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Chart.Name }}-ssh-pub-key
type: Opaque
data:
  authorized_keys: "{{ first (pluck .Values.global.username .Values.ssh_pub_key) }}"
{{ end }}

اللمسة النهائية

بعد ذلك كل ما تبقى هو النقل المتغيرات gitlab-ci.yml المطلوبة:

dev:
  stage: deploy
  script:
   - type multiwerf && source <(multiwerf use 1.0 beta)
   - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
   - werf deploy
     --namespace ${CI_PROJECT_NAME}-stage
     --set "global.env=stage"
     --set "global.git_rev=${CI_COMMIT_SHA}"
     --set "global.debug=yes"
     --set "global.username=${GITLAB_USER_LOGIN}"
 tags:
   - build

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

يعد هذا حلاً عمليًا تمامًا، ولكن من وجهة نظر التنفيذ له عيوب واضحة:

  • الحاجة إلى تحسين مخطط هيلم، مما يجعل من الصعب قراءته في المستقبل؛
  • لا يمكن استخدامه إلا من قبل الشخص الذي قام بنشر الخدمة؛
  • عليك أن تتذكر أن تقوم بعد ذلك بمزامنته مع الدليل المحلي باستخدام الكود وإلزامه بـ Git.

2. الحضور عن بعد

مشروع التواجد عن بعد لقد كان معروفًا منذ فترة طويلة، لكننا، كما يقولون، "لم نحاول بجدية تجربته عمليًا". ومع ذلك، فقد قام الطلب بعمله، ويسعدنا الآن مشاركة تجربتنا، والتي قد تكون مفيدة لقراء مدونتنا - خاصة أنه لا توجد مواد أخرى حول التواجد عن بعد على المركز حتى الآن.

باختصار، تبين أن كل شيء ليس مخيفا جدا. لقد وضعنا جميع الإجراءات التي تتطلب التنفيذ من جانب المطور في ملف نصي لمخطط Helm يسمى NOTES.txt. وبالتالي، بعد نشر الخدمة على Kubernetes، يرى المطور تعليمات تشغيل بيئة التطوير المحلية في سجل وظائف GitLab:

!!! Разработка сервиса локально, в составе Kubernetes !!!

* Настройка окружения
* * Должен быть доступ до кластера через VPN
* * На локальном ПК установлен kubectl ( https://kubernetes.io/docs/tasks/tools/install-kubectl/ )
* * Получить config-файл для kubectl (скопировать в ~/.kube/config)
* * На локальном ПК установлен telepresence ( https://www.telepresence.io/reference/install )
* * Должен быть установлен Docker
* * Необходим доступ уровня reporter или выше к репозиторию https://gitlab.site.com/group/app
* * Необходимо залогинится в registry с логином/паролем от GitLab (делается один раз):

#########################################################################
docker login registry.site.com
#########################################################################

* Запуск окружения

#########################################################################
telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name  }}:backend --mount=/tmp/app --docker-run -v `pwd`:/app -v /tmp/app/var/run/secrets:/var/run/secrets -ti registry.site.com/group/app/backend:v8
#########################################################################

لن نتناول بالتفصيل الخطوات الموضحة في هذه التعليمات... باستثناء الخطوة الأخيرة. ماذا يحدث أثناء إطلاق Telepresence؟

العمل مع الحضور عن بعد

عند بدء التشغيل (باستخدام الأمر الأخير المحدد في التعليمات أعلاه)، قمنا بتعيين:

  • مساحة الاسم التي تعمل فيها الخدمة المصغرة؛
  • أسماء النشر والحاوية التي نريد اختراقها.

الوسائط المتبقية اختيارية. إذا كانت خدمتنا تتفاعل مع Kubernetes API ومن أجلها تم إنشاء حساب الخدمة، نحتاج إلى تحميل الشهادات/الرموز المميزة على سطح المكتب لدينا. للقيام بذلك، استخدم الخيار --mount=true (أو --mount=/dst_path)، والذي سيؤدي إلى تحميل الجذر (/) من حاوية Kubernetes إلى سطح المكتب. بعد ذلك، يمكننا (اعتمادًا على نظام التشغيل وكيفية تشغيل التطبيق) استخدام "المفاتيح" من المجموعة.

أولاً، دعونا نلقي نظرة على الخيار الأكثر عالمية لتشغيل تطبيق ما - في حاوية Docker. للقيام بذلك سوف نستخدم المفتاح --docker-run وقم بتثبيت الدليل بالكود في الحاوية: -v `pwd`:/app

يرجى ملاحظة أن هذا يفترض التشغيل من دليل المشروع. سيتم تثبيت رمز التطبيق في الدليل /app في حاوية.

المقبل: -v /tmp/app/var/run/secrets:/var/run/secrets - لتركيب الدليل الذي يحتوي على الشهادة/الرمز المميز في حاوية.

يتبع هذا الخيار أخيرًا الصورة التي سيتم تشغيل التطبيق بها. NB: عند بناء صورة، يجب عليك تحديد CMD أو ENTRYPOINT!

ماذا سيحدث بالضبط بعد ذلك؟

  • في Kubernetes، بالنسبة لعملية النشر المحددة، سيتم تغيير عدد النسخ المتماثلة إلى 0. وبدلاً من ذلك، سيتم إطلاق عملية نشر جديدة - مع حاوية بديلة backend.
  • سيتم إطلاق حاويتين على سطح المكتب: الأولى مع Telepresence (ستقوم بتوكيل الطلبات من/إلى Kubernetes)، والثانية مع التطبيق قيد التطوير.
  • إذا قمنا بالتنفيذ في حاوية التطبيق، فستكون جميع متغيرات ENV المنقولة بواسطة Helm أثناء النشر متاحة لنا، وستكون جميع الخدمات متاحة أيضًا. كل ما تبقى هو تعديل الكود في IDE المفضل لديك والاستمتاع بالنتيجة.
  • في نهاية العمل، تحتاج فقط إلى إغلاق المحطة التي يعمل بها Telepresence (إنهاء الجلسة باستخدام Ctrl+C) - ستتوقف حاويات Docker على سطح المكتب، وسيعود كل شيء في Kubernetes إلى حالته الأولية. كل ما تبقى هو الالتزام وإصدار MR وتحويله إلى مراجعة/دمج/... (حسب سير العمل لديك).

إذا لم نرغب في تشغيل التطبيق في حاوية Docker - على سبيل المثال، لم نقم بتطويره بلغة PHP، ولكن في Go، وما زلنا نبنيه محليًا - سيكون تشغيل Telepresence أكثر بساطة:

telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name  }}:backend --mount=true

إذا وصل التطبيق إلى واجهة برمجة تطبيقات Kubernetes، فستحتاج إلى تثبيت دليل المفاتيح (https://www.telepresence.io/howto/volumes). هناك فائدة لنظام التشغيل Linux بروت:

proot -b $TELEPRESENCE_ROOT/var/run/secrets/:/var/run/secrets bash

بعد إطلاق Telepresence بدون الخيار --docker-run ستكون كافة متغيرات البيئة متاحة في الجهاز الحالي، لذلك يجب تشغيل التطبيق فيه.

NB: عند استخدام PHP، على سبيل المثال، يجب أن تتذكر تعطيل op_cache وapc والمسرعات الأخرى للتطوير - وإلا فإن تحرير الكود لن يؤدي إلى النتيجة المرجوة.

نتائج

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

PS

آخرون من سلسلة النصائح والحيل K8s:

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

إضافة تعليق