Книга Облачная экосистема - читать онлайн бесплатно, автор Евгений Сергеевич Штольц. Cтраница 3
bannerbanner
Вы не авторизовались
Войти
Зарегистрироваться
Облачная экосистема
Облачная экосистема
Добавить В библиотекуАвторизуйтесь, чтобы добавить
Оценить:

Рейтинг: 0

Добавить отзывДобавить цитату

Облачная экосистема

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. Например,:

Docker run –rm -it –name name_container ubuntu BASH

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

* Docker run для запуска контейнера;

* Docker ps для просмотра запущенных контейнеров;

* Docker rm для удаления контейнера;

* Docker build для создания своего образа;

* Docker images для просмотра существующих контейнеров;

* Docker rmi для удаления образа.

Но с ростом популярности, команд становилось всё больше и их было решено сгруппировать в группы, так вместо простого "Docker run" появилась команда "Docker container", которая имеет 25 команд в 19 версии Docker. Это очистка, и остановка с восстановлением, и логи и различные виды подсоединений к контейнеру. Таже судьба постигла и работы с образами. Но, старые команды остались пока из-за совместимости и удобства, ведь в большинстве случаев требуется базовый набор. На нём и остановимся:

Запуск контейнера:

docker run -d –name name_container ubuntu bash

Удалить работающий контейнер:

docker rm -f name_container

Вывод всех контейнеров:

docker ps -a

Вывод работающих контейнеров:

docker ps

Вывод контейнеров с потребляемыми ресурсами:

docker stats

Вывод процессов в контейнере:

docker top {name_container}

Подключиться к контейнеру через оболочку sh (BASH в контейнерах alpine нет):

docker exec -it sh

Чистка системы от неиспользуемых образов:

docker image prune

Удалить весящие образа:

docker rmi $(docker images -f "dangling=true" -q)

Показать образа:

docker images

Создать образ в папке dir с Dockerfile:

docker build -t docker_user/name_image dir

Удалить образ:

docker rmi docker_user/name_image dir

Подключиться к Docker hub:

docker login

Отравить последнюю редакцию (тэг ставится и смещается автоматически, если не указан иной) образ на Docker hub:

docker push ocker_user/name_image dir:latest

Более широкий список в https://niqdev.github.io/devops/docker/.

Создание Docker Machine можно описать следующими этапами:

Создание виртуальной машины VirtualBox

docker-machine create name_virtual_system

Создание виртуальной машины generic

docker-machine create -d generic name_virtual_system

Список виртуальных машин:

docker-machine ls

Остановить виртуальную машину:

docker-machine stop name_virtual_system

Запустить остановленную виртуальную машину:

docker-machine start name_virtual_system

Удалить виртуальную машину:

docker-machine rm name_virtual_system

Подключиться к виртуальной машине:

eval "$(docker-machine env name_virtual_system)"

Отключить Docker от виртуальной машины:

eval $(docker-machine env -u)

Зайти по SSH:

docker-machine ssh name_virtual_system

Выйти из виртуальной машины:

exit

Запуcк команды sleep 10 в виртуальной машине:

docker-machine ssh name_virtual_system 'sleep 10'

Запуск команд в среде BASH:

docker-machine ssh dev 'bash -c "sleep 10 && echo 1"'

Скопировать папку dir в вируальную машину:

docker-machine scp -r /dir name_virtual_system:/dir

Сделать запрос к контейнерам виртуальной машины:

curl $(docker-machine ip name_virtual_system):9000

Пробросить порт 9005 хостовой машины на 9005 виртуальной машины

docker-machine ssh name_virtual_system -f -N -L 9005:0.0.0.0:9007

Инициализация мастера:

docker swarm init

Запуск множества контейнеров с одинаковыми EXPOSE:

essh@kubernetes-master:~/mongo-rs$ docker run –name redis -p 6379 -d redis

f3916da35b6ba5cd393c21d5305002b78c32b089a6cc01e3e2425930c9310cba

essh@kubernetes-master:~/mongo-rs$ docker ps | grep redis

f3916da35b6b redis"docker-entrypoint.s…" 8 seconds ago Up 6 seconds 0.0.0.0:32769->6379/tcp redis

essh@kubernetes-master:~/mongo-rs$ docker port reids

Error: No such container: reids

essh@kubernetes-master:~/mongo-rs$ docker port redis

6379/tcp –> 0.0.0.0:32769

essh@kubernetes-master:~/mongo-rs$ docker port redis 6379

0.0.0.0:32769

Сборка – первое решение скопировать все файлы и установить. В результате при изменении любого файла будет производится переустановка всех пакетов:

COPY ./ /src/app

WORKDIR /src/app

RUN NPM install

Воспользуемся кэшированием и разделим статические файлы и установку:

COPY ./package.json /src/app/package.json

WORKDIR /src/app

RUN npm install


COPY . /src/app

Использование шаблона базового образа node:7-onbuild:

$ cat Dockerfile

FROM node:7-onbuild

EXPOSE 3000

$ docker build .

В таком случае, файлы, которые не нужно включать в образ, такие как системные файлы, например, Dockerfile, .git, .node_modules, файлы с ключами, их нужно внести в node_modules, файлы с ключами, их нужно внести в .dockerignore.

–v /config

docker cp config.conf name_container:/config/

Статистика использованных ресурсов в реальном времени:

essh@kubernetes-master:~/mongo-rs$ docker ps -q | docker stats

CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS

c8222b91737e mongo-rs_slave_1 19.83% 44.12MiB / 15.55GiB 0.28% 54.5kB / 78.8kB 12.7MB / 5.42MB 31

aa12810d16f5 mongo-rs_backup_1 0.81% 44.64MiB / 15.55GiB 0.28% 12.7kB / 0B 24.6kB / 4.83MB 26

7537c906a7ef mongo-rs_master_1 20.09% 47.67MiB / 15.55GiB 0.30% 140kB / 70.7kB 19.2MB / 7.5MB 57

f3916da35b6b redis 0.15% 3.043MiB / 15.55GiB 0.02% 13.2kB / 0B 2.97MB / 0B 4

f97e0697db61 node_api 0.00% 65.52MiB / 15.55GiB 0.41% 862kB / 8.23kB 137MB / 24.6kB 20

8c0d1adc9b9c portainer 0.00% 8.859MiB / 15.55GiB 0.06% 102kB / 3.87MB 57.8MB / 122MB 20

6018b7e3d9cd node_payin 0.00% 9.297MiB / 15.55GiB 0.06% 222kB / 3.04kB 82.4MB / 24.6kB 11

^C

При создании образов нужно учитывать:

** изменение большого слоя он будет пересоздан, поэтому его, часто лучше разделить, например, создать один слой с 'NPM i' и уже на втором скопировать код ;

* если файл в образе большой и контейнер иго изменят, то из слоя образа доступного только для чтения файл будет целиком скопирован в слой для редактирования, поэтому, контейнера предполагаются быть легковесными, а контент принято располагать в специальном хранилище. code-as-a-service: 12 факторов (12factor.net)

* Codebase – один сервис – они репозиторий;

* Dependeces – все зависимые сервисы в конфиге;

* Config – конфиги доступны через среду;

* BackEnd – обмениваются данными с другими сервисами через сеть на основе API;

* Processes – один сервис – одни процесс, что позволяет в случае падения однозначно отслеживать (завершается сам контейнер) и перезапускать его;

* Независимость о окружения и не влияние на него.

* СI/CD – code control (git) – build (jenkins, GitLab) – relies (Docker, jenkins) – deploy (helm, Kubernetes). Поддержание легковесности сервиса важно, но есть программы, не предназначенные для запуска в контейнерах, таки как базы данных. Из-за своей особенности к их запуску предъявляются определённые требования, а профит ограничен. Так, из-за больших данных они не просто медленно масштабируется, а ролинг-абдейт маловероятен, при этом перезапуск необходимо производить на тех же нодах, что и их данные из соображений производительности доступа к ним.

* Config – взаимоотношения сервисов определённо в конфигурации, например, docker-compose.yml;

* Port bindign – общение сервисов происходит через порты, при этом порт может выбираться автоматически, например, если в Dockerfile указан EXPOSE PORT, то при вызове контейнера с флагом -P он будет прикончен к свободному автоматически.

* Env – настройки среды предаются через переменные окружения, а не через конфиги, что позволяет их вносить в конфигурацию конфига сервисов, например, docker-compose.yml

* Logs – логи передаются потоком по сети, например, ELK, или выводится в вывод, который уже Docker передаёт потоком.

Внутренности Dockerd:

essh@kubernetes-master:~/mongo-rs$ ps aux | grep dockerd

root 6345 1.1 0.7 3257968 123640 ? Ssl июл05 76:11 /usr/bin/dockerd -H fd:// –containerd=/run/containerd/containerd.sock

essh 16650 0.0 0.0 21536 1036 pts/6 S+ 23:37 0:00 grep –color=auto dockerd

essh@kubernetes-master:~/mongo-rs$ pgrep dockerd

6345

essh@kubernetes-master:~/mongo-rs$ pstree -c -p -A $(pgrep dockerd)

dockerd(6345)-+-docker-proxy(720)-+-{docker-proxy}(721)

| |-{docker-proxy}(722)

| |-{docker-proxy}(723)

| |-{docker-proxy}(724)

| |-{docker-proxy}(725)

| |-{docker-proxy}(726)

| |-{docker-proxy}(727)

| `-{docker-proxy}(728)

|-docker-proxy(7794)-+-{docker-proxy}(7808)


Docker-File:

* чистка кэши от пакетных менеджеров: apt-get, pip и других, этот кэш не нужен на продакшне, лишь

занимает место и нагружает сеть, но ныне не зачастую не актуально, так как есть многоэтапные

сборки, но об этом ниже.

* группируйте команды одних сущностей, например, получение кэша APT, установку программ и удаление

кэша: в одной инструкции – код только программ, при разнесённом варианте – код программ и кэш,

так как если не удалить кэш в одной инструкции, то он будет сохранён в слое, не зависимо от

последующих действий.

* разделяйте инструкции по частоте изменения, так, например, если не разделить установку

программного обеспечения и код, то при изменении чего-либо в коде, то вместо использования готового

слоя с программами они будут переустановлены заново, что повлечёт существенное время на подготовку

образа, которое критично для разработчиков:

ADD ./app/package.json /app

RUN npm install

ADD ./app /app


Альтернативы 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


Мониторинг с помощью Prometheus

Мониторинг – поддержка непрерывности работы, отслеживание текущей ситуации (выявление, локализация и отправка об инциденте, например, в SaaS PagerDuty), прогнозирование возможных ситуаций, визуализация, построение моделей нормально работы IAOps (Artificial Intelligence For It Operations, https://www.gartner.com/en/information-technology/glossary/aiops-artificial-intelligence-operations).

Мониторинг содержит следующие этапы:

* выявление инцидента;

* уведомление о инциденте;

* локализация;

* решение.

Мониторинг можно классифицировать по уровню на следующие типы:


* инфраструктурный (операционная система, сервера, Kubernetes, СУБД), ;

* прикладной (логи приложений, трейсы, события приложений), ;

* бизнес-процессов (точки в транзакциях, трейсы транзакциях).

Мониторинг можно классифицировать по принципу:

* распределённый (трейсы), ;

* синтетический (доступность), ;

* IAOps (прогнозирование, аномалии).

Мониторинг делится на две части по степени анализа на системы логирования и системы расследования инцидентов. Примером логирования

служит ELK стек, а расследования инцидентов – Sentry (SaaS). Для микро-сервисов добавляется ещё и система трассировки

запросов, такие как Jeger или Zipkin. Система логирования просто пишет все логи, которые доступны.

Система расследования инцидентов пишет гораздо больше информации, но пишет её только в случае ошибок в приложении, например,

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

по ошибке, а не собрать её по кусочкам с сервера и GIT репозитория. Но набор и формат информации зависит от окружения, поэтому

системе инцидентов нужно иметь интеграцию с различными языковыми платформами, а ещё лучше с конкретными фреймворками. Так Sentry

отравляет переменные окружения, участок кода и указание в каком месте произошла ошибка, параметры программного и платформенного

окружения, вызовы методов.

Мониторинг по экосистеме можно разделить на:

* Встроенный в облако Cloud: Azure Monitoring, Amazon CloudWatch, Google Cloud Monitoring

* Предоставляющийся как сервис с поддержкой различных интеграций SaaS: DataDog, NewRelic

* CloudNative: Prometheus

* Для выделенных серверов OnPremis: Zabbix


Zabbix разработан в 1998 год и выведен в OpenSource под лицензией в GPL в 2001. Для того времени, традиционный интерфейс:

без какого-либо дизайна, с большим числом вкладок, селекторов и тому подобного. Так как он разрабатывался для

собственных нужд, то он содержит конкретные решения. Ориентирован он

на мониторинг устройств и их компонентов, таких как диски, сеть, принтеры, роутеры и тому подобного. Для

взаимодействия можно использовать:


Агенты – устанавливаются на сервера, собирают множество метрик и отравляют Zabbix серверу

HTTP – Zabbix делает запросы по http, например, принтеров

SNMP— сетевой протокол для взаимодействия с сетевых устройств

IPMI – протокол для взаимодействия с серверными устройствами, такими, как роутеры

В 2019 году Gratner представил рейтинг систем мониторинга в своём квадрате:

** Dynatrace;

** Cisco (AppDynamics);

** New Relic;

** Broadcom (CA Technologies);

** Riverbed и Microsoft;

** IBM;

** Oracle;

** SolarWinds;

** Micro Focus;

** ManageEngine и Tingyun.

Не вошли в квадрат:

** Correlsense;

** Datadog;

** Elastic;

** Honeycomb;

** Instant;

** Jennifer Soft;

** Light Step;

** Nastel Technologies;

** SignalFx;

** Splunk;

** Sysdig.

Когда мы запускаем приложение в Docker контейнере, весь стандартный вывод (то, что выводится в консоли) запущенной программы (процесса) помещается в буфер. Этот буфер мы можем просмотреть программой docker logs name_container. Если мы следуем идеологии Docker – "один процесс – один контейнер" – мы можем просматривать логи отдельной программы. Для просмотра логов удобно пользоваться командами less и tail. Первая программа позволяет удобно прокручивать лога стрелками клавиатуры, искать нужное с на основе совпадений и по шаблону регулярных выражений, на подобие текстового редактора vi. Вторая программа выводит нужно нам количество