Русский
Русский
English
Статистика
Реклама

Системное администрирование

Перевод Разработка REST-серверов на Go. Часть 3 использование веб-фреймворка Gin

17.06.2021 16:13:58 | Автор: admin
Сегодня, в третьей части серии материалов, посвящённых разработке серверов на Go, мы займёмся реализацией нашего REST-сервера с использованием Gin одного из самых популярных веб-фреймворков для Go. Вот код, который мы будем тут обсуждать.



Выбор веб-фреймворка


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

Я выбрал именно Gin из-за того, что это один из самых популярных проектов такого рода (если судить по количеству GitHub-звёзд). Этот фреймворк кажется минималистичным, возникает такое ощущение, что с ним будет легко работать. Состояние документации к нему оставляет желать лучшего, но сам фреймворк настолько понятен, что мне, несмотря на это, было достаточно легко в нём разобраться и начать им пользоваться.

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

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

Маршрутизация и Gin


Наша функция main настраивает новый маршрутизатор Gin и регистрирует маршруты:

router := gin.Default()server := NewTaskServer()router.POST("/task/", server.createTaskHandler)router.GET("/task/", server.getAllTasksHandler)router.DELETE("/task/", server.deleteAllTasksHandler)router.GET("/task/:id", server.getTaskHandler)router.DELETE("/task/:id", server.deleteTaskHandler)router.GET("/tag/:tag", server.tagHandler)router.GET("/due/:year/:month/:day", server.dueHandler)

Вызов gin.Default() возвращает новый экземпляр Engine основного типа данных Gin, который не только играет роль маршрутизатора, но и даёт нам другой функционал. В частности, Default регистрирует базовое ПО промежуточного уровня, используемое при восстановлении после сбоев и для логирования. Подробнее о таком ПО мы поговорим позже.

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

  1. Вместо указания HTTP-метода в виде дополнительного (Go) вызова метода в маршруте, метод закодирован в имени функции, используемой для регистрации маршрута. Например тут используется конструкция вида router.POST, а не что-то вроде router.HandleFunc(...).Methods(POST).
  2. Gorilla поддерживает обработку запросов с использованием регулярных выражений. А Gin нет. К этому ограничению мы ещё вернёмся.

Обработчики запросов


Посмотрим на код обработчиков запросов, используемых при применении Gin. Начнём с самых простых, в частности с getAllTasksHandler:

func (ts *taskServer) getAllTasksHandler(c *gin.Context) {allTasks := ts.store.GetAllTasks()c.JSON(http.StatusOK, allTasks)}

Тут стоит обратить внимание на несколько интересных моментов:

  1. У обработчиков, используемых в Gin, нет стандартных сигнатур HTTP-обработчиков Go. Они просто принимают объект gin.Context, который может быть использован для анализа запроса и для формирования ответа. Но в Gin есть механизмы для взаимодействия со стандартными обработчиками вспомогательные функции gin.WrapF и gin.WrapH.
  2. В отличие от ранней версии нашего сервера, тут нет нужды вручную писать в журнал сведения о запросах, так как стандартный механизм логирования Gin, представленный ПО промежуточного уровня, сам решает эту задачу (и делается это с использованием всяческих полезных мелочей, вроде оформления вывода разными цветами и включения в журнал сведений о времени обработки запросов).
  3. Нам, кроме того, больше не нужно самостоятельно реализовывать вспомогательную функцию renderJSON, так как в Gin есть собственный механизм Context.JSON, который позволяет формировать JSON-ответы.

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

func (ts *taskServer) getTaskHandler(c *gin.Context) {id, err := strconv.Atoi(c.Params.ByName("id"))if err != nil {c.String(http.StatusBadRequest, err.Error())return}task, err := ts.store.GetTask(id)if err != nil {c.String(http.StatusNotFound, err.Error())return}c.JSON(http.StatusOK, task)}

Тут особенно интересно выглядит обработка параметров. Gin позволяет обращаться к параметрам маршрута (к тому, что начинается с двоеточия, вроде :id) через Context.Params.

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

Привязка данных запросов


И последний обработчик запросов, который мы рассмотрим, это createTaskHandler. Он обрабатывает запросы, которые включают в себя особые данные, поэтому с ним интересно будет познакомиться поближе:

func (ts *taskServer) createTaskHandler(c *gin.Context) {type RequestTask struct {Text string  `json:"text"`Tags []string `json:"tags"`Due time.Time `json:"due"`}var rt RequestTaskif err := c.ShouldBindJSON(&rt); err != nil {c.String(http.StatusBadRequest, err.Error())}id := ts.store.CreateTask(rt.Text, rt.Tags, rt.Due)c.JSON(http.StatusOK, gin.H{"Id": id})}

В Gin имеется серьёзная инфраструктура для организации привязки запросов к структурам данных Go, содержащих данные из запросов. Тут под привязкой понимается обработка содержимого запросов (которое может быть представлено данными в различных форматах, например JSON и YAML), проверка полученных данных и запись соответствующих значений в структуры Go. Здесь мы пользуемся весьма примитивной формой привязки данных для RequestTask, где проверка данных не используется. Но, полагаю, нам стоит знать не только о базовых, но и о более продвинутых возможностях Gin.

Можно заметить, что Gin-версия createTaskHandler существенно короче более ранних версий аналогичного обработчика, так как за разбор JSON-данных запроса отвечает ShouldBindJSON.

Ещё внимание обратить стоит на то, что теперь нам не нужно пользоваться одноразовой структурой для ID ответа. Вместо этого мы используем gin.H псевдоним для map[string]interface{}; это очень просто, но, всё же, позволяет весьма эффективно конструировать ответы, используя совсем небольшие объёмы кода.

Дополнительные возможности Gin


В нашем примере мы изучили лишь малую долю того, что Gin может предложить разработчикам веб-приложений. У Gin имеется множество стандартных дополнительных возможностей, вроде часто используемого ПО промежуточного уровня, системы аутентификации и вспомогательных механизмов для вывода HTML-шаблонов. Всё это несложно реализовать и без использования фреймворка, но использование Gin, определённо, ускорит решение соответствующих задач и позволит, по крайней мере, в простых случаях, обойтись скромными объёмами кода.

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

Ограничения фреймворков


Обратная сторона удобства работы с веб-фреймворками это их ограничения и непривычные стилистические особенности кода, который пишут с их использованием. Мы уже столкнулись с подобным ограничением в нашем простом примере. Речь идёт об отсутствии поддержки регулярных выражений в системе маршрутизации Gin. А это значит, что обработка любого необычного маршрута, его разбор и проверка, потребуют писать больше кода.

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

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

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

Недостатки фреймворков, однако, нельзя назвать несовместимыми с жизнью. И я не пытаюсь кого-то убеждать в том, что ему нужен или не нужен фреймворк. Я лишь стремлюсь показать объективную реальность и описать некоторые проблемы, с которыми сталкиваются программисты, использующие на практике различные программные пакеты и фреймворки.

Каким фреймворком вы воспользовались бы при разработке сервера на Go?


Подробнее..

Перевод Фишинг с поддельным приглашением на встречу

15.06.2021 12:07:46 | Автор: admin

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

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

Что я хотел сделать в этой атаке?

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

Создание встречи (в Outlook) обычно работает следующим образом:

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

  • установите название встречи и укажите участников

  • нажмите Отправить, и ваши участники получат красивое электронное письмо, в котором они смогут принять или отклонить приглашение на собрание.

Создание встречи в OutlookСоздание встречи в OutlookТак выглядит приглашение на встречуТак выглядит приглашение на встречу

Что не так с этим приглашением?

Когда вы создаёте приглашение на встречу, вы фактически отправляете обычное электронное письмо с вложенным файлом iCalendar.В зависимости от почтового клиента получателя письма и того, как этот клиент обрабатывает iCalendar, вы можете увидеть красивый email или простое письмо с вложением.Ниже вы можете увидеть, как выглядит приглашение на собрание команды в protonmail.

Что такое объект iCalendar?

СогласноВикипедии:

Универсальный формат iCalendar позволяет пользователям хранить и обмениваться информацией своего календаря и расписания (например, события, задачи, информация о свободном/занятом времени).Файл iCalendar сохраняется в текстовом формате и содержит событие или задачу; используется для отправки событий или задач другим пользователям, которые могут импортировать их в свои календари. Обычно имеет расширение .ics

iCalendar поддерживается Outlook, календарём Google, Yahoo, Apple и многими другими.В этой статье я сосредоточусь на Outlook.

Ниже вы можете увидеть мою версию iCalendar для приглашения на групповую встречу.Я просто отправил приглашение на встречу на свой адрес в protonmail, загрузил его и прочитал вложение.

BEGIN:VCALENDARMETHOD:REQUESTPRODID:Microsoft Exchange Server 2010VERSION:2.0BEGIN:VTIMEZONETZID:GTB Standard TimeBEGIN:STANDARDDTSTART:16010101T040000TZOFFSETFROM:+0300TZOFFSETTO:+0200RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10END:STANDARDBEGIN:DAYLIGHTDTSTART:16010101T030000TZOFFSETFROM:+0200TZOFFSETTO:+0300RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3END:DAYLIGHTEND:VTIMEZONEBEGIN:VEVENTORGANIZER;CN=ExAndroid Developer:mailto:<redacted>@outlook.comATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=<redacted>@protonmail.com:mailto:<redacted>@protonmail.comDESCRIPTION;LANGUAGE=en-US:<stripped>\n\nUID:040000008200E00074C5B7101A82E00800000000508CC0468E28D701000000000000000 01000000096DF011F20A29943A70B5DA5047021A5SUMMARY;LANGUAGE=en-US:Test meetingDTSTART;TZID=GTB Standard Time:20210403T000000DTEND;TZID=GTB Standard Time:20210404T000000CLASS:PUBLICPRIORITY:5DTSTAMP:20210403T103619ZTRANSP:OPAQUESTATUS:CONFIRMEDSEQUENCE:0LOCATION;LANGUAGE=en-US:Microsoft Teams MeetingX-MICROSOFT-CDO-APPT-SEQUENCE:0X-MICROSOFT-CDO-OWNERAPPTID:-570210331X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVEX-MICROSOFT-CDO-INTENDEDSTATUS:BUSYX-MICROSOFT-CDO-ALLDAYEVENT:FALSEX-MICROSOFT-CDO-IMPORTANCE:1X-MICROSOFT-CDO-INSTTYPE:0X-MICROSOFT-SKYPETEAMSMEETINGURL:https://teams.microsoft.com/l/meetup-join/ 19%3ameeting_YmM1MjRmMTktYjA2N<stripped>cd8%22%7dX-MICROSOFT-SCHEDULINGSERVICEUPDATEURL:https://api.scheduler.teams.microsof t.com/teams/dc<stripped>DAyMmZj@thread.v2/0X-MICROSOFT-SKYPETEAMSPROPERTIES:{"cid":"19:meeting_YmM1MjRmMTktYjA2Ny00YWQ 4LWI1NWEtZmE1NGVlMDAyMmZj@thread.v2"\,"private":true\,"type":0\,"mid":0\," rid":0\,"uid":null}X-MICROSOFT-ONLINEMEETINGCONFLINK:conf:sip:<redacted>\;gruu\;opaque= app:conf:focus:id:teams:2:0!19:meeting_YmM1MjRmMTktYjA2Ny00YWQ4LWI1NWEtZmE 1NGVlMDAyMmZj-thread.v2!56474ffc245241c5ab4081a127cc1cd8!dcf23acb18fc41d28 6acf752f1ca658dX-MICROSOFT-DONOTFORWARDMEETING:FALSEX-MICROSOFT-DISALLOW-COUNTER:FALSEX-MICROSOFT-LOCATIONS:[ { "DisplayName" : "Microsoft Teams Meeting"\, "Loca tionAnnotation" : ""\, "LocationSource" : 0\, "Unresolved" : false\, "Loca tionUri" : "" } ]BEGIN:VALARMDESCRIPTION:REMINDERTRIGGER;RELATED=START:-PT15MACTION:DISPLAYEND:VALARMEND:VEVENTEND:VCALENDAR

Здесь нужно понимать, что каждый объект iCalendar начинается сBEGIN: VCALENDARи заканчиваетсяEND: VCALENDAR.Часть встречи находится междуBEGIN: VEVENTиEND: VEVENT.Внутри вашего мероприятия вы указываете так называемые компоненты.Обычно требуются не все компоненты, и в моем POC вы можете найти урезанный файл *.ics с только необходимыми компонентами.Большинство из них самоочевидны, но я отмечу самые интересные из них.

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

ATTENDEE. Указывает участников встречи.Если вам нужно много участников, у вас будет несколько компонентов ATTENDEE.Имейте в виду, что участники не получат электронное письмо с приглашением на собрание, оно предназначено только для отображения.Вы можете легко имитировать присутствие 30 человек на собрании, если на самом деле отправляете электронное письмо одной жертве.

X-MICROSOFT-SKYPETEAMSMEETINGURL. Если вы укажете этот компонент, в напоминании о встрече будет отображаться кнопка Подключиться.К сожалению, при нажатии система попытается открыть указанный URL-адрес через приложение для рабочих столов, что приводит к ошибке.

DTSTART, DTSTAMP, DTEND. Указывают время встречи и её продолжительность.Я проделал хитрый трюк и установил время начала встречи на 5 минут раньше текущего времени, таким образом складывается ощущение, что вы опоздали на встречу на 5 минут.Когда жертва получает email, Outlook обрабатывает его как приглашение на встречу. Видит, что встреча началось 5 минут назад, и сразу же отображает напоминание на экране.Это помогает симулировать срочность.

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

В этой статье я показал, как Outlook обрабатывает приглашения на собрания.Это должно работать с любым провайдером/клиентом email-сообщений, который обрабатывает вложения *.ics. Вы можете проверить мой POC наgithubи отредактировать скрипт и шаблоны в соответствии со своими потребностями.


Что ещё интересного есть в блогеCloud4Y

Частые ошибки в настройках Nginx, из-за которых веб-сервер становится уязвимым

Пароль как крестраж: ещё один способ защитить свои учётные данные

Облачная кухня: готовим данные для мониторинга с помощью vCloud API и скороварки

Подготовка шаблона vApp тестовой среды VMware vCenter + ESXi

VMware предупредила о критических уязвимостях в удаленном исполнении кода в vCenter

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

Подробнее..

Интеграция SAML в Zimbra OSE

16.06.2021 14:10:53 | Автор: admin
Технология единого входа обладает массой преимуществ по сравнению с классическими методами аутентификации, главное из которых заключается в том, что именно SSO обеспечивает наилучший баланс между удобством пользователя и информационной безопасностью предприятия. Ранее мы уже рассказывали о том, как реализовать SSO в Zimbra OSE при использовании аутентификации в Active Directory с помощью Kerberos. На этот раз мы расскажем о том, как внедрить Zimbra OSE другую технологию единого входа SAML на примере провайдера Okta.

image

Единый вход с помощью SAML в Zimbra OSE доступен только для пользователей Zextras Suite Pro.

Подготовка к интеграции

В первую очередь для включения интеграции в SAML, необходимо пропатчить NGINX. Для этого в папке /opt/zimbra/conf/nginx/templates/ отредактируйте поочередно файлы:

  • nginx.conf.web.http.default.template
  • nginx.conf.web.http.template
  • nginx.conf.web.https.default.template
  • nginx.conf.web.https.template

Во всех файлах в разделе location ^~ /zx/ замените содержимое на

location ^~ /zx/

{

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header Host $http_host;

proxy_set_header X-Forwarded-Proto $scheme;

proxy_set_header X-Forwarded-Port $server_port;

proxy_pass ${web.upstream.zx};

}


Эти изменения нужны для того, чтобы составлять полноценные URL-запросы Protocol X и X-Port.

Также необходимо активировать движок аутентификации от Zextras на уровне домена. Сделать это может администратор сервера, введя в командной строке команду zmprov modifyDomain example.ru zimbraAuthMech custom:zx.

Создание приложения в Okta

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

1. Зарегистрируйтесь в качестве разработчика на сайте okta.com

2. В личном кабинете нажмите на кнопку Create App Integration



3. В открывшемся списке выберите SAML 2.0 и нажмите Next



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



5. В следующем окне:

  1. В качестве SSO URL укажите адрес вашего сервера с аппендиксом /zx/auth/saml
  2. В качестве Audiend URI укажите адрес вашего сервера с аппендиксом /zx/auth/samlMetadata
  3. В качестве Name ID Format укажите EmailAddress
  4. Нажмите кнопку Next



6. В мини-опросе выберите первый вариант ответа и нажмите кнопку Finish



7. Скачайте метаданные своего приложения SAML



Если у вас уже есть приложение в Okta, просто скачайте файл с метаданными своего приложения.

Экспорт учетных записей из домена Zimbra OSE

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

Для экспорта учетных записей перейдите в консоль администратора Zimbra, перейдите во вкладку Поиск и осуществите поиск по пользователям с названием домена в поисковом запросе. Результатом поиска будет полный список пользователей домена, который можно выгрузить в формате CSV, нажав на иконку Дополнительные настройки в правом верхнем углу и выбрав раздел Загрузить



Импортируйте полученный CSV в приложение SAML с помощью соответствующего инструмента в личном кабинете разработчика.

Интеграция приложения в Zimbra OSE

Чтобы интегрировать приложение SAML в Zimbra OSE, вам потребуются данные из скачанного ранее файла с метаданными приложения.

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

Для того, чтобы выполнить интеграцию в автоматическом режиме, введите команду zxsuite auth saml import example.ru url dev-3299935.okta.com/app/exkvjcggn7C7jrhc75d6/sso/saml/metadata. Если вы используете собственный сервер SAML с самоподписанными сертификатами, используйте параметр allow_insecure true для пропуска проверки подлинности SSL-сертификата.

Чтобы провести интеграцию в ручном режиме, экспортируйте настройки SAML по умолчанию при помощью команды zxsuite auth saml get example.ru export_to /tmp/saml.json. Откройте полученный файл /tmp/saml.json в любом редакторе и добавьте в него следующие данные, заменяя строки отмеченные знаками >> << данными из файла с метаданными. В нашем случае добавленные строки будут выглядеть следующим образом:

sp.nameidformat:urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress ,
sp.entityid: >>example.ru/zx/auth/samlMetadata?domain=example.ru<<,
sp.assertion_consumer_service.url: >>example.ru/zx/auth/saml<<,
idp.single_sign_on_service.url: >>dev-3299935.okta.com/app/dev-3299935_zextrassamlintegration_1/exkvjcggn7C7jrhc75d6/sso/saml<<,
idp.entityid: >>www.okta.com/exkvjcggn7C7jrhc75d6<<,
idp.x509cert: >>MIIDpjCCAo6gAwIBAgIGAXmC9e8bMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYDVQQGEwJVUzETMBEG A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU MBIGA1UECwwLU1NPUHJvdmlkZXIxFDASBgNVBAMMC2Rldi0zMjk5OTM1MRwwGgYJKoZIhvcNAQkB Fg1pbmZvQG9rdGEuY29tMB4XDTIxMDUxOTA0NDkyNloXDTMxMDUxOTA0NTAyNlowgZMxCzAJBgNV BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ0wCwYD VQQKDARPa3RhMRQwEgYDVQQLDAtTU09Qcm92aWRlcjEUMBIGA1UEAwwLZGV2LTMyOTk5MzUxHDAa BgkqhkiG9w0BCQEWDWluZm9Ab2t0YS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQCOJA7bhf/LO89VpuGTHur77RbwKlJg3Eni/P4JKowSVrQD6PghwprCdzThyTsKWcHwESZoYwEL WdrZ6CVzDZWAegWJnaJivfiFlFjsEZ15UHOGizMBM3VI0ePWjaWJ6O2DM9BID2mGULnXUDbQXbf6 rE1EHxzlxzCKIBWmT8ut/JsA/lmBm0YNi4BKfP06KXCLianxoH+fEETNd/NH2mXwgHdxMV1BS/mm TAHSJtkDfWxTM+dTGngrjMANKvmChGjSO1ZXFs/pm+vx0o6ffYcoeXnfgodBX3FZ7aTFBTk0s5Se Wms1utjfa8qhHbrolErqqIc1PPBngEFvzcLjFAfRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAByU jjdAc5tdH+QFAHS0CJNYa9VNaapxuEFrlR3ZdAztIaczKUqYfHqHdXuDHYCjdHXhLFHwntBsnphk M2sk8D2zG0wpoYsEA3IrvbXoTwwqDzACpLF37S7Pfn0RjE5IvvJ9WP4DoZa9ikM/p0N+H7fpqkU2 xavoiNGOMqot9xpWrytM0P+luXereriOOzVaBS1+DuhA4INhze5luyc52X18T4HrJ3iGivfXR2os L8/PI4gZwR956Ju8tDEcmFVCelLN4FlN3ITogPK+SyKHhlTBuSGHidrGKQJBRmkLhk6lhKWTHjWP mI88ECqrA63+QvxU4KRUl1zzRgKVwrgzos4=<<

Сохраните внесенные в файл изменения и импортируйте его в Zimbra OSE с помощью команды zxsuite auth saml import example.ru /tmp/saml.json



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

По всем вопросам, связанными c Zextras Suite Pro и Team Pro вы можете обратиться к Представителю компании Zextras Technology Екатерине Триандафилиди по электронной почте ekaterina.triandafilidi@zextras.com
Подробнее..

USB over IP удалённое администрирование

21.06.2021 16:11:25 | Автор: admin

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

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

Работа в тихом городке

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

Однако, в маленьком приморском городке работы для айтишника не было никакой, а ездить в областной центр мне совсем не хотелось. Так я стал ИП и занялся дистанционным обслуживанием компаний, которым было накладно содержать постоянного админа.

Буквально за пару недель я обзавёлся первыми клиентами небольшими компаниями-мелкооптовиками. В штате 10-50 работников, главбух на аутсорсе, сервер с 1С и одним общим для всех каталогом. Почту используют бесплатную, вопросами ИБ заморачиваются по минимуму. В-общем, достаточно типичный для нашей страны мелкий бизнес.

Иногда приходилось выезжать на место, но не часто. Большинство задач вполне решалось дистанционно либо через TeamViewer, либо по телефону. Меня это устраивало, клиентов тоже.

Токены головная боль

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

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

Всё действительно сложно

Сначала задача показалась мне простой. Технология USB over IP существует достаточно давно все токены подключены к одному устройству, а сотрудники работают с ними, как с локальными. Ничего не теряется, поскольку не покидает пределов офиса.

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

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

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

Поскольку айтишников на фултайме ни в одной конторе не было, самодельные и софтовые решения исключались. Делать, настраивать и чинить некому.

По масштабированию прекрасно подходят облака. Но цены у них откровенно кусаются. Например, сервис FlexiHub обойдётся заказчику более 10 тыс. рублей в месяц за 5 ключей, не считая стоимости хаба. И это без гарантий совместимости.

Но самое главное сервисы требуют регулярной своевременной оплаты. У небольшой компании с этим могут быть проблемы. У неё не всегда есть возможность даже зарплаты сотрудникам заплатить вовремя. Задержка в неделю-другую дело обыкновенное.

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

Если ориентироваться на мировые бренды, то надо брать Digi AnywhereUSB. За 2 USB-порта больше 20 тыс. рублей, за 14 портов в районе 150 тыс. рублей. Для небольших компаний это явно дорого.

Конечная остановка USB over IP концентратор

Перебирая варианты я пришёл к отечественному аппаратно-программному решению DistKontrolUSB. На нём и остановился. Причин этому несколько.

Прежде всего цена. За концентратор на 4 порта мой мелкий клиент заплатит 26 тыс. рублей с хвостиком, а более крупным придётся выложить около 69 тыс. рублей, но за 16 портов. Дешевле западного аналога в два раза.

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

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

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

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

Третье достоинство удобное удалённое управление концентратором через веб-интерфейс. Это особенно важно для более крупных организаций, которым подойдёт концентратор на 16 портов. Сотрудников там больше и без каких-то элементов ИБ не обойтись.

Допустим, по соображением безопасности требуется ограничить доступ к порту по IP-адресу, а к ключу по логину и паролю. Через панель управления это делается мгновенно, причём в одном модуле. Надо всего два раза сдвинуть соответствующие ползунки и нажать на кнопу Сохранить. Изменения сразу вступят в силу.

Проблема нахождения концов актуальна не только для очень крупных организаций, но и для моих клиентов. При помощи системного журнала в WEB-интерфейсе Управляемого USB over IP концентратора решение этой задачи облегчается. В журнале хранится вся информация о подключениях и отключениях, включая логин пользователя и IP-адрес, с которого было осуществлено подключение. Кстати, пару раз пригодилось.

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

В настройках USB over IP концентратора было сформировано автоматическое задание, по которому устройство отключается в заданное время. А чтобы директор не волновался и спал спокойно он получает уведомление о выполнении на электронную почту.

Итоги

Проект по оптимизации работы с токенами я начал в январе этого года. Из семи предприятий, с которыми я работаю, три уже приобрели и успешно используют USB over IP концентраторы. В одной организации это запланировано на лето. Думаю, что и оставшиеся три до конца года примут положительное решение.

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

Например, дневная задержка в оплате счёта на один миллион стоит от 100 до 1000 рублей в зависимости от договора. С отчётностью ещё хуже 5% от суммы налога. А это уже несколько тысяч даже для небольшой фирмочки. Причём, только прямого ущерба о каких-то сорвавшихся сделках я даже не говорю.

Сумму убытков из-за подобных задержек владелец компании знает. Стоимость USB over IP концентратора тоже. Срок окупаемости вычисляется без всякой высшей математики.

Насколько я могу судить, первопроходцы уже ушли в плюс. Даже те, кто приобрёл устройство на 16 портов.

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

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

Подробнее..

Мониторим парк ИБП. Ч.3, заключительная

16.06.2021 12:16:05 | Автор: admin

Или что пригодится знать и уметь, если замена ИБП после поломки урон профессиональной гордости.

Часть 1
Часть 2
TL;DR

И вновь приветствую, уважаемые коллеги и читатели. За пару лет достаточно плотной работы с бесперебойниками я совершил для себя много "открытий чудных". Спешу поделиться с вами.

Disclaimer
  1. Речь идёт в основном о ИБП мощностью 400-800VA, "линейно-интерактивных", со свинцовыми батареями 12В;

  2. Бесперебойное обеспечение в основном офисных "печатных машинок": ЦП мощностью до 100 Вт и SSD в качестве системных дисков, без дискретных видеокарт;

  3. Централизованный ИБП отсутствует.

Решаемые задачи:

  1. Минимум: иметь хотя бы общее представление о состоянии парка устройств;

  2. Хорошо: менять устройства ДО возникновения сбоя, обеспечивая тем самых их фактический и экономический смысл. Да-да, просто поставить ИБП совершенно недостаточно;

  3. Отлично: иметь наглядные данные что было сделано IT-службой и почему это было необходимо сделать (потратив на это деньги и человекочасы).

Об офисных UPS

В очередной раз повторюсь: поставить и забыть не прокатывает.
ИБП без функции передачи данных бесполезны практически полностью, так как не решают одну из важнейших проблем безопасное выключение с сохранением данных. К сожалению, ИБП с передачей данных тоже далеко не панацея. Тому есть несколько причин:

1. Качество соединения
На основании двухлетнего наблюдения могу с уверенностью сказать, что это беда.
Если не следить за подключениями достаточно внимательно, большинство из бесперебойников поотваливаются в течение полугода. Такое поведение сильно зависит от конкретных условий и меняется от машины к машине. Основные причины потери соединения (насколько мне удалось разобраться):
а) чисто физические. Сюда входят ненадёжные разъёмы (и они случаются чаще, чем хотелось бы), случайные нарушения соединений (уборщица слишком ретива, пользователь дёргает ногами или двигает системник) и, внезапно, качество соединительного кабеля похоже, что ИБП довольно чувствительны к этому параметру, особенно при активном опросе;
б) на втором месте не "глючные драйверы", что удивительно, а электроника самих ИБП. Похоже, бесперебойникам из нижнего ценового сегмента не очень нравится, когда их часто "дёргают".

чуть подробнее

вообще, обмен данным с ИБП идёт постоянно, но всё же не раз в миллисекунду. Драйвер usbhid-ups получает данные раз в 2 секунды (видно в дебаг-режиме, если запускать руками с параметром -D+), что-то похожее, наверняка, и в стандартном драйвере Windows и WMI. Но это только "частичное" обновление, "полное" обновление происходит раз в 30 секунд

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

2. Работа внутренних систем, сенсоров и логики UPS
Во-первых, ИБП от разных производителей обращаются с батареей по-разному. В моей практике хуже всех обращаются с батареями ИБП Powercom, лучше всех IPPON (далее по батарее см. п.3). Отличие не принципиальное, Powercom тоже через пол-года не дохнут, но оно есть и весьма заметно, если анализировать накопленные данные за достаточно длительный период. Здесь переходим к во-вторых: наиболее интересные параметры, которые ИБП сам считает и выдаёт:
а) нагрузка (load)
б) предсказание времени работы от батареи (runtime), вычисляемое на основе нагрузки
в) текущий заряд батареи (charge)

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

К сожалению, есть куда больше параметров, которые анализировать, считать и даже просто получать стоило бы, но это не реализовано.
Простейший пример: просадка напряжения на батарее, когда пропадает питание. Это показательнейший параметр, на основании которого можно куда точнее сделать вывод об убитой батарее. Постоянная память EEPROM есть сейчас где угодно, и ИБП запросто может записывать такие данные самостоятельно. Но ни одного ИБП с таким функционалом мне не попалось.
Другой пример: Powercom'ы после потери питания и разряда батареи до 30 процентов могут "зарядить" 12-вольтовую батарею за 10 минут и утверждать, что всё прекрасно, а Self-test passed.

если вас ничего не смущает

время полного заряда 12 В свинцовой батареи даже в "агрессивном" режиме составит не меньше часа, и батарея после такого долго не живёт

Это прямо натуральный epic fail.
Те же Powercom не умеют в вольтаж батареи вообще, только в проценты. На основании чего там эти проценты внутри считаются покрыто китайской мракой.

Очень важного параметра "температура" (батареи, внутри корпуса, да хоть чего-нибудь) не найти днём с огнём в офисных ИБП, хотя датчик копеечный и вообще встроен в почти все микроконтроллеры. Тут переходим к третьему пункту раздела.

3. Батарея и её состояние
Из того зоопарка, с которым я имел дело, "посредственно" справляется с задачей анализа состояния батареи серверный ИБП IPPON. Потуги остальных иначе как "бессмысленно" назвать не могу. Очень важный параметр батареи кривая разряда просто игнорируется.

немного о кривой разряда

Свинцовые батареи ИБП разряжаются нелинейно. Проще говоря, чем меньше заряда осталось в батарее, тем быстрее она разряжается. Ещё проще: время разряда со 100% до 90% будет в разы больше, чем с 20% до 0%. Но и это ещё не всё. Кривая разряда становится круче в более старой батарее и/или в зависимости от внешних условий (та же температура). В итоге это выглядит так:

Чувствуете подвох? Угадайте, проводит ли ИБП запись скорости последнего разряда, анализ, учитывает ли дату установки батареи?

спойлер

ИБП ваще пофигу, не анализирует, не учитывает. Лучшее, что я видел через три года начинает орать "чота батарея старая".

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

Запись и расчёт параметров реализован в очередном обновлении сервера мониторинга. В частности, теперь видно:

  • просадку заряда батареи непосредственно после потери питания. Если этот показатель низкий, сервер выдаст предупреждение;

  • скорость разряда батареи. Этот параметр требует для расчёта не менее 2 мин наблюдаемого разряда ИБП.

Для корректного учёта этих параметров требуется довольно частый опрос ИБП. Соответствующие изменения внесены в код сервера (см. раздел "NUT и сервер мониторинга"). К сожалению, здесь мы упираемся в ранее озвученный п. "б" ч. 1 текущего раздела при частых обращениях за данными возможны глюки. Более того, в первые секунды после потери питания ИБП данные не отдаёт вообще, а вместо этого передаёт "WAIT". По-хорошему, после потери питания ИБП для целей мониторинга нужно бы опрашивать как можно чаще. На данный момент частота опроса от 10 до 30 секунд, в целом для более-менее приличного анализа этого хватает. Более интенсивные опросы не тестировались достаточно долго, чтобы делать какие-то однозначные выводы.

Краткие итоги раздела:

  • обязательно нужен мониторинг самого факта подключения ИБП к машине;

  • нужно собирать и хранить данные о датах установки батарей;

  • в идеале нужно очень детально мониторить процесс разряда и заряда батарей.

NUT и сервер мониторинга

Изначально NUT был выбран как кроссплатформенное универсальное решение. В целом функции свои выполняет. Без нюансов, впрочем, не обошлось:
а) Не слишком дружелюбная и неочевидная установка на клиентских машинах, под Windows особенно. В частности:

  • иногда отказывается видеть библиотеки;

  • встроенный драйвер не обновлялся давно и половину ИБП не знает. Драйвер надо ставить вручную, и это отдельная песня;

  • на клиентах под Windows служба стартует "невовремя", раньше, чем фактически нужно (похожая история есть при поиске домена на Windows с некоторыми сетевыми адаптерами). Из-за этого приходится городить костыли.

б) Заявлено, что клиент NUT может оповещать сервер о пропадании и восстановлении питания, и даже выполнять скрипты по этим событиям. Это убрало бы и необходимость частого опроса ИБП, и позволило бы вести более точечный мониторинг важных состояний (см. предыдущий раздел). Однако заставить стабильно работать этот функционал мне не удалось. Некоторые машины не триггерят сервер вообще, либо делают это один раз из десяти. При этом есть машины, с которых это работает стабильно.

В качестве альтернативы я попробовал (и даже написал "адаптер") получать данные из WMI по предложению @firedragon. Суть, в общем, та же. Плюсы: не нужно альтернативных дайверов и библиотек, не нужно костылить некоторые вещи. Минусы: информации сильно меньше, а по сравнению с настроенным клиентом NUT стабильность ровно та же, при этом отсутствует, хотя бы потенциальная, возможность "триггера".

По результатам изысканий решено было оставить NUT в качестве основного решения для сервера. При этом "сильно больше данных" в какой-то момент обернулось базами, раздутыми по 100 Мб на бесперебойник, что повлияло на производительность. В итоге, сервер был перенесён из среды Windows в Linux, и:

  • написан соответствующий скрипт-демон на bash для непрерывного опроса;

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

В саму веб-морду сервера, как уже говорилось, добавлено:

  • отображение заряда батареи сразу после последней потери питания и соответствующий алерт;

  • расчёт времени работы от батареи на основе реальных данных. Некоторым образом это тоже синтетика, т.к. реальная кривая разряда не строится. Однако, отлично себя показала следующая формула: рассчитанное на основе последних реальных данных время / 1+ лет с десятыми.

Итоги, советы, планы

Для тех, кто хочет "сделать всё правильно", исходя из полученного опыта, дам следующие советы:

  1. Тщательно выберите марку и модель ИБП и по возможности используйте только выбранный ИБП во всем офисе;

  2. Запишите серийные номера и/или присвойте каждому ИБП уникальный номер. Запишите дату установки батареи в каждый ИБП. Меняйте батареи раз в два года, и сразу, заранее, закладывайте эти расходы в бюджеты для бизнеса запланированные расходы гораздо удобнее внезапных;

  3. Любым способом следите за тем, чтобы машины, обеспеченные ИБП, имели с ним постоянную связь;

  4. Раз в пол-года обновляйте параметры battery low и battery warning в используемом вами драйвере/решении, прибавляя к ним от 5% до 20% в зависимости от опыта использования вашей модели ИБП, вручную или скриптами;

  5. По возможности проводите ручное тестирование ИБП (отключить от розетки и подождать) раз в квартал-полгода.

Это то, что нужно делать обязательно.

Использование постоянного и подробного мониторинга, в целом, скорее чрезмерно, хотя и может оказаться полезным и наглядным. Заводить для этого отдельный сервер или нет, решать вам. Некоторые параметры можно мониторить в том же Zabbix (и даже посредством WMI), однако лично у меня в целом не очень удачный опыт с Zabbix active parameters; к тому же, сложность реализации некоторых описанных решений внутри Zabbix по сложности приближается, на мой вкус, к сложности реализации представленного сервера мониторинга.

Я удивлён и рад, что довольно много читателей задумалось о мониторинге ИБП после первой статьи, и многие посоветовали довести решение "до энтерпрайза" после второй статьи. Благодарю за отклики и ответы!

Учитывая накопленный опыт, реализация "до энтерпрайза" может быть довольно длительной. Есть проблемы и на клиентской стороне, и в самом NUT; в веб-интерфейсе многое надо выносить в бэкэнд, нет даже банальной авторизации. Можно было бы даже в таком виде запихнуть всё это в контейнер Docker в качестве версии 0.1 alpha, но мой энтузиазм к теме несколько поугас. Если у кого-то энтузиазм найдётся пишите, буду рад поработать вместе!

Рад, если мой опыт вам пригодится. Спасибо всем, кто прочитал!

Подробнее..

Как мы собираем общие сведения о парке из Kubernetes-кластеров

16.06.2021 10:13:29 | Автор: admin

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

  • версия Kubernetes чтобы все кластеры были on the edge;

  • версия Deckhouse (наша Kubernetes-платформа) для лучшего планирования релизных циклов;

  • количество узлов с разбивкой по типам (управляющие, виртуальные и статические) для отдела продаж;

  • количество ресурсов (CPU, memory) на управляющих узлах;

  • на какой инфраструктуре запущен кластер (виртуальные облачные ресурсы, bare metal или гибридная конфигурация);

  • какой облачный провайдер используется.

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

Истоки и проверка концепции

В какой-то момент времени мы стали использовать Terraform для раскатки инфраструктуры в облака и вопрос отслеживания соответствия желаемых конфигураций реальности встал еще острее. Мы храним Terraform state в самих кластерах и проверку соответствия их с реальностью проверяет отдельно написанный Prometheus exporter. Хотя ранее у нас уже была информация для реагирования на изменения (через соответствующие алерты в системе управления инцидентами), хотелось ещё иметь полное представление о ситуации в отдельной аналитической системе.

Итак, изначально в качестве PoC был несложный Bash-скрипт, которым мы вручную время от времени собирали интересующие данные с K8s-кластеров по SSH. Он выглядел примерно так:

((kubectl -n d8-system get deploy/deckhouse -o json | jq .spec.template.spec.containers[0].image -r | cut -d: -f2 | tr "\n" ";") &&(kubectl get nodes -l node-role.kubernetes.io/master="" -o name | wc -l | tr "\n" ";") &&(kubectl get nodes -l node-role.kubernetes.io/master="" -o json | jq "if .items | length > 0 then .items[].status.capacity.cpu else 0 end" -r | sort -n | head -n 1 | tr "\n" ";") &&(kubectl get nodes -l node-role.kubernetes.io/master="" -o json | jq "if .items | length > 0 then .items[].status.capacity.memory else \"0Ki\" end | rtrimstr(\"Ki\") | tonumber/1000000 | floor" | sort -n | head -n 1 | tr "\n" ";") &&(kubectl version -o json | jq .serverVersion.gitVersion -r | tr "\n" ";") &&(kubectl get nodes -o wide | grep -v VERSION | awk "{print \$5}" | sort -n | head -n 1 | tr "\n" ";") &&echo "") | tee res.csvsed -i '1ideckhouse_version;mastersCount;masterMinCPU;masterMinRAM;controlPlaneVersion;minimalKubeletVersion' res.csv

(Здесь приведен лишь фрагмент для демонстрации общей идеи.)

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

Так начался наш путь разработки волшебного агента для кластеров, который бы:

  • собирал желаемую информацию,

  • агрегировал ее,

  • отправлял в какое-то централизованное хранилище.

а заодно соответствовал каноном высокой доступности и cloud native.

Этот путь дал начало истории модуля в Kubernetes-платформе Deckhouse, развёрнутой на всех наших кластерах, и сопутствующего ему хранилища.

Реализация

Хуки на shell-operator

В первой итерации источником данных в клиентских кластерах служили Kubernetes-ресурсы, параметры из ConfigMap/Deckhouse, версия образа Deckhouse и версия control-plane из вывода kubectl version. Для соответствующей реализации лучше всего подходил shell-operator.

Были написаны хуки (да, снова на Bash) с подписками на ресурсы и организована передача внутренних values. По результатам работы этих хуков мы получали список желаемых Prometheus-метрик (их экспорт поддерживается в shell-operator из коробки).

Вот пример хука, генерирующего метрики из переменных окружения, он прост и понятен:

#!/bin/bash -efor f in $(find /frameworks/shell/ -type f -iname "*.sh"); do  source $fdonefunction __config__() {  cat << EOF    configVersion: v1    onStartup: 20EOF}function __main__() {  echo '  {    "name": "metrics_prefix_cluster_info",    "set": '$(date +%s)',    "labels": {      "project": "'$PROJECT'",      "cluster": "'$CLUSTER'",      "release_channel": "'$RELEASE_CHANNEL'",      "cloud_provider": "'$CLOUD_PROVIDER'",      "control_plane_version": "'$CONTROL_PLANE_VERSION'",      "deckhouse_version": "'$DECKHOUSE_VERSION'"    }  }' | jq -rc >> $METRICS_PATH}hook::run "$@"

Отдельно хочу обратить ваше внимание на значение метрики (параметр set). Изначально мы писали туда просто 1, но возник резонный вопрос: Как потом получить через PromQL именно последние, свежие labels, включая те series, которые уже две недели не отправлялась? Например, в том же MetricsQL от VictoriaMetrics для этого есть специальная функция last_over_time. Оказалось, достаточно в значение метрики отправлять текущий timestamp число, которое постоянно инкрементируется во времени. Вуаля! Теперь стандартная функция агрегации max_over_time из Prometheus выдаст нам самые последние значения labels по всем series, которые приходили хоть раз в запрошенном периоде.

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

Чтобы вписаться в парадигму cloud-native и обеспечить HA агента, мы запустили его в несколько реплик на управляющих узлах кластера.

Grafana Agent

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

Выбор пал на разработку Grafana Labs, а именно Grafana Agent. Он умеет делать scrape метрик с endpointов, отправлять их по протоколу Prometheus remote write, а также (что немаловажно!) ведет свой WAL на случай недоступности принимающей стороны.

Задумано сделано: и вот приложение из shell-operator и sidecarом с grafana-agent уже способно собирать необходимые данные и гарантировать их поступление в центральное хранилище.

Конфигурация агента делается довольно просто благо, все параметры подробно описаны в документации. Вот пример нашего итогового конфига:

server:  log_level: info  http_listen_port: 8080prometheus:  wal_directory: /data/agent/wal  global:    scrape_interval: 5m  configs:  - name: agent    host_filter: false    max_wal_time: 360h    scrape_configs:    - job_name: 'agent'      params:        module: [http_2xx]      static_configs:      - targets:        - 127.0.0.1:9115      metric_relabel_configs:      - source_labels: [__name__]        regex: 'metrics_prefix_.+'      - source_labels: [job]        action: keep        target_label: cluster_uuid        replacement: {{ .Values.clusterUUID }}      - regex: hook|instance        action: labeldrop    remote_write:    - url: {{ .Values.promscale.url }}      basic_auth:        username: {{ .Values.promscale.basic_auth.username }}        password: {{ .Values.promscale.basic_auth.password }}

Пояснения:

  • Директория /data это volumeMount для хранения WAL-файлов;

  • Values.clusterUUID уникальный идентификатор кластера, по которому мы его идентифицируем при формировании отчетов;

  • Values.promscale содержит информацию об endpoint и параметрах авторизации для remote_write.

Хранилище

Разобравшись с отправкой метрик, необходимо было решить что-то с централизованным хранилищем.

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

NB. Справедливости ради, хочется отметить, что на данный момент Cortex выглядит уже вполне жизнеспособным, оформленным как конечный продукт. Очень вероятно, что через какое-то время вернемся к нему и будем использовать. Уж очень сладко при мысли о generic S3 как хранилище для БД: никаких плясок с репликами, бэкапами и растущим количеством данных

К тому времени у нас была достаточная экспертиза по PostgreSQL и мы выбрали Promscale как бэкенд. Он поддерживает получение данных по протоколу remote-write, а нам казалось, что получать данные используя pure SQL это просто, быстро и незатратно: сделал VIEWхи и обновляй их, да выгружай в CSV.

Разработчики Promscale предоставляют готовый Docker-образ, включающий в себя PostgreSQL со всеми необходимыми extensions. Promscale использует расширение TimescaleDB, которое, судя по отзывам, хорошо справляется как с большим количеством данных, так и позволяет скейлиться горизонтально. Воспользовались этим образом, задеплоили connector данные полетели!

Далее был написан скрипт, создающий необходимые views, обновляющий их время от времени и выдающий на выход желаемый CSV-файл. На тестовом парке dev-кластеров всё работало отлично: мы обрадовались и выкатили отправку данных со всех кластеров.

Но с хранилищем всё не так просто

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

Как оказалось, ходить в таблицы базы данных мимо магических оберток, предоставляемых Promscale (в виде своих функций и views, опирающихся в свою очередь на функции TimescaleDB), невероятно неэффективно.

Было решено перестать ковыряться в потрохах данных и положиться на мощь и наработки разработчиков Promscale. Ведь их connector может не только складывать данные в базу через remote-write, но и позволяет получать их привычным для Prometheus способом через PromQL.

Одним Bashем уже было не обойтись мы окунулись в мир аналитики данных с Python. К нашему счастью, в сообществе уже были готовы необходимые инструменты и для походов с PromQL! Речь про замечательный модуль prometheus-api-client, который поддерживает представление полученных данных в формате Pandas DataFrame.

В этот момент еще сильнее повеяло взрослыми инструментами из мира аналитики данных Мотивированные на пощупать интересное и доселе неизведанное, мы двинулись в этом направлении и не прогадали. Лаконичность и простота верчения этой кучей данных через Pandas DataFrame доставила массу позитивных эмоций. И по сей день поддержка полученной кодовой базы, добавление новых параметров и всевозможные правки отображения финальных данных воспринимаются как праздник программиста и не требуют большого количества времени.

Изначально мы выбрали период скрейпинга данных grafana-agentом равным одной минуте, что отразилось на огромных аппетитах конечной БД в диске: ~800 мегабайт данных в день. Это, конечно, не так много в масштабах одного кластера (~5 мегабайт), но когда кластеров много суммарный объём начинает пугать. Решение оказалось простым: увеличили период scrapeа в конфигах grafana-agentов до одного раза в 5 минут. Прогнозируемый суммарный объем хранимых данных с retentionом в 5 лет уменьшился с 1,5 Тб до 300 Гб, что, согласитесь, уже выглядит не так ужасающе.

Некоторый профит от выбора PostgreSQL как конечного хранилища мы уже получили: для успешного переезда хранилища в финальный production-кластер достаточно было отреплицировать базу. Единственное текущий недостаток пока не получилось самостоятельно собрать свой кастомный PostgreSQL с необходимыми расширениями. После пары неудачных попыток мы остались на готовом образе от разработчиков Promscale.

Получившаяся архитектура выглядит так:

Итоги и перспективы

Мы смотрим в будущее и планируем отказаться от отчётов в формате CSV в пользу красивого интерфейса собственной разработки. А по мере разработки собственной биллинговой системы начнём отгружать данные и туда для нужд отдела продаж и развития бизнеса. Но даже те CSV, что мы получили сейчас, уже сильно упрощают рабочие процессы всего Фланта.

А пока не дошли руки до фронтенда, мы сделали dashboard для Grafana (почему бы и нет, раз всё в стандартах Prometheus?..). Вот как это выглядит:

Общая сводная таблица по кластерам с Terraform-состояниямиОбщая сводная таблица по кластерам с Terraform-состояниямиРаспределение кластеров по облачным провайдерамРаспределение кластеров по облачным провайдерамРазбивка по используемым Inlet в Nginx Ingress-контроллерахРазбивка по используемым Inlet в Nginx Ingress-контроллерахКоличество podов Nginx Ingress-контроллеров с разбивкой по версиямКоличество podов Nginx Ingress-контроллеров с разбивкой по версиям

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

P.S.

Читайте также в нашем блоге:

Подробнее..

Перевод Как работает single sign-on (технология единого входа)?

17.06.2021 16:13:58 | Автор: admin

Что такое single sign-on?


Технология единого входа (Single sign-on SSO) метод аутентификации, который позволяет пользователям безопасно аутентифицироваться сразу в нескольких приложениях и сайтах, используя один набор учетных данных.


Как работает SSO?


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


Порядок авторизации обычно выглядит следующим образом:


  1. Пользователь заходит в приложение или на сайт, доступ к которому он хочет получить, то есть к провайдеру услуг.
  2. Провайдер услуг отправляет токен, содержащий информацию о пользователе (такую как email адрес) системе SSO (так же известной, как система управления доступами), как часть запроса на аутентификацию пользователя.
  3. В первую очередь система управления доступами проверяет был ли пользователь аутентифицирован до этого момента. Если да, она предоставляет пользователю доступ к приложению провайдера услуг, сразу приступая к шагу 5.
  4. Если пользователь не авторизовался, ему будет необходимо это сделать, предоставив идентификационные данные, требуемые системой управления доступами. Это может быть просто логин и пароль или же другие виды аутентификации, например одноразовый пароль (OTP One-Time Password).
  5. Как только система управления доступами одобрит идентификационные данные, она вернет токен провайдеру услуг, подтверждая успешную аутентификацию.
  6. Этот токен проходит сквозь браузер пользователя провайдеру услуг.
  7. Токен, полученный провайдером услуг, подтверждается согласно доверительным отношениям, установленным между провайдером услуг и системой управления доступами во время первоначальной настройки.
  8. Пользователю предоставляется доступ к провайдеру услуг.

image

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


Что такое токен в контексте SSO?


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


Является ли технология SSO безопасной?


Ответом на этот вопрос будет "в зависимости от ситуации".


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


SSO также сокращает количество времени, потраченного на восстановление пароля с помощью службы поддержки. Администраторы могут централизованно контролировать такие факторы, как сложность пароля и многофакторную аутентификацию (MFA). Администраторы также могут быстрее отозвать привилегии на вход в систему, если пользователь покинул организацию.


Однако, у SSO есть некоторые недостатки. Например, вероятно, вам захочется, чтобы определенные приложения оставались заблокированы/менее открыты к доступу. По этой причине важно выбрать то решение SSO, которое, к примеру, даст вам возможность запросить дополнительный фактор проверки аутентификации прежде, чем пользователь авторизуется или оградит пользователей от доступа к определенным приложениям пока не обеспечено безопасное соединение.


Как внедрить SSO?


Особенности внедрения SSO могут отличаться с учетом того, с каким именно решением SSO вы работаете. Но вне зависимости от способа, вам нужно точно знать какие цели вы преследуете. Убедитесь, что вы ответили на следующие вопросы:


  • С какими типами пользователей вы работаете и какие у них требования?
  • Вы ищете локальное или облачное решение?
  • Возможен ли дальнейший рост выбранной программной платформы вместе с вашей компанией и ее запросами?
  • Какие функции вам необходимы, чтобы убедиться в том, что процесс авторизации проходят только проверенные пользователи? MFA, Adaptive Authentication, Device Trust, IP Address Whitelisting, и т.д?
  • С какими системами вам необходимо интегрироваться?
  • Нужен ли вам доступ к программному интерфейсу приложения (API)?

Что отличает настоящую SSO от хранилища или менеджера паролей?


Важно понимать разницу между SSO (Технологией единого входа) и хранилищем или менеджерами паролей, которые периодически путают с SSO, но в контексте Same Sign-On что означает такой же/одинаковый вход, а не единый вход (Single Sign-On). Говоря о хранилище паролей, у вас может быть один логин и пароль, но их нужно будет вводить каждый раз при переходе в новое приложение или на новый сайт. Такая система попросту хранит ваши идентификационные данные для других приложений и вводит их когда это необходимо. В данном случае между приложением и хранилищем паролей не установлены доверительные отношения.


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


В чем разница между программным обеспечением единого входа и решением SSO?


Изучая доступные варианты единого входа, вы можете увидеть, что их иногда называют программным обеспечением единого входа, а не решением единого входа или провайдером единого входа. Часто разница состоит лишь в том, как позиционируют себя компании. Фрагмент программного обеспечения предполагает локальную установку. Обычно это то, что разработано для определенного набора задач и ничего более. Программный продукт предполагает, что есть возможность расширяться и кастомизировать потенциальные возможности исходного варианта. Провайдер будет отличным вариантом, чтобы обратиться к компании, которая производит или пользуется программным продуктом. Например, OneLogin в качестве провайдера SSO.


Бывают ли разные типы SSO?


Когда мы говорим о едином входе (SSO), используется множество терминов:


  • Federated Identity Management (FIM)
  • OAuth (OAuth 2.0 в настоящее время)
  • OpenID Connect (OIDC)
  • Security Access Markup Language (SAML)
  • Same Sign On (SSO)

На самом деле, SSO это часть более крупной концепции под названием Federated Identity Management, поэтому иногда SSO обозначается, как федеративная SSO. FIM просто относится к доверительным отношениям, созданным между двумя или более доменами или системами управления идентификацией. Система единого входа (SSO) это характеристика/фича, доступная внутри архитектуры FIM.


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


OpenID Connect (OIDC) это уровень аутентификации, наложенный на базу OAuth 2.0, чтобы обеспечить фунциональность SSO.


Security Access Markup Language (SAML) это открытый стандарт, который также разработан для обеспечения функциональности SSO.


image

Система Same Sign On, которую часто обозначают, как SSO, на самом деле, не похожа Single Sign-on, т.к не предполагает наличие доверительных отношений между сторонами, которые проходят аутентификацию. Она более привязана к идентификационным данным, которые дублируются и передаются в другие системы когда это необходимо. Это не так безопасно, как любое из решений единого входа.


Также существуют несколько конкретных систем, которые стоит упомянуть, говоря о платформе SSO: Active Directory, Active Directory Federation Services (ADFS) и Lightweight Directory Access Protocol (LDAP).


Active Directory, который в настоящее время именуется, как Active Directory Directory Services (ADDS) это централизованная служба каталогов Microsoft. Пользователи и ресурсы добавляются в службу каталогов для централизованного управления, а ADDS работает с такими аутентификационными протоколами, как NTLM и Kerberos. Таким образом, пользователи, относящиеся к ADDS могут аутентифицироваться с их устройств и получить доступ к другим системам, интегрированным с ADDS. Это и есть форма SSO.


Active Directory Federation Services (ADFS) это тип управления федеративной идентификацией (Federated Identity Management system), которая также предполагает возможность Single Sign-on. Он также поддерживает SAML и OIDC. ADFS преимущественно используется для установления доверительных отношений между ADDS и другими системами, такими как Azure AD или других служб ADDS.


Протокол LDAP (Lightweight Directory Service Protocol) это стандарт, определяющий способ запроса и организации информационной базы. LDAP позволяет вам централизованно управлять такими ресурсами, как пользователи и системы. LDAP, однако, не определяет порядок авторизации, это означает, что он не устанавливает непосредственный протокол, используемый для аутентификации. Но он часто применяется как часть процесса аутентификации и контроля доступа. Например, прежде, чем пользователь получит доступ к определенному ресурсу, LDAP сможет запросить информацию о пользователе и группах, в которых он состоит, чтобы удостовериться, что у пользователя есть доступ к данному ресурсу. LDAP платформа на подобие OpenLDAP обеспечивает аутентификацию с помощью аутентификационных протоколов (например, Simple Authentication и Security Layer SASL).


Как работает система единого входа как услуга?


SSO функционирует также, как и многие другие приложения, работающие через интернет. Подобные OneLogin платформы, функционирующие через облако, можно отнести к категории решений единого входа Software as a Service (SaaS).


Что такое App-to-App (приложение-приложение) SSO?


В заключение, возможно вы слышали о App-to-App SSO. Пока еще такой подход не является стандартным. Такое понятие больше используется SAPCloud для обозначения процесса передачи идентификационных данных пользователя из одного приложения в любое из других, состоящих в их экосистеме. В какой-то степени такой метод присущ OAuth 2.0, но хочется снова подчеркнуть, что это не стандартный протокол или метод. В настоящее время он является характерным только для SAPCloud.

Подробнее..

Перевод Как объяснить детям, что такое Apache Kafka за 15 минут с картинками и выдрами

19.06.2021 04:20:24 | Автор: admin


Я учусь иллюстрировать сложные процессы с помощью комиксов. Нашла себе в копилку крутой кейс: как с помощью комиксов про милых выдр можно ребенку объяснить такую сложную штуку как Apache Kafka, и сделать мир немного добрее.

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

Под катом 25 слайдов, объясняющие основы Kafka для детей и гуманитариев. И много милых выдр.



Легко по течению



image

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

image

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

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

image

Со временем, все больше и больше выдр переселялось в лес.

И точно так же росло количество происходящих в лесу событий.

image

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

image

Это не только занимало много времени, но было чревато ошибками.

Что если какая-то выдрячья семья была на пикнике, и не могла получить уведомление о предстоящем событии?

image

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

image

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

Быть тесно связанными супер мило, но это делает коммуникацию с другими сложнее. Это называется Проблема Масштабирования.

image
Именно тогда у одной маленькой выдры по имени Никси, появилась идея, которая навсегда изменила лес.

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

Вы можете установить Kafka в своем лесу:

# clone the repositorygit clone \https://github.com/round-robin-books/gently-kafka.git# start kafkadocker-compose up


image

Она даже сочинила песню, чтобы объяснить, как это работает:

События свои
В реку ты опусти,
Река их отнести
Сможет выдрам другим.

Что о событиях,
Плывущих в потоке,
Этот путь удивителен,
Мы все тут в шоке.

image

Не отстанешь ли ты? вмешался дельфин
Нельзя оставлять все на милость глубин!

Не будет в доставке такого.
Мы командой реку разделим,
На множество мелких потоков
И вместе достигнем цели.

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



image

Во первых, выдра наблюдает Событие, что-то, что произошло в определенный момент времени.

К примеру, Сегодня вернулись пчелы это событие.

image

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

image

Тогда выдры смогут решать в какую часть реки направить это сообщение.

Река делится на потоки, которые называют Топики, которые делают организацию сообщений проще.

image

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

По началу они использовали стеклянные бутылки, но бутылки просто уплывали.

image

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

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

2 типа выдр



image

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

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

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

image

Выдры, которые читают события в потоке называются Консьюмеры.

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

Например, выдры Первой помощи следят за топиком с лесными алертами, так что они могут реагировать в чрезвычайных ситуациях (как в ситуации с пчелами).

image

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

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

image

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

Это подразумевает, что каждая выдра ответственна только за ту часть потока, которую она мониторит.

image

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

image

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

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

И поскольку они могли справляться с Незапланированными Ситуациями, они были Отказоустойчивыми.

image

Еще существовала магическая часть леса, Земля Потоковой Обработки, где выдры могли делать реально классные вещи с событиями в реке.

image

Целая книга написана об этом магическом месте: Mastering Kafka Streams and ksqlDB

image

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

image

Кафка продолжала помогать многим другим во всем мире. И возвращалась обратно в лес.

Жизнь шла своим чередом многие годы, а выдры жили долго и счастливо.



Я не удержалась, вот вам несколько фактов про выдр:



Выдрята, или щенки выдр, спят у мам-выдр на груди.



Взрослые выдры держат друг друга за лапки во сне, чтобы их не разделило течение.



А одинокие выдры, чтобы не дрейфовать, заворачиваются в водоросли.

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

И если эти слайды вы действительно использовали этот материал на детях в образовательных целях, то завершить можно речевым упражнением:

В недрах тундры выдры в гетрах тырят в ведра ядра кедров. Выдрав с выдры в тундре гетры, вытру выдрой ядра кедра, вытру гетрой выдре морду ядра в вёдра, выдру в тундру.
Подробнее..

Проблемы мониторинга дата-пайплайнов и как я их решал

16.06.2021 00:20:01 | Автор: admin

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

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

Чтобы понять, как все это мониторить, давайте разберемся кто вообще работает с данными, которые мы с таким трудом намайнили:

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

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

Код - запускается следующий в цепочке пайплайн, происходят преобразования, рисуются графики и т.п.

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

Вот примеры:

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

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

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

ETL как он естьETL как он есть

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

Чего не хватает во встроенных мониторингах систем работы с данными:

  • Бизнес не может просто посмотреть в модный мониторинг типа того же Airflow или ELK и понять, можно или нельзя доверять данным, актуальность состояния данных непрозрачна.

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

  • Нет возможности собрать реальную статистику и проанализировать, где самое слабое место. Просто считать инциденты не вариант, т.к. важнее не количество инцидентов, а время, в течение которого состояние данных было неактуальным. Знаю, что такие проблемы некоторые компании решают самописными парсерами логов или подсчетом пиков-просадок на графиках (напишите, как это реализовано у вас).

Все это превращается в такие вот проблемы:

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

  2. Люди из бизнеса хотят более наглядного отображения состояния данных и системы, чем оно представлено в технических мониторингах.

  3. Статистика, если и собирается, то собирается по техническим проблемам и нельзя понять, насколько эти технические проблемы повлияли на бизнес.

Концепция

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

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

Почему вообще вебхуки?

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

После того, как мы начали отсылать из процессов события, нужно их проанализировать и получить ответы на всякие важные вопросы, например (все числа абстрактны):

  • запустилась ли наша задача 10 раз за последний день?

  • не превышает ли количество падений (определяем падение, если полученное значение > 0, например) 15% от всех запусков за сегодня?

  • нет ли процессов, которые длятся больше 20 минут?

  • не прошло ли больше часа с момента последнего успешного завершения?

  • стартовало ли событие по планировщику в нужное время?

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

Реализация

Я начал с дашборда, дизайн - не моя профессия, так что просто взял за основу дашборд, показывающий состояние крон-джобов на сайте Nomadlist, у меня получилось как-то так:

Дашборд состояния серверов Sensorpad средствами SensorpadДашборд состояния серверов Sensorpad средствами Sensorpad

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

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


Для инженера тут все понятно:

  • скрипт отрабатывает быстро (еще бы, простая крон-джоба);

  • монитор вполне живой, 25 минут назад обновился;

  • места еще с запасом (цифра 53 в левом нижнем углу - это последнее принятое значение);

Для людей из бизнеса тут тоже все просто:

  • монитор зеленый;

  • статус прописан в первой же строчке;

  • никакой лишней информации;

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

И насколько просто такое настроить?

  1. Создаем вебхук в самом сервисе, они там называются сенсорами, по аналогии со всякими штуками из физического мира.

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

    df -h |grep vda1 | awk  '{ print $5 }'| sed 's/.$//' | xargs -I '{}' curl -G "https://sensorpad.link/<уникальный ID>?value={}" > /dev/null 2>&1
    
  3. Присоединяем к этому вебхуку монитор, называем его: количество свободного места (но можно еще и другие, например, то, что события уходят по графику означает, что сервер не упал)

  4. Настраиваем правила, по которым монитор меняет свой статус.

  5. Присоединяем каналы для отправки уведомлений.

  6. Добавляем монитор на один или несколько дашбордов.

А можно поподробнее?

Для вебхуков я пока что сделал саму простую имплементацию:

  • базовый вебхук, который будет нужен для 80% проектов;

  • cron-вебхук, который ожидает события в заданное через cron-синтаксис время;

  • chain-вебхук, который умеет отслеживать события от процессов, соединенных в цепочки;

главное в нашем деле - не усложнять интерфейсыглавное в нашем деле - не усложнять интерфейсы

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

Догфудинг в действииДогфудинг в действии

Дальше создаем тот самый монитор - квадратик, меняющий статус и цвет.

Можно даже иконку выбратьМожно даже иконку выбрать

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

Теперь, собственно то, из-за чего я и написал эту балалайку: правила и гибкая логика.

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

Правила для мониторинга места на дискеПравила для мониторинга места на диске

На скриншоте выше видно уже созданные правила, но я покажу как они создаются.

Например правило, которое можно сформулировать так: "установи статус Warning, если за последний день было больше 5 джоб, которые работали дольше 10 секунд".

А вот какие вообще можно выбирать проверки в каждом из пунктов:

И какие реальные кейсы можно покрыть этими правилами?

У каждого свои кейсы. Дата-инженерия вообще весьма специфичное для каждой компании направление. Если у вас есть дата-пайплайны или cron jobs, сервис оповестит вас, если (все цифры, разумеется, конфигурируемы):

  • Cron job, Airflow DAG или любой другой процесс не запустился по расписанию;

  • 20% задач одного и того же пайплайна за день не отработали как надо;

  • связанная задача в пайплайне не запустилась через 2 минуты после окончания родительской задачи;

  • интервал между запусками двух задач меньше 1 минуты (похоже, у нас две конкурентные джобы);

  • с момента последнего успешного завершения пайплайна прошло 2 часа (а данные должны считаться каждый час);

  • время работы пайплайна уже целых 20 минут (а должен был отработать за 5, что-то подвисло).

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

А теперь - статистика!

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

Немного полезных и не очень графиковНемного полезных и не очень графиков

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

Вот такой концепт. Чего не хватает?


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

Потыкайте его вживую, заодно зацените, какой я у мамы дизайнер лендингов: https://sensorpad.io

Подробнее..

Стажировка в Southbridge набор в июне

09.06.2021 10:16:43 | Автор: admin

image


В мае мы запустили DevOps-стажировку в Southbridge для начинающих инженеров. Как проходит стажировка для первого потока, мы уже рассказывали. Сейчас начался второй поток, и мы ведем набор на третий. Подробности о стажировке под катом.


Кого приглашаем


Ищем начинающих инженеров, которым интересна сфера DevOps. Важно знать Linux на уровне администрирования. Отлично, если есть опыт написания скриптов на Bash, Python. Но это не обязательно.


Ждем тех, кто хочет не только получить технические навыки, но и развить софт-скилы: работу в команде, коммуникабельность, навык самообразования.


О программе


Стажировка проходит удалённо, занимает примерно 4-5 часов в день, которые можно выделить тогда, когда удобно. Проводим общие встречи в Zoom с наставниками и скрам-мастером, командные встречи.


Программа рассчитана на три месяца.
Что изучаем и с чем работаем на стажировке: Git, Docker, Kubernetes, мониторинг и логирование в Kubernetes, CI/CD и не только. Проходим курсы и сертификации в Слёрме.


Подробная программа

Этап 1 (2 недели)


а) самостоятельное изучение необходимого стека технологий для работы с веб-проектами,


б) выполнение проверочной работы.


Этап 2 (1 неделя)


а) прохождение видеокурса по Git,


б) прохождение видеокурса Docker: from zero to hero,


в) сдача сертификации.


Этап 3 (1 неделя + 5 дней практикум)


Задачи:


а) прохождение курса Kubernetes: База,


б) сдача сертификации,


б) выполнение практикума,


в) работа в команде.


Этап 4 (1 неделя)


Задачи:


а) прохождение курса Мониторинг и логирование в Kubernetes,


б) сдача сертификации.


Этап 5 (2 недели)


Задачи:


а) прохождение курса DevOps: Tools & Cheats,


б) выполнение практической работы из интенсива на выделенном стенде,


в) прохождение видеокурса CI/CD.


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


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


Старт третьего потока стажировки в середине июня. Резюме и ваши вопросы присылайте на почту job@southbridge.ru.

Подробнее..

Перевод Tоп 10 PromQL запросов для мониторинга Kubernetes

12.06.2021 10:05:57 | Автор: admin

В этой статье приведены примеры популярных запросов Prometheus для мониторинга Kubernetes.

Если вы только начинаете работать с Prometheus и у вас возникают сложности при создании запросов PromQL, советуем обратиться к руководству по началу работы с PromQL. Здесь мы пропустим теорию и сразу перейдём к практике.

Рейтинг основан на опыте компании Sysdig, ежедневно оказывающей сотням клиентов помощь в настройке мониторинга их кластеров:

1. Количество pods в каждом namespace

Информация о количестве pod в каждом namespace может быть полезна для обнаружения аномалий в кластере, например, слишком большого количества pods в отдельном namespace:

sum by (namespace) (kube_pod_info)

2. Количество контейнеров без CPU limits в каждом namespace

Важно правильно задавать лимиты для оптимизации производительности приложений и кластера. Этот запрос находит контейнеры без CPU limits:

count by (namespace)(sum by (namespace,pod,container)(kube_pod_container_info{container!=""}) unless sum by (namespace,pod,container)(kube_pod_container_resource_limits{resource="cpu"}))

3. Количество перезагрузок pods в каждом namespace

С помощью этого запроса вы получите список pods, которые перезапускались. Это важный показатель, поскольку большое количество перезагрузок pod обычно означает CrashLoopBackOff:

sum by (namespace)(changes(kube_pod_status_ready{condition="true"}[5m]))

4. Pods в статусе Not Ready в каждом namespace

Запрос выводит все pods, при работе которых возникла проблема. Это может быть первым шагом к её локализации и устранению:

sum by (namespace)(kube_pod_status_ready{condition="false"})

5. Превышение ресурсов кластера ЦП

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

sum(kube_pod_container_resource_limits{resource="cpu"}) - sum(kube_node_status_capacity_cpu_cores)

6. Превышение ресурсов кластера Память

Если все Memory limits суммарно превышают ёмкость кластера, то это может привести к PodEviction, если на узле не будет хватать памяти. Для проверки используйте запрос PromQL:

sum(kube_pod_container_resource_limits{resource="memory"}) - sum(kube_node_status_capacity_memory_bytes)

7. Количество исправных узлов кластера

Запрос выведет количество исправных узлов кластера:

sum(kube_node_status_condition{condition="Ready", status="true"}==1)

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

Найти узлы кластера, которые периодически меняют состояние с Ready на Not Ready:

sum(changes(kube_node_status_condition{status="true",condition="Ready"}[15m])) by (node) > 2

9. Обнаружение простаивающих ядер ЦП

Планировании ресурсов кластера Kubernetes не самая простая задача. Этот запрос поможет вам определить, сколько ядер ЦП простаивают:

sum((rate(container_cpu_usage_seconds_total{container!="POD",container!=""}[30m]) - on (namespace,pod,container) group_left avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="cpu"})) * -1 >0)

10. Обнаружение неиспользуемой памяти

Этот запрос поможет снизить ваши затраты, предоставив информацию о неиспользуемой памяти:

sum((container_memory_usage_bytes{container!="POD",container!=""} - on (namespace,pod,container) avg by (namespace,pod,container)(kube_pod_container_resource_requests{resource="memory"})) * -1 >0 ) / (1024*1024*1024)

Хотите узнать больше?

Рекомендуем изучить нашу шпаргалку по PromQL, чтобы узнать, как писать более сложные запросы PromQL.

Также воспользуйтесь отличной коллекцией Awesome Prometheus alerts collection. Она включает несколько сотен Prometheus alert rules, вы можете изучить их, чтобы узнать больше о PromQL и Prometheus.

Подробнее..

Перевод Контролируем удаление с финализаторами

18.06.2021 08:07:31 | Автор: admin

image


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


В этой статье мы рассмотрим:


  • Какие свойства ресурса влияют на удаление.
  • Как финализаторы и ссылки на родителя-владельца управляют удалением объектов.
  • Как можно использовать propagationPolicy, чтобы изменить порядок удаления.
  • Как работает удаление, с примерами.

Для простоты во всех примерах мы используем ConfigMaps и базовые команды kubectl. Мы увидим, как работают эти команды, и обсудим результаты их использования на практике.


Базовая команда delete


В Kubernetes есть несколько команд для создания, чтения, обновления и удаления объектов. Здесь мы поговорим о четырех командах kubectl: create, get, patch и delete.
Примеры базовой команды kubectl delete:


kubectl create configmap mymapconfigmap/mymap created

kubectl get configmap/mymapNAME    DATA   AGEmymap   0      12s

kubectl delete configmap/mymapconfigmap "mymap" deleted

kubectl get configmap/mymapError from server (NotFound): configmaps "mymap" not found

Перед командой стоит знак $, далее следует ее результат. Как видите, мы начали с kubectl create configmap mymap, чтобы создать пустой configmap mymap. Теперь нужно выполнить get и убедиться, что он существует. Затем мы удалили configmap. Если снова сделать get, получим ошибку HTTP 404, потому что configmap не найден.


У команды deleteочень простая диаграмма состояний:


image
Диаграмма состояний для delete


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


Как работают финализаторы


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


Финализаторы это ключи в манифесте ресурса, отвечающие за операции, которые надо выполнить до удаления объекта. Они контролируют сборку мусора для ресурсов и сообщают контроллерам, какие операции очистки нужно выполнить до удаления ресурса. Они не обязательно обозначают код, который нужно выполнить. По сути, это просто списки ключей, вроде аннотаций. Как и аннотациями, ими также можно управлять.


Скорее всего, вы встречали следующие финализаторы:


  • kubernetes.io/pv-protection
  • kubernetes.io/pvc-protection

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


Ниже приводится configmap без свойств, но с финализатором:


cat <<EOF | kubectl create -f -apiVersion: v1kind: ConfigMapmetadata:  name: mymap  finalizers:  - kubernetesEOF

Контроллер ресурса configmap не понимает, что делать с ключом финализатора kubernetes. Такие финализаторы для configmap я называю мертвыми, и обычно они используются с неймспейсами. Вот что происходит при попытке удалить configmap:


kubectl delete configmap/mymap &configmap "mymap" deletedjobs[1]+  Running kubectl delete configmap/mymap

Kubernetes сообщает, что объект удален, но на самом деле, в традиционном понимании, никуда он не удален. Скорее он находится в процессе удаления. Если мы снова выполним get, то узнаем, что объект изменен и теперь содержит временную метку удаления deletionTimestamp.


kubectl get configmap/mymap -o yamlapiVersion: v1kind: ConfigMapmetadata:  creationTimestamp: "2020-10-22T21:30:18Z"  deletionGracePeriodSeconds: 0  deletionTimestamp: "2020-10-22T21:30:34Z"  finalizers:  - kubernetes  name: mymap  namespace: default  resourceVersion: "311456"  selfLink: /api/v1/namespaces/default/configmaps/mymap  uid: 93a37fed-23e3-45e8-b6ee-b2521db81638

Если в двух словах, объект был изменен, но не удален. Все потому, что Kubernetes увидел, что у объекта есть финализаторы, и поместил его в состояние read-only. Временная метка удаления показывает, что объект можно только читать а еще из него можно удалить апдейты ключа финализатора. Другими словами, удаление будет завершено, только когда мы удалим из объекта финализатор.


Удалить финализаторы можно с помощью команды patch. Фоновое удаление завершится, и объект будет удален. Если мы опять выполним get configmap, то ничего не увидим.


kubectl patch configmap/mymap \    --type json \    --patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'configmap/mymap patched[1]+  Done  kubectl delete configmap/mymapkubectl get configmap/mymap -o yamlError from server (NotFound): configmaps "mymap" not found

Диаграмма состояния для финализации выглядит так:


image
Диаграмма состояний для финализации


Если мы попытаемся удалить объект с финализатором, он останется на этапе финализации, пока контроллер не удалит ключи финализаторов или финализаторы не будут удалены через Kubectl. Когда список финализаторов будет пуст, Kubernetes поместит его в очередь на удаление из реестра.


Ссылки на владельца


Ссылки на владельца (owner references) описывают отношения между группами объектов. Это свойства ресурсов, которые указывают, как они связаны друг с другом, чтобы можно было удалять целые деревья ресурсов.


Правила финализатора обрабатываются, если есть ссылки на владельца. Ссылки на владельца состоят из имени и UID. Они связывают ресурсы в одном неймспейсе и им нужен UID. Ссылки на владельца для подов обычно указывают на replica set, которому они принадлежат. Если удалить deploy или stateful set, дочерние replica set и pod тоже удалятся.


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


cat <<EOF | kubectl create -f -apiVersion: v1kind: ConfigMapmetadata:  name: mymap-parentEOFCM_UID=$(kubectl get configmap mymap-parent -o jsonpath="{.metadata.uid}")cat <<EOF | kubectl create -f -apiVersion: v1kind: ConfigMapmetadata:  name: mymap-child  ownerReferences:  - apiVersion: v1    kind: ConfigMap    name: mymap-parent    uid: $CM_UIDEOF

Если мы удалим дочерний объект, в котором есть ссылка на владельца, родитель никуда не денется:


kubectl get configmapNAME           DATA   AGEmymap-child    0      12m4smymap-parent   0      12m4skubectl delete configmap/mymap-childconfigmap "mymap-child" deletedkubectl get configmapNAME           DATA   AGEmymap-parent   0      12m10s

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


kubectl get configmapNAME           DATA   AGEmymap-child    0      10m2smymap-parent   0      10m2skubectl delete configmap/mymap-parentconfigmap "mymap-parent" deletedkubectl get configmapNo resources found in default namespace.

Получается, что если в дочернем объекте есть ссылка на родителя, он автоматически удаляется при удалении родителя. Это называется cascade. По умолчанию cascade имеет значение true, но можно указать --cascade=false в kubectl delete, чтобы удалить родительский объект, не трогая дочерние.


В следующем примере у нас есть родительский и дочерний объекты, а еще ссылки на владельца. Если мы удалим родителя, указав --cascade=false, дочерние объекты сохранятся:


kubectl get configmapNAME           DATA   AGEmymap-child    0      13m8smymap-parent   0      13m8skubectl delete --cascade=false configmap/mymap-parentconfigmap "mymap-parent" deletedkubectl get configmapNAME          DATA   AGEmymap-child   0      13m21s

Параметр --cascade указывает на политику распространения в API, которая позволяет менять порядок объектов удаления в дереве. В следующем примере используется отправка запроса к API через curl для удаления с фоновой политикой распространения (propagation policy):


kubectl proxy --port=8080 &Starting to serve on 127.0.0.1:8080curl -X DELETE \  localhost:8080/api/v1/namespaces/default/configmaps/mymap-parent \  -d '{ "kind":"DeleteOptions", "apiVersion":"v1", "propagationPolicy":"Background" }' \  -H "Content-Type: application/json"{  "kind": "Status",  "apiVersion": "v1",  "metadata": {},  "status": "Success",  "details": { ... }}

Политику распространения нельзя указать в командной строке с помощью kubectl только при прямом вызове API. Просто создайте прокси, чтобы иметь доступ к серверу API со своего компьютера, и выполните команду curl с одним URL, чтобы послать команду delete.


Есть три варианта политики распространения:


  • Foreground: дочерние объекты удаляются до родительского (обратный порядок).
  • Background: родительский объект удаляется до дочерних (прямой порядок).
  • Orphan: ссылки на владельца игнорируются.

Если вы удаляете объект, в котором есть ссылки на владельца, то финализаторы также будут учитываться. В результаты деревья объектов могут сохраняться, и удаление будет частичным. В этом случае изучите имеющиеся ссылки на владельца и финализаторы, чтобы понять, что происходит.


Принудительное удаление неймспейса


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


cat <<EOF | curl -X PUT \  localhost:8080/api/v1/namespaces/test/finalize \  -H "Content-Type: application/json" \  --data-binary @-{  "kind": "Namespace",  "apiVersion": "v1",  "metadata": {    "name": "test"  },  "spec": {    "finalizers": null  }}EOF

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


Итоги


Как показывают примеры, финализаторы могут помешать удалению ресурсов в Kubernetes, особенно если речь о родительских и дочерних объектах. Обычно финализаторы добавляются в код не просто так, поэтому нужно все проверить, прежде чем удалять их вручную. С помощью ссылок на владельца можно указывать и удалять деревья ресурсов, хотя и в этом случае будут учитываться финализаторы. Наконец, можно использовать политику распространения, чтобы указывать порядок удаления в прямых вызовах API и контролировать процесс удаления объектов. Теперь вы чуть больше знаете о том, как работает удаление в Kubernetes, и можете поэкспериментировать самостоятельно в продакшен-кластере.


Видео от автора:


Подробнее..

Антистресс для твоего сервера. Тестируем балансировщик нагрузки от Timeweb

07.06.2021 16:20:09 | Автор: admin

Привет, Хабр!


Сегодня мы расскажем сообществу о запуске нашего нового сервиса балансировщик нагрузки.

Сейчас услуга доступна для всех желающих в режиме открытого бета-тестирования в личном кабинете VDS. Это, конечно, бесплатно, а мы будем благодарны вам за комментарии и замечания.

Ребята, почему только сейчас?


Можете вполне резонно спросить вы. Мы, как и все, привыкаем к новой, постпандемийной (или еще нет?), реальности и отвечаем запросам наших клиентов.

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

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

Как это работает?


Балансировщик переправляет клиентские запросы на доступные рабочие серверы из группы. Регулярно опрашивая состояние серверов, балансировщик понимает, какие серверы активны и доступны для обработки клиентских запросов.

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

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

Окей, это всё понятно, а как попробовать?


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

В правилах переадресации задаем параметры проброса трафика, указываем входящий и исходящий порт, а также протокол трафика из доступных: tcp, https, http, http2.



Далее вы можете выбрать один из двух доступных алгоритмов балансировки: Round Robin или Least Connections.

Какой алгоритм выбрать?


Round Robin алгоритм, при котором серверы перебираются по кругу: первый запрос передается на первый сервер, следующий на второй сервер, и так далее до последнего сервера, после чего цикл начинается заново.

Least Connections алгоритм, при котором каждый новый запрос передается на сервер с меньшим количеством активных подключений.

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

Теперь остается только выбрать ваши VDS или указать IP-адреса серверов. Кстати, вы можете использовать балансировщик не только с нашими VDS. Мы будем только за!

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

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

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

Да начнется беспощадный бета-тест!



Подробнее..

Инженеры technical support и места, где они обитают

08.06.2021 10:08:20 | Автор: admin

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

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

Что за человек такой - инженер Technical Customer Support в Veeam Software?

В идеальном мире это тот самый универсальный человек, требования к которому сформулированы сухим кадровическим текстом в описании вакансии. И швец, и жнец, и на дуде игрец. Вот только есть одна небольшая проблема его не существует. Так что если вы не знали, то держите первое открытие за сегодняшний день: вакансии, как правило, пишутся под идеального кандидата в вакууме, которого никто никогда не видел. А если даже такой вдруг покажется на горизонте, то его с руками оторвут. Отсюда вывод: если вы не подходите под все пункты в описании вакансии, это нормально, и можно смело откликаться. Если только пропущенные пункты не помечены как критически важные. Тут уж действительно мимо.

Но вернёмся к нашему инженеру техподдержки в Veeam. И да, это наш блог, так что простите, но пишем мы про то как всё устроенно именно у нас, а не у соседей. Так вот, все его навыки можно объединить в три группы: это технические скилы, знание языка и умение общаться с клиентами. Сразу возникает вопрос: а что важнее? Можно же взять сисадмина и научить его разговорному английскому. Или выпускника филфака за недельку натаскать по книжкам а-ля VMware for Dummies. А самого последнего грубияна - отправить на курсы придворного этикета, где его научат родину любить и вилкой с ножом пользоваться, и с людьми вежливо общаться. Но вас тут ждёт большое разочарование: мы в Veeam ищем комбинацию всех трёх навыков в одном человеке. Любой и каждый желающий вступить в наши стройные ряды обязательно проходит все три этапа отбора. К нам трудно попасть, легко потерять и . ну вы и сами знаете.

На практике этапы отбора могут идти вразнобой, но давайте представим, что первым будет техническое собеседование. И как вы думаете, что же можно спросить у кандидата, если твои продукты - это корпоративный софт, и вероятность того, что кандидат их хотя бы видел, крайне мала? Про то, что он их использовал хотя бы в рамках домашней лаборатории, даже фантазировать не будем. Правильно, спросить можно всё что угодно, только не про сам софт. Поэтому техническое собеседование -- это разговор про IT-кругозор кандидата и имеющиеся у него навыки. Вся наша работа строится вокруг множества технологий. Среди них гипервизоры VMware и Hyper-V, Nutanix AHV, Azure, AWS, Oracle, SAP HANA и так далее. Но мы не ожидаем, что кандидаты знают их так же, как и мы. Нет, но если они могут хоть как-то поддержать разговор про виртуальные машины, то им сразу плюсик в карму, тут без сомнений. И мы не ожидаем, что они могут хотя бы час заливаться соловьём, сравнивая особенности работы корпоративных СХД. Или что готовы без запинки объяснить разницу между Ms SQL, MySQL, Oracle и Redis. Нет, ничего такого знать совершенно не требуется. Всему, что надо будет, проще потом научить, но вот базу кандидаты знать обязаны.

Что такое реестр в винде, зачем нужны виртуальные машины, почему домены водятся в лесу, как пинг связан с эхо, а шутка про udp может и вообще не дойти. Если хоть что-то из предыдущего предложения вызывает у кандидата затруднения, то у него нет этой самой базы. Если человек хотя бы улыбнулся в процессе чтения этих вопросов, то, похоже, в этой голове что-то есть. Ведь учиться читать, не зная букваря, сами понимаете, затея гиблая. Поэтому ещё раз: каких-то супер-узких знаний мы от кандидатов не ждём (но если они есть, мы будем только рады), но уверенные знания уровня молодого сисадмина быть должны строго обязательно.

Далее следует проверка уровня владения иностранным языком. Возьмём для примера английский, как самый популярный. (Хотя у нас бывают вакансии и для знающих французский, немецкий и вообще примерно любой, отличный от русского. Но не суть.) Суть в том, что самый частый вопрос в нашу сторону, само собой, про необходимый уровень языкового навыка. И самое типичное уточнение от кандидатов: Ну я документацию нормально читаю. В принципе. А пару раз даже писал в зарубежный саппорт письма. Ну что же, ты большой молодец. Спору нет. Однако есть проблема: этого объективно мало. Наш инженер должен уметь разговаривать с клиентами ртом.

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

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

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

И завершающим этапом служит так называемый customer care. Вещь пока малоизвестная по стране в целом, но очень важная для всех, кто работает с западными рынками. Заключается она не только в умении быть вежливым и красиво выходить из любой ситуации, но и в том, чтобы любить человека как класс. Чтобы даже самый лютый негативщик сиял от радости после общения с нашим специалистом. Тут ведь штука какая: к нам крайне редко звонят, чтобы просто сказать спасибо за наш супер-крутой софт и отличный сервис. Обычно на звонок людей побуждает наличие какой-то проблемы, которую надо решить здесь и сейчас. То есть звонящий априори раздражён, ему плохо, и он совершенно не против на ком-то сорваться. Возможно, даже поорать. И вот тут ваши навыки общения, умение оставаться вежливым и искреннее желание помочь человеку с его бедой выходят на первый план. И вы не поверите, но мы и этому всему научим, а на входном тестировании кандидатов интервьюируют люди, профессионально занимающиеся проблемами customer care. (Да, бывают и такие.)

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

А теперь зайдем с другой стороны

Чего ради такому замечательному специалисту идти работать к нам в техподдержку? Пусть даже в гордом звании инженера.

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

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

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

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

И вот вам первое же отличие: они и не сидят на телефоне целый день. Они набирают из очереди кейсов, отключаются от звонков и занимаются их решением. Потому что на первой же линии мы решаем до 80% обращений. А это, напомню, не истории про зависший роутер, а серьёзные инфраструктурные задачи такого уровня, который львиная доля его бывших коллег может себе только нафантазировать. И то, если наберётся достаточной смелости.

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

Youre in the army now

Ладно, предположим, что кандидат прошёл через горнило отбора, и мы все рады приветствовать нового члена нашей команды. Теперь уже коллеге выдали стол, стул, компьютер, чашку и прочие ништяки новичка, но что будет дальше?

А дальше его ждут три месяца интенсивного обучения. Причём с умным видом дремать на лекциях не получится можно считать, что это обучение без отрыва от производства, с учебными KPI. Где-то с середины программы постепенно начинается работа с кейсами. Поэтому к концу испытательного срока от новобранца ожидается где-то 30-40 закрытых кейсов и уже какие-то свидетельства того, что инженер может применить полученные знания на практике.

Само собой, первым делом ему выделят ментора и начнут подтягивать уровень технических знаний по всем необходимым нам областям. Это гипервизоры, сети, различные операционки, СУБД, СХД, облака и многое другое. Даже если он решит уволиться спустя эти три месяца, с таким набором знаний его с руками отрывают в любую купи-продай контору на должность старшего сисадмина. Но так скоропостижно увольняются только уверенно придерживающиеся методологии Сам Себе Злобный Буратино. Настоящий инженер уже почувствовал, что в IT-мире бывают интересные и нетривиальные задачи, за решение которых платят приятную зарплату, поэтому зачем опять идти торговать помидорами?

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

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

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

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

Итого

Инженер техподдержки, как видите, это не низшее звено в цепи эволюции IT специалиста, а серьёзная работа. Ведь в первую очередь он всё-таки инженер. А как и в любой инженерной специальности, тут всё зависит исключительно от человека. Захочет станет признанным мастером своего дела и посвятит ему всю жизнь. И не важно, будет это работа у станка или со временем захочется научиться руководить другими инженерами. Хороший специалист никогда не пропадёт, а его работа должна (и будет) хорошо оплачена. А даже если со временем он решит кардинально сменить профиль деятельности, то всегда можно легко это сделать, с блеском применяя полученные ранее знания и умения.

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

Сокращённая версия этой статьи была залита ещё и на хх.

Подробнее..

Аварии как опыт 3. Как мы спасали свой мониторинг во время аварии в OVH

09.06.2021 12:21:23 | Автор: admin

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

О мониторинге у нас

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

1. Blackbox-мониторинг для проверки состояния сайтов. Цель проста собирать статистику с определенных endpointов и проверять их состояние по тем условиям, которые требуется установить. Например, это может быть health page в виде JSON-страницы, где отражено состояние всех важных элементов инфраструктуры, или же мониторинг отдельных страниц сайта. У нас принято считать, что данный вид мониторинга самый критичный, так как следит за работоспособностью сайта/сервисов клиента для внешних пользователей.

Вкратце о технической стороне этого мониторинга: он выполняет запросы разного уровня сложности по HTTP/HTTPS. Есть возможность определять размер страницы, ее содержимое, работать с JSON (они обычно используются для построения status page-страниц приложений клиента). Он географически распределен для повышения отказоустойчивости и во избежание всевозможных блокировок (например, от РКН).

Работа данного мониторинга не была затронута аварией благодаря геораспределенности (к тому же, у него вообще нет инсталляций в OVH).

2. Мониторинг Kubernetes-инфраструктуры и приложений клиента, запущенных в ней. С технической точки зрения этот мониторинг основан на связке Prometheus + Grafana + Alertmanager, которые устанавливаются локально на кластеры клиента. Часть данных, собираемых на данных системах мониторинга (например, метрики, напрямую связанные с Kubernetes и Deckhouse), по умолчанию отправляется в нашу общую систему, а остальные могут отправляться опционально (например, для мониторинга приложений и реакции от наших дежурных инженеров).

3. Мониторинг ресурсов, которые находятся вне кластеров Kubernetes. Например, это железные (bare metal) серверы, виртуальные машины и СУБД, запущенные на них. Данную зону мониторинга мы покрываем с помощью стороннего сервиса Okmeter (а с недавних пор уже не очень-то для нас и стороннего). Именно его работа была фатально нарушена в момент аварии OVH.

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

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

Как мы справлялись с этой аварией? Какие шаги предпринимали во время инцидента? И какие после?

Первые признаки аварии

Проверка доступности внешних средств мониторинга осуществляется с применением метода Dead mans switch (DMS). По своей сути это мониторинг, который работает наоборот:

  • Создается поддельный алерт OK, означающий, что всё хорошо, и он постоянно отправляется с локальных мониторингов (Prometheus, Okmeter и т.п.) в нашу систему инцидент-менеджмента.

  • Пока с мониторингом действительно всё хорошо, алерт OK активен, но в системе не показывается.

  • В обратной ситуации, когда возникают проблемы с мониторингом, алерт OK перестает быть активным, из-за чего автоматически создаётся алерт ERROR о неработающем мониторинге. И вот уже на него надо реагировать.

Данная проверка очень эффективна в ситуациях, которая произошла в роковой день (10 марта): первый алерт о проблеме (ERROR) мы получили как раз от DMS.

События разворачивались следующим образом:

  • Первое сообщение о проблеме алерт от DMS, полученный приблизительно в 3:20 ночи по Москве.

  • Связываемся с коллегами из Okmeter и узнаем, что они испытывают проблемы с ЦОД, в котором расположены. Детальной информации на данный момент не получаем, из-за чего масштабы аварии нам неизвестны. Кроме того, дежурный инженер видит, что у нас корректно работают другие системы мониторинга (blackbox и Kubernetes). Поэтому принимается решение отложить инцидент до утра.

  • Утром (в 8:14) становится известно, что ЦОД сгорел, а Okmeter не будет доступен до тех пор, пока не восстановит свою инфраструктуру в другом ЦОД.

Здесь также стоит остановиться подробнее на том, как была устроена инфраструктура у Okmeter. Основные её компоненты находились в дата-центрах OVH:

  • SBG-2 который был полностью уничтожен пожаром;

  • SBG-1 который был частично поврежден и обесточен.

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

Руководствуясь этой информацией утром 10 марта, мы сделали вывод, что нужно срочно замещать важные для нас функции Okmeter хоть какими-то решениями на временной основе.

Первые действия

В компании была собрана специальная команда, основными целями которой являлись:

  1. Определение масштабов аварии;

  2. Поэтапное планирование, как устранять последствия инцидента;

  3. Дальнейшее внедрение полученных решений.

В неё вошли тимлиды наших DevOps-команд, инженеры нашей платформенной команды и CTO компании. Позже к ней также добавились отдельные инженеры, помогавшие со срочной разработкой и тестированием новых инструментов, заменивших критичные проверки от Okmeter.

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

Матрица критичности алертовМатрица критичности алертов

Эта матрица распространяется на события из всех 3 используемых у нас систем мониторинга. Каждому инциденту, зафиксированному в любой из систем, назначается критичность от S1 (полная потеря работоспособности компонента системы) до S9 (диагностическая информация). Большая часть алертов с критичностью S1 это blackbox-мониторинг, который проверяет состояние сайтов клиента. Однако также к этой категории относится и незначительная часть алертов, отправляемых со стороны Okmeter (подробнее о них см. ниже). Другая незначительная часть приходится на S2, а все остальные имеют более низкую критичность (S3 и т.п.).

Проведя учет количества и видов алертов с S1 и S2 от Okmeter, мы приняли очевидное решение заняться ими в первую очередь, полностью компенсировав другим временным решением. А уже после этого можно было переходить на алерты с меньшей критичностью.

Оповестив всех клиентов, инфраструктуру которых задела авария у Okmeter, мы приступили к составлению плана восстановления.

Порядок и план восстановления алертов от Okmeter

Первая очередь алертов: S1-S2

Итак, какие именно критичные алерты мы потеряли с недоступностью Okmeter? Чтобы оперативно собрать эту информацию, каждая команда инженеров тех, что сопровождают проекты с мониторингом от Okmeter, подготовила статистику алертов, приходивших с 1 июля 2020 года.

Получился следующий список:

  1. Различные алерты для СУБД.

    1. Проверка работоспособности СУБД в целом (запущен ли процесс).

    2. Состояние репликации.

    3. Состояние запросов к БД (например, сколько запросов находятся в ожидании).

  2. Дисковое потребление на виртуальных машинах.

  3. Доступность виртуальных машин в целом.

Вторая очередь алертов: S3 и далее

Ситуация с алертами категории S3 была проще: их меньше, они менее критичные, да и вообще эта категория оказалась не у всех команд.

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

Немного магического Bash

Чтобы реализовать замену проверкам и алертам Okmeter, требовалось уметь деплоить на все серверы актуальные скрипты мониторинга, чтобы поддерживать их в актуальном состоянии. Реализация: с помощью Ansible-плейбуков мы задеплоили все необходимые скрипты, среди которых был скрипт автообновления. Последний раз в 10 минут загружал новые версии других скриптов. Из-за очень сжатых сроков основную часть скриптов мы писали на Bash.

Общий подход получился следующим:

  1. Сделали shell-скрипты, которые запускались на виртуальных машинах и bare metal-серверах. Помимо своей основной функции (проверка работоспособности некоторых компонентов) они должны были доставлять сообщения в наш мониторинг с такими же лейблами и другими элементами, как и у Okmeter: имя триггера, его severity, другие лейблы и т.д. Это требовалось для сохранения той логики работы мониторинга, которая была и до падения. В общем, чтобы процесс работы дежурных инженеров оставался неизменным и чтобы работали прежние правила управления инцидентами.

    Быстрой реализации этого этапа способствовал тот факт, что у нас уже были готовые инструменты для работы с API мониторинга внутренний инструмент под названием flint (flant integration).

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

  3. В течение некоторого времени мы дополнительно проверяли, что алерты корректные, а сами скрипты выполняются правильно.

Результаты

На полную реализацию этого временного решения нам понадобился один рабочий день для алертов типа S1-S2 и еще один для S3. Все остальные инциденты (с более низким приоритетом) команды добавляли в индивидуальном порядке по мере необходимости.

В общей сложности новые скрипты были задеплоены примерно на 3000 хостов.

На каждом этапе решения проблемы мы подробно информировали клиентов о ходе восстановительных работ:

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

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

Выводы

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

Более практичные выводы таковы:

  1. Если сервис требует повышенной отказоустойчивости, всегда важно разделять инфраструктуру не только на уровне разных ЦОД, но и географически. Казалось бы, разные ЦОДы у OVH? А в реальной жизни они горели вместе

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

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

P.S.

Читайте также в нашем блоге:

Подробнее..

Acme.sh Ansible Alias mode Автоматизируем получение и распространение TLS сертификатов

09.06.2021 20:16:20 | Автор: admin

Acme.sh - скрипт, позволяющий без особых проблем получать let's encrypt сертификаты очень разными способами. В данной статье я разберу как получать сертификаты через DNS api, но этим уже никого не удивишь, поэтому расскажу про метод DNS alias, он свежий (всего 3 года) и интересный. А так же про автоматизацию на Ansible и немного про мониторинг сертификатов.

Видеоверсия

Режимы acme.sh получения сертификатов прямо на целевом сервере

  • Webroot

  • Nginx\Apache

  • Stanalone

Режимы хорошие и удобные, когда у вас один - два сервера и можно просто на каждый установить acme.sh. Когда количество серверов, которым нужно TLS, переваливает за десяток, удобнее начать использовать wilcard сертификаты и выделить отдельный сервер для получения и распространения сертификата\ов. Получить wildcard сертификат можно только через подтверждение владения DNS зоной. DNS режимов несколько:

  • DNS manual

  • DNS API

  • DNS alias

Все примеры буду показывать на моём личном домене и установленном локально acme.sh.

DNS manual mode

Manual режим работает супер просто. Запускаем acme.sh с флагом --dns

acme.sh --issue --dns -d *.itdog.info --yes-I-know-dns-manual-mode-enough-go-ahead-please

koala@x220:~$ acme.sh --issue --dns -d *.itdog.info --yes-I-know-dns-manual-mode-enough-go-ahead-please[Ср мая  5 14:52:29 MSK 2021] Using CA: https://acme-v02.api.letsencrypt.org/directory[Ср мая  5 14:52:29 MSK 2021] Creating domain key[Ср мая  5 14:52:29 MSK 2021] The domain key is here: /home/koala/.acme.sh/*.itdog.info/*.itdog.info.key[Ср мая  5 14:52:29 MSK 2021] Single domain='*.itdog.info'[Ср мая  5 14:52:29 MSK 2021] Getting domain auth token for each domain[Ср мая  5 14:52:32 MSK 2021] Getting webroot for domain='*.itdog.info'[Ср мая  5 14:52:32 MSK 2021] Add the following TXT record:[Ср мая  5 14:52:32 MSK 2021] Domain: '_acme-challenge.itdog.info'[Ср мая  5 14:52:32 MSK 2021] TXT value: 'QXRgFOfVOZGOBC1qxAToMNOf7Xsv9gjM8hYG6akRoJ8'[Ср мая  5 14:52:32 MSK 2021] Please be aware that you prepend _acme-challenge. before your domain[Ср мая  5 14:52:32 MSK 2021] so the resulting subdomain will be: _acme-challenge.itdog.info[Ср мая  5 14:52:32 MSK 2021] Please add the TXT records to the domains, and re-run with --renew.[Ср мая  5 14:52:32 MSK 2021] Please add '--debug' or '--log' to check more details.[Ср мая  5 14:52:32 MSK 2021] See: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh

--issue - запрос на получение

--dns без аргумента - режим ручного DNS

--yes-I-know-dns-manual-mode-enough-go-ahead-please - интересное решение проблемы, когда люди не понимают что такое ручной режим

Он выдаёт TXT запись, которую нам необходимо добавить в наш dns хостинг, в данном случае это _acme-challenge.itdog.info TXT QXRgFOfVOZGOBC1qxAToMNOf7Xsv9gjM8hYG6akRoJ8

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

Анимация manual modeАнимация manual mode

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

После добавления записи проверяем начала ли она резолвится на гугловом dns

koala@x220:~$ dig -t txt _acme-challenge.itdog.info @8.8.8.8; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> -t txt _acme-challenge.itdog.info @8.8.8.8;; ANSWER SECTION:_acme-challenge.itdog.info. 1798 IN    TXT    "QXRgFOfVOZGOBC1qxAToMNOf7Xsv9gjM8hYG6akRoJ8"

Она резолвится, а значит можно получать сертификат

koala@x220:~$ acme.sh --renew --dns -d *.itdog.info --yes-I-know-dns-manual-mode-enough-go-ahead-please[Ср мая  5 14:58:08 MSK 2021] Renew: '*.itdog.info'[Ср мая  5 14:58:09 MSK 2021] Using CA: https://acme-v02.api.letsencrypt.org/directory[Ср мая  5 14:58:09 MSK 2021] Single domain='*.itdog.info'[Ср мая  5 14:58:09 MSK 2021] Getting domain auth token for each domain[Ср мая  5 14:58:09 MSK 2021] Verifying: *.itdog.info[Ср мая  5 14:58:13 MSK 2021] Success[Ср мая  5 14:58:13 MSK 2021] Verify finished, start to sign.[Ср мая  5 14:58:13 MSK 2021] Lets finalize the order.[Ср мая  5 14:58:13 MSK 2021] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/121...'[Ср мая  5 14:58:15 MSK 2021] Downloading cert.[Ср мая  5 14:58:15 MSK 2021] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/042...'[Ср мая  5 14:58:16 MSK 2021] Cert success.-----BEGIN CERTIFICATE-----certificate-----END CERTIFICATE-----[Ср мая  5 14:58:16 MSK 2021] Your cert is in  /home/koala/.acme.sh/*.itdog.info/*.itdog.info.cer [Ср мая  5 14:58:16 MSK 2021] Your cert key is in  /home/koala/.acme.sh/*.itdog.info/*.itdog.info.key [Ср мая  5 14:58:16 MSK 2021] The intermediate CA cert is in  /home/koala/.acme.sh/*.itdog.info/ca.cer [Ср мая  5 14:58:16 MSK 2021] And the full chain certs is there:  /home/koala/.acme.sh/*.itdog.info/fullchain.cer 

После этого TXT запись можно удалить.

Теперь есть ключ и сертификат, который будет действителен 3 месяца. Обновить сертификат можно будет через 2 месяца, let's enctypt даёт запас времени и если у вас вдруг что-то сломается, будет целый месяц чтобы починить и обновить сертификат.

И да, обновляется только сертификат, ключ остаётся таким, какой был выдан в первый раз. Обратите внимание на даты создания файлов, особенно *.example.com.key

# ls -l --time-style=+%Y-%m-%d \*.example.com/total 28-rw-r--r-- 1 root root 1587 2021-04-15 ca.cer-rw-r--r-- 1 root root 3433 2021-04-15 fullchain.cer-rw-r--r-- 1 root root 1846 2021-04-15 *.example.com.cer-rw-r--r-- 1 root root  719 2021-04-15 *.example.com.conf-rw-r--r-- 1 root root  980 2021-04-15 *.example.com.csr-rw-r--r-- 1 root root  211 2021-04-15 *.example.com.csr.conf-rw-r--r-- 1 root root 1675 2019-04-10 *.example.com.key

Хороший режим для одного раза или для понимания как работает подтверждение, но на постоянке каждые 2 месяца вручную обновлять TXT записи не серьёзно, поэтому рассматриваем следующий режим.

DNS API mode

Как это работает? Принцип действия тот же самый что у manual, только acme.sh сам вносит и удаляет TXT запись с помощью API вашего dns провайдера.

Анимация API modeАнимация API mode

Под DNS хостингом и DNS провайдером я буду иметь в виду сервис, в который вносятся DNS записи. Это может быть и DNS хостинг, который есть почти у каждой компании, торгующей доменами (namecheap, beget итд) или как отдельный сервис за деньги (Amazon Route 53, ClouDNS итд), или же ваш собственный сервис развернутый с помощью BIND, PowerDNS итд.

У каждого DNS провайдера свой не стандартизированный API и их поддержка в acme.sh реализована отдельными скриптами. Список всех поддерживаемых провайдеров находится тут https://github.com/acmesh-official/acme.sh/wiki/dnsapi

Для каждого написано как пользоваться и пример. Если вашего провайдера или сервиса нет в списке, можно написать свой скрипт, но не спешите открывать vim, дождитесь третьего способа.

Работу этого режима покажу на примере хостинга DNS у namecheap.

Для каждого DNS провайдера свои настройки, где-то нужно просто включить API и сгенерировать токен, где-то бывает посложнее, например для namecheap нужно ещё внести IP в allow list. Включаем API и сразу генерируется token, добавляем IP в список.

Теперь на локальной машине нужно настроить доступ к API

export NAMECHEAP_USERNAME="USERNAME"export NAMECHEAP_API_KEY="TOKEN"export NAMECHEAP_SOURCEIP="MY-IP"

Отступление про дополнительные флаги force и test. Будем использовать флаг -f (--force), что бы наши сертификаты генерировались заново, т.к. acme.sh видит уже сгенерированные сертификаты при их наличии не будет заново получать. Можно конечно просто сделать rm -rf ~/.acme.sh/domain/ вместо этого. Так же будем использовать флаг --test, что бы лишний раз не нагружать продакшн сервера let's encrypt. Вот такое сообщение мы получим, если после подтверждения в manual режиме попробуем другой режим.

[Ср мая 5 16:39:31 MSK 2021] *.itdog.info is already verified, skip dns-01.

Команда получения через API выглядит таким образом

acme.sh --issue --dns dns_namecheap -d *.itdog.info --test

Здесь после --dns мы добавляем имя провайдера.

Запускаем acme.sh

Раскрыть
koala@x220:~$ acme.sh --issue --dns dns_namecheap -d *.itdog.info --test[Ср мая  5 16:48:05 MSK 2021] Using ACME_DIRECTORY: https://acme-staging-v02.api.letsencrypt.org/directory[Ср мая  5 16:48:06 MSK 2021] Using CA: https://acme-staging-v02.api.letsencrypt.org/directory[Ср мая  5 16:48:06 MSK 2021] Creating domain key[Ср мая  5 16:48:07 MSK 2021] The domain key is here: /home/koala/.acme.sh/*.itdog.info/*.itdog.info.key[Ср мая  5 16:48:07 MSK 2021] Single domain='*.itdog.info'[Ср мая  5 16:48:07 MSK 2021] Getting domain auth token for each domain[Ср мая  5 16:48:09 MSK 2021] Getting webroot for domain='*.itdog.info'[Ср мая  5 16:48:10 MSK 2021] Adding txt value: nCH4tBWCkSVn76301f2SdJqCAzmtXvzQAB_Ag8hURLo for domain:  _acme-challenge.itdog.info[Ср мая  5 16:48:15 MSK 2021] The txt record is added: Success.[Ср мая  5 16:48:15 MSK 2021] Let's check each DNS record now. Sleep 20 seconds first.[Ср мая  5 16:48:36 MSK 2021] You can use '--dnssleep' to disable public dns checks.[Ср мая  5 16:48:36 MSK 2021] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck[Ср мая  5 16:48:36 MSK 2021] Checking itdog.info for _acme-challenge.itdog.info[Ср мая  5 16:48:37 MSK 2021] Domain itdog.info '_acme-challenge.itdog.info' success.[Ср мая  5 16:48:37 MSK 2021] All success, let's return[Ср мая  5 16:48:37 MSK 2021] Verifying: *.itdog.info[Ср мая  5 16:48:41 MSK 2021] Success[Ср мая  5 16:48:41 MSK 2021] Removing DNS records.[Ср мая  5 16:48:41 MSK 2021] Removing txt: nCH4tBWCkSVn76301f2SdJqCAzmtXvzQAB_Ag8hURLo for domain: _acme-challenge.itdog.info[Ср мая  5 16:48:46 MSK 2021] Removed: Success[Ср мая  5 16:48:46 MSK 2021] Verify finished, start to sign.[Ср мая  5 16:48:46 MSK 2021] Lets finalize the order.[Ср мая  5 16:48:46 MSK 2021] Le_OrderFinalize='https://acme-staging-v02.api.letsencrypt.org/acme/finalize/193...'[Ср мая  5 16:48:48 MSK 2021] Downloading cert.[Ср мая  5 16:48:48 MSK 2021] Le_LinkCert='https://acme-staging-v02.api.letsencrypt.org/acme/cert/fa62...'[Ср мая  5 16:48:49 MSK 2021] Cert success.-----BEGIN CERTIFICATE-----certificate-----END CERTIFICATE-----[Ср мая  5 16:48:49 MSK 2021] Your cert is in  /home/koala/.acme.sh/*.itdog.info/*.itdog.info.cer [Ср мая  5 16:48:49 MSK 2021] Your cert key is in  /home/koala/.acme.sh/*.itdog.info/*.itdog.info.key [Ср мая  5 16:48:49 MSK 2021] The intermediate CA cert is in  /home/koala/.acme.sh/*.itdog.info/ca.cer [Ср мая  5 16:48:49 MSK 2021] And the full chain certs is there:  /home/koala/.acme.sh/*.itdog.info/fullchain.cer

В логе прям видно, что acme.sh добавляет TXT запись, ждёт немного, проверяет запись через доверенные DNS сервера, удаляет запись и скачивает сертификаты с ключом.

После первого запуска через API, acme.sh заносит env переменные c доступами к API себе в файл ~/.acme.sh/account.conf и вам не нужно каждый раз их экспортировать.

Отлично, получение автоматизировали, всё вроде классно. Но у этого метода есть свои недостатки:

  • Если никто не написал скрипта для вашего провайдера\сервиса, то нужно либо писать, либо переезжать на другой провайдер

  • А есть ли у вашего провайдера API?

  • Поразмышляем немного об безопасности. Вот у меня в "открытую" лежит полный доступ к редактированию моего домена, если он каким-то образом попадёт в чужие руки, эти руки могут сделать что угодно. Эту проблему можно решить ограничим доступа в API, например по токену можно только добавлять\удалять txt записи _acme-challenge. Есть ли такая возможность у вашего провайдера? Я не встречал такого, наверное есть у какого-нибудь AWS конечно. Обычно уже хорошо если есть API, а токен один и даёт полный доступ

  • У вас несколько доменов на разных провайдерах (сочувствую). Тут конечно можно настроить каждое API и сделать для каждого провайдера отдельный запуск acme.sh со своими переменными, но мне кажется это не очень удобным. Тем более если у одного из них отсутствует API или скрипт

  • Кто-то просто не любит, что бы в DNS постоянно лазил какой-то скрипт и что-то добавлял\удалял

DNS aliase mode

Это модернизированный режим DNS API.

Идея такая: Есть технический домен, через добавления TXT записей на котором мы подтверждаем владение основным доменом. т.е. acme.sh смотрит CNAME запись у основного домена, видит "перенаправление" на технический домен и идёт к нему проверять TXT запись. А дальше всё как в режиме DNS API.

Анимация alias modeАнимация alias mode

Разберём последовательно. Для демонстрации я купил домен tech-domain.club, он выступает в качестве технического домена. В моём примере основной домен itdog.info располагается на namecheap, а техничский tech-domain.club я делегирую на Hetzner DNS, таким образом операции с записями будут производиться через API Hetzner'a.

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

_acme-challenge CNAME _acme-challenge.tech-domain.club

Для провайдера с техническим доменом мы настраиваем доступ к API.

Экспортируем токен Hetzner export HETZNER_Token="TOKEN"

Команда выглядит так (-f и --test опять же для примера)

acme.sh --issue -d *.itdog.info --challenge-alias tech-domain.club --dns dns_hetzner -f --test
Раскрыть
koala@x220:~$ acme.sh --issue -d *.itdog.info -d itdog.info --challenge-alias tech-domain.club --dns dns_hetzner -f --test[Пт мая  7 13:40:11 MSK 2021] Domains have changed.[Пт мая  7 13:40:11 MSK 2021] Using CA: https://acme-v02.api.letsencrypt.org/directory[Пт мая  7 13:40:11 MSK 2021] Multi domain='DNS:*.itdog.info,DNS:itdog.info'[Пт мая  7 13:40:11 MSK 2021] Getting domain auth token for each domain[Пт мая  7 13:40:15 MSK 2021] Getting webroot for domain='*.itdog.info'[Пт мая  7 13:40:15 MSK 2021] Getting webroot for domain='itdog.info'[Пт мая  7 13:40:15 MSK 2021] Adding txt value: Zlrij9n4y5QXfH6yx_PBn45bgmIcT70-JuW2rIUa6lc for domain:  _acme-challenge.tech-domain.club[Пт мая  7 13:40:16 MSK 2021] Adding record[Пт мая  7 13:40:17 MSK 2021] Record added, OK[Пт мая  7 13:40:20 MSK 2021] The txt record is added: Success.[Пт мая  7 13:40:20 MSK 2021] Let's check each DNS record now. Sleep 20 seconds first.[Пт мая  7 13:40:41 MSK 2021] You can use '--dnssleep' to disable public dns checks.[Пт мая  7 13:40:41 MSK 2021] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck[Пт мая  7 13:40:41 MSK 2021] Checking itdog.info for _acme-challenge.tech-domain.club[Пт мая  7 13:40:42 MSK 2021] Domain itdog.info '_acme-challenge.tech-domain.club' success.[Пт мая  7 13:40:42 MSK 2021] All success, let's return[Пт мая  7 13:40:42 MSK 2021] *.itdog.info is already verified, skip dns-01.[Пт мая  7 13:40:42 MSK 2021] Verifying: itdog.info[Пт мая  7 13:40:46 MSK 2021] Success[Пт мая  7 13:40:46 MSK 2021] Removing DNS records.[Пт мая  7 13:40:46 MSK 2021] Removing txt: Zlrij9n4y5QXfH6yx_PBn45bgmIcT70-JuW2rIUa6lc for domain: _acme-challenge.tech-domain.club[Пт мая  7 13:40:50 MSK 2021] Record deleted[Пт мая  7 13:40:50 MSK 2021] Removed: Success[Пт мая  7 13:40:50 MSK 2021] Verify finished, start to sign.[Пт мая  7 13:40:50 MSK 2021] Lets finalize the order.[Пт мая  7 13:40:50 MSK 2021] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/121...'[Пт мая  7 13:40:52 MSK 2021] Downloading cert.[Пт мая  7 13:40:52 MSK 2021] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/04e...'[Пт мая  7 13:40:53 MSK 2021] Cert success.-----BEGIN CERTIFICATE-----certificate-----END CERTIFICATE-----[Пт мая  7 13:40:53 MSK 2021] Your cert is in  /home/koala/.acme.sh/*.itdog.info/*.itdog.info.cer [Пт мая  7 13:40:53 MSK 2021] Your cert key is in  /home/koala/.acme.sh/*.itdog.info/*.itdog.info.key [Пт мая  7 13:40:53 MSK 2021] The intermediate CA cert is in  /home/koala/.acme.sh/*.itdog.info/ca.cer [Пт мая  7 13:40:53 MSK 2021] And the full chain certs is there:  /home/koala/.acme.sh/*.itdog.info/fullchain.cer 

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

Кстати, если вам нужно в одном файле иметь несколько сертификатов, например и itdog.info и wildcard *.itdog.info, то просто перечислите их с -d, например

acme.sh --issue --challenge-alias tech-domain.club --dns hetzner -d *.itdog.info -d itdog.info

Это правило действует и для других методов.

И так, что даёт нам этот режим:

  • Если у вашего провайдера нет API или лень писать скрипт, возьмите технический домен, делегируйте его на сервис, который поддерживает acme.sh

  • Если у вашего провайдера нет настройки прав для доступа через API, то технический домен тоже выручает. В случае, если наш token утечёт, у злоумышленника будет доступ только к вашему техническому домену, и если вы его используете только для acme.sh, то максимум что сможет сделать злоумышленник - получить ключ и сертификат для вашего домена. Это тоже неприятно и можно использовать, но это совершенно другой уровень угрозы, по сравнению с полным доступом к доменной зоне

  • В ситуации с кучей доменов на одном или нескольких провайдерах, жизнь так же становится проще, когда все они просто имеют CNAME запись

Есть так же режим domain-alias, он даёт возможность использовать не _acme-challenge запись, а кастомную, подробности можно прочитать в документации

Автоматизация получения и распространения сертификатов

Мы получили сертификаты, лежат они у нас красиво в ~/.acme.sh и никак не используются. Надо каким-то образом их распространять на сервера. Далее расскажу, как я это делаю с помощью ansible. Ansible используется и для получения\обновления и для распространения. Сразу предупреждаю, мои плейбуки простые как три копейки и заточены под определенную инфраструктуру. Playbooks, hosts на github.

Мой сервер с ansible, уже имеет доступ ко всем необходимым серверам, на нём установлен acme.sh и реализовано два плейбука, на получение и распространение. Кстати, не забудьте закомментировать acme.sh в crontab, что бы не было лишних запросов и путаницы.

Playbook для получения сертификатов

В vars указывается только технический домен, эта переменная используется несколько раз. Токен от API вынесен в отдельный vars файл, что бы хранить его в зашифрованном виде в git. Task "Date and time" нужен для логирования, что бы понимать когда именно что-то пошло не так. Следующие два плейбука это простой shell, отличаются друг от друга количеством доменов в одном файле сертификата. Всем доменам, которым не нужно сочетать в себе обычный и wildcard домен, идут списком в loop.

Домены, которые должны подходить как для обычного, так и для wildcard идут по втором taks, тоже с помощью loop. Если вам нужно например wilcard вида *.*.itdog.info, то просто добавьте ещё один -d и ещё один subkey в item. Опция ignore_errors необходима, потому что exit code 0 будет только 6 раз за год при обновлении сертификата, в остальное время будут сообщения о том, что сертификат не нужно обновлять, для ansible это ошибка на которой он будет останавливаться.

Для чего плейбук на получение? Ведь в acme.sh и так уже всё настроено!

В одном плейбуке мы собираем всю нашу конфигурацию, доступы и все домены, которым необходим TLS, как минимум, это удобно - не надо копаться конфигах acme.sh. В случае изменения, например, токена, мы просто редактируем его в vars_files, а если нужно добавить ещё один домен\подомен, мы просто добавляем его в loop. Ну и в случае переноса сервера, не нужно переносить ~/.acme.sh, только плейбуки с vars_files взять из git.

Playbook для распространения сертификатов

Здесь нужно писать конечно под вашу инфраструктуру, поэтому повторюсь, показываю это для примера.

Три типа серверов из моей инфраструктуры:

  • tls-hosts - Обычный nginx установленный как пакет из стандартного репозитория

  • tls-hosts-docker - Веб проект с тем же nginx, но уже в docker

  • tls-hosts-docker-rename - Сторонний продукт, в который надо подкладывать сертификат и ключ с определённым именем в определённую директорию (например Harbor, Zabbix)

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

Во втором случае всё плюс-минус так же, но уже нужно сделать docker exec project-nginx -s reolad, т.е. уже другой handler.

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

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

nginx.itdog.info tls_path=/etc/letsencrypt/*.itdog.info/ DOMAIN=*.itdog.info

Для случаев, когда доменов на сервере несколько, делается два хоста с разными именами и одинаковым ansible_host (Совет, как сделать лучше, приветствуется).

nginx.example.com-1 ansible_host=nginx.example.com tls_path=/etc/letsencrypt/*.example.com/ DOMAIN=example.comnginx.example.com-2 ansible_host=nginx.example.com tls_path=/etc/letsencrypt/*.example.org/ DOMAIN=example.org

Для каждого типа серверов создана своя группа в hosts. Для каждой группы свои немного отличающиеся друг от друга tasks. Для tls-hosts-docker так же добавлена переменная с именем контейнера nginx. А для tls-hosts-docker-rename добавлена переменная, в которой задаётся конечное имя сертификата и ключа.

docker-zabbix.itdog.info tls_path=/root/docker-zabbix/zbx_env/etc/ssl/nginx/ DOMAIN=*.itdog.info CONTAINER=docker-zabbix_zabbix-web-nginx-pgsql_1 cert_name=ssl.crt key_name=ssl.key

Для nginx нужен fullchain и domain.key - копируются только они. Если файлы различаются, происходит копирование и срабатывает handler nginx -s reload. Так же есть проверка, перед тем как зарелоудить nginx, что это файл. У меня один раз был случай, в самом начале пользования acme.sh, скрипт вместо файла с сертификатом создал директорию. Прямо как traefik 1.7 создаёт acme.json директорию, вместо файла. Поэтому я сделал простую проверку. В идеале нужно делать проверку, что сертификат валидный и не просроченный, но для этого требуется иметь на каждом хосте python-pyOpenSSL.

Crontab

23 3 * * * /usr/bin/ansible-playbook /etc/ansible/playbook-get-tls.yml -v >> /var/log/get-tls.log23 4 * * * /usr/bin/ansible-playbook /etc/ansible/playbook-copy-tls.yml -v >> /var/log/copy-tls.log

Можно без проблем вызывать их каждый день, let's encrypt будет вежливо говорить, что пока не нужно обновляться. А когда придёт срок, сертификаты будут обновлены.

Мониторинг сертификатов

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

Я использую zabbix и скрипт от @selivanov_pavel

Проверим с его помощью мой домен локально

koala@x220 ~/t/acme.sh-test> ./ssl_cert_check.sh expire itdog.info 44341

41 день сертификат на itdog.info будет актуален. Сертификат в let's encrypt обновляется за 30 дней до протухания. А значит, например, если ему осталось жить 10 дней, значит что-то пошло не так и надо идти смотреть.

Темплейт состоит из одного item и одного trigger. Теплейт есть так же на github

ssl_cert_check.sh["expire","{HOST.NAME}","{$TLS_PORT}"]

В item две переменных, первая HOST.NAME берёт имя хоста, предполагается что у нас хост назван по доменному имени. Переменная $TLS_PORT по дефолту 443, но если нужно проверять на нестандартном порту, то записываем значение порта в macros.

Триггер тоже супер простой

{Check tls expire:ssl_cert_check.sh["expire","{HOST.NAME}","{$TLS_PORT}"].last()}<=10

Если полученное значение меньше 10ти - аллерт. Таким образом, мы узнаем если у нас начнут протухать сертификаты и будет 10 дней на починку.

Нормально работает?

Да, acme.sh + DNS API + ansible у меня крутится два года. acme.sh + DNS Alias + ansible крутится пол года. Проблемы возникали только, когда при тестировании доменов забыл отключить crontab и он принёс staging сертификат на прод. Такая проблема решается проверкой на валидность.

Да, в идеале, ansible должен проверять перед копированием, что сертификат валидный и не просроченный. А система мониторинга проверять, помимо expire, валидность сертификатов.

Подробнее..

Представляем Windows Terminal Preview 1.9

10.06.2021 10:07:14 | Автор: admin

По следам Microsoft Build 2021 у нашего Windows Terminal второй день рождения! Этот релиз впервые представляет версию 1.9 для Windows Terminal Preview и переносит основной Windows Terminal в версию 1.8. Как всегда, вы можете установить обе сборки в Microsoft Store, а также на странице выпусков GitHub. Под катом расскажем, что нового!

Терминал по умолчанию

Теперь вы можете установить Windows Terminal Preview в качестве эмулятора терминала по умолчанию в Windows! Это означает, что любое приложение командной строки будет запускаться внутри выбранного эмулятора терминала (т.е. дважды щелкните PowerShell, и по умолчанию оно откроется в Windows Terminal Preview). Этот параметр в настоящее время находится в сборке Windows Insider Program Dev Channel и может быть найден на странице свойств консоли. Мы также добавили этот параметр в пользовательский интерфейс настроек в Windows Terminal Preview.

Quake mode

Терминал Windows теперь поддерживает quake mode! Quake Mode позволяет быстро открыть новый экземпляр терминала из любого места в Windows, нажав Win+`. Окно quake появится в верхней половине экрана, и его можно легко закрыть с помощью того же сочетания клавиш. Если вы хотите дополнительно настроить способ вызова терминала, ознакомьтесь с новыми функциями, которые мы добавили для на нашем сайте документации.

Обновления шрифта Cascadia Code

Cascadia Code Italic

У Cascadia Code теперь есть курсивный вариант. Этот вариант по умолчанию используется в терминале, а также может быть загружен с GitHub. Версии шрифтов, в названии которых отсутствует Курсив, будут иметь стандартный шрифт без курсивных букв. Огромное спасибо Аарону Беллу за разработку Cascadia Code Italic и Виктории Грабовской за разработку курсивных символов кириллицы!

Арабские и ивритские символы

Мы также добавляем арабские символы и символы иврита в Cascadia Code в середине июня. Они добавляются к существующему набору шрифтов Cascadia Code, но пока не будут иметь курсивного шрифта. Огромное спасибо Мохамаду Дакаку за разработку арабских символов и Лирону Лави Тюркеничу за разработку ивритских символов! Если вы хотите узнать больше о дизайне арабских символов, ознакомьтесь с этим документом.

Обновления UI настроек

Редактируемая страница действий

Теперь вы можете редактировать существующие действия на странице Действия в пользовательском интерфейсе настроек. Это значительно упрощает настройку сочетаний клавиш, которые вы хотите использовать в Windows Terminal.

Добавление нового профиля

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

Окно предварительного просмотра внешнего вида профиля

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

Подробнее..

ISPmanager 6. Что нового?

10.06.2021 20:10:36 | Автор: admin

Обзор версии ISPmanager 6


О панели ISPmanager, ее достоинствах и возможностях, кажется, знают все это одно из самых популярных решений для управления VPS и серверами на базе Linux.

Казалось бы, ну что еще добавить? Всё уже давно сказано. Но недавно разработчики из ISPsystem представили новую версию ISPmanager 6. Давайте разберемся, какие нововведения можно увидеть в решении уже сейчас и чего нам ждать в будущем.

Что такое ISPmanager?


Сначала поговорим немного о сути сервиса, как он работает.

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

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

Первая версия ISPmanager вышла в 2013 году, и с тех пор продукт активно развивается. За этот период разработчики внесли более 1500 изменений и более чем в пять раз расширили кодовую базу. Команда ISPsystem оперативно подстраивается под новые модули, операционные системы и дополнительные инструменты. ISPmanager 5 начал поддерживать:

  • Ubuntu 18.04 и 20.04,
  • CentOS 8,
  • Stream,
  • Debian 10.

Также подключились сервисы:

  • PHP 7.3 и 7.4,
  • MySQL 8.0,
  • Fail2ban.

ISPmanager улучшает и качество шифрования: теперь пользователи могут работать через Lets Encrypt ACME v2 и DNSSEC; появились новые протоколы: HTTP 2.0 и преобразователь NAT.

ISPsystem работает и над улучшением интерфейса. Сегодня графический интерфейс ISPmanager выглядит современно и удобно.

Возможности ISPmanager


На данный момент ISPmanager предлагает:

  • неограниченное количество пользователей в любом тарифном плане;
  • установка прав доступа;
  • полный контроль над доменами: интеграция CMS, работа с редиректами, SSL-сертификатами и прочими техническими моментами;
  • редактирование и управление DNS;
  • работа с почтовыми системами;
  • создание и администрирование баз данных;
  • подключение пользователей по FTP к определенным директориям;
  • файрвол;
  • резервное копирование;
  • полная статистика;
  • разделение пользователей по правам доступа.

Конечно, это не весь список возможностей ISPmanager. В нем немало дополнительных параметров и настроек, которые подробно описаны в официальной документации.

Итак, пришло время рассказать о новой версии продукта ISPmanager 6.

Главные изменения в ISPmanager 6


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

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

  • Lite. Минимальная версия ограничивает количество сайтов до десяти. Остальные функции остались такими же, как и в ISPmanager 5.
  • Pro. Единственное отличие от Lite количество сайтов равняется 50.
  • Host. Пользователь может создавать неограниченное количество сайтов с такой же функциональностью, как и в предыдущих версиях.
  • Business. Самый продвинутый тариф со множеством дополнительных инструментов, таких как Cloudlinux (планируется добавление в Host), управление реселлерами, IP-адресами и так далее.

Пользователи, которые привыкли к старой панели, используют собственные модули или управляют множеством сайтов одновременно, не будут насильно перебрасываться на новую версию. Переход будет постепенным и бесшовным, а предыдущие наработки продолжат функционировать. Служба поддержки продолжит работу с пользователями старых версий до конца 2021 года.

Ближайшие обновления


Хотя на данный момент кажется, что главные изменения только в тарифной системе, до конца 2021 года разработчики добавят множество новых инструментов, которых не было в ISPmanager 5.

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

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

Многие сервисы работают с Telegram, и ISPmanager 6 не исключение. В будущем оповещения о состоянии системы будут приходить прямо в мессенджер.

Ко всему прочему постепенно интегрируются:

  • Python (Django);
  • node.js;
  • OpenVPN;
  • GIT;
  • Lightspeed.

Работаете ли вы с ISPmanager или с другой панелью? Как впечатления?

Подробнее..

Что будет после Docker

12.06.2021 08:11:13 | Автор: admin

Такой мыслью я задался, обдумывая и перечитывая свою статью про Docker для одного внутреннего корпблога. Этот материал -- продолжение этой крайне, крайне субъективной мысли, оформленное во что-то, что может понять и оценить не только я и моя мама-редактор. Это, конечно, не избавляет текст от моих предубеждений, впечатлений от тех или иных технологий, восторга юного, впечатлительного ума от всего нового и блестящего. Но главное, что кто-нибудь да сможет извлечь из неё что-то своё, описать своё мнение, или сделать свой новый инструментарий для контейнеризации.

Кроме того, отмечу, что у меня нет особых претензий к Docker. Просто хорошая прорывная технология, которая стала стандартом индустрии разработки и администрирования. Как bash или Python у сисадминов. Я постараюсь описывать недостатки докера только при сравнении с другими технологиями, и всё.

Почему вообще должно появиться что-то после Docker?

Окей, насчёт запрета на недостатки Docker я соврал, они будут. Но только пара пунктов -- остальные можете почитать в посте "Исповедь docker хейтера", с которыми я, в принципе, согласен. Так вот.

Отсутствие развития. Я не вижу, чтобы в Docker появлялось что-то принципиально новое в последние пару лет. Может, это из-за не очень понятной финансовой модели и вкладывания ресурсов в не то, чтобы перспективный Swarm. Вы сможете вспомнить хайлайты из последних ченжлогов докера? То-то же.

Спорные и местами даже предвзятые решения разработчиков. Дело в том, что Docker в современном дистрибутиве Linux это система в системе, которая активно перетягивает на себя одеяло остальных инструментов: правила фаерволла в iptables (firewalld? Не, не слышали!), инициализация и жизненный цикл приложений (другими словами, докер стремится стать systemd для контейнеров, то есть это сегодня нечто systemd-like в дистрибутиве Linux, где уже есть systemd? шта?), работа от непривелегированных пользователей (и я не про системную группу docker, через которую можно лезть в чужие контейнеры и хостовую систему вообще!), не очень удобный механизм сборки (Dockerfile, конечно, хорошо, но вы попробуйте построить замысловатый пайплайн с пробросом хостовых томов, например), в общем, список наберётся.

Так что же будет после Docker?

Во-первых, будет новый докер. Перефразирую слова из песни одной музыкальной группы: вначале был докер, в конце будет докер, всё повторяется снова, природа сурова. Вполне вероятно, что докер эволюционирует, что его команда и сообщество решат архитектурные и технические болячки, прикрутят сотню крутых фич, сохраняя при этом дистанцию от кубера, выкинут Docker Swarm и всё станет хорошо. Но это, разумеется, не точно. Честно говоря, я сомневаюсь в таком сценарии.

Во-вторых, будет иной докер. Пример сегодня живёт хорошей жизнью и вполне себе развивается -- Podman. С одной стороны, он создан по образу и подобию Docker: CLI мимикрирует под Docker CLI, есть режим эмуляции Docker API для совместимости с docker-compose, технологии под капотом примерно те же, да и написан он тоже на Go.
Но дальше идут различия: например, Podman построен на стандартах OCI, на которые ориентируются остальные инструменты, вроде Harbor container registry. Когда как Docker позволяет от себе отклоняться от стандартов в различных мелочах, просто потому что докер появился до этих стандартов и имеет право.
Это расхождение в стандарте и реализации иногда порождает проблемы. Так, например, я при работе с Podman столкнулся с тем, что Sonatype Nexus отказывается принимать подмановские docker-образы, и надо было использовать особый параметр, чтобы подман собирал образы с конкретно докеровским форматом, а не стандартом OCI. Так что стандарты -- круто, своя имплементация -- не всегда практично.

В-третьих, будет антидокер. Нет, это не аллюзия на антикафе, только где вы платите деньги за время, которое проводите в контейнере. Да, речь о Kubernetes, который расширяет Docker кучей абстракций, концепций, API и всего причитающегося.

В конце-концов, может, я преувеличил касательно Docker как bash современной разработки, и после Docker будет что-то совершенно иное. Может, это будет Serverless?

Каким мог бы быть совершенный Docker?

Для меня критерии совершенного инструмента для разработки и управления контейнерами следующие:

  • Он должен вбирать в себя всё хорошее, что уже есть в Docker, а именно -- отличные REST API и CLI.

  • В нём должны быть результаты уроков, извлечённые из горького опыта Docker, то есть большинство из того, что сделано в Podman.

  • Он должен быть ещё более тесно интегрирован с дистрибутивом Linux. Не так тесно, как systemd-nspawn, который вообще неотделим от systemd, но всё же.

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

  • Каким-то образом решить архитектурный косяк с dangling images. Типа, серьёзно, 2021-й год, а мне приходится в кронтабы плейбуков или systemd-таймеры вписывать задачу на docker image prune -f! Это должен делать или сам сервис, то есть самостоятельно маскировать проблему, или это надо решить на уровне дизайна системы работы с образами.

  • Удобная расширяемость через плагины! К сожалению, язык Go не имеет возможности писать расширяемые через классические плагины системы, как умеет Python или Java. Как фанат Kotlin, я нахожу расширяемость через плагины или скрипты (я имею ввиду Kotlin Script) очень клёвой.

У меня на этом всё.

С-спасибо за внимание, в-вы отличная публика (c)

Подробнее..

Перевод Знакомство с PromQL Cheatsheet

13.06.2021 12:23:01 | Автор: admin

Скачать Cheatsheet по запросам PromQL

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

Поскольку Prometheus хранит данные в виде временных рядов (time-series data model), запросы PromQL радикально отличаются от привычного SQL. Понимание, как работать с данными в Prometheus, является ключом к тому, чтобы научиться писать эффективные запросы.

Не забудьте скачать Cheatsheet по запросам PromQL!

Как работают time-series databases

Временные ряды это потоки значений, связанных с меткой времени.

Каждый временной ряд можно идентифицировать по названию метрики и меткам, например:

mongodb_up{}

или

kube_node_labels{cluster="aws-01", label_kubernetes_io_role="master"}

В приведенном выше примере присутствует имя метрики (kube_node_labels) и метки (cluster и label_kubernetes_io_role). На самом деле, метрики тоже являются метками. Приведенный выше запрос можно записать так:

{__name__ = "kube_node_labels", cluster="aws-01", label_kubernetes_io_role="master"}

В Prometheus есть четыре типа метрик:

  • Gauges(Измеритель) значения, которые могут меняться. Например, метрика mongodb_up позволяет узнать, есть ли у exporter соединение с экземпляром MongoDB.

  • Counters(Счетчик) показывают суммарные значения и обычно имеют суффикс _total. Например, http_requests_total.

  • Histogram (Гистограмма) это комбинация различных счетчиков, используется для отслеживания размерных показателей и их продолжительности, таких как длительность запросов.

  • Summary (Сводка)работает как гистограмма, но также рассчитывает квантили.

Знакомство с выборкой данных PromQL

Выбрать данные в PromQL так же просто, как указать метрику, из которой вы хотите получить данные. В этом примере мы будем использовать метрику http_requests_total.

Допустим, мы хотим узнать количество запросов по пути / api на хосте 10.2.0.4. Для этого мы будем использовать метки host и path из этой метрики:

http_requests_total{host="10.2.0.4", path="/api"}

Запрос вернет следующие значения:

name

host

path

status_code

value

http_requests_total

10.2.0.4

/api

200

98

http_requests_total

10.2.0.4

/api

503

20

http_requests_total

10.2.0.4

/api

401

1

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

Это называетсяinstant vector, самое раннее значение для каждого потока на указанный в запросе момент времени. Поскольку семплы берутся в случайное время, Prometheus округляет результаты. Если длительность не указана, то возвращается последнее доступное значение.

Кроме того, вы можете получить instant vector из другого отрезка времени (например, день назад).

Для этого вам нужно добавить offset (смещение), например:

http_requests_total{host="10.2.0.4", path="/api", status_code="200"} offset 1d

Чтобы получить значение метрики в пределах указанного отрезка времени, необходимо указать его в скобках:

http_requests_total{host="10.2.0.4", path="/api"}[10m]

Запрос вернет следующие значения:

name

host

path

status_code

value

http_requests_total

10.2.0.4

/api

200

641309@1614690905.515

641314@1614690965.515

641319@1614691025.502

http_requests_total

10.2.0.5

/api

200

641319@1614690936.628

641324@1614690996.628

641329@1614691056.628

http_requests_total

10.2.0.2

/api

401

368736@1614690901.371

368737@1614690961.372

368738@1614691021.372

Запрос возвращает несколько значений для каждого временного ряда потому, что мы запросили данные за определенный период времени, а каждое значение связано с отметкой времени.

Это называется range vector все значения для каждой серии в пределах указанного временного интервала.

Знакомство с агрегаторами и операторами PromQL

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

Представим, что у нас есть метрика node_cpu_cores с меткой cluster. Мы могли бы, например, суммировать результаты, объединяя их по определенной метке:

sum by (cluster) (node_cpu_cores)

Запрос вернет следующие значения:

cluster

value

foo

100

bar

50

С помощью этого простого запроса мы видим, что имеется 100 ядер ЦП для кластера cluster_foo и 50 для cluster_bar.

Кроме того, мы можем использовать в запросах PromQL арифметические операторы. Например, используя метрику node_memory_MemFree_bytes, которая возвращает объем свободной памяти в байтах, мы могли бы получить это значение в мегабайтах с помощью оператора деления:

node_memory_MemFree_bytes / (1024 * 1024)

Мы также можем получить процент доступной свободной памяти, сравнив предыдущую метрику с node_memory_MemTotal_bytes, которая возвращает общий объем памяти, доступной на узле:

(node_memory_MemFree_bytes / node_memory_MemTotal_bytes) * 100

Теперь мы можем использовать этот запрос для создания оповещения, когда на узле остается менее 5% свободной памяти:

(node_memory_MemFree_bytes / node_memory_MemTotal_bytes) * 100 < 5

Знакомство с функциями PromQL

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

topk(2, (node_memory_MemFree_bytes / node_memory_MemTotal_bytes) * 100)

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

Представьте, что вы хотите узнать, сколько свободного места будет доступно на диске в следующие 24 часа. Вы можете применить функцию pred_linear к результатам за прошлую неделю из метрики node_filesystem_free_bytes, которая возвращает доступное свободное место на диске. Это позволяет прогнозировать объем свободного дискового пространства в гигабайтах в ближайшие 24 часа:

predict_linear(node_filesystem_free_bytes[1w], 3600 * 24) / (1024 * 1024 * 1024) < 100

При работе со счетчиками Prometheus удобно использовать функцию rate. Она вычисляет среднюю скорость увеличения временного ряда в векторе диапазона в секунду, сбросы счетчика автоматически корректируются. Кроме того, вычисление экстраполируется к концам временного диапазона.

Что делать, если нам нужно создать оповещение, которое срабатывает, если мы не получали запрос в течение 10 минут. Мы не можем просто использовать метрику http_requests_total, потому что при сбросе счетчика в течение указанного временного диапазона результаты были бы неточными:

http_requests_total[10m]

name

host

path

status_code

value

http_requests_total

10.2.0.4

/api

200

100@1614690905.515

300@1614690965.515

50@1614691025.502

В приведенном выше примере после сброса счетчика мы получаем отрицательные значения от 300 до 50, поэтому нам недостаточно только этой метрики. Мы можем решить проблему с помощью функции rate. Поскольку он считает сбросы счетчика, результаты фиксируются, как если бы они были такими:

name

host

path

status_code

value

http_requests_total

10.2.0.4

/api

200

100@1614690905.515

300@1614690965.515

350@1614691025.502

rate(http_requests_total[10m])

name

host

path

status_code

value

http_requests_total

10.2.0.4

/api

200

0.83

Независимо от сбросов за последние 10 минут в среднем было 0,83 запроса в секунду. Теперь мы можем настроить оповещение:

rate(http_requests_total[10m]) = 0

Что дальше?

В этой статье мы узнали, как Prometheus хранит данные, рассмотрели примеры запросов PromQL для выборки и агрегирования данных.

Вы можете скачать Cheatsheet по PromQL, чтобы узнать больше об операторах и функциях PromQL. Вы также можете проверить все примеры из статьи и Cheatsheet с нашим сервисом Prometheus playground.

Подробнее..

Категории

Последние комментарии

© 2006-2021, personeltest.ru