Kubernetes أفضل الممارسات

كنت أتحدث إلى موظف سابق في Googler SRE أشار (بشكل صحيح) إلى أن Kubernetes يتطور بسرعة كبيرة (بسرعة كبيرة للحفاظ على العملة) ، ويستخدم (كثيرًا) مفاهيم جديدة وأن هناك (كثيرًا) طرق عديدة لحل المشكلة نفسها.

الكثير من هذا صحيح وليس بالضرورة شيئًا سيئًا ولا يختلف بالضرورة عن أي تقنية أخرى. ما أختلف فيه هو أن هذه العوامل لم تشجع اعتماده على Kubernetes. أود أن أشجعكم على الغوص. Kubernetes هو النجاح الذي حققته * رغم هذه المخاوف (المعقولة) لأنها جيدة جدًا جدًا.

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

ليس في ترتيب معين:

  1. دع شخصًا آخر يجهد!

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

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

تنشئ مجموعات حاوية بيتا gcloud $ {CLUSTER} ...
مجموعات حاوية بيتا gcloud - الحصول على بيانات اعتماد $ {CLUSTER} ...

وبعد ذلك ، أنت مستعد للذهاب مع:

تطبيق kubectl - اسم الملف = marvels.yaml

2. حاول التفكير "Kubernetes"

قد يمثل هذا * تحديًا أكبر مع Kubernetes Engine مقارنةً بالأنظمة الأساسية الأخرى ، ولكن على Google Cloud Platform ، فأنت مجبر على الحفاظ على فهم لحالة مواردك في Kubernetes (مثل العقد ، Ingresses) ، وفي الوقت نفسه ، الموارد الأساسية في Compute Engine (مثل VMs و HTTP / S Balancers). إن مشكلة ازدواج موجة الجسيم هذه أمر مؤسف. بفضل ديل H. لأول توضيح هذا بالنسبة لي.

حاول ، حيثما أمكن ، التمسك بالتفكير من حيث موارد Kubernetes وتجاهل موارد الحملة العالمية للتعليم الأساسية. بعد أن أمضيت أكثر من عام في التحيز لعملي إلى Kubernetes ، أصبح من الأسهل التفكير بحتة فيما يتعلق بـ "عدد من" السنفات التي تتعرض لها الخدمات (و Ingresses).

3. مساحات الأسماء ، مساحات الأسماء ، مساحات الأسماء

تحديث: شكرًا لمايكل Hausenblas لتثبيتي بشأن أفضل ممارسة ل * عدم الرجوع إلى مساحات الأسماء من داخل ملفات Kubernetes YAML. رغم أنه يجب عليك دائمًا استخدام مساحات الأسماء ، فإن تحديدها عند تطبيق الملف يوفر مزيدًا من المرونة والقدرة على استخدام نفس ملفات YAML ضدها ، على سبيل المثال المناظر الطبيعية المختلفة. انظر مقالة مايكل هنا.

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

نظرًا لأن الحاويات جاهزة للعمل ، فإن مساحات الأسماء تخص مشروعات Kubernetes. وبصرف النظر عن حدود الأمان التي تنقلها Namespaces ، فهي طريقة ممتازة لتقسيم عملك وتنتج طريقة ممتازة لإعادة تعيينه أو حذفه:

kubectl حذف مساحة الاسم / $ WORKING_PROJECT

الجانب السلبي الوحيد هو أنه عند استخدام مساحة الاسم غير الافتراضية ، ستحتاج إلى تحديد مساحة اسم العمل الخاصة بك --namespace = $ WORKING_PROJECT على أوامر kubectl والتي ، في رأيي ، يمكن أن تكون ممارسة حماية جيدة. ومع ذلك ، يمكنك دائمًا - all-namespaces أو تعيين مساحة اسم مختلفة مثل الافتراضي (link).

4. طرق كثيرة جدا لحل مشكلة

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

  • ملفات YAML هي المعرفة في التخزين البارد (انظر # 5)
  • يجب أن تفعل الحاويات الخاصة بك شيئًا جيدًا (انظر "distroless")
  • دائما نشر عمليات النشر (انظر # 6)
  • إذا كنت تريد L7 ويعرف أيضًا باسم HTTP / S Load-Balancing ، استخدم Ingress (انظر # 7 - ها!)
  • إدارة بيانات الاعتماد بأمان باستخدام الأسرار (الرابط)

5. التحيز ل kubectl تطبيق - اسم الملف على البدائل

من السهل الحصول على ضربة سريعة باستخدام kubectl لإنشاء مساحة اسم / $ {WORKING_DIR} ، لكن بعد العديد من هذه الأوامر ، قد تتساءل كيف وصلت إلى الحالة الحالية - والأهم من ذلك - كيفية إعادة إنشاء هذه الحالة. أشجعك على إنشاء ملفات YAML لوصف مواردك بدلاً من الأمر kub ectl create المكافئ.

أشجعك على أن تكون على دراية بوثائق * Kubernetes API * الممتازة (الرابط والرابط و 1.10) والتي هي شاملة ودقيقة وسهلة التصفح (ربما هي الوثائق المثالية !؟). ولكن ، حتى مع هذه الأداة القوية ، يكون من الصعب أحيانًا اتخاذ أمر kubectl الذي يناسبك وتحويله إلى YAML. ليس:

الحصول على النشر kubectl / $ {MY_DEPLOYMENT} - الإخراج = yaml
الحصول على خدمة kubectl / $ {MY_SERVICE} - الإخراج = yaml
الحصول على أي شيء kubectl / $ {MY_ANYTHING} - الإخراج = yaml

قم بنقل النتائج إلى ملف إذا كنت ترغب في ذلك ، ولكن استخدمها كأساس لملف YAML المكافئ (!). سوف تحتاج إلى إسقاط أي مراجع المثال.

بمجرد الانتهاء من إنشاء تحفة فنية. yaml ، أشجعك على التقدم دائمًا للقيام بالإنشاء الأولي والتقديم للقيام بأي تحديثات لاحقة ، وإذا كان يجب عليك الحذف. هذا هو!

تطبيق kubectl - اسم الملف = تحفة
kubectl delete - اسم الملف = masterpiece.yaml

نظرة ثاقبة بسيطة: لا تحتاج إلى سحب ملفات YAML المحلية من أجل النشر. يمكنك توفير تطبيق kubectl - اسم الملف مع عناوين URL أيضًا ، وطالما أن أي ملفات تابعة هي مراجع محلية ، فإن النشر سوف يعمل.

نظرة ثاقبة بسيطة: المكان الوحيد الذي أراه يستخدم هذا هو Kubernetes-land ولكنه ممارسة شرعية ، يمكنك دمج عدة ملفات YAML في ملف YAML واحد مع فواصل الملفات --- و .... لذلك ، بدلاً من مساحة الاسم YAML ، ونشر YAML وخدمة YAML ، قد يكون لديك YAML ميجا تدمج كل الملفات الثلاثة في ملف واحد.

هذا صحيح YAML (انسخه والصقه في YAML Lint). إنه غير صالح * Kubernetes spec | YAML نظرًا لأن كل المواصفات غير مكتملة ، ولكن إذا تم إكمال كل منها ، فسيكون هذا صحيحًا تمامًا وطريقة جيدة للحفاظ على الموارد المرتبطة.

انظر #B (Xsonnet) للحصول على نقد واحد.

6. استخدام النشرات

هناك الكثير من القوة في عمليات النشر ، يكفي إرشاداتي للقول: استخدم عمليات النشر في كل وقت وفي كل مرة. حتى عندما تقوم بنشر أول podnginx الخاص بك. عمليات النشر هي سفر "من الدرجة الأولى" مقابل المدرب ، يمكنك الدخول في عمليات النشر المتدنية ، وترتكب خطأً ، وتعيد تقديم الطلب ، وتعتني Kubernetes بقتل القرون المشاغب واستبدالها بأخرى محترمة جيدًا.

7. LoadBalancer والدخول

هذه تسبب الارتباك. في رأيي (وقد أكون مخطئًا) ، عندما أقوم بإنشاء خدمات باستخدام - النوع = LoadBalancer ، أريد | الحصول على LB شبكة. إذا كنت أريد موازنة التحميل HTTP / S (المستوى 7) ، فأنا بحاجة إلى إنشاء Ingress. دخول هو مورد Kubernetes مربكة. يكفي أن نقول ، L7 == دخول (والكثير من قوة التكوين نتيجة لذلك).

يُظهر محرك Kubernetes موارد Ingress مثل GCE HTTP / S-Balancers. يقوم كريستوفر جرانت بعمل جيد للغاية في إزالة الغموض عن الوظائف في مناصبه (هنا وهنا).

8. NodePorts

لم أقم (من أي وقت مضى؟) بإنشاء ClusterIP مباشرة. لقد فعلت أشياء لـ Kubernetes مما أدى إلى كشف الخدمات عن طريق ClusterIPs. غالبًا (!) قمت بإنشاء NodePorts أو أفعل أشياء (مثل إنشاء موارد Ingress) التي تستخدم NodePorts.

ترتبط NodePorts بعقد Kubernetes وهي منافذ. التسهيلات القوية التي يقدمونها هي أن كل عقدة * في الكتلة (أم أنها NodePool؟ [[TODO]]) تعرض نفس الخدمة على نفس المنفذ (العقدة).

إذا قمت بإنشاء خدمة مكشوفة على NodePort X ، فيمكنني التأكد من أنني إذا قمت بالوصول إلى ذلك المنفذ على * أي * عقدة في الكتلة ، فسوف أقوم بالوصول إلى الخدمة. وهذا يشكل الأساس لقدرات موازنة التحميل لدى Kubernetes لأن المجموعة قادرة على توجيه الطلبات الواردة للخدمة إلى هذا المنفذ على أي عقدة.

يتضمن Google Cloud SDK (يُعرف أيضًا باسم gcloud) عميلًا ssh يجعل التواصل مع Compute Engine VMs أمرًا تافهًا (والتي ، كما تتذكر ، Kubernetes Cluster Node). يتضمن عميل ssh إمكانية إعادة توجيه المنفذ. لذلك ، إذا كنا نريد الاتصال بخدمة Kubernetes ويمكننا البحث عن NodePort للخدمة ، فيمكننا إذن (!) نقل منفذ الوصول إلى تلك الخدمة عن طريق إعادة توجيه المنفذ (باستخدام gcloud أو أي عميل ssh) إلى المنفذ على أي العقدة.

يستخدم المثال التالي kubectl للاستيلاء على العقدة 0 في الكتلة. اسم Kubernetes Engine Node هو نفس اسم حساب محرك VM. نظرًا لخدمة تسمى $ {MY_SERVICE} في مساحة اسم تسمى $ {MY_NAMESPACE} ، فإننا نحدد NodePort للخدمة. بعد ذلك ، ننتقل إلى gcloud ونستخدم ssh المضمنة لإعادة توجيه المنفذ (باستخدام --ssh-flag = "- L XXXX: localhost: XXXX).

NODE_HOST = $ (\
  kubectl الحصول على العقد \
  --output = jsonpath = "{البنود [0] .metadata.name}")
NODE_PORT = $ (\
  الحصول على خدمات kubectl / $ {MY_SERVICE} \
  --namespace = $ {MY_NAMESPACE} \
  --output = jsonpath = "{. spec.ports [0] .nodePort}")
صدى $ {NODE_PORT}
gcloud حساب ssh $ {NODE_HOST} \
--ssh-flag = "- L $ {NODE_PORT}: المضيف المحلي: $ {NODE_PORT}" \
--project = $ {YOUR_PROJECT}

ما هو قوي جدا حول هذا؟ الآن ، يمكنك الوصول إلى الخدمة كما لو كانت محلية ودون الحاجة إلى حفر الثقوب في جدار الحماية.

NodePorts هي منافذ ذات أرقام عالية (حوالي 30،000 - 32،767).

9. التقطيع kubectl استخدام JSON

يعتبر برنامج Google SD Cloud (المعروف أيضًا باسم gcloud) ممتازًا جدًا ولكن kubectl (Kubernetes CLI) هو أفضل (كذا). ميزة واحدة قوية هي تنسيق وتصفية الإخراج. يسمح هذا بطرق غير مشفرة (غير مشفرة ببرمجة API) لتوسيع البرامج النصية وغيرها من الأدوات بمعلومات من مجموعات Kubernetes.

يمكن الوصول إلى جميع حالة موارد Kubernetes من خلال على سبيل المثال الحصول على أوامر kubectl (في تجربتي أكثر فائدة لهذا الغرض من وصف kubectl). بعد ذلك ، كل ما تبقى هو العثور على الإبرة فيما يمكن أن يكون كومة قش JSON.

الحيلة هي:

الحصول على kubectl [مورد] / [اسم المورد] - الإخراج = JSON

ثم قلل النتائج لبدء بناء سلسلة استعلام:

الحصول على kubectl [مورد] / [اسم مورد] - الإخراج = jsonpath = ". items [*]"

وقم بتحسين النتيجة التي تم تعيينها بشكل متكرر حتى تحصل على العنصر (العناصر) الذي تبحث عنه. إليك مثال يجب أن يعمل مع أي مجموعة:

الحصول على العقد kubectl - الإخراج = json
الحصول على العقد kubectl - الإخراج = jsonpath = "{. items [*]}
الحصول على العقد kubectl - الإخراج = jsonpath = "{. items [0]}
الحصول على العقد kubectl - الإخراج = jsonpath = "{. items [0] .metadata.name}

أخيرًا ، هناك حجة لائقة (وتينيت في * nix) لتعلم أداة تحليل JSON واحدة وتطبيق تلك الأداة على جميع احتياجات تحليل JSON. في هذه الحالة ، هل هناك منافس معقول لـ jq؟ لا أظن ذلك.

بالإضافة إلى jq لديه ملعب ممتاز (jqplay.org).

أ. استخدام التسميات

لقد كانت فترة طويلة قادمة ولكن جميع أنواع خدمات البرمجيات تدعم الآن مفهوم التصنيف التعسفي للموارد (عادةً أزواج القيمة الرئيسية). السبب في كونها قوية هو أن بيانات التعريف هذه توفر طريقة مفتوحة بالكامل المعرفة من قبل المستخدم لاستعلام الموارد. يستخدم Kubernetes هذا المبدأ بطبيعته ؛ إنها قدرة جوهرية وليست فكرة مسبقة.

خدمة Kubernetes تكشف عن عدد تعسفي من قرون Kubernetes. لا تعرض الخدمات * * السنفات المسماة "Henry" أو السنفات التي تشتمل على ReplicaSet. وبدلاً من ذلك ، تكشف الخدمة عن السنفات التي تلبي تسمياتها المعايير المحددة خلال مواصفات الخدمة وهذه التسميات ، بالطبع ، معرفة من قبل المستخدم.

ملحوظة: في المثال أعلاه ، نستخدم مساحة اسم تسمى project-x وتظهر مساحة الاسم هذه في Namespace (عند إنشائها) ، و Deployment لتحديد مكان وجود النشر ، وفي الخدمة. ستنشئ خدمة النشر (والتي تسمى microservice-y) نسخة متماثلة (تم تحديدها ضمنيًا هنا ؛ إنها ما ستنشئه عمليات النشر) التي ستحتفظ بـ 100 حزمة. سيكون لكل Pod تطبيق تسمية: publicname-a ويحتوي على حاوية واحدة تسمى grpc-proxy بناءً على صورة تسمى image-grpc-proxy. تسمى الخدمة service-p. الأهم من ذلك ، أن الخدمة تختار (!) السنفات (في مساحة اسم المشروع- x فقط) التي لها تطبيق تسمية: publicname-a. ستقوم الخدمة بتحديد أي قرنة (في مساحة اسم المشروع- x) بها زوج من هذا التصنيف (مفتاح: قيمة) * وليس * فقط تلك القروش التي تم إنشاؤها في هذا النشر. لا تشير الخدمة إلى "السنفات" حسب اسمها (الذي يستند إلى اسم النشر) ، واسم الحاوية أو اسم صورة الحاوية ، فقط التسميات المرتبطة بالجراب.

ملحوظة: هذه * ليست * ممارسة جيدة ولكنها تثبت هذه النقطة. إذا كنت تريد تشغيل تكوين مشابه لما سبق ، فقم بإنشاء منفصل على سبيل المثال قرنة تقوم بتشغيل Nginx (في مساحة اسم المشروع x) ثم قمت بإضافة تطبيق الملصق: publicname-a إليه ، سيتم دمجه بسرعة في مجموعة Pods التي يتم تجميعها بواسطة خدمة service-p. إذا كنت ستقوم بإزالة الملصق من أي من السنفات المجمعة بواسطة الخدمة ، فسيتوقف البود عن التضمين.

تتمثل هذه الميزة في التحديثات المتجددة حيث يقوم Deployment بإنشاء ReplicaSet جديدة تشتمل على Pods جديدة للإصدار X '، متميزة عن ReplicaSet و Pods للإصدار X. قد يتم تعريف الخدمة لفضح تقاطع Pods الذي يعمل عبر كلا الإصدارين لأنه لم يتم تعريفه من حيث ReplicaSets أو السنفات المحددة ولكن من خلال التصنيفات المعرفة من قبل المستخدم ("المحددات") والتي يتم تطبيقها من قبلك عند إنشاء السنفات.

هذا قوي جدا!

B. استخدم Jsonnet ، وربما Ksonnet

اثنين من التحديات مع جميع (!؟) الأشكال المهيكلة (YAML ، JSON ، XML ، CSV ؛-) هي المراجع الذاتية والمتغيرات. أثناء صياغة مواصفات marvellous.yaml لنشر Kubernetes ، ستواجه هذه المشكلة بسهولة. ستجد نفسك تستخدم الحرفي (على سبيل المثال لأسماء الصور وهضمها) ، وحتى مع النشرات المحترمة ، تتكرر الأسماء ومحدداتها.

لا يوجد حل لهذه المشكلات إذا قصرت على YAML و JSON. أنشأ Google Jsonnet جزئيًا لمعالجة هذه المشكلات. لقد مدد أهل Heptio الأذكياء Jsonnet إلى Kubernetes مع ... Ksonnet.

كلاهما templating اللغات التي تعالج المشاكل المذكورة أعلاه (وأكثر). أنا أشجعك على التفكير في Jsonnet. كما هو الحال مع توصيتي للنظر في استخدام jq ، تعلم Jsonnet مرة واحدة وتطبيقه في كل مكان كنت تستخدم JSON. تعتبر Ksonnet خاصة بـ Kubernetes - وفي تجربتي المحدودة (!) - وجدت أن الفوائد التي اكتسبتها من هذه الخصوصية لا يفوقها منحنى التعلم.

C. YAML أو JSON

Kubernetes يعامل YAML و JSON في الغالب على قدم المساواة. أنا شخصياً أجد YAML أفضل لملفات التكوين التي أستخدمها kubectl - تطبيق لأن YAML أكثر إيجازًا من JSON. على الرغم من أنني أجد YAML أكثر صعوبة في الكتابة.

ومع ذلك ، عندما يتعلق الأمر بفهم البنية والتحليل ، فأنا أفضل - الإخراج = JSON وأيضًا - - الإخراج = JSONPATH. أنا من عشاق Golang الضخمة لكن قوالب Go ليست بديهية ولا أستخدمها.

نظرة ثانوية بسيطة: YAML هي مجموعة شاملة من JSON (رابط) ... انتظر! ماذا؟

D. Down Down Dog API and config

"Downward API" لمنحه اسمًا صحيحًا وإن لم يكن مربكًا ، هو منشأة في Kubernetes يمكن بواسطتها اكتساب القرون شعورًا بالتجمع حولهم. أفترض أن التدفق الطبيعي يكون من العالم الخارجي إلى الجراب وحاوياته * ولكن * هناك أوقات يكون من المفيد فيها أن تحصل الحاوية (!) على معلومات حول بيئتها ، على سبيل المثال اسم العقدة | IP ، اسم Pod (المساحة) | IP.

يتم تقديم قيم API لأسفل إلى الحاوية من خلال متغيرات البيئة. تستخدم متغيرات البيئة (كما في مكان آخر) لتوفير التكوين أو حالة أخرى للحاويات. إحدى النتائج اللطيفة جدًا لاستخدام متغيرات البيئة وتطبيق API لأسفل (مع تحذير بسيط) هي أن الحاوية تظل منفصلة عن Kubernetes.

إليك مثال من صديقي - Sal Rashid - يستخدم Downward API لجمع Node and Pod state وتقديم هذه للمستخدم:

https://github.com/salrashid123/istio_helloworld/blob/master/all-istio.yaml

ملحوظة: راجع الأقسام التي تبدأ من السطور 76 و 80 و 84 و 88 حيث يتم توفير اسم Pod ومساحة الاسم وعنوان IP واسم العقدة في وقت التشغيل من خلال واجهة برمجة تطبيقات Downward إلى الحاوية المسماة myapp-container.

API Downward هي الطريقة الوحيدة العملية لجمع هذه البيانات للحاوية. لذلك فهي أكثر من "ممارسة فقط" وليس "أفضل ممارسة".

في العديد من مشاركاتي ، عندما أقوم بإنشاء حلول لـ Kubernetes ، أختبر العملية محليًا وخارج الحاوية ، ثم في حاوية (تحديد متغيرات البيئة) ، ثم على كتلة Kubernetes. الآليات الموجودة في حاويات متسقة (انظر أدناه) على الرغم من أن واحدة تعمل عادة على Docker والآخر على Kubernetes.

في منشور كتبته مؤخرًا على OS-Container Optimized OS من Google ، أثبتت وجود حاوية تعمل محليًا تحت Docker ، عن بُعد تحت OS-Optimized OS ثم على Kubernetes.

هنا يعمل تحت Docker محليًا. لاحظ كيف يتم استخدام متغيرات البيئة (--env) لتوفير التكوين إلى gcr.io/${PROJECT}/datastore.

تشغيل عامل ميناء \
- تفاعلي \
- \
- نشر = 127.0.0.1: 8080: 8080 \
--env = GCLOUD_DATASET_ID = $ {PROJECT} \
--env = GOOGLE_APPLICATION_CREDENTIALS = / tmp / $ {ROBOT} .key.json \
--volume = $ PWD / $ {ROBOT} .key.json: / tmp / $ {ROBOT} .key.json \
gcr.io/${PROJECT}/datastore

ها هي نفس النتيجة التي تلتف حول عملية النشر في إنشاء حاوية VM محسّنة. تحقق هذه المرة من القيم المقدمة إلى علامة حاوية الحاويات:

مثيلات حساب gcloud beta create-with-container $ {INSTANCE} \
- المنطقة = $ {ZONE} \
- صورة الأسرة = كوس مستقرة \
--image-project = cos-cloud \
--container-image=gcr.io/${PROJECT}/${IMAGE}@${DIGEST} \
- الحاويات - إعادة تشغيل السياسة = دائما \
--container-الحياة الفطرية = \
GCLOUD_DATASET_ID = $ {PROJECT}، \
GOOGLE_APPLICATION_CREDENTIALS = / tmp / $ {ROBOT} .key.json \
--container جبل في استضافة مسار = \
جبل مسار = / تمة، \
المضيف مسار = / تمة، \
الوضع = rw \
--project = $ {PROJECT}

وأخيرًا ، إليك مقتطف YAML الخاص بنشر Kubernetes:

حاويات:
      - الاسم: مخزن البيانات
        الصورة: gcr.io/${PROJECT}/datastore
        imagePullPolicy: دائمًا
        volumeMounts:
          - الاسم: مخزن البيانات
            mountPath: / var / secrets / google
        الحياة الفطرية:
        - الاسم: GOOGLE_APPLICATION_CREDENTIALS
          القيمة: /var/secrets/google/datastore.key.json
        - الاسم: GCLOUD_DATASET_ID
          القيمة: $ {PROJECT}
        الموانئ:
        - الاسم: http
          حاوية المنفذ: 8080

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

ومع ذلك ، فإن استخدام متغيرات البيئة بهذه الطريقة هو أفضل ممارسة.

E. Sidecars ولماذا القرون ليست دائما مرادفا للحاويات

5 cl كونياك
2 cl ثلاثية ثانية
2 عصير الليمون cl
إعداد صب جميع المكونات في شاكر كوكتيل مليئة الجليد. يهز جيدا ويصفى في كوب كوكتيل.

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

... ومرة ​​واحدة فقط يجب عليك :-)

ربما أكثر من واحد ، ولكن دعونا نلتزم مرة واحدة فقط.

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

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

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

من الممارسات الجيدة والمألوفة توجيه مثيل خادم الويب نفسه ببروكسي عكسي. عادة ما يكون هذا إما Nginx أو HAProxy وأصبح من الشائع بشكل متزايد استخدام Envoy (أوصي ، إذا كنت تبحث عن وكلاء ، للنظر في Envoy ؛ انظر #F Istio). يوفر الوكيل العكسي الاتساق (نستخدم على سبيل المثال Envoy) فقط حتى لو كنت تستخدم خوادم ويب مختلفة (مثل Apache و Tomcat w / Java وما إلى ذلك) ، حتى إذا كان لديك مزيج من حركة مرور HTTP و gRPC و Web Sockets وما إلى ذلك. ، حتى لو كنت ترغب في توجيه بعض حركة المرور إلى خادم الويب الخاص بك وبعض حركة المرور إلى ذاكرة التخزين المؤقت (مثل الورنيش).

في جميع السيناريوهات السابقة ، سيكون من المنطقي استخدام النموذج "الجانبي". في هذا النموذج ، تحتوي الحاوية الأساسية (خادم الويب الخاص بك) على حاويات إضافية ومكملة (وكيل Envoy ، وذاكرة التخزين المؤقت للورنيش ، وما إلى ذلك). يجب ربطها بإحكام مع مثيل محدد لخادم الويب * و * من الناحية الوظيفية ، المجموعة هي "الوحدة".

من الشائع جدًا رؤية قطع الأشجار والمراقبة والتتبع ومكونات البنية الأساسية الأخرى يتم تسليمها كأدوات جانبية أيضًا. الدافع هنا هو فصل المخاوف. لتزويد المطورين بمتطلبات ثابتة تنتج رمزًا يمكن التحكم فيه وتزويد SRE بالمرونة لاختيار الأدوات المفضلة مع العلم أن جميع الشفرات عبر الأسطول ستقوم بتسجيل الدخول وتنبعث منه المقاييس وتكون قابلة للتعقب وتطبق المصادقة باستمرار وما إلى ذلك. هذا نمط الذي يشكل الأساس لشبكات الخدمة (انظر #F Istio). هذا هو أفضل تدريب نهائي ، وإن كان حديث الولادة.

واو استخدام Istio

استخدم Istio بعناية.

Istio (وشبكات الخدمات الأخرى) هي تقنيات ناشئة نسبيًا ولدت من شركات (بما في ذلك Google) التي تدير حاويات على نطاق واسع. تنسجم الخدمة بشكل تافه مع وكيل (في حالة Istio ، Envoy) وكيل في كل قرنة في كل عملية نشر في كل مساحة اسم في كل مجموعة.

والنتيجة هي ركيزة إدارة متسقة تسمح بالاقتران الفضفاض للإدارة (سنستخدم Stackdriver Trace اليوم ولكن هناك خطة للانتقال إلى Jaeger ، لقد قمنا بتدوير مراقبة Prometheus) وخدمات التحكم (نعلم أن جميع خدماتنا آمنة ، نحن يتم توجيه 10٪ من حركة المرور إلى تصميمات الكناري للخدمات A و B و C).

أنصحك "بعناية" لأن هذه التقنيات جديدة وذات حواف خشنة وتتطور بسرعة. ولكن ، المزايا (المرونة ، الرشاقة ، التدقيق في المستقبل) توفر لك المنهجية على الأرجح تكاليف تفوق بكثير التكاليف. الأهم من ذلك ، استخدم شبكة الخدمة كنموذج لديك مع Kubernetes حتى لو لم تكن ترغب في اعتماد أحد تقنيات شبكات الخدمة.

هذا كل ما لدي أيها الناس!