
لقد أصبحت Kubernetes بالفعل معيارًا فعليًا لتشغيل التطبيقات عديمة الجنسية ، وذلك أساسًا لأنه يمكن أن يقلل الوقت اللازم لتسويق الميزات الجديدة. لا يزال تشغيل التطبيقات ذات الحالة الفعالة ، مثل قواعد البيانات أو الخدمات الدقيقة ذات الحالة ، مهمة معقدة ، لكن يتعين على الشركات مواجهة المنافسة والحفاظ على معدل تسليم مرتفع. لذلك يخلقون طلبًا على مثل هذه الحلول.
نريد أن نقدم حلنا لإطلاق مجموعات
خراطيش Tarantool الخاضعة للولاية :
مشغل Tarantool Kubernetes ، المزيد تحت الخفض.
- بدلا من ألف كلمة
- ما المشغل في الواقع لا
- قليلا عن التفاصيل
- كيف يعمل المشغل
- ما يخلق المشغل
- ملخص
Tarantool هو DBMS مفتوح المصدر وخادم تطبيق الكل في واحد. كقاعدة بيانات ، لها العديد من الخصائص الفريدة: كفاءة عالية في استخدام الأجهزة ، مخطط بيانات مرن ، دعم للتخزين في الذاكرة والقرص ، وإمكانية التمديد باستخدام لغة Lua. كخادم تطبيق ، يتيح لك نقل رمز التطبيق بالقرب من البيانات قدر الإمكان مع الحد الأدنى من وقت الاستجابة والحد الأقصى للإنتاجية. علاوة على ذلك ، لدى Tarantool نظامًا
إيكولوجيًا واسعًا يوفر وحدات جاهزة للاستخدام لحل مشكلات التطبيقات:
التقسيم ،
والصف ، والوحدات النمطية للتطوير السهل (
خرطوشة ،
luatest ) ، وحلول للتشغيل (
المقاييس ،
ansible ) ، على سبيل المثال لا الحصر.
لجميع مزاياها ، تكون إمكانات مثيل Tarantool واحدة محدودة دائمًا. سيتعين عليك إنشاء عشرات ومئات من الحالات لتخزين تيرابايت من البيانات ومعالجة ملايين الطلبات ، مما يعني بالفعل وجود نظام موزع بكل مشاكله المعتادة. لحلها ، لدينا
Tarantool Cartridge ، وهو إطار مصمم لإخفاء كل أنواع الصعوبات عند كتابة التطبيقات الموزعة. يسمح للمطورين بالتركيز على القيمة التجارية للتطبيق. توفر الخرطوشة مجموعة قوية من المكونات لتنسيق الكتلة التلقائي ، وتوزيع البيانات التلقائي ، WebUI للتشغيل ، وأدوات المطور.
لا يتعلق Tarantool بالتكنولوجيات فحسب ، بل يتعلق أيضًا بفريق من المهندسين الذين يعملون على تطوير أنظمة المؤسسات الجاهزة والحلول الجاهزة ودعم المكونات المفتوحة المصدر.
على الصعيد العالمي ، يمكن تقسيم جميع مهامنا إلى مجالين: تطوير أنظمة جديدة وتحسين الحلول الحالية. على سبيل المثال ، هناك قاعدة بيانات شاملة من بائع معروف. لتوسيع نطاق القراءة ، يتم وضع ذاكرة التخزين المؤقت المتسقة المستندة إلى Tarantool في النهاية. أو العكس: لتوسيع نطاق الكتابة ، يتم تثبيت Tarantool بتكوين ساخن / بارد: بينما البيانات "تهدأ" ، يتم إلقاؤها في التخزين البارد وفي نفس الوقت في قائمة انتظار التحليلات. أو يتم كتابة نسخة خفيفة من نظام موجود (نسخة احتياطية وظيفية) لإجراء نسخ احتياطي للبيانات "الساخنة" باستخدام النسخ المتماثل للبيانات من النظام الرئيسي. تعرف على المزيد من
تقارير مؤتمر T + 2019 .
كل هذه الأنظمة لديها شيء واحد مشترك: إنها صعبة إلى حد ما للعمل. حسنًا ، هناك العديد من الأشياء المثيرة: لإنشاء مجموعة من 100+ نسخة احتياطية في 3 مراكز بيانات بسرعة ؛ لتحديث التطبيق الذي يخزن البيانات دون توقف أو تعطل الصيانة ؛ لإنشاء نسخة احتياطية واستعادة من أجل الاستعداد لحادث أو أخطاء بشرية محتملة ؛ لضمان فشل المكون الخفي ؛ لتنظيم إدارة التكوين ...
تعمل خرطوشة Tarantool التي تم إطلاقها للتو في المصدر المفتوح على تبسيط عملية تطوير النظام الموزع بشكل كبير: فهي تدعم تجميع المكونات ، واكتشاف الخدمة ، وإدارة التكوين ، واكتشاف فشل المثيلات ، والفشل التلقائي ، وإدارة طبولوجيا النسخ المتماثل ، ومكونات المشاركة.
سيكون أمرا رائعا لو تمكنا من تشغيل كل هذا بأسرع ما يمكن تطويره. تجعل Kubernetes ذلك ممكنًا ، لكن المشغل المتخصص سيجعل الحياة أكثر راحة.
اليوم نقدم نسخة ألفا من مشغل Tarantool Kubernetes.
بدلا من ألف كلمة
لقد أعددنا مثالًا صغيرًا استنادًا إلى خرطوشة Tarantool ، وسوف نعمل معها. إنه تطبيق بسيط يسمى تخزين قيمة المفتاح الموزع مع واجهة HTTP. بعد بدء التشغيل ، لدينا ما يلي:

حيث
- تعتبر أجهزة التوجيه جزءًا من الكتلة المسؤولة عن قبول طلبات HTTP الواردة ومعالجتها ؛
- المخازن هي جزء من الكتلة المسؤولة عن تخزين ومعالجة البيانات ؛ يتم تثبيت ثلاثة شظايا من خارج منطقة الجزاء ، ولكل منها حاسب رئيسي ونسخة متماثلة.
لموازنة حركة مرور HTTP الواردة على أجهزة التوجيه ، يتم استخدام Kubernetes Ingress. يتم توزيع البيانات في التخزين على مستوى Tarantool نفسه باستخدام
مكون vshard .
نحتاج إلى Kubernetes 1.14+ ، ولكن
minikube سيفعل ذلك. ومن الجميل أيضا أن يكون
kubectl . لبدء المشغل ، قم بإنشاء ServiceAccount ، و Role ، و RoleBinding:
$ kubectl create -f https://raw.githubusercontent.com/tarantool/tarantool-operator/0.0.1/deploy/service_account.yaml $ kubectl create -f https://raw.githubusercontent.com/tarantool/tarantool-operator/0.0.1/deploy/role.yaml $ kubectl create -f https://raw.githubusercontent.com/tarantool/tarantool-operator/0.0.1/deploy/role_binding.yaml
يقوم مشغل Tarantool بتوسيع Kubernetes API بتعريفات الموارد الخاصة به ، لذلك دعونا ننشئها:
$ kubectl create -f https://raw.githubusercontent.com/tarantool/tarantool-operator/0.0.1/deploy/crds/tarantool_v1alpha1_cluster_crd.yaml $ kubectl create -f https://raw.githubusercontent.com/tarantool/tarantool-operator/0.0.1/deploy/crds/tarantool_v1alpha1_role_crd.yaml $ kubectl create -f https://raw.githubusercontent.com/tarantool/tarantool-operator/0.0.1/deploy/crds/tarantool_v1alpha1_replicasettemplate_crd.yaml
كل شيء جاهز لبدء المشغل ، ومن هنا يذهب:
$ kubectl create -f https://raw.githubusercontent.com/tarantool/tarantool-operator/0.0.1/deploy/operator.yaml
نحن في انتظار أن يبدأ المشغل ، ومن ثم يمكننا متابعة بدء التطبيق:
$ kubectl create -f https://raw.githubusercontent.com/tarantool/tarantool-operator/0.0.1/examples/kv/deployment.yaml
تم إعلان Ingress على واجهة المستخدم على الويب في ملف YAML مع المثال ؛ وهي متوفرة في
cluster_ip/admin/cluster
. عندما يكون برنامج Ingress Pod واحدًا على الأقل جاهزًا للتشغيل ، يمكنك الذهاب إلى هناك لمشاهدة كيفية إضافة مثيلات جديدة إلى الكتلة وكيف يتغير هيكلها.
نحن في انتظار الكتلة لاستخدامها:
$ kubectl describe clusters.tarantool.io examples-kv-cluster
نحن في انتظار حالة الكتلة التالية:
… Status: State: Ready …
هذا كل شيء ، والتطبيق جاهز للاستخدام!
هل تحتاج إلى مساحة تخزين أكبر؟ ثم ، دعونا نضيف بعض القطع:
$ kubectl scale roles.tarantool.io storage --replicas=3
إذا لم تتمكن Shards من معالجة التحميل ، فلنزيد عدد المثيلات الموجودة في shard عن طريق تحرير قالب مجموعة النسخ المتماثلة:
$ kubectl edit replicasettemplates.tarantool.io storage-template
دعنا
.spec.replicas
قيمة
.spec.replicas
على حالتين من أجل زيادة عدد الحالات في كل نسخة متماثلة إلى اثنين.
إذا لم تعد هناك حاجة إلى مجموعة ، فما عليك سوى حذفها مع جميع الموارد:
$ kubectl delete clusters.tarantool.io examples-kv-cluster
هل حدث خطأ ما؟
قم بإنشاء تذكرة ، وسنعمل عليها بسرعة.
ما المشغل في الواقع لا
إن بدء تشغيل وتشغيل مجموعة خرطوشة Tarantool هو قصة أداء إجراءات محددة بترتيب معين في وقت محدد.
تتم إدارة الكتلة نفسها بشكل أساسي عبر واجهة برمجة تطبيقات المسؤول: GraphQL عبر HTTP. لا شك في أنه يمكنك الذهاب إلى مستوى أقل وإعطاء الأوامر مباشرة من خلال وحدة التحكم ، لكن هذا لا يحدث كثيرًا.
على سبيل المثال ، هذا هو كيفية بدء تشغيل الكتلة:
- نقوم بنشر العدد المطلوب من مثيلات Tarantool ، على سبيل المثال ، باستخدام systemd.
- ثم نربط المثيلات بالعضوية:
mutation { probe_instance: probe_server(uri: "storage:3301") }
- ثم نقوم بتعيين الأدوار للمثيلات وتحديد معرفات مجموعة النسخ والمثيل. يتم استخدام واجهة برمجة تطبيقات GraphQL لهذا الغرض:
mutation { join_server( uri:"storage:3301", instance_uuid: "cccccccc-cccc-4000-b000-000000000001", replicaset_uuid: "cccccccc-0000-4000-b000-000000000000", roles: ["storage"], timeout: 5 ) }
- داخليًا ، نقوم بتمهيد المكون المسؤول عن المشاركة باستخدام واجهة برمجة التطبيقات:
mutation { bootstrap_vshard cluster { failover(enabled:true) } }
سهل ، أليس كذلك؟
كل شيء أكثر إثارة للاهتمام عندما يتعلق الأمر توسيع الكتلة. يؤدي دور أجهزة التوجيه (router) من مقياس الأمثلة بسهولة: قم بإنشاء المزيد من الحالات ، وانضم إليهم في كتلة موجودة بالفعل ، لقد انتهيت! دور التخزين أكثر تعقيدًا إلى حد ما. وحدة التخزين مظللة ، لذلك عند إضافة / إزالة المثيلات ، من الضروري إعادة توازن البيانات عن طريق نقلها إلى / من المثيلات الجديدة / المحذوفة على التوالي. قد يؤدي الفشل في القيام بذلك إلى حدوث مثيلات ناقصة أو فقدان البيانات. ماذا لو لم يكن هناك واحد فقط ، ولكن عشرات من المجموعات ذات طبولوجيا مختلفة؟
بشكل عام ، هذا هو كل ما يتعامل به مشغل Tarantool. يصف المستخدم الحالة الضرورية لمجموعة خراطيش Tarantool ، ويقوم المشغل بترجمتها إلى مجموعة من الإجراءات المطبقة على موارد K8s وفي مكالمات معينة إلى API مسؤول مسؤول Tarantool في ترتيب معين في وقت معين. كما يحاول إخفاء كل التفاصيل من المستخدم.
قليلا عن التفاصيل
أثناء العمل مع API المسؤول عن نظام المجموعة Tarantool Cartridge ، يعد كل من ترتيب المكالمات والوجهة الخاصة بها أمرًا ضروريًا. لماذا هذا؟
تحتوي خرطوشة Tarantool على تخزين الهيكل ، ومكون اكتشاف الخدمة ومكون التكوين. يخزن كل مثيل من الكتلة نسخة من الهيكل والتكوين في ملف YAML.
servers: d8a9ce19-a880-5757-9ae0-6a0959525842: uri: storage-2-0.examples-kv-cluster:3301 replicaset_uuid: 8cf044f2-cae0-519b-8d08-00a2f1173fcb 497762e2-02a1-583e-8f51-5610375ebae9: uri: storage-0-0.examples-kv-cluster:3301 replicaset_uuid: 05e42b64-fa81-59e6-beb2-95d84c22a435 … vshard: bucket_count: 30000 ...
يتم تطبيق التحديثات باستمرار باستخدام آلية
الالتزام ثنائية الطور . يتطلب التحديث الناجح النصاب القانوني بنسبة 100 ٪: يجب أن يستجيب كل مثيل. خلاف ذلك ، فإنه يتراجع. ماذا يعني هذا من حيث العملية؟ فيما يتعلق بالموثوقية ، يجب إرسال جميع الطلبات إلى API المسؤول التي تقوم بتعديل حالة الكتلة إلى مثيل واحد ، أو إلى العميل الرائد ، وإلا فإننا نخاطر في الحصول على تكوينات مختلفة في حالات مختلفة. لا تعرف خرطوشة Tarantool كيفية إجراء انتخاب زعيم (ليس فقط بعد) ، لكن مشغل Tarantool يمكنه ، وهذا بالنسبة لك ، مجرد حقيقة ممتعة ، لأن المشغل يقوم بكل شيء.
يجب أن يكون لكل مثيل هوية ثابتة ، أي مجموعة من
instance_uuid
و
replicaset_uuid
وكذلك
advertise_uri
. في حالة إعادة تشغيل وحدة التخزين فجأة ، وتغيير إحدى هذه المعلمات ، فستواجه خطر كسر النصاب ويكون المشغل مسؤولاً عن ذلك.
كيف يعمل المشغل
الغرض من المشغل هو إدخال النظام في الحالة المعرفة من قبل المستخدم والحفاظ على النظام في هذه الحالة حتى يتم إعطاء توجيهات جديدة. لكي يتمكن المشغل من العمل ، يحتاج إلى:
- وصف حالة النظام.
- الرمز الذي سيجلب النظام إلى هذه الحالة.
- آلية لدمج هذا الكود في k8s (على سبيل المثال ، لتلقي إعلامات تغيير الحالة).
يتم وصف مجموعة خرطوشة Tarantool من حيث k8s باستخدام
تعريف الموارد المخصص (CRD) . سيحتاج المشغل إلى ثلاثة موارد مخصصة موحدة ضمن مجموعة tarantool.io/v1alpha:
- الكتلة هي مورد المستوى الأعلى الذي يتوافق مع كتلة خرطوشة Tarantool واحدة.
- الدور هو دور المستخدم من حيث Tarantool Cartridge.
- Replicaset Template هو قالب لإنشاء StatefulSets (سأخبرك لاحقًا عن السبب في كونها في حالة جيدة ؛ ولا يجب الخلط بينها وبين K8s ReplicaSet).
تعكس كل هذه الموارد نموذج وصف مجموعة Tarantool Cartridge مباشرةً. وجود قاموس مشترك يجعل من السهل التواصل مع المطورين وفهم ما يودون رؤيته في الإنتاج.
الكود الذي يجلب النظام إلى الحالة المعينة هو المراقب من حيث K8s. في حالة مشغل Tarantool ، هناك عدة وحدات تحكم:
- Cluster Controller هي المسؤولة عن التفاعل مع مجموعة خرطوشة Tarantool ؛ يربط المثيلات إلى الكتلة ويفصل المثيلات من الكتلة.
- دور المراقب هو وحدة تحكم دور المستخدم المسؤولة عن إنشاء StatefulSets من القالب والحفاظ على عدد محدد مسبقا منهم.
ما هو مثل تحكم؟ إنها مجموعة من الكودات التي تضع العالم من حوله بشكل تدريجي. سوف تبدو وحدة التحكم في المجموعة بشكل تخطيطي:

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

يقوم المستخدم باستدعاء
kubectl create -f tarantool_cluster.yaml
، ويتم إنشاء مورد نظام المجموعة المقابل. يتم إعلام وحدة تحكم الكتلة بإنشاء مورد الكتلة. وأول شيء تحاول القيام به هو العثور على جميع موارد الدور التي يجب أن تكون جزءًا من هذه المجموعة. إذا كان الأمر كذلك ، فإنه يعين الكتلة كمالك للدور وتحديث مورد الدور. يتلقى المراقب الدور إشعارًا بتحديث الدور ، ويفهم أن المورد لديه مالكه ، ويبدأ في إنشاء StatefulSets. هذه هي الطريقة التي تعمل بها: الحدث الأول يقوم بتشغيل الحدث الثاني ، الحدث الثاني يقوم بتشغيل الحدث الثالث ، وهكذا حتى يتوقف أحدهما. يمكنك أيضًا تعيين مشغل وقت ، على سبيل المثال ، كل 5 ثوانٍ.
هذه هي الطريقة التي يتم بها تنظيم المشغل: نقوم بإنشاء مورد مخصص وكتابة التعليمات البرمجية التي تستجيب للأحداث المتعلقة بالموارد.
ما يخلق المشغل
تؤدي إجراءات المشغل في النهاية إلى إنشاء حاويات وحاويات K8s. في مجموعة خرطوشة Tarantool التي تم نشرها على K8s ، يتم توصيل جميع Pods بـ StatefulSets.
لماذا StatefulSet؟ كما ذكرت سابقًا ، يحتفظ كل مثيل لـ Tarantool Cluster بنسخة من طبولوجيا الكتلة وتكوينها. وفي كل مرة من حين إلى آخر ، يحتوي خادم التطبيقات على مساحة مخصصة ، على سبيل المثال ، لقوائم الانتظار أو البيانات المرجعية ، وهذه حالة كاملة بالفعل. يضمن StatefulSet أيضًا الحفاظ على هويات Pod ، وهو أمر مهم عند تجميع الحالات: يجب أن يكون للمثيلين هويات ثابتة ، وإلا فإننا نخاطر بفقد النصاب القانوني عند إعادة التشغيل.
عندما تكون جميع موارد المجموعة جاهزة وفي الحالة المطلوبة ، فإنها تعكس التسلسل الهرمي التالي:

تشير الأسهم إلى علاقة المالك بالموارد. من الضروري ، على سبيل المثال ، تنظيف أداة
تجميع مجمعي القمامة بعد إزالة نظام المجموعة.
بالإضافة إلى StatefulSets ، يقوم Tarantool Operator بإنشاء خدمة مقطوعة الرأس لانتخاب القادة ، وتتواصل الحالات مع بعضهم البعض عبر هذه الخدمة.
يعتمد Tarantool Operator على
إطار المشغل ، وكتابة المشغل مكتوبة بلغة Golang ، لذلك لا يوجد شيء مميز هنا.
ملخص
هذا كل ما في الأمر إلى حد كبير. نحن في انتظار ملاحظاتك وتذاكر السفر. لا يمكننا الاستغناء عنها - إنها النسخة ألفا بعد كل شيء. ما التالي؟ والخطوة التالية هي تلميع الكثير:
- وحدة ، اختبارات E2E ؛
- اختبارات الفوضى القرد.
- اختبارات الإجهاد
- النسخ الاحتياطي / استعادة.
- مزود طوبولوجيا الخارجية.
كل موضوع من هذه الموضوعات واسع بمفرده ويستحق مقالة منفصلة ، لذا يرجى الانتظار للحصول على التحديثات!