Docker

Материал из Xgu.ru

Перейти к: навигация, поиск
Docker.png

Docker — opensource-приложение/проект/инфраструктура, позволяющая упаковывать, распространять, устанавливать и использовать opensource-приложения.

Приложения работают в изолированной среде (построенной с помощью пространств имён, namespaces, и групп процессов, cgroups), с одной стороны изолируя процессы друг от друга, с другой стороны не прибегая при этом к таким избыточным средствам как виртуализация или эмуляция.

Система написана на Go. Работает в различных UNIX/Linux-системах, ожидается, что в недалёком будущем будет поддерживаться и Windows.

Docker чаще всего использует различные системы виртуализации на уровне ОС, в настоящее время наибольшее распространение получила комбинация Docker + LXC, на которой он и был первоначально основан. Это привело к тому, что многие путают Docker и LXC, в действительности, естественно, это совершенно разные проекты с разными функциями.

В чём принципиальное отличие Docker от LXC:

http://stackoverflow.com/questions/17989306/what-does-docker-add-to-just-plain-lxc

Содержание

[править] Первые шаги

[править] Установить Docker

echo deb http://get.docker.io/ubuntu docker main | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
sudo apt-get update
sudo apt-get install -y lxc-docker

[править] Найти и установить контейнер

docker search tutorial
docker pull learn/tutorial

[править] Выполнить команды внутри контейнера

docker run apt-get update


Tip-icon.gif

Эти же команды можно выполнить с помощью скрипта:

 curl -sSL https://get.docker.com/ubuntu/

[править] Базовые операции с контейнерами

[править] Список контейнеров

 docker ps

[править] Просмотреть вывод контейнера

 docker logs

В режиме tail -f:

 docker logs -f

[править] Просмотреть конфигурацию контейнера

Просмотреть конфигурацию контейнера в JSON-формате:

 docker inspect container_name

Просмотреть отдельную часть конфигурации/переменную:

 docker inspect -f '{{ .NetworkSettings.IPAddress }}' container_name

[править] Основные команды по работе с контейнерами (Docker cheatsheet)

Источник: https://github.com/wsargent/docker-cheat-sheet Github.png

[править] Жизненный цикл

docker create
создать контейнер, но не запускать его
docker run
создать и запустить контейнер
docker stop
остановить контейнер
docker start
запустить существующий остановленный контейнер
docker restart
перезапустить контейнер
docker rm
удалить контейнер
docker kill
отправить сигнал SIGKILL контейнеру
docker attach
подключиться к работающему контейнеру
docker wait
блокировать команду и ждать, пока контейнер не остановится

[править] Информация о контейнерах

docker ps
показать работающие контейнеры (или вообще контейнеры, если использовать дополнительные опции)
docker inspect
показать всю информацию о контейнере, включая IP-адреса
docker logs
показать лог-вывод контейнера
docker events
показать события контейнера
docker port
показать открытые наружу порты контейнера
docker top
показать процессы, работающие внутри контейнера
docker stats
показать статистику использования ресурсов контейнером
docker diff
показать изменённые файлы в файловой системе контейнера

[править] Импорт/экспорт

   docker cp copies files or folders out of a container's filesystem.
   docker export turns container filesystem into tarball archive stream to STDOUT.


[править] Выполнение команд

   docker exec to execute a command in container.

[править] Создание контейнера / докеризация приложения

Рассмотрим, как можно создать docker-контейнер, в котором будет работать flask-приложение. Потом сделаем приложение доступным через nginx-сервер, работающий в отдельном контейнере.

[править] Создание Docker-файла

FROM python:2.7

RUN mkdir -p /code
COPY . /code
VOLUME [ "/code" ]
WORKDIR /code
RUN pip install -r requirements.txt
EXPOSE 5000
CMD [ "python", "/code/app.py" ]

В текущем каталоге должны быть размещены:

app.py

from flask import Flask
from redis import Redis
import os
app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    redis.incr('hits')
    return 'Hello World! I have been seen %s times.' % redis.get('hits')

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

requirements.txt

flask
redis

[править] Сборка образа

 docker build -t flaskapp .

[править] Запуск контейнера с новым образом

 docker run -d -P --name flaskapp flaskapp

Просмотреть, работает ли контейнер, и на каком порту он доступен:

 $ sudo docker ps
 CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                     NAMES
 0c8339084e07        flaskapp:latest     "python /code/app.py   5 seconds ago       Up 3 seconds        0.0.0.0:49154->5000/tcp   flaskapp            

Если обратиться на порт 49154 хост-системы, будет получен доступ к приложению, работающему внутри контейнера.

Поскольку наше приложение использует для своей работы внешний сервис (redis), нам потребуется контейнер с redis, который будет подключен к этому контейнеру.

 docker rm -f flaskapp
 docker run -d --name redis redis
 docker run -d -P --name flaskapp --link redis:redis flaskapp

Теперь нашему приложению доступен Redis-сервер.

[править] Подключить дополнительные образы

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

Создадим nginx-контейнер, который является сетевым фронтендом для flask-приложения.

Создадим конфигурационный файл nginx назовём flaskapp.conf:

server {
    listen 80;

    location / {
        proxy_pass http://flaskapp:5000;
    }
}

Создадим Dockerfile:

FROM nginx:1.7.8
COPY flaskapp.conf /etc/nginx/conf.d/default.conf

После этого нужно построить и запустить образ:

  docker build -t nginx-flask .
  docker run --name nginx-flask --link flaskapp:flaskapp -d -p 8080:80 nginx-flask

Сейчас работает три контейнера, которые взаимосвязаны друг с другом:

    
      +-------+      +-------+      +-------+
  8080|       |  5000|       |      |       |
      o nginx +----->o flask +----->| redis |
      |       |      |       |      |       |
      +-------+      +-------+      +-------+
    

Работающие контейнеры:

$ docker ps
CONTAINER ID        IMAGE                COMMAND                CREATED             STATUS              PORTS                           NAMES
980b4cb3002a        nginx-flask:latest   "nginx -g 'daemon of   59 minutes ago      Up 59 minutes       443/tcp, 0.0.0.0:8080->80/tcp   nginx-flask         
ae4320dc419a        flaskapp:latest      "python /code/app.py   About an hour ago   Up About an hour    0.0.0.0:49161->5000/tcp         flaskapp            
3ecaab497403        redis:latest         "/entrypoint.sh redi   About an hour ago   Up About an hour    6379/tcp                        redis               

Проверим, отвечает ли наш сервис:


$ curl http://5.9.243.189:8080/ ; echo
Hello World! I have been seen 1 times.

$ curl http://5.9.243.189:8080/ ; echo
Hello World! I have been seen 2 times.

$ curl http://5.9.243.189:8080/ ; echo
Hello World! I have been seen 3 times.

[править] Дисковая подсистема Docker

Различные бэкенды Docker, существующие на сегодняшний день:

  • vfs;
  • devicemapper;
  • btrfs;
  • aufs.


[править] Доступ внутрь контейнера

В новых версиях Docker (начиная с 1.3) вы можете подключиться внутрь контейнера с помощью docker exec:

 docker run --name ubuntu_bash --rm -i -t ubuntu bash
 docker exec -d ubuntu_bash touch /tmp/execWorks

В результате будет создан файл /tmp/execWorks.

В более старых версиях нужно использовать команду nsenter напрямую. Эта команда, кстати, может быть полезна не только с docker, но и в других случаях доступа внутрь namespace'ов.

Само собой, что кроме этих способов всегда есть возможность запустить sshd внутри контейнера и подключиться к нему с помощью ssh. Однако, это не очень правильный метод (смотрите ниже статью на эту тему).

[править] Зачем может быть нужен Docker?

Почему Docker это хорошо?

  • Контейнеры Docker кроссплатформены. Один и тот же контейнер может использоваться под разными операционными системами.
  • Docker отделяет приложения от инфраструктуры. Описание инфраструктуры в терминах образов Docker помогает держать инфраструктуры в обозримом легко контролируемом состоянии;
  • Выполнение приложений в контейнерах изолирует их от внешнего мира, открывая только те ресурсы, которые явно указаны. Это сводит к минимум неучтённое внешнее влияние;
  • Автоматическая подготовка окружения и установка приложения. Docker делает это автоматически.

Зачем может быть нужен Docker?

  • Создание сложной гетерогенной системы, включающей большое множество взаимосвязанных подсистем/служб, и сохранение её в обозримом управляемом состоянии;
  • Создание собственной PaaS-инфраструктуры;
  • Предоставление какого-то программного обеспечения в SaaS-модели (например, memcached-as-a-Service);
  • Создание изолированных инстанций для тестирования программного обеспечения/конфигураций;
  • Быстрое создание и удаление своих игровых песочниц в ходе изучения нового программного обеспечения (не нужно готовить отдельную виртуальную машину и портить свою рабочую машину, экспериментировать можно в Docker-контейнере).

[править] Вопросы и ответы

[править] Тома снаружи защищённые SELinux не доступны внутри контейнеров?

Да.

Разрешить доступ можно следующим образом:

 chcon -Rt svirt_sandbox_file_t /path/to/volume

Подробнее:

[править] Дополнительная информация

Построение кластера контейнеров:

  • kubernetes (англ.) — Container Cluster Manager from Google
  • kubernetes Github.png, код Kubernetes на GitHub
Источник — «http://xgu.ru/wiki/Docker»
На других языках