Девопсолог | DevOps, GitOps и прочий Ops
272 subscribers
60 photos
5 videos
2 files
91 links
Пишу про docker, k8s, gitops и прочие инфраструктурные штуки

Чат канала: https://t.me/AppliedTryndology
Download Telegram
10 лет Kubernetes!

Сегодня исполняется ровно 10 лет с момента первого коммита в репозиторий кубера. Это, без сомнения, самый интересный и крутой инструмент для управления контейнерными нагрузками. Коллеги из компании Флант написали хороший пост о том, как все начиналось - https://habr.com/ru/companies/flant/articles/820153
🔥3
PHP исполнилось 29!

На днях нашему любимому пыху исполнилось 29. По этому случаю Роман Пронский собрал и запустил 1 версию. Сам я начинал с 4-ки в далеком 2008. С тех пор php сильно вырос как язык, очень серьезно подросла и экосистема вокруг. Появились такие классные инструменты как psalm, php-cs-fixer, rector, deptrac. Live long and prosper, php!
🔥4👍2
FluxCD в действии! Воркшоп от Георга Гаала

Пока собираюсь с мыслями и думаю о чем еще написать - поделюсь с вами отличным воркшопом по использованию Gitops инструмента FluxCD.

https://www.youtube.com/live/T4fkWIGahiQ
Зависимости при сборке образа приложения

Важная, но не очень очевидная, мысль - ваше приложение при сборке образа не должно зависеть ни от чего, кроме кода приложения и рантайма, который его запускает. Все настройки под конкретные окружения (prod, stage, dev) должны осуществляться только через переменные среды (env). Мы собираем только один образ и используем его в разных окружениях. Если этого не делать - увеличится время сборки, так как мы будем собирать приложение под разные среды, увеличится объём хранимых в registry образов. А это доп. расходы времени и финансов на дисковое пространство
Есть мысль написать длинный цикл постов про php в кубере. Начиная от поднятия и настройки кластера, до подготовки php приложения для работы в кубах. Я в этом не специалист и буду разбираться по ходу дела вместе с вами. Как вам такая идея?
Anonymous Poll
92%
Хочу. Пиши
0%
Не хочу. Напишу в комментариях какие темы мне интересны
5%
Не хочу. Не знаю о чем будешь писать, но читать планирую)
3%
Посмотреть результаты
Кубер. Зачем?

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

Кубер вам не нужен, если:
1. Проект только зарождается и вы не прогнозируете со старта бурный рост
2. У вас простая серверная архитектура и ей можно запросто управлять вручную или с простой автоматизацией
3. У вас нет жестких требований к простою во время обслуживания. Если сервер ночью приляжет на полчасика - ничего страшного
4. Нет высоких нагрузок и нет требований к автоматическому скейлингу инстансов приложения
5. У вас не микросервисы

Для всех вышеперечисленных случаев подойдет docker swarm или docker-compose. Или вообще по старинке без контейнеров

Кубер вам пригодится, если:
1. Серверов стало слишком много и ими довольно сложно управлять
2. Высокие требования к простою. Нужна отказоустойчивость. SLA 99.9
3. Highload
4. Куча микросервисов

Почему кубер, а не что-то другое (Docker swarm, Hashicorp nomad, etc):
1. Это уже индустриальный стандарт и вам будет гораздо проще найти специалиста для поддержки на рынке
2. Просто огромное количество инструментов на все случаи жизни, поддержка со стороны софта из коробки (RabbitMQ, Grafana, etc)
3. Возможность автоскейлинга. Причем при определенных настройках и поддержке со стороны облачного провайдера - кубер даже сам может заказывать виртуалки, когда нужно и потом их гасить, если они больше не требуются
4. Kubernetes ориентированные ОС, где нет ничего лишнего, они созданы, чтобы только запускать кубы. Если у вас жесткие требования по безопасности - это может быть хорошим решением. Самый яркий представитель таких ОС сейчас - Talos Linux
5. Если вы доросли до собственного ЦОД - куб даже можно использовать для построения своего приватного облака. С интересом наблюдаю за проектом cozystack
👍4
Mailpit вместо Mailhog

Чтобы тестировать отправку писем локально при разработке есть удобный инструмент - mailhog.
Отправляешь ему письма по протоколу SMTP и смотришь в веб-интерфейсе что пришло. В интеграционных тестах можно использовать api, чтобы проверить, что письмо корректно отправилось.
Однако проект заброшен, баги не фиксятся (Привет сортировка писем в режиме maildir).
Сегодня нашел вариант на замену - mailpit. Он вдохновлен мэйлхогом и поддерживает все те же фишки и имеет более приятный интерфейс. Ну и самое главное - проект активно развивается и поддерживается.
👍4🔥21
Php cs fixer научился в параллельность

php-cs-fixer наконец-то научили в распараллеливание проверок. И если на рабочей машине обычно с этим нет проблем, так как есть кэш, то в CI мы проверяем без кэша и на большом проекте проверка может занять довольно продолжительное время. Ранее я распараллеливал этот процесс костылями, но теперь достаточно добавить в конфиг ->setParallelConfig(ParallelConfigFactory::detect()) и фиксер начнет использовать все доступные ядра процессора для проверки кодстайла. Можно этот параллелизм настроить и более гибко. Подробнее в документации - https://cs.symfony.com/doc/usage.html
🔥5👍4
Создаем "виртуалки" для нашего Dev кластера с помощью Terraform

И так. Мы захотели завести себе k8s кластер. И чтобы как следует со всем разобраться мы начнем с Dev кластера. В прод пихать кубы пока рано. У нас будет две машины: k8s-master для служебных нужд и управления кластером (В терминах кубера это называется control-plane) и k8s-worker для нашей прикладной нагрузки.

Чтобы не возиться ручками - создавать "виртуалки" мы будем как всегда с применением подхода Infrastructure as a Code. Для этого есть прекрасный инструмент под названием Terraform от компании Hashicorp.
Сервера мы будем заказывать у нашего доморощенного облака на базе Proxmox (Это специализированный дистрибутив линукса, который делает из вашего железного сервера/серверов среду для выполнения виртуальных машин и не только).

Приступим:
1. Устанавливаем на нашу рабочую машину terraform. Пакет есть во всех популярных дистрибутивах линукса
2. Создаем файлик main.tf. Здесь в начале идет секция с провайдерами (У каждого уважающего себя облака есть провайдер для терраформа). Дальше описываем параметры подключения к proxmox. Юзер и пароль задается в переменных окружения. Это подробно описано в документации. Ну и дальше описываем какие машины мы хотим получить, думаю там все очевидно. Если нет - добро пожаловать с вопросами в комментарии к посту. Ранее я написал виртуалки в кавычках, потому что это не совсем виртуальные машины. Это LXC контейнеры, предшественники докера. Они не используют виртуализацию и запускаются на ядре хост машины.
3. Открываем консоль и набираем terraform init. Здесь терраформ будет качать нужные провайдеры и создавать свои служебные файлики. Из РФ репозиторий с провайдерами недоступен, поэтому на этом шаге потребуется VPN.
4. Далее запускаем terraform plan и смотрим на план, который был для нас построен.
5. Если все окей и нас устраивает - делаем terraform apply. Подтверждаем и ждем. Через некоторое время запрошенные машины будут созданы. Провайдер немного глючный, поэтому иногда приходится после создания писать start = false, делать apply, потом снова ставить start = true и снова применять изменения, чтобы машины стартанули.

Вот и всё, мы получили сервера под наш кластер. В следующем выпуске будем устанавливать k8s и настраивать его для дальнейшей работы с помощью инструмента ansible. При желании можно создание серверов тоже запихнуть куда-нибудь в CI/CD систему, чтобы вообще руками ничего не делать и только дождаться выполнения pipeline
🔥2👍1
Heredoc в Dockerfile

Недавно узнал, что в Dockerfile уже достаточно давно поддерживается Heredoc синтаксис.

Т.е. вместо того, чтобы писать амперсанды:

RUN set -xe \
&& apt-get update && apt-get install --no-install-recommends --no-install-suggests -q -y \
gnupg2 \
libicu-dev \
libpq-dev \
libzip-dev \
postgresql-client \
unzip \
$PHPIZE_DEPS \
&& groupmod --gid=${GID} www-data \
&& usermod --uid=${UID} --gid=${GID} www-data \
&& chown www-data:www-data /var/www \
&& docker-php-ext-enable \
opcache \
&& docker-php-ext-install \
intl \
pdo_pgsql \
sockets \
zip \


можно делать вот так:

RUN <<EOF
set -xe
apt-get update
apt-get install --no-install-recommends --no-install-suggests -q -y \
gnupg2 \
libicu-dev \
libpq-dev \
libzip-dev \
postgresql-client \
unzip \
$PHPIZE_DEPS
groupmod --gid=${GID} www-data
usermod --uid=${UID} --gid=${GID} www-data
chown www-data:www-data /var/www
docker-php-ext-enable \
opcache
docker-php-ext-install \
intl \
pdo_pgsql \
sockets \
zip
EOF


Пользуйтесь, очень удобно!
👍15🔥6
mkcert — удобный способ делать доверенные ssl сертификаты для локальной разработки

Когда мы разрабатываем проект локально — нам часто нужны самоподписанные ssl сертификаты. И желательно чтобы браузер/система им доверяла. Ранее я генерировал такие сертификаты через openssl и добавлял какими-то страшными костылями в доверенные системные серты. Это не всегда работало нормально. А потом моим страданиям пришел конец, я узнал про прекрасную утилиту — mkcert. Спешу и с вами поделиться.

Делаем:
mkcert -install
mkcert -cert-file ./some-dir/example.localhost.crt -key-file ./some-dir/example.localhost.key "*.example.localhost"


И всё! Генерируются сертификаты и добавляются в доверенные. Остается только нужные домены в /etc/hosts внести и пользоваться.

P.S. Посты про кубер на пару недель на паузе. С LXC контейнерами и разворачиванием в них k8s слишком много возни. Будем делать через обычные виртуалки. Я сейчас вдали от своего тестового стенда, а внутри VirtualBox Proxmox работает не совсем корректно с виртуалками, поэтому продолжим как только вернусь к настоящим железкам.
👍8
.dockerignore

Я уже ссылался на то, как пишу файлы .dockerignore в своих проектах в рамках статей по бест-практикам по сборке докер образов. Но решил все таки написать и разъяснить отдельным постом дополнительно про этот файл. Как удобно его писать? Вместо того, чтобы постоянно добавлять то, что мы игнорируем - можно сделать иначе. Заигнорить все, а потом добавить исключения, т.е. то, что попасть в образ все таки должно. Таким образом мы гарантируем, что в сборку не просочится мусор, который мы не учли. Делается это вот так (на примере проекта на symfony):
## Ignore all
*

## Except
!/bin
!/config
!/docker
!/public
!/src
!.env
!.env.local
!composer.json
!composer.lock
!symfony.lock
👍8💯2👏1
Виртуалки для кластера. Дубль 2. Теперь настоящие :)

Первое, что нам нужно сделать - подготовить шаблон для ВМ.
Я делал по вот этой инструкции - ссылка. Соответственно поменял имя с debian12-cloudinit на debian12.vm и storage с local-lvm на local. Тут нужно поправить в соотвествии с тем как у вас настроен proxmox. Делаем это все на сервере, где у нас будут жить ВМ.
Также, чтобы не делать руками каждый раз пункт 14 из инструкции - после 2 шага делаем следующее:
apt install libguestfs-tools -y
virt-customize -a debian-12-generic-amd64.qcow2 --install qemu-guest-agent

Ну а после подготовки шаблона делаем все тоже самое, что делали в этом посте. Только с поправленным main.tf. На этот раз виртуалки создались корректно и сами стартанули без плясок с бубном.

P.S. Долго готовил этот пост, потому как у меня не хотела работать сеть в ВМ на моем стенде. Тому виной был скопированный конфиг для terraform и мои ограниченные познания в сетях в линуксе. Спасибо ребятам из русскоязычного сообщества proxmox, они помогли оперативно разобраться.
👍3
Разворачиваем dev cluster kubernetes с помощью ansible

И так. У нас есть виртуальные машины, теперь самое время засетапить на них кластер куба.
Вручную конечно же мы это делать не хотим, поэтому прибегнем к ansible.
Также будем для настройки нашего кластера в дальнейшем использовать подход GitOps, т.е. все, что мы коммитим в специальный репозиторий - будет отражаться в нашем кластере. Для этого будем использовать инструмент FluxCD. Приступим.

1. В гитлабе создаем репозиторий, в котором будут храниться настройки кластера (Гитлаб у нас не облачный, а развернутый собственноручно - self-hosted)
2. В профиле пользователя делаем Personal Access Token c доступом api, read_repository, write_repository
3. Берем мой плэйбук для разворачивания кластера - https://github.com/Etherlord/k8s-dev-cluster-bootstrap
4. Создаем файл hosts.yaml по примеру из hosts.yaml.dist. Там нужно заполнить ip адреса машин, имя юзера, который будет создан на виртуалках, путь до публичной части вашего ssh ключа, кастомный номер порта для ssh и переменные, которые касаются гитлаба. Все описано в README. ansible_user у нас будет terraform. Он был создан в предыдущем посте, когда мы создавали виртуальные машины.
5. Выполняем make cluster. Дожидаемся успешного выполнения плэйбука
6. Выполняем make install-flux. Дожидаемся успешного выполнения
7. Удаляем из гитлаба токен, он нужен только на время установки FluxCD

Готово! Можно зайти на сервер k8s-master под пользователем из hosts.yaml и выполнить sudo kubectl get node.
Должна получиться примерно такая картина:
NAME         STATUS   ROLES           AGE   VERSION
k8s-master Ready control-plane 23h v1.30.3
k8s-worker Ready <none> 23h v1.30.3


Кластер готов и работает. Но он пока пустой. Для его полноценного функционирования нужны дополнительные настройки. Этим мы займемся в следующих постах. И будем работать уже через наш репозиторий, изменение которого будет влиять на кластер
👍5
Балансировщик нагрузки Metallb

Кластер у нас есть. Давайте начнем его конфигурировать. Чтобы заруливать http трафик в наш кластер нам нужна такая сущность, как ingress. Мы будем использовать самый популярный ingress для куба на базе ingress-nginx. Но для того чтобы он корректно работал - нам потребуется еще одна сущность куба - load balancer. В облаке он есть по умолчанию. А нам на виртуалках придется установить балансировщик для железных серверов - metallb (Есть способы обойтись без балансировщика, но я решил сделать все максимально близким к тому, как будет работать в облаке). Приступим.

При установке кластера через ansible мы также установили систему FluxCD, чтобы использовать подход GitOps для настройки всего, что нам необходимо. Flux при инициализации создал репозиторий, в котором есть папка flux-system.

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

2. В каталоге cluster создаем namespace для metallb с помощью конфигурационного файла namespace.yaml. Коммитим, пушим, через минуту проверяем, что namespace создался с помощью команды sudo kubectl get ns на мастер сервере нашего кластера.

3. Далее заходим в документацию Flux и смотрим на способ установки чего-либо в кластер через Helm (Это что-то вроде пакетного менеджера для куба). Нас интересует конфигурация HelmRepository и HelmRelease. Копируем примеры в файлик hr-metallb.yaml. Далее идем в документацию metallb и ищем там способ установки через helm. Правим файлик примеров под наш случай:

3.1. Берем из доки строчку helm repo add metallb https://metallb.github.io/metallb и в нашем конфиге HelmRepository меняем поля name, namespace и url в соответствии с этой командой.

3.2. Берем следующую строчку helm install metallb metallb/metallb и в соответствии с ней правим в конфиге HelmRelease. Тут также надо поменять name, namespace. Их делаем такими же, как в HelmRepository. Далее меняем поля chart и sourceRef.name. Их берем из команды установки - metallb/metallb. До слэша это chart, после sourceRef.name. В поле version в dev среде можно ставить '*'. В продакшне тут должна быть конкретная версия устанавливаемого софта.

Все это пушим, проверяем статус и ошибки с помощью команды sudo flux get all -n metallb-system. В поле Ready должно быть True по завершению. В противном случае в поле Message будет описание ошибки.

4. Осталось только сконфигурировать установленный metallb. Смотрим раздел доки Configuration. Нас интересует простейшая - Layer 2 Configuration. Создаем файлик metallb-configuration.yaml. В addresses указываем ip адреса, которые metallb сможет выдавать через себя сервисам куба. Пушим. Проверяем командой sudo kubectl get ipaddresspools.metallb.io -n metallb-system что пул адресов создался и содержит правильные значения.

Готово! Балансировщик установлен и настроен. В следующем посте будем устанавливать ingress-nginx
👍3
Устанавливаем ingress-nginx в кластер

Пришло время установить ingress-nginx в наш кластер, но прежде чем это сделать - мы сделаем еще одно важное изменение. Разобьем наш репозиторий на компоненты, чтобы не сваливать все в одну кучу. Приступим

1. Создаем на верхнем уровне каталог components. В нем подкаталог metallb. Переносим файлы, связанные с metallb, туда
2. Для того, чтобы flux видел наши компоненты - в каталоге cluster создаем файл 01-metallb.yaml, где указываем, что нужно подтягивать изменения из каталога components/metallb в кластер
3. Создаем файл kustomization.yaml и указываем там, что в кластер нужно применять файл 01-metallb.yaml и все, что находится в каталоге flux-system
4. Пушим изменения в репозиторий. Проверяем что metallb по прежнему установлен и работает. Способ проверки описан в предыдущем посте. Если вдруг metallb не заработает - удаляем файл metallb-configuration.yaml, пушим в репозиторий, чтобы flux переустановил metallb. Проверяем статус установки flux get all -A. Как только все установится - снова пушим metallb-configuration.yaml в репо
5. Теперь установим ingress-nginx. В каталоге components создаем подкаталог ingress-nginx. Там создаем файл namespace.yaml
6. В каталоге cluster создаем файл 02-ingress-nginx.yaml, там указываем путь к нашему новому компоненту. В kustomization.yaml добавляем 02-ingress-nginx.yaml
7. Пушим все в репозиторий. Некоторое время ждем и проверяем командой kubectl get ns, что неймспейс был создан
8. Дальше в каталоге components/ingress-nginx создаем файл hr-ingress-nginx.yaml. Создаем его по тому же принципу, что был описан в предыдущем посте для metallb. Документацию по установке через helm можно найти тут
9. Пушим в репо. Отслеживаем статус установки через команду flux get all -A
10. Как только статус Ready везде станет True - смотрим какой ip выдался для ingress-nginx командой kubectl get svc -n ingress-nginx. Должно получиться примерно следующее:

NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller LoadBalancer 10.109.132.65 192.168.0.200 80:32547/TCP,443:32076/TCP 32m
ingress-nginx-controller-admission ClusterIP 10.102.137.72 <none> 443/TCP 32m


Здесь нас интересует TYPE LoadBalancer, поле EXTERNAL-IP. Видим, что metallb успешно выдал адрес для ingress-nginx. Переходим в браузере по этому адресу и видим знакомый статус 404 от nginx

Вот и все! ingress-nginx установлен и работает. Финальный вид репозитория можно посмотреть в этой ветке. В следующих постах будем упаковывать php приложение в helm и пробовать задеплоить его в кластер
3👍2
Упаковываем php приложение в helm chart и деплоим в k8s. Часть 1

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

1. Заходим в гитлаб, в репозиторий приложения. Там открываем раздел Settings -> Repository -> Deploy tokens. Создаем три токена: app-example-pull с правом read_registry, helm с правом read_package_registry и helm-push с правом write-package-registry. При создании токенов будут сгенерированы пароли для каждого. Запишите их в надежное хранилище паролей. Далее они нам понадобятся.

2. В репозитории приложения создаем папку .helm. Тут будет лежать наш helm chart. Он состоит из следующих файлов:
2.1. Chart.yaml - здесь лежит описание чарта, его тип, версия чарта и версия приложения. Мы будем в дальнейшем использовать только версию чарта
2.2. values.yaml - здесь хранятся дефолтные настройки чарта. Мы будем переопределять при деплое image, из которого будет деплоится приложение и image tag. Также обратите внимание на параметр ingress.host. По этому адресу будет доступно приложение из браузера.
2.3. .helmignore - думаю понятно для чего этот файл. Взят дефолтный из конструктора чарта (Команда helm create)
2.4. templates/deployment.yaml - здесь описана базовая сущность куба - deployment. В этом файле описывается в скольких репликах запускать приложение, из какого образа, на каком порту контейнер принимает подключения, healthchecks и ограничения по ресурсам, на основе которых куб решает на какую ноду деплоить приложение. Все значения тут - плэйсхолдеры, которые подставляются при установке чарта из values.yaml и переопределенных значений.
2.5. templates/service.yaml - создается также базовая сущность k8s - service. Тут мы говорим кластеру, что данный сервис принимает подключения на 80 порту и перенаправляет трафик на поды (Еще одна базовая сущность куба, по сути стручок с контейнерами; пока у нас в стручке будет один контейнер) приложения на порт 8080. На какие именно поды отправлять трафик задается в секции selector. Тут указываются labels, которые заданы в deployment, чтобы сервис и поды могли друг-друга найти.
2.6. Ну и наконец templates/ingress.yaml - настраиваем ingress так, чтобы трафик приходящий на домен app-example.local перенаправлялся на наш сервис, который в свою очередь зарулит все в нужные контейнеры.

3. Возвращаемся в gitlab и в разделе Settings -> CI/CD -> Variables создаем две переменные HELM_USER со значением helm-push и HELM_PASS с паролем этого Deploy token, его мы создавали на первом шаге. Переменную с паролем помечаем как masked, чтобы в логах pipeline не светилось ее значение.

4. Правим .gitlab-ci.yml. Тут у нас будет три шага:
4.1. Собираем production образ приложения (На самом деле не совсем production, пока мы не переопределям APP_ENV, будем делать это позже, когда подключим БД)
4.2. Пушим в gitlab registry. Тэг ставим по тэгу текущего коммита в сокращенной форме
4.3. Подменяем адрес image и image tag в values.yaml чарта. К сожалению, сам helm при запаковке в архив подменять значения не умеет. Это возможно только при установке, но мы будем ставить чарт автоматом через flux. Далее добавляем helm repo, запаковываем чарт, при этом подменяя последнюю цифру версии на ID текущей Job`ы гитлаба (Это нужно для того, чтобы flux автоматически обновлял приложение в кластере). Ну и пушим архив в гитлаб. На машине с gitlab-runner должен быть установлен helm и плагин cm-push. Плагин устанавливается след. командой helm plugin install https://github.com/chartmuseum/helm-push под юзером gitlab-runner

5. Закидываем изменения в гитлаб, ждем выполнения pipeline. В секции Deploy -> Package registry проверяем наличие helm chart, в секции Deploy -> Container registry должен лежать образ приложения с нужным тэгом.
Упаковываем php приложение в helm chart и деплоим в k8s. Часть 2

6. Осталось настроить только выкатку этого добра через flux.
Тут все практически аналогично установке metallb и ingress-nginx. Смотрим этот коммит.
Из отличий:
6.1. Файл image-pull-secret.yaml - тут мы создаем secret (сущность куба для хранения чувствительных данных) для скачивания образов приложения из gitlab container registry. Тут необходимо в секцию .dockerconfigjson вставить строку, подготовленную след. образом:
6.1.1. Логинимся в registry с помощью команды docker --config deploy login registry.example.com. Используем токен app-example-pull, созданный на первом шаге
6.1.2. Делаем base64 deploy/config.json, получаем искомую строку
6.1.3. Удаляем папку deploy
6.2. В файле hr-app.yaml тоже есть создание секрета. Но тут мы уже напрямую указываем логин helm и пароль для этого токена.

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

7. Пушим в инфраструктурный репозиторий наши изменения, смотрим статус flux get all -A. Как только везде будет Ready = True - переходим к след. шагу.

8. С помощью команды kubectl get ing -n app-example проверяем настроен ли наш ingress для работы с доменом app-example.local. Видим что-то подобное:
NAME                  CLASS   HOSTS               ADDRESS         PORTS   AGE
app-example-ingress nginx app-example.local 192.168.0.200 80 47h


Если все окей добавляем в локальный DNS или /etc/hosts своей машины соответствующую запись. У меня это 192.168.0.200 app-example.local

Открываем браузер и проверяем, что приложуха отвечает по нужному домену. Должна быть надпись Welcome to example application.

Фуф, мы молодцы. В след. посте прикрутим к этому всему добру SSL сертификат, получаемый через letsencrypt. Домен тоже придется сделать настоящий)
👍4
Опрос в догонку. Сложность постов возрастает, объяснить все в маленьком количестве текста становится сложно. Нужны ли видео на ютубе, где все вышеизложенное будет наглядно показано?
Anonymous Poll
52%
Нужны
35%
И текстом норм
13%
Мне все равно
В декабре буду выступать с докладом на PHP Russia 2024!
Расскажу как подготовить своё PHP приложение к работе в облаке.

Если кто-то планирует быть оффлайн - с радостью пообщаюсь.
🎉7👍5🔥5
Шифрованные секреты в инфраструктурном репозитории

Мне не давала покоя мысль о том, что в нашем инфраструктурном git репозитории не должно быть секретов в открытом виде. Все best practice твердят нам это. Я почитал доку и сейчас мы будем делать шифрованные секреты в репозитории, чтобы затем они расшифровывались в кластере и попадали в нужное место. Я выбрал вариант с использованием gpg и утилиты sops.
Приступим:

1. Заходим на мастер машину нашего кластера и создаем там gpg ключ
export KEY_NAME="cluster.yourdomain.com"
export KEY_COMMENT="flux secrets"

gpg --batch --full-generate-key <<EOF
%no-protection
Key-Type: 1
Key-Length: 4096
Subkey-Type: 1
Subkey-Length: 4096
Expire-Date: 0
Name-Comment: ${KEY_COMMENT}
Name-Real: ${KEY_NAME}
EOF

2. Получаем отпечаток нашего ключа
gpg --list-secret-keys "${KEY_NAME}"
Видим следующее:
pub   rsa4096 2024-09-23 [SCEA]
AD02237C200DCF7465E0FA88AF8CB328D6E19757
uid [ultimate] dev flux (flux secrets)
sub rsa4096 2024-09-23 [SEA]

3. Сохраняем его в env переменную export KEY_FP=AD02237C200DCF7465E0FA88AF8CB328D6E19757
4. Экспортируем ключ в кластер
gpg --export-secret-keys --armor "${KEY_FP}" |
sudo kubectl create secret generic sops-gpg \
--namespace=flux-system \
--from-file=sops.asc=/dev/stdin

5. Экспортируем публичную часть ключа и сохраняем его в репозитории в файл cluster/flux-system/.sops.pub.asc
gpg --export --armor "${KEY_FP}" > /home/user/.sops.pub.asc
6. Удаляем ключи с мастер машины кластера. Они тут нам больше не нужны
gpg --delete-secret-and-public-keys "${KEY_FP}"
rm /home/user/.sops.pub.asc
7. Теперь пришло время зашифровать наши секреты и настроить flux так, чтобы он их расшифровывал и в расшифрованном виде сохранял в кластер. Первым делом добавляем в 03-app.yaml следующие строчки:
decryption:
provider: sops
secretRef:
name: sops-gpg

Здесь мы указываем кластеру имя секрета, где хранится секретный ключ gpg, который будет использоваться для расшифровки файлов из репозитория
8. Из файла hr-app.yaml убираем секрет и кладем его в helm-pull-secret.yaml
9. Импортируем публичную часть ключа уже на нашей рабочей машине
gpg --import cluster/flux-system/.sops.pub.asc
10. Ставим утилиту sops. И шифруем наши секреты
cd components/app-example
sops --encrypt --encrypted-regex '^(data|stringData)$' --pgp 'AD02237C200DCF7465E0FA88AF8CB328D6E19757' --in-place helm-pull-secret.yaml
sops --encrypt --encrypted-regex '^(data|stringData)$' --pgp 'AD02237C200DCF7465E0FA88AF8CB328D6E19757' --in-place image-pull-secret.yaml


Получаем зашифрованные версии наших конфигов секретов. helm-pull-secret.yaml и image-pull-secret.yaml
11. Вот и все. Пушим в репо и проверяем статус командой flux get all -A

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

Stay tuned ;)
🔥6