Loading [MathJax]/extensions/tex2jax.js

11 листопада 2018

Kubernetes кластер на Raspberry PI (кінцеві налаштування)

Минулого разу ми завершили на налаштуванні мережі нашого майбутнього кластеру. Основну кількість роботи ми зробили на мастері, а на нодах у вас повинно працювати автоматично. Сьогодні ми встановимо основні Kubernetes компоненти на мастері і всіх нодах і тим самим запустимо наш невеличкий кластер на Raspberry PI.

Майже всі кроки (крім кількох останніх) будуть аналогічні як на мастері так і на кожному ноді, тому загалом непогана ідея записати це все в маленький скрипт який можна буде запустити на кожному вузлі окремо, але цю вправу я залишу вам на домашнє завдання.

Перш за все нам необхідно встановити рантайм для майбутніх контейнерів. В цій статті я опишу встановлення докера, мабуть, найпопулярнішого рішення на сьогодні, а в майбутньому підготую окрему статтю про containerd та його переваги і недоліки. Для встановлення Докера я скористаюся офіційним скриптом, який здійснить всю необхідну конфігурацію:
$ curl -sSL get.docker.com | sh && sudo usermod pi -aG docker
На жаль, в подальшому у вас можуть виникнути труднощі. Проблема в тому, що цей скрипт встановлює останню версію, а Kubernetes з великою ймовірністю не був протестований на ній. Тому я вирішив встановити старшу версію, яка офіційна підтримується Kubernetes (зауважте, що на момент прочитання цієї статті, версія може змінитися). Для версії Kubernetes 1.12.2 найновіша версія докера це 18.06, тому я скористався наступними командами для перевстановлення:
$ sudo apt-get -y remove docker-ce docker-engine$ sudo apt-get -y install docker-ce=18.06.1~ce~3-0~raspbian
Далі для коректтної роботи kubelet (один з базових компонентів) необхідно відключити на лінуксі swap, цього можна досягти з допомогою наступних команд:
$ sudo dphys-swapfile swapoff
$ sudo dphys-swapfile uninstall
$ sudo update-rc.d dphys-swapfile remove
І останній з конфігураційних кроків це налаштування cgroups (коротко це те, що дозволяє запускати контейнери на лінуксі):
$ orig="$(head -n1 /boot/cmdline.txt) cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1"
$ echo $orig | sudo tee /boot/cmdline.txt
Далі необхідно перезапустити малину:
$ sudo reboot
Тепер приступаємо до встановлення компонентів Kubernetes. Перш за все створюємо файл /etc/apt/sources.list.d/kubernetes.list і до нього добавляємо одну лінійку:
deb https://apt.kubernetes.io/ kubernetes-xenial main
Після цього можна встановити все за допомогою apt-get:
$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl
Всі кроки, які ми виконали до цього моменту були спільні для всіх вузлів. Тепер переходимо конкретно на мастер і запускаємо наступну команду:
$ sudo kubeadm init --pod-network-cidr 10.244.0.0/16 --apiserver-advertise-address 10.0.0.1
Тут мушу вас засмутити, швидше за все через кілька хвилин ви отримаєте повідомлення про помилку. Перед тим як продовжити необхідно буде очистити все від сміття, для цього може скористатися командою:
$ sudo kubeadm reset
А тепер я спробую пояснити в чому проблема. Якщо коротко то kubelet кожних 15 секунд перевіряє kube-apiserver, чи йому вдалося нормально запуститися, а після 8 невдалих спроб він його вбиває і знову запускає. Але проблема в тому що двох хвилин явно замало на комп'ютері з 1Гб оперативної пам'яті, тому ми отримуємо процес в якому kubelet весь час вбиває, майже готового kube-apiserver. Мені експериментальним шляхом вдалося знайти невеличкий хак, який допоможе вам обійти цю проблему. Для цього повторюємо ініціалізацію кластеру, як тільки в консолі появиться надпис: 
[init] this might take a minute or longer if the control plane images have to be pulled
Виконуємо в іншому терміналі наступні дві команди:
$ sed -i 's/failureThreshold: 8/failureThreshold: 20/g' /etc/kubernetes/manifests/kube-apiserver.yaml$ docker kill `docker ps | grep POD_kube-apiserver | awk '{ print $1 }'`
Першою командою ми переписуємо ліміт в 8 спроб на 20 (тобто даємо kube-apiserver приблизно 5 хвилин на старт), а наступною перезапускаємо kube-apiserver. Якщо все пройде успішно, то за кілька хвилин ви повинні побачити в консолі приблизно наступний текст:


Виконаємо наступні команди, для того щоб могли користуватися утилітою kubectl:
$ mkdir -p $HOME/.kube$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
Також копіюємо команду, яку ви бачите на кінці. Переходимо на кожен з нодів і запускаємо її. Ви повинні побачити в консолі текст наступного вмісту:


Тепер спробуємо отримати інформацію про підключені ноди нашого кластера. Для цього на мастері запускаємо команду:
$ kubectl get nodes
Ви повинні побачити що всі ваші ноди не готові:


Це пов'язано з тим, що для правильної роботи Kubernetes необхідна спеціальна конфігурація внутрішної мережі (між подами які ми будемо запускати в майбутньому). На превелике щастя цю конфігурацію ми можемо здійснити за допомогою одної команди:
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Якщо ви повторите через кілька хвилин команду kubectl get nodes то тепер статус нодів має змінитися на Ready.

Ну і як підсумок. Загалом процедура встановлення не є дуже складною. Багато шаманства пішло на конфігурацію мережі, а при запуску кластера необхідно було догадатися переписати одну змінну, але це проблема, яка не повинна виникнути при використанні більш потужніших машин. У випадку нодів нашаштування взагалі зайняло кілька хвилин і то більшість з них можна автоматизувати за допомогою невеличкого скрипта. В наступних статтях я постараюся детальніше пояснити архітектуру кластеру і для чого необхідний кожен з компонентів.

Немає коментарів:

Дописати коментар