Установка и правильная настройка Docker на Windows Subsystem Linux (WSL)

Автор оригинала: Rio Martinez
  • Перевод
  • Tutorial

Предварительные требования


Прежде чем начать, убедитесь, что ваша система имеет примерно следующую конфигурацию:

  • Windows 10 Version 1803 Build 1734 и выше
  • Ubuntu for WSL 16.0.4 LTS или что-то в этом роде (ваша версия может немного отличаться)

Важно, чтобы версия и сборка Windows были не ниже того, что здесь указано. Дело в том, что, начиная с этих цифр, в ядро Windows ​​WSL были внесены принципиальные изменения, которые позволяют использовать cgroups (control groups — в 2008 году добавлены в ядро Linux). А они необходимы Docker’у для управления ресурсами вашей системы в контейнерах.



Установка Docker-CE 17.09.0


Мы будем устанавливать Docker Community Edition 17.09.0 (потому что на момент написания этой статьи более свежие версии падали при установке на WSL).

Первое, что мы сделаем — избавимся от всех предыдущих установок Docker (если таковые были). Для этого запустим bash-терминал и напишем следующее:

$ sudo apt-get remove docker docker-engine docker.io containerd runc


Теперь установим репозиторий для Docker CE. Через apt-get мы можем установить нужную версию, самостоятельно не занимаясь её сборкой из исходников. Следуя рекомендациям на официальном сайте Docker, мы пишем следующие команды:

# Обновляем список пакетов
$ sudo apt-get update
# Устанавливаем необходимые пакеты, которые позволяют apt получить доступ по HTTPS
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common

# Добавляем в свою систему ключ GPG официального репозитория Docker
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
#Добавляем репозиторий Docker в список пакетов:
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# Обновляем данные о пакетах с учетом пакетов Docker из вновь добавленного репозитория
$ sudo apt-get update

Если вы когда либо добавляли новый репозиторий с помощью apt, всё это вам в целом знакомо. Если нет — надеюсь, вы всё равно остались со мной :)

Далее устанавливаем Docker:

$ sudo apt-get install docker-ce=17.09.0~ce-0~ubuntu

Если вы не используете WSL в стиле Ubuntu, список доступных версий можно посмотреть так:

$ apt list -a docker-ce


… или использовать аналогичную команду какой-то другой библиотеки, если вы отказались от APT

В конце нужно добавить своего текущего пользователя в группу ‘docker’, чтобы получить возможность правильно использовать Docker Engine («движок»), который должен быть запущен в вашей системе с правами root.

sudo usermod -aG docker $USER

Запуск Docker на Windows


Теперь, когда Docker установлен, нам нужно использовать довольно хитрый метод, чтобы запускать его как службу в WSL каждый раз при загрузке Windows. Это не так легко, как может показаться. Нам нужно действовать от имени суперпользователя и запустить командную оболочку с повышенными привилегиями, что немного усложняет задачу.

Чтобы немного упростить процесс, создайте в /usr /local/sbin/ новый файл — скрипт, который содержит соответствующие команды для запуска сервиса Docker:

$ sudo nano /usr/local/sbin/start_docker.sh

со следующим содержимым:

#!/usr/bin/env bash
sudo cgroups-mount
sudo service docker start

Первая команда sudo — это монтирование cgroups (оно выполнится при перезагрузке), а вторая отдает сервис docker в руки systemd (это подсистема Ubuntu для инициализации и управления службами).

Теперь разрешите скрипту запуститься и выполните его:

$ sudo chmod +x /usr/local/sbin/start_docker.sh
# Запрещаем запись
$ sudo chmod 755 /usr/local/sbin/start_docker.sh
$ /bin/sh /usr/local/sbin/start_docker.sh

Однако сервис Docker не запустится по двум причинам:

  1. Сценарий выполняет вызовы как суперпользователь, поэтому сам скрипт должен быть запущен с правами суперпользователя, чтобы работать как задумано. По идее, сделать это так же просто, как написать любую команду sudo, но для этого пользователь должен после каждой загрузки вводить свои данные, что сильно раздражает.
  2. Первая команда для монтирования cgroups должна быть выполнена в bash с повышенными привилегиями. Чтобы запустить её без ввода данных пользователем, нам придётся использовать Windows Task Scheduler.

Всё ясно? Тогда за дело…

Запуск скрипта с правами root без пользовательского ввода


В ОС семейства Linux файл /etc /sudoers определяет, кто и что может запускать с правами суперпользователя. Давайте модифицируем его так, чтобы ваш пользователь смог вызывать скрипт без необходимости постоянного ввода пароля root. (Но будьте очень осторожны с этим файлом! Очень легко выпилить себя из системы, если вы не знаете, что делаете!)

$ sudo nano /etc/sudoers

Добавим в конец файла новую строку. При этом вы должны точно знать имя своего пользователя (запустите echo $USER, если не уверены):

<your username here> ALL=(ALL:ALL) NOPASSWD: /bin/sh /usr/local/sbin/start_docker.sh

Теперь мы можем запустить сервис Docker с правами root без пользовательского ввода:

$ sudo /bin/sh /usr/local/sbin/start_docker.sh 

Ура, товарищи!

Правильный запуск Docker при загрузке Windows


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



Запустите Планировщик задач Windows и выберите Task Scheduler Library на левой панели. Затем выберите Create Task (создать задачу) на правой панели.



Далее вам предложат отредактировать основные настройки задачи. Дайте вашей задаче понятное название и убедитесь, что остальные настройки соответствуют моим. Важно, чтобы вы выбрали «Запуск с повышенными привилегиями» (Run with highest privileges).



Во вкладке Triggers добавьте новый триггер, который будет запускать задачу сразу же, как только локальный пользователь выполнит вход.



Переключившись на вкладку Actions, создайте новое действие, которое будет запускать bash и сразу же выполнять наш скрипт с ключом -с:

-c "sudo /bin/sh /usr/local/sbin/start_docker.sh"


Обратите внимание, что это нужно делать с повышенными привилегиями, поэтому проверьте галочку Run with highest privileges на вкладке General.



Остальные параметры в основном зависят от индивидуальных предпочтений, но я покажу свои настройки. Если хотите — можете их скопировать. Некоторые параметры питания могут не отображаться, если вы сидите на стационарной машине. Лично я пользуюсь ноутбуком.



Ну вот, всё идёт так, как мы задумали. Если вы на предыдущих этапах еще не запускали Docker, используя команды с повышенными привилегиями, просто щёлкните правой кнопкой мыши по задаче, созданной нами в Планировщике задач, и выберите «Выполнить»! Вот и всё!

Проверьте, что всё работает


Если хотите перестраховаться — перезагрузите свою машину (да, ради этого вам придётся в кое веки закрыть вкладки вашего браузера), запустите bash и введите:

$ docker run --rm hello-world

Если всё пройдёт хорошо, то вы увидите стандартное приветствие Docker’а. Сервис запустится автоматически и прямо в WSL! Мои поздравления!

Закругляемся


Вы только что установили и запустили Docker в WSL. Это означает, что ваши контейнеры теперь могут совместно использовать ​​Ubuntu, уже работающую в вашей системе. Таким образом отпадает необходимость разворачивать новую (виртуализированную) ОС, как это делает обычный Docker для Windows.

Производительность работы Docker в WSL пока [на момент написания оригинальной статьи] оставляет желать лучшего, но по мере развития платформы и выпуска обновлений Windows она будет только улучшаться.

Использованные источники


  1. onomatopellan из GitHub: https://github.com/Microsoft/WSL/issues/2291#issuecomment-383698720
  2. Official Docker Documentation: https://docs.docker.com/install/linux/docker-ce/ubuntu/
  3. cgroupfs-mount: https://github.com/tianon/cgroupfs-mount
  4. Bash Command Line Interface: https://docs.microsoft.com/en-us/windows/wsl/reference

VDSina.ru — хостинг серверов
Серверы в Москве и Амстердаме

Комментарии 37

    +2
    Ничего себе, сколько приседаний надо сделать только для запуска докера… Оно того стоит?

    Я смотрю, что оригинал был написал больше года назад. Сам Докер за это время не научился в WSL нативно?
      +1
      WSL2 will be generally available in Windows 10, version 2004
        0
        Да, я тоже жду Windows 10 2004 где будет WSL2 — что есть полноценное ядро Linux, а не эмуляция в WSL (1.0). Там докер будет запускаться без таких танцев с бубном
          0
          Обещали в мае, но в связи сами знаете с чем, непонятно когда выйдет.
            0
            Думаю также в мае и начнётся. Разработку они закрыли под новый год. Сейчас уже идёт стадия финального тестирования.
            +1

            Можно не ждать. WSL2 в раз 10 медленней WSL1. Зря только ставил ради этого инсайдерскую версию винды… Докер под виндой вообще очень тормознутый.

              0

              У тебя какие-то проблемы с файловой системой, у меня работает не медленнее нативного варианта.

                0
                Ну не знаю. На чистой линухе та же стартовая страничка на симфони загружается за 75-100мс, на WSL1 за ~400-600мс, а на WSL2 так вообще за 3-4сек. Я тут подумал, возможно, если проект разворачивать не на локальных дисках винды, а на самом WSL, внутри какой-нибудь директории home, то должно работать гораздо быстрее. Но это не точно.
                  0
                  Разница в скорости i/o в файловой системе винды и WSL2 сильно отличаются — docs.microsoft.com/en-us/windows/wsl/wsl2-ux-changes#cross-os-file-speed-will-be-slower-in-initial-preview-builds. Пользуюсь WSL2 на работе и не знаю бед, все работает быстрее и нативнее чем у маковских коллег.
                    0
                    А проект в самом WSL разворачиваешь или на локальных дисках?
                      0
                      Разворачиваю в \\wsl$. Нужно чтобы докер и проект были в одной системе, чтобы не было кросс-системной работы с файлами.
                        0
                        Ну вот. Из-за этого, возможно, у меня и тормозяки докера…
                          0
                          Точно из-за этого, у них в документации об этом целый параграф написан — для кого WSL 1, а для кого WSL 2.
          0
          пару дней подождать и 2004H выйдет
            0
            Вчера я только про это подумал,
            А сегодня ребятя из Докера уже написали статью, в которой говорят, что они вовсю тестируют докер с WSL 2:
            www.docker.com/blog/how-we-test-docker-desktop-with-wsl-2
            –1
            service docker start

            Подозрительно похоже на upstart. Это точно про systemd? Его вызов выглядел бы как
            systemctl start docker
            Он вообще «искаропки» умеет запускать сервис от любой учётной записи без приседаний с sudo, описанными в статье.
            В общем, я считаю, что если с каким-то сервисом не поставляется unit-файл — стыд и позор его мейнтейнерам (maintainers). С другой стороны, не хотите стыдить и позорить — свой unit-файл пишется примерно 5 минут (читать здесь и здесь). Может получиться что-то типа
            такого.
            [Install]
            WantedBy=multi-user.target
            [Service]
            Type=forking
            Environment=PID_FILE=/opt/unrealircd/data/unrealircd.pid
            PIDFile=/opt/unrealircd/data/unrealircd.pid
            ExecStart=/opt/unrealircd/bin/unrealircd
            ExecStop=/bin/kill -15 $MAINPID
            User=sp
            WorkingDirectory=/opt/unrealircd
            [Unit]
            ConditionPathExists=/opt/unrealircd/conf/unrealircd.conf
            

            За окном уже 2020 — пора знать systemd.
              0
              Я так полагаю, что статья опирается на Ubuntu 16.04+, то там ещё есть поддержка Upstart и вызов service docker start прокатывает. И то что unit-файла для нестандартной установки нет — думаю в этом ничего не логичного нет. Себе на Ubuntu 18.04 я ставил по официальной инструкции без проблем. Всё запускается само — файл есть :)
                +2

                если есть systemd, то обычно service просто перенаправляет на systemctl внутри.


                # service nginx status
                ● nginx.service - A high performance web server and a reverse proxy server
                   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
                   Active: active (running) since Tue 2020-02-11 16:19:40 MSK; 2 months 0 days ago
                 Main PID: 1248 (nginx)
                    Tasks: 5
                   Memory: 13.4M
                      CPU: 3h 36min 30.064s
                   CGroup: /system.slice/nginx.service
                           ├─ 1248 nginx: master process /usr/sbin/nginx -g daemon on; master_process on
                           ├─10943 nginx: worker process
                           ├─10944 nginx: worker process
                           ├─10945 nginx: worker process
                           └─10946 nginx: worker process
                
                Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
                0
                Полгода тому назад с WSL не получилось завести docker-compose из-за проблем с iptables, поэтому вернулся на легаси вариант где используется VirtualBox. Интересно есть ли у кого-нибудь положительный опыт?
                  +1
                  Есть. Буквально в пятницу прошел во второй раз пусть настройки WSL2. Именно WSL2, прошу обратить внимание. При запуску ubuntu делаю `service docker start`, далее все ровно также, как если бы был на нативном линуксе, т.е. docker-compose, swarm, что угодно. Устанавливал по официальным гайдам от MS. Главное — это обновить версию ядра винды до той, где можно будет переключить образ убунту на вторую версию wsl.
                  0
                  Не очень понимаю этих танцев с бубнами.
                  Win10 Insider Preview Fast Ring + WSL2 + Docker Desktop Edge
                  Пол года полёт нормальный.
                  DD Edge ставит докер в отдельный дистрибутив WSL2, пробрасывает докер в ваши WSL2 дистрибутивы и на винду. Всё отлично работает (кубер не тестил).
                  Upd: Win10 одна из сборок — поломала WSL2. Откатился назад, подождал неделю — обновился, всё супер.
                    0

                    Считаете, что виртуалка с Win10 Insider Preview, снапшот которой надо периодически сохранять — не танцы с бубном?

                      0
                      Через виртуалку тем более танцы. У меня на ноуте это основная и единственная ОС (не считая wsl2 дистрибутивы)
                    0

                    Это the god food challenge:


                    • Неустранимых багов #902 и #1927 достаточно чтобы здоровый человек зарекся использовать WSL1.
                    • Проблем "very slow" достаточно чтобы не связываться с WSL2, но для "потыкать палочкой" (не для production) вполне приемлемо.
                      0
                      very slow — смотря для чего.
                      Мне не нужна WSL2 чтобы из под винды сидеть в FS линухи.
                      Я либо в иксах, либо в терминале, либо в VScode (wsl remote).
                      Тогда она совсем не very slow.
                        0
                        Пробовал я использовать докер/wsl2/windows и vscode remote. По нашим тестам — только git pull/push занимает в 3-7 раз дольше чем на нативной системе, а ещё если работает VPN сеть в WSL2 отваливается, хотя в WSL1 работает, первая версия намного медленней второй. После месяца мучений и тестов просто получили апрув на маки и. теперь я щастлив.
                        Ещё перформанс тести вот здесь есть www.phoronix.com/scan.php?page=article&item=wsl-windows-eo2019&num=1
                          0
                          Gigabyte AERO 15 OLED WA, (9750H/512nvme) — я не видел задержек по сравнению с рабочим компом(слез с него как взял себе этот ноут). Учитывая конфигурацию (на работе SATA SSD) — у меня быстрее отрабатывает git.

                          Важно понимать, что в WSL2 нужно сидеть в «не шаренных» директориях (/home/xxx/dir — по умолчанию не расшарена, /mnt/{c,d,e...}/ — расшарены).
                          Я много читаю и слышу о проблемах в WSL2, но меня они не касаются — ни при сборке nuxtjs, ни при установке composer, ни при билдах Go-сервисов, ни при билдах docker.
                          Есть только две проблемы, которые доставляют дискомфорт:
                          1. ekaterinaryabukha Вы пилите idea-wsl2-remote? Нам очень не хватает виндовых GUI и linux environment вместе с вашими продуктами, вынуждены юзать VScode и скоро совсем к нему привыкнем.
                          2. GPU/CUDA/ML не работает в WSL2.
                          И одна проблема была с билдом Win10 Fast Ring — поломали wsl2 в сборке. откатился на предыдущий билд и всё тип топ.
                            0
                            Выше я привел ссылку на бенчмарки которые показывают WSL не супер быстрим в сравнении с нативным линуксом. Если поискать — на github есть множество тикетов про проблемы с перфомансом, но самая большая проблема для нас оказалось поломанный нетворкинг при подключенном VPN.

                            При подключении Cisco AnyConnect полностью отваливается нетворкинг в WSL2 (правда говоря в WSL1 все работает, но тормоз это еще тот). И де ми сравнивали не NVMe vs SATA/SSD, а два ноута с одинаковой конфигурацией (одно поколение процов, одинаковое количество памяти и немного разние диски).
                              0
                              Последние новости по поддержке WSL можно почитать, начиная с этого комментария.
                                0
                                Судя по комментам — о той поддержке как в vscode — речь не идёт. Посмотрим что замутили в phpstorm, но похоже придётся принять то что JB не справится с WSL2 «a la native»
                                  0

                                  Спасибо, но уже не надо. Получил апрув на использование мака в корпоративной сети и забыл о WSL как о страшном сне. Ну и ище раз убедился что видна не моё и на собесах надо уточнять не только что используется в инфраструктуре но и на ноутах.

                          0
                          Я знаю еще много «правильных» способов запуска docker. Например, nssm, который умеет запускать консольное приложение как службу windows. Или запустить любой гипервизор, можно даже qemu. Вот только зачем запускать docker в windows?
                            0

                            Так и не смог в схеме windows+docker заставить корректно работать монтирование, не работало монтирование например данных mongodb, ругалось на не существующие файлы, что-то со ссылками я так понял.


                            В wsl2 вроде должно все хорошо работать

                              0

                              Вопрос, docker по прежнему требует специфических настроек в windows при которых vmware не функционирует или я отстал от жизни и это пофиксили?

                                0
                                VMWare, которая может работать с активным Hyper-V сейчас в превью, если это имелось ввиду.
                                  0
                                  спасибо за инфу
                                0
                                Очень жду когда докер допилят до ума в винде, относительно недавно поймал проблему с монтированием волюмов в docker-compose, после пары часов дебага казалось бы банальной вещи, оказалось быстрее освоить Remote Development extension pack в VSCode, и с тех пор бед не знаю. В общем ждемс wsl 2.0 :)

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое