Docker существует только с 2013 года, но, похоже, это все в моем твиттере и RSS-ридере. В прошлом я рассматривал пример «Привет, мир!», Но никогда не чувствовал, что действительно понимаю или ценностное предложение, или как именно оно работает. На этой неделе у меня было время сесть и уделить этому больше внимания. Я обнаружил, что это было не так таинственно и не так сложно, как я ожидал.
Установка на Mac
Docker родился в Linux и использует внутреннюю часть Linux, такую как LXC, чтобы творить чудеса. Есть родная версия Windows в работах (не то, чтобы кто-то заботился). Но, учитывая, что в разработке программного обеспечения в Bay Area доминируют Mac, давайте начнем с того, как установить и запустить его на OSX.
Прежде всего, не пытайтесь установить его через brew
какой-либо другой менеджер пакетов. Docker написан на Go, который имеет преимущество компиляции в бинарные файлы без зависимостей. Кроме того, проект движется так быстро, что версии в менеджерах пакетов устарели. Итак, смиритесь с этим и установите его вручную, загрузив бинарный файл .
Если вы можете открыть терминал и запустить docker --version
, все в порядке. Это руководство для версии 1.5.0.
Boot2Docker
Если вы попытаетесь запустить образ докера сейчас, вы получите загадочную ошибку, например docker max dial unix /var/run/docker.sock: no such file or directory
. Это потому, что процесс демона Docker не запущен. На самом деле, он не может работать на Mac! Вместо этого вы должны использовать boot2docker , крошечную виртуальную машину, которая работает в VirtualBox и имеет демон Docker. Опять же, используйте бинарный установщик (извините!).
Чтобы начать работу, откройте терминал и запустите следующее.
boot2docker init boot2docker up eval "$(boot2docker shellinit)" docker run ubuntu:14.04 /bin/echo 'Hello world'
Это твой привет пример мира. Давайте разберемся, что здесь происходит. boot2docker init
создает новую виртуальную машину в VirtualBox.
Следующим шагом boot2docker up
запускается виртуальная машина. На этом eval "$(boot2docker shellinit)"
шаге устанавливаются некоторые переменные окружения, которые сообщают Docker, в каком контексте контейнера вы находитесь в данный момент. Если вы запустите один boot2docker shellinit
, вы увидите необработанный вывод:
Writing /Users/chase/.boot2docker/certs/boot2docker-vm/ca.pem Writing /Users/chase/.boot2docker/certs/boot2docker-vm/cert.pem Writing /Users/chase/.boot2docker/certs/boot2docker-vm/key.pem export DOCKER_HOST=tcp://192.168.59.104:2376 export DOCKER_CERT_PATH=/Users/chase/.boot2docker/certs/boot2docker-vm export DOCKER_TLS_VERIFY=1
Первые три строки являются только информационными, только последние три строки выводятся на стандартный вывод.
Последняя строка docker run ubuntu:14.04 /bin/echo 'Hello world'
фактически создает новый контейнер Docker (с использованием Ubuntu 14.04) и запускает внутри него одну команду.
Примечание о контейнерах
Контейнеры — это маленькие экземпляры Linux в песочнице. Изображения — это сериализованное определение файла, из которого создаются контейнеры. Волшебство Docker заключается в том, что изображения полностью переносимы. Эта концепция сначала ускользнула от меня. У меня сложилось впечатление, что вам нужно создать образ на своем Mac, чтобы запустить его там, а затем создать отдельный образ на Amazon EC2, чтобы запустить там то же самое.
Фактически вы можете создать образ на своем Mac, а затем, по сути, scp
этот файл до AWS и запустить его. На самом деле вам даже не нужно копировать его вручную, для этого предназначен Docker Hub.
Кроме того, дистрибутив Linux, используемый внутри вашего контейнера Docker, НЕ должен соответствовать дистрибутиву операционной системы хоста. Вы можете запустить Ubuntu внутри хоста CentOS, и наоборот.
Наконец, изображения имеют встроенный механизм наложения . По сути, вы можете иметь базовое изображение, а затем любое количество небольших слоев различий поверх этого. Это мощная оптимизация и абстракция, о которой мы поговорим позже.
Пример приложения Python Flask
Это каноническое учебное пособие для начинающих пользователей Python с Docker, и все же я не смог завершить успешно с какой-либо документацией, которую я нашел. Вот моя собственная специальная версия снежинки.
Сначала создайте новый каталог с именем flask
. Внутри вы собираетесь создать три файла.
Первый файл называется app.py
простым приложением Flask.
from flask import Flask import os app = Flask(__name__) @app.route('/') def hello(): return 'Hello World!' if __name__ == "__main__": app.run(host="0.0.0.0", debug=True)
Затем создайте requirements.txt
файл для отображения Flask как зависимости:
Flask==0.10.1
Наконец, создайте свой Dockerfile
:
FROM python:2.7 ADD . /code WORKDIR /code RUN pip install -r requirements.txt EXPOSE 5000 CMD python app.py
Давайте на минутку разберем этот последний файл. FROM
Строка сообщает Docker базировать этот контейнер от именованного изображения в общедоступном хранилище называется python
, и используйте именованный тег этим образом (вроде как редакция) 2.7
.
В ADD
линии копирует код из текущего каталога .
в /code
внутри экземпляра Docker контейнер Linux. WORKDIR
там же работает рабочая директория.
RUN
можно указать несколько раз. Он сообщает Docker, что нужно запускать эти команды при сборке контейнера в первый раз. Шаги выполнения на самом деле кэшируются; изменение одного из них позже приведет только к тому, что его снова запустят. Это возможно из-за расслоения контейнера, о котором мы говорили ранее.
EXPOSE
сообщает Docker, что контейнер будет обслуживать порт 5000 извне. Это порт, на котором мы будем запускать колбу.
Наконец, в CMD
строке указывается команда, которая будет запускаться внутри контейнера в качестве основного процесса демона. Если вам нужно несколько демонов, посмотрите в docker-compose .
Запустить его
Для запуска примера выполните следующие команды:
open "http://$(boot2docker ip):5000" docker build -t flask-example . docker run -it -p 5000:5000 -v $(pwd):/code:ro flask-example
Это должно было открыть вкладку браузера до появления колбы. Скорее всего, возникла ошибка «Эта веб-страница недоступна», но если вы обновите ее сейчас, вы должны увидеть свой «Hello World!» текст.
Что вы сделали, это создали именованное изображение flask-example
и запустите его. Вы даже можете отредактировать код в локальной файловой системе, и он синхронизируется с Docker (спасибо -v
) и колба перезапустится.
Запуск того же контейнера на AWS
Теперь давайте посмотрим, как запустить тот же контейнер в AWS. Сначала зайдите в Docker Hub . Это бесплатно.
Давайте предположим, что ваше имя пользователя Docker Hub foobar
. Сначала пересоберите и опубликуйте свой образ:
docker build -t foobar/flask-example . docker login docker push foobar/flask-example
Теперь создайте новый экземпляр EC2. Обязательно используйте базовый образ «Amazon Linux», что облегчит установку Docker. SSH в ваш экземпляр и запустите контейнер докера:
sudo yum install -y docker; sudo service docker start sudo docker run -it -p 8000:5000 foobar/flask-example
Первая строка просто устанавливает Docker и запускает его. Вторая строка извлекает ваше изображение из Docker Hub (примечание: не требуется аутентификация!), Запускает его в интерактивной оболочке и сопоставляет внешний порт 8000 на экземпляре EC2 хоста с портом 5000 внутри контейнера.
Если у вас настроена группа безопасности для предоставления доступа к порту 8000
, вы сможете открыть это общедоступное имя хоста EC2 на порту 8000 в веб-браузере.
Больше вещей
Когда я начинал с этим, я сделал ошибку, читая о и пытаясь использовать docker-compose
и docker-machine
сразу. Это официальные плагины, которые упрощают настройку мультисервисных и мультимашинных возможностей в Docker соответственно. Я предлагаю НЕ начинать с тех, пока вы не нажмете вышеупомянутые основы. Я обнаружил, что они омрачают мое понимание того, что происходит вначале.