من الحاويات إلى kubernetes جدولة تطبيق Node.js مع MongoDB على Kubernetes باستخدام Helm


عبد الصمد العماري

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

يختار العديد من المطورين استخدام مدير الحزمة Helm عند إنشاء عمليات نشر متعددة الخدمات باستخدام Kubernetes. ويبسّط Helm عملية إنشاء موارد Kubernetes متعددة من خلال تقديم مخططات وقوالب تنسق كيفية تفاعل هذه الكائنات. كما يقدم أيضًا مخططات مُهيأة مسبقًا لمشاريع مفتوحة المصدر.

في هذا الدرس، سوف تنشر تطبيق Node.js بقاعدة بيانات MongoDB على عنقود Kubernetes باستخدام مخططات Helm. ستستخدم مخطط تعيين النسخة المتماثلة Helm MongoDB الرسمي لإنشاء كائن StatefulSet يتكون من ثلاث علب (pods) وخدمة بدون رأس (stateless) وثلاث طلبات وحدة تخزين ثابتة PersistentVolumeClaims. ستُنشئ أيضًا مخططًا لنشر تطبيق Node.js متعدد النسخ باستخدام صورة تطبيق مخصصة. سيعكس الإعداد الذي ستنشئه في هذا البرنامج التعليمي وظيفة الشيفرة الموضحة في كيفية إعداد تطبيق node.js لسير عملٍ يعتمد على الحاويات باستخدام Docker Compose وسيكون نقطة انطلاق جيدة لإنشاء تطبيق Node.js مرن مع مخزن بيانات MongoDB يتناسب مع احتياجاتك.

المتطلبات الأساسية

لإكمال هذا الدرس، ستحتاج إلى:

الخطوة الأولى: استنساخ وتحزيم التطبيق

لاستخدام تطبيقنا على Kubernetes، سنحتاج إلى تحزيمه حتى تتمكن الأداة kubelet من سحب الصورة.

سنحتاج قبل تحزيم التطبيق، مع ذلك، إلى تعديل العنوان URI لاتصال MongoDB في شيفرة التطبيق للتأكد من أن تطبيقنا يستطيع الاتصال بعناصر مجموعة النسخ المتماثلة التي سننشئها باستخدام مخطط Helm mongodb-replicaset.

ستكون خطوتنا الأولى هي استنساخ مستودع node-mongo-docker-dev من حساب DigitalOcean Community GitHub. يتضمن هذا المستودع شيفرة الإعداد الموضح في كيفية إعداد تطبيق node.js لسير عملٍ يعتمد على الحاويات باستخدام Docker Compose، والذي يستخدم تطبيق Node.js لشرح كيفية إعداد بيئة تطوير باستخدام Docker Compose. يمكنك العثور على مزيد من المعلومات حول التطبيق نفسه في سلسلة من الحاويات إلى Kubernetes باستخدام Node.js.

انسخ المستودع في مجلّد يسمى node_project:

git clone https://github.com/do-community/node-mongo-docker-dev.git node_project

انتقل إلى المجلّد node_project:

cd node_project

يحتوي مجلّد node_project على ملفات ومجلدات لتطبيق معلومات سمك القرش الذي يعمل على مدخلات المستخدم. تمّ تحديثه للعمل على الحاويات وأزيلت منه معلومات التكوين الحساسة والمحددة في شيفرة التطبيق وأُعيد تشكيلها من أجل حقنها عند تنفيذ التطبيق، كما أُلغيَ تحميل حالة التطبيق إلى قاعدة بيانات MongoDB.

لمزيد من المعلومات حول تصميم التطبيقات الحديثة عديمة الحالة، يرجى الاطلاع على هيكلة التطبيقات ل Kubernetes وتحديث التطبيقات لKubernetes.

عندما ننشر مخطط Helm mongodb-replicaset، فسينشئ ما يلي:

  • كائن StatefulSet بثلاث علب تمثّل مجموعة النسخ المتماثلة MongoDB. سيكون لكل علبة طلب PersistentVolumeClaim مرتبط وسيحتفظ بهوية ثابتة في حالة إعادة الجدولة.
  • مجموعة نسخ متماثلة MongoDB تتكون من العلب الموجودة في StatefulSet. سوف تشمل المجموعة واحدة ابتدائية واثنتان ثانويتان. ستُنسَخ البيانات من العلبة الابتدائية إلى الثانويتين، مما يضمن إتاحة بيانات التطبيق على أعلى مستوى.
  • لكي يتفاعل تطبيقنا مع النسخ المتماثلة لقاعدة البيانات، سيتطلب الأمر تضمين أسماء المضيفين (hostnames) لعناصر مجموعة النسخ المتماثلة بالإضافة إلى اسم النسخة المتماثلة نفسها في العنوان URI لاتصال MongoDB في الشيفرة.

يُسمّى الملف الموجود في مخزننا المستنسخ والذي يحدد معلومات اتصال قاعدة البيانات db.js. افتح هذا الملف الآن باستخدام nano أو المحرر المفضل لديك:

nano db.js

يشتمل الملف حاليًا على قيم ثابتة يمكن الرجوع إليها في اتصال URI لقاعدة البيانات أثناء التشغيل. تُحقًن هذه القيم الثابتة باستخدام خاصية process.env الخاصة ب Node، والتي تُعيد كائنًا يحتوي على معلوماتٍ حول بيئة المستخدم الخاصة بك في وقت التشغيل. يتيح لنا تحديد القيم ديناميكيًا في شيفرة التطبيق فصل الشيفرة عن البنية التحتية الأساسية، وهو أمر ضروري في بيئة ديناميكية وعديمة الحالة (stateless). لمزيد من المعلومات حول إعادة تشكيل شيفرة التطبيق بهذه الطريقة، راجع الخطوة الثانية من كيفية إعداد تطبيق node.js لسير عملٍ يعتمد على الحاويات باستخدام Docker Compose.

تبدو ثوابت الاتصال URI وسلسلة URI نفسها حاليًا كما يلي:

...
const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;

...

const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;
...

تماشيا مع الطريقة 12FA، لا نريد ترميز أسماء مضيفي مثيلات النسخ المتماثلة أو اسم مجموعة النسخ المتماثلة في سلسلة URI هذه. يمكننا توسيع الثابت MONGO_HOSTNAME الحالي ليشمل عِدّة أسماء مضيفين لعناصر مجموعة النسخ المتماثلة. لذلك سنترك الأمر على حاله. وسنحتاج، مع ذلك، إلى إضافة مجموعة متماثلة ثابتة إلى قسم الخيارات في سلسلة URI.

أضف MONGO_REPLICASET إلى كل من كائن الثابت URI وسلسلة الاتصال:

...
const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB,
  MONGO_REPLICASET
} = process.env;

...
const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?replicaSet=${MONGO_REPLICASET}&authSource=admin`;
...

يتيح استخدام خيار replicaSet في قسم الخيارات في URI تمرير اسم مجموعة النسخ المتماثلة، والتي تتيح لنا بمعية أسماء المضيفين المحدّدة في ثابت MONGO_HOSTNAME الاتصال بعناصر المجموعة.

احفظ الملف وأغلقه عند الانتهاء من التحرير.

بعد تعديل معلومات اتصال قاعدة البيانات الخاصة بك للعمل مع مجموعات النسخ المتماثلة، يمكنك الآن تحزيم تطبيقك، وبناء الصورة باستخدام الأمر docker build، ودفعها إلى Docker Hub.

ابدأ ببناء الصورة باستخدام Docker والراية t- التي تتيح لك تعليم الصورة باسم لا يُنسى. في هذه الحالة، علّم الصورة باسم مستخدمك Docker Hub وسَمِّها node-replicas أو اسمًا تختاره أنت:

docker build -t your_dockerhub_username/node-replicas .

تحدد النقطة . في الأمر أن سياق البناء هو المجلّد الحالي.

سوف يستغرق الأمر دقيقة أو دقيقتين لبناء الصورة. بمجرد اكتماله، تحقق من صورك:

docker images

سوف يظهر لك الإخراج التالي:

REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
your_dockerhub_username/node-replicas   latest              56a69b4bc882        7 seconds ago       90.1MB
node                                    10-alpine           aa57b0242b33        6 days ago

بعد ذلك، سجّل الدخول إلى حساب Docker Hub الذي أنشأته في المتطلبات الأساسية:

docker login -u your_dockerhub_username

عندما يطلب منك ذلك، أدخل كلمة مرور حساب Docker Hub. سيؤدي التسجيل بهذه الطريقة إلى إنشاء ملف ‎~/.docker/config.json في المجلّد الرئيسي لمستخدمك غير الجذري باستخدام بيانات اعتماد Docker Hub.

ادفع صورة التطبيق إلى Docker Hub باستخدام الأمر docker push.‎ ولا تنس أن تعوّض yourdockerhubusername باسم مستخدمك Docker Hub:

docker push your_dockerhub_username/node-replicas

لديك الآن صورة للتطبيق يمكنك سحبها لتشغيل التطبيق المنسوخ باستخدام Kubernetes. ستكون الخطوة التالية هي إعداد بارامترات محدّدة لاستخدامها مع مخطط Helm ل MongoDB.

الخطوة الثانية: إنشاء أسرار لمجموعة النسخ المتماثلة MongoDB

يوفر المخطط stable/mongodb-replicaset خيارات مختلفة عندما يتعلق الأمر باستخدام الأسرار، وسننشئ منها خيارين لاستخدامهما في نشر المخطط:

  • سرٌّ (secret) لمجموعة ملفات النسخ المتماثلة سيعمل ككلمة مرور مشتركة بين عناصر مجموعة النسخ المتماثلة، مما يسمح بتصديق الهوية لأعضاء آخرين.
  • سرٌّ للمستخدم المشرف في MongoDB، الذي سيتم إنشاؤه كمستخدم الجذر في قاعدة بيانات المشرف. سيتيح هذا الدور بإنشاء مستخدمين لاحقًا بأذونات محدودة عند نشر تطبيقك على الإنتاج.

بإنشائنا لهذه الأسرار، سنكون قادرين على تعيين قيم المعاملات المفضلة لدينا في ملف قيم مخصص وإنشاء كائن StatefulSet ونسخة متماثلة MongoDB مع مخطط Helm.

دعنا أولًا ننشئ ملف keyfile. سنستخدم الأمر openssl مع خيار rand لإنشاء سلسلة عشوائية بحجم 756 بايت لملف keyfile:

openssl rand -base64 756 > key.txt

سيُشفَّر الإخراج الذي أُنشِئ باستخدام الأمر base64، مما يضمن نقل بيانات موحد، كما سيُعاد توجيهه إلى ملف يسمى key.txt، باتباع الإرشادات الواردة في وثائق مصادقة تخطيط mongodb-replicaset. يجب أن يتراوح طول المفتاح نفسه بين 6 محارف و 1024 محرفًا، ويتألف فقط من المحارف في مجموعة base64.

يمكنك الآن إنشاء سر يسمى keyfilesecret على هذا الملف باستخدام kubectl create:

kubectl create secret generic keyfilesecret --from-file=key.txt

سيُنشئ هذا كائنًا سرًّا في المجال الاسمي الافتراضي، نظرًا لأننا لم ننشئ مجالًا اسميًا محددا لإعدادنا.

سيظهر لك الإخراج التالي مشيرًا إلى إنشاء سرّك:

secret/keyfilesecret created

احذف key.txt:

rm key.txt

إذا كنت ترغب في حفظ الملف بدلاً من ذلك، فتأكد من تقييد أذوناته وإضافته إلى ملفك gitignore. لإبقائه خارج تحكم الإصدارات.

بعد ذلك، أنشئ سرًّا لمستخدمك المشرف في MongoDB. ستكون الخطوة الأولى هي تحويل اسم المستخدم وكلمة المرور المطلوبين إلى base64.

ابدأ بتحويل اسم مستخدم قاعدة بياناتك:

echo -n 'your_database_username' | base64

دوّن القيمة التي تظهر في الإخراج. بعد ذلك، حوّل كلمة مرورك:

echo -n 'your_database_password' | base64

دوّن القيمة الظاهرة في الإخراج هنا أيضا. افتح ملف السر:

nano secret.yaml

ملاحظة: تُحدّد كائنات Kubernetes عادة باستخدام YAML، الذي يمنع بصرامة علامات التبويب ويتطلب مسافتين للمسافة البادئة. إذا كنت ترغب في التحقق من تنسيق أي من ملفاتك YAML، فيمكنك استخدام linter أو اختبار صحّة صياغة (syntax) تركيبك باستخدام kubectl create مع الرايتين dry-run-- و validate--:

kubectl create -f your_yaml_file.yaml --dry-run --validate=true

بشكل عام، من المستحسن التحقق من صحة الصياغة قبل إنشاء الموارد باستخدام kubectl.

أضف الشيفرة التالية إلى الملف لإنشاء سرّ يحدد المستخدم وكلمة المرور مع القيم المشفرة التي أنشأتها للتو. لا تنس تعويض القيم الوهمية هنا باسم المستخدم وكلمة المرور المشفرة:

apiVersion: v1
kind: Secret
metadata:
  name: mongo-secret
data:
  user: your_encoded_username
  password: your_encoded_password

نحن نستخدم هنا أسماء المفاتيح التي يتوقعها مخطط mongodb-replicaset: المستخدم وكلمة المرور. ولقد سمّينا كائن السرّ mongo-secret، ولكن تستطيع تسميته كما تشاء.

احفظ الملف وأغلقه عند الانتهاء من التحرير. أنشئ كائن السرّ باستخدام الأمر التالي:

kubectl create -f secret.yaml

سيظهر لك في الإخراج ما يلي:

secret/mongo-secret created

يمكنك مرة أخرى إما حذف secret.yaml أو تقييد أذوناته وإضافته إلى ملفك gitignore..

بعد إنشاء كائنات السرّ، يمكنك الانتقال إلى تحديد قيم المعاملات التي ستستخدمها مع مخطط mongodb-replicaset وإنشاء نشر MongoDB.

الخطوة الثالثة: تكوين المخطّط MongoDB Helm وإنشاء النشر

يأتي Helm مع مستودع نشط ومحفوظ يدعى stable والذي يحتوي على المخطط الذي سنستخدمه: mongodb-replicaset. لاستخدام هذا المخطط مع الأسرار التي أنشأناها للتو، سننشئ ملفًا به قيم معاملات التكوين يسمى mongodb-values.yaml ثم نثبت المخطط باستخدام هذا الملف.

سوف يعكس ملفنا mongodb-values.yaml إلى حد كبير ملف value.yaml الافتراضي في مستودع تخزين المخطط mongodb-replicaset. ومع ذلك، سنجري التغييرات التالية على ملفنا:

  • سنعيّن المعامل auth على القيمة true لنضمن تفعيل التفويض (authorization) عند بدء اشتغال مثيلات قاعدة البيانات. هذا يعني أنه سيُطلب من جميع العملاء تصديق الهوية للوصول إلى موارد وعمليات قاعدة البيانات.
  • سنضيف معلومات حول الأسرار التي أنشأناها في الخطوة السابقة حتى يتمكن المخطط من استخدام هذه القيم لإنشاء مجموعة النسخ المتماثلة keyfile والمستخدم المشرف.
  • سنقلّل من سعة وحدات التخزين الثابتة PersistentVolumes المرتبطة بكل علبة Pod في مجموعة StatefulSet لاستخدام الحد الأدنى القابل للتطبيق في وحدات التخزين DigitalOcean ، المحدّد في 1 جيجابايت، رغم أنك تبقى حرًّا في تعديل هذه القيمة لتلبية متطلبات التخزين الخاصة بك.

يجب عليك أولاً قبل كتابة ملف mongodb-values.yaml، ومع ذلك، التحقق من أنّك لديك صنف StorageClass أُنشِئ وأُعِدّ لتوفير موارد التخزين. سيكون لكل علبة موجودة في قاعدة بياناتك StatefulSet هوية ملازمة وما يرتبط بها من طلبات PersistentVolumeClaim، والتي ستوفر PersistentVolume ديناميكيًا للعلبة. إذا أُعيدت جدولة العلبة، فستثبّت PersistentVolume على أي عقدة (node) تُجدول عليها العلبة Pod (رغم أنه ينبغي حذف كل وحدة تخزين يدويًا إذا حذفت العلبة Pod أو StatefulSet المقترن بها نهائيًا).

وبما أننا نعمل على DigitalOcean Kubernetes، فإن مزود StorageClass الافتراضي الخاص بنا يعيّن على dobs.csi.digitalocean.com أي وحدة التخزين DigitalOcean. ويمكننا التحقق من ذلك بكتابة:

kubectl get storageclass

إذا كنت تعمل عل عنقود DigitalOcean، فسترى في الإخراج مايلي:

NAME                         PROVISIONER                 AGE
do-block-storage (default)   dobs.csi.digitalocean.com   21m

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

الآن وبعد التأكد من تكوين StorageClass، افتح الملفّ mongodb-values.yaml لتحريره:

nano mongodb-values.yaml

سوف نعيّن القيم في هذا الملف للقيام بما يلي:

  • تفعيل التفويض.
  • تحديد مراجع لملفك keyfilesecret وكائناتك mongo-secret.
  • تحديد القيمة Gi1 لـ PersistentVolumes.
  • تعيين اسم مجموعة النسخ المتماثلة على db.
  • تحديد 3 نسخ متماثلة للمجموعة.
  • تثبيت صورة mongo بأحدث إصدار.

انسخ الشيفرة التالية إلى الملف:

replicas: 3
port: 27017
replicaSetName: db
podDisruptionBudget: {}
auth:
  enabled: true
  existingKeySecret: keyfilesecret
  existingAdminSecret: mongo-secret
imagePullSecrets: []
installImage:
  repository: unguiculus/mongodb-install
  tag: 0.7
  pullPolicy: Always
copyConfigImage:
  repository: busybox
  tag: 1.29.3
  pullPolicy: Always
image:
  repository: mongo
  tag: 4.1.9
  pullPolicy: Always
extraVars: {}
metrics:
  enabled: false
  image:
    repository: ssalaues/mongodb-exporter
    tag: 0.6.1
    pullPolicy: IfNotPresent
  port: 9216
  path: /metrics
  socketTimeout: 3s
  syncTimeout: 1m
  prometheusServiceDiscovery: true
  resources: {}
podAnnotations: {}
securityContext:
  enabled: true
  runAsUser: 999
  fsGroup: 999
  runAsNonRoot: true
init:
  resources: {}
  timeout: 900
resources: {}
nodeSelector: {}
affinity: {}
tolerations: []
extraLabels: {}
persistentVolume:
  enabled: true
  #storageClass: "-"
  accessModes:
    - ReadWriteOnce
  size: 1Gi
  annotations: {}
serviceAnnotations: {}
terminationGracePeriodSeconds: 30
tls:
  enabled: false
configmap: {}
readinessProbe:
  initialDelaySeconds: 5
  timeoutSeconds: 1
  failureThreshold: 3
  periodSeconds: 10
  successThreshold: 1
livenessProbe:
  initialDelaySeconds: 30
  timeoutSeconds: 5
  failureThreshold: 3
  periodSeconds: 10
  successThreshold: 1

يوجد هنا تعليق على المُعامل persistentVolume.storageClass: سيؤدي حذف التعليق وتعيين قيمته على "-" إلى تعطيل التزويد الديناميكي. في حالتنا هذه، نظرًا لأننا نترك هذه القيمة غير محددة، فإن المخطط سيختار المزود الافتراضي، أي dobs.csi.digitalocean.com.

لاحظ أيضًا وضع الولوج accessMode المقترن بالمفتاح persistentVolume: يعني ReadWriteOnce أن وحدة التخزين المتوفرة ستكون للقراءة والكتابة بواسطة عقدة واحدة فقط. يرجى الاطلاع على التوثيق لمزيد من المعلومات حول أوضاع الولوج المختلفة.

لمعرفة المزيد حول المعاملات الأخرى المضمنة في الملف، راجع جدول التكوين المضمّن في المستودع.

احفظ الملف وأغلقه عند الانتهاء من التحرير.

قبل نشر مخطط mongodb-replicaset، ستحتاج إلى تحديث المستودع الثابت stable باستخدام الأمر helm repo update:

helm repo update

سيستخرج هذا أحدث معلومات المخطط من المستودع الثابت.

أخيرًا، ثبّت المخطط باستخدام الأمر التالي:

helm install --name mongo -f mongodb-values.yaml stable/mongodb-replicaset

ملاحظة: قبل تثبيت أحد المخططات، يمكنك تنفيذ helm install باستخدام الخيارين run dry-- و debug-- للتحقق من البيانات التي أُنشئت لإصدارك:

helm install --name your_release_name -f your_values_file.yaml --dry-run --debug your_chart

لاحظ أننا نسمي إصدار Helm بالاسمmongo. سوف يشير هذا الاسم إلى هذا النشر المحدد للمخطط بخيارات التكوين التي حددناها. لقد أشرنا إلى هذه الخيارات من خلال تضمين الراية f- وملفنا mongodb-values.yaml.

لاحظ أيضًا أنه نظرًا لأننا لم نضمّن الراية ‎--namespace مع helm install، سيكون إنشاء كائنات المخطط في المجال الاسمي الافتراضي.

بمجرد إنشاء الإصدار، ستظهر حالته في الإخراج، إلى جانب معلومات حول الكائنات التي أُنشِئت وإرشادات للتفاعل معها:

NAME:   mongo
LAST DEPLOYED: Tue Apr 16 21:51:05 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                              DATA  AGE
mongo-mongodb-replicaset-init     1     1s
mongo-mongodb-replicaset-mongodb  1     1s
mongo-mongodb-replicaset-tests    1     0s
...

يمكنك الآن التحقق من إنشاء علبك pods باستخدام الأمر التالي:

kubectl get pods

سيظهر لك في الإخراج مايلي عند إنشاء العلب:

NAME                         READY   STATUS     RESTARTS   AGE
mongo-mongodb-replicaset-0   1/1     Running    0          67s
mongo-mongodb-replicaset-1   0/1     Init:0/3   0          8s

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

بعد إنشاء العلب وتشغيل جميع الحاويات المرتبطة بها، سيظهر لك هذا الإخراج:

NAME                         READY   STATUS    RESTARTS   AGE
mongo-mongodb-replicaset-0   1/1     Running   0          2m33s
mongo-mongodb-replicaset-1   1/1     Running   0          94s
mongo-mongodb-replicaset-2   1/1     Running   0          36s

يشير Running STATUS إلى أن علبك مرتبطة بالعقد وأن الحاويات المرتبطة بتلك العلب تعمل. ويشير READY إلى عدد الحاويات الموجودة في العلب. لمزيد من المعلومات، يرجى الرجوع إلى وثائق دورة حياة العلبة.

ملحوظة

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

kubectl describe pods your_pod
kubectl logs your_pod

لكل علبة موجودة في StatefulSet اسم يجمع اسم StatefulSet مع الرقم الترتيبي للعلبة. ونظرًا لأننا أنشأنا ثلاث نسخ متماثلة، ترقَّم عناصر StatefulSet من 0 إلى 2، ولكل منها إدخال DNS ثابت يتكون من العناصر التالية:

‎$(statefulset-name)-$(ordinal).$(service name).$(namespace).svc.cluster.local.

في حالتنا هذه، لكلّ من StatefulSet والخدمة بدون ترويسة التي أنشأها مخطط mongodb-replicaset نفس الاسم:

kubectl get statefulset
NAME                       READY   AGE
mongo-mongodb-replicaset   3/3     4m2s
kubectl get svc
NAME                              TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE
kubernetes                        ClusterIP   10.245.0.1   <none>        443/TCP     42m
mongo-mongodb-replicaset          ClusterIP   None         <none>        27017/TCP   4m35s
mongo-mongodb-replicaset-client   ClusterIP   None         <none>        27017/TCP   4m35s

هذا يعني أن العنصر الأول في StatefulSet سيحصل على إدخال DNS التالي:

mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local

ولأننا نحتاج إلى أن يتصل تطبيقنا بكل نسخة من إصدارات MongoDB، فمن الضروري أن تتوفر لدينا هذه المعلومات حتى نتمكن من التواصل مباشرة مع العلب، وليس مع الخدمة. عندما ننشئ مخطط Helm للتطبيق المخصص، سنمرّر إدخالات DNS لكل علبة إلى تطبيقنا باستخدام متغيرات البيئة.

بعد تشغيل مثيلات قاعدة بياناتك ، يمكنك البدء في إنشاء المخطط لتطبيقك Node.

الخطوة الرابعة: إنشاء مخطط تطبيق مخصّص وتكوين المعاملات

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

ابدأ أولاً بإنشاء مجلّد مخطط جديد يسمى nodeapp باستخدام الأمر التالي:

helm create nodeapp

سيؤدي هذا إلى إنشاء مجلّد بالاسم nodeapp في المجلد ‎~/node_project بالموارد التالية:

  • ملف Chart.yaml يحتوي على معلومات أساسية حول المخطط.

  • ملف value.yaml يتيح لك تعيين قيم معاملات محددة، كما فعلت مع نشر MongoDB.

  • ملف helmignore. مع أنماط الملفات والمجلّد التي سيتم تجاهلها عند تحزيم المخططات.

  • مجلّد templates/ بملفات القوالب التي سيولّدها Kubernetes.

  • مجلّد templates/tests/ لملفات الاختبار.

  • مجلّد charts/ لأي مخططات يعتمد عليها هذا المخطط.

    value.yaml هو الملف الأول الذي سنعدّله من هذه الملفات الافتراضية. افتح هذا الملف الآن:

nano nodeapp/values.yaml

تشمل القيم التي سنضعها هنا ما يلي:

  • عدد النسخ المتماثلة.
  • صورة التطبيق التي نريد استخدامها. في حالتنا، ستكون هذه هي صورة النسخ المتماثلة للعقدة التي أنشأناها في الخطوة الأولى.
  • نوع الخدمة. في هذه الحالة، سنحدد LoadBalancer لإنشاء نقطة وصول إلى تطبيقنا لأغراض الاختبار. ونظرًا لأننا نعمل على عنقود DigitalOcean Kubernetes، فسيؤدي ذلك إلى إنشاء موازن تحميل DigitalOcean عند نشر مخططنا. يمكنك في الإنتاج تكوين مخططك لاستخدام موارد Ingress و Controllers لتوجيه حركة المرور إلى خدماتك.
  • المنفذ المستهدف targetPort لتحديد المنفذ على العلبة Pod حيث سيتم الكشف عن تطبيقنا.

لن ندخل متغيرات البيئة في هذا الملف. وبدلاً من ذلك، سننشئ قوالب لـ ConfigMap وكائنات السرّ ونضيف هذه القيم إلى بيان نشر التطبيق (application Deployment manifest) ، الموجود في ‎~/node_project/nodeapp/templates/deployment.yaml.

أضف تكوين القيم التالية في ملف values.yaml:

# Default values for nodeapp.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 3

image:
  repository: your_dockerhub_username/node-replicas
  tag: latest
  pullPolicy: IfNotPresent

nameOverride: ""
fullnameOverride: ""

service:
  type: LoadBalancer
  port: 80
  targetPort: 8080
...

احفظ الملف وأغلقه عند الانتهاء من التحرير.

بعد ذلك، افتح ملف secret.yaml في المجلّد nodeapp/templates:

nano nodeapp/templates/secret.yaml

أضف في هذا الملف قيمًا لثوابت التطبيق MONGOUSERNAME و MONGOPASSWORD. هذه هي الثوابت التي يتوقع تطبيقك الوصول إليها أثناء التشغيل، كما هو محدّد في db.js، ملف اتصال قاعدة البيانات. وأثناء إضافتك لقيم هذه الثوابت، لا تنس استخدام القيم المرمّزة base64 التي استخدمتها سابقًا في الخطوة الثانية عند إنشاء الكائن mongo-secret. إذا كنت بحاجة إلى إعادة إنشاء هذه القيم، يمكنك العودة إلى الخطوة الثانية ونفّذ الأوامر ذات الصلة مرة أخرى.

أضف الشيفرة التالية إلى الملف:

apiVersion: v1
kind: Secret
metadata:
  name: {{ .Release.Name }}-auth
data:
  MONGO_USERNAME: your_encoded_username
  MONGO_PASSWORD: your_encoded_password

يعتمد اسم كائن السرّ هذا على اسم إصدار Helm، والذي ستحدّده عند نشر مخطط التطبيق.

احفظ الملف وأغلقه عند الانتهاء. بعد ذلك، افتح ملفًا لإنشاء ConfigMap لتطبيقك:

nano nodeapp/templates/configmap.yaml

سوف نحدد في هذا الملف المتغيرات المتبقية التي ينتظرها تطبيقنا: MONGO_HOSTNAME و MONGO_PORT و MONGO_DB و MONGO_REPLICASET. سيتضمن متغير MONGO_HOSTNAME إدخال DNS لكل مثيل في مجموعة النسخ المتماثلة، إذ أن هذا هو ما يتطلبه عنوان URI لاتصال MongoDB.

وفقًا لتوثيق Kubernetes، عندما يقوم أحد التطبيقات بإجراء اختبارات الصلاحية والاستعداد، يجب استخدام سجلات SRV عند الاتصال بـالعلب Pods. وكما تطرقنا إليه في الخطوة الثالثة، تتبع سجلات SRV للعلبة هذا النموذج: ‎$(statefulset-name)-$(ordinal).$(service name).$(namespace).svc.cluster.local. ونظرًا لأن تطبيق StatefulSet يجري عمليات فحص الثبات والاستعداد، فسيتوجب علينا استخدام هذه المعرّفات الثابتة عند تحديد قيم المتغير MONGO_HOSTNAME.

أضف الشيفرة التالية إلى الملف لتعريف متغيرات MONGOHOSTNAME و MONGOPORT و MONGODB و MONGOREPLICASET. وتبقى لك الحرية في استخدام اسم آخر لقاعدة بيانات MONGODB، ولكن يجب أن تكتب قيمك MONGOHOSTNAME و MONGO_REPLICASET مثلما تظهر هنا:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-config
data:
  MONGO_HOSTNAME: "mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local,mongo-mongodb-replicaset-1.mongo-mongodb-replicaset.default.svc.cluster.local,mongo-mongodb-replicaset-2.mongo-mongodb-replicaset.default.svc.cluster.local"  
  MONGO_PORT: "27017"
  MONGO_DB: "sharkinfo"
  MONGO_REPLICASET: "db"

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

لاحظ أيضًا أن القيم المذكورة هنا موضوعة في شكل اقتباس، وهو ما يتوقّعه Helm لمتغيرات البيئة.

احفظ الملف وأغلقه عند الانتهاء من التحرير.

بعد تحديد قيم معاملات مخطّطك وإنشاء قوائم Secret و ConfigMap، يمكنك المرور لتحرير قالب نشر التطبيق لاستخدام متغيرات البيئة الخاصة بك.

الخطوة الخامسة: دمج متغيرات البيئة في نشر Helm

بعد إعدادنا لملفات التطبيق Secret و ConfigMap، سنحتاج إلى التأكد من أن نشر تطبيقنا يستطيع استخدام هذه القيم. وسنعمل أيضًا على تخصيص اختبارات الثبات والاستعداد التي حُدّدت بالفعل في بيان النشر.

افتح قالب نشر التطبيق للتحرير:

nano nodeapp/templates/deployment.yaml

رغم أنّ هذا ملف YAML، فإن قوالب Helm تستخدم صياغة تركيب مختلفة عن ملفات YAML المعيارية Kubernetes لإنشاء كشوف البيانات. لمزيد من المعلومات حول القوالب، راجع توثيق Helm.

أضف في الملف أولاً مفتاح env لمواصفات حاوية التطبيق، أسفل مفتاح imagePullPolicy وأعلى ports:

apiVersion: apps/v1
kind: Deployment
metadata:
...
  spec:
    containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        env:
        ports:

بعد ذلك، أضف المفاتيح التالية إلى قائمة متغيرات env:

apiVersion: apps/v1
kind: Deployment
metadata:
...
  spec:
    containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        env:
        - name: MONGO_USERNAME
          valueFrom:
            secretKeyRef:
              key: MONGO_USERNAME
              name: {{ .Release.Name }}-auth
        - name: MONGO_PASSWORD
          valueFrom:
            secretKeyRef:
              key: MONGO_PASSWORD
              name: {{ .Release.Name }}-auth
        - name: MONGO_HOSTNAME
          valueFrom:
            configMapKeyRef:
              key: MONGO_HOSTNAME
              name: {{ .Release.Name }}-config
        - name: MONGO_PORT
          valueFrom:
            configMapKeyRef:
              key: MONGO_PORT
              name: {{ .Release.Name }}-config
        - name: MONGO_DB
          valueFrom:
            configMapKeyRef:
              key: MONGO_DB
              name: {{ .Release.Name }}-config      
        - name: MONGO_REPLICASET
          valueFrom:
            configMapKeyRef:
              key: MONGO_REPLICASET
              name: {{ .Release.Name }}-config       

يتضمن كل متغير مرجعًا إلى قيمته، يعرّف إما بمفتاح secretKeyRef، في حالة قيم السرّ، أو configMapKeyRef لقيم ConfigMap. تشير هذه المفاتيح إلى ملفات Secret و ConfigMap التي أنشأناها في الخطوة السابقة.

بعد ذلك، تحت المفتاح ports، عدّل تعريف containerPort لتحديد المنفذ الموجود في الحاوية التي سيُعرَض عليها تطبيقنا:

apiVersion: apps/v1
kind: Deployment
metadata:
...
  spec:
    containers:
    ...
      env:
    ...
      ports:
        - name: http
          containerPort: 8080
          protocol: TCP
      ...

دعنا نعدّل بعد ذلك، اختبارات الصلاحية والاستعداد المضمنة في بيان النشر هذا افتراضيًا. تضمن هذه الفحوصات اشتغال علب التطبيق لدينا وجاهزيتها لخدمة حركة المرور:

  • تُقيِّم اختبارات الجاهزية (Readiness) ما إذا كانت العلبة جاهزًا لخدمة حركة المرور أم لا، مع إيقاف جميع الطلبات إلى العلبة حتى تنجح عمليات الفحص.
  • تفحص اختبارات الثبات (Liveness) سلوك التطبيق الأساسي لتحديد ما إذا كان التطبيق في الحاوية قيد التشغيل أو يتصرف كما هو متوقع. في حالة فشل اختبار الثبات، سيعيد Kubernetes تشغيل الحاوية.

لمزيد من المعلومات حول كليهما، راجع المناقشة ذات الصلة في هيكلة تطبيقات لـ Kubernetes.

في حالتنا هذه، سنبني على طلب httpGet الذي قدمه Helm افتراضيًا ونختبر ما إذا كان تطبيقنا يقبل الطلبات في نقطة نهاية sharks/ أم لا. ستجري خدمة kubelet اختبارًا بإرسال طلب GET إلى خادم Node الذي يشتغل في حاوية علب التطبيق ويستمع على المنفذ 8080. إذا كان رمز الجواب يتراوح بين 200 و 400، فسوف تستنتج kubelet أن الحاوية في وضعٍ صحي. خلاف ذلك، إذا كان الرمز 400 أو 500، فإن kubelet تعمد إمّا إلى إيقاف حركة المرور إلى الحاوية، في حالة اختبار الجاهزية، أو إعادة تشغيل الحاوية، في حالة اختبار الثبات.

أضف التعديل التالي إلى المسار path المذكور لاختبارات الثبات والجاهزية:

apiVersion: apps/v1
kind: Deployment
metadata:
...
  spec:
    containers:
    ...
      env:
    ...
      ports:
        - name: http
          containerPort: 8080
          protocol: TCP
      livenessProbe:
        httpGet:
          path: /sharks
          port: http
      readinessProbe:
        httpGet:
          path: /sharks
          port: http

احفظ الملف وأغلقه عند الانتهاء من التحرير.

أنت الآن جاهز لإنشاء إصدار التطبيق الخاص بك باستخدام Helm. نفذ الأمر التالي لتثبيت helm، والذي يتضمن اسم الإصدار وموقع مجلّد المخطط:

helm install --name nodejs ./nodeapp

لا تنس أنه يمكنك تنفيذ تثبيت helm باستخدام الخيارين dry-run-- و debug-- أولاً، كما ذكرناه في الخطوة الثالثة، من أجل التحقق من البيانات (manifests) التي أُنشئت لإصدارك.

مرة أخرى، نظرًا لأننا لا نقوم بتضمين الراية --namespace مع helm install، سيكون إنشاء كائنات المخطط في المجال الاسمي الافتراضي.

سيظهر لك الإخراج التالي مشيرًا إلى إنشاء إصدارك:

NAME:   nodejs
LAST DEPLOYED: Wed Apr 17 18:10:29 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME           DATA  AGE
nodejs-config  4     1s

==> v1/Deployment
NAME            READY  UP-TO-DATE  AVAILABLE  AGE
nodejs-nodeapp  0/3    3           0          1s

...

مرة أخرى، سيشير الإخراج إلى حالة الإصدار، بالإضافة إلى معلومات حول الكائنات التي أُنشئت وكيفية تفاعلك معها.

تحقق من حالة علبك:

kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
mongo-mongodb-replicaset-0        1/1     Running   0          57m
mongo-mongodb-replicaset-1        1/1     Running   0          56m
mongo-mongodb-replicaset-2        1/1     Running   0          55m
nodejs-nodeapp-577df49dcc-b5fq5   1/1     Running   0          117s
nodejs-nodeapp-577df49dcc-bkk66   1/1     Running   0          117s
nodejs-nodeapp-577df49dcc-lpmt2   1/1     Running   0          117s

تحقق من خدماتك بمجرد تشغيل العلب:

kubectl get svc
NAME                              TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)        AGE
kubernetes                        ClusterIP      10.245.0.1     <none>            443/TCP        96m
mongo-mongodb-replicaset          ClusterIP      None           <none>            27017/TCP      58m
mongo-mongodb-replicaset-client   ClusterIP      None           <none>            27017/TCP      58m
nodejs-nodeapp                    LoadBalancer   10.245.33.46   your_lb_ip        80:31518/TCP 

العنوان EXTERNAL_IP المرتبط بخدمة nodejs هو عنوان IP يمكّنك من الوصول إلى التطبيق. إذا رأيت حالة في عمود EXTERNAL_IP، فهذا يعني أن مُوازِن التحميل لا يزال قيد الإنشاء.

بمجرد رؤية عنوان IP في هذا العمود، انتقل إليه في متصفحك: http://yourlbip.

ينبغي أن تظهر لك صفحة الهبوط التالية:

landing_page.png

الآن بعد أن تم تشغيل التطبيق المنسوخ، دعنا نضيف بعض بيانات الاختبار لضمان عمل التماثل بين عناصر مجموعة النسخ المتماثلة.

الخطوة السادسة: اختبار المتماثل في MongoDB

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

تأكّد أولًا من فتح صفحة الهبوط على متصفحك:

landing_page.png

انقر على زر الحصول على معلومات القرش. ستظهر لك صفحة ذات نموذج يمكنك فيه إدخال اسم سمك القرش ووصف لسلوكه العام:

shark_form.png

أضف في النموذج سمكة قرش أولية من اختيارك. سنضيف لغرض التوضيح Megalodon Shark إلى حقل Shark Name، وAncient لحقل Shark Character:

shark_filled.png

انقر على زر الإرسال. سترى صفحة بها معلومات القرش معروضة لك:

shark_added.png

انتقل الآن مرة أخرى إلى نموذج معلومات سمك القرش من خلال النقر على Sharks في شريط التنقل العلوي:

shark_form.png

أدخل سمكة قرش جديدة من اختيارك. سنستخدم Whale Shark مع Large:

whale_shark.png

بمجرد نقرك على زر الإرسال، سترى أنه القرش الجديد أضيف إلى المجموعة shark في قاعدة البيانات الخاصة بك:

persisted_data.png

دعنا نتحقق من أن البيانات التي أدخلناها نُسخت نسخًا متماثلاً بين العناصر الأساسية والثانوية في مجموعة النسخ المتماثلة.

استعرض قائمة علبك:

kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
mongo-mongodb-replicaset-0        1/1     Running   0          74m
mongo-mongodb-replicaset-1        1/1     Running   0          73m
mongo-mongodb-replicaset-2        1/1     Running   0          72m
nodejs-nodeapp-577df49dcc-b5fq5   1/1     Running   0          5m4s
nodejs-nodeapp-577df49dcc-bkk66   1/1     Running   0          5m4s
nodejs-nodeapp-577df49dcc-lpmt2   1/1     Running   0          5m4s

للوصول إلى صدفة mongo على علبك، يمكنك استخدام الأمر kubectl exec واسم المستخدم الذي استعملته لإنشاء mongo secret في الخطوة الثانية.

ادخل إلى صدفة mongo على العلبة الأولى في StatefulSet باستخدام الأمر التالي:

kubectl exec -it mongo-mongodb-replicaset-0 -- mongo -u your_database_username -p --authenticationDatabase admin

عند يطلب منك ذلك، أدخل كلمة المرور المرتبطة باسم المستخدم هذا:

MongoDB shell version v4.1.9
Enter password:

سيتم تحويلك إلى صدفة إدارية:

MongoDB server version: 4.1.9
Welcome to the MongoDB shell.
...

db:PRIMARY>

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

rs.isMaster()

سيظهر لك الإخراج التالي، مع الإشارة إلى اسم المضيف الأساسي:

db:PRIMARY> rs.isMaster()
{
        "hosts" : [
                "mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local:27017",
                "mongo-mongodb-replicaset-1.mongo-mongodb-replicaset.default.svc.cluster.local:27017",
                "mongo-mongodb-replicaset-2.mongo-mongodb-replicaset.default.svc.cluster.local:27017"
        ],
        ...
        "primary" : "mongo-mongodb-replicaset-0.mongo-mongodb-replicaset.default.svc.cluster.local:27017",
        ...

انتقل بعد ذلك إلى قاعدة بياناتك sharkinfo:

use sharkinfo
switched to db sharkinfo

اعرض قائمة المجموعات في قاعدة البيانات:

show collections
sharks

استخرج الملفات في المجموعة:

db.sharks.find()

سيظهر لك في الإخراج ما يلي:

{ "_id" : ObjectId("5cb7702c9111a5451c6dc8bb"), "name" : "Megalodon Shark", "character" : "Ancient", "__v" : 0 }
{ "_id" : ObjectId("5cb77054fcdbf563f3b47365"), "name" : "Whale Shark", "character" : "Large", "__v" : 0 }

اخرج الآن من صدفة MongoDB:

Exit

الآن بعد أن تفحصنا البيانات الموجودة على العنصر الأساسي، دعنا نتحقق من نسخها في الثانوي. نفّذ الأمر exec kubectl في mongo-mongodb-replicaset-1:

kubectl exec -it mongo-mongodb-replicaset-1 -- mongo -u your_database_username -p --authenticationDatabase admin

بمجرد الدخول إلى الصدفة الإدارية، سنحتاج إلى استخدام التابع ()db.setSlaveOk للسماح بعمليات القراءة من المثيل الثانوي:

db.setSlaveOk(1)

انتقل إلى قاعدة بيانات sharkinfo:

use sharkinfo
switched to db sharkinfo

اسمح بعمليات قراءة الملفات في المجموعة sharks:

db.setSlaveOk(1)

استخرج الملفات في المجموعة:

db.sharks.find()

ينبغي أن تشاهد الآن نفس المعلومات التي شاهدتها عند تنفيذ هذا التابع على العنصر الأساسي:

db:SECONDARY> db.sharks.find()
{ "_id" : ObjectId("5cb7702c9111a5451c6dc8bb"), "name" : "Megalodon Shark", "character" : "Ancient", "__v" : 0 }
{ "_id" : ObjectId("5cb77054fcdbf563f3b47365"), "name" : "Whale Shark", "character" : "Large", "__v" : 0 }

يؤكد هذا الإخراج نسخ بيانات تطبيقك بين عناصر مجموعة النسخ المتماثلة.

خاتمة

لقد تمكّنت الآن من نشر تطبيق متكرّر (replicated) ومتاح على أعلى مستوى لمعلومات سمك القرش على عنقود Kubernetes باستخدام مخططات Helm. يمكن أن يعمل هذا التطبيق التجريبي وسير العمل الموضح في هذا البرنامج التعليمي كنقطة انطلاق أثناء إنشاء مخططات مخصصة لتطبيقك والاستفادة من مستودع Helm الثابت ومستودعات التخطيط الأخرى.

أثناء سعيك نحو الإنتاج، فكر في تنفيذ ما يلي:

  • تسجيل الدّخول والمراقبة بشكل مركزي. يرجى الاطلاع على المناقشة ذات الصلة حول تحديث تطبيقات Kubernetes للحصول على نظرة أشمل. يمكنك أيضًا الاطلاع على كيفية إعداد حزمة تسجيل دخول Elasticsearch, Fluentd and Kibana (EFK) على Kubernetes. راجع أيضًا مقدمة لشبكات الخدمة للحصول على معلومات حول كيفية تنفيذ شبكات الخدمات مثل Istio لهذه الوظيفة.

  • موارد الولوج لتوجيه حركة المرور إلى عنقودك. يعد هذا بديلاً جيدًا لـ LoadBalancer في الحالات التي تشغّل فيها خدمات متعددة، والتي تتطلب كل منها موازِنًا LoadBalancer خاصًّا بها، أو عندما ترغب في تنفيذ استراتيجيات توجيه على مستوى التطبيق (اختبارات A/B & canary، على سبيل المثال). لمزيد من المعلومات، تحقّق من كيفية إعداد Nginx Ingress مع Cert-Manager على DigitalOcean Kubernetes والمناقشة ذات الصلة بالتوجيه في سياق شبكة الخدمة في مقدمة لشبكات الخدمة.

  • استراتيجيات النسخ الاحتياطي لكائناتك Kubernetes. للحصول على إرشادات حول تنفيذ النسخ الاحتياطية باستخدام Velero (سابقًا Heptio Ark) مع منتج Kubernetes الخاص بـ DigitalOcean، يرجى الاطلاع على كيفية عمل نسخة احتياطية واستعادة عنقود Kubernetesعلى DigitalOcean باستخدام Heptio Ark.

لمعرفة المزيد حول Helm، راجع مقدمة إلى Helm، ومدير الحزم لـ Kubernetes، وكيفية تثبيت البرامج على عناقيد Kubernetes باستخدام Helm Package Manager، وتوثيق Helm.

ترجمة -وبتصرف- للمقال How To Scale a Node.js Application with MongoDB on Kubernetes Using Helm لصاحبته Kathleen Juell





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن