Эшу быдлокодит
299 subscribers
128 photos
12 videos
7 files
169 links
Дневник C# разработчика.

Личка: @EshuMarabo
Гитхаб: https://github.com/vladzvx

Стек: C#, PostgreSQL
Download Telegram
Довольно важная и модная сейчас тема - автоматическое развертывание кода и в пределе - непрерывная поставка. После того как программист отправил несколько строк кода в репозиторий запускаются сонмы автотестов, если всё ок - строки попадают на прод или в грядущее большое обновление.

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

Использовать Actions можно двумя путями (в т.ч. комбинируя их): для проверки работоспособности кода, прогоняя автотесты и для развертывания собранного ПО на сервер. Тестирование - отдельная тема, расскажу о нём потом, как разберусь до конца сам. В целом, документация довольно подробная, потому остановлюсь только на некоторых неочевидных моментах.

1. Github Actions позволяет выполнять консольные команды как на удаленном сервере, так и на виртуалке, выделяемой гитхабом на время работы скрипта. На этой виртуалке осуществляется компиляция и сборка, а также отправка готовой программы по назначению. Дисковое пространство виртуалки организовано довольно неочевидно, потому не стесняйтесь после каждого чиха делать
run: |
ls
pwd

Чтобы понять где вы находитесь и что происходит. Результат будет выведен в лог выполнения Action-а.

2. Для работы с внешним миром стоит воспользоваться готовыми решениями. Так, для исполнения скрипта на сервере можно воспользоваться пакетом appleboy/ssh-action@master, а для архивирования и отправки результата сборки - appleboy/scp-action@master

Главное - не забывать, что вы имеете дело со стандартным консольным линуксом. Практически всё, что можете сделать там - можно сделать и тут.

3. Приватная информация. К серверу надо логиниться, а раскрывать IP адрес и пароль от сервера или SSH-ключ - не комильфо. Специально для этого добавлены Секретки: вкладка Settings, там - Secrets. Туда можно приватную информацию и использовать её в скриптах по необходимости примерно таким образом: ${{ secrets.DOCKER_HUB_LOGIN }}.

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

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

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

#кодинг
#devops
1
Продолжу затронутую уважаемым @ssleg тему тестов. Я наконец повзрослел и осознал логику организации функциональных и интеграционных тестов.

Если коротко - используем CD/CI (в моем случае Github Actions) для прогона обычных unit-тестов, завязанных на внешние сервисы. Нужные элементы - базы данных/другие микросервисы - поднимаем на отдельном сервере с помощью Docker из того же скрипта CD/CI. По завершении тестов - убираемся за собой.

Для иллюстрации создал репозиторий на гитхабе и настроил конвейер CD/CI.

Суть происходящего: проверяется взаимодействие самописного сервиса на c#, MongoDB и Tarantool-а. В моём случае - на идентичность тестовых данных, положенных в обе базы из моего сервиса.

Скрипт CD/CI состоит из трех частей (job-ов):
1. Развертывание инфраструктуры (deploy_infrastructure). Я тупо клонирую на сервер репозиторий и поднимаю прямо в папке решения всю систему с помощью docker-compose up -d --build. У меня на сервере запускаются 3 сервиса: мой, тарантул и монга.

2. Собственно тестирование (build_and_run_test). Если инфраструктура была развёрнута - запускаются все тесты, реализованные в соответствующих проектах, в т.ч. завязанные на базы данных.

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

При воспроизведении тесты живут в чем-то вроде виртуалки, предоставляемой Github-ом. Известны параметры подключения к сервисам, запущенным на предыдущей стадии, потому с ними можно провзаимодействовать и провалидировать результат.

Если всё ок - job загорается зелёным, нет - красным. К результату можно привязывать различные действия: пропускать коммит в репозиторий, начинать деплой в прод и т.д.

3. Зачистка следов (clear_infrastructure). Вне зависимости от результатов прошлой стадии, останавливаются и удаляются все запущенные на этапе 1 сервисы.

Имея простенький сервер-полигон за 130р/месяц и бесплатный Github actions можно реализовать практически любые свои фантазии по покрытию кода тестами: у меня тестируется только класс для работы с базами.

P.S. Синтаксис в скрипте вида ${{MAIN_HOST}} - это использование секретов Github actions: хранилища конфиденциальных данных, которым не место в репозитории. Добавляются они через настройки. Туда удобно помещать ssh ключи, адреса серверов, пароли и т.д.

#кодинг
#автотесты
#devops
👍1
На неделе перешагнул ещё одну важную ступеньку: освоил гитлаб на базовом уровне. Собрал пока экспериментальный стенд вида: мы коммитим в репозиторий, сам собирается докер образ, сохраняется в хранилище образов, после чего вытягивается оттуда и запускается на машине.

Система непрерывной поставки/развертывания с гитлабом выглядит примерно так: есть центральная машина на которой стоит гитлаб. На той же или на соседних машинах установлены Gitlab Runner-ы, выполняющие команды гитлаба.

Вариантов использования Runner-ов масса, я пока остановился на самом простом: выполнение последователльности консольных команд, забитых в скрипте CI/CD.

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

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

#devops
#gitlab
👍7
Гитлаб для чайников. Часть 1.

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

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

Необходимая база:
1. Командная строка линукса, хотя бы минимум
2. docker, docker-compose
3. Основы git, чтобы не терять сознание от веток, мержей и коммитов.

Заодно добавлю новый тэг - #devops

#gitlab
Гитлаб для чайников. Часть 2.

Система выглядит примерно таким образом:
На первый сервер ставится гитлаб. В нем включается функционал хранения докер-образов.

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

На третий сервер ставится gitlab runner, который будет собирать образы и NuGet пакеты.

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

Логика работы примерно такая: когда кто-то коммитит в репозиторий, запускается скрипт ci cd. Первая часть собирает пакеты или образа на сервере 3. Пакеты отправляются в BaGet на втором сервере. Образа - во встроенное в Gitlab хранилище.

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

Оба этапа предваряются логином к хранилищу образов и зачисткой кэша образов докера на машине с runner-ом. Я логинился с помощью Deploy Token-ов.

#gitlab
#devops
Гитлаб для чайников. Часть 3.

В гитлабе нам понадобится создать группу проектов, в ней добавить runner, общий на всю группу (для сборки образов/пакетов во всей группе). Runner может быть как групповым, так и выделенным проекту.

После этого скопировать сгенерированную команду для подключения на сервер номер 3. Выбрать тип runner-а shell, то есть он будет тупо выполнять консольные команды, прописанные в скрипте автодеплоя в гитлабе.

Давлее, повторить процедуру для всех серверов, куда будет идти деплой, runner-ы по ситуации цепляются или к проектам, или к группе.

Если общение с gilab-ом проходит по http, а не по https, надо не забыть добавить gitlab в перечень разрешенных небезопасных источников для докера в файле /etc/docker/daemon.json.

Также надо не забыть выдать пользователю-докеру прав на работу в линухе.

#gitlab
#devops
Гитлаб для чайников. Часть 4.

Всю информацию, необходимую для деплоя и работы сервисов, которая не является статичной/открытой я поместил в переменные (Settings => CI/CD => Variables).

Переменные подтягиваются при выполнении скрипта деплоя двумя способами:
1. Обычные переменные просто подставляются в текст скрипта синтаксисом вида ${VAR_NAME}
2. Переменные типа File можно подсунуть в файловую систему проекта во время строки синтаксисом вида


cp  ${FILE_VAR_NAME} prod.env
В обычных переменных я держу пароли, адреса серверов и т.д. А в файловые сохраняю .env файлы для подтягивания переменных окружения docker-compose-ом.

При деплое используется два типа docker-compose файлов. Первый для построения образов, второй - собственно для деплоя.

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

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

В Gitlab CI/CD скриптах можно менять поведение в зависимости от ветки Гита, пока самое удобное для меня место - секция workflow в скрипте. Если ветка - dev, то подтягиваем из переменных файлы DEV_BUILD_ENV и DEV_DEPLOY_ENV, а также вызываем для деплоя runner, помеченный тегом dev_deploy_runner. И MASTER_BUILD_ENV, MASTER_DEPLOY_ENV, master_deploy_runner для ветки master соответственно.

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

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

Механизм подсовывания примерно такой. В файлы с переменными окружения, после выполнения операции cp ${FILE_VAR_NAME} .env подсовывается строка tag_suffix = $CI_COMMIT_SHORT_SHA, и соответствующее значение начинает подтягиваться в тэг образа.

Сей поток сознания - изложение опыта работы с гитлабом, полученного примерно за 16 часов, 8 в июле, 8 - на этой неделе. А предваряла им пара лет эпизодических мучений с GitHub Actions и докером. Естественно, нормальный девопс сделает лучше и быстрее, но если его нет под рукой, вполне реально завести небольшое хозяйство самостоятельно.

#gitlab
#devops
Sphagnum. Часть 9. Доска задач и репозиторий.
#sphagnum@eshu_coding

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

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

Затем я подумал о Гитлабе. Весь нужный функционал есть, но вспомнил, сколько мороки с администрированием и настройкой и расхотел.

Зашёл на гитхаб - ux не очень. Быстро (в течение 2 минут) сделать минималистичный канбан в проекте не удалось.

Тогда я решил причаститься Gitea. Доска конкретного репозитория создалась за минуту, коммиты прилинковались, чек листы в задачах удобные. Зеркалирование на гитхаб настроилось мгновенно.

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

#gitea
#cicd
#devops
👍9👏1
Освоил девопсячий минимум на базе Gitea. В целом - тот же gitlab, но без понтов и ощутимо проще.

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

Вставляем кусок yml скрипта из примера в папку для ci cd скриптов - управление командной строкой работает. Если гитлаб раннер может выполняться миллионом разных способов: и в докере, и в командной строке самой машины и ещё хрен знает как, тот у act_runner-а - раннера gitea - вариант один - в докер контейнере с node.js.

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

В общем, отличное решение для микрокоманд. Но человек на 5 и более, работающих над одним проектом я бы уже ставил гитлаб.

#gitea
#devops
👍6🤮1
Пожалуй пришло время обновить закреплённый пост. Каналу уже 5 лет, с прошлого закрепа изменилось многое.

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

За прошедшие 5 лет я сменил 4 места работы:
1. Фирма, занимающая АСУ ТП в области учёта ресурсов.
2. Медтех стартап в Сколково, делали системы поддержки принятия врачебных решений.
3. Сеть общепита, делал бэкенд службы доставки.
4. Банк, текущее место работы. Работаю в домене клиентских карточек.

Мой технологический стек:
C#, PostgreSQL. Плотно работал с MongoDB, RabbitMQ, Tarantool, умею строить базовую инфраструктуру: логи (Loki), метрики (Prometheus), девопсятина (gitlab, gitea, github actions, docker).

Поверхностно знаком с Apache Kafka, MS SQL и фронтовыми фреймворками - React.js и AvaloniaUI.

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

Далее будет навигация по каналу.

Общие теги:
#csharp@eshu_coding - общий тег для постов про разные аспекты разработки на языке программирования c#
#postgresql@eshu_coding - разные интересные моменты про PostgreSQL.
#devops@eshu_coding - мои эксперименты в девопсятине и инфраструктуре.
#mongodb@eshu_coding - записки про MongoDB.
#tarantool@eshu_coding - заметки про Tarantool.

Pet - проекты:
#палантир@eshu_coding - завершенный проект, которым я занимался весь 2021 год - поисковик по телеграму.
#sphagnum@eshu_coding - попытка написать свой брокер сообщений, пока застопорилась на стадии изучения теории и прототипирования по причине нехватки времени.

Книги:
#рихтер@eshu_coding - заметки и конспекты по основополагающей книге про C# - CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#, Джеффри Рихтер. Хоть .NET 4.5 вышел до моего появления в IT, внутренности платформы во основном остались прежними.

Конспекты прослушанных выступлений на конференциях:
#dotnext@eshu_coding - Dotnext 2023
#highload@eshu_coding - Highload++ 2024

Шпаргалки и мои заметки для подготовки к собеседованиям #собес@eshu_coding

Природа и путешествия #природа@eshu_coding #путешествие@eshu_coding
7👍6🔥2👎1