Ссылки

Введение

Эта книга является олицетворением всех моих навыков, умений и наработок за все время работы в роли DevOps.

Книга реализованна, как open source проект, вы можете посмотреть все исходники в GitLab.

Если вы склонируете весь проект себе и выставить правильные переменные, то получите полную копию этого проекта в своей инфраструктуре

Вся (почти) инфраструктура книга реализованная бесплатно благодаря:

  • Oracle
  • GitLab

DNS куплен, т.к. Cloudflare не дает управлять через API бесплатными доменами.

Вы можете купить доменное имя где дешевле и делегировать в Cloudflare.

Что такое CI/CD?

CI - сборка

CD - деплой

Vse!

Шютка!

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

Здесь я просто в общих словах расскажу, как покрасивее хранить все конфиги, скрипты и т.п.

Проект ci-cd-includes

У меня есть отдельный репо со всеми .yml файлами для сиайки, вот примерная структура каталогов в этом репо:

Includes

Основные файлы
    build.yml: Описывает этап сборки Docker-образа с использованием Kaniko.
    common.yml: Включает в себя файлы build.yml и deploy.yml.
    common_arm64.yml: Включает в себя файлы build.yml, deploy.yml и notify-tg.yml, а также задает дополнительные переменные.
    deploy.yml: Описывает этап развертывания с использованием Helm.
    notify-tg.yml: Описывает уведомления в Telegram.
    tf_oracle.yml: Включает в себя файл terraform.yml и задает дополнительные переменные для работы с Oracle Cloud Infrastructure.
    variables.yml: Содержит общие переменные для конфигурации CI/CD Pipeline.
Функции
    functions/build_kaniko.yml: Описывает сборку Docker-образа с использованием Kaniko.
    functions/install_helm_chart.yml: Описывает установку Helm chart.
    functions/notify.yml: Описывает уведомления с использованием HTTP API.
    functions/push_chart.yml: Описывает отправку Helm chart в репозиторий.
    functions/terraform.yml: Описывает планирование и применение изменений в инфраструктуре с использованием Terraform.

Давайте рассмотрим пример сборки

Функция сборки:

<!-- cmdrun bash /scripts/git_show_file.sh remote https://gitlab.com/from-the-lamp/infra/ci-cd-includes functions/build_kaniko.yml -->

Основной файл сборки:

<!-- cmdrun bash /scripts/git_show_file.sh remote https://gitlab.com/from-the-lamp/infra/ci-cd-includes build.yml -->

Файл, который мы будем инклюдить в проекты:

<!-- cmdrun bash /scripts/git_show_file.sh remote https://gitlab.com/from-the-lamp/infra/ci-cd-includes common_arm64.yml -->

Почему все именно так? Да потому что это прививает правильный подход к созданию инфы.

Большинство девопсов колхозят что-то кривое и каждое мельчайшое изменение аффектит всю инфраструктуру.

Здесь же у нас есть конкретная функция сборки и мы ее не трогаем, мы можешь добавлять параметры с помощью build.yml через variables

И, например, если у нас будет 100500 проектов и необходимо будет сделать какой-то один особенный проект, то мы просто создадим buils_crutch.yml (например) сделаем в нем инклюд функции сборки с нужными параметрами и таким образом будем уверены, что остальная инфра не будет затронута

p.s. Это одна из самых обширных тем и эта страница будет сильно меняться

Сборка проекта

Давайте посмотрим на то, как устроена сборка проекта, который вы сейчас читаете

Ссылка на репо

Структура файлов проекта

Ниже вы видите файлы и каталоги из корня проекта на три уровня внутрь

<!-- cmdrun bash /scripts/tree.sh -->

Файлы, которые учавствуют в сборке проекта:

Dockerfile

<!-- cmdrun echo lol-->

.gitlab-ci.yml

<!-- cmdrun bash /scripts/git_show_file.sh local ../../../.gitlab-ci.yml -->

Суть

Все лишнее вынесено из проекта в шаблоны сборки, в проекте только самое необходимое для сборки

Сборка осуществляет на любой пуш в репозиторий

Результатом сборки являет Docker образ, которым мы в следующей статье будем деплоить в кластер k8s

Докер образ хранится в conrainer registry проекта gitlab, что позволяет удобно управлять кешем

Основы Linux за 40 секунд

40 sec

Структуры директорий в Linux

В Linux с этим все очень круто и логично.

Давайте включим нашу виртуалку с убунтой и подключимся к ней с помощью mobaxterm.

Я введу команду:

ls /

И получу вот такой результат:

ls

Что такое ls / и что мы тут видим?

Команда ls это сокращение от лист, т.е. показать список (а может и нет, мне лень гуглить, но так проще запомнить). / - это корень, он же root (рут), корень файловой системы. А сама файловая система, как вы могли догадаться - древовидная.

Когда мы вводим команду ls / то мы просто смотрим, какие есть каталоги в корне нашей файловой системы. Я не буду расписывать, где что в ФС линукс хранится, вы можете погуглить. Скажу лишь, что в каталоге home (он же хомяк) храняться профили пользователей, например /home/ubuntu это будет моя пользовательская директория и при авторизации через юзера ubuntu изначально я буду оказываться в ней. Единственный пользователь, который не хранится в хомяке - root. Его данные храняться прям вот тут /root. Вы конечно можете для пользователя задать любой путь до хомяка, но по умолчанию вот так.

Основные моменты при работе с консолью

Каждая команда на вход получает какие-то аргументы и может иметь флаги

Рассмотрим команду ls:

ls -la /home

В данном примере мы вызываем команду ls и передаем ей аргумент /home, т.е. хотим посмотреть, что лежит в хомяке. Но, так же мы передаем ей флаги -l и -a. Флаги можнно записывать по отдельности, а можно совмещать их вместе, как в примере.

Вы так же можете вызвать эту команду в таком виде:

ls /home -l -a

Что делает -la ?

-l выводит результат расширенным списком (с указанием владельца файлы и т.п.)

-a выводить также все скрытые файлы

Чтобы узнать флаги вы всегда можете ввести название команды и добавить --help

ls --help

Обычно этого хватает, чтобы найти нужный параметр.

Вы также можете воспользоваться

man ls

Либо гуглом

Что такое скрытые файлы?

Да просто файлы, у которых название начинается с точки, например .env

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

Относительные и полные пути

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

По этому иногда удобно использовать относительные пути, иногда полные.

Полные пути указываются элементарно, вам надо прописать ВЕСЬ путь до файла

/home/ubuntu/secret.txt

Т.е. начинаем прям с / (корня)

Относительные пути можно указывать по разному.

Предположим, что вы уже находитесь в каталоге /home/ubuntu

Тогда путь до файла secret.txt будет выглядеть так:

./secret.txt (точка указывает на текущий каталог)

Либо так:

~/secret.txt (тильда указывает на ваш домашний каталог, вы должны быть пользователем ubuntu, чтобы тильда указала на /home/ubuntu, если вы допустим будете root’ом, то она укажет на /root)

Еще есть переменные окружения, про них еще расскажу, но суть такая:

$HOME/secret.txt будет тем же самым, что и ~/secret.txt

CHEATSHIT

Я не буду каждую команду отдельно описывать. Главное понять принцип работы в консоли, а дальше уже будет просто.

Каждая команда выполняет какое-то дейстивия и ждет аргументов. Для ls нам нужен был один аргумент (посмотреть где?), а для некоторых команд, например для перемещения файла, мы можешь задать себе вопрос (откуда? куда?). Соответственно для команды перемещения нам придется указать 2 аргумента, путь до файла (откуда) и путь до файла (куда).

ls <arg> (вывести содержимое каталога)

cd <arg> (перейти в каталог)

mv <arg1> <arg2> (перенести файл откуда куда)

cp  <arg1> <arg2> (скопировать файл откуда куда)

pwd (показать путь до текущего каталога)

echo <arg> (вывести текст)

cat <arg> (вывести содержимое файла)

touch <arg> (создать пустой файл)

rm <arg> (удалить файл, удалить папку с файлами rm -rf, будьте аккуратны с такими командами)

Немного о сетке (IPv4/IPv6, NAT)

Я постараюсь простым языком объяснить базовые вещи в постороение сетей.

Общее

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

Так вот, чтобы понимать к каком компьютеру обращаться у каждого компьютера есть IP Address. То есть адрес в сети интернет. Вы могли видеть уже такие цифры раньше, вроде 192.168.1.254 или чего-то подобного.

Основная и самая широко используемая реализация протокола IP это IPv4. Это как раз адреса из цифр с точками. Но этому протоколу скоро стукнет 50 лет и как вы понимаете, 50 лет назад продумать все нюансы было невозможно.

Мы уже давно приблежаемся к моменту, когда IPv4 адресов перестанет хватать. И, чтобы эта проблема была не настолько больнючей, было придумано простое решение - NAT.

Из-за такого явления, как NAT (не только конечно), эта статья станет чуть длинее.

Что такое NAT и почему важно это понимать

Это простая, как пробка вещь на самом деле.

У нас стали заканчивать адреса ipv4, мы прикрутили NAT и стали выдавать меньше адресов.

NAT позволяет преобразовывать адреса, схема примерно такая:

ls

Слева у нас клиенты (ваш мобильник, ноут, микроволновка и сосед укравший ваш пароль от вифи).

Справа у нас сервер, например это Twitter

Когда запрос от нашего клиента идет к твиттеру то происходит следующее преобразование адресов:

  • Изначально клиент имеет локальный адрес, такие адреса недоступны в глобальной сети интернет, например 192.168.1.3
  • Когда клиент запрашивает твиттер, то устройство реализующее NAT (обычно это ваш домашний роутер), преобразует ваш локальный IP (192.168.1.3) в публичный (тот, что у вашего роутера, этот IP выдал вам провайдер интернета, например 73.71.31.29).
  • В итоге твитер получает запрос и выдает вам ответ, отправляя его уже на адрес 73.71.31.29 (вышего роутера), где роутер с помощью NAT перенаправляет запрос уже вам на локальный адрес (192.168.1.3)

Белый IP/Серый IP

Белый айпи - в контексте этой статьи это адрес вашего роутера. Т.е. тот адрес который явно доступен в глобальной сети интернет и не находится за NAT.

Серый айпи - ваш локальный айпи, пакеты напрямую на него не могу прийти, так как адрес не доступен в глобальной сети интернет и требует NAT.

Статический IP/Динамический IP

Еще одно ухищрение провайдеров, для экономии адресов (а соответственно и денег) - динамические адреса.

Любой статический или динамический IP может быть как белым так и серым.

Тут различие лиш в том, что статический IP закрепляется за вашим устройством навсегда (или на оговоренное время), каждый раз, когда у вас выключат свет и вы заново запустите ваш роутер - на нем будет тот же самый адрес.

Статические IP в основном назначаются серверам, чтобы до него было можно всегда достучаться.

Динамические IP - это то, что с вероятностью в 90% выдает вам ваш провайдер интернета

Каждый раз, когда вы перезагружаете роутер, вы получаете новый адрес IPv4.

Самый хреновый провайдер

Тот, что выдает вам серый динамический IP.

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

Что такое IPv6

По хорошему, нам на него плевать :)

Но все же темы с ним будут, идейки есть.

Когда до всех наконец-то дошло, что IPv4 не то, чего хватить на долго. То изобрели IPv6, где адреса имеют страшный вид, например 2001:0db8:85a3:0000:0000:8a2e:0370:7334

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

Переход на IPv6 идет уже кучу времени, но прогреса не видно. Его поддерживают далеко не все.

И на каком-нибудь хабре вы бы читали об этой проблеме рассуждения типа “дорого, оборудование, сложно” и т.п.

Но я открою вам тайну. От IPv6 сейчас нет спасения. Я могу генерировать сотни адресов и стучаться с них на ваш сайт и как вы поймете бот я или просто куча людей из этой подсети? Т.е. мне не надо покупать ваши HQ мега убер прокси, я просто беру и генерирую адреса.

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

Что такое виртуальная машина

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

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

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

Установка виртуальной машины

В этой статье мы установим и подготовим нашу ОС Linux к работе.

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

Загрузка и установка среды виртуализации

В Windows изначально есть виртуализация с помощью hyper-v. Можете сразу забыть это слово, мы этим пользоваться не будем. Если вы знаете, что вам по душе, то выбирайте сами хоть vmware хоть proxmox.

Мы же будем использовать VirtualBox, потому что это просто, бесплатно и хорошо работает.

  • Переходим на сайт VirtualBox
  • Жмем на огромную кнопку Download и скачиваем последнюю версию. В моем случае 7.0.4 Windows hosts
  • Устанавливаем. Во время установки жмем везде далее, лишнего ничего не настраиваем
  • Жмем Finish и у нас откроется вот такое окно:

ls

  • Далее нам необходимо создать виртуальную машину
  • Но, для сначала поставим на скачку ubuntu. Переходим на сайт ubuntu и скачиваем последнюю server версию, в моем случае 22.04. Вы можете скачать декстоп версию, тогда у вас будет красивый интерфейс. Но работать мы будем исключительно с консолью
  • И так, пока качается ISO файл с ubuntu server, мы создаем машину в VirtualBox.
  • Жмем New
  • Указываем имя виртуальной машины (Name)
  • Указываем путь до скачанного ISO:
  • Указываем имя пользователя, пароль и имя хоста. В общем то все можно указать от балды, потому что в дальнейшем мы будем указывать это в процессе настройки убунты:

ls

  • Здесь выставляем размер диска, диск будет расширятся по мере заполнения (по умолчанию). Можно поставить галочку, чтобы диск сразу занял все выделенное ему место:

ls

  • Жмем далее и фишиш
  • Запускаем созданную ВМ
  • Жмем Enter несколько раз пока не дойдем до такого экрана:

ls

  • Здесь жмем вниз до Done и опять Enter
  • Далее заполняем информацию о сервере. Сделаем юзера ubuntu и пароль ubuntu:

ls

  • Жмем Done
  • Далее отмечаем галочкой Install OpenSSH server

ls

  • Жмем Done
  • Далее предложит установить дополнительный набор ПО. Пропускаем все и жмем Done
  • Ждем завершения установки (появится надпись Install complete! на оранжевом фоне). Жмем Reboot now
  • Ждем полной загрузки ОС. До момента ввода логина и пароля
  • Останавливаем машину (крестик и power off)
  • Делаем копию (Clone):

ls

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

SSH

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

Установка SSH клиента в Windows

Я рекомендую использовать MobaXterm. В большинстве статей вы увидите putty, потому что эти статьи пишут обычные копирайтеры, которые это пути видели только на ютубе.

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

  • Скачиваем MobaXterm
  • Устанавливаем или используем portable версию, на ваше усмотрение
  • Открываем, видим такое окно:

ls

  • Жмем Session
  • Выбираем SSH и видим вот такое окно:

ls

  • Нам необходимо заполнить основные параметры: Remote host, Specify username
  • Чтобы узнать адрес удаленного хоста (remote host) нам необходимо вернуться к нашей виртуальной машине (пока что не запускаем ее)
  • Открываем окно VirtualBox
  • Выбираем нашу машину с убунту и жмем Settings
  • Переходим в вкладку Network и выбираем Bridged Adapter, примерно так (имя интерфейса у вас может отличаться):

ls

  • Жмем Ok и запускаем виртуальную машину
  • Авторизовываемся в системе с помощью логина: ubuntu пароля: ы (мы указывали их в прошлой статье при установке убунты)
  • Мы получим вот такое окно:

ls

  • Мы уже находимся внутри системы линукс, но нас интересует IP адрес этой машины
  • Вводим терминал команду:
ip ad
  • Жмем Enter. Cтатья о базовых командах линукса
  • Вывод будет примерно таким:

ls

  • Мы видим, что в системе 2 сетевых интерфейса. Первый нас не особо интересует, это лупбек интерфейс и я расскажу о нем когда-нибудь потом.
  • Второй же интерфейс enp0s3 это как раз то, что мы выставили в настройка VirtualBox
  • Как вы видите у второго интерфейса назначился IP адрес из основной сети (192.168.0.108). Т.к. мы выставили bridge adapter в виртуалбокс - наша виртуальная машина получает адреса с нашего роутера точно так же, как наш мобильный телефон или ноутбук. Статья про сеть и IP адреса.
  • Берем этот IP и вставляем в MobaXterm

ls

  • Жмем Ок и подключаемся к серверу (там будет пара всплывающих окон, жмите как считаете удобным)
  • Все, теперь мы можем работать с нашей машиной удаленно (внутри локальной сети). Это позволяет более удобно пользоваться терминалом, да и вообще не трогать сам виртуалбокс, а просто запускать в нем сервера
  • Ради интереса вы можете поставить себе на мобильник какой-либо SSH клиент и попробовать подключиться к вашему серверу с телефона (главное, чтобы вы были в том же WiFi, что и все ваши домашние гаджеты)

Что такое контейнеры?

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

Сами контейнеры, в сущности, это облегченные виртуальные машины.

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

В общем и целом контейнеры это очень круто, классно, удобно

Установка Docker

Об установке пакетов и собственно докера

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

Но, т.к. я не хочу делать отдельную тему по установке пакетов в линукс, то распишу сразу тут.

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

Все пакеты хранятся в репозиториях, в вашей системе линукс есть список репозиториев, где ваш менеджер пакетов (в убунту это apt) будет смотеть “а не надо ли мне обновить что-то”

Давайте выполним в нашей ВМ с убунтой такую команду:

sudo apt update Эта команда обновит список пакетов, а запускаем мы ее через sudo

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

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

Установка Docker

Вы можете копировать и вставлять эти команды в терминал и жать Enter.

  • Выполним команду установки необходимых пакетов:
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
  • Теперь установим ключ репозитория
sudo mkdir -p /etc/apt/keyrings && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
  • Добавим репозиторий
 echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  • Чтобы наш менеджер пакетов понял, что появился новый репозиторий выполним
sudo apt-get update
  • Теперь поставим докер и докер-композ
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Все. Докер установлен. Но есть нюанс, докер на самом деле немного убог тем, что использует демон, который имеет привелегии root. Для того, чтобы наш пользователь ubuntu мог использовать команды докера без sudo, нам надо добавить пользователя в группу docker вот такой командой:

sudo usermod -aG docker ubuntu

Теперь с установкой точно все

Пишем Dockerfile. Или как пользоваться Vim

Что такое Dockerfile?

Докерфайл - файл в котором мы описываем наш будующий докер образ. В нем можно указать какую ОС взять за основу, какие файлы и переменные добавить в образ или например, что доустановить из пакетов.

Что такое Vim?

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

Нам надо уметь им пользоваться, либо уметь пользоваться nano, однако я рекомендую сразу освоить базовые команды Вим.

Пишем Dockerfile

Подключаемся к нашей убунту и начинаем:

  • vim Dockerfile (откроется вим)
  • Теперь нам надо перейти в интерактивный режим (режим ввода), для этого нажимакм i или insert
  • Теперь мы можешь водить текст
  • Пишем вот такой вот текст:
FROM nginx

ENV LOL=LAL

Этого достаточно для ознакомления :)

Теперь нам надо сохранить и выйти из вим:

  • Жмем ESC
  • Жмем двоеточие (shift+ж на англ. раскладке, снизу появится командная строка)
  • Вводим wq и Enter (w - значит write, т.е. сохранить, q - quit, т.е. выйти)

На всякий случай показываю скриншот, как это выглядит (советую всегда быть на eng раскладке клавиатуры):

40 sec

Поздравляю мы написали самый простой Dockerfile на свете!

Docker. Сборка образов, запуск контейнеров

Что такое образы и контейнеры?

Образы докер мы билдим (собираем) из Dockerfile’ов. Это образы могут хранится у вас локально или на внешнем сервере, таком, как docker hub.

На основе образа можно создать контейнер, который уже непосредственно выполняет что-то (например хостит ваш сайт), либо можно использовать контейнер как временную виртуальную среду, т.е. зайти, что-то поделать, выйти и создать новый чистый.

Проще будет показать на примере

Собираем Docker образ

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

ls
  • Видим наш Dockerfile
docker build . -t lol

Здесь мы запускаем сборку с помощью докер билд.

Точка указывает на каталог сборки (текущий каталог), -t позволяет задать имя lol итоговому образу.

Cмотрим образы которые есть в системе:

docker images 

40 sec

Видим 2 образа lol и nginx. Nginx мы использовали как базовый образ в поле FROM. А lol это наш образ, где мы изменили только переменую.

Давайте попробуем запустить контейнер на основе нашего образа

Запуск контейнера

В команде ниже:

--rm - Удалять контейнер, после того как он завершит работу

-p 80:80 - Мапинг портов. Так докер скажет вашей системе, что трафик должен на 80 порт ходить в контейнер, где будет nginx (на основе которого мы делали наш образ) слушать 80 порт (по умолчанию).

-d - Говорим контейнеру запуститься в фоне, чтобы отпустил консоль.

docker run --rm -d -p 80:80 lol

Запускаем и проверяем:

curl localhost

Ответ должен быть таким:

40 sec

Если вы все делали по моим статьям, то у вас сайт должен быть доступен со всей локальной сети, т.е. открываться по IP адресу вашей машины с любого устройства, которое подключено к вашему Wi-Fi или по Ethernet кабелю к вашему роутеру.

То есть я просто ввожу IP адрес виртуалки в браузере и попадаю на дефолтный сайт Nginx’а:

40 sec

Остановка контейнера

Смотрим все работающие контейнеры:

docker ps

40 sec

docker kill 7e1fd4198f3e 
  • Убиваем по id, достаточно ввести первые пару символов из id, например docker kill 7e)

Очистка всего

  • docker ps -a (покажет вам все контейнеры, а не только запущеные)
  • docker volume prune (удалит все вольюмы)
  • docker network prune (удалит все сети)
  • docker system prune -a (удалит все что можно)

Что такое GIT?

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

GIT - система контроля версий. Эта штука позволяет фиксировать состоянии кода (комитить) и возвращаться к нему когда вздумается.

Т.е. вы сделали изменение в коде, например собака стала кошкой и вы делаете соответствующий комит с название “dog now cat”. Спустя полгода вас спрашивают почему собака стала кошкой и вы даете ссылку на этот комит.

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

ЗАПОМНИТЕ: GIT запоминает ВСЁ, никогда не храните пароли и другие секреты в гите!

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

Основные команды:

- git add . # Добавит все измененные файлы текущего каталога в коммит
- git commit -m "my commit" # создаст коммит с именем "my commit"
- git push # Отправит ваш коммит на удаленный сервер гит
- git remote show origin # Покажет адрес удаленного сервера гит

Что такое GitHub и GitLab?

Это “гит сервера" с веб интерфейсом

Т.е. вы можете зайти на гитхаб, нажать там создать репозиторий, сделать git clone себе

В таком режиме работы (и он для нас является по умолчанию) у вас есть 1 центральный репо в гитхабе. Новые работники могут сделать git clone этого репозитория себе на машину и получить все ваши исходники.

При работе с удаленным репо, по мимо git commit необходимо делать git push, чтобы ваши локальные изменения попали на сервер. Если вы работает с другим человеком, то ему нужно будет делать git pull, для того, чтобы получить ваши изменения.

НО! Сделать удаленный репозиторий можно и без гитхаба или гитлаба. На самом деле эти инструменты предоставляют нам еще и CI/CD для нашего кода.

Мы будем в приоритете использовать GitLab и его CI/CD.

Создаем проект, пробуем запушить

Настраиваем GIT

  • Для начала идем на сайт GitLab’a и регистрируемся
  • Запускаем нашу ВМ с убунту
  • Создаем в домашнем коталоге файл .gitconfig
vim ~/.gitconfig
  • Пишем туда свои данные
[user]
  name = Zaliv Podliv
  email = [email protected]
  username = djinn
[credential]
  helper = store
  • Идем на gitlab.com
  • Preference → Access Tokens
  • Создаем токен примерно так:

Access token page

  • Создаем файл .git-credentials в хомяке:
vim ~/.git-credentials
  • Добавляем в файл строку (прописываем токен вместо "ваш_токен"):
https://gitlab-ci-token:ваш_токен@gitlab.com/
  • wq

Теперь вы можете клонировать и пушить в свои приватные репо по HTTPS

Создаем проект

New project button

  • Называем наш проект test
  • В Project URL выбираем ваш юзернейм
  • Все остальное поля оставляем по умолчанию:

New project fields

  • Жмем Create project
  • Копируем ссылку на наш проект, выбираем ту, что HTTPS:

GitLab clone via https

  • Переходим в консоль
  • Клонируем репо по своему урлу (в примере мой):
git clone https://gitlab.com/djinno/test.git
  • Получаем такую картину:

git clone

  • Давайте посмотри, что у нас вышло:
ls test

Мы видим в нашем репо файл README.md, он создался автоматически, потому что мы не убрали соответсвующую галочку при создании репо

Пушим в проект

  • Выполняем команды:
сd test # если вы уже в каталоге test, то не выполняйте эту команду
touch lol
git add .
git commit -m "lol"
git push
  • Идем на сайт гитлаба в наш проект и видим наш новый файл lol и комит lol

lol commit

Поздравляю вы плюс минус поработали с Git и GitLab!

Если вы случайно удалите test каталог у себя на ВМ, то вы всегда можете сделать git clone и забрать актуальные данные из гитлаба

Советую потратить лишнее минут 10-20 и попробовать покомитить, попушить и т.п. Может быть даже посоздавать новые ветки и мердж реквесты

Для тех, кто дочитал до конца, два самых полезных (для меня конечно же) алиаса для гита:

alias gtest='git add . && git commit -m "Test" && git push || git push'
alias gempty='git commit --allow-empty -m "Empty" && git push'

Идеально для дебага ci-cd

Мое рабочее окружение

❯ cat /etc/os-release
BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
BUILD_ID="23.05.20230318.1603d11"
DOCUMENTATION_URL="https://nixos.org/learn.html"
HOME_URL="https://nixos.org/"
ID=nixos
LOGO="nix-snowflake"
NAME=NixOS
PRETTY_NAME="NixOS 23.05 (Stoat)"
SUPPORT_URL="https://nixos.org/community.html"
VERSION="23.05 (Stoat)"
VERSION_CODENAME=stoat
VERSION_ID="23.05"

С недавнего времени я перешел на NixOS и вот почему.

У меня нестандартная система с тайлинговым менеджером Sway, настроек в системе очень много и при этом мой ноутбук с sway является моим основыным рабочим иснтрументом.

В связи с этим возникает вопрос, что делать, если ноутбук украдут/сломается. И тут на помощь приходит NixOS.

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

Это основное требование, которое мне необходимо было от NixOS. Прочие вещи в виде изоляции и т.п. меня на данный момент не интересуют :)

Установка NixOS с шифрованным разделом /root на btrfs

Что получим в итоге:

  • Шифрованные раздел с системой
  • Голый NixOS без интерфейса, настройка будет в отдельной статье

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

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

Подготовка

На офф. сайте скачиваем Minimal ISO image под ваш процессор (64bit intel/amd в большинстве случаев).

Берем любую флешку, если вы читаете это не из 2000ых то размера вашей флешки должно хватить в любом случае. Для записи ISO на флешку из под винды рекомендую Rufus. Для записи из под линукс - dd.

После записи пихаем ее в наш ПК/ноут и грузимся с нее. Для того, чтобы загрузиться с внешнего устройства, надо после нажатия кнопки питания вашего компухтера нажимать F8 (если ПК) или F12 (если ноут) в большинстве случаев. Можете загуглить кнопку конкретно для вашего производителя ноута/материнки.

Разметка диска

Мы создадим всего 2 раздела, один FAT32 для /boot, второй BTRFS для системы.

Переходим сразу под рута

sudo -i

Смотри на наши диски в системe:

lsblk

Я пишу эту статью, используя виртуальную машину, чтобы наделать для вас скриншотов. На ВМ у меня диск называется sda (так обычно обозначается первый в системе сата диск, второй будет sdb), но на реальном ноутбуке у меня NVME диск и называется там он nvme0n1. Определитель какого типа у вас диск и далее по статье просто подменяйте на свой, в случаее необходимости.

Мы используем gdisk для разметки, вот cheatsheet с полезными командами:

  • p (показать статус)
  • d (удалить раздел)
  • n (создать раздел)
  • w (записать все, что сделали, на диск)

Запускаем утилиту разметки:

gdisk /dev/sda # В случае NVME диска /dev/nvme0n1, один раз подсказываю дальше сами

Я риспишу по пунктам, что нажать :)

  • Вводим n и жмем Enter
  • Еще раз Enter (указываем, что это 1 раздел)
  • Еще раз Enter (первый сектор)
  • Вводим +1Gi и жмем Enter (делаем бут раздел в 1 гигабайт)
  • Вводим ef00 и жмем Enter (говорим, что это EFI раздел)

Мы создали бут раздел, теперь создадим раздел под систему:

  • Вводим n и жмем Enter
  • И просто жмем Enter на все вопросы, нас устраивают значения по умолчаню. Давайте посмотрим, что получилось:
  • Вводим p и жмем Enter Вы должны увидеть вот такой результат:

gdisk example

  • Если результат вас устраивает, то вводим w и жмем Enter

Шифрование диска

Вводим:

cryptsetup luksFormat /dev/sda2 # мы шифруем второй раздел (с системой)

Задаем пароль (он будет спрашиваться у вас каждый раз на этапе загрузки системы)

Сразу же открываем и диск:

cryptsetup open  /dev/sda2 nixenc

(nixec - так диск замапится в системе на данный момент)

Создаем волумы в btrfs

Вводим команды по очереди, думать не надо, а то придется расписывать про BTRFS

pvcreate /dev/mapper/nixenc

vgcreate vg /dev/mapper/nixenc

lvcreate -n swap -L 8GB vg       # Свап, можете сделать больше/меньше

lvcreate -n root -l +100%FREE vg # Все остальное отдаем под /root

Форматируем

Для начала форматнем /boot:

mkfs.vfat -n boot /dev/sda1

Создаем и включаем swap:

mkswap /dev/mapper/vg-swap
swapon /dev/mapper/vg-swap

Теперь форматируем рут:

mkfs.btrfs -L root /dev/mapper/vg-root

Установка

Если вы устанавливаете ОС на ноутбук, то вам нужно подключится к Wi-Fi или воткнуть кабель ноут.

Подключится к Wi-Fi можно вот так:

Запускаем сервис wpa_supplicant

systemctl start wpa_supplicant 

Заходим в утилиту wpa_cli:

wpa_cli

И выполняем команды:

> add_network
> set_network 0 ssid "myhomenetwork"
> set_network 0 psk "mypassword"
> set_network 0 key_mgmt WPA-PSK
> enable_network 0

Приступаем к установке:

Монтируем рут:

mount /dev/mapper/vg-root /mnt

Монтируем бут:

mkdir /mnt/boot
mount /dev/sda1 /mnt/boot

Генерируем хардварный конфиг

nixos-generate-config --root /mnt

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

Вводим команду

lsblk -o name,type,mountpoint,uuid

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

NAME          TYPE  MOUNTPOINT     UUID
loop0         loop  /nix/.ro-store 
sda           disk                 1980-01-01-00-00-00-00
├─sda1        part  /iso           1980-01-01-00-00-00-00
└─sda2        part                 1234-5678
sda           disk                 
├─sda1        part  /mnt/boot      8C6D-DD63
└─sda2        part                 d6f3e071-f449-4aab-87f4-93ee3a3fbab1 # Нам нужно это значение
  └─nixenc    crypt                qtCMVj-QKcW-0rcm-Pyud-Fqzc-tA8f-inZp3M
    ├─vg-swap lvm   [SWAP]         a7208e31-c1e7-44b8-895c-d01d0b930508
    └─vg-root lvm   /mnt     

Берем UUID второго раздела (смотрите комментарий в выводе выше), можно сделать фотку на мобильник

Открываем файл /mnt/etc/nixos/hardware-configuration.nix

И добавляем туда строчки после boot

boot.initrd.luks.devices = {
  root = {
    device = "/dev/disk/by-uuid/<здесь полученны UUID>";
    preLVM = true;
    allowDiscards = true;
  };
};

Если у вас ноутбук, то стоит сразу прописать данные от WiFi в конфиг, чтобы не мучаться в дальнейшем (мы эти данные потом удалим, при настройке системы)

Открываем файл /mnt/etc/nixos/configuration.nix и прописываем:

networking.wireless.enable = true;
networking.wireless.networks.ИМЯ_WiFi.psk = "Пароль WiFi";

Устанавливаем NixOS

nixos-install

Что дальше?

Вы можете вынуть флешку с установщиком и перезагрузить систему

Первая загрузка спросит у вас пароль от root пользователя

Если у вас что-то пошло не так, то вы всегда можете загрузиться с установщика еще раз и поправить конфигурацию, для этого надо расшифровать диск и примонтировать:

cryptsetup open /dev/sda2 nixenc
mount /dev/mapper/vg-root /mnt
mount /dev/sda1 /mnt/boot
swapon /dev/mapper/vg-swap

Настройка

После установки системы и ее загрузки, мы можем настроить систему

  • Авторизовываемся в системе
Логин: root
Пароль: который вы задавали
  • Веменно ставим GIT
nix-shell -p git
  • Клонируем репо с настройками
git clone https://gitlab.com/djinno/dotfiles
  • Меняем хардварный конфиг
cd ./dotfiles
cp /etc/nixos/hardware-configuration.nix ./hosts/laptop/hardware-configuration.nix
  • Запускаем сборку системы
sudo nixos-rebuild switch --flake .#laptop

Итого

После того, как сборка пройдет, вы можете перезагрузить систему

Первая авторизация с помощью рута и пароля который вы задавали

Далее вы можете поменять пароль для своего юзера

passwd djinn

Т.к. конфиг мой, то и юзер соответственно мой

Вы можете изменить имя юзера и пересобрать систему

Если вы дошли до этого момента, то вы очень круты, а значит и в конфиге со временем разберетесь

Большинство настроек вы можете задать в каталоге hosts/laptop

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

sudo nixos-rebuild switch --flake .#какойто_хост_с_своими_настройками

Помочь проекту

Fiat:

Crypto:

  • USDT: 0x16e2dBd6D52b320c237dc7aC212a93579F90442d
  • BTC: bc1qlu0npwtv8a77vqxemjtqrked62wvyyvnzktuez