banner banner banner
Облачная экосистема
Облачная экосистема
Оценить:
Рейтинг: 0

Полная версия:

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

скачать книгу бесплатно


unser DOCKER_HOST

Важно прописать export для обеспечения доступности переменной всем программам: дочерним процессам. Также не должно стоять пробелов вокруг =. Теперь мы так можем обращаться из любого места находящимся в одной сети сервером Dockerd. Для управления удалёнными и локальными Docker Engine (Docker на хостах) разработана программа Docker Machine. Взаимодействие с ней осуществляется с помощью команды Docker-machine. Для начала установим:

base=https://github.com/docker/machine/releases/download/v0.14.0 &&

curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/usr/local/bin/docker-machine &&

chmod +x /usr/local/bin/docker-machine

Группа взаимосвязанных приложений

У нас уже есть несколько разных приложений, допустим, таких как NGINX, MySQL и наше приложение. Мы их изолировали в разных контейнерах, теперь она не конфликтуют между собой и NGINX и MySQL мы не стали тратить время и усилия на изготовление собственной конфигурации, а просто скачали: Docker run mysql, docker run Nginx, а для приложения docker build .; docker run myapp -p 80:80 bash. Как видно, казалось бы, всё очень просто, но есть два момента: управление и взаимосвязь.

Для демонстрации управления возьмём контейнер нашего приложения, и реализуем две возможности – старт и создание (переборку). Для ручного старта, когда мы знаем, что контейнер уже создан, но просто остановлен, достаточно выполнить docker start myapp, но для автоматического режима этого недостаточно, а нам нужно написать скрипт, который бы учитывал, существует ли уже контейнер, существует ли для него образ:

if $(docker ps | grep myapp)

then

docker start myapp

else

if ! $(docker images | grep myimage)

docker build .

fi

docker run -d –name myapp -p 80:80 myimage bash

fi

. А для создания нужно удалить контейнер, если он существует:

if $(docker ps | grep myapp)

docker rm -f myapp

fi

if ! $(docker images | grep myimage)

docker build .

fi

docker run -d –name myapp -p 80:80 myimage bash

. Понятно, что нужно общими параметры, название образа, контейнера вывести в переменные, проверить, что Dockerfile есть, он валидный и только после этого удалять контейнер и много другого. Для понимания реального масштаба, на вдаваясь во взаимодействие контейнеров, о клонировании (масштабирование) этих групп и тому подобного, а только упомяну, то, что команда Docker run может превышать один – два десятка строк. Например, десяток проброшенных портов, монтируемых папок, ограничения на память и процессор, связи с другими контейнерами и ещё немного специфичных параметров. Да, это нехорошо, но делить в таком варианте на множество контейнеров сложно, из-за отсутствия карты взаимодействия контейнеров. Но возникает вопрос: Не много ли нужно делать, чтобы просто предоставить пользователю возможность стартовать контейнер или пересобрать? Зачастую ответ системного администратора сводится к тому, что давать доступы можно только избранным. Но и тут есть решение: Docker-compose – инструмент для работы с группой контейнеров:

#docker-compose

version: v1

services:

myapp:

container-name: myapp

images: myimages

ports:

– 80:80

build: .

. Для старта docker-compose up -d, а для переборки docker down; docker up -d. Причём, при изменении конфигурации, когда не нужна полная переборка, произойдёт просто её обновление.

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

#docker-compose

version: v1

services:

mysql:

images: mysql

Nginx:

images: Nginx

ports:

– 80:80

myapp:

container-name: myapp

build: .

depence-on: mysql

images: myimages

link:

– db:mysql

– Nginx:Nginx

. Здесь мы видим всю картину в целом, контейнера связаны одной сетью, где приложение может обращаться к mysql и NGINX по хостам db и NGINX, соответственно, контейнер myapp будет создан, только когда после поднятия базы данных mysql, даже если это займёт некоторое время.

Service Discovery

С ростом кластера вероятность падения нод вырастает и ручное обнаружение произошедшего усложняется, для автоматизации обнаружение вновь появившихся сервисов и их исчезновение предназначены системы Service Discovery. Но, чтобы кластер мог обнаруживать состояние, учитывая, что система децентрализована – ноды должны уметь обмениваться сообщениями с друг другом и выбирать лидера, примерами могут быть Consul, ETCD и ZooKeeper. Мы рассмотрим Consul исходя их следующих его особенностей: вся программа – одни файл, крайне прост в работе и настройке, имеет высокоуровневый интерфейс (ZooKeeper его не имеет, полагается, что со временем должны появиться сторонние приложения, его реализующие), написан на не требовательном языке к ресурсам вычислительной машины (Consul – Go, ZooKeeper – Java) и пренебрегли его поддержкой в других системах, такай как, например, ClickHouse (поддерживает по умолчанию ZooKeeper).

Проверим распределение информации между нодами с помощью распределенного key-value хранилища, то есть, если мы в одну ноду добавили записи, то они должны распространиться и на другие ноды, при этом жёстко заданного координирующего (Master) ноды у неё не должно быть. Поскольку Consul состоит из одного исполняемого файла – скачиваем его с официального сайта по ссылке https://www.consul.io/downloads. html на каждой ноде:

wget https://releases.hashicorp.com/consul/1.3.0/consul_1.3.0_linux_amd64.zip -O consul.zip

unzip consul.zip

rm -f consul.zip

Теперь необходимо запустить одну ноду, пока, как master consul -server -ui, а другие как slave consul -server -ui и consul -server -ui . После чего остановим Consul, находящийся в режиме master, и запускаем его как равного, в результате Consul – переизберут временного лидера, а в случае иго падения, переизберут снова. Проверим работу нашего кластера consul members:

consul members;

И так проверим распределение информации нашего хранилища:

curl -X PUT -d 'value1' .....:8500/v1/kv/group1/key1

curl -s .....:8500/v1/kv/group1/key1

curl -s .....:8500/v1/kv/group1/key1

curl -s .....:8500/v1/kv/group1/key1

Настроим мониторинг сервисов, подробнее в документации https://www.consul.io/docs/agent/options. html #telemetry, для этого .... https://medium.com/southbridge/monitoring-consul-with-statsd-exporter-and-prometheus-bad8bee3961b

Чтобы не настраивать, воспользуемся контейнером и режимом для разработки с уже настроенным IP-адресом на 172.17.0.2:

essh@kubernetes-master:~$ mkdir consul && cd $_

essh@kubernetes-master:~/consul$ docker run -d –name=dev-consul -e CONSUL_BIND_INTERFACE=eth0 consul

Unable to find image 'consul:latest' locally

latest: Pulling from library/consul

e7c96db7181b: Pull complete

3404d2df15cb: Pull complete

1b2797650ac6: Pull complete

42eaf145982e: Pull complete

cef844389e8c: Pull complete

bc7449359c58: Pull complete

Digest: sha256:94cdbd83f24ec406da2b5d300a112c14cf1091bed8d6abd49609e6fe3c23f181

Status: Downloaded newer image for consul:latest

c6079f82500a41f878d2c513cf37d45ecadd3fc40998cd35020c604eb5f934a1

essh@kubernetes-master:~/consul$ docker inspect dev-consul | jq ' .[] | .NetworkSettings.Networks.bridge.IPAddress'

"172.17.0.4"

essh@kubernetes-master:~/consul$ docker run -d –name=consul_follower_1 -e CONSUL_BIND_INTERFACE=eth0 consul agent -dev -join=172.17.0.4

8ec88680bc632bef93eb9607612ed7f7f539de9f305c22a7d5a23b9ddf8c4b3e

essh@kubernetes-master:~/consul$ docker run -d –name=consul_follower_2 -e CONSUL_BIND_INTERFACE=eth0 consul agent -dev -join=172.17.0.4

babd31d7c5640845003a221d725ce0a1ff83f9827f839781372b1fcc629009cb

essh@kubernetes-master:~/consul$ docker exec -t dev-consul consul members

Node Address Status Type Build Protocol DC Segment

53cd8748f031 172.17.0.5:8301 left server 1.6.1 2 dc1 < all>

8ec88680bc63 172.17.0.5:8301 alive server 1.6.1 2 dc1 < all>

babd31d7c564 172.17.0.6:8301 alive server 1.6.1 2 dc1 < all>

essh@kubernetes-master:~/consul$ curl -X PUT -d 'value1' 172.17.0.4:8500/v1/kv/group1/key1

true

essh@kubernetes-master:~/consul$ curl $(docker inspect dev-consul | jq -r ' .[] | .NetworkSettings.Networks.bridge.IPAddress'):8500/v1/kv/group1/key1

[

{

"LockIndex": 0,