Docker (Русский) - ArchWiki

# Docker (Русский)

From ArchWiki
Jump to navigation Jump to search

Ссылки по теме

- systemd-nspawn
- Linux Containers
- Vagrant

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

## Установка

Установите пакет docker или docker-gitAUR, версию для разработки. Затем включите и запустите службу `docker.service` и проверьте ее работу:

     # docker info

Обратите внимание, что запуск службы Docker может завершиться сбоем, если имеется активное VPN-соединение. Это происходит из-за IP-конфликтов между сетевыми мостами и оверлейными сетями VPN и Docker. Если это так, попробуйте отключить VPN перед запуском службы Docker. Вы можете переподключить VPN сразу после этого. Вы также можете попытаться разрешить конфликт сетей.

Если требуется запуск Docker от имени обычного пользователя, добавьте его в группу пользователей `docker`:

    # gpasswd -a user docker

Важно: Каждый пользователь в группе `docker` имеет права, равноценные правам суперпользователя. Больше информации здесь и здесь.

## Настройка

### Драйвер хранения

Драйвер хранения Docker (storage driver или graph driver) значительно влияет на производительность. Его задача — эффективно хранить слои образов контейнеров, то есть когда несколько образов совместно используют слой, только один слой использует дисковое пространство. Совместимая опция `devicemapper` предлагает неоптимальную производительность, которая просто ужасна на вращающихся дисках. Кроме того, `devicemapper` не рекомендуется использовать в промышленной среде.

Поскольку Arch Linux поставляется с новыми ядрами Linux, нет смысла использовать опцию совместимости. Хороший, современный выбор — `overlay2`.

Выполните `# docker info | grep -i storage`, чтобы увидеть текущий драйвер хранилища. Новые установки Docker уже должны использовать `overlay2` по умолчанию.

Отредактируйте файл `/etc/docker/daemon.json` (создайте его, если он не существует), чтобы изменить драйвер хранения:

    /etc/docker/daemon.json

    {
      "storage-driver": "overlay2"
    }

После чего перезапустите Docker.

Дополнительную информацию о доступных опциях можно найти в руководстве пользователя. Также см. документацию dockerd для получения информации о параметрах `daemon.json`.

### Remote API

Используйте следующую команду, чтобы вручную открыть порт `4243` для Remote API:

    # /usr/bin/dockerd -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock

`-H tcp://0.0.0.0:4243` — часть для открытия Remote API.

`-H unix:///var/run/docker.sock` — часть для доступа к хост-машине через терминал.

#### Remote API с systemd

Чтобы запустить Remote API с помощью демона Docker, создайте Drop-in сниппет со следующим содержимым:

    /etc/systemd/system/docker.service.d/override.conf

    [Service]
    ExecStart=
    ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock

### Конфигурация сокета демона

Демон docker по умолчанию прослушивает Unix-сокет. Чтобы прослушивать определённый порт, создайте Drop-in сниппет со следующим содержимым:

    /etc/systemd/system/docker.socket.d/socket.conf

    [Socket]
    ListenStream=0.0.0.0:2375

### Прокси

#### Конфигурация прокси

Создайте Drop-in сниппет со следующим содержанием:

    /etc/systemd/system/docker.service.d/proxy.conf

    [Service]
    Environment="HTTP_PROXY=192.168.1.1:8080"
    Environment="HTTPS_PROXY=192.168.1.1:8080"

Примечание: Предполагается, что прокси-сервер имеет адрес `192.168.1.1`, не используйте `127.0.0.1`.

Убедитесь, что конфигурация была загружена:

    # systemctl show docker --property Environment

    Environment=HTTP_PROXY=192.168.1.1:8080 HTTPS_PROXY=192.168.1.1:8080

#### Конфигурация контейнера

Настройки в файле `docker.service` не применяются к контейнерам. Для этого необходимо задать переменные `ENV` в `Dockerfile` следующим образом:

    FROM archlinux/base
    ENV http_proxy="http://192.168.1.1:3128"
    ENV https_proxy="https://192.168.1.1:3128"

Docker предоставляет подробную информацию о конфигурации с помощью `ENV` в Dockerfile.

### Конфигурация DNS

По умолчанию docker создаёт `resolv.conf` в контейнере с `/etc/resolv.conf` на хост-машине, отфильтровывая локальные адреса (например, `127.0.0.1`). Если это приводит к пустому файлу, тогда используются Google DNS серверы. Если вы используете службу типа dnsmasq для предоставления разрешения имен, вам может потребоваться добавить запись в `/etc/resolv.conf` для сетевого интерфейса докера, чтобы она не отфильтровывалась.

### Запуск Docker с сетью, заданной вручную, в systemd-networkd

Если вы вручную конфигурируете свою сеть, используя systemd-networkd версии 220 или выше, контейнеры, которые вы запускаете с помощью Docker, могут не иметь доступа к вашей сети. Начиная с версии 220, параметр переадресации для данной сети (`net.ipv4.conf.<Interface>.forwarding`) по умолчанию равен `off`. Этот параметр запрещает переадресацию IP. Он также конфликтует с Docker, который включает параметр `net.ipv4.conf.all.forwarding` внутри контейнера.

Обходной путь — отредактировать файл `<interface>.network` в `/etc/systemd/network/`, добавив `IPForward=kernel` на хосте Docker:

    /etc/systemd/network/<interface>.network

    [Network]
    ...
    IPForward=kernel
    ...

Эта конфигурация разрешает переадресацию IP из контейнера, как и ожидалось.

### Расположение образов

По умолчанию Docker образы расположены в `/var/lib/docker`. Они могут быть перемещены в другие разделы. Во-первых, остановите `docker.service`.

Если вы запустили Docker образы, вам необходимо убедиться, что они полностью размонтированы. После этого вы можете переместить изображения из `/var/lib/docker` в целевой путь.

Затем добавьте Drop-in сниппет для `docker.service`, добавив параметр `--data-root` в `ExecStart`:

    /etc/systemd/system/docker.service.d/docker-storage.conf

    [Service]
    ExecStart=
    ExecStart=/usr/bin/dockerd --data-root=/path/to/new/location/docker -H fd://

### Небезопасные реестры

Если вы решите использовать самозаверенный сертификат для своего личного реестра, Docker откажется использовать его, пока вы не заявите, что доверяете ему. Добавьте Drop-in сниппет для `docker.service`, добавив `--insecure-registry` параметр в `dockerd`:

    /etc/systemd/system/docker.service.d/override.conf

    [Service]
    ExecStart=
    ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry my.registry.name:5000

## Образы

### Arch Linux

Следующая команда выгружает archlinux/base x86_64 образ. Это урезанная версия ядра Arch без сети и т.д.

    # docker pull archlinux/base

Смотрите также README.md.

Для полноценного образа Arch, клонируйте репозиторий и создайте свой собственный образ.

    $ git clone https://github.com/archlinux/archlinux-docker.git

Отредактируйте файл `packages` так, чтобы он содержал только «base». Затем запустите:

    # make docker-image

### Debian

Следующая команда выгружает debian x86_64 образ.

    # docker pull debian

#### Создание образа вручную

Создайте образ Debian с debootstrap:

    # mkdir jessie-chroot
    # debootstrap jessie ./jessie-chroot http://http.debian.net/debian/
    # cd jessie-chroot
    # tar cpf - . | docker import - debian
    # docker run -t -i --rm debian /bin/bash

## Удаление Docker и образов

Если вы хотите полностью удалить Docker, вам следует выполнить следующие шаги:

Примечание: Не копируйте бездумно эти команды, не убедившись, что вы знаете, что делаете.

Выдать список работающих контейнеров:

    # docker ps

Выдать список всех контейнеров, запущенных на хосте для удаления:

    # docker ps -a

Остановить работающий контейнер:

    # docker stop <CONTAINER ID>

Выполнить команду kill для всё ещё работающих контейнеров:

    # docker kill <CONTAINER ID>

Удалить все контейнеры, перечисленные по ID:

    # docker rm <CONTAINER ID>

Выдать список всех образов Docker:

    # docker images

Удалить все образы Docker по ID:

    # docker rmi <IMAGE ID>

Удалить все данные Docker (очистить каталог):

The factual accuracy of this article or section is disputed.

Reason: После команды # rm -R /var/lib/docker останутся тома btrfs удалённых контейнеров (Discuss in Talk:Docker (Русский)#)

    # rm -R /var/lib/docker

## Полезные советы

Чтобы получить IP адрес контейнера, выполните:

    $ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container-name OR id>

    172.17.0.37

Для каждого работающего контейнера имя и соответствующий IP-адрес могут быть перечислены для использования в `/etc/hosts`:

    #!/usr/bin/env sh
    for ID in $(docker ps -q | awk '{print $1}'); do
        IP=$(docker inspect --format="{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" "$ID")
        NAME=$(docker ps | grep "$ID" | awk '{print $NF}')
        printf "%s %s\n" "$IP" "$NAME"
    done

## Запуск Docker-контейнеров с ускорением на графических процессорах NVIDIA

### С помощью NVIDIA Container Toolkit (рекомендовано)

Начиная с версии 19.03, графические процессоры NVIDIA поддерживаются в качестве устройств Docker. NVIDIA Container Toolkit ― рекомендованный способ запуска контейнеров, использующих графические процессоры NVIDIA.

Установите пакет nvidia-container-toolkitAUR и перезапустите Docker. Теперь вы можете запускать контейнеры Docker, использующие графические процессоры NVIDIA, с помощью параметра `--gpus`:

    # docker run --gpus all nvidia/cuda:9.0-base nvidia-smi

Укажите, сколько графических процессоров разрешено в контейнере:

    # docker run --gpus 2 nvidia/cuda:9.0-base nvidia-smi

Укажите, какие GPU следует использовать:

    # docker run --gpus '"device=1,2"' nvidia/cuda:9.0-base nvidia-smi

или

    # docker run --gpus '"device=UUID-ABCDEF,1"' nvidia/cuda:9.0-base nvidia-smi

Укажите возможности ("graphics", "compute", ...) контейнера (хотя это редко, если вообще когда либо используется таким образом):

    # docker run --gpus all,capabilities=utility nvidia/cuda:9.0-base nvidia-smi

Для получения дополнительной информации см. README.md и Wiki.

### С помощью NVIDIA Container Runtime

Установите пакет nvidia-container-runtimeAUR. Затем, зарегистрируйте среду выполнения NVIDIA, отредактировав конфигурационный файл `/etc/docker/daemon.json`:

    /etc/docker/daemon.json

    {
      "runtimes": {
        "nvidia": {
          "path": "/usr/bin/nvidia-container-runtime",
          "runtimeArgs": []
        }
      }
    }

и перезапустите docker.

Среда выполнения также может быть зарегистрирована с помощью параметра командной строки dockerd:

    # /usr/bin/dockerd --add-runtime=nvidia=/usr/bin/nvidia-container-runtime

После этого контейнеры с ускорением на графических процессорах могут быть запущены с помощью следующей команды:

    # docker run --runtime=nvidia nvidia/cuda:9.0-base nvidia-smi

или (требуется Docker версии 19.03 или выше):

    # docker run --gpus all nvidia/cuda:9.0-base nvidia-smi

См. также README.md.

### С помощью nvidia-docker (устарело)

nvidia-docker — обёртка над библиотекой среды исполнения NVIDIA Container Runtime, которая регистрирует среду выполнения NVIDIA по умолчанию и предоставляет команду nvidia-docker.

Чтобы использовать nvidia-docker, установите пакет nvidia-dockerAUR и перезапустите Docker. Контейнеры с поддержкой NVIDIA GPU могут быть запущены, используя один из следующих методов:

    # docker run --runtime=nvidia nvidia/cuda:9.0-base nvidia-smi

    # nvidia-docker run nvidia/cuda:9.0-base nvidia-smi

или (требуется Docker версии 19.03 или выше)

    # docker run --gpus all nvidia/cuda:9.0-base nvidia-smi

Примечание: nvidia-docker — устаревший метод запуска Docker-контейнеров с ускорением на графических процессорах NVIDIA, использующийся в версиях Docker, предшествующих версии 19.03. Если вы используете Docker версии 19.03 или выше, рекомендуется использовать NVIDIA Container Toolkit.

## Устранение неполадок

### docker0 Bridge не получает IP адреса/нет доступа к Интернету в контейнерах

Docker сам включает переадресацию IP, но по умолчанию systemd-networkd переопределяет соответствующую настройку sysctl. Установите `IPForward=yes` в настройках сети. Подробнее читайте в Internet sharing#Enable packet forwarding.

Примечание: Вам может понадобится выполнить перезапустить `docker.service` каждый раз, когда Вы выполняете перезапуск `systemd-networkd.service` или `iptables.service`

### Слишком низкое значение количества процессов/потоков по умолчанию

Если вы столкнетесь с сообщениями об ошибках, похожими на следующие:

    # e.g. Java
    java.lang.OutOfMemoryError: unable to create new native thread
    # e.g. C, bash, ...
    fork failed: Resource temporarily unavailable

тогда вам может потребоваться настроить количество процессов, разрешенных systemd. Значени по умолчанию 500 (смотрите `system.conf`), что довольно мало для запуска нескольких Docker контейнеров. Отредактируйте `docker.service` со следующим фрагментом:

    # systemctl edit docker.service

    [Service]
    TasksMax=infinity

### Ошибка инициализации графического драйвера: devmapper

Если systemctl не запускает Docker и выдает ошибку::

    Error starting daemon: error initializing graphdriver: devmapper: Device docker-8:2-915035-pool is not a thin pool

Попробуйте выполнить следующие действия, чтобы устранить ошибку. Остановите службу, сделайте резервную копию `/var/lib/docker/` (если это необходимо), удалите содержимое `/var/lib/docker/`, и попробуйте запустить службу. Смотрите описание проблемы на GitHub для более детальной информации.

### Failed to create some/path/to/file: No space left on device

Если вы получаете сообщение об ошибке, подобное этому:

    ERROR: Failed to create some/path/to/file: No space left on device

При создании или исполнении Docker образа, даже если у вас достаточно свободного места на диске, убедитесь, что:

- Tmpfs отключен или имеет достаточно памяти. Docker может пытаться записать файлы в `/tmp` но терпит неудачу из-за ограничений в использовании памяти, а не дискового пространства.
- Если вы используете XFS, Вы можете удалить опцию монтирования `noquota` из соответствующих записей в `/etc/fstab` (обычно, где находятся `/tmp` и/или `/var/lib/docker`). Для получения дополнительной информации обратитесь к Disk quota, особенно, если вы планируете использовать и изменить размер `overlay2` Docker хранилища.
- Варианты установки монтирования квоты XFS (`uquota`, `gquota`, `prjquota`, и т.д.) выдают ошибку при перемонтировании файловой системы.

Чтобы включить квоту для корневой файловой системы, параметр монтирования должен быть передан как kernel parameter `rootflags=`. Впоследствии его не следует указывать среди параметров монтирования в `/etc/fstab` для корневой файловой системы (`/`).

Примечание: Есть некоторые отличия XFS Quota по сравнению со стандартом Linux Disk quota, [1] рекомендуется к прочтению.

### Неверная ссылка между устройствами в ядре 4.19.1

Если команды типа dpkg не запускаются в Docker, например:

    dpkg: error: error creating new backup file '/var/lib/dpkg/status-old': Invalid cross-device link

Либо добавьте `overlay.metacopy=N` kernel parameter или поставьте версию 4.18.x, в которой эта проблема решена. Больше информации в Arch forum.

### Отсутствие CPUACCT в docker с Linux-ck

В новых версиях Linux-ck (Русский) (замечено в версиях 4.19 и 4.20), было сделано изменение в MuQSS, отключающее опцию `CONFIG_CGROUP_CPUACCT` в ядре, что вызывает следующую ошибку при использовании некоторых команд docker (`run` или `build`):

    $ docker run --rm hello-world

    docker: Error response from daemon: unable to find "cpuacct" in controller set: unknown.

Похоже, что эта ошибка не влияет на демон docker, а только на контейнеры. См. раздел Linux-ck#CPUACCT missing in docker[broken link: invalid section] для получения более подробной информации.

### Docker-machine не может создать виртуальные машины с драйвером virtualbox

Если docker-machine не может создать виртуальные машины с драйвером virtualbox и отображает следующую ошибку:

    VBoxManage: error: VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory

Перезагрузите virtualbox из командной строки с помощью команды `vboxreload`.

## Docker 0.9.0 — 1.2.x и LXC

Начиная с версии 0.9.0, Docker предоставляет новый способ запуска контейнеров без необходимости в LXC, называемый libcontainer.

LXC может быть удален в ближайшем будущем, однако таким образом вы не сможете использовать `lxc-attach` с контейнерами, управляемыми Docker 0.9.0+ по умолчанию (запрос 5797). Для этого потребуется запускать службу Docker с параметром `-e lxc`.

Вы можете создать файл с именем `lxc.conf` в `/etc/systemd/system/docker.service.d/` со следующим содержимым:

    [Service]
    ExecStart=
    ExecStart=/usr/bin/docker -d -e lxc

## Смотрите также

- Официальный сайт
- Arch Linux на docs.docker.com
- Are Docker containers really secure? — opensource.com
- Awesome Docker

Categories:

- Virtualization (Русский)
- Sandboxing (Русский)

Hidden categories:

- Pages or sections flagged with Template:Accuracy
- Pages with broken section links