В последнее время я много думал о создании повторяющихся процессов, которым можно доверять. Я думаю, что есть разница между тем, чтобы быть счастливым хакером, создающим код для удовольствия, и счастливым хакером, предоставляющим то, на что вы можете рассчитывать. То, что делает вас профессионалом, это процесс, который стабилен, безопасен и позволяет развиваться без регресса.
В рамках этого процесса я больше сосредоточился на непрерывной интеграции и методах тестирования . Я думаю, что большая часть хорошего процесса состоит в том, чтобы иметь среду, которую вы можете контролировать, легко настраивать и реплицировать по своему усмотрению. Вы когда-нибудь обновляли что-то на своей машине для разработки, и все черт побери? Ну, мне это не нравится. Конечно, есть несколько инструментов, которые мы можем использовать:
- Virtualenv при работе на python, чтобы изолировать библиотеки, к которым вы хотите получить доступ
- RVM и Gemfiles для работы с разными версиями библиотек Ruby / JRuby + для разных проектов
- Cabal, который позволяет задавать специфичные для проекта наборы библиотек для проектов на Haskell (и, кстати, удачи в этом …)
- Maven, чтобы указать, какую версию компилятора Java вы хотите использовать и какие зависимости
Эти инструменты очень помогают, но их недостаточно. Иногда вам нужно получить доступ к общим библиотекам, иногда вам нужен определенный инструмент (apache httpd? MySQL? Postgresql?), Установленный и настроенный определенным образом, например:
- вам может понадобиться настроить apache httpd на определенный порт для определенного доменного имени
- вам может понадобиться определенный набор пользователей для вашей БД с установленными конкретными разрешениями
- вам может понадобиться использовать определенный компилятор, может быть, даже определенную версию (C ++ ’11, кто-нибудь?)
Есть много вещей, которые вы могли бы контролировать, чтобы иметь полностью воспроизводимую среду. Иногда вы можете просто использовать некоторые сценарии для создания этой среды и распространения этих сценариев. Иногда вы можете дать инструкции, перечислив все шаги для репликации этой среды. Проблема в том, что другие участники могут не выполнить эти шаги, и вся ваша среда может испортиться, когда вы обновите что-то в своей системе. Когда это произойдет, вы хотите нажать кнопку, чтобы вернуться к известному рабочему состоянию .
Вы можете легко начать использовать несколько иные среды по сравнению с другими членами вашей команды или рабочую среду, и начнут появляться противоречия. Более того, если у вас длительный процесс установки, вам может потребоваться много времени для воссоздания среды на новом компьютере. , Когда вам нужно по какой-то причине начать работать на другом ноутбуке, если вы хотите сделать это легко, когда вы хотите, чтобы кто-то начал вносить свой вклад в ваши проекты с открытым исходным кодом, вы хотите снизить барьеры.
Именно по этим причинам я недавно начал играть с Docker.
Что такое Docker и как его установить
По сути, вы можете представить Docker как своего рода легкую альтернативу VirtualBox или другим подобным гипервизорам. Запустив Linux, вы можете создавать виртуальные машины различного типа, используя ядро «реальной» машины. Однако вы можете полностью изолировать эти виртуальные машины, установить конкретные версии необходимых вам инструментов, определенные библиотеки и т. Д.
Docker изначально работает только в Linux. Чтобы использовать его в Mac OS-X или Windows, вам нужно создать облегченную виртуальную машину под управлением Linux, и Docker будет работать на этой виртуальной машине. Однако весь беспорядок может быть частично скрыт с помощью boot2docker . Это означает некоторые дополнительные головные боли, но вы можете пережить это, если придется. Если я могу, я предпочитаю ssh на Linux-боксе и запускать там Docker, но иногда это не лучшее решение.
Чтобы установить docker на производную Debian, просто запустите:
1
2
|
# if your system is not recent you could have to use apt-get instead of apt sudo apt install docker |
Наш пример: создание двух взаимодействующих Docker-контейнеров
Давайте начнем с простого примера: предположим, что вы хотите разработать приложение PHP (извините …) и хотите использовать MySQL в качестве базы данных (еще раз извините …).
Мы создадим два docker-контейнера: в первом мы установим PHP, во втором — MySQL. Мы установим связь между двумя контейнерами и получим доступ к приложению из браузера на нашей гостевой машине. Для простоты мы будем запускать PhpMyAdmin вместо разработки какого-либо примера приложения на PHP.
Первый Docker-контейнер: PHP
Давайте начнем с чего-то очень простого: давайте настроим образ Docker для запуска httpd под centos6. Давайте создадим каталог с именем phpmachine и создадим файл с именем Dockerfile .
01
02
03
04
05
06
07
08
09
10
|
# Based on an example found at https://github.com/CentOS/CentOS-Dockerfiles FROM centos:centos6 MAINTAINER Federico Tomassetti RUN yum -y update; yum clean all RUN yum -y install httpd; yum clean all RUN yum -y install php; yum clean all RUN yum -y install php-mbstring; yum clean all RUN yum -y install php-mysql; yum clean all RUN echo "Apache HTTPD" >> /var/www/html/index .html EXPOSE 80 |
Обратите внимание, что это очень простой пример: мы не указываем определенную версию httpd для установки. При установке какого-либо другого программного обеспечения мы могли бы захотеть это сделать.
Из каталога, содержащего Dockerfile, запустите:
1
|
docker build -t phpmachine . |
Эта команда создаст контейнер, как описано в инструкциях. Первым делом он загрузит изображение Centos 6, которое будет использоваться в качестве основы этой машины.
Теперь, запустив образы Docker, вы должны найти строку, похожую на эту:
1
2
3
|
~ /d/phpmachine ❯❯❯ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE phpmachine latest a6f6e10d6834 About a minute ago 236.6 MB |
Теперь вы можете запустить этот контейнер и войти в него с помощью этой команды:
1
|
docker run -t -i -P phpmachine /bin/bash |
После входа в контейнер вы можете запустить Apache и узнать IP-адрес докера, на котором он работает:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
~ /d/phpmachine ❯❯❯ docker run -t -i -P phpmachine /bin/bash [root@f9226ce4ca3b /] # /usr/sbin/apachectl start httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.5 for ServerName [root@f9226ce4ca3b /] # ifconfig eth0 Link encap:Ethernet HWaddr 5A:71:53:91:7C:D2 inet addr:172.17.0.5 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::5871:53ff:fe91:7cd2 /64 Scope:Link UP BROADCAST RUNNING MTU:1500 Metric:1 RX packets:7 errors:0 dropped:2 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:558 (558.0 b) TX bytes:648 (648.0 b) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1 /128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) [root@f9226ce4ca3b /] # |
Теперь, если вы введете этот IP-адрес в браузере, вы должны увидеть что-то вроде этого:
Круто, все работает!
Давайте улучшим процесс так, чтобы 1) мы могли запустить сервер httpd без необходимости использовать консоль док-контейнера 2) нам не нужно выяснять IP-адрес контейнера.
Чтобы решить первую проблему, просто добавьте эту строку в Dockerfile:
1
|
CMD exec /usr/sbin/apachectl -D FOREGROUND |
Теперь пересоберите контейнер и запустите его так:
1
2
|
docker build -t phpmachine . docker run -t -p 80:80 -P phpmachine |
Таким образом, порт 80 док-контейнера повторно сопоставляется с портом 80 хост-машины. Теперь вы можете открыть браузер и использовать адрес localhost или 127.0.0.1.
Замечательно, теперь давайте начнем с сервера MySQL.
Второй Docker-контейнер: MySQL сервер
Мы хотим создать Dockerfile в другом каталоге и добавить в тот же каталог скрипт с именем config_db.sh .
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
# Dockerfile FROM centos:centos6 MAINTAINER Federico Tomassetti RUN yum -y update; yum clean all RUN yum -y install mysql-server; yum clean all EXPOSE 3306 # Run a script to create a DB ADD . /config_db .sh /config_db .sh RUN chmod +x /config_db .sh RUN /etc/init .d /mysqld start && /config_db .sh && /etc/init .d /mysqld stop # Start Mysql and open a mysql shell just to keep the process alive: # this is a poor-man trick and you probably want to do something smarter CMD /etc/init .d /mysqld start && mysql |
1
2
3
4
5
6
7
|
# config_db.sh # note that by default we do not need a password to connect to # mysql as root mysql -e "CREATE DATABASE mydb" mysql -e "GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost' IDENTIFIED BY 'myuserpwd'; FLUSH PRIVILEGES;" mysql -e "GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'%' IDENTIFIED BY 'myuserpwd'; FLUSH PRIVILEGES;" mysql -e "select user, host FROM mysql.user;" |
Примечание: мы никоим образом не сохраняем данные нашей базы данных MySQL, поэтому каждый раз, когда мы перезапускаем контейнер, мы теряем все.
Теперь мы можем построить машину:
1
|
docker build -t mysqlmachine . |
Тогда мы можем запустить это:
1
|
docker run -p 3306:3306 -P -i -t mysqlmachine |
И мы можем подключиться с нашего «реального ящика» к серверу mysql, работающему в контейнере Docker:
1
|
mysql --host=127.0.0.1 --protocol=TCP -u myuser -pmyuserpwd mydb |
Пока все работает как положено? Круто, давай двигаться дальше.
Заставьте два док-контейнера общаться
Давайте присвоим имя контейнеру mysql:
1
|
docker run -p 3306:3306 -P --name mysqlcontainer -i -t mysqlmachine |
Теперь давайте запустим контейнер PHP, рассказывающий о mysqlcontainer:
1
|
docker run -i -t -p 80:80 -P --link mysqlcontainer:dbhost phpmachine /bin/bash |
С консоли phpmachine вы сможете пинговать dbhost (имя, под которым phpmachine может достигать контейнера mysql). Хороший!
На практике в файл / etc / hosts phpmachine добавляется строка, связывающая dbhost с IP-адресом нашего mysqlmachine .
Установка PHPMyAdmin
Мы используем PHPMyAdmin в качестве заполнителя для некоторого приложения, которое вы можете захотеть разработать. Когда вы разрабатываете приложение, вы хотите отредактировать его на компьютере разработчика и сделать его доступным для контейнера Docker. Итак, загрузите PhpMyAdmin версии 4.0.x (более поздние версии требуют mysql 5.5, а centos 6 использует mysql 5.1) и распакуйте его в какой-то каталог, предположим, что он находится в ~ / Downloads / phpMyAdmin-4.0.10-all-languages . Теперь вы можете запустить Docker-контейнер с php следующим образом:
1
|
docker run - v ~ /Downloads/phpMyAdmin-4 .0.10-all-languages: /var/www/html -i -t -p 80:80 -P --link mysqlcontainer:dbhost phpmachine |
Это смонтирует каталог с исходным кодом PhpMyAdmin в / var / www / html в * phpmachine *, который является каталогом, который настроен для обслуживания Apache httpd.
На этом этапе вам нужно переименовать config.sample.inc.php в config.inc.php и изменить эту строку:
1
2
3
4
5
6
7
|
# From $cfg[ 'Servers' ][$i][ 'host' ] = 'localhost' ; # To $cfg[ 'Servers' ][$i][ 'host' ] = 'dbhost' ; |
Таким образом, phpmachine должен использовать базу данных на mysqlmachine .
Теперь вы должны иметь возможность посетить localhost и увидеть форму. Там введите учетные данные для db: myuser , myuserpwd, и у вас все будет готово!
Как Докер связан с Vagrant и Ansible, Chef, Puppet?
Есть несколько других инструментов, которые могут помочь в управлении виртуальными машинами и виртуальными машинами. Если вас немного смущают отношения между различными инструментами, это упрощенное резюме:
- Vagrant — это утилита командной строки для управления виртуальными машинами, но мы говорим о полной имитации машины, в то время как Docker использует ядро с хоста Docker, что приводит к гораздо более легким «виртуальным машинам» (наши контейнеры Docker)
- Ansible, Chef и Puppet — это способы управления конфигурацией этих машин (операционные процессы), которые они могут использовать вместе с Docker. Ansible кажется намного легче по сравнению с Chef и Puppet (но чуть менее мощный). Он набирает обороты среди пользователей Docker, и я планирую узнать о нем больше.
Этот пост дает более подробную информацию об отношениях между этими инструментами.
Выводы
В нашем небольшом примере мы могли бы поиграть с реалистичной имитацией окончательной производственной установки, которая, как мы предполагаем, составлена на двух машинах с CentOS 6. Таким образом, мы выяснили несколько вещей (например, у нас есть пакеты для MySQL 5.1, и это заставляет мы не используем последнюю версию PhpMyAdmin, мы знаем полный список пакетов, которые нам нужно установить, и т. д.). Таким образом, мы можем ожидать, что очень немногие будут удивлены при развертывании в производственной среде. Я твердо верю, что меньше сюрпризов — это очень хорошо.
Мы также можем просто развернуть докер-контейнеры, если захотим (я еще никогда не пробовал).
Обновление: я рад, что ребята из Docker цитировали эту статью в своем еженедельном бюллетене , спасибо!