التطبيقات الحديثة على OpenShift، الجزء 2: البنيات المتسلسلة

أهلاً بكم! هذه هي المقالة الثانية في سلسلتنا التي نعرض فيها كيفية نشر تطبيقات الويب الحديثة على Red Hat OpenShift.

التطبيقات الحديثة على OpenShift، الجزء 2: البنيات المتسلسلة

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

صورة البناء النظيفة

كما ذكرنا في الجزء الأول، تحتوي معظم تطبيقات الويب الحديثة على ما يسمى بمرحلة البناء، والتي عادةً ما تؤدي عمليات مثل نقل التعليمات البرمجية وتسلسل الملفات المتعددة والتصغير. يتم تخزين الملفات التي تم الحصول عليها نتيجة لهذه العمليات - وهي ملفات HTML وJavaScript وCSS الثابتة - في مجلد الإخراج. يعتمد موقع هذا المجلد عادةً على أدوات البناء المستخدمة، وبالنسبة لـ React سيكون هذا هو المجلد ./build (سنعود إلى هذا بمزيد من التفاصيل أدناه).

المصدر إلى الصورة (S2I)

في هذه التدوينة لا نتطرق لموضوع "ما هو S2I وكيفية استخدامه" (يمكنك قراءة المزيد عن هذا هنا)، ولكن من المهم أن تكون واضحًا بشأن الخطوتين في هذه العملية لفهم ما تفعله صورة Web App Builder.

مرحلة التجميع

تشبه مرحلة التجميع بطبيعتها ما يحدث عند تشغيل docker build وينتهي الأمر بصورة Docker جديدة. وبناء على ذلك، تحدث هذه المرحلة عند بدء البناء على منصة OpenShift.

في حالة صورة Web App Builder، فهي مسؤولة عن تثبيت تبعيات تطبيقك وتشغيل الإنشاء. تجميع البرنامج النصي. افتراضيًا، تستخدم صورة المنشئ بنية البناء npm run، ولكن يمكن تجاوز ذلك من خلال متغير البيئة NPM_BUILD.

كما قلنا سابقًا، يعتمد موقع التطبيق النهائي والمبني بالفعل على الأدوات التي تستخدمها. على سبيل المثال، في حالة React سيكون هذا هو المجلد ./build، وبالنسبة للتطبيقات Angular سيكون المجلد project_name/dist. وكما هو موضح بالفعل في المنشور السابق، يمكن تجاوز موقع دليل الإخراج، الذي تم تعيينه للإنشاء افتراضيًا، من خلال متغير البيئة OUTPUT_DIR. حسنًا، نظرًا لأن موقع مجلد الإخراج يختلف من إطار عمل إلى إطار عمل آخر، فما عليك سوى نسخ المخرجات التي تم إنشاؤها إلى المجلد القياسي في الصورة، وهو /opt/apt-root/output. وهذا أمر مهم لفهم بقية هذه المقالة، ولكن الآن دعونا نلقي نظرة سريعة على المرحلة التالية - مرحلة التشغيل.

مرحلة التشغيل

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

تعد هذه الطريقة جيدة لنشر التطبيقات بسرعة، ولكن لا يُنصح عمومًا بتقديم محتوى ثابت بهذه الطريقة. حسنًا، نظرًا لأننا في الواقع لا نقدم سوى محتوى ثابت، فلا نحتاج إلى تثبيت Node.js داخل صورتنا - سيكون خادم الويب كافيًا.

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

يبني بالسلاسل

هذا ما يكتبون عنه يبني بالسلاسل في وثائق OpenShift:

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

بمعنى آخر، يمكننا استخدام صورة Web App Builder لتشغيل البناء الخاص بنا، ثم استخدام صورة خادم الويب، وهي نفس NGINX، لخدمة المحتوى الخاص بنا.

وبالتالي، يمكننا استخدام صورة Web App Builder كمنشئ "خالص" وفي نفس الوقت يكون لدينا صورة صغيرة لوقت التشغيل.

الآن دعونا نلقي نظرة على هذا بمثال محدد.

للتدريب سوف نستخدم تطبيق رد فعل بسيط، تم إنشاؤها باستخدام أداة سطر الأوامر create-react-app.

سوف يساعدنا على تجميع كل شيء معًا ملف قالب OpenShift.

دعونا نلقي نظرة على هذا الملف بمزيد من التفصيل، ونبدأ بقسم المعلمات.

parameters:
  - name: SOURCE_REPOSITORY_URL
    description: The source URL for the application
    displayName: Source URL
    required: true
  - name: SOURCE_REPOSITORY_REF
    description: The branch name for the application
    displayName: Source Branch
    value: master
    required: true
  - name: SOURCE_REPOSITORY_DIR
    description: The location within the source repo of the application
    displayName: Source Directory
    value: .
    required: true
  - name: OUTPUT_DIR
    description: The location of the compiled static files from your web apps builder
    displayName: Output Directory
    value: build
    required: false

كل شيء هنا واضح تمامًا، لكن الأمر يستحق الاهتمام بمعلمة OUTPUT_DIR. بالنسبة لتطبيق React في مثالنا، لا يوجد ما يدعو للقلق، نظرًا لأن React يستخدم القيمة الافتراضية كمجلد الإخراج، ولكن في حالة Angular أو أي شيء آخر، ستحتاج هذه المعلمة إلى التغيير حسب الضرورة.

الآن دعونا نلقي نظرة على قسم ImageStreams.

- apiVersion: v1
  kind: ImageStream
  metadata:
    name: react-web-app-builder  // 1 
  spec: {}
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: react-web-app-runtime  // 2 
  spec: {}
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: web-app-builder-runtime // 3
  spec:
    tags:
    - name: latest
      from:
        kind: DockerImage
        name: nodeshift/ubi8-s2i-web-app:10.x
- apiVersion: v1
  kind: ImageStream
  metadata:
    name: nginx-image-runtime // 4
  spec:
    tags:
    - name: latest
      from:
        kind: DockerImage
        name: 'centos/nginx-112-centos7:latest'

ألق نظرة على الصورتين الثالثة والرابعة. يتم تعريفهما على أنهما صور Docker، ويمكنك أن ترى بوضوح مصدرها.

الصورة الثالثة هي web-app-builder وهي تأتي منnodeshift/ubi8-s2i-web-app الموسوم بـ 10.x في محور عامل ميناء.

الرابعة هي صورة NGINX (الإصدار 1.12) مع تشغيل أحدث علامة محور عامل ميناء.

الآن دعونا نلقي نظرة على الصورتين الأوليين. كلاهما فارغ في البداية ويتم إنشاؤهما فقط أثناء مرحلة الإنشاء. ستكون الصورة الأولى، React-web-app-builder، نتيجة لخطوة التجميع التي ستدمج صورة وقت تشغيل web-app-builder-runtime وكود المصدر الخاص بنا. ولهذا السبب أضفنا "-builder" إلى اسم هذه الصورة.

الصورة الثانية - React-web-app-runtime - ستكون نتيجة دمج nginx-image-runtime وبعض الملفات من صورة React-web-app-builder. سيتم استخدام هذه الصورة أيضًا أثناء النشر وستحتوي فقط على خادم الويب وHTML وJavaScript وCSS الثابت لتطبيقنا.

مشوش؟ الآن دعونا نلقي نظرة على تكوينات البناء وسوف تصبح أكثر وضوحا قليلا.

يحتوي القالب الخاص بنا على تكوينين للبناء. هذا هو الأول، وهو قياسي جدًا:

  apiVersion: v1
  kind: BuildConfig
  metadata:
    name: react-web-app-builder
  spec:
    output:
      to:
        kind: ImageStreamTag
        name: react-web-app-builder:latest // 1
    source:   // 2 
      git:
        uri: ${SOURCE_REPOSITORY_URL}
        ref: ${SOURCE_REPOSITORY_REF}
      contextDir: ${SOURCE_REPOSITORY_DIR}
      type: Git
    strategy:
      sourceStrategy:
        env:
          - name: OUTPUT_DIR // 3 
            value: ${OUTPUT_DIR}
        from:
          kind: ImageStreamTag
          name: web-app-builder-runtime:latest // 4
        incremental: true // 5
      type: Source
    triggers: // 6
    - github:
        secret: ${GITHUB_WEBHOOK_SECRET}
      type: GitHub
    - type: ConfigChange
    - imageChange: {}
      type: ImageChange

كما ترون، يشير السطر ذو التسمية 1 إلى أنه سيتم وضع نتيجة هذا الإصدار في نفس صورة أداة إنشاء تطبيقات الويب التفاعلية التي رأيناها سابقًا في قسم ImageStreams.

يخبرك السطر المسمى 2 بمكان الحصول على الرمز منه. في حالتنا، هذا هو مستودع git، ويتم تحديد الموقع والمرجع ومجلد السياق من خلال المعلمات التي رأيناها بالفعل أعلاه.

السطر المسمى 3 هو ما رأيناه بالفعل في قسم المعلمات. فهو يضيف متغير البيئة OUTPUT_DIR، والذي في مثالنا هو build.
يشير السطر المسمى 4 إلى استخدام صورة وقت تشغيل تطبيق الويب، والتي رأيناها بالفعل في قسم ImageStream.

يشير السطر المسمى 5 إلى أننا نريد استخدام بنية تزايدية إذا كانت صورة S2I تدعمها، وكانت صورة Web App Builder تدعمها. عند الإطلاق الأول، بعد الانتهاء من مرحلة التجميع، ستحفظ الصورة مجلدNode_modules في ملف أرشيف. بعد ذلك، في عمليات التشغيل اللاحقة، ستقوم الصورة ببساطة بفك ضغط هذا المجلد لتقليل وقت الإنشاء.

وأخيرًا، السطر المسمى 6 هو مجرد عدد قليل من المحفزات لتشغيل البناء تلقائيًا، دون تدخل يدوي، عندما يتغير شيء ما.

بشكل عام، هذا تكوين بناء قياسي جدًا.

الآن دعونا نلقي نظرة على تكوين البناء الثاني. إنه مشابه جدًا للأول، ولكن هناك اختلاف مهم.

apiVersion: v1
  kind: BuildConfig
  metadata:
    name: react-web-app-runtime
  spec:
    output:
      to:
        kind: ImageStreamTag
        name: react-web-app-runtime:latest // 1
    source: // 2
      type: Image
      images:                              
        - from:
            kind: ImageStreamTag
            name: react-web-app-builder:latest // 3
          paths:
            - sourcePath: /opt/app-root/output/.  // 4
              destinationDir: .  // 5
             
    strategy: // 6
      sourceStrategy:
        from:
          kind: ImageStreamTag
          name: nginx-image-runtime:latest
        incremental: true
      type: Source
    triggers:
    - github:
        secret: ${GITHUB_WEBHOOK_SECRET}
      type: GitHub
    - type: ConfigChange
    - type: ImageChange
      imageChange: {}
    - type: ImageChange
      imageChange:
        from:
          kind: ImageStreamTag
          name: react-web-app-builder:latest // 7

لذا فإن تكوين البناء الثاني هو وقت تشغيل تطبيق الويب التفاعلي، ويبدأ بشكل قياسي جدًا.

السطر المسمى 1 ليس شيئًا جديدًا - فهو يشير ببساطة إلى أنه تم وضع نتيجة البناء في صورة وقت تشغيل تطبيق الويب التفاعلي.

يشير السطر المسمى 2، كما في التكوين السابق، إلى مكان الحصول على الكود المصدري منه. لكن لاحظ أننا هنا نقول أنها مأخوذة من الصورة. علاوة على ذلك، من الصورة التي أنشأناها للتو - من React-web-app-builder (المشار إليه في السطر المسمى 3). الملفات التي نريد استخدامها موجودة داخل الصورة وموقعها هناك محدد في السطر المسمى 4، في حالتنا هو /opt/app-root/output/. إذا كنت تتذكر، فهذا هو المكان الذي يتم فيه تخزين الملفات التي تم إنشاؤها بناءً على نتائج بناء تطبيقنا.

المجلد الوجهة المحدد في المصطلح بالتسمية 5 هو ببساطة الدليل الحالي (تذكر أن هذا كل شيء، يعمل داخل شيء سحري يسمى OpenShift، وليس على جهاز الكمبيوتر المحلي الخاص بك).

قسم الإستراتيجية - السطر المسمى 6 - يشبه أيضًا تكوين البناء الأول. هذه المرة فقط سنستخدم nginx-image-runtime، والذي رأيناه بالفعل في قسم ImageStream.

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

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

نشر التطبيق

والآن بعد أن ألقينا نظرة على القالب، دعونا نرى كيفية استخدامه لنشر التطبيق.

يمكننا استخدام أداة عميل OpenShift التي تسمى oc لنشر القالب الخاص بنا:

$ find . | grep openshiftio | grep application | xargs -n 1 oc apply -f

$ oc new-app --template react-web-app -p SOURCE_REPOSITORY_URL=https://github.com/lholmquist/react-web-app

الأمر الأول في لقطة الشاشة أعلاه هو طريقة هندسية متعمدة للعثور على القالب./openshiftio/application.yaml.

يقوم الأمر الثاني ببساطة بإنشاء تطبيق جديد بناءً على هذا القالب.

بعد عمل هذه الأوامر سنرى أن لدينا مجموعتين:

التطبيقات الحديثة على OpenShift، الجزء 2: البنيات المتسلسلة

وبالعودة إلى شاشة النظرة العامة، سنرى الكبسولة التي تم إطلاقها:

التطبيقات الحديثة على OpenShift، الجزء 2: البنيات المتسلسلة

انقر على الرابط وسيتم نقلك إلى تطبيقنا، وهو صفحة تطبيق React الافتراضية:

التطبيقات الحديثة على OpenShift، الجزء 2: البنيات المتسلسلة

الملحق 1

لعشاق Angular لدينا أيضًا تطبيق المثال.

النمط هنا هو نفسه، باستثناء المتغير OUTPUT_DIR.

الملحق 2

استخدمنا في هذه المقالة NGINX كخادم ويب، ولكن من السهل جدًا استبداله بـ Apache، فقط قم بتغيير القالب الموجود في الملف صورة ‏‎NGINX‎‏ في صورة أباتشي.

اختتام

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

محتويات هذه السلسلة من المقالات

  • جزء 1: كيفية نشر تطبيقات الويب الحديثة في خطوات قليلة فقط;
  • الجزء 2: كيفية استخدام صورة S2I جديدة مع صورة خادم HTTP موجودة، مثل NGINX، باستخدام تجميعات OpenShift المرتبطة لنشر الإنتاج؛
  • الجزء 3: كيفية تشغيل خادم تطوير لتطبيقك على منصة OpenShift ومزامنته مع نظام الملفات المحلي.

مصادر إضافية

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

إضافة تعليق