С появлением Docker интерес к контейнерам вырос взрывообразно: разворачивать приложения оказалось настолько удобно, что технологию начали использовать буквально везде. Облачные сервисы уже дают быстрый доступ к большому количеству виртуальных машин, которыми нужно управлять. Поэтому без инструмента, позволяющего запускать контейнеры на множестве хостов, масштабировать и выполнять балансировку, уже не обойтись. Разберемся с решением, предложенным Google.

 

Проект Kubernetes

Проект Kubernetes, или K8S, стартовал в Google в 2014 году, первая публичная версия 0.1 была представлена сообществу практически через год — в июле 2015-го. Нужно, наверное, особо отметить, что разработка не начиналась с нуля. В основе K8S лежит суперсекретный (в буквальном смысле этого слова) проект Гугла Borg — фактически основа основ управления кластерами в этой корпорации, проект, наработками которого до этого гигант не особо хотел делиться. Многие из разработчиков Borg перешли в Kubernetes, а вместе с ними туда перекочевали все идеи и решения проблем — перенос контейнеров без потерь данных, балансировка нагрузки, обнаружение сервисов. То есть можно сказать, что K8S — точная копия того, что в Google создавали долгое время, но адаптированная и ориентированная к применению Docker. Сразу после анонса проекта совместно с Linux Foundation была сформирована Cloud Computing Native Foundation (CNCF), в которую вошли сама Google, Cisco, IBM, Docker и VMware. Задача CNCF — выработать единый стандарт и обеспечить взаимодействие между разработчиками.

В Kubernetes реализованы все функции, необходимые для запуска приложений на основе Docker в конфигурации с высокой доступностью (кластеры более 1000 узлов, с multi-availability и multi-region зонами): управление кластером, планирование, обнаружение сервисов, мониторинг, управление учетными данными и многое другое. Выглядит это пугающе, но вся внутренняя кухня скрыта от админа. Он просто размещает контейнеры, все остальное — забота K8S. Для реализации этого используется больше десятка сторонних взаимодействующих услуг, которые вместе обеспечивают требуемую функциональность. Например, за координацию и хранение настроек отвечает etcd, создание сетей между контейнерами — flannel. Это несколько усложняет первоначальную настройку (хотя в последних релизах это уже не так заметно), но позволяет при необходимости просто заменить любой компонент. Для состыковки служб используются разные CLI, API, которые уже совместно реализуют API более высокого уровня для сервисных функций, таких как планирование ресурсов. Нужная функциональность должна быть специально адаптирована для K8S. Например, обратиться напрямую к API Docker нельзя (точнее, можно, но очень и очень нежелательно), следует использовать Docker Compose.

Kubernetes представляет собой систему с несколькими концепциями. Многие из этих понятий проявляются как «объекты» или «ресурсы» RESTful API. Кроме общепринятых, таких как Node, Cluster и Replication controller, есть и весьма специфические.

  • Pods — единица планирования в Kubernetes. Группа или ресурс, в котором могут работать несколько контейнеров. Контейнеры из одного Pod будут запускаться на одном сервере и могут совместно использовать общие разделы. Объекты Pod описаны в так называемых PodSpec — YAML/JSON-файлах.
  • Services — набор контейнеров, которые работают вместе, обеспечивая, например, функционирование многоуровневого приложения. K8S поддерживает динамическое наименование и балансировку нагрузки Pods с помощью абстракций, гарантируя прозрачное подключение к Services по имени и отслеживая их текущее состояние.
  • Labels — пары ключ/значение, которые прикрепляются к Pod и фактически к любому объекту (сервису), позволяя их легко группировать, отбирать и назначать задания.
  • IP-per-Pod — в Borg сервисы использовали один IP и для распределения сетевых ресурсов применялись порты. Это накладывало ряд ограничений. В K8S возможно назначить каждому Pod отдельный адрес.
  • Namespaces — способ, позволяющий логически разделить единый кластер K8S на несколько виртуальных, каждый из них будет существовать в изолированном пространстве, ограниченном квотами, не влияя на других.

На всех узлах кластера minion устанавливаются агенты kubelet и kube-proxy (прокси-балансировщик). Агенты принимают из специального API сервера данные PodSpec (файл или HTTP) и гарантируют работоспособность указанных в нем объектов. Прокси обеспечивает перенаправление потоков между Pod. Мастер кластера содержит специальные компоненты — kube-controller-manager (менеджер сервисов) и kube-scheduler (планировщик), kube-apiserver, etcd и flannel. Доступ к API управления, кроме программного способа, можно получить через консольную утилиту kubectl и веб-интерфейс. С их помощью можно просматривать текущую конфигурацию, управлять ресурсами, создавать и разворачивать контейнеры.

 

Установка Kubernetes

Установка Kubernetes выполняется скриптом, и в процессе следует ориентироваться на официальную инструкцию, адаптировав ее к своему дистрибутиву. Она несложная, просто нужно быть очень внимательным. Мануалы из Сети работают не всегда, так как в разных версиях дистрибутива часто требуются различные действия и встречаются специфические проблемы, также разработчики по мере развития K8S меняют процесс развертывания и параметры в конфигурационных файлах. Установим в простейшем варианте K8S на одну систему master/minion в Ubuntu 14.04/16.04, так что нам не потребуются некоторые компоненты вроде сервера ключей. Перед установкой нужно составить список всех узлов и их сетевые параметры и роль. Проект предлагает исходные тексты и bash-скрипт.

Скрипт установки Kubernetes
Скрипт установки Kubernetes

Первый вариант дает чуть больше контроля, если что-то пойдет не так. Ставим приложения:

$ sudo apt install docker.io curl git bridge-utils

Для беспарольного входа генерируем ключ. Так как впоследствии понадобятся права root, то ключи генерируем для него. Все параметры оставляем по умолчанию, на запрос пароля жмем Enter.

$ sudo ssh-keygen -t rsa
$ sudo ssh-copy-id -i /home/user/.ssh/id_rsa.pub 127.0.0.1

Подтверждаем операцию и вводим свой пароль.

$ sudo cat /home/root/.ssh/id_rsa.pub >> /home/root/.ssh/authorized_keys

После этого пробуем войти. Должно пустить без запроса пароля:

$ sudo ssh root@127.0.0.1

Если серверов несколько, поступаем аналогично и копируем на них ключи. Несмотря на простоту, это очень важный момент. Малейшая ошибка — и дальнейшие действия ни к чему не приведут. Забираем актуальный релиз (файл большой, почти 1,5 Гбайт):

$ wget -c https://github.com/kubernetes/kubernetes/releases/download/v1.3.5/kubernetes.tar.gz

Или ветку master:

$ wget -c https://github.com/kubernetes/kubernetes/archive/master.zip

Распаковываем:

$ tar -xvf kubernetes.tar.gz

Архив содержит примеры и готовые настройки в kubernetes/cluster для самых разных конфигураций. Следует выбрать свою и запустить установочный скрипт. Так как ставим на Ubuntu, то выбираем этот вариант. Для начала нам нужно указать конфигурацию сети. Смотрим вывод ifconfig — настройку физического интерфейса и docker0 — и приступаем к настройке.

# nano kubernetes/cluster/ubuntu/config-default.sh
# Прописываем ноды, она у нас пока одна, остальные при необходимости добавляем через пробел
export nodes=${nodes:-"root@127.0.0.1"}
# Роль a(master), i(minion), ai(master+minion)
export roles="ai"
# Количество minion
export NUM_MINIONS=${NUM_MINIONS:-1}
# Диапазон IP кластера, приватная сеть rfc1918
export SERVICE_CLUSTER_IP_RANGE=${SERVICE_CLUSTER_IP_RANGE:-192.168.1.0/24}
# Диапазон IP flannel сети Docker
export FLANNEL_NET=${FLANNEL_NET:-172.17.42.0/16}
DNS_SERVER_IP=${DNS_SERVER_IP:-"192.168.1.1"}
DNS_DOMAIN=${DNS_DOMAIN:-"cluster.local"}
ENABLE_CLUSTER_UI="${KUBE_ENABLE_CLUSTER_UI:-true}"
Конфигурационный файл config-default.sh
Конфигурационный файл config-default.sh

Это основные настройки, позволяющие запустить K8S. В файле также настраиваются параметры Docker и остальных компонентов, журналирование, мониторинг. Если к интернету подключение происходит через прокси, то его параметры следует прописать в PROXY_SETTING.

PROXY_SETTING="http_proxy=http://server:port https_proxy=https://server:port"

Теперь можно развернуть кластер.

$ cd kubernetes/cluster
$ KUBERNETES_PROVIDER=ubuntu ./kube-up.sh
Starting cluster using provider: ubuntu

Скрипт закачает и установит все необходимые компоненты (etcd), на все прописанные в конфиге ноды. В процессе потребуется указать пароль для управления узлом. По окончании получим сообщение Cluster validation succeeded. Причем скрипт повторно будет скачивать последний релиз K8S — чтобы не повторять это дважды, просто скопируй файл kubernetes.tar.gz в каталог kubernetes/cluster/ubuntu и подправь скрипт закачки download-release.sh.

Еще одна проблема, которую не могут устранить уже пару месяцев, — это ошибка при создании кластера:

saltbase/salt/generate-cert/make-ca-cert.sh: No such file or directory

Нужный файл расположен в каталоге kubernetes/server, его просто забыли положить на место. Это можно сделать вручную или добавить в cluster/ubuntu/download-release.sh две строки распаковки kubernetes-salt.

tar xzf kubernetes-server-linux-amd64.tar.gz
tar xzf kubernetes-salt.tar.gz
....
cp kubernetes/server/kubernetes/server/bin/kubectl binaries/
cp -a kubernetes/server/kubernetes/saltbase ../

После чего master будет слушать на порту http://127.0.0.1:8080. Остановить кластер можно также одной командой:

$ KUBERNETES_PROVIDER=ubuntu ./kube-down.sh
Устанавливаем Kubernetes
Устанавливаем Kubernetes
 

Управляем кластером

Для управления K8S используется утилита kubectl. Настройки можно указывать прямо в командной строке или использовать заранее подготовленный YAML/JSON-файл. Чтобы было проще вводить команды, укажем в переменной PATH, где ее искать.

$ export PATH=$PATH:~/kubernetes/cluster/ubuntu/binaries

Для удобства лучше строку прописать сразу в ~/.bash_profile. Два подкаталога — master и minion в ubuntu/binaries — содержат утилиты для настройки мастера и подчиненных узлов. Все операции реализуются указанием одного из 20 ключей, список которых можем получить, введя

$ kubectl --help
Параметры kubectl
Параметры kubectl

Смотрим список нод, настройки и данные кластера.

$ kubectl get nodes
$ kubectl cluster-info
$ kubectl config

В ответ должны получить список указанных ранее в config-default.sh узлов. Запустим контейнер с nginx:

$ kubectl run nginxtest --image=nginx --port=80 --hostport=81

K8S сам загрузит и установит образ. Через время к nginx можно обратиться, подключившись на 81-й порт. Если нод несколько и нам нужна балансировка, может указываться параметр --create-external-load-balancer и указывается количество реплик --replicas=№. Текущее состояние репликации выводится командой kubectl get rc.

Возможно заранее прописать настройки контейнера в файле, который затем использовать при развертывании командой create:

$ kubectl create -f nginx.yaml

Если файлов много, то просто указывается каталог, в котором они находятся. Далее создаем сервис:

$ kubectl expose rc nginx --port=80 --target-port=80 --service-name=nginx -s "http://192.168.1.2:8080"

Теперь можем проверить доступные сервисы и POD.

$ kubectl get pods

В ответ получим имя (по которому можем обращаться к POD), состояние и возраст.

$ kubectl get services
Получение информации при помощи kubectl
Получение информации при помощи kubectl

Если нужно выполнить команду внутри контейнера, то используем kubectl exec. Kubectl позволяет обращаться к некоторым ресурсам сразу по имени. В настоящее время доступно 19 типов ресурсов, все они описаны в документации к kubectl. Когда информации много, можно форматировать вывод при помощи -o, отбирая произвольные колонки, или вывести в JSON/YAML-формате для дальнейшей обработки. Например, выведем в расширенном формате список нод и сервисов:

$ kubectl get rc,services -o=wide

Веб-интерфейс доступен по адресу https://<K8S-host>/ui, пароль для входа можно посмотреть в выводе kubectl config view. Если он не работает, следует установить его последнюю стабильную версию.

$ kubectl create -f https://rawgit.com/kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml
Веб-интерфейс Kubernetes
Веб-интерфейс Kubernetes

Не Kubernetes единым

Параллельно с Kubernetes несколько компаний предложило свои решения, которые внешне похожи, но существенно различаются по реализации. Это Docker Swarm от разработчиков Docker, Nomad, Mesos/Marathon и Fleet.

Docker Swarm позволяет очень просто объединить Docker-хосты в один виртуальный хост, который внешне выглядит как обычный. Очень прост в развертывании, фактически нужно запустить еще один контейнер и присоединить к остальным. Для управления используется REST API интерфейс, совместимый с Docker API. В итоге абсолютно все инструменты, совместимые с API Docker, — Dokku, Compose, DockerUI и многие другие — могут работать с кластером Docker Swarm, как с обычным хостом. Это огромный плюс Docker Swarm, но, если API не поддерживает какую-то возможность, простого решения проблемы не будет.

Разработкой Nomad занимается HashiCorp — компания, специализирующаяся на инструментах управления кластерами, виртуальными машинами и облачными сервисами. В итоге получился универсальный многофункциональный инструмент, который может быть использован для более широкого круга задач. Он сочетает в себе легкий менеджер ресурсов и сложный планировщик, определяющий, на каком узле развернуть указанные ресурсы. Архитектурно проще Kubernetes, его легко разворачивать и настраивать. Поддерживает несколько ЦОД и multi-region конфигурации. Тестировался на кластерах до 5000 узлов, хотя вполне способен работать на гораздо более крупных кластерах. Серверная и клиентская часть реализованы в одном бинарнике, для координации или хранения не требуется других внешних служб. Может использоваться Consul для обнаружения сервисов и Vault для организации единого доступа. Все разработки HashiCorp.

Marathon представляет собой надстройку над менеджером кластера Apache Mesos, расширяя его возможности управлять контейнерами в нескольких ЦОД. Изначально разработан и применяется в Twitter. Использует другие решения Apache Software Foundation для организации, обнаружения приложений, планирования и прочего — ZooKeeper, Chronos, Kafka, Hadoop и другие. Поддерживается формат контейнера Docker и свой Mesos, но в принципе можно просто добавить другую технологию. Самостоятельная установка не самое простое дело, поэтому удобный способ развертывания — Mesosphere Enterprise DC/OS (CentOS + репозиторий). Кстати, уже есть наработки по интеграции API планировщика Kubernetes с Mesos — Kubernetes-Mesos.

Fleet — распределенная система инициализации на основе Systemd и etcd, которые разработчики представляют как Systemd уровня кластера. Нет некоторых важных функций — балансировки нагрузки, интеграции DNS, ACL и других. Их реализация пока под вопросом.

 

Вывод

Вывод короткий: несомненно, Kubernetes — интересный проект, который поможет справиться с увеличивающимся количеством контейнеров Docker и снимет с сисадмина часть проблем.

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    2 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии