Введение
На этой неделе команда Docker анонсировала официальные базовые образы для Go и других основных языков, предоставляя разработчикам простой и надежный способ создания контейнеров для программ на Go.
В этой статье мы шаг за шагом пройдём создание Docker-контейнера для простого веб-приложения на Go а также деплой этого контейнера в Google Compute Engine. Если вы ещё не знакомы с Docker, вам следует прочесть статью Understanding Docker, прежде чем читать дальше.
Демо приложение
Для нашего примера мы будем использовать программу outyet из репозитория примеров Go, которая представляет собой простой веб-сервер, который сообщает, была ли выпущена следующая версия Go. Эта программа не имеет зависимостей кроме стандартной библиотеки и не требует никаких дополнительных файлов данных во время выполнения.
Используйте «go get» для загрузки и установки outyet в вашем рабочем окружении:
$ go get github.com/golang/example/outyet
Создаём Dockerfile
Создайте файл с именем Dockerfile в каталоге outyet со следующим содержимым:
# Start from a Debian image with the latest version of Go installed
# and a workspace (GOPATH) configured at /go.
FROM golang
# Copy the local package files to the container's workspace.
ADD . /go/src/github.com/golang/example/outyet
# Build the outyet command inside the container.
# (You may fetch or manage dependencies here,
# either manually or with a tool like "godep".)
RUN go install github.com/golang/example/outyet
# Run the outyet command by default when the container starts.
ENTRYPOINT /go/bin/outyet
# Document that the service listens on port 8080.
EXPOSE 8080
Этот Dockerfile указывает, как собрать контейнер, который будет исполнять outyet, начиная с базовых зависимостей (системы Debian с установленным Go, официального образа golang). и заканчивая исходными кодами outyet, его сборкой, и, наконец, запуском.
Шаги ADD, RUN, и ENTRYPOINT являются общими для любого проекта Go. Есть вариант проще: onbuild из образа golang, который автоматически копирует исходный код пакета, подгружает зависимости приложения, собирает программу, и настраивает её для запуска при старте.
Если использовать onbuild-вариант, Dockerfile становится гораздо проще:
FROM golang:onbuild
EXPOSE 8080
Сборка и запуск образа
Вызовите docker из каталога приложения чтобы собрать образ из Dockerfile:
$ docker build -t outyet .
При этом будет взят базовый образ golang Docker Hub'a, содержимое приложения будет скопировано в него. Итоговый образ будет помечен тегом outyet.
Чтобы запустить контейнер с созданным образом выполним команду:
$ docker run --publish 6060:8080 --name test --rm outyet
Флаг --publish
говорит Docker'у, что необходимо пробросить порт 8080 из контейнера на 6060 в хост-системе.
Флаг --name
дает нашему контейнеру указанное имя, чтобы облегчить последующую работу с ним.
Флаг --rm
сообщает, что нужно удалить контейнер по завершении его работы.
Запустите контейнер и откройте в браузере адрес localhost:6060/. Вы должны увидеть нечто подобное:
(Если Docker запущен на другой машине (или в виртуальной машине), вы должны заменить localhost адресом этой машины. Если вы используете boot2docker на OS X или Windows, вы можете найти этот адрес с помощью boot2docker ip
.
Теперь, когда мы убедились, что образ работает, давайте закроем работающий контейнер из другого окна терминала:
$ docker stop test
Создание репозитария в Docker Hub
Docker Hub, репозитарий контейнеров, из которого мы до этого взяли образ golang, имеет функцию Автоматической сборки, которая может собирать образ из репозитариев на GitHub или BitBucket.
После коммита Dockerfile'а в репозитарий и создания автоматической сборки для него, любой, у кого установлен Docker, может скачать и запустить наш образ всего одной командой. (Мы увидим насколько это полезно в следующем разделе.)
Чтобы настроить автоматическую сборку, нужно закоммитить Dockerfile в ваш репозитарий на GitHub или BitBucket, создать учетную запись на Docker Hub, и выполнить все инструкции по созданию автоматизированной сборки.
Когда все будет готово, вы сможете запустить свой контейнер, используя имя автоматизированной сборки:
$ docker run goexample/outyet
(Замените goexample/outyet на имя автоматизированной сборки, которую вы создали)
Развертывание контейнера в Google Compute Engine
Google предоставляет оптимизированные для контейнеров образы Google Compute Engine, которые позволяют легко поднять виртуальную машину, которая будет работать с произвольным Docker-контейнером. При запуске, запущеная программа читает конфигурационный файл, который определяет, какой контейнер нужно запустить, получает образ контейнера, и запускает его.
Создайте файл containers.yaml, который определяет, какой Docker-образ нужно запустить и какие порты пробросить:
version: v1beta2
containers:
- name: outyet
image: goexample/outyet
ports:
- name: http
hostPort: 80
containerPort: 8080
Обратите внимание, что мы пробрасываем порт контейнера 8080 на внешний 80 порт, порт по умолчанию для обслуживания HTTP трафика. И, опять же, вы должны заменить goexample/outyet на имя вашей автоматической сборки.
Используйте gcloud, чтобы создать экземпляр виртуальной машины для контейнера:
$ gcloud compute instances create outyet
--image container-vm-v20140826
--image-project google-containers
--metadata-from-file google-container-manifest=containers.yaml
--tags http-server
--zone us-central1-a
--machine-type f1-micro
Первый аргумент (outyet) задает имя экземпляра, которое впоследствии будет удобно использовать для административных целей.
Флаги --image
и --image-project
задают специальный контейнер-оптимизированный образ системы (просто скопируйте эти флаги дословно).
Флаг --metadata-from-file
передаёт файл containers.yaml в виртуальную машину.
Флаг --tags
помечает экземпляр ВМ как HTTP-сервер, сообщая брандмауэру, что нужно открыть 80 порт.
Флаги --zone
и --machine-type
флаги указать зону, в которой нужно запустить ВМ и тип машины. (Чтобы увидеть список типов машин и зон, выполните gcloud compute machine-types
)
По завершении работы команда gcloud должна вывести информацию о созданном экземпляре. В выводе найдите секцию networkInterfaces
, там будет указан IP-адрес экземпляра ВМ. Через пару минут у вас должно получиться открыть этот IP через браузер и увидеть: «Has Go 1.4 been released yet?»
(Чтобы увидеть, что происходит в виртуальной машине, вы можете подключиться к ней по SSH с помощью gcloud compute ssh outyet
. Перейдя туда, попробуйте выполнить sudo docker ps
чтобы увидеть, какие Docker-контейнеры работают)
Дополнительная информация
То, что мы сделали — только верхушка айсберга и вы можете сделать ещё много со связкой Go, Docker, и Google Compute Engine.
- Чтобы узнать больше о Docker, посмотрите их подробную документацию.
- Чтобы узнать больше о Docker и Go, взгляните на официальный репозитарий golang в Docker Hub.
- Чтобы узнать больше о Docker и Google Compute Engine, посмотрите страницу Container-optimized VM и репозитарий google/docker-registry.
Andrew Gerrand
От переводчика: все замечания по точности перевода, орфографии и стилистике, пожалуйста передавайте через личные сообщения. Буду рад поправить.
Автор: prg