في المنشورتين السابقتين ، قمنا بتغطية كيفية نشر تطبيقات الويب الحديثة في بضع خطوات فقط ، وكيفية استخدام صورة S2I جديدة مع صورة خادم HTTP جاهزة مثل NGINX باستخدام عمليات إنشاء متسلسلة لنشر الإنتاج.
سنعرض لك اليوم كيفية تشغيل خادم تطوير لتطبيقك على النظام الأساسي OpenShift ومزامنته مع نظام الملفات المحلي ، وكذلك الحديث عن ماهية OpenShift Pipelines وكيف يمكنك استخدامه كبديل للتجميعات المرتبطة.
OpenShift كبيئة تطوير
سير عمل التطوير
كما تمت مناقشته في المنشور الأول ، فإن سير عمل التطوير النموذجي لتطبيقات الويب الحديثة هو ببساطة "خادم تطوير" يراقب التغييرات في الملفات المحلية. عند حدوثها ، يبدأ إنشاء التطبيق ثم يتم تحديثه إلى المتصفح.
في معظم الأطر الحديثة ، تم دمج "خادم التطوير" هذا في أدوات سطر الأوامر المقابلة.
مثال محلي
أولاً ، دعنا نرى كيف يعمل هذا في حالة تشغيل التطبيقات محليًا. لنأخذ تطبيق React من المقالات السابقة كمثال ، على الرغم من أن الكثير من نفس مفاهيم سير العمل تنطبق على جميع الأطر الحديثة الأخرى.
لذلك ، لبدء "خادم التطوير" في مثال React الخاص بنا ، نصدر الأمر التالي:
$ npm run start
ثم سنرى في النافذة الطرفية شيئًا مشابهًا لما يلي:

وسيتم فتح تطبيقنا في المتصفح الافتراضي:

الآن ، إذا أجرينا تغييرات على الملف ، فيجب تحديث التطبيق في المتصفح.
حسنًا ، مع التطوير في الوضع المحلي ، كل شيء واضح ، ولكن كيف يتم تحقيق ذلك على OpenShift؟
خادم التطوير على OpenShift
إذا كنت تتذكر ، في المنشور السابق ، قمنا بتحليل ما يسمى بمرحلة التشغيل لصورة S2I ورأينا أن وحدة الخدمة بشكل افتراضي مسؤولة عن خدمة تطبيق الويب الخاص بنا.
ومع ذلك ، إذا ألقيت نظرة فاحصة على البرنامج النصي للتشغيل من هذا المثال ، فسترى أنه يحتوي على متغير البيئة $ NPM_RUN ، والذي يسمح لك بتنفيذ الأمر الخاص بك.
على سبيل المثال ، يمكننا استخدام وحدة nodeshift لنشر تطبيقنا:
$ npx nodeshift --deploy.env NPM_RUN="yarn start" --dockerImage=nodeshift/ubi8-s2i-web-app
ملاحظة: يتم اختصار المثال أعلاه لتوضيح الفكرة العامة.
لقد أضفنا هنا متغير البيئة NPM_RUN إلى عملية النشر الخاصة بنا ، والتي تخبر وقت التشغيل بتشغيل أمر بدء الغزل ، والذي يبدأ خادم تطوير React داخل جراب OpenShift الخاص بنا.
إذا نظرت إلى سجل البود قيد التشغيل ، فسيكون هناك شيء مشابه لما يلي:

بالطبع ، لن يكون هذا كله شيئًا حتى نتمكن من مزامنة الكود المحلي مع الكود الذي يتم مراقبته أيضًا من أجل التغييرات ، ولكنه يعيش على خادم بعيد.
مزامنة التعليمات البرمجية المحلية والبعيدة
لحسن الحظ ، يمكن أن يساعد nodeshift بسهولة في المزامنة ، ويمكنك استخدام أمر الساعة لتتبع التغييرات.
لذلك بعد أن ننفذ الأمر لنشر خادم التطوير لتطبيقنا ، يمكننا استخدام الأمر التالي بأمان:
$ npx nodeshift watch
نتيجة لذلك ، سيتم إجراء اتصال بجراب التشغيل ، الذي أنشأناه قبل ذلك بقليل ، وسيتم تنشيط مزامنة ملفاتنا المحلية مع الكتلة البعيدة ، وستتم مراقبة الملفات الموجودة على نظامنا المحلي من أجل التغييرات.
لذلك ، إذا قمنا الآن بتحديث ملف src / App.js ، فسيتفاعل النظام مع هذه التغييرات ، ونسخها إلى الكتلة البعيدة وبدء خادم التطوير ، الذي سيقوم بعد ذلك بتحديث تطبيقنا في المتصفح.
للتأكد من اكتمالها ، دعنا نظهر كيف تبدو هذه الأوامر في مجملها:
$ npx nodeshift --strictSSL=false --dockerImage=nodeshift/ubi8-s2i-web-app --build.env YARN_ENABLED=true --expose --deploy.env NPM_RUN="yarn start" --deploy.port 3000
$ npx nodeshift watch --strictSSL=false
أمر الساعة هو تجريد أعلى الأمر oc rsync ، يمكنك معرفة المزيد حول كيفية عمله هنا .
كان هذا مثالاً على React ، ولكن يمكن استخدام نفس الطريقة بالضبط مع أطر أخرى ، فقط اضبط متغير البيئة NPM_RUN حسب الحاجة.
فتح خطوط الأنابيب

بعد ذلك ، سنتحدث عن أداة مثل OpenShift Pipelines وكيف يمكن استخدامها كبديل للبنى المقيدة.
ما هي خطوط أنابيب OpenShift
OpenShift Pipelines عبارة عن نظام CI / CD للتكامل المستمر والتسليم قائم على السحابة لتنظيم خطوط الأنابيب باستخدام Tekton. Tekton هو إطار عمل CI / CD أصلي مرن ومفتوح المصدر لـ Kubernetes يقوم بأتمتة عمليات النشر عبر الأنظمة الأساسية (Kubernetes ، بدون خادم ، أجهزة افتراضية ، وما إلى ذلك) عن طريق التجريد من الطبقة الأساسية.
مطلوب بعض المعرفة بخطوط الأنابيب لفهم هذه المقالة ، لذلك ننصحك بشدة بقراءة البرنامج التعليمي الرسمي أولاً .
تهيئة بيئة العمل
للتلاعب بالأمثلة الواردة في هذه المقالة ، تحتاج أولاً إلى إعداد بيئة الإنتاج الخاصة بك:
- OpenShift 4. CodeReady Containers (CRD), .
- , , Pipeline Operator. , , .
- Tekton CLI (tkn) .
- create-react-app, , ( React).
- () , npm install npm start.
سيحتوي مستودع التطبيقات أيضًا على مجلد k8s ، حيث سيتم تحديد موقع Kubernetes / OpenShift YAMLs المستخدمة لنشر التطبيق. ستكون هناك مهام ، و ClusterTasks ، وموارد وخطوط أنابيب سنقوم بإنشائها في هذا المستودع .
هيا بنا نبدأ
الخطوة الأولى لمثالنا هي إنشاء مشروع جديد في مجموعة OpenShift. دعنا نطلق على هذا المشروع webapp-pipeline وننشئه بالأمر التالي:
$ oc new-project webapp-pipeline
علاوة على ذلك ، سيظهر اسم المشروع هذا في الكود ، لذلك إذا قررت تسميته بشيء آخر ، فلا تنس تحرير الكود من الأمثلة وفقًا لذلك. بدءًا من هذه النقطة ، لن ننتقل من أعلى إلى أسفل ، بل من أسفل إلى أعلى: أي أننا سننشئ أولاً جميع مكونات الناقل ، وبعد ذلك فقط هو نفسه.
لذا ، أولاً وقبل كل شيء ...
مهام
لنقم بإنشاء بعض المهام التي ستساعدنا بعد ذلك في نشر التطبيق ضمن خط الأنابيب الخاص بنا. المهمة الأولى ، application_manifests_task ، هي المسؤولة عن تطبيق YAML على موارد Kubernetes (الخدمة والنشر والمسار) الموجودة في مجلد k8s لتطبيقنا. المهمة الثانية - update_deployment_task - مسؤولة عن تحديث الصورة المنشورة بالفعل إلى تلك التي تم إنشاؤها بواسطة خط الأنابيب الخاص بنا.
لا تقلق إذا لم يكن واضحًا بعد. في الواقع ، هذه المهام تشبه المرافق ، وسنناقشها بمزيد من التفصيل لاحقًا. الآن ، دعنا ننشئها:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/update_deployment_task.yaml
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/apply_manifests_task.yaml
ثم ، باستخدام الأمر tkn CLI ، تحقق من إنشاء المهام:
$ tkn task ls
NAME AGE
apply-manifests 1 minute ago
update-deployment 1 minute ago
ملاحظة: هذه مهام محلية لمشروعك الحالي.
مهام الكتلة
المهام المجمعة هي في الأساس نفس المهام البسيطة. أي أنها مجموعة من الخطوات يمكن إعادة استخدامها والتي يتم دمجها بطريقة أو بأخرى عند بدء مهمة معينة. الفرق هو أن مهمة الكتلة متاحة في كل مكان داخل الكتلة. للاطلاع على قائمة مهام المجموعة التي يتم إنشاؤها تلقائيًا عند إضافة عامل تشغيل خط الأنابيب ، استخدم مرة أخرى الأمر tkn CLI:
$ tkn clustertask ls
NAME AGE
buildah 1 day ago
buildah-v0-10-0 1 day ago
jib-maven 1 day ago
kn 1 day ago
maven 1 day ago
openshift-client 1 day ago
openshift-client-v0-10-0 1 day ago
s2i 1 day ago
s2i-go 1 day ago
s2i-go-v0-10-0 1 day ago
s2i-java-11 1 day ago
s2i-java-11-v0-10-0 1 day ago
s2i-java-8 1 day ago
s2i-java-8-v0-10-0 1 day ago
s2i-nodejs 1 day ago
s2i-nodejs-v0-10-0 1 day ago
s2i-perl 1 day ago
s2i-perl-v0-10-0 1 day ago
s2i-php 1 day ago
s2i-php-v0-10-0 1 day ago
s2i-python-3 1 day ago
s2i-python-3-v0-10-0 1 day ago
s2i-ruby 1 day ago
s2i-ruby-v0-10-0 1 day ago
s2i-v0-10-0 1 day ago
لنقم الآن بإنشاء مجموعتين من المهام. الأول سينشئ صورة S2I ويرسلها إلى سجل OpenShift الداخلي ؛ والثاني هو بناء صورتنا المستندة إلى NGINX باستخدام التطبيق الذي قمنا بتجميعه بالفعل كمحتوى.
إنشاء وإرسال الصورة
عند إنشاء المهمة الأولى ، سنكرر ما فعلناه بالفعل في المقالة السابقة حول التجميعات المرتبطة. تذكر أننا استخدمنا صورة S2I (ubi8-s2i-web-app) من أجل "إنشاء" تطبيقنا وانتهى بنا الأمر بالصورة المخزنة في سجل OpenShift الداخلي. سنستخدم الآن صورة S2I هذه لتطبيق الويب لإنشاء DockerFile لتطبيقنا ، ثم نستخدم Buildah للقيام بالبناء الفعلي ودفع الصورة الناتجة إلى سجل OpenShift الداخلي ، نظرًا لأن هذا هو بالضبط ما يفعله OpenShift عند نشر نسختك. التطبيقات التي تستخدم NodeShift.
كيف عرفنا كل هذا تسأل؟ من النسخة الرسمية لـ Node.js الرسمية ، قمنا بنسخها وإنهائها لأنفسنا.
لذلك ، نقوم الآن بإنشاء مهمة مجموعة تطبيقات الويب s2i:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml
لن نخوض في التفاصيل حول هذا الأمر ، ولكن سنركز فقط على معلمة OUTPUT_DIR:
params:
- name: OUTPUT_DIR
description: The location of the build output directory
default: build
افتراضيًا ، يتم ضبط هذه المعلمة على الإنشاء ، حيث تضع React المحتوى المُجمع. تستخدم الأطر الأخرى مسارات مختلفة ، على سبيل المثال ، في Ember هو dist. ستكون مخرجات مهمة المجموعة الأولى لدينا عبارة عن صورة تحتوي على HTML و JavaScript و CSS قمنا بجمعها.
بناء صورة على أساس NGINX
بالنسبة لمهمة المجموعة الثانية ، يجب أن تجمع صورة تستند إلى NGINX لنا باستخدام محتوى التطبيق الذي جمعناه بالفعل. في الأساس ، هذا هو الجزء من القسم السابق حيث نظرنا إلى الإنشاءات المقيدة.
للقيام بذلك ، نقوم - بنفس الطريقة الموضحة أعلاه - بإنشاء مجموعة مهام webapp-build-runtime:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml
إذا نظرت إلى رمز مهام المجموعة هذه ، يمكنك أن ترى أن مستودع Git الذي نعمل معه أو أسماء الصور التي ننشئها غير محددة هناك. نحدد فقط ما ننقله بالضبط إلى Git ، أو صورة معينة ، حيث يجب عرض الصورة النهائية. هذا هو السبب في أنه يمكن إعادة استخدام مهام المجموعة هذه عند العمل مع التطبيقات الأخرى.
وهنا ننتقل برشاقة إلى النقطة التالية ...
مصادر
لذلك ، نظرًا لأنه ، كما قلنا للتو ، يجب أن تكون مهام المجموعة عامة قدر الإمكان ، فنحن بحاجة إلى إنشاء الموارد التي سيتم استخدامها في المدخلات (مستودع Git) والمخرجات (الصور النهائية). المورد الأول الذي نحتاجه هو Git حيث يوجد تطبيقنا ، شيء من هذا القبيل:
# This resource is the location of the git repo with the web application source
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: web-application-repo
spec:
type: git
params:
- name: url
value: https://github.com/nodeshift-starters/react-pipeline-example
- name: revision
value: master
هنا PipelineResource من النوع git. يشير مفتاح url في قسم المعلمات إلى مستودع معين ويقوم بتعيين الفرع الرئيسي (هذا اختياري ، لكننا نكتبه للتأكد من اكتماله).
نحتاج الآن إلى إنشاء مورد للصورة ، حيث سيتم حفظ نتائج مهمة تطبيق الويب s2i ، ويتم ذلك على النحو التالي:
# This resource is the result of running "npm run build", the resulting built files will be located in /opt/app-root/output
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: built-web-application-image
spec:
type: image
params:
- name: url
value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-application:latest
هنا PipelineResource هي صورة من النوع ، وتشير قيمة معلمة url إلى OpenShift Image Registry ، تحديدًا إلى واحد في مساحة اسم خط أنابيب الويب. تذكر تغيير هذه المعلمة إذا كنت تستخدم مساحة اسم مختلفة.
وأخيرًا ، سيكون المورد الأخير الذي نحتاجه أيضًا من نوع الصورة وستكون هذه هي صورة NGINX النهائية ، والتي سيتم استخدامها بعد ذلك أثناء النشر:
# This resource is the image that will be just the static html, css, js files being run with nginx
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: runtime-web-application-image
spec:
type: image
params:
- name: url
value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtime-web-application:latest
مرة أخرى ، لاحظ أن هذا المورد يخزن الصورة في سجل OpenShift الداخلي في مساحة اسم مسار تطبيقات الويب.
لإنشاء كل هذه الموارد مرة واحدة ، استخدم الأمر create:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml
يمكنك التأكد من إنشاء الموارد على النحو التالي:
$ tkn resource ls
خط الأنابيب
الآن بعد أن أصبح لدينا جميع المكونات الضرورية ، سنقوم بتجميع خط أنابيب منها ، وإنشاءه بالأمر التالي:
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml
لكن قبل تشغيل هذا الأمر ، دعنا نلقي نظرة على هذه المكونات. الأول هو الاسم:
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
name: build-and-deploy-react
بعد ذلك ، في قسم المواصفات ، نرى إشارة إلى الموارد التي أنشأناها سابقًا:
spec:
resources:
- name: web-application-repo
type: git
- name: built-web-application-image
type: image
- name: runtime-web-application-image
type: image
ثم نقوم بإنشاء مهام لإكمال خط الأنابيب الخاص بنا. بادئ ذي بدء ، يجب عليه تنفيذ مهمة تطبيق الويب s2i التي أنشأناها بالفعل:
tasks:
- name: build-web-application
taskRef:
name: s2i-web-app
kind: ClusterTask
تأخذ هذه المهمة معلمات المدخلات (gir-Resource) والمخرجات (مورد صورة تطبيق ويب مدمج). نقوم أيضًا بتمرير معلمة خاصة لها بحيث لا تتحقق من TLS نظرًا لأننا نستخدم الشهادات الموقعة ذاتيًا:
resources:
inputs:
- name: source
resource: web-application-repo
outputs:
- name: image
resource: built-web-application-image
params:
- name: TLSVERIFY
value: "false"
المهمة التالية هي نفسها تقريبًا ، هنا فقط تسمى مهمة مجموعة webapp-build-runtime التي أنشأناها بالفعل:
name: build-runtime-image
taskRef:
name: webapp-build-runtime
kind: ClusterTask
كما هو الحال مع المهمة السابقة ، نقوم بتمرير المورد ، ولكن هذه الآن صورة تطبيق ويب مدمجة (ناتج مهمتنا السابقة). وكمخرج ، قمنا مرة أخرى بتعيين الصورة. نظرًا لأنه يجب تنفيذ هذه المهمة بعد المهمة السابقة ، فإننا نضيف حقل runAfter:
resources:
inputs:
- name: image
resource: built-web-application-image
outputs:
- name: image
resource: runtime-web-application-image
params:
- name: TLSVERIFY
value: "false"
runAfter:
- build-web-application
المهمتان التاليتان مسؤولتان عن تطبيق ملفات YAML للخدمة والتوجيه والنشر الموجودة في دليل k8s لتطبيق الويب الخاص بنا ، وكذلك عن تحديث هذا النشر عند إنشاء صور جديدة. قمنا بتعيين هاتين المهمتين العنقوديتين في بداية المقالة.
تشغيل الناقل
لذلك ، يتم إنشاء جميع أجزاء خط الأنابيب الخاص بنا ، وسنبدأ بالأمر التالي:
$ tkn pipeline start build-and-deploy-react
في هذه المرحلة ، يتم استخدام سطر الأوامر بشكل تفاعلي وتحتاج إلى تحديد الموارد المناسبة استجابةً لكل طلب من طلباته: بالنسبة لمورد git ، حدد web-application-repo ، ثم لمصدر الصورة الأول - صورة تطبيق الويب المدمجة ، وأخيراً من أجل مصدر الصورة الثاني - وقت التشغيل - تطبيق الويب - صورة:
? Choose the git resource to use for web-application-repo: web-application-repo (https://github.com/nodeshift-starters/react-pipeline-example)
? Choose the image resource to use for built-web-application-image: built-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-
application:latest)
? Choose the image resource to use for runtime-web-application-image: runtime-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtim
e-web-application:latest)
Pipelinerun started: build-and-deploy-react-run-4xwsr
الآن دعنا نتحقق من حالة خط الأنابيب باستخدام الأمر التالي:
$ tkn pipeline logs -f
بعد بدء خط الأنابيب ونشر التطبيق ، نطلب المسار المنشور بالأمر التالي:
$ oc get route react-pipeline-example --template='http://{{.spec.host}}'
لمزيد من الوضوح ، يمكنك عرض خط الأنابيب الخاص بنا في وضع المطور لوحدة تحكم الويب في قسم خطوط الأنابيب ، كما هو موضح في الشكل. 1.

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

الشكل: 2. مزيد من المعلومات حول خط الأنابيب.
بعد مزيد من المعلومات ، يمكنك رؤية التطبيقات قيد التشغيل في طريقة عرض Topology ، كما هو موضح في الشكل 3.

الشكل 3. جراب الجري.
يؤدي النقر فوق الدائرة الموجودة في الزاوية اليمنى العلوية من الرمز إلى فتح تطبيقنا ، كما هو موضح في الشكل 4.

الشكل: 4. إطلاق تطبيق React.
خاتمة
لذلك ، أوضحنا كيفية تشغيل خادم تطوير لتطبيقك على OpenShift ومزامنته مع نظام الملفات المحلي. نظرنا أيضًا في كيفية محاكاة قالب البناء المتسلسل باستخدام خطوط أنابيب OpenShift. يمكن العثور على جميع نماذج الرموز من هذه المقالة هنا .
موارد إضافية (بالإنكليزية)
- كتاب إلكتروني مجاني بعنوان "Develop with OpenShift: A Guide for the Impatient"
- أنشئ تطبيقات Node.js موجهة للحاويات باستخدام أوقات تشغيل تطبيق Red Hat OpenShift و Istio
- تصحيح أخطاء تطبيقات Node.js على OpenShift باستخدام Chrome DevTools
- ثلاثة أوامر لإتقان Express على OpenShift من البداية
- الإعلان عن إصدار عام من Node.js كجزء من أوقات تشغيل تطبيق Red Hat OpenShift
- مراقبة تطبيقات Node.js على OpenShift باستخدام Prometheus
- المزيد من المقالات حول OpenShift و Kubernetes على Red Hat
إعلانات ندوات الويب القادمة
نبدأ سلسلة ندوات عبر الإنترنت يوم الجمعة حول التجربة الأصلية لاستخدام Red Hat OpenShift Container Platform و Kubernetes:
- 28 أغسطس ، إمبراطور الويبينار "المشغل": المشغلون في OpenShift و Kubernetes
- 11 سبتمبر ، DeploymentConfig vs Deployment - سحر خاص بـ OpenShift لبناء التطبيقات ونشرها
- 25 سبتمبر ، Red Hat OpenShift و Machine API
- 9 أكتوبر ، كيفية التعامل مع نمو الحمل المفاجئ
- 23 أكتوبر ، Embedded Jenkins ، Pipeline-builds ، Tekton في Red Hat OpenShift Container Platform