Sunday, December 6, 2015

Docker для разработчика. Основы. Часть 1.

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

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

До докера моя рабочая машина включала в себя.

  1. mysql
  2. memcache
  3. redis
  4. elasticsearch
  5. rabbitmq
  6. statsd
  7. logstash
  8. postgresql
  9. mongo
  10. python 2.7
  11. python 3.4
  12. python 3.5
  13. nginx
  14. apache
  15. phing
  16. ant
  17. fabric
  18. Порядочное число библиотек, для сборки которых нужны была уйма *dev пакетов. 
  19. И наверное еще кучу мелочей которые сходу и не припомнить. 
Отдельной песней шел один из проектов который состоит из нескольких сервисов, настройка проекта в целом занимала очень долгое время. Помню когда мы наняли первого стороннего разработчика, настройка его рабочего места заняла практически день. Теперь, новый человек, который приходит в проект получает рабочее место в пределах часа.  В качестве дополнительного бонуса, все работы для быстрого разворачивания пригодились в CI сервере. 

Итак что за софт у меня теперь? 
  1. docker
  2. docker-compose
  3. ant который идет в idea, просто для удобства
У меня теперь нет даже php, несмотря на то, что я веду несколько проектов на нем. У меня нет python3.4, python3.5, хотя все остальные проекты на нем. И даже python 2.7 который есть в системе я не трогаю для своих целей. 

А развертывание вышеупомянутого проекта из нескольких сервисов занимает несколько минут ожидания выкачивания образов.  

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

Теория


Итак основы.  Я не собираюсь подробно расписывать все возможности. Сосредоточусь на минимуме, которого хватит для его использования при разработке.
  1. docker - это демон который позволяет запускать из образов (images) процессы (контейнеры, containers)
  2. image - образ для запуска процессов ( контейнеров). Состоит из набора файловых систем, которые наслаиваются друг на друга, образуя единую файловую систему. Слои обычно выглядят как
    1. Операционная система.
    2. Библиотеки
    3. Программа. 
  3. container - процесс запущенный на основе образа. По умолчанию все запущенные контейнеры живут в отдельной подсети созданной демоном докера. 

Программисту, возможно, будет проще воспринимать image как класс, а container как объект созданный из класса (образа).  Отсюда все можно делать простые выводы, два контейнера запущенные из одного образа - независимы, но при запуске имеют одинаковую файловую систему.

Важно! docker image может базироваться на любой операционной системе, никто вам не помешает запускать docker image memcached на основе debian stable из вашей операционной системы, пусть у вас будет ubuntu или slackware. memcached запущенный внутри докера будет считать что он работает из под debian. 

Основные команды. 

1. Запуск контейнера, например нам нужен memcached 1.4  для работы. (!!!! минимум 132 Мб будет скачено)

docker run  -d memcached:1.4
82a90b065744f43fa2efd8f00fece0faeacc53c7d306cc54b137482728d8c9bb
-d Говорит докеру чтобы он запустил новый контейнер в фоновом режиме, без этой опции контейнер будет запущен, а ваш терминал будет получать stdout/stderrs от запущенного контейнера.

Мы запустили контейнер с memcached сервисом, из образа memcache версии 1.4 который докер будет искать в публичном репозитории докера. Если образа не было в системе, он скачается. 

2. Скачать образ 

docker pull memcached:1.4

Команда
docker pull memcached 
Эквивалентна
docker pull memcached:latest 
Т.к. latest это версия используемая по умолчанию. 

3. Список запущенных контейнеров

docker ps 

CONTAINER ID        IMAGE                                   COMMAND  ....
82a90b065744        memcached:1.4                           "memcached"   ...

Важно! 82a90b065744 это ID созданного контейнера, у вас будет другой. И во все команды нужно будет подставлять именно ваш. 


4. Узнать подробности о запущенном контейнере 

docker inspect 82a90b065744 | less

В частности нас интересует  "IPAddress": "172.17.0.89". (У вас будет другой)

Также ip запущенного контейнера можно получить при помощи команды 
docker inspect --format '{{ .NetworkSettings.IPAddress }}' 82a90b065744
Проверяем этот адрес 

cd:$ telnet 172.17.0.89 11211
Trying 172.17.0.89...
Connected to 172.17.0.89.
Escape character is '^]'.
set key 0 900 4
data
STORED
get key
VALUE key 0 4
data
END
quit
Connection closed by foreign host.


Видим что memcached запущен и работает. 

5. Остановка контейнера

cd:$ docker stop 82a90b065744 
82a90b065744

6. Повторный запуск остановленного контейнера 
cd:$ docker start 82a90b065744
82a90b065744

7. Попадаем внутрь контейнера

cd:$ docker exec -it 82a90b065744 /bin/bash
memcache@82a90b065744:/$ ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

-i - интерактивный режим.
-t - прикрепить терминал 
/bin/bash команда внутри докера которую вы хотите запустить

8. Удаление контейнера (предварительно его нужно остановить)

cd:$ docker rm  82a90b065744
82a90b065744

Где искать образы? 

https://hub.docker.com/ отдавайте предпочтение официальным образам, либо образам крупных компаний, как правило они правильнее собраны и имеют меньший размер. 

Теперь мы умеем. 

1. Находить нужные образы
2. Скачивать нужные образы
3. Запускать контейнеры из образов
4. Попадать внутрь запущенного контейнера.
5. Останавливать контейнер


Практика:


Что нам дают эти знания?

1. У вас есть проект, который использует mysql, локально у вас установлен mysql5.3, ошибка воспроизводится на mysql 5.4.

Делаете дамп базы.
mysqldump mydatabasename -u myuser -pmypassword > projectname.dump.sql
Запускаете mysql5.4. из образа

docker run  -e MYSQL_ROOT_PASSWORD=root mysql:5.4

Образ mysql построен таким образом, что при создании контейнера, требуется переменная окружения MYSQL_ROOT_PASSWORD, для того чтобы установить пароль рута для базы.

-e ENV_NAME=env_value для команды run - создает переменную окружения ENV_NAME с указаным значением для запущенного контейнера.

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

находим id образа
docker ps
получаем его ip 
docker inspect --format '{{ .NetworkSettings.IPAddress }}' IDOFMYSQLCONTAINER
Внутри контейнера создаем базу данных, заливаем дамп, меняем настройки доступа - исправляем ошибку.

Уже одного этого более чем достаточно для того чтобы начать использовать docker : )

Какие еще преимущества нам дает? Пусть вы используете gentoo и mysql 5.3.  Ошибка воспроизводится на ubuntu 14.04 и mysql 5.3. Вы ищете образ сделанный на основе ubuntu 14.04 с установленным mysql5.3 запускаете контейнер и получаете mysql 5.3. работающий внутри ubuntu 14.04 на вашем ненаглядном gentoo.


В следующей статье я расскажу как используя этот набор знаний я упрощал себе работу, что нового узнал и какую проблему получил следующей.





 
Каталог сайтов, Добавить сайт