Если токены будут забыты, их можно получить, выполнив в ноде с распределённым хранилищем команды docker swarm join-token manager и docker swarm join-token worker.
Для создания кластера необходимо зарегистрировать (присоединить) все его будущие ноды командой Docker swarm join token 192.168.99.100:2377, для аутентификации используется токен, для их обнаружения необходимо, чтобы они находились в одной подсети. Посмотреть все сервера можно командой docker node info
Команда docker swarm init создаст лидера кластера, пока одинокого, но в полученном ответе будет на неё будет придана команда, необходимая для подключение других нод к этому кластеру, важная информация в котором токен, например, docker swarm join token 192.168.99.100:2377. Подключимся к оставшимся нодам по SSH командой docker-machine SSH name_node и выполним её.
Для взаимодействия контейнеров используется сеть bridge, которая является свитчем. Но для работы нескольких реплик нужна подсеть, так как все реплики будут с одинаковыми портами, а проксирование производится по ip с помощью распределённого хранилища, при этом не имеет значение физически они расположены на одном сервере или разных. Следует сразу заметить, что балансировка осуществляется по правилу roundrobin, то есть поочерёдно к каждой реплике. Важно создать сеть типа overlay для создания DNS по верх неё и возможности обращаться к репликам по им именам. Создадим подсеть:
docker network create driver overlay subnet 10.10.1.0/24 opt encrypted services
Теперь нам нужно наполнить на кластер контейнерами. Для этого создаём не контейнер, а сервис, который является шаблоном для создания контейнеров на разных нодах. Количество создаваемых реплик указывается при создании в ключе replicas, причём распределение случайное по нодам, но по возможности равномерное. Помимо реплик, сервис имеет балансировщик нагрузки, порты с которого на которые (входные порты для всех реплик) производится проксирование указывается в ключе -p, а Server Discovery (обнаружение работающих реплик, определение их ip-адресов, перезапуск) реплик балансировщик осуществляет самостоятельно.
docker service create -p 80:80 name busybox replicas 2 network services busybox sleep 3000
Проверим состояние сервиса docker service ls, состояние и равномерность распределения реплик контейнеров docker service ps busybox и его работу wget -O- 10.10.1.2. Сервис более высокоуровневая абстракция, которая включает в себя контейнер и организующее его обновление (далеко не только), то есть для обновления параметров контейнера не нужно его удалять и создавать, а просто обновить сервис, а уже сервис сперва создаст новый с обновлённой конфигурацией, а только после того, как он запустится удалит старый.
Docker Swarm имеет свой балансировщик нагрузки Ingress load balacing, который балансирует нагрузку между репликами на порту, объявленном при создании сервиса, в нашем случае это 80 порт. Входной точкой может быть любой сервер с этим портом, но ответ будет получен от сервера, на который был перенаправлен запрос балансировщиком.
Мы также можем сохранять данные на хостовую машину, как и в обычном контейнере, для этого есть два варианта:
docker service create mount type=bind, src=, dst=.... name=.... ..... #
docker service create mount type=volume, src=, dst=.... name=.... ..... # на хост
Развёртывание приложения производится через Docker-compose, запущенного на нодах (репликах). При обновлении конфигурации Docker-compose нужно обновить Docker stack, и кластер будет последовательно обновлён: одна реплика будет удалена и в место неё будет создана новая в соответствии с новым конфигом, далее следующая. Если произошла ошибка буде произведён откат к предыдущей конфигурации. Что ж, приступим:
docker stack deploy -c docker-compose.yml test_stack
docker service update label-add foo=bar Nginx docker service update label-rm foo Nginx docker service update publish-rm 80 Nginx docker node update availability=drain swarm-node-3 swarm-node-3
Docker Swarm
$ sudo docker pull swarm
$ sudo docker run rm swarm create
docker secrete create test_secret docker service create secret test_secret cat /run/secrets/test_secret проверка работоспособности: hello-check-cobbalt пример pipeline: trevisCI > Jenkins > config -> https://www.youtube.com/watch?v=UgUuF_qZmWc https://www.youtube.com/watch?v=6uVgR9WPjYM
Docker в масштабах компании
Давайте посмотрим в масштабах компании: у нас есть контейнера и есть сервера. Не важно, это две виртуалки и несколько контейнеров или это сотни серверов и тысячи контейнеров, проблема в том, чтобы распределить контейнера на серверах нужен системный администратор и время, если мало времени и много контейнеров, нужно много системных администраторов, иначе они будут неоптимальное распределены, то есть сервер (виртуальная машина) работает, но не в полную силу и ресурсы продают. В этой ситуации для оптимизации распределения и экономии человеческих ресурсов предназначены системы оркестрации контейнеров.
Рассмотрим эволюцию:
* Разработчик создаёт необходимые контейнера руками.
* Разработчик создаёт необходимые контейнера используя для этого заранее подготовленные скрипты.
* Системный администратор, с помощью какой-либо системы управления конфигурации и развёртывания, таких как Chef, Pupel, Ansible, Salt, задаёт топологию системы. В топологии указывается какой контейнер на каком месте располагается.
* Оркестрация (планировщики) полуавтоматическое распределение, поддержание состояния и реакция на изменение системы. Например: Google Kubernetes, Apache Mesos, Hashicorp Nomad, Docker Swarm mode и YARN, который мы рассмотрим. Также появляются новые: Flocker (https://github.com/ClusterHQ/Flocker/), Helios (https://github.com/spotify/helios/).
Существует нативное решение Docker-swarm. Из взрослых систем наибольшую популярность показали Kubernetes (Kubernetes) и Mesos, при этом первый представляет из себя универсальную и полностью готовую к работе систему, а второй комплекс разнообразных проектов, объединённых в единый пакет и позволяющие заменить или изменять свои компоненты. Существует также огромное количество менее популярных решений, не продвигаемы такими гигантами, как Google, Twitter и другими: Nomad, Scheduling, Scalling, Upgrades, Service Descovery, но мы их рассматривать не будем. Здесь мы будем рассматривать наиболее готовое решение Kubernetes, которое завоевало большую популярность за низкий порог вхождения, поддержки и достаточную гибкость в большинстве случае, вытеснив Mesos в нишу кастомизируемых решений, когда кастомизация и разработка экономически оправдана.
У Kubernetes есть несколько готовых конфигураций:
* MiniKube кластер из одной локальной машины, предназначен для преодоления порога вхождения и экспериментов;
* kubeadm;
* kops;
* Kubernetes-Ansible;
* microKubernetes;
* OKD;
* MicroK8s.
Для самостоятельного запуска кластера можно воспользоваться
KubeSai бесплатный Kubernetes
Наименьшая структурная единица называется POD, которая соответствует YML-файлу в Docker-compose. Процесс создания POD, как и других сущностей производится декларативно: через написание или изменение конфигурационного YML-файла и применение его к кластеру. И так, создадим POD:
# test_pod.yml
# kybectl create -f test_pod.yaml
containers:
name: test
image: debian
Для запуска нескольких реплик:
# test_replica_controller.yml
# kybectl create -f test_replica_controller.yml
apiVersion: v1
kind: ReplicationController
metadata:
name: Nginx
spec:
replicas: 3
selector:
app: Nginx // метка, по которой реплика определяет наличие запущенных контейнеров
template:
containers:
name: test
image: debian
Для балансировки используется разновидность service (логическая сущность) LoadBalancer, кроме которого существует ещё ClasterIP и Node Port:
appVersion: v1
kind: Service
metadata:
name: test_service
apec:
type: LoadBalanser
ports:
port: 80
targetPort: 80
protocol: TCP
name: http
selector:
app: WEB
Плагины overlay сети (создаётся и настраивается автоматически): Contig, Flannel, GCE networking, Linux bridging, Calico, Kube-DNS, SkyDNS. #configmap apiVersion: v1 kind: ConfigMap metadata: name: config_name data:
Аналогично секретам в Docker-swarm существует секрет и для Kubernetes, примером которых могут быть настройки NGINX :
#secrets
apiVersion: v1
kind: Secrets
metadata:name: test_secret
data:
password: ....
А для добавления секрета в POD, нужно его указать в конфиге POD:
....
valumes:
secret:
secretName: test_secret
У Kubernetes больше разновидностей Volumes:
* emptyDir;
* hostPatch;
* gcePersistentDisc диск на Google Cloud;
* awsElasticBlockStore диск на Amazon AWS.
volumeMounts:
name: app
nountPath: ""
volumes:
name: app
hostPatch:
....
Особенностью буде UI: Dashbord UI
Дополнительно имеется:
* Main metrics сбор метрик;
* Logs collect сбор логов;
* Scheduled JOBs;
* Autentification;
* Federation распределение по дата-центрам;
* Helm пакетный менеджер, аналог Docker Hub.
https://www.youtube.com/watch?v=FvlwBWvI-Zg
Команды Docker
Docker более современный аналог контейнеров RKT.
В Linux, когда завершается процесс с PID=1, то зарывается и NameSpace, что приводит к завершению работы ОС, в случае контейнера, аналогично, так как он является частным случаем ОС. Разграничение процессов сам по себе не даёт дополнительного оверхед, также как и мониторинг и ограничение ресурсов на процессы, ибо такие же возможности по настройки предоставляет systemd в хостовой ОС. Виртуализация сети происходит полностью: и localhost и мост, что позволяет создать мосты от нескольких контейнеров к одному localhost и тем самым сделать его единым для них, что активно используется в POD Kubernetes.
Запуск временного контейнера в интерактивном режиме -it. Для входа нужно нажать Ctrl+D, которое отравит сигнал на завершение работы, после чего он будет удалён rm во избежание засорения системы остановленными современными контейнерами. Если образ создан таким образом, что в контейнере приложение запускается в оболочке, что неправильно, то сигнал буде отравлен приложению, а контейнер продолжит работать с оболочкой, в таком случае для выхода в отдельном терминале нужно будет его убить по его имени name name_container. Например,: