Для построения собственного отказоустойчивого облака в вашем датацентре, нужно запастись терпением и базовыми знаниями Docker.
Мы будем использовать не малый программный stack:
- Named (round-robin) — Балансировка базовыми средствами DNS
- NGINX — Веб-сервер для проксирования запросов на веб приложение
- Docker — Программное обеспечение для автоматизации развёртывания и управления приложениями в средевиртуализации на уровне операционной системы
- Docker compose — Является инструментом для запуска и соединения нескольких Docker контейнеров
- Docker registry — Программное обеспечение для хранения образов Docker
- Rancher — Rancher Labs разрабатывает программное обеспечение, которое позволяет легко развертывать и управлять контейнерами в любой организации, работающей на любой инфраструктуре
- Rancher compose — Работает по принципу docker-compose, служит для включений функций Rancher
- Consul — Утилита для Service Dicovery и Key/Value Store
- Jenkins — инструмент непрерывной интеграции, написанный на Java
Для построения базовой инфраструктуры(без HA) на нужны будут:
Название | IP | DNS |
WebServer | 192.168.11.140 | web.cloud.infra |
CloudMaster | 192.168.11.72 | master1.cloud.infra |
CloudClient1 | 192.168.11.73 | ci1.cloud.infra |
CloudClient2 | 192.168.11.132 | ci2.cloud.infra |
* Используемые IP взяты с реальной системы и нужны для соответствия со скриншотами

1. Настройка локального DNS
Построение облака происходит внутри нашей сети, для этого создаем отдельную зону.
Редактируем конфигурационный файл named:
1 |
nano /etc/named/cloud.zones |
1 2 3 4 |
zone "cloud.infra" { type master; file "/var/named/master/cloud.infra"; }; |
Теперь создаем файл зоны:
1 |
nano /var/named/master/cloud.infra |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$TTL 3600 @ IN SOA ns.cloud.infra. hostmaster.cloud.com. ( 2015111800 ; Serial 28800 ; Refresh 7200 ; Retry 604800 ; Expire 3600 ) ; Default Minimum TTL IN NS ns.cloud.infra. master1 A 192.168.11.72 ci1 A 192.168.11.73 ci2 A 192.168.11.132 web A 192.168.11.140 |
И перезапускаем Named
1 |
service named restart |
DNS настроен, приступаем к созданию мастер сервера
2. Настройка мастер сервера
На мастер сервере будут размещаться:
- Rancher-server
- Consul-server
- Jenkins
Запускаем контейнер с Rancher
1 |
sudo docker run -d --restart=always -p 8080:8080 rancher/server |
Наш Rancher сервер доступен по адресу http://master1.cloud.infra:8080.
Настраиваем авторизацию:
- Admin -> Access Control
- Выбираем LOCAL
3. добавляем нового пользователя
Настраиваем окружения:
- Переходим на вкладку Default
- Нажимаем «Add Environment»
- Выбираем Cattle
- Пишем название и добавляем пользователей
Настройка своего registry
- Переходим по вкладке Infrastructure -> Registries
- Выбираем Custom
- Вписываем свои значения
Создаем API key
- Переходим на вкладук API
- Генрируем и записываем себе знчаения
Пока c Rancher мы закончим, вернемся когда будем настраивать клиенты
Запускаем контейнер с Сonsul-server
1 2 3 |
docker run -d -p 8500:8500 -p 53:8600/udp \ -p 400:8400 -p 8300:8300 -p 8301:8301 -p 8302:8302 \ --name=consul gliderlabs/consul-server -bootstrap |
Consul доступен по адресу http://master1.cloud.infra:8500
Запускаем Jenkins
1 |
docker run -d -p 32769:8080 jenkins |
Jenkins доступен по адресу http://master1.cloud.infra:32769
3. Настройка клиентов
На CloudClient1 и CloudClient2 запускаем два Docker контейнера
- Rancher client
- Consul registrator
Для запуска Rancher client нужно зайти на Rancher master:
- Перейти Infrastructure -> Hosts
- И нажать «Add Host»
- В 4 пункте прописать внешний IP сервера
- Скопировать содержание 5-го пункта
На CloudClient1 запускаем контейнеры с Rancher и Consul
1 2 3 4 |
sudo docker run -e CATTLE_AGENT_IP="192.168.11.73" \ -d --privileged -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.0.2 \ http://master1.cloud.infra:8080/v1/scripts/E0EC8B33530A5512C0C7:q2qdFb3XY4 |
1 2 3 |
docker run -d -v \ /var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator \ -ip 192.168.11.73 consul://192.168.11.72:8500 |
Тоже самое делаем на CloudClient2 только меняем IP адреса
1 2 3 4 |
sudo docker run -e CATTLE_AGENT_IP="192.168.11.132" \ -d --privileged -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.0.2 \ http://master1.cloud.infra:8080/v1/scripts/E0EC8B33530A5512C0C7:1473764400000:jq2qdFb3XY4 |
1 2 3 |
docker run -d -v \ /var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator \ -ip 192.168.11.132 consul://192.168.11.72:8500 |
Если все прошло удачно то мы увидим в Rancher наши сервера
* Не обращаем внимания на запущенные сервисы
4. Настройка проекта
Для создания проекта в Rancher, необходимо создать docker-compose v1 файл, добавить данные полученные с API и скачать Rancher-compose.
Rancher не собирает проекты из Dockerfile он выкачивает их из registry. Поэтому собирать нужно локально либо на каком-то хосте
Создаем проект homepage:
1 |
nano docker-compose-rancher.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
homepage: image: registry.cloud.infra/homepage ports: - "3000" links: - mongo environment: - MONGO_URL=mongodb://mongo:27017/homepage-dev - ROOT_URL=http://localhost - MAIL_URL=smtp://some.mailserver.com:25 labels: io.rancher.container.pull_image: always mongo: image: mongo:3.2.6 command: mongod --smallfiles volumes: - /srv/docker/homepage/mongo:/data/db labels: io.rancher.container.pull_image: always |
Так же создаем простой build скрипт
1 |
nano new.sh |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/bin/bash IMAGE_NAME="registry.cloud.infra/homepage" case "${1}" in --build | -b ) docker build --no-cache --rm -t ${IMAGE_NAME} . ;; --run | -r ) docker run -d -P -t ${IMAGE_NAME} ;; --help | -h ) printf "usage: ${0} [arg]\n--build,-b\tBuild image\n--run,-r\tRun\n" ;; * ) printf "Print ${0} --help for help\n" ;; esac |
Экспортим глобальные переменные
1 2 3 |
export RANCHER_URL='http://master1.cloud.infra:8080/v1/' export RANCHER_ACCESS_KEY='access' export RANCHER_SECRET_KEY='secret' |
И скачиваем rancher-compose (Ссылка в правом нижнем углу в Rancher)
Добавляем проект в Rancher
1 |
rancher-compose --file docker-compose-rancher.yml create |
Запускаем проект
1 |
rancher-compose --file docker-compose-rancher.yml up -d |
Если все прошло удачно то в Rancher должны увидеть:
Так же в Consul мы увидим:
5. Настройка WEB сервера
Устанвливаем NGINX и скачиваем consul-template
1 2 |
yum install nginx wget https://releases.hashicorp.com/consul-template/0.15.0/ |
Создаем consul-template для NGINX
1 |
nano /etc/nginx/conf.d/homepage.ctmpl |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
server { listen 80; server_name homepage.cloud.infra; client_max_body_size 4M; proxy_cache one; location / { proxy_set_header Host $host:$server_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; {{range service "homepage-3000" }} proxy_pass http://{{.Address}}:{{.Port}};{{end}} proxy_read_timeout 90; proxy_cache_valid 200 10m; proxy_cache_methods GET HEAD POST; proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } |
Стартуем NGINX и consul-template
1 2 3 4 |
service nginx start consul-template \ -consul master1.cloud.infra:8500 \ -template "/etc/nginx/conf.d/nginx.ctmpl:/etc/nginx/conf.d/nginx.conf:service nginx restart" |
Теперь consul-template будет следить за изменениями в cosnul-server и перезаписывать данные в NGINX конфигурации.
6. Jenkins CI
Последний штрих в нашем облаке — это добавление continuous integration
Для этого в Jenkins в конфигурации добавляем значения полученные с API
Создаем Job и в пункте shell exec вписываем
1 2 3 |
cd $JOB_NAME; ./new.sh -b docker push registry/homepage rancher-compose --file docker-compose-rancher.yml up --force-upgrade --pull --confirm-upgrade -d |
P.S
После всех действий у нас есть проект в облаке который разворачивается по нажатию кнопки. Контейнеры поднимаются на хостах менее всего загруженных и линкуются между через внутреннюю сеть Rancher.
Я не описывал все возможности данного облака, для этого нужно много времени, я описал базовые возможности.
Дальше вы сами