Первый релиз Кандидат в Docker 1.12 был объявлен более двух недель назад . В этом выпуске запланировано несколько новых функций.
В этом блоге будет показано, как создать пакет распределенных приложений из Docker Compose и развернуть его как стек Docker в режиме Docker Swarm. Большое спасибо @friism, чтобы помочь мне понять эти концепции.
Давайте сначала посмотрим на функции:
- Встроенная оркестровка . Типичное приложение определяется с помощью файла Docker Compose. Это определение состоит из нескольких контейнеров и развернуто на нескольких хостах. Это позволяет избежать единой точки отказа (SPOF) и обеспечивает устойчивость вашего приложения. Множество структур оркестровки, таких как Docker Swarm, Kubernetes и Mesos, позволяют вам управлять этими приложениями. Однако это очень важная характеристика приложения, теперь в Docker Engine встроена оркестровка. Подробнее об этой теме в более позднем блоге.
- Сервис : реплицированный, распределенный сервис с балансировкой нагрузки может быть легко создан с помощью команды
docker service create. Предоставляется «желаемое состояние» приложения, такое как запуск 3 контейнеров Couchbase, а самовосстанавливающийся механизм Docker гарантирует, что в кластере работает много контейнеров. Если контейнер выходит из строя, запускается другой контейнер. Если узел выходит из строя, контейнеры на этом узле запускаются на другом узле. Подробнее об этом позже. - Безопасность с нулевой конфигурацией : Docker 1.12 поставляется с взаимно аутентифицированным TLS, обеспечивая аутентификацию, авторизацию и шифрование для связи каждого узла, участвующего в рое, из коробки. Подробнее об этом позже.
- Стек Docker и пакет распределенных приложений. Пакет распределенных приложений, или DAB, представляет собой формат многоадресного распространяемого образа. Читайте дальше для более подробной информации.
Пока что вы можете взять Dockerfile и создать из него образ, используя команду docker build . Контейнер можно запустить с помощью команды docker run . Несколько контейнеров можно легко запустить, дав эту команду несколько раз. Или вы также можете использовать файл Docker Compose и масштабировать ваши контейнеры с помощью команды docker-compose scale .
Изображение — это переносимый формат для одного контейнера. Распределенный пакет приложений , или DAB, — это новая концепция, представленная в Docker 1.12, представляющая собой переносимый формат для нескольких контейнеров. Каждый пакет может быть развернут как стек во время выполнения.
Узнайте больше о DAB на docker.com/dab .
Для простоты можно привести аналогию:
Dockerfile -> Изображение -> Контейнер
Docker Compose -> Комплект распределенных приложений -> Стек Docker
Давайте используем файл Docker Compose, создадим из него DAB и развернем его как стек Docker.
Важно отметить, что это экспериментальная функция в 1.12-RC2.
Создать распределенный пакет приложений из Docker Compose
Docker Compose CLI добавляет новую команду bundle . Более подробную информацию можно найти:
|
01
02
03
04
05
06
07
08
09
10
11
|
docker-compose bundle --helpGenerate a Docker bundle from the Compose file. Local images will be pushed to a Docker registry, and remote imageswill be pulled to fetch an image digest. Usage: bundle [options] Options: -o, --output PATH Path to write the bundle file to. Defaults to ".dsb". |
Теперь давайте возьмем определение Docker Compose и создадим из него DAB. Вот наше определение Docker Compose:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
version: "2"services: db: container_name: "db" image: arungupta/oreilly-couchbase:latest ports: - 8091:8091 - 8092:8092 - 8093:8093 - 11210:11210 web: image: arungupta/oreilly-wildfly:latest depends_on: - db environment: - COUCHBASE_URI=db ports: - 8080:8080 |
Этот Compose файл запускает WildFly и сервер Couchbase. Приложение Java EE предварительно развернуто на сервере WildFly, который подключается к серверу Couchbase и позволяет выполнять операции CRUD с использованием REST API.
Источник этого файла: github.com/arun-gupta/oreilly-docker-book/blob/master/hello-javaee/docker-compose.yml .
Создайте пакет приложений с ним:
|
1
2
3
4
|
docker-compose bundleWARNING: Unsupported key 'depends_on' in services.web - ignoringWARNING: Unsupported key 'container_name' in services.db - ignoringWrote bundle to hellojavaee.dsb |
depends_on только создает зависимость между двумя сервисами и заставляет их запускаться в определенном порядке. Это только обеспечивает запуск контейнера Docker, но запуск приложения в контейнере может занять больше времени. Так что этот атрибут только частично решает проблему. container_name дает конкретное имя для контейнера. Опора на конкретное имя контейнера является жесткой связью и не позволяет масштабировать контейнер. Таким образом, оба предупреждения можно пока игнорировать.
Эта команда создает файл, используя имя проекта Compose, которое является именем каталога. В нашем случае hellojavaee.dsb файл hellojavaee.dsb . Это расширение файла было переименовано в .dab в RC3.
Сгенерированный пакет приложений выглядит так:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
{ "services": { "db": { "Image": "arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c", "Networks": [ "default" ], "Ports": [ { "Port": 8091, "Protocol": "tcp" }, { "Port": 8092, "Protocol": "tcp" }, { "Port": 8093, "Protocol": "tcp" }, { "Port": 11210, "Protocol": "tcp" } ] }, "web": { "Env": [ "COUCHBASE_URI=db" ], "Image": "arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914", "Networks": [ "default" ], "Ports": [ { "Port": 8080, "Protocol": "tcp" } ] } }, "version": "0.1"} |
Этот файл содержит полное описание услуг, включенных в приложение. Я не совсем уверен, является ли Distributed Application Bundle наиболее подходящим именем, обсудите это в # 24250 . Было бы здорово, если бы здесь могли поддерживаться другие форматы контейнеров, такие как Rkt или даже виртуальные машины. Но на данный момент Docker — единственный поддерживаемый формат.
Инициализировать Swarm Mode в Docker
Как упоминалось выше, «желаемое состояние» теперь поддерживается Docker Swarm. И это уже запечено в Docker Engine.
Концепции Docker Swarm также развивались и могут быть прочитаны в ключевых концепциях режима Swarm . Более подробный блог об этом будет позже.
Но для этого блога добавлена новая команда docker swarm :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
docker swarm --help Usage: docker swarm COMMAND Manage Docker Swarm Options: --help Print usage Commands: init Initialize a Swarm join Join a Swarm as a node and/or manager update Update the Swarm leave Leave a Swarm inspect Inspect the Swarm Run 'docker swarm COMMAND --help' for more information on a command. |
Инициализируйте узел Swarm (как рабочий) в Docker Engine:
|
1
2
|
docker swarm initSwarm initialized: current node (ek9p1k8r8ox7iiua5c247skci) is now a manager. |
Более подробную информацию об этом узле можно найти с помощью команды docker swarm inspect .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
docker swarm inspect[ { "ID": "1rcvu7m9mv2c8hiaijr7an9zk", "Version": { "Index": 1895 }, "CreatedAt": "2016-07-01T23:52:38.074748177Z", "UpdatedAt": "2016-07-02T04:54:32.79093117Z", "Spec": { "Name": "default", "AcceptancePolicy": { "Policies": [ { "Role": "worker", "Autoaccept": true }, { "Role": "manager", "Autoaccept": false } ] }, "Orchestration": { "TaskHistoryRetentionLimit": 10 }, "Raft": { "SnapshotInterval": 10000, "LogEntriesForSlowFollowers": 500, "HeartbeatTick": 1, "ElectionTick": 3 }, "Dispatcher": { "HeartbeatPeriod": 5000000000 }, "CAConfig": { "NodeCertExpiry": 7776000000000000 } } }] |
Вывод показывает, что узел является только работником, а не менеджером. Это может быть хорошо, если кластер имеет один узел. Но в многоузловом кластере должен быть хотя бы менеджер.
Развертывание стека докеров
Создайте стек с помощью команды docker deploy :
|
1
2
3
4
5
|
docker deploy -f hellojavaee.dsb hellojavaeeLoading bundle from hellojavaee.dsbCreating network hellojavaee_defaultCreating service hellojavaee_dbCreating service hellojavaee_web |
Использование команды, безусловно, может быть упрощено, как описано в # 24249 .
Смотрите список услуг:
|
1
2
3
4
|
docker service lsID NAME REPLICAS IMAGE COMMAND2g8kmrimztes hellojavaee_web 1/1 arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914 46xhlb15cc60 hellojavaee_db 1/1 arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c |
Вывод показывает, что запущены две службы, WildFly и Couchbase. Сервисы — это также новая концепция, представленная в Docker 1.12. Есть то, что дает вам «желаемое состояние», и Docker Engine работает, чтобы дать вам это.
docker ps показывает список запущенных контейнеров:
|
1
2
3
|
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES622756277f40 arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c "/entrypoint.sh /opt/" 3 seconds ago Up 1 seconds 8091-8093/tcp, 11207/tcp, 11210-11211/tcp, 18091-18092/tcp hellojavaee_db.1.19enwdt6i5m853m5675tx3z29abf8703ed713 arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914 "/opt/jboss/wildfly/b" 3 seconds ago Up 1 seconds 8080/tcp hellojavaee_web.1.70piloz6j4zt06co8htzisgyl |
Контейнер WildFly запускается до запуска и запуска контейнера Couchbase. Это означает, что приложение Java EE пытается подключиться к серверу Couchbase и терпит неудачу. Таким образом, приложение никогда не загружается успешно.
Докер Сервис
Docker Service поддерживает «желаемое состояние» приложения. В нашем случае желаемое состояние — убедиться, что запущен один и только один контейнер для службы. Если мы удалим контейнер, а не службу, то служба автоматически запустит контейнер снова.
Удалить контейнер как:
|
1
|
docker rm -f abf8703ed713 |
Обратите внимание, вы должны -f поскольку контейнер уже запущен. Механизмы самовосстановления Docker 1.12 включаются и автоматически перезапускают контейнер. Теперь, если вы снова перечислите контейнеры
|
1
2
3
|
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESdb483ac27e41 arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914 "/opt/jboss/wildfly/b" 1 seconds ago Up Less than a second 8080/tcp hellojavaee_web.1.ddvwdmojjysf46d4n3x4g8uv4622756277f40 arungupta/oreilly-couchbase@sha256:f150fcb9fca5392075c96f1baffc7f893858ba763f3c05cf0908ef2613cbf34c "/entrypoint.sh /opt/" 26 seconds ago Up 25 seconds 8091-8093/tcp, 11207/tcp, 11210-11211/tcp, 18091-18092/tcp hellojavaee_db.1.19enwdt6i5m853m5675tx3z29 |
Это показывает, что новый контейнер был запущен.
Проверьте сервис WildFly:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
docker service inspect hellojavaee_web[ { "ID": "54otfi6dc9bis7z6gc6ubynwc", "Version": { "Index": 328 }, "CreatedAt": "2016-07-02T01:36:35.735767569Z", "UpdatedAt": "2016-07-02T01:36:35.739240775Z", "Spec": { "Name": "hellojavaee_web", "Labels": { "com.docker.stack.namespace": "hellojavaee" }, "TaskTemplate": { "ContainerSpec": { "Image": "arungupta/oreilly-wildfly@sha256:d567ade7bb82ba8f15a85df0c6d692d85c15ec5a78d8826dfba92756babcb914", "Env": [ "COUCHBASE_URI=db" ] } }, "Mode": { "Replicated": { "Replicas": 1 } }, "Networks": [ { "Target": "epw57lz7txtfchmbf6u0cimis", "Aliases": [ "web" ] } ], "EndpointSpec": { "Mode": "vip", "Ports": [ { "Protocol": "tcp", "TargetPort": 8080 } ] } }, "Endpoint": { "Spec": {}, "Ports": [ { "Protocol": "tcp", "TargetPort": 8080, "PublishedPort": 30004 } ], "VirtualIPs": [ { "NetworkID": "9lpz688ir3pzexubkcb828ikg", "Addr": "10.255.0.5/16" }, { "NetworkID": "epw57lz7txtfchmbf6u0cimis", "Addr": "10.0.0.4/24" } ] } }] |
Swarm назначает случайный порт службе или может быть обновлен вручную с помощью команды docker service update . В нашем случае порт 8080 контейнера сопоставлен с портом 30004 на хосте.
Проверьте приложение
Убедитесь, что приложение успешно развернуто:
|
1
2
|
curl http://localhost:30004/books/resources/book[{"books":0}] |
Добавить новую книгу в приложение:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
curl -v \&qt; -H "Content-Type: application/json" \&qt; -X POST -d '{&qt; "isbn": "978-1-4919-1889-0",&qt; "name": "Minecraft Modding with Forge",&qt; "cost": 29.99&qt; }' \&qt; http://localhost:30004/books/resources/book* Trying ::1...* Connected to localhost (::1) port 30004 (#0)&qt; POST /books/resources/book HTTP/1.1&qt; Host: localhost:30004&qt; User-Agent: curl/7.43.0&qt; Accept: */*&qt; Content-Type: application/json&qt; Content-Length: 92&qt; * upload completely sent off: 92 out of 92 bytes<HTTP/1.1 200 OK<Connection: keep-alive<X-Powered-By: Undertow/1<Server: WildFly/10<Content-Type: application/octet-stream<Content-Length: 88<Date: Sat, 02 Jul 2016 01:39:49 GMT<* Connection #0 to host localhost left intact |
Проверьте книги еще раз:
|
1
2
|
curl http://localhost:30004/books/resources/book[{"books":{"name":"Minecraft Modding with Forge","cost":29.99,"id":"1","isbn":"978-1-4919-1889-0"}}, {"books":1}] |
Узнайте больше об этом приложении Java EE на github.com/arun-gupta/oreilly-docker-book/tree/master/hello-javaee .
В этом блоге показано, как создать пакет распределенных приложений из Docker Compose и развернуть его как стек Docker в режиме Docker Swarm.
| Ссылка: | Услуги Docker, стек и распределенные приложения от нашего партнера JCG Аруна Гупты в блоге Miles to go 3.0… . |

