Dockerfile, создаем свой контейнер

Сегодня поговорим о создании своего Docker-контейнера, рассмотрим некоторые особенности построения Dockerfile и сборки контейнеров.

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

Гайд по установке Docker на Ubuntu 18.04 можно взять отсюда: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04

После, нагуглите и осмотрите содержимое Docker Hub. Там есть много всего, но нас интересует официальный образ Ubuntu. Пулить образ сразу напрямую не нужно, мы хотим его модифицировать и собрать сами. Смотрите описание на странице образа. Там будут и ссылки на github, где находится готовый Dockerfile и архив. Скачиваем их:

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

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

Рассмотрим на примере. Допустим, я хочу сделать контейнер, который будет являться моим ssh-шлюзом в другую сеть (для multi-hop и не только). Мне нужно:

  • Обновить все ПО в контейнере.
  • Поставить сам ssh-сервер: openssh-server, + всякие ништяки для удобства.. htop, mc, nano, wget, tar, curl, telnet и т.д.
  • Отредактировать конфиг ‘/etc/ssh/sshd_config’: отключить авторизацию по паролю и просто пустые пароли, включить авторизацию по ssh-ключам, включить возможность заходить под root удаленно.
  • Импортировать в контейнер свой ssh-ключ, чтобы я сразу смог авторизоваться в нем.
  • А еще мне нужно, чтобы контейнер сразу «не угасал» и продолжал работать.

Вот конкретный перечень требований к контейнеру. Что же, окей. Приступим к правке Dockerfile. Открываем существующий, и добавляем в конце свой блок:

########## DF build
RUN apt update
RUN apt install openssh-server htop mc nano wget tar curl telnet atop -y
RUN echo "# DF add" >> /etc/ssh/sshd_config && echo "PermitRootLogin yes" >> /etc/ssh/sshd_config && echo "PasswordAuthentication no" >> /etc/ssh/sshd_config && echo "PermitEmptyPasswords no" >> /etc/ssh/sshd_config && echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config && echo "GSSAPIAuthentication no" >> /etc/ssh/sshd_config
RUN mkdir /root/.ssh
RUN touch /root/.ssh/authorized_keys && echo "ssh-rsa AAAAB3NzaC1yc2EAAAZDAQABAAABAQDFhrqudGbIVJLQOSKKb1pBdu3D77rmXP/YCoQm9LMNK44QWa3FMv3inGK+E4op8O2aRVWFfeFq///V7Vlk5R/lbUL4aUcT61MY1JS2F1kAx4mw7u8xeNTeFc+CHYY7fMQ//CnX1oFG7cqt6BohH529dbMJvtQ0Tqx3LgmWDvsE6NjsdQ04IpWpkY32JDzRNjy/TbtNCnaRazZsZmCLOGeJimHH3YYkI/aCAOKuwyxg8nnO9WuAA9RtXXyuMMEVo5b1u/h2oLEz++D5Gzu7uchWk3byQzAqeMFCZNyqM3BbUpn1uOPsDSkWgrFEqFU/sWRKdbkd73fFIrW7ZkGAmkuH darkfess@DFT" >> /root/.ssh/authorized_keys
#
CMD service ssh restart && tail -F /var/log/auth.log

raw: df_build

RUN — это команды, выполняемые единоразово при сборке образа. CMD — это команды, исполняемые при каждом запуске контейнера. Есть еще ENTRYPOINT, но об различии между ним и CMD, лучше почитать в отдельных статьях на Хабре.

Собственно на этом все. Особенно обратите внимание на последнюю строку, она отвечает за автозапуск сервиса и удерживает контейнер от «засыпания».

Финальное ‘docker build..’ собирает необходимый нам образ, который потом можно будет отправить с помощью ‘docker push..’ в Docker Hub, либо куда еще вам нужно.


Испугались?

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

FROM ubuntu:18.04
########## DF build
RUN apt update
RUN apt install openssh-server htop mc nano wget tar curl telnet atop -y
RUN echo "# DF add" >> /etc/ssh/sshd_config && echo "PermitRootLogin yes" >> /etc/ssh/sshd_config && echo "PasswordAuthentication no" >> /etc/ssh/sshd_config && echo "PermitEmptyPasswords no" >> /etc/ssh/sshd_config && echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config && echo "GSSAPIAuthentication no" >> /etc/ssh/sshd_config
RUN mkdir /root/.ssh
RUN touch /root/.ssh/authorized_keys && echo "ssh-rsa AAAAB3NzaC1yc2EAAAZDAQABAAABAQDFhrqudGbIVJLQOSKKb1pBdu3D77rmXP/YCoQm9LMNK44QWa3FMv3inGK+E4op8O2aRVWFfeFq///V7Vlk5R/lbUL4aUcT61MY1JS2F1kAx4mw7u8xeNTeFc+CHYY7fMQ//CnX1oFG7cqt6BohH529dbMJvtQ0Tqx3LgmWDvsE6NjsdQ04IpWpkY32JDzRNjy/TbtNCnaRazZsZmCLOGeJimHH3YYkI/aCAOKuwyxg8nnO9WuAA9RtXXyuMMEVo5b1u/h2oLEz++D5Gzu7uchWk3byQzAqeMFCZNyqM3BbUpn1uOPsDSkWgrFEqFU/sWRKdbkd73fFIrW7ZkGAmkuH darkfess@DFT" >> /root/.ssh/authorized_keys
#
CMD service ssh restart && tail -F /var/log/auth.log

raw: df_build_from

И уже потом на базе одного только нового Dockerfile фигачить ‘docker build..’. Вот теперь порядок, не правда ли?

Примечание: собрать контейнер такого типа можно и иначе, подготовив заранее конфиги sshd_config и authorized_keys и добавив их через ADD. Вот так вот. Как видите, вариаций как сделать одну и ту же задачу есть несколько. Это приводит к самому важному на сегодня утверждению — творческая составляющая. Как и в написании скриптов и пайплайнов, здесь она достаточно высока. Лично меня это очень вдохновляет.

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