مجموعة Kubernetes مقابل 20 دولارًا شهريًا

TL د


نحن نرفع المجموعة لخدمة تطبيقات الويب عديمة الجنسية مع إدخال ، يتيح للتشفير ، دون استخدام أدوات التشغيل الآلي مثل kubespray ، kubeadm وأي أدوات أخرى.
وقت القراءة: ~ 45-60 دقيقة ، وقت التشغيل: من 3 ساعات.


الديباجة


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


مكونات


ستظهر المكونات التالية في المقالة:


- Linux المفضل لديك - لقد استخدمت Gentoo (العقدة 1: systemd / node-2: openrc) ، Ubuntu 18.04.1.
- خادم Kubernetes - kube-apiserver ، kube-controller-manager ، kube-scheduler ، kubelet ، kube-proxy.
- Containerd + CNI Plugins (0.7.4) - لنقل الحاويات ، سنتخذ containerd + CNI بدلاً من عامل ميناء (على الرغم من أن التكوين بالكامل تم تحميله بالكامل إلى عامل الميناء ، لذلك لن يمنع أي شيء استخدامه إذا لزم الأمر).
- CoreDNS - لتنظيم اكتشاف الخدمة للمكونات العاملة داخل كتلة kubernetes. يوصى باستخدام إصدار لا يقل عن 1.2.5 ، لأنه مع هذا الإصدار ، يوجد دعم عاقل لل coredns للعمل كعملية تعمل خارج الكتلة.
- الفانيلا - لتنظيم مكدس الشبكة ، وتوصيل الموقد والحاويات فيما بينها.
- ديسيبل المفضل لديك .


للجميع


القيود والافتراضات


  • لا تبحث المقالة في تكلفة حلول vps / vds في السوق ، وكذلك إمكانية نشر الأجهزة على هذه الخدمات. من المفترض أن لديك بالفعل شيء موسع ، أو أنك قادر على القيام بذلك بنفسك. أيضًا ، لا تتم تغطية تثبيت / تكوين قاعدة البيانات المفضلة لديك ومستودع التخزين الخاص ، إذا كنت بحاجة إلى قاعدة بيانات.
  • يمكننا استخدام كل من الإضافات containerd + cni والإرساء. لا تعتبر هذه المقالة استخدام عامل ميناء كأداة حاوية. إذا كنت ترغب في استخدام عامل ميناء ، فستتمكن من تكوين الفانيلا وفقًا لذلك ، بالإضافة إلى ذلك ، ستحتاج إلى تكوين kubelet ، أي إزالة جميع الخيارات المتعلقة بالحاوية. كما أوضحت تجاربي ، فإن عامل الإرساء والحاوية على عقد مختلفة حيث ستعمل الحاويات بشكل صحيح.
  • لا يمكننا استخدام الواجهة الخلفية host-gw للفانيلا ، اقرأ قسم تكوين الفانيلا لمزيد من التفاصيل
  • لن نستخدم أي شيء للمراقبة والنسخ الاحتياطي وحفظ ملفات المستخدم (الحالة) وتخزين ملفات التكوين ورمز التطبيق (git / hg / svn / إلخ)

مقدمة


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


التعيينات

قائمة المصطلحات / مسرد المصطلحات


  • api-server - جهاز فعلي أو افتراضي توجد عليه مجموعة من التطبيقات للتشغيل والأداء الصحيح kubernetes kube-apiserver. لأغراض هذه المقالة ، إنها etcd ، kube-apiserver ، kube-controller-manager ، kube-scheduler.
  • سيد - محطة عمل مخصصة أو تثبيت VPS ، مرادف لخادم api.
  • node-X - محطة عمل مخصصة أو تثبيت VPS ، تشير X إلى الرقم التسلسلي للمحطة. في هذه المقالة ، تكون جميع الأرقام فريدة ومهمة لفهم:
    • عقدة 1 - رقم الجهاز 1
    • عقدة -2 - رقم الجهاز 2
  • vCPU - وحدة المعالجة المركزية الافتراضية ، والمعالج الأساسية. الرقم يتوافق مع عدد النوى: 1vCPU - واحد الأساسية ، 2vCPU - اثنين ، وهلم جرا.
  • المستخدم - المستخدم أو مساحة المستخدم. عند استخدام user$ في تعليمات سطر الأوامر ، يشير المصطلح إلى أي جهاز عميل.
  • العامل - عقدة العمل التي سيتم إجراء الحسابات المباشرة عليها ، بشكل متزامن مع node-X
  • المورد هو الكيان الذي تعمل عليه مجموعة Kubernetes. تتضمن موارد Kubernetes عددًا كبيرًا من الكيانات ذات الصلة .

حلول هندسة الشبكات


في عملية رفع المجموعة ، لم أقم بتعيين مهمة تحسين موارد الحديد بطريقة تناسب ميزانية 20 دولارًا شهريًا. كان من الضروري فقط تجميع مجموعة عمل مع عقدتي عمل على الأقل (عقدتين). لذلك ، بدا في البداية الكتلة مثل هذا:


  • الجهاز مع 2 vCPU / 4G RAM: api-server + node-1 [20 $]
  • الجهاز مع 2 vCPU / 4G RAM: العقدة -2 [20 دولار]

بعد أن عملت النسخة الأولى من الكتلة ، قررت إعادة إنشائها للتمييز بين العقد المسؤولة عن تشغيل التطبيقات داخل الكتلة (عقد العمل ، وهي أيضًا عمال) وواجهة برمجة التطبيقات الخاصة بالخادم الرئيسي.


نتيجةً لذلك ، حصلت على إجابة للسؤال: "كيف يمكنني الحصول على مجموعة أقل تكلفة ، ولكن تعمل ، إذا كنت لا أرغب في وضع أكثر التطبيقات سمكًا هناك".


قرار 20 دولار

تصميم
(المخطط أن يكون مثل هذا)


Kubernetes العمارة معلومات عامة

تصميم
(سرق من الإنترنت إذا كان شخص ما فجأة ما زال لا يعرف أو لم ير)


المكونات وأدائها


كانت الخطوة الأولى هي فهم عدد الموارد التي أحتاج إليها لتشغيل حزم البرامج المرتبطة مباشرة بالكتلة. لم يعط البحث عن "متطلبات الأجهزة" نتائج محددة ، لذلك اضطررت إلى التعامل مع المهمة من وجهة نظر عملية. كقياس لـ MEM و CPU ، أخذت إحصاءات من systemd - يمكننا أن نفترض أن القياسات قد أجريت بطريقة هواة للغاية ، لكن لم يكن لديّ مهمة الحصول على قيم دقيقة ، لأنني ما زلت لا أستطيع العثور على خيارات أرخص من 5 دولارات لكل مثيل.


لماذا بالضبط 5 دولارات؟

كان من الممكن العثور على VPS / VDS أرخص عند استضافة الخوادم في روسيا أو رابطة الدول المستقلة ، ولكن القصص المحزنة المرتبطة بـ ILV وإجراءاتها تخلق مخاطر معينة وتثير رغبة طبيعية في تجنبها.


لذلك:


  • تكوين الخادم / الخادم الرئيسي (العقد الرئيسية):
    • etcd (3.2.17): 80 - 100M ، تم أخذ المقاييس في وقت تم اختياره عشوائيًا. متوسط ​​استهلاك الذاكرة لا يتعدى 300 متر ؛
    • kube-apiserver (1.12.x - 1.13.0): 237.6M ~ 300M ؛
    • kube-controller-manager (1.12.x - 1.13.0): حوالي 90 مترًا ، لم يرتفع عن 100 متر ؛
    • kube-scheduler (1.12.x - 1.13.0): حوالي 20 مليونًا ، استهلاك ثابت أعلى من 30-50 متر.
  • تكوين خادم العامل (عقد العامل):
    • kubelet (1.12.3 - 1.13.1): حوالي 35 ميجا بايت ، الاستهلاك فوق 50 متر غير ثابت ؛
    • kube-proxy (1.12.3 - 1.13.1): حوالي 7.5 - 10M ؛
    • الفانيلا (0.10.0): حوالي 15-20 متر ؛
    • coredns (1.3.0): حوالي 25M ؛
    • الحاوية (1.2.1): استهلاك الحاوية منخفض ، لكن الإحصاءات تظهر أيضًا عمليات الحاوية التي أطلقها البرنامج الخفي.

هل containerd / عامل ميناء اللازمة على العقد الرئيسية؟

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


التكوين المذكور أعلاه ضئيل وكافي لبدء الكتلة. لا يلزم اتخاذ إجراء / مكون إضافي ، إلا إذا كنت ترغب في إضافة شيء كما يحلو لك.


لإنشاء كتلة اختبار أو كتلة للمشاريع المنزلية ، ستكون ذاكرة الوصول العشوائي 1vCPU / 1G كافية لكي تعمل العقدة الرئيسية. بطبيعة الحال ، سوف يختلف الحمل على العقدة الرئيسية حسب عدد العمال المعنيين ، بالإضافة إلى توفر وحجم طلبات الطرف الثالث لخادم api.


لقد فجرت تكوينات السيد والعامل على النحو التالي:


  • 1X Master مع المكونات المثبتة: etcd ، kube-apiserver ، kube-controller-manager ، kube-scheduler
  • 2x العمال مع المكونات المثبتة: containerd ، coredns ، الفانيلا ، kubelet ، kube-proxy

التكوين


لتكوين المعالج ، تكون المكونات التالية مطلوبة:


  • الخ - لتخزين البيانات لخادم api ، وكذلك الفانيلا ؛


  • kube-apiserver - في الواقع ، api-server ؛


  • kube-controller-manager - لتوليد ومعالجة الأحداث ؛


  • kube-scheduler - لتوزيع الموارد المسجلة من خلال api-server - على سبيل المثال ، الموقد .
    لتكوين أوراق العمل ، تكون المكونات التالية مطلوبة:


  • kubelet - لتشغيل الموقد ، لتكوين إعدادات الشبكة ؛


  • kube-proxy - لتنظيم التوجيه / تحقيق التوازن بين خدمات kubernetes ؛


  • coredns - لاكتشاف الخدمة داخل حاويات التشغيل ؛


  • الفانيلا - لتنظيم الوصول إلى الشبكة من الحاويات التي تعمل على عقد مختلفة ، وكذلك للتوزيع الديناميكي للشبكات بين العقد العنقودية (عقدة kubernetes).



Coredns

يجب إجراء استطراد صغير هنا: يمكن أيضًا تشغيل coredns على الخادم الرئيسي. لا توجد قيود من شأنها أن تجبر coredns على العمل على عقد العمل ، باستثناء فارق التكوين corsns.service ، والذي ببساطة لا يبدأ على خادم Ubuntu قياسي / غير معدل بسبب تعارض مع الخدمة التي تم حلها systemd. لم أحاول حل هذه المشكلة ، نظرًا لأن خوادم 2 ns الموجودة على العقد العاملة كانت سعيدة جدًا معي.


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


الملفات


يتم وضع جميع الملفات الخاصة بتشغيل مكونات نظام المجموعة للمعالج وعقد العمل في / var / lib / kubernetes / للراحة. إذا لزم الأمر ، يمكنك وضعها في طريقة أخرى.


الشهادات


أساس توليد الشهادات لا يزال هو نفسه Kubernetes بالطريقة الصعبة ، لا توجد اختلافات كبيرة عمليا. لتجديد الشهادات الثانوية ، تمت كتابة نصوص bash بسيطة حول تطبيقات cfssl - كان ذلك مفيدًا للغاية في عملية تصحيح الأخطاء.


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


توليد الشهادة باستخدام البرامج النصية باش

يمكنك الحصول على البرامج النصية هنا: kubernetes bootstrap . قبل البدء ، قم بتحرير الملف certs / env.sh ، مع تحديد إعداداتك. مثال:


 $ cd certs #:   certs$ ./generate-keys.sh # ... certificate generate output #:  kubeconfig     certs$ ./generate-configkube.sh 

إذا استخدمت env.sh وحددت جميع المعلمات بشكل صحيح ، فلا داعٍ للمس الشهادات التي تم إنشاؤها. إذا ارتكبت خطأ في مرحلة ما ، فيمكن إعادة إصدار الشهادات في أجزاء. البرامج النصية للباش أعلاه تافهة ، وتصنيفها ليس بالأمر الصعب.


ملاحظة مهمة - لا ينبغي لك في كثير من الأحيان إعادة إنشاء ca.pem و ca-key.pem ، لأنها شهادات الجذر لجميع الشهادات اللاحقة ، بمعنى آخر ، سيكون عليك إعادة إنشاء جميع الشهادات المصاحبة وتسليمها إلى جميع الآلات وجميع الأدلة اللازمة.


السيد


يجب وضع الشهادات اللازمة لبدء تشغيل الخدمات على العقدة الرئيسية في /var/lib/kubernetes/ :


  • ca.pem - يتم استخدام هذه الشهادة في كل مكان ، ويمكن إنشاؤها مرة واحدة فقط ثم استخدامها دون تغييرات ، لذلك كن حذرًا. عند تجديده ، ستحتاج إلى نسخه إلى جميع العقد ، بالإضافة إلى تحديث ملفات kubeconfig باستخدامه (أيضًا على جميع الأجهزة).
  • ca-key.pem هو نفس النسخ عبر العقد.
  • kube-controller-manager.pem - مطلوب فقط من أجل kube-controller-manager.
  • kube-controller-manager-key.pem - مطلوب فقط من أجل kube-controller-manager.
  • kubernetes.pem - مطلوب من أجل الفانيلا ، coredns عند الاتصال بـ etcd ، kube-apiserver.


    تراجع نظري

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


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




  • kubernetes-key.pem - يبقى على الخوادم الرئيسية.
  • service-account.pem - مطلوب فقط للشياطين kube-controller-manager.
  • خدمة حساب key.pem - بالمثل.

وحدات العمل


  • ca.pem - ضروري لجميع الخدمات المعنية بعقد العمل (kubelet ، kube-proxy) ، وكذلك للفلانين ، coredns. من بين أشياء أخرى ، يتم تضمين محتوياته في ملفات kubeconfig عندما يتم إنشاؤها باستخدام kubectl.
  • kubernetes-key.pem - مطلوب فقط لفانيلا و coredns للاتصال بـ etcd ، الموجود على العقدة الرئيسية لـ api.
  • kubernetes.pem - على غرار سابقتها ، لا يحتاج إلا إلى الفانيلا و coredns.
  • kubelet / node-1.pem - مفتاح ترخيص العقدة -1.
  • kubelet / node-1-key.pem - مفتاح ترخيص العقدة -1.

مهم! إذا كان لديك أكثر من عقدة واحدة ، node-X-key.pem node-X.pem و node-X.kubeconfig وملفات node-X.kubeconfig داخل kubelet.


تصحيح الشهادة

تصحيح الشهادة


قد تحتاج في بعض الأحيان إلى النظر في كيفية تكوين الشهادة لمعرفة مضيفي IP / DNS الذين تم استخدامهم لإنشاءها. cfssl-certinfo -cert <cert> الأمر. على سبيل المثال ، نتعلم هذه المعلومات node-1.pem :


 $ cfssl-certinfo -cert node-1.pem 

 { "subject": { "common_name": "system:node:node-1", "country": "RU", "organization": "system:nodes", "organizational_unit": "Infrastructure Unit", "locality": "Moscow", "province": "Moscow", "names": [ "RU", "Moscow", "Moscow", "system:nodes", "Infrastructure Unit", "system:node:node-1" ] }, "issuer": { "common_name": "Kubernetes", "country": "RU", "organization": "Kubernetes", "organizational_unit": "Infrastructure", "locality": "Moscow", "province": "Moscow", "names": [ "RU", "Moscow", "Moscow", "Kubernetes", "Infrastructure", "Kubernetes" ] }, "serial_number": "161113741562559533299282037709313751074033027073", "sans": [ "w40k.net", "node-1", "178.79.168.130", "192.168.164.230" ], "not_before": "2019-01-04T14:24:00Z", "not_after": "2029-01-01T14:24:00Z", "sigalg": "SHA256WithRSA", "authority_key_id": "6:C8:94:67:59:55:19:82:AD:ED:6D:50:F1:89:B:8D:46:78:FD:9A", "subject_key_id": "A1:5E:B3:3C:45:14:3D:C6:C:A:97:82:1:D5:2B:75:1A:A6:9D:B0", "pem": "<pem content>" } 

يتم تضمين كافة الشهادات الأخرى لـ kubelet و kube-proxy مباشرةً في kubeconfig المناظر.


kubeconfig


كل الكوبيكونفيغ الضروري يمكن القيام به باستخدام Kubernetes بالطريقة الصعبة ، ولكن هنا تبدأ بعض الاختلافات. يستخدم الدليل kubedns و cni bridge ، كما أنه يغطي coredns و flannel . هاتين الخدمتين ، بدوره ، استخدام kubeconfig إلى الكتلة.


 $ cd certs #:  kubeconfig     certs$ ./generate-configkube.sh 

السيد


بالنسبة للمعالج ، هناك حاجة إلى ملفات kubeconfig التالية (كما هو مذكور أعلاه ، بعد إنشاء يمكن التقاطها في certs/kubeconfig ):


 master /var/lib/kubernetes/$ tree -L 2 . +-- kube-controller-manager.kubeconfig L-- kube-scheduler  L-- kube-scheduler.kubeconfig 

ستكون هذه الملفات مطلوبة لتشغيل كل مكون من مكونات الخدمة.


وحدات العمل


بالنسبة لعقد العمل ، تكون ملفات kubeconfig التالية مطلوبة:


 node-1 /var/lib/kubernetes/$ tree -L 2 . +-- coredns ¦  L-- coredns.kubeconfig +-- flanneld ¦  L-- flanneld.kubeconfig +-- kubelet ¦  L-- node-1.kubeconfig L-- kube-proxy  L-- kube-proxy.kubeconfig 

إطلاق الخدمة


الخدمات

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


لبدء الخدمات ، تحتاج إلى نسخ service-name.service إلى /lib/systemd/system/ أو أي دليل آخر توجد به خدمات systemd ، ثم قم بتشغيل الخدمة وبدء تشغيلها. مثال على kube-apiserver:


 $ systemctl enable kube-apiserver.service $ systemctl start kube-apiserver.service 

بالطبع ، يجب أن تكون جميع الخدمات خضراء (أي ، تعمل وتعمل). إذا واجهت خطأ ، فإن journalct -xe أو journal -f -t kube-apiserver ستساعدك في فهم الخطأ الذي حدث بالضبط.


لا تتعجل في بدء تشغيل جميع الخوادم دفعة واحدة ، فالبداية ستكون كافية لتمكين etcd و kube-apiserver. إذا سارت الأمور على ما يرام ، وحصلت على الفور على جميع الخدمات الأربع على المعالج ، يمكن اعتبار تشغيل المعالج ناجحًا.


السيد


يمكنك استخدام إعدادات systemd أو إنشاء البرامج النصية الأولية للتكوين الذي تستخدمه. كما سبق ذكره ، للسيد تحتاج:


- systemd / الخ
- systemd / kube-apiserver
- systemd / kube-controller-manager
- SYSTEMD / كوب المجدول


وحدات العمل


- systemd / containerd
- systemd / kubelet
- systemd / kube-proxy
- systemd / coredns
- systemd / الفانيلا


العملاء


لكي يعمل العميل ، ما عليك سوى نسخ certs/kubeconfig/admin.kubeconfig (بعد certs/kubeconfig/admin.kubeconfig أو كتابته بنفسك) بـ ${HOME}/.kube/config


قم بتنزيل kubectl وتحقق من تشغيل kube-apiserver. اسمحوا لي أن أذكرك مرة أخرى أنه في هذه المرحلة ، لكي يعمل kube-apiserver ، يجب أن يعمل فقط etcd. ستكون هناك حاجة إلى المكونات المتبقية للتشغيل الكامل للكتلة في وقت لاحق.


تحقق من عمل kube-apiserver و kubectl:


 $ kubectl version Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.0", "extra info": "..."} Server Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.0", "extra info": "..."} 

تكوين الفانيلا


vxlan الفانيلا ، استقر على الواجهة الخلفية لـ vxlan . قراءة المزيد عن الخلفية هنا .


المضيف غيغاواط ولماذا لن ينجح

يجب أن أقول على الفور أن تشغيل مجموعة kubernetes على VPS من المحتمل أن يحدك من استخدام الواجهة الخلفية host-gw . لا أكون مهندس شبكة متمرسًا ، فقد قضيت تصحيح الأخطاء لمدة يومين لفهم المشكلة التي تكمن في استخدامها مع موفري خدمة VDS / VPS الرائدين.


تم اختبار Linode.com و digitalocean . جوهر المشكلة هو أن مقدمي الخدمات لا يوفرون L2 صادقًا لشبكة خاصة. وهذا بدوره يجعل من المستحيل نقل حركة مرور الشبكة بين العقد في هذا التكوين:


المرور


لكي تعمل حركة مرور الشبكة بين العقد ، سيكفي التوجيه العادي. لا تنسَ أنه يجب تعيين net.ipv4.ip_forward على 1 ، ويجب ألا تحتوي سلسلة FORWARD في جدول الترشيح على قواعد حظر للعقد.


 node1$ ip route add 10.200.12.0/24 via 192.168.1.2 node2$ ip route add 10.200.8.0/24 via 192.168.1.1 

 [10.200.80.23 container-1]->[192.168.1.1 node-1]->[192.168.1.2 node-2]->[10.200.12.5 container-2] 

هذا هو بالضبط ما لا يعمل على VPS / VDS المشار إليها (وعلى الأرجح ، بشكل عام على جميع).


لذلك ، إذا كان تكوين حل بأداء عالي للشبكة بين العقد مهمًا بالنسبة لك ، فلا يزال عليك إنفاق أكثر من 20 دولارًا لتنظيم المجموعة.


يمكنك استخدام set-flannel-config.sh من etc / flannel لتعيين تكوين الفانيلا المطلوب. من المهم أن تتذكر : إذا قررت تغيير الخلفية ، فستحتاج إلى حذف التكوين في etcd وإعادة تشغيل جميع شياطين الفانيلا على جميع العقد ، لذلك اختره بحكمة. الافتراضي هو vxlan.


 master$ export ETCDCTL_CA_FILE='/var/lib/kubernetes/ca.pem' master$ export ETCDCTL_CERT_FILE='/var/lib/kubernetes/kubernetes.pem' master$ export ETCDCTL_KEY_FILE='/var/lib/kubernetes/kubernetes-key.pem' master$ export ETCDCTL_ENDPOINTS='https://127.0.0.1:2379' master$ etcdctl ls /coreos.com/network/subnets/ /coreos.com/network/subnets/10.200.8.0-24 /coreos.com/network/subnets/10.200.12.0-24 master$ etcdctl get /coreos.com/network/subnets/10.200.8.0-24 {"PublicIP":"178.79.168.130","BackendType":"vxlan","BackendData":{"VtepMAC":"22:ca:ac:15:71:59"}} 

بعد تسجيل التكوين المطلوب في etcd ، تحتاج إلى تكوين الخدمة لتشغيلها على كل من العقد العاملة.


الفانيلا


يمكن أخذ مثال للخدمة هنا: systemd / flannel


الفانيلا
 [Unit] Description=Flanneld overlay address etcd agent After=network.target [Service] Type=notify #: current host ip. don't change if ip have not changed Environment=PUBLIC_IP=178.79.168.130 Environment=FLANNEL_ETCD=https://192.168.153.60:2379 ExecStart=/usr/bin/flanneld \ -etcd-endpoints=${FLANNEL_ETCD} -etcd-prefix=${FLANNEL_ETCD_KEY} \ -etcd-cafile=/var/lib/kubernetes/ca.pem \ -etcd-certfile=/var/lib/kubernetes/kubernetes.pem \ -etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \ -etcd-prefix=/coreos.com/network \ -healthz-ip=127.0.0.1 \ -subnet-file=/run/flannel/subnet.env \ -public-ip=${PUBLIC_IP} \ -kubeconfig-file=/var/lib/kubernetes/config/kubeconfig/flanneld.kubeconfig \ $FLANNEL_OPTIONS ExecStartPost=/usr/libexec/flannel/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker Restart=on-failure RestartSec=5 [Install] RequiredBy=docker.service 

التخصيص


كما هو موضح سابقًا ، نحتاج إلى ملفات ca.pem و kubernetes.pem و kubernetes-key.pem للترخيص في etcd. جميع المعلمات الأخرى لا تحمل أي معنى مقدس. الشيء الوحيد المهم حقًا هو تكوين عنوان IP العمومي الذي سيتم من خلاله نقل حزم الشبكة بين الشبكات:


الشبكات الفانيلا
( تراكب الشبكات متعددة المضيفين مع الفانيلا )


 #:   node-1$ systemctl enable flanneld.service #:  node-1$ systemctl start flanneld 

بعد بدء تشغيل flannel بنجاح ، يجب أن تجد واجهة الشبكة flannel.N على نظامك:


 node-1$ ifconfig flannel.100: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450 inet 10.200.8.0 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::20ca:acff:fe15:7159 prefixlen 64 scopeid 0x20<link> ether 22:ca:ac:15:71:59 txqueuelen 0 (Ethernet) RX packets 18853 bytes 1077085 (1.0 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 11856 bytes 264331154 (252.0 MiB) TX errors 0 dropped 47 overruns 0 carrier 0 collisions 0 

التحقق من أن واجهاتك تعمل بشكل صحيح على جميع العقد أمر بسيط للغاية. في حالتي ، تحتوي العقدة -1 والعقدة 2 على شبكات 10.200.8.0/24 و 10.200.12.0/24 ، على التوالي ، وبالتالي ، باستخدام طلب icmp عادي ، تحقق من توفرها:


 #:  node-2  node-1 node-1 $ ping -c 1 10.200.12.0 PING 10.200.12.0 (10.200.12.0) 56(84) bytes of data. 64 bytes from 10.200.12.0: icmp_seq=1 ttl=64 time=4.58 ms #:  node-1  node-2 node-2 $ ping -c 1 10.200.8.0 PING 10.200.8.0 (10.200.8.0) 56(84) bytes of data. 64 bytes from 10.200.8.0: icmp_seq=1 ttl=64 time=1.44 ms 

في حالة حدوث أي مشاكل ، يوصى بالتحقق مما إذا كانت هناك قواعد قطع في iptables عبر UDP بين المضيفين.


Containerd التكوين


ضع etc / containerd / config.toml في /etc/containerd/config.toml أو في أي مكان مناسب لك ، الشيء الرئيسي هو تذكر تغيير المسار إلى ملف التكوين في الخدمة (containerd.service ، الموضح أدناه).


التكوين مع بعض التعديلات على المعيار. من المهم عدم تعيين enable_tls_streaming = true إذا كنت لا تفهم سبب قيامك بذلك. kubectl exec , .


containerd.service


containerd.service
 [Unit] Description=containerd container runtime Documentation=https://containerd.io After=network.target [Service] ; uncomment this if your overlay module are built as module ; ExecStartPre=/sbin/modprobe overlay ExecStart=/usr/bin/containerd \ -c /etc/containerd/config.toml Restart=always RestartSec=5 Delegate=yes KillMode=process OOMScoreAdjust=-999 LimitNOFILE=1048576 LimitNPROC=infinity LimitCORE=infinity [Install] WantedBy=multi-user.target 

التخصيص


, , cri-tools .
etc/crictl.yaml /etc/crictl.yaml . :


 node-1$ CONTAINERD_NAMESPACE=k8s.io crictl ps CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT POD ID 

, - kubernetes , crictl , , .


CNI Plugins


CNI , , , .


التخصيص


cni plugins /opt/cni/bin/


/etc/cni/net.d :


/etc/cni/net.d/10-flannel.conflist
 { "cniVersion": "0.3.0", "name": "cbr0", "plugins": [ { "type": "flannel", "name": "kubenet", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true }, "externalSetMarkChain": "KUBE-MARK-MASQ" } ] } 

/etc/cni/net.d/99-loopback.conf
 { "cniVersion": "0.3.0", "type": "loopback" } 

, . , , Red Hat Docker Podman , Intro to Podman


Kubelet


kubelet ( cni) — . kubelet hostname. , "" kubectl logs , kubectl exec , kubectl port-forward .


kubelet-config.yaml

, etc/kubelet-config.yaml , , . :


 systemReserved: cpu: 200m memory: 600Mi 

, GO kubernetes, , . . 0.2 vCPU 600 MB .


, , kubelet, kube-proxy, coredns, flannel . , — 2 vCPU / 4G ram, , kubernetes + postgresql .


- (micro nodes) .


kubelet.service


service : systemd/kubelet


kubelet.service
 [Unit] Description=Kubernetes Kubelet Documentation=https://github.com/kubernetes/kubernetes Requires=containerd.service [Service] #Environment=NODE_IP=192.168.164.230 Environment=NODE_IP=178.79.168.130 #: node name given by env Environment=NODE_NAME=w40k.net ExecStart=kubelet \ --allow-privileged \ --root-dir=/var/lib/kubernetes/kubelet \ --config=/var/lib/kubernetes/kubelet/kubelet-config.yaml \ --kubeconfig=/var/lib/kubernetes/kubelet/node-1.kubeconfig \ --cni-bin-dir=/opt/cni/bin \ --cni-conf-dir=/etc/cni/net.d/ \ --network-plugin=cni \ --container-runtime=remote \ --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \ --image-pull-progress-deadline=10m \ --node-ip=${NODE_IP} \ --hostname-override=${NODE_NAME} \ --v=1 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target 

التخصيص


, RBAC , kubelet.


etc/kubelet-default-rbac.yaml , kubelet :


 user$ kubectl apply -f etc/kubelet-default-rbac.yaml 

, , .


 #:   node-1$ systemctl enable kubelet.service #:  node-1$ systemctl start kubelet 

, api :


 $ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME w40k.net Ready <none> 5m v1.13.1 178.79.168.130 <none> Gentoo/Linux 4.18.16-x86_64-linode118 containerd://1.2.1 

Kube Proxy


: systemd/kubelet . , , kube-proxy-config.yaml : etc/kube-proxy


kube-proxy.service


kube-proxy.service
 [Unit] Description=Kubernetes Proxy Documentation=https://github.com/kubernetes/kubernetes After=network.target [Service] ExecStart=kube-proxy \ --config=/var/lib/kubernetes/kube-proxy/kube-proxy-config.yaml Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target 

التخصيص


 #:   node-1$ systemctl enable kube-proxy.service #:  node-1$ systemctl start kube-proxy 

kube-proxy "" iptables, , - kubernetes (- ). .


CoreDNS


Corefile : etc/coredns/Corefile , :


/etc/coredns/Corefile
 .:53 { errors log stdout health :8081 kubernetes cluster.local 10.200.0.0/16 { endpoint https://178.79.148.185:6443 tls /var/lib/kubernetes/kubernetes.pem /var/lib/kubernetes/kubernetes-key.pem /var/lib/kubernetes/ca.pem pods verified upstream /etc/resolv.conf kubeconfig /var/lib/kubernetes/config/kubeconfig/coredns.kubeconfig default } proxy . /etc/resolv.conf cache 30 } 

coredns.kubeconfig pem- ( ) worker . , coredns systemd-resolved. , Ubuntu , , , , . .


coredns.service


coredns.service
 [Unit] Description=CoreDNS Documentation=https://coredns.io/ After=network.target [Service] ExecStart=/usr/bin/coredns -conf /etc/coredns/Corefile Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target 

التخصيص


 #:   node-1$ systemctl enable coredns.service #:  node-1$ systemctl start coredns 

, , :


 node-1$ dig kubernetes.default.svc.cluster.local @127.0.0.1 #:    ;kubernetes.default.svc.cluster.local. IN A ;; ANSWER SECTION: kubernetes.default.svc.cluster.local. 5 IN A 10.32.0.1 

, coredns ip kubernetes .
, kubernetes.default kube-controller-manager, :


 $ kubectl get svc -n default NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.32.0.1 <none> 443/TCP 26h 

nginx-ingress & cert-manager


, . nginx-ingress cert-manager.


nginx kubernetes ingress (master), :


  user$ git clone https://github.com/nginxinc/kubernetes-ingress.git user$ cd kubernetes-ingress/deployments user$ kubectl apply -f common/ns-and-sa.yaml user$ kubectl apply -f common/nginx-config.yaml user$ kubectl apply -f common/default-server-secret.yaml user$ kubectl apply -f daemon-set/nginx-ingress.yaml user$ kubectl apply -f rbac/rbac.yaml 

cert manager (v0.5.2)


  user$ git clone https://github.com/jetstack/cert-manager.git user$ cd cert-manager && git co v0.5.2 user$ cd contrib/manifests/cert-manager user$ kubectl apply -f with-rbac.yaml 

, , , :


 NAMESPACE NAME READY STATUS RESTARTS AGE cert-manager cert-manager-554c76fbb7-t9762 1/1 Running 0 3h38m nginx-ingress nginx-ingress-sdztf 1/1 Running 0 10h nginx-ingress nginx-ingress-vrf85 1/1 Running 0 10h 

cert-manager nginx-ingress running state, , . , Running . .



, . , kubernetes resource : app/k8s


 user$ kube apply -f ns-and-sa.yaml user$ kube apply -f configmap.yaml #:  secret-example.yaml       #: secret.yaml user$ kube apply -f secret.yaml user$ kube apply -f tls-production.yaml user$ kube apply -f deployment.yaml user$ kube apply -f service.yaml user$ kube apply -f ingress-production.yaml 

, - . , ( kubernetes-example.w40k.net), , , cert-manager nginx-ingress . , ingress tls/ssl.


:



, - . - , , .


المراجع


, , :


Kubernetes the hard way
Multi-Host Networking Overlay with Flannel
Intro to Podman
Stateless Applications
What is ingress


:


Kubernetes Networking: Behind the scenes ( )
A Guide to the Kubernetes Networking Model
Understanding kubernetes networking: services ( )


Q&A


<tbd>, .



, , . , , - , , .


Api Server


kube-apiserver.service , api-server' curl http . - .
admin.kubeconfig ${HOME}/.kube/config, kubectl api-server (kube-apiserver).


( ) HTTP 200 OK + , api-server :


 curl -H "Authorization: Bearer e5qXNAtwwCHUUwyLilZmAoFPozrQwUpw" -k -L https://<api-server-address>:6443/api/v1/ 

Kube Controller Manager


, controller manager api , . , service account' :


 $ kubectl get sa NAME SECRETS AGE default 1 19h 

, , kube-controller-manager .


Kube Scheduler


. , , debug/job.yaml kubectl describe <type/resource> .
, kube controller manager .


 #:   job user$ kubectl apply -f debug/job.yaml job.batch/app created #:  ,   job user$ kubectl get pods -l job-name=app NAME READY STATUS RESTARTS AGE app-9kr9z 0/1 Completed 0 54s #: ,        #:   user$ kubectl describe pods app-9kr9z # ...   ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 12s default-scheduler Successfully assigned example/app-9kr9z to w40k.net 

, default-scheduler pod w40k.net. - , — .


. , , , — "". systemd .


kube scheduler


Kubelet


Kubelet kubernetes . kubelet . kubernetes event ( kubectl get events -o wide ) .


( )


Kube Proxy


kube-proxy :


  • ( Flannel , );
  • iptables, filter nat .

, 10.32.0.0/24 "". , . iptables, , , - +. icmp , ping' . , .


, kube-proxy, :


 #:    user$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE backend ClusterIP 10.32.0.195 <none> 80/TCP 5m #:     user$ kubectl get pods -o wide #:     ' NAME READY STATUS RESTARTS AGE IP NODE backend-896584448-4r94s 1/1 Running 0 11h 10.200.8.105 w40k.net backend-896584448-np992 1/1 Running 0 11h 10.200.12.68 docker.grart.net #:  10   /status/ endpoint ,       #:       node-1$ for i in `seq 10`; do curl -L http://10.32.0.195/status/; done okokokokokokokokokok node-1$ conntrack -L -d 10.32.0.195 tcp 6 62 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62158 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62158 [ASSURED] mark=0 use=1 tcp 6 60 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62144 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62144 [ASSURED] mark=0 use=1 tcp 6 58 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62122 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62122 [ASSURED] mark=0 use=1 tcp 6 59 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62142 dport=80 src=10.200.8.105 dst=10.200.8.1 sport=8000 dport=62142 [ASSURED] mark=0 use=1 tcp 6 58 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62130 dport=80 src=10.200.8.105 dst=10.200.8.1 sport=8000 dport=62130 [ASSURED] mark=0 use=1 tcp 6 61 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62150 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62150 [ASSURED] mark=0 use=1 tcp 6 56 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62116 dport=80 src=10.200.8.105 dst=10.200.8.1 sport=8000 dport=62116 [ASSURED] mark=0 use=1 tcp 6 57 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62118 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62118 [ASSURED] mark=0 use=1 tcp 6 59 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62132 dport=80 src=10.200.12.68 dst=10.200.8.0 sport=8000 dport=62132 [ASSURED] mark=0 use=1 tcp 6 56 TIME_WAIT src=178.79.168.130 dst=10.32.0.195 sport=62114 dport=80 src=10.200.8.105 dst=10.200.8.1 sport=8000 dport=62114 [ASSURED] mark=0 use=1 

src/dst (9 10 ). , src :


  • 10.200.8.105
  • 10.200.12.68

, . , - ( , ) . .


 #: node-1   10.200.8.105, node-2 10.200.12.68, #:      8000  #:  node-1 node-1$ curl -L http://10.200.8.105:8000/status/ ok node-1$ curl -L http://10.200.12.68:8000/status/ ok #:  node-2 node-2$ curl -L http://10.200.8.105:8000/status/ ok node-2$ curl -L http://10.200.12.68:8000/status/ ok 

, , conntrack , , kube-proxy. , nat :


node-1$ iptables -t nat -vnL


.


. , , . , . - , , .


Source: https://habr.com/ru/post/ar435228/


All Articles