Статьи

Автоматизируйте Docker с помощью Remote API и Ruby

docker_logo

Докер — действительно отличный инструмент, чтобы иметь под вашим поясом. Он используется многими разработчиками для облегчения процесса разработки. Мы сделали много тем для Docker, вы можете проверить их здесь . Если вы еще не установили Docker на свой компьютер, вы можете узнать, как с помощью этих статей или на сайте Docker .

В этом посте я расскажу об удаленном API Docker . Если вы использовали Docker до этого момента, то, скорее всего, через интерфейс командной строки, который на самом деле является клиентом, использующим Remote API. Кстати, я предполагаю, что вы понимаете все основы Docker. Если нет, пожалуйста, прочитайте статьи, на которые я ссылаюсь выше.

Прежде чем мы сможем взаимодействовать с API, мы должны настроить Docker для прослушивания определенного порта TCP. Давайте отредактируем конфигурационный файл Docker:

Путь: /etc/init/docker.conf

Добавьте эту строку:

 DOCKER_OPTS='-H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock'

Перезапустите докер:

 service docker restart

Теперь мы можем подключиться к нашему серверу Docker через порт 4243 . Давайте проверим наше соединение с сервером, прежде чем продолжить. Это можно сделать с помощью инструмента командной строки curl

 curl -X GET http://139.59.148.228:4243/images/json

Это напечатает все изображения, которые мы имеем на нашем сервере Docker. Я предпочитаю использовать клиент REST при работе с большим количеством данных:

RESTClient дополнение для Firefox

RESTClient дополнение для Firefox

Это подтверждает, что мы можем получить доступ к нашему серверу Docker.

Рубин

Давайте перейдем к части Ruby. Мы собираемся использовать драгоценный камень docker-api . Это позволит нам иметь объектно-ориентированный интерфейс к Docker Remote API.

Мы можем установить его прямо с нашего терминала:

 gem install docker-api

Или добавьте его в Gemfile:

 gem "docker-api" # followed by a `bundle install`

Мы будем использовать IRB (Interactive Ruby Shell) на протяжении всего урока, но любой из примеров можно сделать в файле Ruby.

Первый шаг — импортировать камень docker-api:

 require 'docker-api'

Направьте его на наш докер-сервер:

 Docker.url = 'tcp://139.59.148.228:4243/'

Давайте проверим наше соединение сейчас, это можно легко сделать с помощью метода version:

 Docker.version
 => {"Version"=>"1.11.1", "ApiVersion"=>"1.23", "GitCommit"=>"5604cbe", "GoVersion"=>"go1.5.4", "Os"=>"linux", "Arch"=>"amd64", "KernelVersion"=>"3.13.0-85-generic", "BuildTime"=>"2016-04-26T23:30:23.291099901+00:00"}

Сервер отвечает некоторой информацией для хост-системы сервера Docker. Если вы получаете сообщение об ошибке «Отказано в соединении», например:

 Excon::Errors::SocketError: Connection refused - connect(2) for 139.59.148.228:42432 (Errno::ECONNREFUSED)

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

Docker Images

Управлять изображениями очень просто:

 image = Docker::Image.create('fromImage' => 'rails:4.2')

Это может занять некоторое время, в зависимости от сетевого подключения, оно получит образ Rails из Docker Hub .

Здесь нужно кое-что заметить: мы разделяем Rails и версию (4.2), которую мы хотим. Это соглашение об именах и тегах образов Docker, которое работает для многих других образов докеров, таких как ruby:latestdebian:latest

Давайте удостоверимся, что у нас есть изображение на сервере. SSH на ваш сервер Docker (это, вероятно, только ваш локальный ящик) и запустите:

 $ docker images

Совет: если вы загрузили много изображений, вы можете запустить:

 $ docker images | grep ruby

Это теперь будет только список изображений, которые имеют слово ruby Вывод может выглядеть примерно так:

 ruby                latest               2d43e11a3406        2 weeks ago         729.1 MB`

Показанная информация:

  • Наименование хранилища
  • Тег или версия изображения, это может быть указано в виде числа или имени, например ruby:latestruby:1-wheezy
  • ID изображения
  • Дата создания
  • размер .

Это подтверждает, что мы успешно потянули изображение. Теперь давайте посмотрим, какие изображения мы имеем на нашем сервере Docker через API. Если мы выполним метод Image.all

 Docker::Image.all
=> [#<Docker::Image:0x00000001834e28 @id="sha256:299e53ed9d2a9d07391855b2f49a823af145c1cf66bd711968b3b2ccc29d49d8", @info={"ParentId"=>"", "RepoTags"=>["rails:4.2"], "RepoDigests"=>nil, "Created"=>1464136334, "Size"=>837203335, "VirtualSize"=>837203335, "Labels"=>{}, "id"=>"sha256:299e53ed9d2a9d07391855b2f49a823af145c1cf66bd711968b3b2ccc29d49d8"}, @connection=#<Docker::Connection:0x0000000176c6f8 @url="tcp://139.59.148.228:4243/", @options={}>>, #<Docker::Image:0x00000001834cc0 @id="sha256:31e17b0746e48958b27f1d3dd4fe179fbba7e8efe14ad7a51e964181a92847a6", @info={"ParentId"=>"", "RepoTags"=>["tutum/hello-world:latest"], "RepoDigests"=>nil, "Created"=>1450109804, "Size"=>17791668, "VirtualSize"=>17791668, "Labels"=>nil, "id"=>"sha256:31e17b0746e48958b27f1d3dd4fe179fbba7e8efe14ad7a51e964181a92847a6"}, @connection=#<Docker::Connection:0x0000000176c6f8 @url="tcp://139.59.148.228:4243/", @options={}>>]

Контейнеры

Создание и запуск экземпляров этих изображений в виде контейнеров также возможно:

 container = Docker::Container.create('Image' => 'ubuntu', 'Tty' => true)

Это создаст контейнер с образом Ubuntu, который мы имеем на нашем сервере. Обратите внимание на 'Tty' => true Если мы не добавим параметр Tty

 => #<Docker::Container:0x000000025f6bb0 @id="5bbf21e99459052a816cd74006aec00a53cf9bd0814d5517804257a5869f3329", @info={"Warnings"=>nil, "id"=>"5bbf21e99459052a816cd74006aec00a53cf9bd0814d5517804257a5869f3329"}, @connection=#<Docker::Connection:0x00000002541b98 @url="tcp://139.59.148.228:4243/", @options={}>>

Контейнер создан, нам нужно его запустить:

 container.start

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

 $ docker ps
ba13a1bfb728        ubuntu              "/bin/bash"              1 minutes ago       Up 52 seconds                           pedantic_torvalds

Мы подтвердили, что наш контейнер Docker работает. Теперь из API вернемся в irb

 container.top
=> [{"UID"=>"root", "PID"=>"28267", "PPID"=>"28248", "C"=>"0", "STIME"=>"12:43", "TTY"=>"pts/5", "TIME"=>"00:00:00", "CMD"=>"/bin/bash"}]

Мы получаем упрощенное возвращаемое значение, представляющее работающий контейнер. Есть также некоторые другие методы, которые вы можете использовать для остановки, перезапуска и приостановки работы контейнера. Проверьте документацию для более подробной информации о них.

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

Что если у нас есть существующий контейнер, и мы хотим присоединить к нему? Просто запросите контейнер по ID или имени:

 container = Docker::Container.get('500f53b25e6e')

Это позволит получить контейнер с помощью идентификатора. Если мы хотим запросить его по имени, сначала запустите команду docker ps

CONTAINERID ОБРАЗ КОМАНДА СОЗДАНО ПОЛОЖЕНИЕ ДЕЛ ПОРТЫ ИМЕНА
5e2ff2107855 Рельсы: 4,2 «ЭСО» 4 дня назад До 4 дней sick_austin

В этом примере, если мы хотим запросить наш контейнер rails, его имя — sick_austin . Имя всегда будет отличаться, даже если у вас есть два контейнера с одного изображения. Каждый контейнер будет иметь другое имя.

 container = Docker::Container.get('sick_austin')

Это напечатает много информации обратно о контейнере; какая версия ruby ​​у нас работает, версия пакета и даже информация о сети.

Теперь мы можем легко остановить контейнер (пока не делайте этого… у нас еще есть работа):

 container.stop

Мы также можем передавать команды в контейнер и перехватывать вывод, например, команду ls

 container.exec(['ls'])
[["bin\nboot\ndev\netc\nhome\nlib\nlib64\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nsrv\nsys\ntmp\nusr\nvar\n"], [], 0]`

Создание изображения из контейнера

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

Во-первых, давайте внесем изменения в наш контейнер. В нашем примере мы создали этот действительно важный файл конфигурации с именем sitepoint.conf .

 container.exec(["touch", "sitepoint.conf"])

Мы используем тот же метод exectouchsitepoint.conf touch

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

 container.exec(["ls")
[["bin\nboot\ndev\netc\nhome\nlib\nlib64\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nsitepoint.conf\nsrv\nsys\ntmp\nusr\nvar\n"], [], 0]

Мы видим, что sitepoint.conf указан на нашем сервере:

Создание изображения

Метод commit

 container.commit

Теперь, если мы перечислим наши изображения докера, мы увидим наше новое изображение. Я делаю это через сессию SSH для лучшего предварительного просмотра:

 $ docker images

Который вернется:

СКЛАД ТЕГ ID ИЗОБРАЖЕНИЯ СОЗДАНО РАЗМЕР
<Никто> <Никто> «8eee633c7cb6» 2 секунды назад 837,2 МБ
рельсы 4,2 «299e53ed9d2a» 3 недели назад 837,2 МБ
рельсы 4,2 «299e53ed9d2a» 3 недели назад 837,2 МБ
убунту самый последний «2fa927b5cdd3» 3 недели назад 122 МБ
рельсы 4,2 «299e53ed9d2a» 3 недели назад 837,2 МБ

Сверху — скопированное изображение нашего контейнера, которое можно узнать по дате его создания. Кроме того, нет репозитория или тега для вновь созданного изображения.

Создайте новый контейнер, который запускает приглашение bash, используя новый идентификатор изображения:

 $ docker run -i -t 8eee633c7cb6 /bin/bash

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

 $ ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  sitepoint.conf  srv  sys  tmp  usr  var

Там файл sitepoint.conf , живой и здоровый. Это подтверждает, что мы создали новый контейнер из изображения, которое мы создали выше.

Вывод

Доступ к нашему серверу Docker из разных сред может помочь в автоматизации нашего рабочего процесса. Это позволяет создавать креативные решения и новые идеи для Docker. Есть еще некоторые вещи, которые необходимо охватить, такие как защита соединения с API, вы можете прочитать об этом здесь . Теперь перейдите и автоматизируйте рабочий процесс Docker, используя Ruby и Remote API.