Полная версия
Из разработчика в архитекторы. Практический путь
Мы также можем сохранять данные на хостовую машину, как и в обычном контейнере, для этого есть два варианта:
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, при этом первый представляет из себя универсальную и полностью готовую к работе систему, а второй – комплекс разнообразных проектов, объединённых в единый пакет и позволяющие заменить или изменять свои компоненты. Cуществует, также, огромное количество менее популярных решений, не продвигаемы такими гигантами, как Google, Twitter и другими: Nomad, Scheduling, Scalling, Upgrades, Service Descovery, но мы их рассматривать не будем. Здесь мы будем рассматривать наиболее готовое решение – Kuberntes, которое завоевало большую популярность за низкий порог вхождения, поддержки и достаточную гибкость в большинстве случае, вытеснив Mesos в нишу кастомизуруемых решений, когда кастомизация и разработка экономически оправдана.
У Kubernetes есть несколько готовых конфигураций:
* MiniKube – кластер из одной локальной машины, предназначен для преодоления порога вхождения и экспериментов
* kubeadm
* kops
* kubernetes-ansible
* microKubernetes
Мониторинг – Heapster
Наименьшая структурная единица называется 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 сети (создаётся и настраивается автоматически): Contiv, Flannel, GCE networking, Linux bridging, Callico, 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:….
А для добавления секрета в под, нужно его указать в конфиге пода:
….
valumes:
secret:
secretName: test_secret
…
У Kubernetes больше разновидностей Valumes:
* 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
* Rocket или rkt – контейнеры для операционной среды CoreOS от RedHut, специально созданной на использование
контейнеров.
* Hyper-V – среда для запуска Docker в операционной системе Windows, представляющая из себя обертку (легковесную
виртуальную машину) контейнера.
От Docker ответвились его базовые компоненты, которые используются им как примитивы, ставшие стандартными компонентами для реализации контейнеров, таких как RKT, объединенных в проект containerd:
* CRI-O – OpanSource проект, с самого начала нацеленный на полную поддержку стандартов CRI (Container Runtime
Interface), github.com/opencontainers/runtime-spec/">Runtime Specification и github.com/opencontainers/image-spec">Image Specification как общего интерфейса
взаимодействия системы оркестровки с контейнерами. Наряду c Docker, добавлена поддержка CRI-O 1.0 в Kubernetes
(речь пойдёт дальше) с версии 1.7 в 2007, а также в MiniKube и Kubic. Имеет реализацию CLI (Common Line
Interface) в проекте Pandom, практически полностью повторяющий команды Docker, но без оркестровки (Docker
Swarm), который по умолчанию является инструментом в Linux Fedora.
* CRI (kubernetes.io/blog/2016/12/container-runtime-interface-cri-in-kubernetes/">Container
Runtime Interface) – среда для запуска контейнеров, универсально предоставляющие примитивы (Executor,
Supervisor, Metadata, Content, Snapshot, Events и Metrics) для работы с Linux контейнерами (пространствами
процессов, групп и т. д.).
* CNI (Container Networking Interface) – работа с сетью
Portainer
Простейшим вариантом мониторинга будет Portainer:
essh@kubernetes-master:~/microKubernetes$ cat << EOF > docker-compose.monitoring.yml
version: 2
>
services:
portainer:
image: portainer/portainer
command: – H unix:///var/run/docker.sock
restart: always
ports:
– 9000:9000
volumes:
– /var/run/docker.sock:/var/run/docker.sock
–./portainer_data:/data
>
EOF
essh@kubernetes-master:~/microKubernetes$ docker-compose – f docker-compose.monitoring.yml up – d
Облачные системы, как источник непрерывного масштабирования: Google Cloud и Amason AWS
Кроме хостинга и аренды сервера, в частности виртуального VPS, можно воспользоваться облачными решениями (SAS, Service As Software) решениями, то есть осуществлять работу нашего Web приложения (ий) только через панель управления используя готовую инфраструктуру. Этот подход имеет как плюсы, так и минусы, которые зависит от бизнеса заказчика. Если с технической стороны сам сервер удалён, но мы можем к нему подключиться, и как бонус получаем панель администрирования, то для разработчика различия более существенны. Разделим проекты на три группы по месту развёртывания: на хостинге, в своём дата центре или использующие VPS и в облаке. Компании использующие хостинг в силу существенных ограничений налагаемых на разработку – невозможность установить своё программное обеспечение и нестабильность и размер предоставляемой мощности – в основном специализируются на заказной (потоковой) разработке сайтов и магазинов, которая в силу малых требований к квалификации разработчиков и нетребовательности к знаниям инфраструктуры рынок готов оплачивать их труд по минимум. Ко второй группе относятся компании реализующие состоявшиеся проекты, но разработчики отстранены от работы с инфраструктурой наличием системных администраторов, build инженеров, DevOps и других специалистов по инфраструктуре. Компании, выбирающие облачные решения, в основном оправдывают переплату за готовую инфраструктуру и мощности их расширяемостью (актуально для стартапов, когда рост нагрузки не предсказуем). Для реализации подобных проектов в основном берут высококвалифицированных специалистов широкого круга для реализации нестандартных решений, где инфраструктура уже является просто инструментом, а специалисты по ней просто отсутствуют. На разработчиков возлагаются функции по проектированию проекта в целом, как единого целого, а не программы в отрыве от инфраструктуры. В основном это зарубежные компании, готовые хорошо оплачивать труд ценных сотрудников.
Для развёртывания будем использовать Kubernetes для противодействия vender lock, когда инфраструктура проекта завязана на api конкретного облачного провайдера и не позволят перейти на другие или собственные облака без существенных изменений в самом приложении. Kubernetes поддерживается Amazon AWS, Google Cloud, Microsorft Azure, локальной установкой одного иснтанца с помощью MiniKube.
Воспользуемся Google Cloud, на текущий 2018 год он предоставляет бесплатное использование на один год ограниченных ресурсов (300 долларов США), при этом существуют лимиты, которые можно посмотреть в меню IAM и администрирование —> Квоты. Важно заметить, облачные провайдеры не предоставляют тарифов в современном диапазоне, а предоставляют тарифы на использовании определённых мощностей, то есть сайт мало посещаем – платим мало, сложно обрабатываем много данных – платим много. По этой причине, когда потребности в вычислительных мощностях у компании предсказуемы (не стартап) может быть целесообразно использовать собственные возможности для постоянной нагрузки, что может быть экономически целесообразно, не рискую ограниченностью вычислительными мощностями.
И так заходим на cloud.google.com регистрируется, привязываем дебетовую карту с минимальным балансом и переходим в консоль console.cloud.google.com, в котором можно пройти обучение по интерфейсу для общего ознакомления. В меню нажимаем пункт Оплата: у меня нетронутые демо-деньги 300 долларов США и осталось 356 дней (средства списываются не в режиме реального времени).
Если смотреть на как основу для Back-End для мобильной разработки (MBasS, Mobile backend as a service), то его предоставляют разные провайдеры: Google Firebase, AWS Mobile, Azure Mobile
Google App Engine
Создание кластера через Web-интерфейс
Предварительно проверим ограничения (квоты) Меню —> Продукты —> IAM и администрирование —> Квоты, а если вы находитесь на тестовом аккаунте, то Static IP addresses будет равен 1, то не сможет создаться балансировщик и придётся удалять кластер. Создадим кластер в Меню – Ресурсы – Kubernetes Engine в тремя репликами микромашины и последней версией Kubernetes. В левом нижнем углу в пункте Marketplace создадим 2 инстанса Nginx. После создания кластера кликнем по вкладке Сервисы и перейдём по IP-адресу.
MarketPlace: Сеть, Бесплатные, Приложения Kubernetes: Nginx Создадим кастомный кластер standard-cluster-Nginx, выбрав минимум CPU и RAM, 2 ноды вместо 3 и последнюю вер сию Kubernetes (я выбрал 1.11.3, а мой код будет совместим с – не ниже 1.10). В Меню – Ресурсы – Kubernetes Engine во кладке Кластера нажмём кнопку Подключиться. Управлением кластером в командной строке осуществляется с помощью команды cubectl, о ней можно почитать в документации https://kubernetes.io/docs/reference/kubectl/overview/ и список по https://gist.github.com/ipedrazas/95391ffd88190bea94ca188d3d2c1cbe.
Создание виртуальной машины:
Можно создать программный проект, но пользоваться им можно будет только на платном аккаунте:
NAME_PROJECT=bitrix_12345;
NAME_CLUSTER=bitrix;
gcloud projects create $NAME_CLUSTER – name $NAME_CLUSTER;
gcloud config set project $NAME_CLUSTER;
gcloud projects list;
Несколько тонкостей: ключ – zone обязателен и ставится в конце, диска не должен быть меньше 10Gb, а тип машин можно взять из https://cloud.google.com/compute/docs/machine-types. Если реплика у нас одна, то по умолчанию создаётся минимальная конфигурация для тестирования:
gcloud container clusters create $NAME_CLUSTER – zone europe-north1-a
Вы можете увидеть в админке, развернув выпадающий список в шапке, и открыв вкладку Все проекты.
gcloud projects delete NAME_PROJECT;
, если больше – стандартная, параметры которой мы подредактируем:
$ gcloud container clusters create mycluster \
– machine-type=n1-standard-1 —disk-size=10GB – image-type ubuntu \
– scopes compute-rw,gke-default \
– machine-type=custom-1-1024 \
– cluster-version=1.11 —enable-autoupgrade \
– num-nodes=1 —enable-autoscaling – min-nodes=1 —max-nodes=2 \
– zone europe-north1-a
Ключ – enable-autorepair запускаем работу мониторинга доступности ноды и в случае её падения – она будет пересоздана. Ключ требует версию Kubernetes не менее 1.11, а на момент написания книги версия по умолчанию 1.10 и по этому нужно её задать ключом, например, – cluster-version=1.11.4-gke.12. Но можно зафиксировать только мажорную версия – cluster-version=1.11 и установить автообновление версии – enable-autoupgrade. Также зададим авто уверение количества нод, если ресурсов не хватает: —num-nodes=1 —min-nodes=1 —max-nodes=2 —enable-autoscaling.
Теперь поговорим об виртуальный ядрах и оперативной памяти. По умолчанию поднимается машина n1-standart-1, имеющая одно виртуальное ядро и 3.5Gb оперативной памяти, в трёх экземплярах, что совокупно даёт три виртуальных ядра и 10.5Gb оперативной памяти. Важно, чтобы в кластере было всего не менее двух виртуальных ядер процессора, иначе их, формально по лимитам на системные контейнера Kubernetes, не хватит для полноценной работы (могут не подняться контейнера, например, системные). Я возьму две ноды по одному ядру и общее количество ядер будет два. Такая же ситуация и с оперативной памятью, для поднятия контейнера с Nginx мне вполне хватало 1Gb (1024Mb) оперативной памяти, а вот для поднятия контейнера с LAMP (Apache MySQL PHP) уже нет, у меня не поднялся системный сервис kube-dns-548976df6c-mlljx, который отвечает за DNS в поде. Не смотря не то, что он не является жизненно важным и нам не пригодится, в следующий раз может не подняться уж более важный вместо него. При этом важно заметить, что у меня нормально поднимался кластер с 1Gb и было всё нормально, я общий объём в 2Gb оказался пограничным значением. Я задал 1080Mb (1.25Gb), учтя, что минимальная планка оперативной памяти составляет 256Mb (0.25Gb) и мой объём должен быть кратен ей и быть не меньше, для одно ядра, 1Gb. В результате в кластера 2 ядра и 2.5Gb вместо 3 ядре и 10.5Gb, что является существенной оптимизацией ресурсов и цены на платном аккаунте.
Теперь нам нужно подключиться к серверу. Ключ у нас уже есть на сервере ${HOME}/.kube/config и теперь нам нужно просто авторизоваться:
$ gcloud container clusters get-credentials b – zone europe-north1-a – project essch
$ kubectl port-forward Nginxlamp-74c8b5b7f-d2rsg 8080:8080
Forwarding from 127.0.0.1:8080 —> 8080
Forwarding from [::1]:8080 —> 8080
$ google-chrome http://localhost:8080 # это не будет работать в Google Shell
$ kubectl expose Deployment Nginxlamp – type="LoadBalancer" – port=8080
Для локального использования kubectl Вам нужно установить gcloud и с помощью него установить kubectl используя команду gcloud components install kubectl, но пока не будем усложнять первые шаги.
В разделе Сервисы админки будет доступен под не только через сервис балансировщик frontend, но и через внутренний балансировщик Deployment. Хоть и после пересоздания и сохранится, но конфиг более поддерживаем и очевиден.
Также есть возможность дать возможность регулировать количество нод в автоматическом режиме в зависимости от нагрузки, например, количества контейнеров с установленными требованиями к ресурсам, с помощью ключей – enable-autoscaling – min-nodes=1 —max-nodes=2.
Простой кластер в GCP
Для создания кластера можно пойти двумя путями: через графический интрефейс Google Cloud Platform или через его API командой gcloud. Посмотрим, как это можно сделать через UI. Рядом с меню кликнем на выпадающей список и создадим отдельный проект. В разделе Kuberntes Engine выбираем создать кластер. Дадим название, 2CPU, зону europe-north-1 (дата-центр в Финляндии ближе всего к СПб) и последнюю версию Kubernetes. После создания кластера кликаем на подключиться и выбираем Cloud Shell. Для создания через api по кнопке в правом верхнем углу выведем консольную панель и введём в ней:
gcloud container clusters create mycluster – zone europe-north1-a
Через некоторое время, у меня это заняло две с половиной минуты, будут подняты 3 виртуальные машины, на них установлена операционная система и примонтирован диск. Проверим:
esschtolts@cloudshell:~ (essch)$ gcloud container clusters list – filter=name=mycluster
NAME LOCATION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
mycluster europe-north1-a 35.228.37.100 n1-standard-1 1.10.9-gke.5 3 RUNNING
esschtolts@cloudshell:~ (essch)$ gcloud compute instances list
NAME MACHINE_TYPE EXTERNAL_IP STATUS
gke-mycluster-default-pool-43710ef9-0168 n1-standard-1 35.228.73.217 RUNNING
gke-mycluster-default-pool-43710ef9-39ck n1-standard-1 35.228.75.47 RUNNING
gke-mycluster-default-pool-43710ef9-g76k n1-standard-1 35.228.117.209 RUNNING
Подключимся к виртуальной машине:
esschtolts@cloudshell:~ (essch)$ gcloud projects list
PROJECT_ID NAME PROJECT_NUMBER
agile-aleph-203917 My First Project 546748042692
essch app 283762935665
esschtolts@cloudshell:~ (essch)$ gcloud container clusters get-credentials mycluster \
– zone europe-north1-a \
– project essch
Fetching cluster endpoint and auth data.
kubeconfig entry generated for mycluster.
У нас пока нет кластера:
esschtolts@cloudshell:~ (essch)$ kubectl get pods
No resources found.
Создадим кластер:
esschtolts@cloudshell:~ (essch)$ kubectl run Nginx – image=Nginx – replicas=3
deployment.apps «Nginx» created
Проверим его состав:
esschtolts@cloudshell:~ (essch)$ kubectl get deployments – selector=run=Nginx
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
Nginx 3 3 3 3 14s
esschtolts@cloudshell:~ (essch)$ kubectl get pods – selector=run=Nginx
NAME READY STATUS RESTARTS AGE
Nginx-65899c769f-9whdx 1/1 Running 0 43s
Nginx-65899c769f-szwtd 1/1 Running 0 43s
Nginx-65899c769f-zs6g5 1/1 Running 0 43s
Удостоверимся, что все три реплики кластера распределились равномерно на все три ноды:
esschtolts@cloudshell:~ (essch)$ kubectl describe pod Nginx-65899c769f-9whdx | grep Node:
Node: gke-mycluster-default-pool-43710ef9-g76k/10.166.0.5
esschtolts@cloudshell:~ (essch)$ kubectl describe pod Nginx-65899c769f-szwtd | grep Node:
Node: gke-mycluster-default-pool-43710ef9-39ck/10.166.0.4
esschtolts@cloudshell:~ (essch)$ kubectl describe pod Nginx-65899c769f-zs6g5 | grep Node:
Node: gke-mycluster-default-pool-43710ef9-g76k/10.166.0.5
Теперь поставим балансировщик нагрузки:
esschtolts@cloudshell:~ (essch)$ kubectl expose Deployment Nginx – type="LoadBalancer" – port=80
service «Nginx» exposed
Проверим, что он создался:
esschtolts@cloudshell:~ (essch)$ kubectl expose Deployment Nginx – type="LoadBalancer" – port=80
Конец ознакомительного фрагмента.
Текст предоставлен ООО «ЛитРес».
Прочитайте эту книгу целиком, купив полную легальную версию на ЛитРес.
Безопасно оплатить книгу можно банковской картой Visa, MasterCard, Maestro, со счета мобильного телефона, с платежного терминала, в салоне МТС или Связной, через PayPal, WebMoney, Яндекс.Деньги, QIWI Кошелек, бонусными картами или другим удобным Вам способом.