Первое знакомство с Kubernetes: установка кластера k8s вручную

В небольшом цикле статей мы поближе познакомим читателей с оркестратором Kubernetes. Для начала настроим кластер k8s c нуля на VPS-хостинге с помощью Kubespray.

Kubernetes – открытое программное обеспечение для оркестровки контейнеризированных приложений, автоматизации их развертывания, масштабирования и координации в условиях кластера. Чем этот хорош этот инструмент и почему стоит тратить время на его изучение? Перечислим основные преимущества Kubernetes:

● Быстрый deploy приложений;

● Удобное масштабирование развернутых приложений;Вcя необходимая математика для начала карьеры в Data ScienceСкидка 15% по промокоду PROGЗаписаться

● Внутренние self-health;

● Нулевой простой при обновлениях приложений.

В первой статьи цикла мы займемся практическими вопросами и поднимем кластер k8s, а более подробно про оркестраторы расскажем в следующих частях цикла.

Варианты установки

k8s можно развернуть несколькими способами в зависимости от ваших целей и времени, которое вы намерены потратить. Есть быстрые варианты, вроде GKE (Google) или EKS (Amazon). Они позволяют быстро поднять кластер, не задумываясь о его внутреннем устройстве: вы получите результат менее чем за 5 минут.

Если вам интересно погрузиться в тему поглубже и буквально собрать k8s в ручном режиме, эта статья поможет. Поехали 🙂

Подготовка

В дальнейшем мы будем использовать созданный кластер для публикации различных сервисов и поэтому установку будет производить на VPS. Для кластера потребуется несколько виртуальных машин:

● Master node (CentOS 7, 1vCPU, RAM 2 ГБ, HDD 10 ГБ);

● Worker node (CentOS 7, 1vCPU, RAM 2 ГБ, HDD 10 ГБ);

● Worker node (CentOS 7, 1vCPU, RAM 2 ГБ, HDD 10 ГБ);

● Ingress node (CentOS 7, 2vCPU, RAM 8 ГБ, HDD 10 ГБ).

На всех узлах нашего кластера k8s установлена хост-система CentOS 7. Если вы хотите использовать другую хост-систему, ищите информацию на официальном сайте Kubernetes. Рассмотрим вариант развертывания с помощью Kubespray – набора ролей Ansible для установки и конфигурирования k8s.

Развертывание k8s

Для начала мы отключим файл/раздел подкачки и межсетевой экран на всех узлах кластера, а также сгенерируем и скопируем ключи SSH, чтобы Ansible мог ходить по хостам и творить свою магию:

Отключаем SWAP:

        swapoff -a
    

Отключаем firewall (на учебном стенде это допустимо, но на проде не стоит так делать не стоит):

        firewall-cmd --state
systemctl stop firewalld
systemctl disable firewalld

    

Наша следующая задача – сгенерировать ключ SSH и скопировать его на все узлы будущего кластера, включая master (где ключ был изначально сгенерирован):

        ssh-keygen
ssh-copy-id root@<master host IP>

    

Теперь копируем ключ на оставшиеся хосты (команды выполняются на мастер-хосте):

        ssh-copy-id root@remote_host
    

Далее на master устанавливаем pip и git:

        curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
python get-pip.py
yum install git

    

Если у вас используется старая версия Python, pip можно поставить следующим способом:

        curl "https://bootstrap.pypa.io/pip/2.7/get-pip.py" -o "get-pip.py"
python get-pip.py

    

Подготовка платформы завершена. Мы по-прежнему находимся на мастер-хосте и до конца развертывания кластера с него не уйдем. За нас будет ходить Ansible 🙂

Для дальнейших действий потребуется репозиторий Kubespray. Клонируем его:

        git clone https://github.com/kubernetes-sigs/kubespray.git
cd kubespray

    

Устанавливаем зависимости для Kubespray, описанные в файле requirements.txt:

        pip install --ignore-installed requests==2.23.0
pip install -r requirements.txt

    

Подведем итог наших действий:

● На ноде master установлен Ansible;

● Сгенерирован и скопирован ssh ключ на все узлы кластера;

● Установлены необходимые зависимости из файла requirements.txt.

Конфигурация Kubespray

Чтобы Kubespray понимал, на какие узлы нужно устанавливать k8s, придется создать директорию с описанием конфигурации будущего кластера. Тему inventory в первой статье мы подробно разбирать не будем, поскольку она слишком обширная (рабочий inventory доступен по ссылке – скопируйте его).

Потребуется изменить IP-адреса. Ниже приведет пример inventory.ini c нашими адресами (у вас они будут другими):

        master-1.root.local.io ansible_host=192.168.0.3 ip=192.168.0.3
ingress-1.root.local.io ansible_host=192.168.0.6 ip=192.168.0.6
node-1.root.local.io ansible_host=192.168.0.4 ip=192.168.0.4
node-2.root.local.io ansible_host=192.168.0.5 ip=192.168.0.5

[kube-master]

master-1.root.local.io

[etcd]

master-1.root.local.io

[kube-node]

node-1.root.local.io node-2.root.local.io ingress-1.root.local.io

[kube-ingress-1]

ingress-1.root.local.io

[k8s-cluster:children]

kube-node kube-master

Наш кластер состоит из 4 узлов:

  • один master с компонентами Control Plane;
  • один Ingress для маршрутизации трафика;
  • два Workers, на которых будут запускаться сервисы.

Control Plane (API server, etcd, Sheduler, Controle manager) собран на одной ноде. Это очень нехорошо: обычно в секции [kube-master] больше одного узла, а в секции [etcd] – более трех. Это связано с тем, что quorum собирается не меньше чем на 3 узлах при нечетным общем количестве узлов в etcd. Поскольку речь идет об учебной площадке, наш вариант тоже имеет право на существование.

Отредактируем k8s-cluster/k8s-cluster.yml. Нужно поменять network plugin на flannel и имя нашего кластера на root.local:

        kube_network_plugin: flannel
cluster_name: root.local

    

Теперь поправим k8s-cluster/k8s-net-flannel.yml. Тут обычный regexp на сеть провайдера VPS (в нашем случае это 192.168.0.0/24, но у вас подсеть может отличаться).

Исправляем:

        flannel_interface_regexp: '192\.168\.0\.\d{1,9}'
    

Сборка кластера

Поскольку inventory у нас уже подготовлен, остается только запустить playbook на исполнение и минут 15 – 20 подождать, пока соберется кластер. Если у вас отвалится соединение SSH, и сборка прервется, ее можно будет запустить повторно – это не вызовет ошибок:

        ansible-playbook -u root -i inventory/inventory.ini cluster.yml -b --diff
    

Кластер собран. Проверяем:

        [root@master-1 kubespray] kubectl get nodes
NAME                      STATUS   ROLES    AGE    
ingress-1.root.local.io   Ready    <none>   2d1h   
master-1.root.local.io    Ready    master   2d1h   
node-1.root.local.io      Ready    <none>   2d1h   
node-2.root.local.io      Ready    <none>   2d1h

    

Последний штрих – добавляем роль нашей ноде с ingress:

        [root@master-1 kubespray] kubectl label node ingress-1.root.local.io node-role.kubernetes.io/ingress=
    

Если повторно посмотреть на ingress, роль должна появиться:

        root@master-1 kubespray] kubectl get nodes
NAME                      STATUS   ROLES     AGE    
ingress-1.root.local.io   Ready    ingress   2d1h   
master-1.root.local.io    Ready    master    2d1h   
node-1.root.local.io      Ready    <none>    2d1h   
node-2.root.local.io      Ready    <none>    2d1h  

    

***

Поздравляем! Вы практически вручную развернули кластер k8s, и теперь можно запустить в нем простенькое приложение. Это только начало большого пути в современное системное администрирование (или даже в DevOps). Более сложные шаги мы сделаем с вами вместе в следующих статьях. Удачи в обучении!