Контейнер для файлов: Как спрятать файлы на компьютере

Содержание

работа с данными / Блог компании RUVDS.com / Хабр

В сегодняшней части перевода серии материалов о Docker мы поговорим о работе с данными. В частности — о томах Docker. В этих материалах мы постоянно сравнивали программные механизмы Docker с разными съедобными аналогиями. Не будем отходить от этой традиции и здесь. Данные в Docker пусть будут специями. В мире существует множество видов специй, а в Docker — множество способов работы с данными.

→ Часть 1: основы
→ Часть 2: термины и концепции
→ Часть 3: файлы Dockerfile
→ Часть 4: уменьшение размеров образов и ускорение их сборки
→ Часть 5: команды
→ Часть 6: работа с данными



Обратите внимание на то, что этот материал подготовлен с использованием движка Docker версии 18.09.1 и API версии 1.39.

Данные в Docker могут храниться либо временно, либо постоянно. Начнём с временных данных.

Временное хранение данные


В контейнерах Docker организовать работу с временными данными можно двумя способами.

По умолчанию файлы, создаваемые приложением, работающим в контейнере, сохраняются в слое контейнера, поддерживающем запись. Для того чтобы этот механизм работал, ничего специально настраивать не нужно. Получается дёшево и сердито. Приложению достаточно просто сохранить данные и продолжить заниматься своими делами. Однако после того как контейнер перестанет существовать, исчезнут и данные, сохранённые таким вот нехитрым способом.

Для хранения временных файлов в Docker можно воспользоваться ещё одним решением, подходящим для тех случаев, когда требуется более высокий уровень производительности, в сравнении с тем, который достижим при использовании стандартного механизма временного хранения данных. Если вам не нужно, чтобы ваши данные хранились бы дольше, чем существует контейнер, вы можете подключить к контейнеру tmpfs — временное хранилище информации, которое использует оперативную память хоста. Это позволит ускорить выполнение операций по записи и чтению данных.

Часто бывает так, что данные нужно хранить и после того, как контейнер прекратит существовать. Для этого нам пригодятся механизмы постоянного хранения данных.

Постоянное хранение данных


Существуют два способа, позволяющих сделать срок жизни данных большим срока жизни контейнера. Один из способов заключается в использовании технологии bind mount. При таком подходе к контейнеру можно примонтировать, например, реально существующую папку. Работать с данными, хранящимися в такой папке, смогут и процессы, находящиеся за пределами Docker. Вот как выглядят монтирование tmpfs и технология bind mount.
Монтирование tmpfs и bind mount

Минусы использования технологии bind mount заключаются в том, что её использование усложняет резервное копирование данных, миграцию данных, совместное использование данных несколькими контейнерами. Гораздо лучше для постоянного хранения данных использовать тома Docker.

Тома Docker


Том — это файловая система, которая расположена на хост-машине за пределами контейнеров. Созданием и управлением томами занимается Docker. Вот основные свойства томов Docker:
  • Они представляют собой средства для постоянного хранения информации.
  • Они самостоятельны и отделены от контейнеров.
  • Ими могут совместно пользоваться разные контейнеры.
  • Они позволяют организовать эффективное чтение и запись данных.
  • Тома можно размещать на ресурсах удалённого облачного провайдера.
  • Их можно шифровать.
  • Им можно давать имена.
  • Контейнер может организовать заблаговременное наполнение тома данными.
  • Они удобны для тестирования.

Как видите, тома Docker обладают замечательными свойствами. Давайте поговорим о том, как их создавать.

Создание томов


Тома можно создавать средствами Docker или с помощью запросов к API.

Вот инструкция в Dockerfile, которая позволяет создать том при запуске контейнера.

VOLUME /my_volume

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

Создавать тома в Dockerfile можно и используя формат JSON.

Кроме того, тома можно создавать средствами командной строки во время работы контейнера.

Работа с томами из командной строки


▍Создание тома


Создать самостоятельный том можно следующей командой:
docker volume create —-name my_volume

▍Выяснение информации о томах


Для того чтобы просмотреть список томов Docker, воспользуйтесь следующей командой:
docker volume ls

Исследовать конкретный том можно так:
docker volume inspect my_volume

▍Удаление тома


Удалить том можно так:
docker volume rm my_volume

Для того чтобы удалить все тома, которые не используются контейнерами, можно прибегнуть к такой команде:
docker volume prune

Перед удалением томов Docker запросит у вас подтверждение выполнения этой операции.

Если том связан с каким-либо контейнером, такой том нельзя удалить до тех пор, пока не удалён соответствующий контейнер. При этом, даже если контейнер удалён, Docker не всегда это понимает. Если это случилось — можете воспользоваться следующей командой:

docker system prune

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

Флаги —mount и —volume


Для работы с томами вам, при вызове команды docker, часто придётся пользоваться флагами. Например, для того чтобы создать том во время создания контейнера можно воспользоваться такой конструкцией:
docker container run --mount source=my_volume, target=/container/path/for/volume my_image

В давние времена (до 2017 года) популярен был флаг --volume. Изначально этот флаг (ещё им можно пользоваться в сокращённом виде, тогда он выглядит как -v) использовался для самостоятельных контейнеров, а флаг --mount — в среде Docker Swarm. Однако, начиная с Docker 17.06, флаг --mount можно использовать в любых сценариях.

Надо отметить, что при использовании флага --mount увеличивается объём дополнительных данных, которые приходится указывать в команде, но, по нескольким причинам, лучше использовать именно этот флаг, а не

--volume. Флаг --mount — это единственный механизм, который позволяет работать с сервисами или указывать параметры драйвера тома. Кроме того, работать с этим флагом проще.

В существующих примерах команд, направленных на работу с данными в Docker, вы можете встретить множество примеров употребления флага -v. Пытаясь адаптировать эти команды для себя, учитывайте то, что флаги --mount и --volume используют различные форматы параметров. То есть, нельзя просто заменить -v на --mount и получить рабочую команду.

Главное различие между --mount и --volume заключается в том, что при использовании флага --volume все параметры собирают вместе, в одном поле, а при использовании --mount параметры разделяются.

При работе с --mount параметры представлены как пары вида ключ-значение, а именно, это выглядит как key=value. Эти пары разделяют запятыми. Вот часто используемые параметры --mount:

  • type — тип монтирования. Значением для соответствующего ключа могут выступать bind, volume или tmpfs. Мы тут говорим о томах, то есть — нас интересует значение volume.
  • source — источник монтирования. Для именованных томов это — имя тома. Для неименованных томов этот ключ не указывают. Он может быть сокращён до src.
  • destination — путь, к которому файл или папка монтируется в контейнере. Этот ключ может быть сокращён до dst или target.
  • readonly — монтирует том, который предназначен только для чтения. Использовать этот ключ необязательно, значение ему не назначают.

Вот пример использования --mount с множеством параметров:
docker run --mount type=volume,source=volume_name,destination=/path/in/container,readonly my_image

Итоги


Вот полезные команды, которыми можно пользоваться при работе с томами Docker:
  • docker volume create
  • docker volume ls
  • docker volume inspect
  • docker volume rm
  • docker volume prune

Вот список часто используемых параметров для --mount, применимых в команде вида docker run --mount my_options my_image:
  • type=volume
  • source=volume_name
  • destination=/path/in/container
  • readonly

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

Уважаемые читатели! Какие материалы о Docker вы посоветовали бы изучить новичкам?

Восторг безопасника — технология для шифрования образов контейнеров

На днях поступила интересная задачка — необходимо найти способ защитить исходные данные контейнера (читай: не иметь возможности прочитать, что лежит внутри), когда он остановлен. В голову сразу пришла мысль про шифрование, а пальцы начали набирать в гугле заветные слова. Пока разбирался в теме, наткнулся на достаточно интересную статью, которую с удовольствием привожу вам.



Обеспечение конфиденциальности данных и кода в образах контейнеров


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

Успех технологии контейнеризации в основном зависит от безопасности контейнеров на различных этапах их жизненного цикла. Одна из проблем безопасности — наличие уязвимостей внутри отдельных контейнеров. Для их выявления пайплайны DevOps, используемые для создания контейнеров, дополняют сканерами, которые ищут в контейнерах пакеты с возможными уязвимостями и предупреждают их владельцев или технических специалистов в случае их обнаружения. Vulnerability Advisor в IBM Cloud является примером такой утилиты.

Еще один аспект безопасности заключается в том, что нужно убедиться, что запускаемый контейнер — именно тот контейнер, который вам нужен, и он не был изменен. Этот вопрос решается путем использования хранящихся в Notary цифровых подписей, которые защитят контейнеры от каких-либо модификаций. Docker Notary — это пример публичного репозитория, в котором хранятся подписи образов. Используя Notary, клиент может проверить подпись образа контейнера, чтобы убедиться, что образ контейнера не был изменен с момента его подписания ключом владельца или специалиста по обслуживанию.

Еще одна потенциальная проблема безопасности — это изоляция контейнера. Технологии безопасности среды исполнения Linux, такие как пространство имен, контрольные группы (cgroups), возможности Linux, а также профили SELinux, AppArmor и Seccomp, помогают ограничить процессы контейнеров и изолировать контейнеры друг от друга во время исполнения.

В этой статье рассматривается все еще актуальная проблема безопасности предприятий в отношении конфиденциальности данных и кода в образах контейнеров. Основная цель безопасности при работе с образами контейнеров — позволить создавать и распространять зашифрованные образы контейнеров, чтобы сделать их доступными только определенному кругу получателей. В этом случае другие могут иметь доступ к этим образам, но они не смогут запускать их или видеть конфиденциальные данные внутри них. Шифрование контейнеров основано на существующей криптографии, такой как технологии шифрования Ривеста-Шамира-Адлемана (RSA), эллиптической кривой и Advanced Encryption Standard (AES), также известный как Rijndael — симметричный алгоритм блочного шифрования.

Вводные


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

Смежные работы по шифрованию и контейнерам


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

Зашифрованные файловые системы существуют во многих операционных системах на предприятиях и могут поддерживать монтирование зашифрованных разделов и каталогов. Зашифрованные файловые системы могут даже поддерживать загрузку с зашифрованного загрузочного диска. Linux поддерживает шифрование на уровне блочного устройства с помощью драйвера dm-encrypt; ecryptfs является одним из примеров зашифрованной файловой системы. Для Linux доступны другие решения для шифрования файлов с открытым исходным кодом. В ОС Windows шифрование поддерживает файловая система NTFS v3.0. Кроме того, многие производители создают диски с самошифрованием. Для образов виртуальных машин существует решение, подобное зашифрованным дискам. Эмулятор машины (ПК) QEMU с открытым исходным кодом и продукты виртуализации VMware поддерживают зашифрованные образы виртуальных машин.

Шифрование данных обычно направлено на защиту от кражи данных в то время, когда система отключена. Смежная технология — это подписание образа контейнера ключом, который предоставляется клиентом и сервером Docker Notary. Сервер Docker Notary работает в непосредственной близости с реестром образов контейнера. Пользователи клиентского инструмента Docker имеют возможность подписать образ контейнера и загрузить подпись в свои учетные записи через Docker Notary. В ходе этого процесса подпись привязывается к образу контейнера через имя пути к образу и его версиям. Подпись создается с помощью хеш-функции, которая рассчитывается на основе описания всего содержимого образа. Это описание называется манифестом образа контейнера. Технология подписи образов контейнера решает проблему защиты образов контейнеров от несанкционированного доступа и помогает определить происхождение образа контейнера.

Структура


Экосистема Docker сформировалась для того, чтобы стандартизировать форматы образов контейнеров с помощью группы стандартов Open Container Initiative (OCI), которая теперь контролирует формат времени исполнения контейнера (runtime-spec) и формат образа контейнера (image-spec). Поскольку работа команды требовала расширения существующего формата образа контейнера, мы выделили расширение стандарта для поддержки зашифрованных образов. В следующих разделах описывается существующий формат образа контейнера и расширения.

На верхнем уровне контейнер может состоять из документа в JavaScript Object Notation (JSON), который представляет собой список манифестов образов. Например, вы можете использовать этот список манифестов, когда для образа контейнера используются несколько архитектур или платформ. Список манифестов содержит ссылки на манифесты контейнеров, по одной для каждой комбинации архитектуры и операционной системы. Например, поддерживаемые архитектуры включают amd64, arm и ppc64le, а к поддерживаемым операционным системам относится Linux или Windows. Пример списка манифестов показан на скриншоте ниже:

Поле mediaType описывает точный формат указанного документа. Этот список манифестов позволяет в будущем расширять и выбирать соответствующий синтаксический анализатор для задействованного документа.

Уровень ниже списка манифестов — это манифест. Манифест также является документом JSON и содержит упорядоченный список ссылок на слои образов. Эти ссылки содержат mediaType, описывающий формат слоя. Формат может описывать, сжимается ли слой, и если да, то каким образом. Например, каждый уровень может быть сохранен в виде файла .tar, содержащего файлы, которые были добавлены на определенном этапе сборки при выполнении docker build в файле Docker. Для повышения эффективности хранения слои часто также упаковываются с использованием сжатых файлов .gzip. Пример документа манифеста показан на следующем скриншоте:

Как показано, манифесты и уровни ссылаются через «дайджест», который обычно представляет собой хеш-функцию sha256 в документах JSON. Манифесты и слои обычно хранятся в виде файлов в файловой системе. Зачастую имена файлов представляют собой хеш-функции над содержимым, что упрощает их поиск и загрузку. Следствием этого метода хеш-функции является то, что небольшое изменение в документе, на который есть ссылка, вызывает изменения во всех документах, которые на него ссылаются, вплоть до списка манифестов.

В рамках проекта нашей команды мы создали шифрование образов на основе гибридной схемы шифрования с использованием открытого и симметричного ключей. Симметричные ключи используются для массового шифрования данных (применяются для многоуровневого шифрования), а открытые ключи используются для упаковки симметричных ключей. Мы использовали три различные технологии шифрования на основе открытых ключей: OpenPGP, JSON Web Encryption (JWE) и PKCS#7.

OpenPGP


OpenPGP — это технология шифрования и подписи, которая обычно используется для шифрования и подписи сообщений электронной почты. Сообщества с открытым исходным кодом также часто используют его для подписания коммитов (тегов) исходного кода в репозиториях git. Это интернет-стандарт, определенный IETF в RFC480, и его можно рассматривать как открытую версию предыдущей проприетарной технологии PGP.

OpenPGP имеет собственный формат для ключей RSA. Ключи обычно хранятся в файле keyring и могут быть импортированы из простых файлов ключей OpenPGP. Наиболее удобный аспект keyring OpenPGP состоит в том, что открытые ключи могут быть связаны с адресами электронной почты их владельцев. Вы можете работать с несколькими получателями сообщения, просто выбрав список получателей по их адресам электронной почты, которые затем отображаются в открытых ключах для этих получателей. Кроме того, вокруг этой технологии была создана сеть доверия: вы можете найти открытые ключи многих пользователей, упорядоченные по их адресам электронной почты. Например, эти ключи часто используются для подписания тегов git.

Можно использовать формат зашифрованного сообщения OpenPGP для шифрования массовой рассылки сообщения для нескольких получателей. Заголовок сообщения OpenPGP содержит по одному блоку для каждого получателя. Каждый блок содержит 64-битный идентификатор ключа, который указывает алгоритму дешифрования, где необходимо пытаться дешифровать соответствующий закрытый ключ. После того как зашифрованный большой двоичный объект внутри блока расшифрован, он показывает симметричный ключ, который можно использовать для дешифрования массовой рассылки сообщения. Зашифрованный большой двоичный объект с открытым ключом каждого получателя показывает один и тот же симметричный ключ.

Мы использовали OpenPGP аналогичным образом, но в данном случае зашифрованное сообщение, которое он передает, не является слоем. Вместо этого оно содержит документ JSON, который, в свою очередь, содержит симметричный ключ, используемый для шифрования и дешифрования как слоя, так и вектора инициализации. Мы называем этот ключ ключом шифрования слоя (LEK), он представляет собой форму ключа шифрования данных. Преимущество этого метода в том, что нам нужен только один LEK. С помощью LEK мы шифруем слой для одного или нескольких получателей. У каждого получателя (образа контейнера) может быть свой тип ключа, и это не обязательно должен быть ключ OpenPGP. Например, это может быть простой ключ RSA. Пока у нас есть возможность использовать этот ключ RSA для шифрования LEK, мы сможем работать с несколькими получателями с разными типами ключей.

JSON Web Encryption (JWE)


JSON Web Encryption, также известное как JWE, является еще одним интернет-стандартом IETF и определено в RFC7516. Это более новый стандарт шифрования, чем OpenPGP, поэтому в нем используются более свежие низкоуровневые шифры, предназначенные для удовлетворения более строгих требований к шифрованию.

Если смотреть укрупненно, JWE работает по тому же принципу, что и OpenPGP, поскольку он также поддерживает список получателей и массовую рассылку сообщения, зашифрованного с помощью симметричного ключа, к которому имеет доступ каждый получатель сообщения. Получатели сообщения JWE могут иметь разные типы ключей, такие как ключи RSA, определенные типы ключей эллиптической кривой, предназначенные для шифрования, и симметричные ключи. Поскольку это более новый стандарт, все еще есть возможность расширения JWE для поддержки ключей в аппаратных устройствах, таких как TPM или модули аппаратной защиты (HSM), с использованием интерфейсов PKCS#11 или Key Management and Interoperability Protocol (KMIP). Использование JWE происходит аналогичным OpenPGP образом, если получатели имеют ключи RSA или эллиптические кривые. В будущем мы могли бы расширить его для поддержки симметричных ключей, таких как KMIP внутри HSM.

PKCS#7


PKCS#7, также известный как синтаксис криптографических сообщений (CMS), определен в стандарте IEFT RFC5652. Согласно Википедии о CMS, «его можно использовать для цифровой подписи, дайджеста, аутентификации или шифрования любых форм цифровых данных».

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

Для поддержки ранее описанных технологий шифрования мы расширили документ манифеста, добавив следующую информацию:

  • Сообщения OpenPGP, JWE и PKCS#7 хранятся в карте аннотаций, которая является частью манифеста.
  • В каждом указанном слое содержится по одной карте. Карта аннотаций в основном представляет собой словарь со строками в качестве ключей и строками в качестве значений (пары ключ-значение).

Для поддержки шифрования образов мы определили следующие ключи:
  • org.opencontainers.image.enc.keys.openpgp
  • org.opencontainers.image.enc.keys.jwe
  • org.opencontainers.image.enc.keys.pkcs7

Значение, на которое ссылается каждый ключ, содержит одно или несколько зашифрованных сообщений для соответствующей технологии шифрования. Поскольку эти сообщения могут быть в двоичном формате, они кодируются с помощью base64. Зашифрованный уровень должен иметь по крайней мере одну такую аннотацию, но может иметь и все, если его получатель имеет достаточное количество различных типов ключей.

Чтобы определить, что слой был зашифрован с помощью LEK, мы расширили существующие медиатипы суффиксом ‘+encrypted’, как показано в следующих примерах:

  • application/vnd.docker.image.rootfs.diff.tar+encrypted
  • application/vnd.docker.image.rootfs.diff.tar.gzip+encrypted

Эти примеры показывают, что слой заархивирован в файле .tar и зашифрован — или оба заархивированы в файле .tar и сжаты в файл .gzip и зашифрованы. На следующем скриншоте показан пример манифеста, который ссылается на зашифрованные слои. Он также показывает карту аннотаций, содержащую зашифрованное сообщение JWE.

Многослойное шифрование с использованием симметричных ключей


Для симметричного шифрования с помощью LEK наша команда выбрала шифр, который поддерживает аутентифицированное шифрование и основан на стандарте шифрования AES со 128- и 256-битными ключами.

Пример реализации: containerd


Мы реализовали наш вариант в новом проекте среды выполнения контейнеров под названием containerd. Его исходный код на golang можно посмотреть, перейдя по ссылке. Docker-демон использует containerd для запуска некоторых своих служб, а у Kubernetes есть плагин для прямого использования containerd. Поэтому мы надеемся, что наши расширения для поддержки зашифрованных образов контейнеров пригодятся обоим.

Реализация многоуровневого шифрования с использованием LEK находится на самом низком архитектурном уровне расширений. Одно из требований к реализации состояло в том, чтобы вместить объемные слои в несколько гигабайтов, сохраняя при этом объем памяти, занимаемый процессом, выполняющим криптографическую операцию в слое, размером всего несколько мегабайт.

Поддержка алгоритмов аутентифицированного шифрования в Golang принимает байтовый массив в качестве входных данных и выполняет весь этап его шифрования (запечатывания) или дешифрования (открытия), не допуская передачи и добавления дополнительных массивов в поток. Поскольку этот криптографический API требовал загрузки всего уровня в память или изобретения некоторой схемы для изменения вектора инициализации (IV) для каждого блока, мы решили не использовать аутентифицированное шифрование golang с поддержкой связанных данных (AEAD). Вместо этого мы использовали крипто-библиотеку miscreant golang, которая поддерживает AEAD в потоках (блоках) и реализует собственную схему изменения IV в каждом блоке. В нашей реализации мы разбиваем уровень на блоки размером 1 МБ, которые и передаем один за другим для шифрования. Такой подход позволяет снизить объем памяти при использовании аутентифицированного шифра. На стороне дешифрования мы делаем обратное и обращаем внимание на ошибки, возвращаемые функцией Open (), чтобы убедиться, что блоки шифрования не были подделаны.

На уровне выше симметричного шифрования, асимметричные криптографические схемы шифруют LEK уровня и вектор инициализации (IV). Для добавления или удаления криптографических схем мы регистрируем каждую асимметричную криптографическую реализацию. Когда API асимметричного криптографического кода вызывается для шифрования уровня, мы вызываем один за другим зарегистрированные криптографические обработчики, передавая открытые ключи получателей. После того как все ключи получателей используются для шифрования, мы возвращаемся к карте аннотаций с идентификаторами асимметричных криптоалгоритмов в качестве ключей сопоставления и со значениями, содержащими сообщения в кодировке OpenPGP, JWE и PKCS#7. Каждое сообщение содержит упакованные LEK и IV. Карты аннотаций хранятся в документе манифеста, как показано на предыдущем скриншоте.

Мы также можем добавлять получателей к уже зашифрованному образу. Авторы образов добавляют получателей, если они есть в списке. Для списка получателей используется закрытый ключ, необходимый для распаковки LEK и IV уровней. Затем мы упаковываем LEK и IV в новое сообщение, используя ключ нового получателя, и добавляем это сообщение к карте аннотаций.

Мы использовали три типа асимметричных схем шифрования для разных типов ключей. Мы используем ключи OpenPGP для шифрования сообщений OpenPGP. PKCS#7, которую мы используем, требует сертификаты x.509 для ключей шифрования. JWE обрабатывает все остальные типы ключей, такие как простые ключи RSA, эллиптические кривые и симметричные ключи. Мы создали прототип расширения для JWE, который позволяет выполнять криптографические операции с использованием ключей, управляемых сервером KMIP.

Среда выполнения containerd включает клиентский инструмент ctr для взаимодействия с ней. Мы расширили ctr, чтобы включить тестирование наших изменений и предоставить доступ для пользователей контейнера. ctr уже реализует подкоманду, которая поддерживает операции с образами, такие как взаимодействие с реестром образов через их извлечение и отправку.

Мы расширили эту подкоманду, добавив функционал для шифрования образов и включения шифрования отдельных уровней отдельных архитектур с помощью определенного набора ключей. Такой подход позволяет пользователям шифровать только те слои, которые содержат конфиденциальные данные, и оставлять другие слои без шифрования. Последние можно дедуплицировать, но это вряд ли возможно для зашифрованных слоев.

Точно также мы можем расшифровывать отдельные слои отдельных архитектур. Мы добавили подкоманду layerinfo, которая показывает статус шифрования каждого уровня и отображает технологии шифрования, используемые для него. Для OpenPGP мы также можем отображать идентификаторы ключей, необходимые для дешифрования, или преобразовывать их в адреса электронной почты их получателей с помощью keyring.

Дополнительно можно делать экспорт и импорт образов контейнеров. Мы реализовали поддержку шифрования слоев при экспорте и дешифрования при импорте. Несмотря на то, что мы расшифровываем слои для создания файловой системы rootfs контейнера, зашифрованные слои и исходные файлы метаданных, например, его манифесты, сохраняются. Такой подход позволяет экспортировать образ в зашифрованном виде и выполнять проверки авторизации, когда пользователи хотят запустить контейнер с зашифрованным образом.

Когда простой (незашифрованный) образ извлекается из реестра, он автоматически распаковывается и разархивируется, чтобы из него можно было сразу создавать контейнеры. Чтобы упростить это действие для зашифрованных образов, мы предлагаем передавать закрытый ключ команде, которая занимается распаковкой образов, чтобы они могли расшифровать слои до распаковки. Если образ зашифрован с помощью нескольких ключей, команде pull можно передать несколько. Такая передача также поддерживается. После успешного извлечения зашифрованного образа из реестра любой пользователь, имеющий доступ к containerd, может создать контейнер из образа. Чтобы подтвердить, что пользователь имеет права на использование образа контейнера, мы предлагаем ему предоставить закрытые ключи, используемые для расшифровки контейнера. Мы используем ключи для проверки авторизации пользователя, могут ли они использоваться для расшифровки LEK каждого зашифрованного уровня, и если это подтверждается, разрешаем запуск контейнера.

Пошаговое руководство шифрования с использованием containerd


В этом разделе мы продемонстрируем шаги шифрования, которые применяются с containderd, используя ctr в командной строке. Мы покажем, как происходит шифрование и дешифрование образа контейнера.

В первую очередь, нужно клонировать репозиторий git containerd/imgcrypt, который является подпроектом и может шифровать/дешифровать образ контейнера. Затем необходимо собрать containerd и запустить его. Чтобы выполнить эти шаги, нужно знать, как настраивается среда разработки golang:

Для imgcrypt требуется использовать containerd версии не ниже 1.3.

Собираем и устанавливаем imgcrypt:

# make
# sudo make install

Запустите containerd с файлом конфигурации, который можно увидеть на примере ниже. Чтобы избежать возникновения конфликта в containerd, используйте директорию /tmp для каталогов. Также соберите containerd версии 1.3 из исходника, но не устанавливайте его.
# cat config.toml
disable_plugins = ["cri"]
root = "/tmp/var/lib/containerd"
state = "/tmp/run/containerd"
[grpc]
  address = "/tmp/run/containerd/containerd.sock"
  uid = 0
  gid = 0
[stream_processors]
    [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
        accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
        returns = "application/vnd.oci.image.layer.v1.tar+gzip"
        path = "/usr/local/bin/ctd-decoder"
    [stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
        accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
        returns = "application/vnd.oci.image.layer.v1.tar"
        path = "/usr/local/bin/ctd-decoder"
# sudo ~/src/github.com/containerd/containerd/bin/containerd -c config.toml

Создайте пару ключей RSA с помощью инструмента командной строки openssl и зашифруйте образ:
# openssl genrsa --out mykey.pem
Generating RSA private key, 2048 bit long modulus (2 primes)
...............................................+++++
............................+++++
e is 65537 (0x010001)
# openssl rsa -in mykey.pem -pubout -out mypubkey.pem
writing RSA key
# sudo chmod 0666 /tmp/run/containerd/containerd.sock
# CTR="/usr/local/bin/ctr-enc -a /tmp/run/containerd/containerd.sock"
# $CTR images pull --all-platforms docker.io/library/bash:latest
[...]
# $CTR images layerinfo --platform linux/amd64 docker.io/library/bash:latest
   #                                                                    DIGEST      PLATFORM      SIZE   ENCRYPTION   RECIPIENTS
   0   sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609   linux/amd64   2789669                          
   1   sha256:7dd01fd971d4ec7058c5636a505327b24e5fc8bd7f62816a9d518472bd9b15c0   linux/amd64   3174665                          
   2   sha256:691cfbca522787898c8b37f063dd20e5524e7d103e1a3b298bd2e2b8da54faf5   linux/amd64       340                          
# $CTR images encrypt --recipient jwe:mypubkey.pem --platform linux/amd64 docker.io/library/bash:latest bash.enc:latest
Encrypting docker.io/library/bash:latest to bash.enc:latest
$ $CTR images layerinfo --platform linux/amd64 bash.enc:latest
   #                                                                    DIGEST      PLATFORM      SIZE   ENCRYPTION   RECIPIENTS
   0   sha256:360be141b01f69b25427a9085b36ba8ad7d7a335449013fa6b32c1ecb894ab5b   linux/amd64   2789669          jwe        [jwe]
   1   sha256:ac601e66cdd275ee0e10afead03a2722e153a60982122d2d369880ea54fe82f8   linux/amd64   3174665          jwe        [jwe]
   2   sha256:41e47064fd00424e328915ad2f7f716bd86ea2d0d8315edaf33ecaa6a2464530   linux/amd64       340          jwe        [jwe]

Запустите локальный реестр образов, чтобы вы могли отправить в него зашифрованный образ. Для приема зашифрованных образов контейнеров нужны последние версии реестра.
# docker pull registry:latest
# docker run -d -p 5000:5000 --restart=always --name registry registry

Отправьте зашифрованный образ в локальный реестр, извлеките его с помощью ctr-enc, а затем запустите образ:
# $CTR images tag bash.enc:latest localhost:5000/bash.enc:latest
# $CTR images push localhost:5000/bash.enc:latest
# $CTR images rm localhost:5000/bash.enc:latest bash.enc:latest
# $CTR images pull localhost:5000/bash.enc:latest
# sudo $CTR run --rm localhost:5000/bash.enc:latest test echo 'Hello World!'
ctr: you are not authorized to use this image: missing private key needed for decryption
# sudo $CTR run --rm --key mykey.pem localhost:5000/bash.enc:latest test echo 'Hello World!'
Hello World!

Заключение


Шифрование образов контейнеров — это хорошее дополнение к их безопасности, оно обеспечивает конфиденциальность данных и целостность образов контейнеров в месте хранения. Предложенная технология основана на общедоступных технологиях шифрования RSA, эллиптической кривой и AES. Она применяет ключи к схемам шифрования более высокого уровня, таким как OpenPGP, JWE и PKCS#7. Если вы умеете работать с OpenPGP, вы можете шифровать образы контейнеров для получателей OpenPGP, используя их адреса электронной почты, в то время как простые ключи RSA и эллиптические кривые используются для шифрования, например, JWE.

Шифрование данных | ПК для всех

Многие задаются вопросом – “Как безопасно хранить данные на компьютере?”. Это очень важная проблема защиты Ваших данных и информации. Для ее решения, используются различные способы: скрытие, шифрование, резервное копирование и тд.

Сейчас мы рассмотри вариант хранения данных в зашифрованном контейнере. На данный момент шифрование данных – самый безопасный способ хранить и передавать информацию.

Для безопасного хранения данных мы создадим контейнер (файл) в котором данные (документы, личные фотографии и тд.) будет храниться в зашифрованном виде. Этот контейнер Вы сможете передавать по электронной почте, на флешке  и  прочими средствами передачи информации, не опасаясь, что кто-то украдет ваши данные. Даже если этот контейнер попадет в руки злоумышленников,  расшифровать информацию будет практически невозможно.

Для того, что бы создать зашифрованный контейнер мы будем использовать бесплатную программу TrueCrypt. В этой программе мы создадим зашифрованный контейнер и установим пароль для доступа к информации.

Установка и настройка TrueCrypt

Первым делом нам необходимо скачать и русифицировать программу TrueCrypt. Скачиваем последнюю версию программы и русификатор (в списке найдите русский язык и скачайте его).

Устанавливаем программу TrueCrypt.   На одном из этапов установки Ван нужно будет выбрать  «Install» или «Extract». Install – обычная установка программы, а Extract – переносная версия. Переносную версию программы можно скопировать на флешку и запускать с нее. Сейчас выберите Install.

Для русификации необходимо скопировать файл – русификатор в директорию с программой ( по умолчанию C:\Program Files\TrueCrypt  ). Теперь запускаем программу. При запуске TrueCrypt должна быть на русском.

Если после русификации она все еще на английском, то в меню программы выберите пункт Settings – Language и выберите русский язык.

Создание шифрованного контейнера

Приступим к созданию зашифрованного контейнера. Выбираем пункт создать том.

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

В разделе “Тип тома” нам предложат выбрать тип тома обычный (видимый)  и скрытый. Оставляем как указанно по умолчанию “Обычный том TrueCrypt” и движемся дальше.

В разделе “Размещение тома” укажите директорию или папку, в которой будет создан контейнер и его название. После создания вы можете перемещать шифрованный контейнер, как любой файл,  куда хотите.

В раздел “Алгоритм шифрования”  Вы можете выбрать алгоритм, по которому будет шифроваться данные. Я советую просто нажать далее.

Затем следует указать размер тома. Тут все зависит от свободного места на вашем диске и предназначения создаваемого контейнера. Если Вы хотите хранить там личные фото, то размер тома нужно выбрать несколько гигабайт (Гб), а для небольших текстовых документов достаточно будет 50 мегабайт. Но размер выбирайте, приблизительно прикинув размер всех данных, которые вы будите там хранить.  И если Вы в последствие хотите перенести этот том на другой компьютер через флешку, то размер контейнера не должен быть больше чем может вместить флешка.

Придумайте и введите пароль для открытия контейнера. Пароль должен быть очень надежный! Что бы получить надежный пароль воспользуетесь онлайн генератором паролей 

Теперь выберите файловую систему тома (по умолчанию FAT) и хаотично в течение 30 секунд водите внутри окна мастера создания томов.  Так вы увеличите стойкость тома к взлому. Теперь нажмите кнопку разместить. В зависимости от размера тома, нужно будет подождать некоторое время и вас шифрованный контейнер готов.

 

Работа с шифрованным контейнером

Отлично! Вы создали зашифрованный контейнер. Теперь давайте посмотрим, как с ним  работать. Как я уже говорил, контейнер ничем не отличается от файла или папки. Вы можете перенести его из одной папки в другую, копировать или удалить.

Для того что бы получить доступ к данным нам нужно открыть контейнер. Откройте программу TrueCrypt. Наймите на кнопку “Файл…” и укажите где находиться вас зашифрованный контейнер.

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

В операционной системе шифрованный контейнер отображается как один из разделов жесткого диска. Если Вы откроете “Компьютер”, то среди списка всех дисков появиться еще один. Вы можете сбрасывать любую информацию, а шифрование будет происходить автоматически. Кроме этого открыть шифрованный диск можно через окно программы TrueCrypt.  Для этого нужно нажать правой клавишей мыши на нужны диск и выбрать в меню пункт “Открыть”.

Что бы завершить работу с контейнером нужно в программе TrueCrypt выбрать нужный диск и нажать кнопку “Размонтировать”.

Шифрованные контейнер Вы можете переносить с одного компьютера на другой, открывать с флешки и никто не будет знать, что за информация в нем скрыта. Таким образом, Вы решаете проблему безопасного хранения любых данных и комбинируете все методы (скрытие, шифрование и копирование) одним действием.

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

Организация хранения большого количества небольших файлов в нескольких контейнерах с одной точкой монтирования. Как?

Есть примерно 1,5 терабайта аудио данных (аудиобиблиотеки, музыка и др) как в lossy так и в lossless, на данный момент файлов больше 200 тысяч. Есть как простаивающие данные, так и часто обновляющиеся (изменяются и добавляются новые). Эти данные бэкапятся в облако (зеркалятся между разными облачными дисками). Раньше (и пока что сейчас) данные хранились и бекапились в открытом виде (имею ввиду как есть — обычными файлами), чтобы их можно было просматривать/пользоваться (как в облаке так и локально) и редактировать.
Так как данных становится все больше, такой вариант хранения и бэкапов больше не устраивает, сейчас загрузка по сети занимает очень много времени (больше недели всей аудиотеки), при значительных изменениях (условно от 50Гб, хотя может быть и больше) частичная загрузка/синхронизация тоже идет долго. Фактически, при доступных 100Мбит/с средняя скорость загрузки ~13Мбит/с (это уже при отключении сверки файлов по md5).

Хочу перейти на хранение в динамических контейнерах (как локально, так и в облаке) и работать только локально примонтировав контейнер. Но тут появляется другая проблема хранения и передачи одного большого контейнера, который может легко запороться если начнутся проблемы с жестким диском и в целом тоже неудобен. Поэтому vhd, veracrypt и подобные решения не подходят.

Сейчас безуспешно ищу контейнер, который может разбиваться на части определенного размера и будет монтироваться как один диск, и в идеале будет безошибочно монтироваться при отсутствующих частях, допустим есть битый файл контейнера (часть контейнера), и контейнер будет монтироваться и работать корректно, но с отсутствием данных из битого файла. Есть ли вообще такой контейнер, который умеет так? Из систем используется как windows (10 версия), так и linux.

Я в принципе готов руками создавать отдельные контейнеры, заполнять их, главное чтобы они монтировались как один диск. Вроде как есть вариант хранения в нескольких vhd в soft raid 0, но даже если это работает все сломается при выходе из строя хотя бы одного контейнера

Используем TrueCrypt для хранения конфиденциальных данных

Утилиты

В ходе анализа работы вредоносного программного обеспечения достаточно часто бывает полезным запись циркулирующего сетевого

Windows

Содержание1 Зачем определять модель материнской платы2 Как определить модель материнской платы2.1 Сторонний софт2.2 Штатные

Windows

Содержание1 Общий план2 Возможности3 Ох нифига себе!4 Выводы Всем привет! Продолжаю делать обзоры на

Утилиты

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

Утилиты

Привет! То и дело возникают различного рода неполадки в системе или приложениях Windows и

Безопасность

Содержание1 Первый запуск программы2 Краткие настройки3 Экран блокировки Попалась на глаза интересная программа, пусть

Инфраструктура сборки проекта с docker / Хабр

На Хабре уже есть материалы про то, как настроить docker-контейнер для компиляции проекта. Например, Использование Docker для сборки и запуска проекта на C++. В этой статье, как и в предыдущей будет рассмотрен вопрос сборки проекта, но здесь я бы хотел выйти за рамки туториала и рассмотреть глубже вопросы использования контейнеров в таких задачах, а так же построения инфраструктуры сборки с docker.


Немного о docker

Для наглядности дальнейшего изложения необходимо привести описание некоторых компонент docker.


Image

Docker image это шаблон только для чтения с инструкциями по созданию контейнера. Для того, чтобы собрать image необходимо создать Dockerfile, в котором описываются все шаги сборки. Каждый такой шаг создает отдельный слой внутри image. Каждый последующий слой накладывается поверх всех предыдущих и содержит лишь изменения, которые необходимо внести в предшествующий слой.

Например, для Dockerfile:

FROM ubuntu:18.04
ADD app.sh /app
ENTRYPOINT  /bin/bash /app/app.sh

docker-образ будет иметь следующую структуру:

Слои внутри image кешируются и могут быть переиспользованы, если никаких изменений не обнаружено. Если слой меняется(добавляется/удаляется), то все последующие создаются с нуля. Для внесения изменений в образ контейнера (и соответственно в окружение запускаемого процесса) достаточно поправить Dockerfile и запустить сборку образа.


Контейнер

Docker контейнер — это запускаемый экземпляр image. Его можно создать, запустить, остановить, удалить и пр. По умолчанию, контейнеры изолированы друг от друга и хост-системы. При старте контейнер запускает команду, которая может быть указана в ENTRYPOINT или CMD, и останавливается при ее завершении. Допустимой является ситуация, когда присутствуют и CMD и ENTRYPOINT, как они взаимодействуют описано в документации.

При создании каждого контейнера добавляется новый слой поверх всех существующих. Он доступен для записи в текущем контейнере, и уничтожается вместе с контейнером. Все операции записи, создания новых файлов при работе контейнера применяются к этому слою, image всегда остается неизменным. Таким образом структура слоев созданного контейнера будет иметь вид:

При использовании команды docker run каждый раз будет создаваться новый контейнер, со своим слоем для записи. В задачах сборки это означает, что при каждом запуске будет создавать новое чистое окружение, которое никак не связано с предыдущими выполнениями. Список созданных контейнеров можно посмотреть, выполнив команду: docker container ls -a.


Собираем проект в контейнере

Для наглядности кратко опишем процесс сборки приложения в контейнере, более подробно этот процесс описан в статье 1 и статье 2.

Схематично возможные шаги по сборке приложения в docker можно представить следующим образом:

Разберем показанные этапы:


  1. Используем Dockerfile, который описывает окружение, команды для сборки и копирования результатов, и на его основе создаем образ контейнера.
  2. Применяем полученный образ для создания и запуска контейнера командой docker run. Монтируем в контейнер папку с исходниками и папку, куда будет скопирован результат сборки.
  3. После завершения работы контейнера артефакты сборки будут помещены в смонтрованную директорию.

Пример приведен в статье.

Так как здесь используется команда docker run, то для каждого запуска будет создаваться отдельный контейнер со своим слоем для записи, поэтому временные файлы из предыдущих сборок не попадут в текущую. Необходимо не забывать чистить остановленные контейнеры.

Монтирование директории с исходниками облегчает отладку сборки. Но несет риски — можно собрать релиз из кода, который не прошел проверку на качество, или вообще не добавлен в систему контроля версий. Чтобы этого избежать, можно при каждой сборке клонировать git-репозиторий внутрь контейнера, как, например, в файле:

FROM ubuntu:bionic

RUN apt-get update \
 && apt-get install -y apt-utils 

RUN  apt-get update \
  && apt-get install -y make gcc g++  qt5-default git

RUN mkdir -p /app/src

WORKDIR /app/build

# Собираем проект и копируем артефакты сборки
ENTRYPOINT git -C /app/src clone https://github.com/sqglobe/SimpleQtProject.git \
               && qmake  /app/src/SimpleQtProject/SimpleQtProject.pro \
               && make \
               && cp SimpleQtProject  /app/res/SimpleQtProject-ubuntu-bionic 

Здесь клонирование выполняется в ENTRYPOINT, а не в инструкции RUN, по причине кеширования. ENTRYPOINT выполняется всегда при запуске контейнера, а результат выполнения команды RUN может быть взят из кеша.


Инфраструктура для сборки

Для сборки проекта под разные операционные системы или дистрибутивы Linux может применяться некая конфигурация серверов (машин сборки, серверов с системой контроля версий и пр.). На практике мне приходилось сталкиваться со следующей инфраструктурой:

Здесь пользователь обращается к web-серверу, через который запускается сборка проекта на машинах с Ubuntu и Red Hat. Далее, на каждой машине выполняется клонирование git-репозитория с проектом во временную директорию и запускается сама сборка. Пользователь может скачать результирующие файлы с той же страницы, с которой и запускал весь процесс.

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

Из минусов — необходимо поддерживать целую инфраструктуру, администрировать несколько серверов, устранять баги в скриптах и web-приложении и пр.


Упрощаем с docker

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

Рассмотрим тривиальный Qt проект, который собирается с помощью qmake — SimpleQtProject. В папке docker указанного проекта находится ряд файлов:


  • centos7.docker — описывает контейнер для сборки проекта под CentOS 7;
  • ubuntu-bionic.docker — контейнер для сборки под Ubuntu 18.04;
  • ubuntu-xenial.docker — описывает контейнер для сборки под Ubuntu 16.04.

Данные файлы реализуют идею клонирования исходного кода внутрь контейнера.

Запускается вся сборка с помощью Makefile. Он очень короткий и содержит достаточно комментариев. Его основа — это создание образа и запуск контейнера:

%: %.docker
    docker build -t  simple-qt-$(strip $(subst .docker,, $< )) --file $< . 
    docker run --mount type=bind,source=$(RELEASE_DIR),target=/app/res simple-qt-$(strip $(subst .docker,, $< ))

В этом этапе сборки создается образ контейнера с именем, состоящим из префикса simple-qt- и названия системы (для centos 7 это будет simple-qt-centos7). В качестве Dockerfile используется соответствующий файл с разрешением .docker. Далее запускается контейнер на основе созданного образа, и к нему монтируется папка для копирования артефактов сборки.

После запуска команды make в директории docker, в папке docker/releases будут находится результаты сборки под несколько платформ.

Таким образом наша инфраструктура для сборки SimpleQtProject будет выглядеть следующим образом:

Достоинства данной конфигурации:


  1. Локальность. Разработчик собирает проект для нескольких платформ на своей локальной машине, это исключает необходимость содержать парк серверов, настраивать копирование артефактов между серверами по сети, отправку и обработку сетевых команд.
  2. Изоляция окружения. Контейнер обеспечивает полностью изолированную среду для сборки конкретного приложения. Есть возможность обеспечить сборку проектов с несовместимыми окружениями на одной машине (например таких, которые требуют различных версий одной и той же библиотеки).
  3. Версионирование. Поместив Dockerfile в git-репозиторий, можно отслеживать изменения в среде сборки с выходом новых релизов, откатываться к предыдущим версиям среды сборки и пр.
  4. Мобильность. При необходимости данная инфраструктура без особых проблем разворачивается на другом компьютере. Технология создания образа контейнера позволяет вносить изменения в сам образ очень легко — достаточно обновить Dockerfile и запустить сборку образа.
  5. Самодокументируемость. По сути, Dockerfile содержит шаги для развертывания окружения сборки. Поэтому, при необходимости развернуть такое окружение, но уже в обычной системе, можно воспользоваться командами из него же.
  6. Легковесность. Контейнер запускается в момент начала сборки и останавливается по ее завершению автоматически. Он не тратит процессорное время и оперативную память впустую.

Однако есть и существенный минус — сборка проекта потребует и сборки образа контейнера. При первом запуске это может занять продолжительное время. Но при повторных, особенно если Dockerfile не менялся, образ собирается с использованием кеша в разы быстрее.

Так же необходимо не забывать очищать остановленные контейнеры.


Заключение

В заключении хотелось бы отметить, что docker является не единственной технологией контейнеризации. Но есть некоторые особенности, которые его выгодно отличают для задач сборки от того же LXC:


  1. Создать контейнер можно используя текстовый Dockerfile. Это файл с простым синтаксисом, его можно добавить в репозиторий с проектом (как я всегда делаю) и держать постоянно под рукой.
  2. Каждый раз, запуская контейнер docker командой docker run мы получаем чистую среду, как если бы выполняли все в первый раз. Временные файлы между сборками не сохраняются.
  3. Контейнер запускет не целую операционную систему, а только необходимый процесс сборки.

файлы Dockerfile / Блог компании RUVDS.com / Хабр

В переводе третьей части серии материалов, посвящённых Docker, мы продолжим вдохновляться выпечкой, а именно — бубликами. Нашей сегодняшней основной темой будет работа с файлами Dockerfile. Мы разберём инструкции, которые используются в этих файлах.

→ Часть 1: основы
→ Часть 2: термины и концепции
→ Часть 3: файлы Dockerfile
→ Часть 4: уменьшение размеров образов и ускорение их сборки
→ Часть 5: команды
→ Часть 6: работа с данными


Бублики — это инструкции в файле Dockerfile

Образы Docker


Вспомните о том, что контейнер Docker — это образ Docker, вызванный к жизни. Это — самодостаточная операционная система, в которой имеется только самое необходимое и код приложения.

Образы Docker являются результатом процесса их сборки, а контейнеры Docker — это выполняющиеся образы. В самом сердце Docker находятся файлы Dockerfile. Подобные файлы сообщают Docker о том, как собирать образы, на основе которых создаются контейнеры.

Каждому образу Docker соответствует файл, который называется Dockerfile. Его имя записывается именно так — без расширения. При запуске команды docker build для создания нового образа подразумевается, что Dockerfile находится в текущей рабочей директории. Если этот файл находится в каком-то другом месте, его расположение можно указать с использованием флага -f.

Контейнеры, как мы выяснили в первом материале этой серии, состоят из слоёв. Каждый слой, кроме последнего, находящегося поверх всех остальных, предназначен только для чтения. Dockerfile сообщает системе Docker о том, какие слои и в каком порядке надо добавить в образ.

Каждый слой, на самом деле, это всего лишь файл, который описывает изменение состояния образа в сравнении с тем состоянием, в котором он пребывал после добавления предыдущего слоя. В Unix, кстати, практически всё что угодно — это файл.

Базовый образ — это то, что является исходным слоем (или слоями) создаваемого образа. Базовый образ ещё называют родительским образом.


Базовый образ — это то, с чего начинается образ Docker

Когда образ загружается из удалённого репозитория на локальный компьютер, то физически скачиваются лишь слои, которых на этом компьютере нет. Docker стремится экономить пространство и время путём повторного использования существующих слоёв.

Файлы Dockerfile


В файлах Dockerfile содержатся инструкции по созданию образа. С них, набранных заглавными буквами, начинаются строки этого файла. После инструкций идут их аргументы. Инструкции, при сборке образа, обрабатываются сверху вниз. Вот как это выглядит:
FROM ubuntu:18.04
COPY . /app

Слои в итоговом образе создают только инструкции FROM, RUN, COPY, и ADD. Другие инструкции что-то настраивают, описывают метаданные, или сообщают Docker о том, что во время выполнения контейнера нужно что-то сделать, например — открыть какой-то порт или выполнить какую-то команду.

Здесь мы исходим из предположения, в соответствии с которым используется образ Docker, основанный на Unix-подобной ОС. Конечно, тут можно воспользоваться и образом, основанным на Windows, но использование Windows — это менее распространённая практика, работать с такими образами сложнее. В результате, если у вас есть такая возможность, пользуйтесь Unix.

Для начала приведём список инструкций Dockerfile с краткими комментариями.

Дюжина инструкций Dockerfile


  1. FROM — задаёт базовый (родительский) образ.
  2. LABEL — описывает метаданные. Например — сведения о том, кто создал и поддерживает образ.
  3. ENV — устанавливает постоянные переменные среды.
  4. RUN — выполняет команду и создаёт слой образа. Используется для установки в контейнер пакетов.
  5. COPY — копирует в контейнер файлы и папки.
  6. ADD — копирует файлы и папки в контейнер, может распаковывать локальные .tar-файлы.
  7. CMD — описывает команду с аргументами, которую нужно выполнить когда контейнер будет запущен. Аргументы могут быть переопределены при запуске контейнера. В файле может присутствовать лишь одна инструкция CMD.
  8. WORKDIR — задаёт рабочую директорию для следующей инструкции.
  9. ARG — задаёт переменные для передачи Docker во время сборки образа.
  10. ENTRYPOINT — предоставляет команду с аргументами для вызова во время выполнения контейнера. Аргументы не переопределяются.
  11. EXPOSE — указывает на необходимость открыть порт.
  12. VOLUME — создаёт точку монтирования для работы с постоянным хранилищем.

Теперь поговорим об этих инструкциях.

Инструкции и примеры их использования


▍Простой Dockerfile


Dockerfile может быть чрезвычайно простым и коротким. Например — таким:
FROM ubuntu:18.04

▍Инструкция FROM


Файл Dockerfile должен начинаться с инструкции FROM, или с инструкции ARG, за которой идёт инструкция FROM.

Ключевое слово FROM сообщает Docker о том, чтобы при сборке образа использовался бы базовый образ, который соответствует предоставленному имени и тегу. Базовый образ, кроме того, ещё называют родительским образом.

В этом примере базовый образ хранится в репозитории ubuntu. Ubuntu — это название официального репозитория Docker, предоставляющего базовую версию популярной ОС семейства Linux, которая называется Ubuntu.

Обратите внимание на то, что рассматриваемый Dockerfile включает в себя тег 18.04, уточняющий то, какой именно базовый образ нам нужен. Именно этот образ и будет загружен при сборке нашего образа. Если тег в инструкцию не включён, тогда Docker исходит из предположения о том, что требуется самый свежий образ из репозитория. Для того чтобы яснее выразить свои намерения, автору Dockerfile рекомендуется указывать то, какой именно образ ему нужен.

Когда вышеописанный Dockerfile используется на локальной машине для сборки образа в первый раз, Docker загрузит слои, определяемые образом ubuntu. Их можно представить наложенными друг на друга. Каждый следующий слой представляет собой файл, описывающий отличия образа в сравнении с тем его состоянием, в котором он был после добавления в него предыдущего слоя.

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


Структура контейнера (взято из документации)

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

Когда образ выполняется, если слой нужно модифицировать средствами контейнера, то соответствующий файл копируется в самый верхний, изменяемый слой. Для того чтобы узнать подробности о стратегии копирования при записи, взгляните на этот материал из документации Docker.

Продолжим рассмотрение инструкций, которые используются в Dockerfile, приведя пример такого файла с более сложной структурой.

▍Более сложный Dockerfile


Хотя файл Dockerfile, который мы только что рассмотрели, получился аккуратным и понятным, он устроен слишком просто, в нём используется всего одна инструкция. Кроме того, там нет инструкций, вызываемых во время выполнения контейнера. Взглянем на ещё один файл, который собирает маленький образ. В нём имеются механизмы, определяющие команды, вызываемые во время выполнения контейнера.
FROM python:3.7.2-alpine3.8
LABEL maintainer="[email protected]"
ENV ADMIN="jeff"
RUN apk update && apk upgrade && apk add bash
COPY . ./app
ADD https://raw.githubusercontent.com/discdiver/pachy-vid/master/sample_vids/vid1.mp4 \
/my_app_directory
RUN ["mkdir", "/a_directory"]
CMD ["python", "./my_script.py"]

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

Базой этого образа является официальный образ Python с тегом 3.7.2-alpine3.8. Проанализировав этот код можно увидеть, что данный базовый образ включает в себя Linux, Python, и, по большому счёту, этим его состав и ограничивается. Образы ОС Alpine весьма популярны в мире Docker. Дело в том, что они отличаются маленькими размерами, высокой скоростью работы и безопасностью. Однако образы Alpine не отличаются широкими возможностями, характерными для обычных операционных систем. Поэтому для того, чтобы собрать на основе такого образа что-то полезное, создателю образа нужно установить в него необходимые ему пакеты.

▍Инструкция LABEL



Метки

Инструкция LABEL (метка) позволяет добавлять в образ метаданные. В случае с рассматриваемым сейчас файлом, она включает в себя контактные сведения создателя образа. Объявление меток не замедляет процесс сборки образа и не увеличивает его размер. Они лишь содержат в себе полезную информацию об образе Docker, поэтому их рекомендуется включать в файл. Подробности о работе с метаданными в Dockerfile можно прочитать здесь.

▍Инструкция ENV



Окружающая среда

Инструкция ENV позволяет задавать постоянные переменные среды, которые будут доступны в контейнере во время его выполнения. В предыдущем примере после создания контейнера можно пользоваться переменной ADMIN.

Инструкция ENV хорошо подходит для задания констант. Если вы используете некое значение в Dockerfile несколько раз, скажем, при описании команд, выполняющихся в контейнере, и подозреваете, что, возможно, вам когда-нибудь придётся сменить его на другое, его имеет смысл записать в подобную константу.

Надо отметить, что в файлах Dockerfile часто существуют разные способы решения одних и тех же задач. Что именно использовать — это вопрос, на решение которого влияет стремление к соблюдению принятых в среде Docker методов работы, к обеспечению прозрачности решения и его высокой производительности. Например, инструкции RUN, CMD и ENTRYPOINT служат разным целям, но все они используются для выполнения команд.

▍Инструкция RUN



Инструкция RUN

Инструкция RUN позволяет создать слой во время сборки образа. После её выполнения в образ добавляется новый слой, его состояние фиксируется. Инструкция RUN часто используется для установки в образы дополнительных пакетов. В предыдущем примере инструкция RUN apk update && apk upgrade сообщает Docker о том, что системе нужно обновить пакеты из базового образа. Вслед за этими двумя командами идёт команда && apk add bash, указывающая на то, что в образ нужно установить bash.

То, что в командах выглядит как apk — это сокращение от Alpine Linux package manager (менеджер пакетов Alpine Linux). Если вы используете базовый образ какой-то другой ОС семейства Linux, тогда вам, например, при использовании Ubuntu, для установки пакетов может понадобиться команда вида RUN apt-get. Позже мы поговорим о других способах установки пакетов.

Инструкция RUN и схожие с ней инструкции — такие, как CMD и ENTRYPOINT, могут быть использованы либо в exec-форме, либо в shell-форме. Exec-форма использует синтаксис, напоминающий описание JSON-массива. Например, это может выглядеть так: RUN ["my_executable", "my_first_param1", "my_second_param2"].

В предыдущем примере мы использовали shell-форму инструкции RUN в таком виде: RUN apk update && apk upgrade && apk add bash.

Позже в нашем Dockerfile использована exec-форма инструкции RUN, в виде RUN ["mkdir", "/a_directory"] для создания директории. При этом, используя инструкцию в такой форме, нужно помнить о необходимости оформления строк с помощью двойных кавычек, как это принято в формате JSON.

▍Инструкция COPY



Инструкция COPY

Инструкция COPY представлена в нашем файле так: COPY . ./app. Она сообщает Docker о том, что нужно взять файлы и папки из локального контекста сборки и добавить их в текущую рабочую директорию образа. Если целевая директория не существует, эта инструкция её создаст.

▍Инструкция ADD


Инструкция ADD позволяет решать те же задачи, что и COPY, но с ней связана ещё пара вариантов использования. Так, с помощью этой инструкции можно добавлять в контейнер файлы, загруженные из удалённых источников, а также распаковывать локальные .tar-файлы.

В этом примере инструкция ADD была использована для копирования файла, доступного по URL, в директорию контейнера my_app_directory. Надо отметить, однако, что документация Docker не рекомендует использование подобных файлов, полученных по URL, так как удалить их нельзя, и так как они увеличивают размер образа.

Кроме того, документация предлагает везде, где это возможно, вместо инструкции ADD использовать инструкцию COPY для того, чтобы сделать файлы Dockerfile понятнее. Полагаю, команде разработчиков Docker стоило бы объединить ADD и COPY в одну инструкцию для того, чтобы тем, кто создаёт образы, не приходилось бы помнить слишком много инструкций.

Обратите внимание на то, что инструкция ADD содержит символ разрыва строки — \. Такие символы используются для улучшения читабельности длинных команд путём разбиения их на несколько строк.

▍Инструкция CMD



Инструкция CMD

Инструкция CMD предоставляет Docker команду, которую нужно выполнить при запуске контейнера. Результаты выполнения этой команды не добавляются в образ во время его сборки. В нашем примере с помощью этой команды запускается скрипт my_script.py во время выполнения контейнера.

Вот ещё кое-что, что нужно знать об инструкции CMD:

  • В одном файле Dockerfile может присутствовать лишь одна инструкция CMD. Если в файле есть несколько таких инструкций, система проигнорирует все кроме последней.
  • Инструкция CMD может иметь exec-форму. Если в эту инструкцию не входит упоминание исполняемого файла, тогда в файле должна присутствовать инструкция ENTRYPOINT. В таком случае обе эти инструкции должны быть представлены в формате JSON.
  • Аргументы командной строки, передаваемые docker run, переопределяют аргументы, предоставленные инструкции CMD в Dockerfile.

▍Ещё более сложный Dockerfile


Рассмотрим ещё один файл Dockerfile, в котором будут использованы некоторые новые команды.
FROM python:3.7.2-alpine3.8
LABEL maintainer="[email protected]"
# Устанавливаем зависимости
RUN apk add --update git
# Задаём текущую рабочую директорию
WORKDIR /usr/src/my_app_directory
# Копируем код из локального контекста в рабочую директорию образа
COPY . .
# Задаём значение по умолчанию для переменной
ARG my_var=my_default_value
# Настраиваем команду, которая должна быть запущена в контейнере во время его выполнения
ENTRYPOINT ["python", "./app/my_script.py", "my_var"]
# Открываем порты
EXPOSE 8000
# Создаём том для хранения данных
VOLUME /my_volume

В этом примере, кроме прочего, вы можете видеть комментарии, которые начинаются с символа #.
Одно из основных действий, выполняемых средствами Dockerfile — это установка пакетов. Как уже было сказано, существуют различные способы установки пакетов с помощью инструкции RUN.

Пакеты в образ Alpine Docker можно устанавливать с помощью apk. Для этого, как мы уже говорили, применяется команда вида RUN apk update && apk upgrade && apk add bash.

Кроме того, пакеты Python в образ можно устанавливать с помощью pip, wheel и conda. Если речь идёт не о Python, а о других языках программирования, то при подготовке соответствующих образов могут использоваться и другие менеджеры пакетов.

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

Например, инструкцию RUN в Dockerfile можно использовать для установки списка пакетов с помощью pip. Если вы так поступаете — объедините все команды в одну инструкцию и разделите её символами разрыва строки с помощью символа \. Благодаря такому подходу файлы будут выглядеть аккуратно и это приведёт к добавлению в образ меньшего количества слоёв, чем было бы добавлено при использовании нескольких инструкций RUN.

Кроме того, для установки нескольких пакетов можно поступить и по-другому. Их можно перечислить в файле и передать менеджеру пакетов этот файл с помощью RUN. Обычно таким файлам дают имя requirements.txt.

▍Инструкция WORKDIR



Рабочие директории

Инструкция WORKDIR позволяет изменить рабочую директорию контейнера. С этой директорией работают инструкции COPY, ADD, RUN, CMD и ENTRYPOINT, идущие за WORKDIR. Вот некоторые особенности, касающиеся этой инструкции:

  • Лучше устанавливать с помощью WORKDIR абсолютные пути к папкам, а не перемещаться по файловой системе с помощью команд cd в Dockerfile.
  • Инструкция WORKDIR автоматически создаёт директорию в том случае, если она не существует.
  • Можно использовать несколько инструкций WORKDIR. Если таким инструкциям предоставляются относительные пути, то каждая из них меняет текущую рабочую директорию.

▍Инструкция ARG


Инструкция ARG позволяет задать переменную, значение которой можно передать из командной строки в образ во время его сборки. Значение для переменной по умолчанию можно представить в Dockerfile. Например: ARG my_var=my_default_value.

В отличие от ENV-переменных, ARG-переменные недоступны во время выполнения контейнера. Однако ARG-переменные можно использовать для задания значений по умолчанию для ENV-переменных из командной строки в процессе сборки образа. А ENV-переменные уже будут доступны в контейнере во время его выполнения. Подробности о такой методике работы с переменными можно почитать здесь.

▍Инструкция ENTRYPOINT



Пункт перехода в какое-то место

Инструкция ENTRYPOINT позволяет задавать команду с аргументами, которая должна выполняться при запуске контейнера. Она похожа на команду CMD, но параметры, задаваемые в ENTRYPOINT, не перезаписываются в том случае, если контейнер запускают с параметрами командной строки.

Вместо этого аргументы командной строки, передаваемые в конструкции вида docker run my_image_name, добавляются к аргументам, задаваемым инструкцией ENTRYPOINT. Например, после выполнения команды вида docker run my_image bash аргумент bash добавится в конец списка аргументов, заданных с помощью ENTRYPOINT. Готовя Dockerfile, не забудьте об инструкции CMD или ENTRYPOINT.

В документации к Docker есть несколько рекомендаций, касающихся того, какую инструкцию, CMD или ENTRYPOINT, стоит выбрать в качестве инструмента для выполнения команд при запуске контейнера:

  • Если при каждом запуске контейнера нужно выполнять одну и ту же команду — используйте ENTRYPOINT.
  • Если контейнер будет использоваться в роли приложения — используйте ENTRYPOINT.
  • Если вы знаете, что при запуске контейнера вам понадобится передавать ему аргументы, которые могут перезаписывать аргументы, указанные в Dockerfile, используйте CMD.

В нашем примере использование инструкции ENTRYPOINT ["python", "my_script.py", "my_var"] приводит к тому, что контейнер, при запуске, запускает Python-скрипт my_script.py с аргументом my_var. Значение, представленное my_var, потом можно использовать в скрипте с помощью argparse. Обратите внимание на то, что в Dockerfile переменной my_var, до её использования, назначено значение по умолчанию с помощью ARG. В результате, если при запуске контейнера ему не передали соответствующее значение, будет применено значение по умолчанию.

Документация Docker рекомендует использовать exec-форму ENTRYPOINT: ENTRYPOINT ["executable", "param1", "param2"].

▍Инструкция EXPOSE



Инструкция EXPOSE

Инструкция EXPOSE указывает на то, какие порты планируется открыть для того, чтобы через них можно было бы связаться с работающим контейнером. Эта инструкция не открывает порты. Она, скорее, играет роль документации к образу, средством общения того, кто собирает образ, и того, кто запускает контейнер.

Для того чтобы открыть порт (или порты) и настроить перенаправление портов, нужно выполнить команду docker run с ключом -p. Если использовать ключ в виде -P (с заглавной буквой P), то открыты будут все порты, указанные в инструкции EXPOSE.

▍Инструкция VOLUME



Инструкция VOLUME

Инструкция VOLUME позволяет указать место, которое контейнер будет использовать для постоянного хранения файлов и для работы с такими файлами. Об этом мы ещё поговорим.

Итоги


Теперь вы знаете дюжину инструкций, применяемых при создании образов с помощью Dockerfile. Этим список таких инструкций не исчерпывается. В частности, мы не рассмотрели здесь такие инструкции, как USER, ONBUILD, STOPSIGNAL, SHELL и HEALTHCHECK. Вот краткий справочник по инструкциям Dockerfile.

Вероятно, файлы Dockerfile — это ключевой компонент экосистемы Docker, работать с которым нужно научиться всем, кто хочет уверенно чувствовать себя в этой среде. Мы ещё вернёмся к разговору о них в следующий раз, когда будем обсуждать способы уменьшения размеров образов.

Уважаемые читатели! Если вы пользуетесь Docker на практике, просим рассказать о том, как вы пишете Docker-файлы.

файл-контейнер — это … Что такое файл-контейнер?

  • Формат контейнера (цифровой) — Формат контейнера или оболочки — это формат метафайла, спецификация которого описывает сосуществование различных элементов данных и метаданных в компьютерном файле. Среди первых кроссплатформенных контейнерных форматов были Distinguished Encoding Rules и…… Wikipedia

  • Формат файла — Формат файла — это особый способ кодирования информации для хранения в компьютерном файле.Поскольку диск или любое другое компьютерное хранилище может хранить только биты, компьютер должен каким-то образом преобразовывать информацию в нули, единицы и наоборот … Wikipedia

  • Контейнер — может относиться к: Предметам, используемым для содержания, хранения и транспортировки продуктов, таких как: Картонная бутылка Банка (значения), несколько значений Транспортные контейнеры включают Ящик Деревянный ящик Интермодальный контейнер, также известный как Судовой контейнер или Грузовой контейнер Двадцать футов … Википедия

  • Служба репликации файлов — это служба Microsoft Windows Server для распространения общих файлов и объектов групповой политики.Он заменил (Windows NT) службу репликации Lan Manager [1] и был частично заменен репликацией распределенной файловой системы. Это также…… Википедия

  • файл — файл1 [файл] vt. подана, подача [ME filen & LT; OFr filer, чтобы связать документы в потоке, ориг., Чтобы развернуть поток & LT; LL filare, вращать и LT; L нить, нить и LT; База IE * gwhislo & GT; Lith gýsla, сухожилие] 1. а) оформить (бумаги и т. Д.) Для…… English World Dictionary

  • Контейнерный формат — может означать: Формат записи, для хранения аналоговых или цифровых записанных данных на носителе записи Контейнерный формат (цифровой), для хранения данных, закодированных в цифровом виде, в виде файла данных программного обеспечения. Формат сигнала носителя, для хранения данные во время…… Wikipedia

  • файл — файл1 [faıl] количество существительных *** 1.) набор бумаг, документов или записей, которые вы храните, потому что они содержат информацию: страховая компания может захотеть проверить ваши медицинские карты. Досье на: Полицейское дело по этому конкретному делу теперь…… Использование слов и фраз на современном английском языке

  • файл — I UK [faɪl] / US существительное [исчисляемое] Файл форм слов: файл в единственном числе файлы во множественном числе *** 1) a) набор бумаг, документов или записей, которые вы храните, потому что они содержат информацию. компания может захотеть проверить вашу медицинскую карту.keep / hold a… Английский словарь

  • файл * / * / * / — [faɪl] существительное [C] I 1) набор документов или записей, которые вы храните, потому что они содержат медицинские файлы информации [/ ex] У нас есть все ваши данные в файле (= хранится в досье). [/ ex] Полицейское дело по делу закрыто. [/ ex] 2) набор…… словаря для письменной и устной речи на английском языке

  • Таблица размещения файлов — Для использования в других целях, см. Жир (значения). FAT Developer Microsoft Full Name File Allocation Table FAT12 (12-битная версия) FAT16 / FAT16B (16-битные версии) FAT32 (32-битная версия с использованием 28 битов) Представлено… Wikipedia

  • файл — ▪ I.file file 1 [faɪl] имя существительное [исчисляемо] 1. информация о человеке или субъекте, которая хранится в компании или другой организации: • Я вижу из своих файлов, что мы все еще не получили от вас платеж. • Кредитно-справочное агентство — это компания…… Финансовые и коммерческие условия

  • .

    Расширенная конфигурация контейнера

    В этой статье представлены сценарии расширенной настройки для расширения Visual Studio Code Remote — Containers. Дополнительную информацию см. В статье «Разработка внутри контейнера».

    Добавление переменных среды

    Вы можете установить переменные среды в своем контейнере, не изменяя образ контейнера, используя одну из опций ниже. Однако вам следует убедиться, что Terminal> Integrated: Inherit Env отмечен в настройках, иначе установленные вами переменные могут не отображаться в интегрированном терминале.

    Вариант 1: Добавить отдельные переменные

    В зависимости от того, на что вы ссылаетесь в devcontainer.json :

    • Dockerfile или образ : добавьте свойство containerEnv в devcontainer.json , чтобы установить переменные, которые должны применяться ко всему контейнеру, или remoteEnv , чтобы установить переменные для VS Code и связанных подпроцессов (терминалы, задачи, отладка и т. д.):

        "containerEnv": {
          "MY_CONTAINER_VAR": "здесь какое-то значение",
          "MY_CONTAINER_VAR2": "$ {localEnv: SOME_LOCAL_VAR}"
      },
      "remoteEnv": {
          "ПУТЬ": "$ {containerEnv: PATH}: / some / other / path",
          "MY_REMOTE_VARIABLE": "здесь какое-то другое значение",
          "MY_REMOTE_VARIABLE2": "$ {localEnv: SOME_LOCAL_VAR}"
      }  

      Как показывает этот пример, containerEnv может ссылаться на локальные переменные, а remoteEnv может ссылаться как на локальные, так и на существующие переменные контейнера.

    • Docker Compose : поскольку Docker Compose имеет встроенную поддержку для обновления переменных всего контейнера, только remoteEnv поддерживается в devcontainer.json :

        "remoteEnv": {
          "ПУТЬ": "$ {containerEnv: PATH}: / some / other / path",
          "MY_REMOTE_VARIABLE": "здесь какое-то другое значение",
          "MY_REMOTE_VARIABLE2": "$ {localEnv: SOME_LOCAL_VAR}"
      }  

      Как показано в этом примере, remoteEnv может ссылаться как на локальные, так и на существующие переменные контейнера.

      Чтобы обновить переменные, которые применяются ко всему контейнеру, обновите (или расширите) ваш docker-compose.yml следующим образом для соответствующей службы:

        версия: '3'
      Сервисы:
        ваше-имя-услуги-здесь:
          среда:
            - YOUR_ENV_VAR_NAME = ваша ценность здесь
            - ANOTHER_VAR = другое значение
           # ...  

    Если вы уже создали контейнер и подключились к нему, запустите Remote-Containers: Rebuild Container из палитры команд (F1), чтобы принять изменения.В противном случае запустите Remote-Containers: Open Folder in Container … , чтобы подключиться к контейнеру.

    Вариант 2. Используйте файл env

    Если у вас есть большое количество переменных среды, которые вам нужно установить, вы можете вместо этого использовать файл .env . VS Code автоматически подберет файл с именем .env в корне вашей рабочей области, но вы также можете создать его в другом месте.

    Сначала создайте файл среды где-нибудь в дереве исходного кода. Рассмотрим этот .devcontainer / devcontainer.env файл:

      YOUR_ENV_VAR_NAME = ваша ценность здесь
    ANOTHER_ENV_VAR_NAME = ваша ценность здесь
      

    Далее, в зависимости от того, на что вы ссылаетесь в devcontainer.json :

    • Dockerfile или образ : отредактируйте devcontainer.json и добавьте путь к файлу .env относительно расположения devcontainer.json :

        «runArgs»: [«--env-file», «devcontainer.env "]  
    • Docker Compose: Отредактируйте docker-compose.yml и добавьте путь к файлу .env относительно файла Docker Compose:

        версия: '3'
      Сервисы:
        ваше-имя-услуги-здесь:
          env_file: devcontainer.env
          # ...  

    Если вы уже создали контейнер и подключились к нему, запустите Remote-Containers: Rebuild Container из палитры команд (F1), чтобы принять изменения.В противном случае запустите Remote-Containers: Open Folder in Container … , чтобы подключиться к контейнеру.

    Добавление еще одного локального файла при монтировании

    Вы можете добавить том, привязанный к любой локальной папке, выполнив следующие соответствующие шаги в зависимости от того, что вы ссылаетесь на devcontainer.json :

    • Dockerfile или образ : добавьте следующее в свойство mounts (VS Code 1.41+) в том же файле:

        "крепления": [
        "источник = / локальный / источник / путь / идет / сюда, цель = / цель / путь / в / контейнер / идет / сюда, тип = привязка, согласованность = кэширование"
      ]  

      Вы также можете ссылаться на локальные переменные среды или локальный путь к рабочей области.Например, это свяжет монтирование ~ ( $ HOME ) в macOS / Linux и папку пользователя (% USERPROFILE% ) в Windows и подпапку в рабочей области в другое место:

        "крепления": [
          "source = $ {localEnv: HOME} $ {localEnv: USERPROFILE}, target = / host-home-folder, type = bind, consistency = cached",
          "source = $ {localWorkspaceFolder} / app-data, target = / data, type = bind, consistency = cached"
      ]  
    • Docker Compose: Обновите (или расширите) файл docker-compose.yml со следующим для соответствующей службы:

        версия: '3'
      Сервисы:
        ваше-имя-услуги-здесь:
          объемы:
            - / локальный / источник / путь / идет / здесь: / цель / путь / в / контейнер / идет / здесь: кэшировано
            - ~: / домашняя-хост-папка: кэшировано
            - ./data-subfolder:/data:cached
           # ...  

    Если вы уже создали контейнер и подключились к нему, запустите Remote-Containers: Rebuild Container из палитры команд (F1), чтобы принять изменения.В противном случае запустите Remote-Containers: Open Folder in Container … , чтобы подключиться к контейнеру.

    Persist bash история между прогонами

    Вы также можете использовать монтирование для сохранения истории команд bash во время сеансов / перестроек контейнеров.

    Во-первых, обновите свой Dockerfile , чтобы каждый раз, когда команда используется в bash , история обновлялась и сохранялась в месте, где мы будем сохраняться. Замените user-name-go-here именем пользователя без полномочий root в контейнере (если таковой существует).

      ARG USERNAME = имя-пользователя-идет-сюда
    
    RUN SNIPPET = "export PROMPT_COMMAND = 'history -a' && export HISTFILE = / commandhistory / .bash_history" \
        && echo $ SNIPPET >> "/root/.bashrc" \
        # [Необязательно] Если у вас есть пользователь без полномочий root
        && mkdir / история команд \
        && touch /commandhistory/.bash_history \
        && chown -R $ ИМЯ ПОЛЬЗОВАТЕЛЯ / история команды \
        && echo $ SNIPPET >> "/ home / $ USERNAME /.Башрц " 

    Затем добавьте локальный том для хранения истории команд. Этот шаг зависит от того, используете вы Docker Compose или нет.

    • Dockerfile или образ : используйте свойство mounts (VS Code 1.41+) в файле devcontainer.json . Замените user-name-go-here именем пользователя без полномочий root в контейнере (если таковой существует).

        "крепления": [
            "source = имя проекта-bashhistory, target = / commandhistory, type = volume"
        ]  
    • Docker Compose: Обновите (или расширите) файл docker-compose.yml со следующими данными для соответствующей службы. Замените user-name-go-here именем пользователя без полномочий root в контейнере (если таковой существует).

        версия: '3'
      Сервисы:
        ваше-имя-услуги-здесь:
          объемы:
            - имя проекта-bashhistory: / commandhistory
           # ...
      объемы:
        история проекта:  

    Наконец, если вы уже создали контейнер и подключились к нему, запустите Remote-Containers: Rebuild Container из палитры команд (F1), чтобы принять изменение.В противном случае запустите Remote-Containers: Open Folder in Container … , чтобы подключиться к контейнеру.

    Изменение исходного кода по умолчанию mount

    Если вы добавите свойства image или dockerFile в devcontainer.json , VS Code автоматически «привяжет» монтирование вашей текущей папки рабочей области к контейнеру. Если git присутствует на хосте PATH , а папка, содержащая ./devcontainer/devcontainer.json , находится в репозитории git , текущее смонтированное рабочее пространство будет корнем репозитория.Если git отсутствует в PATH хоста , текущее смонтированное рабочее пространство будет папкой, содержащей ./devcontainer/devcontainer.json .

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

    Вы можете использовать свойство workspaceMount в devcontainer.json , чтобы изменить поведение автоматического монтирования. Он ожидает того же значения, что и флаг Docker CLI --mount .

    Например:

      "workspaceMount": "источник = $ {localWorkspaceFolder} / подпапка, цель = / рабочая область, тип = привязка, согласованность = делегировано",
    "workspaceFolder": "/ workspace"  

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

    Если вы уже создали контейнер и подключились к нему, запустите Remote-Containers: Rebuild Container из палитры команд (F1), чтобы применить изменения.В противном случае запустите Remote-Containers: Open Folder in Container ... , чтобы подключиться к контейнеру.

    Повышение производительности диска контейнера

    Расширение Remote - Containers по умолчанию использует «привязку монтирования» к исходному коду в вашей локальной файловой системе. Хотя это самый простой вариант, в macOS и Windows вы можете столкнуться с более низкой производительностью диска при выполнении таких команд, как yarn install из контейнера. Есть несколько способов решения подобных проблем.

    Сохраните исходный код в файловой системе WSL 2 в Windows

    Windows 10 2004 и выше включает улучшенную версию подсистемы Windows для Linux (WSL 2), которая предоставляет полное ядро ​​Linux и значительно улучшает производительность по сравнению с WSL 1. Docker Desktop 2.3+ включает новый механизм WSL 2, который запускает Docker в WSL. а не в виртуальной машине. Следовательно, если вы сохраните исходный код в файловой системе WSL 2, вы увидите улучшенную производительность наряду с лучшей совместимостью для таких вещей, как установка разрешений.

    Подробнее об использовании этого нового движка из VS Code см. В разделе Открытие папки WSL 2 в контейнере в Windows.

    Обновите согласованность монтирования на «делегировано» для macOS

    По умолчанию расширение Remote - Containers использует согласованность кэшированного монтирования Docker в macOS, поскольку это обеспечивает хорошее сочетание производительности и гарантий записи в ОС хоста. Однако вы можете выбрать использование согласованности делегированного вместо этого, если вы не ожидаете, что будете писать в один и тот же файл в обоих местах очень часто.

    При использовании файла Dockerfile или образа обновите свойство Remote> Containers: Workspace Mount Consistency в настройках до делегировано :

    При использовании Docker Compose обновите локальную привязку mount в docker-compose.yml следующим образом:

      томов:
          # Обновите это там, где вы хотите, чтобы VS Code смонтировал папку вашего проекта
          -.: / рабочее пространство: делегировано  

    Если вы уже создали контейнер и подключились к нему, запустите Remote-Containers: Rebuild Container из палитры команд (F1), чтобы применить изменения.В противном случае запустите Remote-Containers: Open Folder in Container ... , чтобы подключиться к контейнеру.

    Использовать репозиторий клонов в томе контейнера

    Удаленные контейнеры : клонировать репозиторий в том контейнера ... Команда использует изолированный локальный именованный том Docker вместо привязки к локальной файловой системе. Помимо того, что локальные тома не загрязняют файловое дерево, они имеют дополнительное преимущество в виде повышения производительности в Windows и macOS.

    Подробнее об использовании этого подхода см. В разделе «Репозиторий клонов в томе контейнера».

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

    Используйте целевой именованный том

    Поскольку macOS и Windows запускают контейнеры на виртуальной машине, «привязка» монтирования выполняется не так быстро, как прямое использование файловой системы контейнера. К счастью, в Docker есть концепция локального «именованного тома», который может действовать как файловая система контейнера, но выдерживает перестройку контейнера. Это делает его идеальным для хранения папок пакетов, таких как node_modules , папок данных или выходных папок, таких как build , где производительность записи критична.Выполните соответствующие шаги, указанные ниже, в зависимости от того, что вы ссылаетесь на devcontainer.json .

    Dockerfile или образ :

    Давайте воспользуемся репозиторием vscode-remote-try-node, чтобы проиллюстрировать, как ускорить установку yarn .

    Выполните следующие действия:

    1. Используйте свойство workspaceMount в devcontainer.json , чтобы указать VS Code, где привязать исходный код. Затем используйте свойство mounts (VS Code 1.41+), чтобы вместо этого смонтировать подпапку node_modules в именованный локальный том.

        "крепления": [
          "source = try-node-node_modules, target = $ {containerWorkspaceFolder} / node_modules, type = volume"
      ]  
    2. Поскольку в этом репозитории VS Code запускается от имени пользователя "узла" без полномочий root, нам нужно добавить postCreateCommand , чтобы убедиться, что пользователь может получить доступ к папке.

        "remoteUser": "узел",
      "mounts": [
          "source = try-node-node_modules, target = $ {containerWorkspaceFolder} / node_modules, type = volume"
      ],
      "postCreateCommand": "sudo chown node node_modules"  

      Этот второй шаг не требуется, если вы будете работать в контейнере как root .

    Если вы уже создали контейнер и подключились к нему, запустите Remote-Containers: Rebuild Container из палитры команд (F1), чтобы принять изменения. В противном случае запустите Remote-Containers: Open Folder in Container ... , чтобы подключиться к контейнеру.

    Два примечания по этому подходу:

    1. Если вы удалите папку node_modules в контейнере, она может потерять соединение с томом. При необходимости удалите содержимое папки node_modules ( rm -rf node_modules / * node_modules /.* ).

    2. Вы обнаружите, что с помощью этого метода локально создается пустая папка node_modules . Это связано с тем, что точка монтирования тома в контейнере находится внутри монтирования привязки локальной файловой системы. Это ожидаемо и безвредно.

    Docker Compose :

    Хотя vscode-remote-try-node не использует Docker Compose, действия аналогичны, но конфигурация монтирования тома помещается в другой файл.

    1. В файле Docker Compose (или в расширенном) добавьте именованное монтирование локального тома в подпапку node_modules для соответствующей службы (служб). Например:

        версия: '3'
      Сервисы:
        ваше-имя-услуги-здесь:
          объемы:
            # Или куда бы вы ни примонтировали исходный код
            -.: / рабочая область: кэшировано
            - try-node-node_modules: / workspace / node_modules
          # ...
      
      объемы:
        попробовать-узел-node_modules:  
    2. Затем убедитесь, что workspaceFolder свойство в devcontainer.json соответствует месту, где установлен ваш фактический исходный код:

        "workspaceFolder": "/ workspace"  
    3. Если вы работаете в контейнере с пользователем, отличным от root, добавьте postCreateCommand , чтобы обновить владельца подключаемой папки, поскольку он мог быть смонтирован как root. Замените user-name-go-here на соответствующего пользователя.

        "remoteUser": "узел",
      "workspaceFolder": "/ рабочая область",
      "postCreateCommand": "sudo chown имя-пользователя-идет-сюда node_modules"  

    Если вы уже создали контейнер и подключились к нему, запустите Remote-Containers: Rebuild Container из палитры команд (F1), чтобы принять изменения.В противном случае запустите Remote-Containers: Open Folder in Container ... , чтобы подключиться к контейнеру.

    Используйте именованный том для всего исходного дерева

    Наконец, если ни один из вышеперечисленных вариантов не соответствует вашим потребностям, вы можете пойти еще дальше и клонировать все свое исходное дерево внутри именованного тома , а не локально. Вы можете настроить именованный том, взяв существующую конфигурацию devcontainer.json и изменив ее следующим образом (обновив your-volume-name-here тем, что вы хотите назвать томом).

    В зависимости от того, на что вы ссылаетесь в devcontainer.json :

    • Dockerfile или образ : используйте следующие свойства в devcontainer.json для монтирования локального именованного тома в контейнер:

        "workspaceMount": "source = your-volume-name-here, target = / workspace, type = volume"
      "workspaceFolder": "/ workspace",  
    • Docker Compose : обновите (или расширьте) файл docker-compose.yml со следующими данными для соответствующих служб:

        версия: '3'
      Сервисы:
        ваше-имя-услуги-здесь:
          объемы:
              - имя-вашего-тома-здесь: / рабочая область
          # ...
      
      объемы:
        имя-том-здесь:  

      Вы также захотите убедиться, что свойство workspaceFolder в devcontainer.json соответствует месту, где установлен том (или подпапке внутри тома):

        "workspaceFolder": "/ workspace"  

    Если вы уже создали контейнер и подключились к нему, запустите Remote-Containers: Rebuild Container из палитры команд (F1), чтобы принять изменения.В противном случае запустите Remote-Containers: Open Folder in Container ... , чтобы подключиться к контейнеру.

    Затем либо используйте команду Git: Clone из палитры команд, либо запустите интегрированный терминал (⌃⇧` (Windows, Linux Ctrl + Shift + `)) и используйте команду git clone для клонирования исходного кода в папку / workspace .

    Наконец, используйте команду Файл> Открыть ... / Открыть папку ... , чтобы открыть клонированный репозиторий в контейнере.

    Предотвращение повторной установки расширений при восстановлении контейнера

    По умолчанию VS Code устанавливает расширения и VS Code Server внутри файловой системы контейнера. Хотя это дает преимущества в производительности по сравнению с локально смонтированной файловой системой, недостатком является то, что VS Code придется переустанавливать их при перестроении контейнера. Если вы часто перестраиваете, вы можете использовать локальное монтирование «именованного тома», чтобы расширения и VS Code Server пережили перестройку контейнера.

    У этого есть два побочных эффекта, о которых вам следует знать:

    • Удаление контейнера не приведет к автоматическому удалению указанного тома.
    • Совместное использование тома в нескольких контейнерах может иметь непредвиденные последствия, поэтому для безопасности мы выберем уникальное имя для каждого.

    Чтобы создать именованный локальный том, выполните следующие действия:

    1. Если вы работаете как пользователь без полномочий root , вам необходимо убедиться, что ваш Dockerfile создает ~ / .vscode-server / extensions и / или ~ / .vscode-server-insiders / extensions в контейнер с этим пользователем без полномочий root в качестве владельца.Если вы этого не сделаете, папка будет принадлежать пользователю root, и ваше соединение не будет установлено из-за проблем с разрешениями. Дополнительные сведения см. В разделе Добавление пользователя без полномочий root в контейнер разработчика, но вы можете использовать этот фрагмент в своем Dockerfile для создания папок. Замените user-name-go-here фактическим именем пользователя:

        ARG USERNAME = имя-пользователя-идет-сюда
      
      ЗАПУСТИТЬ mkdir -p /home/$USERNAME/.vscode-server/extensions \
              /home/$USERNAME/.vscode-server-insiders/extensions \
          && chown -R $ ИМЯ ПОЛЬЗОВАТЕЛЯ \
              / home / $ USERNAME /.vscode-сервер \
              /home/$USERNAME/.vscode-server-insiders  
    2. Затем мы настроим монтирование именованного тома для ~ / .vscode-server / extensions и ~ / .vscode-server-insiders / extensions в контейнере. Конфигурация будет зависеть от того, указываете ли вы образ, Dockerfile или файл Docker Compose в файле devcontainer.json .

      Dockerfile или образ :

      Добавьте следующее в devcontainer.json , заменяя / root домашним каталогом в контейнере, если не root (например, / home / user-name-go-here ) и unique-vol-name-here с уникальным именем для объем:

        "крепления": [
          "source = unique-vol-name-here, target = / root / .vscode-server / extensions, type = volume",
          // И / или для инсайдеров VS Code
          "source = unique-vol-name-here-insiders, target = / root / .vscode-server-insiders / extensions, type = volume",
      ]  

      Docker Compose :

      Обновите (или расширьте) файл docker-compose.yml со следующими данными для соответствующей службы. Замените unique-vol-name-here на уникальное имя тома.

        услуги:
        ваше-имя-услуги-здесь:
          объемы:
            - unique-vol-name-here: ~ / .vscode-server / extensions
            # И / или для инсайдеров VS Code
            - unique-vol-name-here-insiders: ~ / .vscode-server-insiders / extensions
          # ...
      
      объемы:
        уникальное имя-том-здесь:
        уникальное-имя-здесь-инсайдеры:  
    3. Наконец, если вы уже создали контейнер и подключились к нему, вам нужно запустить Remote-Containers: Rebuild Container из палитры команд (F1), чтобы принять изменение.В противном случае запустите Remote-Containers: Reopen Folder in Container , чтобы подключиться к контейнеру в первый раз.

    После того, как контейнер будет запущен и запущен, последующие перестроения не будут повторно получать какие-либо расширения или сервер VS Code. В сборке также не будет использоваться последний список расширений из devcontainer.json .

    Однако, если вы хотите полностью выполнить сброс, вы можете удалить том, и все будет переустановлено при перезагрузке.

      docker volume rm unique-vol-name-здесь  

    Добавление пользователя без полномочий root в контейнер разработчика

    Во многих образах Docker в качестве пользователя по умолчанию используется root, но есть случаи, когда вы можете предпочесть использовать вместо этого пользователя без полномочий root. Если вы это сделаете, то вам следует знать о некоторых особенностях при монтировании (привязке) локальной файловой системы . В частности:

    • Docker Desktop для Mac : внутри контейнера все подключенные файлы и папки будут действовать так, как если бы они принадлежали указанному пользователем контейнера.Вместо этого локально все операции с файловой системой будут использовать разрешения вашего локального пользователя.

    • Docker Desktop для Windows : внутри контейнера все подключенные файлы и папки будут отображаться так, как если бы они принадлежали корню , но указанный вами пользователь по-прежнему сможет их читать / записывать, и все файлы будут исполняемыми. Вместо этого локально все операции с файловой системой будут использовать разрешения вашего локального пользователя. Это связано с тем, что принципиально нет способа напрямую сопоставить права доступа к файлам в стиле Windows с Linux.

    • Docker CE / EE в Linux : внутри контейнера любые подключенные файлы / папки будут иметь те же разрешения, что и вне контейнера, включая идентификатор пользователя-владельца (UID) и идентификатор группы (GID). Из-за этого пользователь вашего контейнера должен будет иметь один и тот же UID или находиться в группе с тем же GID. Фактическое имя пользователя / группы не имеет значения. Первый пользователь на машине обычно получает UID 1000, поэтому большинство контейнеров используют его в качестве идентификатора пользователя, чтобы избежать этой проблемы.

    Указание пользователя для VS Code

    Если образ или файл Dockerfile, который вы используете , уже предоставляет необязательного пользователя без полномочий root (например, образ узла ), но по-прежнему по умолчанию используется root, вы можете выбрать VS Code (сервер) и любые подпроцессы (терминалы , tasks, debugging) используйте его, указав свойство remoteUser в devcontainer.json :

      "remoteUser": "имя-пользователя-здесь"  

    В Linux, если вы ссылаетесь на Dockerfile или образ в devcontainer.json , это также автоматически обновит UID / GID пользователя контейнера в соответствии с вашим локальным пользователем, чтобы избежать проблемы с разрешениями монтирования привязки, которая существует в этой среде (если вы не установите "updateRemoteUserUID": false ). В случае Docker Compose UID / GID пользователя контейнера не будет обновляться, но вы можете вручную изменить эти значения в Dockerfile.

    Поскольку этот параметр влияет только на VS Code и связанные подпроцессы, VS Code необходимо перезапустить (или перезагрузить окно), чтобы он вступил в силу.Однако обновления UID / GID применяются только при создании контейнера и требуют перестройки для изменения.

    Указание пользователя контейнера по умолчанию

    В некоторых случаях может потребоваться, чтобы все процессы в контейнере запускались от имени другого пользователя (например, из-за требований к запуску), а не только VS Code. То, как вы это делаете, может немного отличаться в зависимости от того, используете ли вы Docker Compose.

    • Dockerfile и образ : добавьте свойство containerUser в тот же файл.

        "containerUser": "имя-пользователя-здесь"  

      В Linux, например, remoteUser , это также автоматически обновит UID / GID пользователя контейнера в соответствии с вашим локальным пользователем, чтобы избежать проблемы с разрешениями на монтирование привязки, которая существует в этой среде (если вы не установите «updateRemoteUserUID»: false ).

    • Docker Compose : обновите (или расширьте) свой docker-compose.yml следующим образом для соответствующей службы:

        пользователь: имя-пользователя или UID-здесь  

    Создание пользователя без полномочий root

    В то время как любые образы или файлы Docker, которые поступают из расширения Remote - Containers, будут включать пользователя без полномочий root с UID / GID, равным 1000 (обычно это называется vscode или node ), многие базовые образы и файлы Docker этого не делают.К счастью, вы можете обновить или создать Dockerfile, который добавляет в ваш контейнер пользователя без полномочий root.

    Запуск вашего приложения от имени пользователя без полномочий root рекомендуется даже в производственной среде (поскольку он более безопасен), поэтому это хорошая идея, даже если вы повторно используете существующий файл Dockerfile. Например, этот фрагмент для контейнера Debian / Ubuntu создаст пользователя с именем user-name-go-here , даст ему возможность использовать sudo и установит его по умолчанию:

      ARG USERNAME = имя-пользователя-идет-сюда
    ARG USER_UID = 1000
      
    .

    Разработка внутри контейнера с использованием удаленной разработки Visual Studio Code

    Расширение Visual Studio Code Remote - Containers позволяет использовать контейнер Docker в качестве полнофункциональной среды разработки. Он позволяет открывать любую папку внутри контейнера (или подключенную к нему) и использовать весь набор функций Visual Studio Code. Файл devcontainer.json в вашем проекте сообщает VS Code, как получить доступ (или создать) контейнер разработки с четко определенным инструментом и стеком времени выполнения.Этот контейнер можно использовать для запуска приложения или инструментов песочницы, библиотек или сред выполнения, необходимых для работы с базой кода.

    Файлы рабочей области монтируются из локальной файловой системы или копируются или клонируются в контейнер. Расширения устанавливаются и запускаются внутри контейнера, где у них есть полный доступ к инструментам, платформе и файловой системе. Это означает, что вы можете легко переключить всю среду разработки, просто подключившись к другому контейнеру.

    Это позволяет VS Code обеспечивать опыт разработки с локальным качеством - включая полный IntelliSense (завершение), навигацию по коду и отладку - независимо от того, где находятся ваши инструменты (или код) .

    Начало работы

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

    Системные требования

    Местный:

    Контейнеры :

    • x86_64 / ARMv7l (AArch42) / ARMv8l (AArch64) Debian 9+, Ubuntu 16.04+, CentOS / RHEL 7+
    • x86_64 Alpine Linux 3.9+

    Другие контейнеры Linux на базе glibc могут работать, если для них необходимы предварительные требования Linux.

    Установка

    Чтобы начать, выполните следующие действия:

    1. Установите и настройте Docker для вашей операционной системы.

      Windows / macOS :

      1. Установите Docker Desktop для Windows / Mac.

      2. Щелкните правой кнопкой мыши элемент панели задач Docker, выберите Settings / Preferences и обновите Resources> File Sharing , указав все места хранения исходного кода.См. Советы и рекомендации по устранению неполадок.

      3. Если вы используете WSL 2 в Windows, чтобы включить серверную часть Windows WSL 2: щелкните правой кнопкой мыши элемент панели задач Docker и выберите Параметры . Отметьте Используйте механизм на основе WSL 2 и убедитесь, что ваш дистрибутив включен в разделе Ресурсы > Интеграция WSL .

      Linux :

      1. Следуйте официальным инструкциям по установке Docker CE / EE для вашего дистрибутива.Если вы используете Docker Compose, следуйте также указаниям Docker Compose.

      2. Добавьте своего пользователя в группу docker с помощью терминала для запуска: sudo usermod -aG docker $ USER

      3. Выйдите и войдите снова, чтобы изменения вступили в силу.

    2. Установите Visual Studio Code или Visual Studio Code Insiders.

    3. Установите пакет расширений удаленной разработки.

    Работаете с Git?

    Вот два совета, которые следует учитывать:

    • Если вы работаете с одним и тем же репозиторием как локально в Windows, так и внутри контейнера, обязательно настройте согласованные окончания строк. См. Подробности в советах и ​​приемах.
    • Если вы клонируете с помощью диспетчера учетных данных Git, ваш контейнер уже должен иметь доступ к вашим учетным данным! Если вы используете ключи SSH, вы также можете разрешить их совместное использование. См. Раздел «Совместное использование учетных данных Git с вашим контейнером».

    Работа с контейнерами

    Расширение Remote - Containers поддерживает две основные рабочие модели:

    Быстрый старт: попробуйте контейнер для разработки

    Самый простой способ начать - попробовать один из примеров контейнеров для разработки. Учебник по контейнерам проведет вас через настройку Docker и расширения Remote - Containers и позволит вам выбрать образец:

    Быстрый старт: открытие существующей папки в контейнере

    В этом кратком руководстве рассказывается, как настроить контейнер разработчика для существующего проекта, чтобы использовать его в качестве постоянной среды разработки, используя существующий исходный код в вашей файловой системе.Выполните следующие действия:

    1. Запустите VS Code, запустите команду Remote-Containers: Open Folder in Container ... из палитры команд (F1) или элемента строки состояния быстрых действий и выберите папку проекта, для которой вы хотите настроить контейнер.

      Совет: Если вы хотите отредактировать содержимое или настройки контейнера перед открытием папки, вы можете запустить Remote-Containers: Add Development Container Configuration Files... вместо этого.

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

      Примечание: При использовании контейнеров Alpine Linux некоторые расширения могут не работать из-за зависимостей glibc в собственном коде внутри расширения.

      Список будет автоматически отсортирован по содержимому открытой папки. Обратите внимание, что отображаемые определения контейнеров разработчика взяты из репозитория vscode-dev-container. Вы можете просмотреть папку контейнеров и этого репозитория, чтобы увидеть содержимое каждого определения.

    3. После выбора начальной точки для вашего контейнера VS Code добавит файлы конфигурации контейнера разработчика в ваш проект (.devcontainer / devcontainer.json ).

    4. Окно VS Code перезагрузится и начнет сборку контейнера разработчика. Уведомление о ходе выполнения предоставляет обновления статуса. Вам нужно создать контейнер разработчика только при первом его открытии; открытие папки после первой успешной сборки будет намного быстрее.

    5. После завершения сборки VS Code автоматически подключится к контейнеру.

    Теперь вы можете взаимодействовать со своим проектом в VS Code так же, как при локальном открытии проекта.С этого момента, когда вы открываете папку проекта, VS Code автоматически выбирает и повторно использует вашу конфигурацию контейнера разработчика.

    Совет: Хотите использовать удаленный хост Docker? Подробную информацию о настройке см. В статье «Дополнительные контейнеры».

    Хотя использование этого подхода для привязки монтирования локальной файловой системы к контейнеру удобно, он имеет некоторые накладные расходы на производительность в Windows и macOS. Есть несколько методов, которые можно применить для повышения производительности диска, или вы можете открыть репозиторий в контейнере, используя вместо этого изолированный том контейнера.

    Откройте папку WSL 2 в контейнере в Windows

    Если вы используете подсистему Windows для Linux v2 (WSL 2) и включили серверную часть WSL 2 Docker Desktop, вы можете работать с исходным кодом, хранящимся внутри WSL!

    После включения механизма WSL 2 вы можете:

    • Используйте команду Remote-Containers: Reopen Folder in Container из папки, уже открытой с помощью расширения Remote - WSL.
    • Выберите удаленные контейнеры : открыть папку в контейнере... из палитры команд (kbstyle (F1)) и выберите папку WSL, используя локальный общий ресурс \ wsl $ (со стороны Windows).

    Остальная часть быстрого запуска действует как есть! Вы можете узнать больше о расширении Remote - WSL в документации.

    Открыть существующее рабочее пространство в контейнере

    Вы также можете выполнить аналогичный процесс, чтобы открыть многокорневое рабочее пространство VS Code в одиночном контейнере , если рабочее пространство ссылается только на относительные пути к подпапкам папки .code-workspace файл (или сама папка).

    Вы можете либо:

    • Используйте команду удаленных контейнеров : открыть рабочую область в контейнере ... .
    • Используйте File> Open Workspace ... после того, как вы открыли папку, содержащую файл .code-workspace в контейнере.

    После подключения вы можете добавить папку .devcontainer в рабочую область, чтобы вы могли легко редактировать ее содержимое, если оно еще не отображается.

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

    Быстрый старт: откройте репозиторий Git или GitHub PR в изолированном томе контейнера

    Хотя вы можете открыть локально клонированный репозиторий в контейнере, вы можете захотеть работать с изолированной копией репозитория для PR-проверки или для исследования другой ветви, не влияя на вашу работу.

    Контейнеры репозитория

    используют изолированные локальные тома Docker вместо привязки к локальной файловой системе. Помимо того, что локальные тома не загрязняют файловое дерево, они имеют дополнительное преимущество в виде повышения производительности в Windows и macOS. (См. Раздел Расширенная конфигурация для получения информации о том, как использовать эти типы томов в других сценариях.)

    Например, выполните следующие действия, чтобы открыть один из «пробных» репозиториев в контейнере репозитория:

    1. Запустите VS Code и запустите Remote-Containers: Clone Repository in Container Volume... из палитры команд (F1).

    2. Введите microsoft / vscode-remote-try-node (или один из других репозиториев «try»), URI Git, URL-адрес ветви GitHub или URL-адрес GitHub PR в появившемся поле ввода и нажмите Enter.

      Совет: Если вы выбираете частный репозиторий, вы можете настроить диспетчер учетных данных или добавить свои ключи SSH к своему агенту SSH. См. Раздел «Совместное использование учетных данных Git с вашим контейнером».

    3. Если в вашем репозитории нет файла .devcontainer / devcontainer.json , вам будет предложено выбрать начальную точку из фильтруемого списка или существующего файла Dockerfile или Docker Compose (если он существует).

      Примечание: При использовании контейнеров Alpine Linux некоторые расширения могут не работать из-за зависимостей glibc в собственном коде внутри расширения.

      Список будет автоматически отсортирован по содержимому открытой папки.Обратите внимание, что отображаемые определения контейнеров разработчика взяты из репозитория vscode-dev-container. Вы можете просмотреть папку контейнеров и этого репозитория, чтобы увидеть содержимое каждого определения.

    4. Окно VS Code (экземпляр) перезагрузится, клонирует исходный код и начнет сборку контейнера разработчика. Уведомление о ходе выполнения предоставляет обновления статуса.

      Если вы вставили URL-адрес запроса на вытягивание GitHub на шаге 2, PR будет автоматически проверен, и в контейнер будет установлено расширение GitHub Pull Requests.Расширение предоставляет дополнительные функции, связанные с PR, такие как PR-проводник, взаимодействие с встроенными PR-комментариями и видимость строки состояния.

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

    Обратите внимание, что если контейнер не открывается из-за чего-то вроде ошибки сборки Docker, вы можете выбрать Reopen in Recovery Container в появившемся диалоговом окне, чтобы перейти в «контейнер восстановления», который позволяет вам редактировать файл Dockerfile или другой контент.Это откроет том докера с клонированным репозиторием в минимальном контейнере и покажет вам журнал создания. Как только вы закончите исправление, используйте Reopen в контейнере , чтобы повторить попытку.

    Совет: Хотите использовать удаленный хост Docker? Подробную информацию о настройке см. В статье «Дополнительные контейнеры».

    Создайте файл devcontainer.json

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

    VS Code хранится в файле devcontainer.json. Этот файл похож на запуск .json для отладки конфигураций, но вместо этого используется для запуска (или присоединения) вашего контейнера разработки. Вы также можете указать любые расширения для установки после запуска контейнера или команды после создания для подготовки среды. Конфигурация контейнера разработчика находится либо в .devcontainer / devcontainer.json , либо хранится в виде файла .devcontainer.json (обратите внимание на префикс точки) в корне вашего проекта.

    В качестве отправной точки можно использовать любой образ, файл Dockerfile или набор файлов Docker Compose.Вот простой пример, в котором используется один из предварительно созданных образов VS Code Development Container:

      {
      "изображение": "mcr.microsoft.com/vscode/devcontainers/typescript-node:0-12",
      "forwardPorts": [3000],
      "extension": ["dbaeumer.vscode-eslint"]
    }  

    Выбор удаленных контейнеров : Добавить файлы конфигурации контейнера разработки ... Команда из палитры команд (F1) добавит необходимые файлы в ваш проект в качестве отправной точки, которую вы можете дополнительно настроить для своих нужд.Команда позволяет вам выбрать заранее определенную конфигурацию контейнера из списка на основе содержимого вашей папки, повторно использовать существующий файл Docker или повторно использовать существующий файл Docker Compose.

    Дополнительные сведения о создании файлов devcontainer.json см. В разделе Создание контейнера разработки.

    Инспекционные объемы

    Иногда вы можете столкнуться с ситуацией, когда вы используете именованный том Docker, который вы хотите проверить или внести изменения. Вы можете использовать VS Code для работы с этим содержимым, не создавая или изменяя devcontainer.json , выбрав Remote-Containers: Inspect Volume in Container ... на панели команд (F1).

    Если у вас установлено расширение Docker, вы также можете щелкнуть правой кнопкой мыши том в разделе Volumes в Docker Explorer и выбрать Inspect в Visual Studio Code .

    Управление добавочными номерами

    VS Code запускает расширения в одном из двух мест: локально на стороне пользовательского интерфейса / клиента или в контейнере.Хотя расширения, которые влияют на пользовательский интерфейс VS Code, такие как темы и фрагменты, устанавливаются локально, большинство расширений будут находиться внутри определенного контейнера. Это позволяет вам устанавливать в контейнер только расширения, необходимые для данной задачи, и легко переключать всю цепочку инструментов, просто подключившись к новому контейнеру.

    Если вы устанавливаете расширение из представления «Расширения», оно будет автоматически установлено в правильном месте. Вы можете определить, где установлено расширение, по группировке категорий.Будет категория Local - Installed , а также категория для вашего контейнера.

    Примечание: Если вы являетесь автором расширения и ваше расширение не работает должным образом или устанавливается не в том месте, см. Раздел «Поддержка удаленной разработки».

    Локальные расширения, которые действительно необходимо запускать удаленно, будут отображаться как Отключено в категории Локально - Установлено . Выберите Install , чтобы установить расширение на удаленный хост.

    Вы также можете установить все локально установленные расширения внутри контейнера разработчика, перейдя в представление «Расширения» и выбрав Установить локальные расширения в контейнере разработчика: [Имя] , используя облачную кнопку справа от строки заголовка Локально - установлено . Появится раскрывающийся список, в котором вы можете выбрать, какие локально установленные расширения установить в свой контейнер.

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

    Добавление расширения к devcontainer.json

    Хотя вы можете вручную отредактировать файл devcontainer.json, чтобы добавить список идентификаторов расширений, вы также можете щелкнуть правой кнопкой мыши любое расширение в представлении «Расширения» и выбрать Добавить в devcontainer.json .

    Расширения "Всегда устанавливались"

    Если есть расширения, которые вы хотели бы всегда устанавливать в любом контейнере, вы можете обновить удаленный .container.defaultExtensions Пользовательская настройка. Например, если вы хотите установить расширения GitLens и Resource Monitor, вы должны указать их идентификаторы расширения следующим образом:

      "remote.containers.defaultExtensions": [
        "eamodio.gitlens",
        "mutantdino.resourcemonitor"
    ]  

    Дополнительно: принудительный запуск расширения локально или удаленно

    Расширения

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

    Например, настройка ниже заставит расширение Docker запускаться локально, а расширение Debugger for Chrome - запускать удаленно вместо значений по умолчанию:

      "remote.extensionKind": {
        "ms-azuretools.vscode-docker": ["ui"],
        "msjsdiag.debugger-for-chrome": ["рабочая область"]
    }  

    Значение «ui» вместо «рабочая область» заставит расширение вместо этого запускаться на стороне локального пользовательского интерфейса / клиента.Как правило, это следует использовать только для тестирования, если иное не указано в документации расширения, поскольку это может нарушить расширения . См. Статью о поддержке удаленной разработки.

    Перенаправление или публикация порта

    Контейнеры

    - это изолированные среды, поэтому, если вы хотите получить доступ к серверу, службе или другому ресурсу внутри вашего контейнера, вам нужно будет либо «перенаправить», либо «опубликовать» порт на вашем хосте. Вы можете настроить свой контейнер так, чтобы эти порты всегда открывались, или просто временно перенаправляли их.

    Всегда перенаправлять порт

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

      "forwardPorts": [3000, 3001]  

    Просто перезагрузите / снова откройте окно, и настройка будет применена, когда VS Code подключается к контейнеру.

    Временное перенаправление порта

    Если вам нужен доступ к порту, который вы не добавляли в devcontainer.json или опубликовать в файле Docker Compose, вы можете временно перенаправить новый порт на время сеанса, выполнив команду Forward a Port из палитры команд (F1).

    После выбора порта в уведомлении будет указан порт localhost, который следует использовать для доступа к порту в контейнере. Например, если вы перенаправили HTTP-сервер, прослушивающий порт 3000, в уведомлении может быть указано, что он сопоставлен с портом 4123 на локальном хосте.Затем вы можете подключиться к этому удаленному HTTP-серверу, используя http: // localhost: 4123 .

    Эта же информация доступна в разделе Forwarded Ports удаленного проводника, если вам понадобится доступ к нему позже.

    Если вы хотите, чтобы VS Code запомнил все перенаправленные порты, отметьте Remote: Restore Forwarded Ports в редакторе настроек (⌘, (Windows, Linux Ctrl +,)) или установите «remote.restoreForwardedPorts»: true в настройки.json .

    Публикация порта

    Docker имеет концепцию «публикации» портов при создании контейнера. Опубликованные порты очень похожи на порты, которые вы делаете доступными в своей локальной сети. Если ваше приложение принимает вызовы только от localhost , оно будет отклонять соединения с опубликованных портов так же, как ваш локальный компьютер для сетевых вызовов. С другой стороны, перенаправленные порты выглядят для приложения как localhost .Каждый может быть полезен в разных ситуациях.

    Для публикации порта вы можете:

    1. Используйте свойство appPort: Если вы ссылаетесь на образ или файл Docker в devcontainer.json , вы можете использовать свойство appPort для публикации портов на узле.

        "appPort": [3000, "8921: 5000"]  
    2. Используйте сопоставление портов Docker Compose: Сопоставление портов можно легко добавить в файл docker-compose.yml для публикации дополнительных портов.

        порты:
      - «3000»
      - «8921: 5000»  

    В каждом случае вам нужно будет перестроить контейнер, чтобы настройки вступили в силу. Это можно сделать, выполнив команду Remote-Containers: Rebuild Container на панели команд (F1), когда вы подключены к контейнеру.

    Открытие терминала

    Открыть терминал в контейнере из VS Code просто.После того, как вы открыли папку в контейнере, любое окно терминала , которое вы открываете в VS Code ( Terminal> New Terminal ), будет автоматически запускаться в контейнере, а не локально.

    Вы также можете использовать командную строку code из того же окна терминала для выполнения ряда операций, таких как открытие нового файла или папки в контейнере. Введите код --help , чтобы узнать, какие параметры доступны в командной строке.

    Отладка в контейнере

    Открыв папку в контейнере, вы можете использовать отладчик VS Code так же, как и при локальном запуске приложения.Например, если вы выберете конфигурацию запуска в launch.json и начнете отладку (F5), приложение запустится на удаленном хосте и подключит к нему отладчик.

    См. Документацию по отладке для получения подробной информации о настройке функций отладки VS Code в .vscode / launch.json .

    Настройки для конкретного контейнера

    Локальные пользовательские настройки

    VS Code также повторно используются, когда вы подключены к контейнеру разработчика. Хотя это обеспечивает единообразие взаимодействия с пользователем, вы можете захотеть изменить некоторые из этих параметров между вашим локальным компьютером и каждым контейнером.К счастью, после подключения к контейнеру вы также можете установить параметры для конкретного контейнера, выполнив команду Preferences: Open Remote Settings из палитры команд (F1) или выбрав вкладку Remote в редакторе настроек. Они переопределят любые локальные настройки, которые у вас есть при каждом подключении к контейнеру.

    Параметры контейнера по умолчанию

    Вы можете включить значения по умолчанию для конкретных настроек контейнера в devcontainer.json с использованием свойства settings . Эти значения будут автоматически помещены в файл настроек конкретного контейнера внутри контейнера после его создания.

    Например, добавление этого в .devcontainer / devcontainer.json установит домашний путь Java:

      "настройки": {
        "java.home": "/ docker-java-home"
    }  

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

    Совместное использование учетных данных Git с вашим контейнером

    Расширение Remote - Containers обеспечивает готовую поддержку использования локальных учетных данных Git изнутри контейнера. В этом разделе мы рассмотрим два поддерживаемых варианта.

    Если ваше имя пользователя или адрес электронной почты не настроены локально, вам может быть предложено сделать это. Вы можете сделать это на своем локальном компьютере , выполнив следующие команды:

      git config --global user.name "Ваше имя"
    git config --global user.электронная почта "[email protected]"  

    Расширение автоматически скопирует ваш локальный файл .gitconfig в контейнер при запуске, поэтому вам не нужно делать это в самом контейнере.

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

    Если вы используете HTTPS для клонирования репозиториев и имеет помощник по учетным данным, настроенный в вашей локальной ОС, дальнейшая настройка не требуется. Учетные данные, которые вы ввели локально, будут повторно использоваться в контейнере и наоборот.

    Использование ключей SSH

    В некоторых случаях вы можете клонировать свой репозиторий, используя ключи SSH вместо помощника по учетным данным.Чтобы включить этот сценарий, расширение автоматически перенаправит ваш локальный агент SSH , если он работает под управлением .

    Вы можете добавить локальные ключи SSH к агенту, если он запущен, с помощью команды ssh-add . Например, запустите это из терминала или PowerShell:

      ssh-add $ HOME / .ssh / github_rsa  

    В Windows и Linux вы можете получить сообщение об ошибке, потому что агент не запущен (в macOS он обычно работает по умолчанию). Выполните следующие действия, чтобы решить проблему:

    Windows :

    Запустите локальный администратор PowerShell и выполните следующие команды:

      # Убедитесь, что вы работаете как администратор
    Set-Service ssh-agent -StartupType Автоматический
    Старт-Сервис ssh-агент
    Get-Service ssh-агент  

    Linux:

    Сначала запустите агент SSH в фоновом режиме, запустив в терминале следующее:

      eval "$ (ssh-agent -s)"  

    Затем добавьте эти строки в свой ~ /.bash_profile или ~ / .zprofile (для Zsh), поэтому он запускается при входе в систему:

      если [-z "$ SSH_AUTH_SOCK"]; тогда
       # Проверить, есть ли в данный момент запущенный экземпляр агента
       RUNNING_AGENT = "` ps -ax | grep 'ssh-agent -s' | grep -v grep | wc -l | tr -d '[: space:]' `"
       если ["$ RUNNING_AGENT" = "0"]; тогда
            # Запускаем новый экземпляр агента
            ssh-агент -s &> .ssh / ssh-агент
       фи
       eval `cat .ssh / ssh-agent`
    fi  

    Совместное использование ключей GPG

    Если вы хотите, чтобы GPG подписывала ваши коммиты, вы также можете поделиться своими локальными ключами с вашим контейнером.Вы можете узнать о подписании с помощью ключа GPG в документации GitHub.

    Если у вас не настроен GPG, на Windows вы можете установить Gpg4win или на macOS вы можете установить GPG Tools. В Linux , локально установите пакет gnupg2 с помощью диспетчера пакетов вашей системы.

    Затем установите gnupg2 в свой контейнер, обновив файл Dockerfile. Например:

      RUN apt-get update && apt-get install gnupg2 -y  

    Или, если вы работаете как пользователь без полномочий root:

      ЗАПУСТИТЬ sudo apt-get update && sudo apt-get install gnupg2 -y  

    При следующем запуске контейнера ваши ключи GPG также должны быть доступны внутри контейнера.

    Примечание: Если вы ранее использовали gpg в контейнере, вам может потребоваться запустить Remote-Containers: Rebuild Container , чтобы обновление вступило в силу.

    Управление контейнерами

    По умолчанию расширение Remote - Containers автоматически запускает контейнеры, упомянутые в devcontainer.json , когда вы открываете папку. Когда вы закрываете VS Code, расширение автоматически отключает контейнеры, к которым вы подключились.Вы можете изменить это поведение, добавив "shutdownAction": "none" к devcontainer.json .

    Хотя вы можете использовать командную строку для управления своими контейнерами, вы также можете использовать Remote Explorer . Чтобы остановить контейнер, выберите «Контейнеры» из раскрывающегося списка (если он есть), щелкните правой кнопкой мыши работающий контейнер и выберите Остановить контейнер . Вы также можете запускать закрытые контейнеры, удалять контейнеры и удалять недавние папки. В представлении «Подробности» вы можете перенаправлять порты и открывать уже перенаправленные порты в браузере.

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

    Персонализация с помощью репозиториев файлов точек

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

    Распространенный способ сделать это - сохранить эти файлы точек в репозитории GitHub, а затем использовать служебную программу для их клонирования и применения. Расширение Remote - Containers имеет встроенную поддержку для их использования с вашими собственными контейнерами. Если вы новичок в этой идее, взгляните на различные существующие репозитории начальной загрузки точечных файлов.

    Чтобы использовать его, добавьте репозиторий GitHub файлов точек в настройки пользователя VS Code (⌘, (Windows, Linux Ctrl +,)) следующим образом:

    Или в настройках .json :

      {
      "dotfiles.repository": "your-github-id / your-dotfiles-repo",
      "dotfiles.targetPath": "~ / dotfiles",
      "dotfiles.installCommand": "~ / dotfiles / install.sh"
    }  

    С этого момента репозиторий dotfiles будет использоваться всякий раз, когда создается контейнер.

    Расширенная конфигурация контейнера

    См. Статью Advanced Container Configuration для получения информации по следующим темам:

    .

    Определение команды и аргументов для контейнера

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

    Перед тем как начать

    У вас должен быть кластер Kubernetes, а инструмент командной строки kubectl должен быть настроенным для связи с вашим кластером. Если у вас еще нет кластер, вы можете создать его, используя Миникубе, или вы можете использовать одну из этих игровых площадок Kubernetes:

    Чтобы проверить версию, введите kubectl version .

    Определите команду и аргументы при создании Pod

    При создании Pod вы можете определить команду и аргументы для контейнеры, которые работают в Pod. Чтобы определить команду, включите команду в конфигурационном файле. Чтобы определить аргументы для команды, включите поле args в файле конфигурации. Команда и аргументы, которые вы определяете, что нельзя изменить после создания модуля.

    Команда и аргументы, которые вы определяете в файле конфигурации переопределить команду и аргументы по умолчанию, предоставленные образом контейнера.Если вы определяете аргументы, но не определяете команду, используется команда по умолчанию с вашими новыми аргументами.

    Примечание: Поле команды соответствует точке входа в некотором контейнере. время выполнения. См. Примечания ниже.

    В этом упражнении вы создадите Pod, который запускает один контейнер. Конфигурация файл для модуля Pod определяет команду и два аргумента:

      apiVersion: v1
    вид: Стручок
    метаданные:
      имя: команда-демонстрация
      ярлыки:
        цель: демонстрация-команда
    спецификации:
      контейнеры:
      - имя: команда-демонстрационный контейнер
        изображение: debian
        команда: ["printenv"]
        аргументы: ["HOSTNAME", "KUBERNETES_PORT"]
      restartPolicy: OnFailure
      
    1. Создайте под на основе файла конфигурации YAML:

        kubectl apply -f https: // k8s.io / примеры / стручки / commands.yaml
        
    2. Список запущенных модулей:

      Выходные данные показывают, что контейнер, который запускался в модуле command-demo, имеет завершено.

    3. Чтобы увидеть результат выполнения команды в контейнере, просмотрите журналы из модуля:

        kubectl logs command-demo
        

      Выходные данные показывают значения среды HOSTNAME и KUBERNETES_PORT. переменные:

        команда-демонстрация
      tcp: //10.3.240.1: 443
        

    Используйте переменные среды для определения аргументов

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

      env:
    - имя: СООБЩЕНИЕ
      значение: "привет, мир"
    команда: ["/ bin / echo"]
    аргументы: ["$ (СООБЩЕНИЕ)"]
      

    Это означает, что вы можете определить аргумент для Pod, используя любой из методы, доступные для определения переменных среды, включая ConfigMaps а также Секреты.

    Примечание: Переменная среды отображается в скобках, "$ (VAR)" . Это требуется для раскрытия переменной в поле command или args .

    Запустить команду в оболочке

    В некоторых случаях вам нужно, чтобы ваша команда запускалась в оболочке. Например, ваш команда может состоять из нескольких команд, соединенных вместе, или это может быть оболочка сценарий. Чтобы запустить команду в оболочке, оберните ее следующим образом:

      команда: ["/ bin / sh"]
    args: ["-c", "пока истина; делать эхо привет; спать 10; готово"]
      

    Примечания

    В этой таблице приведены имена полей, используемые Docker и Kubernetes.

    Описание Имя поля Docker Имя поля Kubernetes
    Команда, выполняемая контейнером Entrypoint command
    Аргументы, переданные команде 9011 ard12

    Когда вы переопределяете точку входа и Cmd по умолчанию, применяются следующие правила:

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

    • Если вы предоставите команду , но не аргументов для Контейнера, только предоставленные Используется команда . EntryPoint по умолчанию и Cmd по умолчанию, определенные в Docker изображения игнорируются.

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

    • Если вы вводите команду и аргументы , точка входа по умолчанию и точка входа по умолчанию Cmd, определенный в образе Docker, игнорируется.Ваша команда запускается с вашим аргументов .

    Вот несколько примеров:

    ] foo bar]
    Image Entrypoint Image Cmd Container command Container args Command run

    008 [/ 9

    [ep-1 foo bar]
    [/ ep-1] [foo bar] [/ ep-2] <не настроено> [ep-2]
    [/ ep-1] [foo bar] <не установлено> [zoo boo] [ep-1 zoo boo]
    [/ ep-1] [foo bar] [/ ep-2] [zoo boo] [ep-2 zoo boo]

    Wha t’s next

    Последнее изменение 30 мая 2020 г., 15:10 по тихоокеанскому стандартному времени: добавить страницы en (ecc27bbbe).

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

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Theme: Overlay by Kaira Extra Text
    Cape Town, South Africa