Докер — действительно отличный инструмент, чтобы иметь под вашим поясом. Он используется многими разработчиками для облегчения процесса разработки. Мы сделали много тем для 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 при работе с большим количеством данных:
Это подтверждает, что мы можем получить доступ к нашему серверу 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:latest
debian:latest
Давайте удостоверимся, что у нас есть изображение на сервере. SSH на ваш сервер Docker (это, вероятно, только ваш локальный ящик) и запустите:
$ docker images
Совет: если вы загрузили много изображений, вы можете запустить:
$ docker images | grep ruby
Это теперь будет только список изображений, которые имеют слово ruby
Вывод может выглядеть примерно так:
ruby latest 2d43e11a3406 2 weeks ago 729.1 MB`
Показанная информация:
- Наименование хранилища
- Тег или версия изображения, это может быть указано в виде числа или имени, например
ruby:latest
ruby: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"])
Мы используем тот же метод exec
touch
sitepoint.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.