مغامرات مع مجموعة Kubernetes الرئيسية

ملاحظة perev. : يشغل مؤلف المقال ، مارشال بريكا ، منصب مدير تصميم النظام في Fair.com ، والذي يقدم تطبيقه لتأجير السيارات. في وقت فراغه ، يحب استخدام خبرته الواسعة في حل المشكلات "المنزلية" التي من غير المرجح أن تفاجئ أي مهووس (وبالتالي ، فإن السؤال "لماذا؟" - فيما يتعلق بالإجراءات الموضحة أدناه - تم حذفه مسبقًا). لذلك ، في نشره ، يشارك مارشال نتائج نشر Kubernetes مؤخرا على ... لوحات ARM.



مثل العديد من المهوسون الآخرين ، على مر السنين ، جمعت مجموعة متنوعة من لوحات التطوير مثل Raspberry Pi. ومثل العديد من المهوسون ، فقد غمروا أنفسهم على الأرفف بفكرة أنهم سيأتون يومًا ما في متناول يدي. والآن بالنسبة لي هذا اليوم قد حان أخيرا!

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

  • حاوية RAID ذات 5 محركات مع اتصال USB3 ؛
  • توت العليق بي نموذج B (نموذج OG) ؛
  • CubbieBoard 1؛
  • Banana Pi M1؛
  • HP netbook (2012؟).

من بين مكونات الحديد الخمسة المدرجة ، استخدمت ما لم يكن RAID و netbook بمثابة NAS مؤقت. ومع ذلك ، بسبب عدم وجود دعم USB3 في نتبووك ، لم تستخدم RAID إمكانات السرعة الكاملة.

أهداف الحياة


نظرًا لأن العمل مع RAID لم يكن الأمثل عند استخدام netbook ، فقد حددت الأهداف التالية للحصول على أفضل تكوين:

  1. NAS مع USB3 وإيثرنت جيجابت ؛
  2. أفضل طريقة لإدارة البرنامج على جهازك
  3. (مكافأة) القدرة على دفق محتوى الوسائط المتعددة من RAID إلى Fire TV.

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

بعد أن حلّت احتياجات الأجهزة الخاصة بي (وانتظر وصول هذا الحل) ، انتقلت إلى الهدف الثاني.

إدارة البرنامج على الجهاز


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

قلت لنفسي إن هذه المرة سيكون كل شيء مختلفًا!



والتفت إلى حقيقة أنني أعرف جيدا بما فيه الكفاية - ل Kubernetes.

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

اعتقدت أيضًا أنه نظرًا لأن الأجهزة المتوفرة لا تفي بالمتطلبات الضرورية لنظام NAS ، سأحاول على الأقل تجميع مجموعة منه ، وربما تكون بعض البرامج التي لا تتطلب الكثير من الموارد قادرة على العمل على الأجهزة القديمة.

Kubernetes على أرمينيا


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

تم اختيار Raspbian كنظام تشغيل ، لأنه يشتهر بتقديم أفضل دعم للوحاتي.

لقد وجدت مقالًا جيدًا حول إعداد Kubernetes على Raspberry Pi باستخدام HypriotOS. نظرًا لأنني لم أكن متأكدًا من توفر HypriotOS لجميع اللوحات الخاصة بي ، فقد عدلت هذه التعليمات لـ Debian / Raspbian.

المكونات المطلوبة


أولاً ، يلزم تثبيت الأدوات التالية:

  • عامل الميناء ،
  • kubelet
  • kubeadm ،
  • كوبكتل.

يجب تثبيت عامل الميناء باستخدام برنامج نصي خاص للراحة (كما هو موضح لحالة استخدام Raspbian).

 curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh 

بعد ذلك ، قمت بتثبيت مكونات Kubernetes وفقًا للتعليمات الواردة من مدونة Hypriot ، مع تكييفها بحيث يتم استخدام إصدارات محددة لجميع التبعيات:

 curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" > /etc/apt/sources.list.d/kubernetes.list apt-get update apt-get install -y kubelet=1.13.1-00 kubectl=1.13.1-00 kubeadm=1.13.1-00 

التوت بي ب


نشأت أول صعوبة عند محاولة تمهيد مجموعة على Raspberry Pi B:

 $ kubeadm init Illegal instruction 

اتضح أن Kubernetes أزال الدعم لـ ARMv6 . حسنًا ، لدي أيضًا CubbieBoard و Banana Pi.

الموز بي


في البداية ، بدا أن نفس تسلسل الإجراءات الخاصة بـ Banana Pi كان أكثر نجاحًا ، ومع ذلك ، kubeadm init أمر kubeadm init أثناء محاولة الانتظار حتى تعمل طائرة التحكم:

 error execution phase wait-control-plane: couldn't initialize a Kubernetes cluster 

عندما اكتشفت مع docker ps ما كان يحدث مع الحاويات ، رأيت أن كلا من kube-controller-manager و kube-scheduler كانا يعملان لمدة لا تقل عن 4-5 دقائق ، لكن kube-api-server استيقظ منذ 1-2 دقائق فقط:

 $ docker ps CONTAINER ID COMMAND CREATED STATUS de22427ad594 "kube-apiserver --au…" About a minute ago Up About a minute dc2b70dd803e "kube-scheduler --ad…" 5 minutes ago Up 5 minutes 60b6cc418a66 "kube-controller-man…" 5 minutes ago Up 5 minutes 1e1362a9787c "etcd --advertise-cl…" 5 minutes ago Up 5 minutes 

من الواضح أن api-server كان يموت أو أن عملية السترونتيوم كانت تقتله وتعيد تشغيله.

عند التحقق من السجلات ، رأيت إجراءات بدء تشغيل قياسية للغاية - كان هناك سجل لبداية الاستماع إلى المنفذ الآمن وتوقف مؤقت طويل قبل ظهور العديد من الأخطاء في مصافحة TLS:

 20:06:48.604881 naming_controller.go:284] Starting NamingConditionController 20:06:48.605031 establishing_controller.go:73] Starting EstablishingController 20:06:50.791098 log.go:172] http: TLS handshake error from 192.168.1.155:50280: EOF 20:06:51.797710 log.go:172] http: TLS handshake error from 192.168.1.155:50286: EOF 20:06:51.971690 log.go:172] http: TLS handshake error from 192.168.1.155:50288: EOF 20:06:51.990556 log.go:172] http: TLS handshake error from 192.168.1.155:50284: EOF 20:06:52.374947 log.go:172] http: TLS handshake error from 192.168.1.155:50486: EOF 20:06:52.612617 log.go:172] http: TLS handshake error from 192.168.1.155:50298: EOF 20:06:52.748668 log.go:172] http: TLS handshake error from 192.168.1.155:50290: EOF 

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

ذهبت أبعد من ذلك وأعتقد أنه ربما يحصل api-server على الكثير من الطلبات المتكررة من scheduler ومدير controller-manager .

ستؤدي إزالة هذه الملفات من دليل البيان إلى إخبار kubelet بإيقاف تنفيذ القرون المقابلة:

 mkdir /etc/kubernetes/manifests.bak mv /etc/kubernetes/manifests/kube-scheduler.yaml /etc/kubernetes/manifests.bak/ mv /etc/kubernetes/manifests/kube-controller-mananger.yaml /etc/kubernetes/manifests.bak/ 

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

لذلك ، راجعت /etc/kubernetes/manifests/kube-api-server.yaml - /etc/kubernetes/manifests/kube-api-server.yaml ، بالطبع ...

 livenessProbe: failureThreshold: 8 httpGet: host: 192.168.1.155 path: /healthz port: 6443 scheme: HTTPS initialDelaySeconds: 15 timeoutSeconds: 15 

قتل Pod بعد 135 ثانية ( initialDelaySeconds + timeoutSeconds * failureThreshold ). زيادة initialDelaySeconds إلى 120 ...

النجاح! حسنًا ، لا تزال أخطاء المصافحة تحدث (من المفترض أن تكون من kubelet) ، ومع ذلك ما زال الإطلاق يحدث:

 20:06:54.957236 log.go:172] http: TLS handshake error from 192.168.1.155:50538: EOF 20:06:55.004865 log.go:172] http: TLS handshake error from 192.168.1.155:50384: EOF 20:06:55.118343 log.go:172] http: TLS handshake error from 192.168.1.155:50292: EOF 20:06:55.252586 cache.go:39] Caches are synced for autoregister controller 20:06:55.253907 cache.go:39] Caches are synced for APIServiceRegistrationController controller 20:06:55.545881 controller_utils.go:1034] Caches are synced for crd-autoregister controller ... 20:06:58.921689 storage_rbac.go:187] created clusterrole.rbac.authorization.k8s.io/cluster-admin 20:06:59.049373 storage_rbac.go:187] created clusterrole.rbac.authorization.k8s.io/system:discovery 20:06:59.214321 storage_rbac.go:187] created clusterrole.rbac.authorization.k8s.io/system:basic-user 

عندما نهض api-server ، قمت بنقل ملفات YAML لوحدة التحكم والجدولة مرة أخرى إلى دليل البيان ، وبعد ذلك بدأت بشكل طبيعي أيضًا.

حان الوقت للتأكد من نجاح التنزيل إذا تركت جميع الملفات في الدليل المصدر: هل يكفي تغيير التأخير المسموح به في تهيئة livenessProbe ؟

 20:29:33.306983 reflector.go:134] k8s.io/client-go/informers/factory.go:132: Failed to list *v1.Service: Get https://192.168.1.155:6443/api/v1/services?limit=500&resourceVersion=0: dial tcp 192.168.1.155:6443: i/o timeout 20:29:33.434541 reflector.go:134] k8s.io/client-go/informers/factory.go:132: Failed to list *v1.ReplicationController: Get https://192.168.1.155:6443/api/v1/replicationcontrollers?limit=500&resourceVersion=0: dial tcp 192.168.1.155:6443: i/o timeout 20:29:33.435799 reflector.go:134] k8s.io/client-go/informers/factory.go:132: Failed to list *v1.PersistentVolume: Get https://192.168.1.155:6443/api/v1/persistentvolumes?limit=500&resourceVersion=0: dial tcp 192.168.1.155:6443: i/o timeout 20:29:33.477405 reflector.go:134] k8s.io/client-go/informers/factory.go:132: Failed to list *v1beta1.PodDisruptionBudget: Get https://192.168.1.155:6443/apis/policy/v1beta1/poddisruptionbudgets?limit=500&resourceVersion=0: dial tcp 192.168.1.155:6443: i/o timeout 20:29:33.493660 reflector.go:134] k8s.io/client-go/informers/factory.go:132: Failed to list *v1.PersistentVolumeClaim: Get https://192.168.1.155:6443/api/v1/persistentvolumeclaims?limit=500&resourceVersion=0: dial tcp 192.168.1.155:6443: i/o timeout 20:29:37.974938 controller_utils.go:1027] Waiting for caches to sync for scheduler controller 20:29:38.078558 controller_utils.go:1034] Caches are synced for scheduler controller 20:29:38.078867 leaderelection.go:205] attempting to acquire leader lease kube-system/kube-scheduler 20:29:38.291875 leaderelection.go:214] successfully acquired lease kube-system/kube-scheduler 

نعم ، كل شيء يعمل ، على الرغم من أن هذه الأجهزة القديمة ، على ما يبدو ، لم يكن المقصود منها إطلاق طائرة التحكم ، لأن اتصالات TLS المتكررة تسبب فرامل كبيرة. بطريقة أو بأخرى - تم استلام تثبيت عملي لـ K8s على ARM! دعنا نذهب أبعد من ذلك ...

RAID تصاعد


نظرًا لأن بطاقات SD ليست مناسبة للتسجيل على المدى الطويل ، فقد قررت استخدام تخزين أكثر موثوقية للأجزاء الأكثر تقلبًا في نظام الملفات - في هذه الحالة ، RAID. تم تسليط الضوء على 4 أقسام على ذلك:

  • 50 جيجابايت ؛
  • 2 × 20 جيجابايت ؛
  • 3.9 تيرابايت.

لم أتوصل بعد إلى غرض محدد للأقسام التي تبلغ سعتها 20 غيغابايت ، لكنني أردت ترك فرص إضافية للمستقبل.

في الملف /etc/fstab بالنسبة لقسم 50 غيغابايت ، تم تحديد نقطة التحميل كـ /mnt/root ، وبالنسبة إلى 3.9 تيرابايت - /mnt/raid . بعد ذلك ، قمت بتثبيت الدلائل مع etcd ورسو السفن إلى قسم 50 جيجابايت:

 UUID=655a39e8-9a5d-45f3-ae14-73b4c5ed50c3 /mnt/root ext4 defaults,rw,user,auto,exec 0 0 UUID=0633df91-017c-4b98-9b2e-4a0d27989a5c /mnt/raid ext4 defaults,rw,user,auto 0 0 /mnt/root/var/lib/etcd /var/lib/etcd none defaults,bind 0 0 /mnt/root/var/lib/docker /var/lib/docker none defaults,bind 0 0 

وصول ROC-RK3328-CC


عندما تم تسليم اللوحة الجديدة ، قمت بتثبيت المكونات الضرورية لـ K8s (انظر بداية المقالة) وأطلقت kubeadm init . بضع دقائق من الانتظار هي نجاح وإخراج الأمر join لتعمل على العقد الأخرى.

عظيم! لا ضجة مع المهلات.

ونظرًا لأنه سيتم استخدام RAID أيضًا في هذه اللوحة ، فسوف تحتاج إلى إعادة التكوين. لتلخيص كل الخطوات:

1. جبل الأقراص في / الخ / fstab


 UUID=655a39e8-9a5d-45f3-ae14-73b4c5ed50c3 /mnt/root ext4 defaults,rw,user,auto,exec 0 0 UUID=0633df91-017c-4b98-9b2e-4a0d27989a5c /mnt/raid ext4 defaults,rw,user,auto 0 0 /mnt/root/var/lib/etcd /var/lib/etcd none defaults,bind 0 0 /mnt/root/var/lib/docker /var/lib/docker none defaults,bind 0 0 

2. تثبيت ثنائيات Docker و K8s


 curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh 

 curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" > /etc/apt/sources.list.d/kubernetes.list apt-get update apt-get install -y kubelet=1.13.1-00 kubectl=1.13.1-00 kubeadm=1.13.1-00 

3. تكوين اسم مضيف فريد (مهم يتم إضافة العديد من العقد)


 hostnamectl set-hostname k8s-master-1 

4. التهيئة Kubernetes


لقد حذفت المرحلة باستخدام طائرة التحكم ، لأنني أريد أن أكون قادرًا على التخطيط للقرون العادية على هذه العقدة:

 kubeadm init --skip-phases mark-control-plane 

5. تثبيت البرنامج المساعد للشبكة


كانت المعلومات الواردة في هذا المقال في Hypriot مؤرخة قليلاً لأن المكون الإضافي لشبكة Weave أصبح معتمدًا أيضًا على ARM :

 export KUBECONFIG=/etc/kubernetes/admin.conf kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')" 

6. إضافة تسميات المضيف


على هذه العقدة ، سأبدأ تشغيل خادم NAS ، لذلك سأضع علامة عليه مع تسميات للاستخدام المستقبلي المحتمل في المجدول:

 kubectl label nodes k8s-master-1 marshallbrekka.raid=true kubectl label nodes k8s-master-1 marshallbrekka.network=gigabit 

ربط العقد الأخرى إلى الكتلة


كان إعداد الأجهزة الأخرى (Banana Pi، CubbieBoard) بنفس السهولة. بالنسبة لهم ، تحتاج إلى تكرار الخطوات الثلاث الأولى (تغيير الإعدادات الخاصة بتركيب الأقراص / وسائط الفلاش ، حسب توفرها) وتشغيل الأمر kubeadm join بدلاً من kubeadm init .

العثور على حاويات قفص الاتهام ل ARM


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

الخطوات التالية


ما زلت لا أحصل على التكوين الأولي للأجهزة بصيغة تلقائية / نصية كما نود ، فقد قمت على الأقل بتكوين مجموعة من الأوامر الأساسية ( kubeadm docker kubeadm ) وقمت بتوثيقها في مستودع Git. تلقت بقية التطبيقات المستخدمة أيضًا تكوينات YAML لـ K8s المخزّنة في نفس المستودع ، لذا أصبح من السهل جدًا الآن الحصول على التكوين الضروري من البداية.

في المستقبل ، أود تحقيق ما يلي:

  1. اجعل المواقع الرئيسية متوفرة للغاية
  2. إضافة المراقبة / الإخطارات لمعرفة الفشل في أي مكونات ؛
  3. تغيير إعدادات DCHP للموجه لاستخدام خادم DNS من الكتلة من أجل تبسيط اكتشاف التطبيقات (من يريد أن يتذكر عناوين IP الداخلية؟) ؛
  4. قم بتشغيل MetalLB لإعادة توجيه خدمات الكتلة إلى شبكة خاصة (DNS ، وما إلى ذلك).


PS من المترجم


اقرأ أيضًا في مدونتنا:

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


All Articles