Pull to refresh
0
Сергей Чудаков @CSRedRatread⁠-⁠only

DevOps

Send message
Очень давно получил электронное письмо от друга, в нем в подписи были две такие собачки:

                                 ```           \\|//
                                (o o)          (^ ^)
----------------------------oOO--(_)--OOo---ooO-(_)-Ooo---- 

Теперь понимаю, откуда они родом

Отличная статья, но на мой взгляд местами too opinionated :)


Ничего не имею против Werf, я люблю стандартизацию подходов и тулза у вас вышла отличная, но тем не менее выскажу немного критики по содержанию:


CI/CD у нас обычно несколько окружений (production, staging, development и т. д.). И конфигурация приложения может отличаться для разных окружений.

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

На счёт "не стандартизован" соглашусь, вариантов достичь желаемого достаточно много: можно передавать параметры через опции CLI или переменные окружения; можно пилить umbrela-чарты с оверрайдами для каждого энвайромента, но считаю что подход с использованием нескольких values файлов наиболее стандартным и популярным:


-f base.yaml -f stage.yaml

-f base.yaml -f prod.yaml

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


Если я правильно понял, werf позволяет реализовать тот же паттерн, но в виду упомянутого вами гитерминизма, по прежнему, не является правильным. К слову, тот же Helmfile позволяет указать набор параметров для хельма в зависимости от конкретного энвайромента.
Таким образом у меня по прежнему возникает вопрос: каким образом в werf правильно хранить и передавать параметры для разных энвайроментов? :)


  1. werf должна поддерживать GitOps-подход


GitOps в общем виде — это подход, при котором для развертывания приложений в Kubernetes используется единственный источник правды — Git-репозиторий. Через декларативные действия в Git вы управляете реальным состоянием инфраструктуры, запущенной в Kubernetes. Этот паттерн «из коробки» работает в werf.

У нас есть собственный взгляд на то, как должен быть реализован GitOps для CI/CD (уже упомянутый Giterminism). GitOps в werf поддерживает не только хранение Kubernetes-манифестов в Git, но и версионирование собираемых образов, связанное с Git. Откат до предыдущей версии приложения выполняется без сборки выкатывавшихся ранее образов (при условии, что версия учитывается политиками очистки). Другие существующие реализации GitOps не дают этой гарантии.

Можно долго ходить вокруг да около GitOps (огромное "спасибо" Weaveworks за то что придумали такой неоднозначный термин). Хранение правды в Git да, но всё-таки оно немного не про то.


Использование GitOps подразумевает наличие контроллера или GitOps-оператора (называйте как хотите), который делает непрерывный синк состояния Git-репозитория с Kubernetes-кластером.



По сути — это такой же reconciling loop, по аналогии с тем как контроллеры Kubernetes создают нижестоящие ресурсы. Например Deployment генерирует ReplicaSet, ReplicaSet генерирует Pods. Таким же образом должен работать и GitOps-оператор, отрендерив код описанного приложения в Git-репозитории, он должен непрерывно перекладывать его в Kubernetes.


Оба решения Helm и Werf не обладают данной характеристикой. Однако иметь контроллер Werf для Flux2, думаю, было бы весьма здорово.


Для организации GitOps, в том понимании в котором он изначально задумывался, таких решения сейчас два: ArgoCD и FluxCD. Второй более нативен к хельму, так как непосредственно использует его для деплоя в кластер.


Забавен тот факт, что применение GitOps может быть вообще не завязано на использование Git. Вышеупомянутые тулзы могут следить и работать также с Helm-registry и даже S3-бакетами.


У нас есть собственный взгляд на то, как должен быть реализован GitOps для CI/CD (уже упомянутый Giterminism). GitOps в werf поддерживает не только хранение Kubernetes-манифестов в Git, но и версионирование собираемых образов, связанное с Git. Откат до предыдущей версии приложения выполняется без сборки выкатывавшихся ранее образов (при условии, что версия учитывается политиками очистки). Другие существующие реализации GitOps не дают этой гарантии.

Здесь стоит упомянуть про kbld и kapp и другие утилиты от Caravel, которые делают примерно тоже самое что и Werf, но без жёсткой привязки к конкретному стеку.


И Gitkube, решения, которое может выступать в качестве гейтвея для деплоя с помощью простого git push, оно также умеет собирать образы и подставлять дайджест в темплейты.
Так как оно представляет своего рода гейтвей Git-to-Kubernetes, оно в принципе не позволяет запушить неисправный коммит в кластер. Таким образом, скрепя зубами, его всё таки можно назвать push-based GitOps-решением, однако оно не развивается уже как 3 года и я не советовал бы его использовать.


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

Стоит заметить, что в дистрибутивах с systemd могут использоваться sytemd timers. Например, в Дебиане на одной из моей машин скрипт для обновления сертификатов let’s encrypt запускается именно по таймеру systemd, а не по крону.


Также таймеры systemd имеет чуть больше возможностей, например монотонный таймер: запуск сервиса или скрипта через n минут после загрузки компьютера.


Чуть больше, например, на вики Arch: https://wiki.archlinux.org/index.php/Systemd_(Русский)/Timers_(Русский)

Так этот анекдот правда!

Некий программист-коболист в поте лица трудился над пресловутой проблемой 2000 года. Он чинил программы во многих фирмах и зашибал приличные бабки. Но по мере приближения роковой даты его все больше охватывал ужас: что будет со всеми этими программами и с ним самим? Наконец он решил заморозиться и проспать в анабиозе до февраля 2000 года, а там, глядишь, вся свистопляска и уляжется…
… Он проснулся в странном незнакомом помещении, вокруг ликовали люди:
— Очнулся, очнулся!
— Сейчас с вами будет говорить президент Земного Шара.
На огромном стереоскопическом экране возник человек, весьма похожий на Билла Гейтса.
— Видите ли, программа вашей камеры при переходе к 2000 году сработала неправильно, и вы проспали почти 8000 лет. Но вы не волнуйтесь. Наша жизнь прекрасна. Мы достигли огромных успехов в науке и технологии. Мы покорили время и пространство. Мы…
— Но почему вы меня разморозили?
— Понимаете, приближается 10000 год, а в вашем досье указано, что вы знаете КОБОЛ…
Ниже практически всё подметили:
* нижние подчеркивания перед всем что только можно — чтобы защитить себя от пользователей, пишущих макросы в нижнем регистре
* вместо throw/try/catch — макросы, так как многие пользователи используют стандартную библиотеку с выключенными исключениями
* большие и длинные тела if — оптимизация под конкретный компилятор (разработчик знает где у него hot path и знает какую ветку компилятор делает hot path). Некоторые стандартные библиотеки имеют в телах goto по той же причине — знают косяки своего компилятора и написали goto чтобы сгенерировался более оптимальный код
* Множество макросов так же делают библиотеку юзабельной для разных версий стандарта. Так libstdc++ работает на флагах -std=(gnu++98,gnu++03,gnu++11,gnu++14,gnu++1z,c++98,c++03,c++11,c++14,c++1z), без макросов напободие _GLIBCXX_NOEXCEPT просто не обойтись.
* Есть макросы, которые позволяют работать без RTTI (так любят делать embedded разработчики)
* Другие странности форматирования (например после открывающей фигурной скобки отступ в -4 пробела) связаны с очень древними кодовыми базами… когда мониторы были узкие и вся С++ строчка иначе на экран не помещалась
* Куча плясок с бубном вокруг аллокаторов (поэтому много всякого метапрограммирования и специфичные typedef для указателей, вместо T*). Все для того, чтобы пользовательские аллокаторы с using pointer = fancy-pointers работали
* Куча плясок с бубном вокруг точек кастомизации — поэтому часть методов помечены как ::std::, другие методы вызываются без указания namespace
* Много плясок с бубном вокруг исключений — практически всё что пользователь передал в качестве шаблонного параметра может кинуть исключение в любой момент. После такого исключения надо оставаться в валидном состоянии (да, даже если функция хеширования кинула исключения — надо подчистить ресурсы и остаться в валидном состоянии).
* Некоторые имплементации поддерживают дебажные версии стандартной библиотеки, из-за чего макросов становится еще больше, а странность кода возрастает в угоду производительности в дебажном режиме
*… (я что-то наверняка забыл)
Для понимания нужно вспомнить историю Си. Пара аспирантов и пара студентов делала структурный ассемблер для PDP-7. Машина была словной (16 битные слова), а язык безтиповым и назывался Би.

От PDP-7 в языке Си остались такие конструкции как эквивалентность arr[i] и *(arr+i). На безтиповом языке для словной машине это было просто сложение.

Когда они решили перейти на PDP-11, безтиповым языком было уже не обойтись. PDP-11 была словной машиной с адресацией до байта. То есть по четном адресу можно было прочитать и слово и байт, а по нечетному — только байт. Поэтому им пришлось вводить типы. Ну и сменить название языка на Си.

И тогда, для ускорения переделок, была придумана гениальная идея. Вместо описания типа — описывать, какими преобразованиями переменная приводится к базовому типу. int **pp означает, что если дважды разыменовать pp, то получиться int. Этих хаком они упростили себе переделку компилятора,

От PDP-11 в Си осталась конструкция *dst++ = *src++, которая транслировалась в одну команду mov (R5)++, (R3)++

Если бы вы начали изучение Си с The C Programming Language, то там довольно явно рассказывается об этом…

Ну а первые впечатления от Си (1984 год): вау, какой красивый ассемблер! Теперь можно писать код на ЯВУ и понимать, какие команды будут исполняться! Особенность компиляции (из.с в .s, а уж потом в .obj) этому только помогали.

Но да, к 1990ому году пришли иные машины и иные компиляторы. И Си перестал восприниматься ассемблером конкретной машины. А хак с заменой описания переменных на описание преобразования в базовые типы — остался.
Как уже писали выше — чтобы собирать чть-то на Debian/Ubuntu из исходников нужна очень веская причина. Обычно, если ПО популярно, его тут же добавляют в какой-нибудь репозиторий. Если не добавили до сих пор — значит, как правило, есть причины.
Checkinstall, несмотря на все его плюсы (сам им иногда пользуюсь) — жуткий костыль, который работает на перехвате API
Что-то из исходников собирается так:
apt-get build-dep samba (или samba4) — вместо строки «apt-get install [куча dev-пакетов]»
apt-get source samba
правим файлик debian/rules под наши нужды
dpkg-buildpackage -b -rfakeroot (собираем только бинарный пакет, работает без прав админа)
Результат — нормальные deb-пакеты со всеми зависимостями, скриптами установки и т.п.
А вот еще мануал от самой Самбы. Тоже через dpkb-buildpackage: wiki.samba.org/index.php/Samba4/Debian

В случае с Самбой намного более интересен вопрос: «Что не работает?»
У вас все с первого раза завелось? Клиенты под всем спектром ОС от Windows 2000 до Windows 8/Server 2012 заходят/авторизуются? Все стабильно, ничего не отваливается? Сколько уже работает система в продакшене?
А ещё можно в «Run» или в cmd писать windowsupdate.log, как будто это название программы.
Есть еще такая интересная софтина http://riemann.io/ — поверх collectd
Недавно обсуждали на hackernews, если не ошибаюсь, http://netdata.firehol.org
Можно просто systemctl restart nginx. А вообще, я у себя сделал:
alias 'stop'='sudo systemctl stop'
alias 'start'='sudo systemctl start'
alias 'restart'='sudo systemctl restart'
alias 'status'='sudo systemctl status'

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

Пример, как это выглядит:

DGS-3200-10:4#cable_diag ports 1-10
Command: cable_diag ports 1-10

 Perform Cable Diagnostics …

 Port     Type       Link Status          Test Result          Cable Length (M)
 ---- ------------  -------------  -------------------------  -----------------
  1    1000Base_T    Link Up        OK                                50
  2    1000Base_T    Link Up        OK                                1
  3    1000Base_T    Link Up        OK                                3
  4    1000Base_T    Link Down      Pair1 Open      at 3   M          -
                                    Pair2 Open      at 4   M
                                    Pair3 Open      at 3   M
                                    Pair4 Open      at 4   M
  5    1000Base_T    Link Up        OK                                -
  6    1000Base_T    Link Down      No Cable                          -
  7    1000Base_T    Link Down      No Cable                          -
  8    1000Base_T    Link Down      No Cable                          -
  9    1000Base_T    Link Down      No Cable                          -
  10   1000Base_T    Link Down      No Cable                          -
Раз сказал А, то почему-бы не показать как отличать коней по зубам. Вот внешние отличительные визуальные особенности. С ретинами сложнее, внешне они практически не отличаются.
Как правило, ноуты с Thunderbolt имеют гравировку по аллюминию, в то время как более старые устройства с mini-Displayport маркировались краской.
Типа дисклеймер.
Не полагайтесь только на приведенные ниже признаки. Но они помогут примерно опознать «коня по зубам».

Macbook Pro 2010 и ранее.

— разъем подключения экрана mini-displayport со значком |[]|

Macbook Pro 2011

— разъем подключения экрана и иных устройств thunderbolt (с молнией)

Macbook Pro 2012

— USB 3.0, выглядит примерно так


Macbook Air 2010


— Зарядка MagSafe1, внешне более квадратная
— разъем подключения экрана mini-displayport со значком |[]|

Macbook Air 2011


— Зарядка MagSafe1, внешне более квадратная
— разъем подключения экрана и иных устройств thunderbolt (с молнией)

Macbook Air 2012

— Зарядка MagSafe2, внешне более узкая
— Решетка микрофона круглая, 1шт
— Usb 3.0

Macbook Air 2013 и 2014

— Зарядка MagSafe2, внешне более узкая
— Отверстия микрофонов, 2шт

Macbook Air 2015
— При выключенном ноутбуке тачпад не щелкает. При включенном щелкает при нажатии в самой верхней точке тачпада, при загруженной макоси щелкает дважды, если давление наращивать постепенно (ForceTouch). У более старых ноутов одна физическая кнопка в нижней части тачпада. По этой причине при нажатии в верхней точке тачпада клик будет только при очень сильном давлении.
Chrome DevTools — и правда незаменимая штука.

В обязательном порядке смотреть бесплатный курс по нему от Google/CodeSchool — Discover DevTools.
-Джон, хотя в Вашем контракте и указан 8-часовой рабочий день, Вам прекрасно известно, что в нашей компании принято работать до 9 вечера. Вы уже второй день уходите домой в 6. Как Вы это объясните?
-Сэр, но я ведь в отпуске.
Что немцу хорошо, то русскому — смерть. Это мое мнение по содержанию перевода.

В современных условиях я советую 4 принципа работы программистом в РФ

  • Будь всегда администратором репозитория — иначе потеряешь работу
  • Пиши так, чтобы читать код мог только ты — иначе потеряешь работу
  • Оставляй всегда пару косяков — иначе потеряешь работу
  • Минимальная единица планирования — неделя — иначе потеряешь работу


Перевожу последний пункт на язык попроще —

Никогда не говори
Тут работы на два часа


Все советы — для проектов, не нужных будущему. А таких — 90 процентов.

И самое главное.

Я программирую, потому что программирую
Портос

Задайте алиас. Делов-то.
C:\> doskey cd=cd /D $*
C:\> cd Y:\
Y:\>
UFO landed and left these words here
UFO landed and left these words here

Information

Rating
Does not participate
Location
Пермь, Пермский край, Россия
Date of birth
Registered
Activity