Docker

Docker

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

Содержание

1 Первые шаги

1.1 Установить Docker

1.2 Найти и установить контейнер

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

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

2.1 Список контейнеров

2.2 Просмотреть вывод контейнера

2.3 Просмотреть конфигурацию контейнера

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

3.1 Жизненный цикл
3.2 Информация о контейнерах

3.3 Импорт/экспорт
3.4 Выполнение команд

4 Создание контейнера / докеризация приложения

4.1 Создание Docker-файла

4.2 Сборка образа

4.3 Запуск контейнера с новым образом

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

5 Дисковая подсистема Docker

6 Доступ внутрь контейнера

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

8 Вопросы и ответы

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

9 Дополнительная информация


Установить 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

Жизненный цикл

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 , код Kubernetes на GitHub

Источник http://xgu.ru/wiki/Docker

Оставить первый комментарий

Добавить комментарий