Архив метки: Devops

Установка, настройка и работа с Hashicorp Vault

В данной инструкции попробуем охватить как можно больше примеров работы с Hashicorp Vault. Мы выполним установку на системы Linux, настоим сервер, сохраним несколько секретов и попробуем получить доступ к данным секретам из различных систем. В качестве Linux рассмотрим Debian и CentOS 7 и 8.




Подготовка




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




Установка пакетов




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




а) Debian:




apt-get install wget chrony curl apt-transport-https




б) CentOS:




yum install wget chrony curl




* где:







Настройка времени




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




timedatectl set-timezone Europe/Moscow




* полный перечень вариантов можно посмотреть командой timedatectl list-timezones.




Если у нас в сети есть свой сервер синхронизации времени, открываем на редактирование файл настройки chrony.




а) Debian:




vi /etc/chrony/chrony.conf




б) CentOS:




vi /etc/chrony.conf




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




а) в Debian или CentOS 8:




pool dmosk.local
#pool ...




* в нашем примере мы комментируем тот адрес pool, который был в конфигурации и подставляем адрес нашего сервера dmosk.local.




а) в CentOS 7:




server dmosk.local
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst




* в нашем примере мы комментируем адреса server, которые были в конфигурации и подставляем адрес нашего сервера dmosk.local.




Разрешаем автоматический запуск для сервиса синхронизации времени и перезапускаем его.




а) для Debian:




systemctl enable chrony




systemctl restart chrony




б) для CentOS:




systemctl enable chronyd




systemctl restart chronyd




Настройка брандмауэра




Для корректной работы сервиса нам необходимо открыть порт 8200. В зависимости от используемой утилиты управления netfilter мы должны применять разные инструменты.




а) Iptables (как правило, Debian):




iptables -I INPUT -p tcp --dport 8200 -j ACCEPT




Для сохранения правила можно воспользоваться утилитой iptables-persistent:




apt-get install iptables-persistent




netfilter-persistent save




б) Firewalld (как правило, для CentOS):




firewall-cmd --permanent --add-port=8200/tcp




firewall-cmd --reload




Установка и запуск




Программный продукт поддерживает различные варианты установки. Мы рассмотрим установку из репозитория.




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




а) Debian:




curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -




echo "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" > /etc/apt/sources.list.d/hashicorp.list




apt-get update




apt-get install vault




б) CentOS:




wget https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo -O /etc/yum.repos.d/hashicorp.repo




yum install vault




Разрешаем автозапуск службы и если она не запущена, стартуем ее:




systemctl enable vault --now




Установка выполнена. При попытке зайти по адресу https://<IP-адрес сервера Vault>:8200/ мы должны увидеть страницу начальной настройки мастер-ключей.




Идем дальше.




Настройка рабочего окружения




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




Error checking seal status: Get "https://127.0.0.1:8200/v1/sys/seal-status": x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs




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




export VAULT_ADDR=http://127.0.0.1:8200




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




Error checking seal status: Error making API request.

URL: GET http://127.0.0.1:8200/v1/sys/seal-status
Code: 400. Raw Message:

Client sent an HTTP request to an HTTPS server.




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




Для решения проблемы открываем файл:




vi /etc/vault.d/vault.hcl




И снимаем комментарии со следующих строк, а также меняем значение для поля address:




listener "tcp" {
  address = "127.0.0.1:8201"
  tls_disable = 1
}




* так как для https уже используется порт 8200, мы должны поменять предложенный по умолчанию вариант на свой, чтобы не возникало конфликтов при запуске сервиса.




Перезапускаем службу vault:




systemctl restart vault




Обновляем системную переменную VAULT_ADDR:




export VAULT_ADDR=http://127.0.0.1:8201




* обратите внимание, что мы поменяли порт подключения на 8201.




Пробуем вывести на экран статус:




vault status




Мы должны получить что-то на подобие:




Key                Value
---                -----
Seal Type          shamir
Initialized        false
Sealed             true
Total Shares       0
Threshold          0
Unseal Progress    0/0
Unseal Nonce       n/a
Version            1.7.1
Storage Type       file
HA Enabled         false




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




vi /etc/environment




И добавляем:




VAULT_ADDR=http://127.0.0.1:8201




Распечатывание




После установки, сервер Vault находится в запечатанном (sealed) состоянии. То есть, он не знает, как ему расшифровывать секреты, которые будут храниться в базе.




При попытке выполнить любую операцию с хранилищем секретов мы получим ошибку:




* Vault is sealed




Чтобы исправить ситуацию, нужно выполнить инициализацию сервера — мы получим ключи для распечатывания (Unseal Keys). После необходимо ввести эти ключи и можно будет авторизоваться в системе.




Инициализация, распечатывание и вход




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




vault operator init




Команда нам вернет 5 ключей. Любые 3 из них являются ключами для распечатывания сервера (Unseal Key). Также нам будет предоставлен токен для root (Initial Root Token), с помощью которого можно будет войти в систему vault.




И так, распечатаем наш сервер, введя по очереди 3 команды.




Для первого ключа:




vault operator unseal




Для второго: 




vault operator unseal




И третьего: 




vault operator unseal




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




Sealed          false




Это значит, что сервер больше не запечатан и с ним можно работать.




Теперь необходимо залогиниться в систему командой:




vault login




… и ввести ключ root, который мы получили после инициализации.




Мы можем выполнять команды для работы с Hashicorp Vault.




Автоматическое распечатывание




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




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




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




Выполним настройку в несколько шагов.




1. Скрипт.




Создадим каталог для хранения скриптов:




mkdir /scripts




Создадим скрипт:




vi /scripts/unseal.sh




#!/bin/bash
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

sleep 10
vault operator unseal w1SgHSWyXm+7kwmYk4bFX2rBLG5jKxIn01DMkj57071D
vault operator unseal 38s4+FkxKTTANFZgCwEPFOgJIMwTvLca1j36yYPc3gdx
vault operator unseal 4xlpKVwPuNlskydM/qmCmW22x7WZdfuiFu92HGRNOa8o




* где w1SgHSWyXm+7kwmYk4bFX2rBLG5jKxIn01DMkj57071D38s4+FkxKTTANFZgCwEPFOgJIMwTvLca1j36yYPc3gdx и 4xlpKVwPuNlskydM/qmCmW22x7WZdfuiFu92HGRNOa8o — любых 3 токена (из 5 сгенерированных). Обратите внимание, мы задерживаем выполнение скрипта на 10 секунд — на практике, сервис vault может не успеть запуститься, и мы тогда получим ошибку при выполнении команды vault operator unseal.




Разрешаем запуск скрипта на выполнение:




chmod +x /scripts/unseal.sh




Можно, даже, выполнить скрипт:




/scripts/unseal.sh




В итоге, мы распечатаем наш сервер.




2. Автозапуск скрипта при старте системы:




Большинство современных серверных систем работает на основе systemd. Рассмотрим автозапуск с помощью последней.




Создаем юнит:




vi /etc/systemd/system/vault-unseal.service




[Unit]
Description=Vault Auto Unseal Service
After=network.target
After=vault.service

[Service]
Environment="VAULT_ADDR=http://127.0.0.1:8201"
ExecStart=/scripts/unseal.sh
Type=oneshot
RemainAfterExit=no

[Install]
WantedBy=multi-user.target




* в данном примере мы выполняем одну команду при запуске сервиса — запуск скрипта /scripts/unseal.sh. Перед этим мы создаем системную переменную VAULT_ADDR, чтобы при выполнении команд в скрипте система понимала, к какому серверу подключаться.




Перечитаем конфигурацию для systemd:




systemctl daemon-reload




Разрешаем автозапуск созданного сервиса:




systemctl enable vault-unseal




Пробуем перезагрузить сервер — vault должен оказаться распечатанным.




Работа с секретами




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




Для начала дадим разрешение на хранение секретов по пути secret:




vault secrets enable -path=secret/ kv




Мы должны получить ответ:




Success! Enabled the kv secrets engine at: secret/




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




vault kv put secret/hello foo=world




* команда kv взаимодействует с хранилищем Vault. В данном примере мы добавляем пару ключ-значение, соответственно foo-world.




Мы должны получить ответ:




Success! Data written to: secret/hello




Посмотреть содержимое можно командой:




vault kv get secret/hello




На что мы получим:




===== Data =====
Key        Value
---        -----
foo        world




Также можно внести за раз множество значений:




vault kv put secret/hello foo=world excited=yes




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




vault kv list secret




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




vault kv delete secret/hello




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




vault -help




После чего можно будет получить помощь по конкретной команде vault, например:




vault kv -help




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




Версионность и метаданные




Hashicorp Vault поддерживает версионность данных, то есть, мы можем посмотреть определенную версию данных внутри секрета. Однако, по умолчанию, сервис устанавливается с kv версии 1, которая не поддерживает данной операции. При попытке выполнить любую команду, захватывающую версионность, мы получим ошибку:




Metadata not supported on KV Version 1




Для решения необходимо создание механизма kv с поддержкой версии 2. Это делается командой:




vault secrets enable -version=2 kv




Или для ранее созданного пути включаем ведение версионности командой:




vault kv enable-versioning secret/




Теперь занесем 2 раза данные:




vault kv put secret/hello foo=world




vault kv put secret/hello foo=world2




Посмотреть данные определенной версии можно командой:




vault kv get -version=1 secret/hello




В нашем примере мы увидим:




=== Data ===
Key    Value
---    -----
foo    world




* то есть значение, которое вводилось первой командой.




Посмотреть метаданные секрета можно командой:




vault kv metadata get secret/hello




Для удаления определенной версии секрета вводим:




vault kv destroy -versions=1 secret/hello




Динамические секреты




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




Рассмотрим пример настройки динамических секретов для базы данных MariaDB/MySQL.




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




mysql -uroot -p




Создаем учетную запись, под которой будет подключаться vault к СУБД:




> CREATE USER 'vaultuser'@'localhost' IDENTIFIED BY 'vaultpass';




Дадим права созданной учетной записи создавать других пользователей и назначать им права:




> GRANT CREATE USER ON *.* TO 'vaultuser'@'localhost' WITH GRANT OPTION;




Выходим из оболочки SQL:




> exit;




Теперь разрешаем механизм секретов базы данных (database secrets engine):




vault secrets enable database




Мы должны увидеть:




Success! Enabled the database secrets engine at: database/




* также мы можем получить ошибку path is already in use at database/, если данный механизм уже разрешен в нашей системе.




Создадим настройку для подключения к нашей базе:




vault write database/config/test 
 plugin_name=mysql-database-plugin
 connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/"
 allowed_roles="test-role"
 username="vaultuser"
 password="vaultpass"




* предполагается, что:







Создадим роль, по сути, зададим команду для создания временной учетной записи:




vault write database/roles/test-role 
 db_name=test
 creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; GRANT SELECT ON *.* TO '{{name}}'@'%';"
 default_ttl="1h"
 max_ttl="24h"




* где:







И так, теперь давайте создадим пользователя и пароль:




vault read database/creds/test-role




* после ввода команды vault сгенерирует и создаст в базе нового пользователя и пароль.




Мы должны увидеть что-то на подобие:




Key                Value
---                -----
lease_id           database/creds/test-role/JpEmEh2MJV115Lr4S4Lx5UHW
lease_duration     1h
lease_renewable    true
password           7v9jC-XHXJjQ2sicLI42
username           v-test--gVPavnGVr




* Если мы увидим ошибку, на подобие Error 1470: String ‘v-root-test-role-KHWyA2IwdoaUth7c’ is too long for user name (should be no longer than 16) мы столкнулись с ограничением на стороне СУБД (нельзя создавать имя пользователя с длиной более 16 символов). Чтобы решить проблему мы должны пересоздать подключение database/config/test с новым плагином mysql-legacy-database-plugin.




Также для создания пользователя мы можем использовать API запрос:




curl --header "X-Vault-Token: s.e0YKJEOHlpfgQiWqZlzVuUbY" http://127.0.0.1:8201/v1/database/creds/test-role




* где X-Vault-Token — токен с доступом. Для теста можно использовать тот, что был получен для root после инициализации системы.




Теперь давайте проверим, что созданные учетные записи имеют нужный нам доступ. Для начала, под пользователем root можно проверить, что записи созданы:




> SELECT user, host FROM mysql.user;




Мы должны увидеть в списках нужную запись (в нашем примере, v-test—gVPavnGVr).




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




mysql -h192.168.0.15 -u'v-test--gVPavnGVr' -p'7v9jC-XHXJjQ2sicLI42'




* в моем случае из-за доступа %, подключение с localhost было запрещено. Поэтому я проверяю доступ с другого хоста в локальной сети, добавив опцию -h192.168.0.15 (где 192.168.0.15 — сервер с СУБД, доступ к которой предоставлялся через vault).




Мы должны подключиться к базе.




Отменить доступ можно командой:




vault lease revoke database/creds/test-role/JpEmEh2MJV115Lr4S4Lx5UHW




* где database/creds/test-role/JpEmEh2MJV115Lr4S4Lx5UHW — значение lease_id, которое нам вернула система при создании временной учетной записи.




Посмотреть список всех идентификатором можно командой:




vault list sys/leases/lookup/database/creds/test-role




* где test-role — имя созданной нами роли.




Продлить lease_duration или default_ttl (пароль) можно с помощью команды:




vault lease renew database/creds/test-role/JpEmEh2MJV115Lr4S4Lx5UHW




Аутентификация и политики




Hashicorp Vault позволяет управлять доступами с помощью политик и токенов авторизации. Рассмотрим процесс настройки.




Работа с токенами




Для начала научимся управлять токенами. Простая команда для создания нового:




vault token create




Система сгенерирует новый ключ и сделает вывод на экран. 




Также мы можем создать временный токен:




vault token create -period=1h




* на один час.




Посмотреть информацию о токене можно через его аксессор. Сначала получим список аксессоров:




vault list auth/token/accessors




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




vault token lookup -accessor uW9Ajr8VzFiCwHzHWn75qWVe




Войти в систему с помощью токена можно командой:




vault login




После вводим наш токен. Или одной командой:




vault login s.Db9j6Q4TvyFDr3j2aQmXttrX




Посмотреть информацию о токене, под которым мы зарегистрировались в системе, можно командой:




vault token lookup




А данной командой мы создаем пользователя и привязываем его к политике my-policy:




vault token create -policy=my-policy




Если политики нет в системе, то мы получим предупреждение:




WARNING! The following warnings were returned from Vault:

  * Policy "my-policy" does not exist




Нас это не должно заботить — на следующем шаге мы ее создадим.




При необходимости привязать токен к нескольким политикам, перечисляем из в опциях policy:




vault token create -policy=my-policy -policy=my-policy2




Работа с политиками




Выше мы создали токен и привязали его к политике my-policy. Создадим ее:




vault policy write my-policy - << EOF
path "secret/data/foo/*" {
  capabilities = ["read", "create", "update"]
}

path "secret/data/hello/*" {
  capabilities = ["read", "update"]
}

path "secret/data/*" {
  capabilities = ["read"]
}
EOF




* в данной политике мы разрешаем чтение всех секретов в secret. Для ранее созданного секрета secret/hello мы разрешим чтение и обновление записей, а для секрета secret/foo также мы разрешаем создавать записи. Обратите внимание, что на самом деле, данные хранятся в secret/data




Посмотреть список политик можно командой:




vault policy list




Посмотреть информацию о конкретной политике можно командой:




vault policy read my-policy




Проверка политики




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




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




vault token create -policy=my-policy




Зарегистрируемся с нужным нам токеном (который привязан к  проверяемой политике):




vault login




Попробуем сначала создать секрет в ветке secret/foo и в нем указать пару ключ-значение:




vault kv put secret/foo/new foo=world




Команда должна выполниться успешно.




Теперь сделаем то же самое для secret/hello




vault kv put secret/hello/new foo=world




Мы должны получить ошибку




Error writing data to secret/data/hello/new: Error making API request.

URL: PUT http://127.0.0.1:8201/v1/secret/data/hello/new
Code: 403. Errors:

* 1 error occurred:
    * permission denied




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




vault kv put secret/hello/new foo=world




И снова заходим под токеном с ограниченными правами. Пробуем обновить запись:




vault kv put secret/hello/new foo=world2




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




Аутентификация на основе пользователей




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




Разрешаем метод auth по пути userpass:




vault auth enable userpass




Создаем пользователя:




vault write auth/userpass/users/dmosk password="test-pass" policies="my-profile"




* данной командой мы создали пользователя dmosk с паролем test-pass и привязали его к политике my-profile.




Войти в систему можно командой:




vault login -method=userpass username=dmosk




Вводим пароль и попадаем в систему под пользователем dmosk. Можно выполнить тесты, которые мы делали выше.




Одноразовые SSH пароли




Рассмотрим варианты хранения секретов для авторизации по SSH с использованием одноразовых паролей или One-Time SSH Password (OTP).




Настройка на сервере Vault




Разрешаем механизм ssh:




vault secrets enable ssh




Создаем роль для создания одноразового пароля:




vault write ssh/roles/otp_key_role 
 key_type=otp
 default_user=test
 cidr_list=10.0.2.0/24




* в данном примере:







На сервере, пока, все. Переходим к настройке клиента.




Настройка на клиенте




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




  1. Создавать одноразовые пароли на стороне Vault.
  2. Осуществлять проверку подлинности при подключении по SSH.




Данной задачей занимается vault-ssh-helper. Рассмотрим процесс его установки и настройки.




Нам понадобится пакет для распаковки zip-архивов. В зависимости от системы ставим его одной из команд ниже.




а) для Debian / Ubuntu:




apt-get install unzip




б) для CentOS / Red Hat / Fedora:




yum install unzip




Установка vault-ssh-helper выполняется простым копированием бинарника. Переходим на официальный сайт для загрузки и выбираем последнюю версию пакета. На следующей страницы копируем ссылку на нужный вариант архива, в зависимости от архитектуры нашего сервера:







С помощью скопированной ссылки загружаем архив:




wget https://releases.hashicorp.com/vault-ssh-helper/0.2.1/vault-ssh-helper_0.2.1_linux_amd64.zip




 Распаковываем его:




unzip vault-ssh-helper_*.zip -d /usr/bin




Создадим каталог для конфигурационных файлов vault-ssh-helper:




mkdir /etc/vault-ssh-helper




Создадим конфигурационный файл:




vi /etc/vault-ssh-helper/config.hcl




vault_addr = "https://192.168.0.20:8200"
ssh_mount_point = "ssh"
tls_skip_verify = true
allowed_roles = "*"




* где:




  • vault_addr — адрес нашего сервера секретов.
  • ssh_mount_point — путь на стороне Vault, по которому будут храниться секреты. Настраивается при включении механизма SSH.
  • tls_skip_verify — стоит ли пропускать проверку подлинности сертификата. Так как у нас еще не настроен валидный сертификат, устанавливаем значение в true.
  • allowed_roles — на стороне сервера можно создавать разным пользователей от разных ролей. В данной настройке мы можем определить, пользователям с какой ролью будет разрешен вход по SSH.




Открываем конфигурационный файл pamd для sshd:




vi /etc/pam.d/sshd




И в самый верх добавляем:




auth sufficient pam_exec.so quiet expose_authtok log=/tmp/vaultssh.log /usr/bin/vault-ssh-helper -config=/etc/vault-ssh-helper/config.hcl
auth optional pam_unix.so not_set_pass use_first_pass nodelay
...




* в данной конфигурации мы, по-прежнему, сможем авторизоваться под учетными записями, созданными на самом сервере. Если необходимо это отключить, разрешив вход только с OTP, комментируем @include common-auth и меняем sufficient на required.




Наконец, редактируем конфигурационный файл sshd. Открываем его:




vi /etc/ssh/sshd_config




Выставляем следующие значения для опций:




ChallengeResponseAuthentication yes
...
UsePAM yes




* где ChallengeResponseAuthentication разрешает авторизацию с применением интерактивного ввода пароля; UsePAM разрешает использование модуля pam.




Перезапустим сервис ssh:




systemctl restart sshd




Выполняем проверку нашей настройки командой:




vault-ssh-helper -verify-only -config /etc/vault-ssh-helper/config.hcl




Мы должны получить ответ:




2021/05/18 14:07:14 [INFO] using SSH mount point: ssh
2021/05/18 14:07:14 [INFO] using namespace: 
2021/05/18 14:07:14 [INFO] vault-ssh-helper verification successful!




Значит настройка на клиенте выполнена коррекнто.




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




useradd test -m




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




Создаем одноразовый пароль




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




vault write ssh/creds/otp_key_role ip=192.168.0.25




* в данном примере мы создаем одноразовый пароль для компьютера с IP-адресом 192.168.0.25.




Мы должны получить, примерено, такой вывод:




Key                Value
---                -----
lease_id           ssh/creds/otp_key_role/5SYfW5VDZ3qGnaMtPhUEHbNr
lease_duration     768h
lease_renewable    false
ip                 192.168.0.25
key                83a57021-74b0-3ce3-8179-6fb92288c0ce
key_type           otp
port               22
username           test




* мы получили одноразовый пароль 83a57021-74b0-3ce3-8179-6fb92288c0ce.




Пробуем войти в систему:




ssh test@192.168.0.25




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




Настройка SSL




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




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




  • Сертификат должен быть выдан для hostname, по которому мы будем отправлять запросы.
  • Для сертификата мы должны указать альтернативное имя subjectAltName.




И так, создаем каталог для хранения сертификатов:




mkdir /etc/ssl/vault




Проверяем версию openssl:




openssl version




Она должна быть 1.1.1 и выше. В противном случае, необходимо выполнить обновление OpenSSL. Как правило, данное действие требуется только на CentOS 7.




Генерируем сертификат:




openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/vault/cert.pem -keyout /etc/ssl/vault/cert.key -subj "/C=RU/ST=SPb/L=SPb/O=Global Security/OU=IT Department/CN=vault.dmosk.local" -addext "subjectAltName = DNS:vault.dmosk.local"




* в данном примере мы сгенерируем необходимые ключи по пути /etc/ssl/vault; обязательно, нужно поменять значения vault.dmosk.local на имя сервера, который используется у вас.




Если команда вернет ошибку, проверяем, что у нас обновленная версия openssl, которая поддерживает ключ addext.




Теперь откроем конфигурационный файл hashicorp vault:




vi /etc/vault.d/vault.hcl




Приведем секцию HTTPS listener к виду:




# HTTPS listener
listener "tcp" {
  address       = "0.0.0.0:8200"
  tls_cert_file = "/etc/ssl/vault/cert.pem"
  tls_key_file  = "/etc/ssl/vault/cert.key"
}




* необходимо поменять пути до файлов tls_cert_file и tls_key_file.




Перезапускаем сервис:




После перезагрузки сервиса, он станет запечатанным и нам нужно будет снова ввести 3 части ключа (команды vault operator unseal).




systemctl restart vault




Меняем в окружении переменную VAULT_ADDR:




export VAULT_ADDR=https://vault.dmosk.local:8200




* мы указываем протокол https, обращения должны выполняться по доменному имени, для которого мы получили сертификат; также указываем порт 8200.




Выполняем команду:




vault status




Мы должны получить состояние системы. Значит запросы по https работают.




И последнее, снова открываем файл:




vi /etc/environment




И также меняем значение для переменной VAULT_ADDR:




VAULT_ADDR=https://vault.dmosk.local:8200




Запуск в виде контейнера Docker




В инструкции мы рассмотрели установку Hashicorp Vault как пакета. Также мы можем установить данный сервис в виде контейнера Docker из официального образа. Рассмотрим вкратце данный вопрос.




Для начала, необходимо установить в систему Docker. После загружаем образ




docker pull vault




Для запуска vault в режиме сервера вводим:




docker run --cap-add=IPC_LOCK --name vault -d -p 8200:8200 -e 'VAULT_LOCAL_CONFIG={"backend": {"file": {"path": "/vault/file"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h", "listener": {"tcp": {"address": "127.0.0.1:8200", "tls_disable": "true"}}}' vault server




После заходим внутрь контейнера:




docker exec -it vault sh




Задаем системную переменную для подключения к vault по http:




export VAULT_ADDR=http://127.0.0.1:8200




Инициализируем сервер:




vault operator init




… и так далее.




Установка клиента и удаленное подключение




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




Установка клиента ничем не отличается от установки сервера. Только нам не нужно инициализировать систему и запускать ее в качестве сервиса. Операции отличаются в зависимости от установленной операционной системы.




а) для Debian / Ubuntu / Mint:




apt-get install wget apt-transport-https




echo "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" > /etc/apt/sources.list.d/hashicorp.list




apt-get update




apt-get install vault




б) для CentOS / Red Hat / Fedora:




yum install wget




wget https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo -O /etc/yum.repos.d/hashicorp.repo




yum install vault




После чего задаем переменную системного окружения 




export VAULT_ADDR=https://vault.dmosk.local:8200




* обратите внимание, что мы подключаемся уже по https. Имя нашего сервера должно разрешаться в DNS или быть прописано в файле hosts на компьютере управления.




Также, если у нас самоподписанный сертификат, вводим:




export VAULT_SKIP_VERIFY=true




* данная системная переменная указывает системе не проверять валидность сертификата.




Пробуем посмотреть статус удаленного сервера:




vault status




Регистрируемся в системе:




vault login -method=userpass username=dmosk




* в данном примере мы заходим под пользователем dmosk. Также мы можем войти с использованием токена.




Можно выполнять действия согласно разрешениям.




источник: https://www.dmosk.ru/instruktions.php?object=vault-hashicorp



Установка и использование Grafana Loki на Linux

В нашей инструкции мы рассмотрим процесс установки и настройки Grafana Loki в качестве сервера сбора логов. Есть несколько способов ее установки — Helm chart, в качестве контейнера Docker, скачать готовый бинарник или собрать его из исходника. Мы выполним установку из последнего на систему Linux. Также, в качестве примера, мы прочитаем лог веб-сервера nginx и сделаем его вывод в Grafana.




Подготовка




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




Установка пакетов




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




а) на системах Red Hat:




yum install git wget




б) для систем на основе Debian:




apt-get install git wget




Установка Go




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







* по умолчанию, страница предлагает загрузить Go для нашей операционной системы, поэтому, если мы открыли сайт на компьютере Windows, ниже под кнопкой загрузки выбираем Linux.




Воспользовавшись ссылкой, скачиваем архив на наш сервер:




wget https://golang.org/dl/go1.15.6.linux-amd64.tar.gz




* на момент написания инструкции, последняя версия была 1.15.6.




Распаковываем архив в каталог /usr/local:




tar -v -C /usr/local -xzf go*.tar.gz




Открываем файл:




vi /etc/profile




Добавляем в самый низ строку:




export PATH=$PATH:/usr/local/go/bin




Один раз выполняем данную команду:




export PATH=$PATH:/usr/local/go/bin




Проверяем, что go установлен и готов выполнять команды:




go version




Мы должны увидеть версию скачанного пакета.




Настройка безопасности




1. Брандмауэр




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




а) если используем iptables (по умолчанию, в системах на базе Debian):




iptables -I INPUT 1 -p tcp --dport 3100 -j ACCEPT




* данная команда добавит правило на разрешение порта 3100 (на котором, по умолчанию, запускается Grafana Loki).




Для сохранения правил устанавливаем пакет:




apt-get install iptables-persistent




Сохранение правил теперь можно выполнить командой: 




netfilter-persistent save




б) если используем firewalld (по умолчанию, в системах на базе Red Hat):




firewall-cmd --permanent --add-port=3100/tcp




firewall-cmd --reload




* данная команда добавит правило на разрешение порта 3100 (на котором, по умолчанию, запускается Grafana Loki).




2. SELinux




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




setenforce 0




sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config




* первая команда вводится до разового отключения SELinux. Вторая не дает ему запуститься после перезагрузки.




Установка




Установка Grafana Loki сводится к загрузке готового бинарника или исходника с последующей компиляцией. Также мы настроим юнит в systemd для работы приложения в качестве сервиса.




Копирование бинарника и конфигурационного файла




Переходим в каталог:




cd /usr/src/




Загружаем исходные файлы проекта:




git clone https://github.com/grafana/loki




Переходим в каталог loki:




cd loki/




Запускаем компиляцию бинарника:




go build ./cmd/loki




В текущем каталоге появится файл loki — перенесем его в каталог /usr/local/bin:




mv loki /usr/local/bin/




Создадим каталог:




mkdir /etc/loki




… и перенесем в него конфигурационный файл:




mv cmd/loki/loki-local-config.yaml /etc/loki/




В конфиге, который идет в исходнике в качестве рабочего каталога для Grafana Loki используется /tmp — мы это исправим двумя командами:




sed -i 's//tmp/wal//opt/loki/wal/g' /etc/loki/loki-local-config.yaml




* первой командой мы меняем настройку dir для wal (журнала предзаписи). 




sed -i 's//tmp/loki//opt/loki/g' /etc/loki/loki-local-config.yaml




* в данном примере мы заменили путь для storage_configworking_directory и ruler storage на /opt/loki.




Создаем каталог:




mkdir /opt/loki




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




/usr/local/bin/loki -config.file=/etc/loki/loki-local-config.yaml




Открываем браузер и переходим по адресу http://192.168.0.15:3100/metrics, где 192.168.0.15 — IP-адрес нашего сервера Grafana Loki. Мы должны увидеть страницу с метриками:







Значит наш сервис запустился и нормально работает. Можно прервать его работу на сервере комбинацией клавиш Ctrl + С и продолжать настройку.




Автозапуск




Чтобы сервис мог автоматически запускаться при старте системы, добавим его в systemd. 




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




useradd --no-create-home --shell /bin/false loki




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




Делаем владельцем loki бинарник для запуска сервиса:




chown loki:loki /usr/local/bin/loki




Задаем владельца для рабочих каталогов Loki: 




chown -R loki:loki /etc/loki




chown -R loki:loki /opt/loki




Создаем юнит в systemd:




vi /etc/systemd/system/loki.service




[Unit]
Description=Grafana Loki Service
After=network.target

[Service]
User=loki
Group=loki
Type=simple
ExecStart=/usr/local/bin/loki -config.file=/etc/loki/loki-local-config.yaml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target




Перечитываем конфигурацию systemd:




systemctl daemon-reload




Теперь можно разрешить и стартовать наш сервис:




systemctl enable loki --now




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




systemctl status loki




Установка серверной части завершена.




Отправка логов на сервер




В нашем примере мы передадим логи веб-сервера NGINX в нашу Grafana Loki. Для этого переходим на сервер с NGINX и выполним следующие действия.




Установка Promtail




Promtail — агент, который читает и отправляет логи на сервер. Его установка во многом напоминает установку сервера — получаем бинарник и добавляем его в автозагрузку. В нашем примере мы загрузим уже скомпилированный файл для запуска.




Для начала, установим следующие пакеты:




yum install unzip wget




unzip нужен для распаковки архива с бинарником; wget — для скачивания архива.




Загружаем последнюю версию promtail для Linux:




wget https://github.com/grafana/loki/releases/latest/download/promtail-linux-amd64.zip




* в нашем примере загружается бинарник на систему 64-бит. На странице https://github.com/grafana/loki/releases можно скачать файлы для установки под Linux и Windows.




Распаковываем скачанный архив:




unzip promtail-linux-amd64.zip




Переносим бинарник в каталог /usr/local/bin:




mv promtail-linux-amd64 /usr/local/bin/promtail




* обратите внимание, что мы его сразу переименовали в promtail.




Создаем каталог для конфигурационных файлов promtail:




mkdir /etc/promtail




Создаем конфигурационный файл:




vi /etc/promtail/promtail.yaml




server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://192.168.0.15:3100/loki/api/v1/push




* где 9080 — номер порта, на котором будет слушать promtail; 192.168.0.15 — IP-адрес нашего сервера Loki, куда нужно отправлять данные.




Создаем юнит в systemd для promtail:




vi /etc/systemd/system/promtail.service




[Unit]
Description=Promtail Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/promtail -config.file=/etc/promtail/promtail.yaml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target




Перечитываем конфигурацию systemd:




systemctl daemon-reload




Разрешаем запуск сервиса promtail и стартуем его:




systemctl enable promtail --now




Проверяем статус:




systemctl status promtail




На клиенте в настройки брандмауэра добавляем правило на разрешение порта 9080.




а) если используем iptables (Debian, Ubuntu): 




iptables -I INPUT 1 -p tcp --dport 9080 -j ACCEPT




apt-get install iptables-persistent




netfilter-persistent save




б) если используем firewalld (CentOS, Red Hat):




firewall-cmd --permanent --add-port=9080/tcp




firewall-cmd --reload




После установки promtail открываем браузер и переходим на страницу http://192.168.0.25:9080/targets, где 192.168.0.25 — IP-адрес клиентского компьютера с NGINX. Мы должны увидеть страницу:




Веб-страница сервиса Promtail




Promtail работает. Можно приступать к сбору логов.




Настройка сбора логов




Открываем конфигурационный файл promtail:




vi /etc/promtail/promtail.yaml




… и добавляем:




...

scrape_configs:
- job_name: nginx
  static_configs:
  - targets:
      - localhost
    labels:
      job: nginxlogs
      __path__: /var/log/nginx/*log




* где:







Перезапускаем сервис promtail:




systemctl restart promtail




Снова заходим по адресу http://192.168.0.25:9080/targets — мы должны увидеть настроенное нами задание:







Сбор логов настроен.




Настройка Grafana




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




Заходим в веб-интерфейс и переходим в Configuration — Data Sources:







Добавляем новый источник, кликая по Add data source:







Среди списка возможных источников выбираем Loki:







В настройках задаем имя и указываем IP-адрес сервера Loki:







* в нашем примере задается имя Loki и подключение к серверу 192.168.0.15.




Нажимаем на Save & Test:







Если мы увидели сообщение «Data source connected and labels found.»:







… значит подключение выполнено и можно двигаться дальше.




Переходим в раздел Create — Dashboard:







Кликаем по кнопке Add new panel:







В открывшемся окне выбираем в качестве источника данных Loki, затем кликаем по Log labels — выбираем job и nginxlogs:







Мы увидим Unable to graph data (так как логи представляют из себя данные, на основе которых нельзя постоить график) — кликаем по Switch to table view:







Мы должны увидеть строки из логов:







Логи NGINX отображаются в Grafana.




Парсинг лога




Мы увидели логи в графане, но они представленны в неудобном для отбора и фильрации виде. Попробуем это исправить с помощью парсинга логов на стороне promtail.




Открываем файл для редактирования:




vi /etc/promtail/promtail.yaml




Дополним нашу задачу для сбора логов NGINX:




...

scrape_configs:
- job_name: nginx
  static_configs:
  - targets:
      - localhost
    labels:
      job: nginxlogs
      __path__: /var/log/nginx/*log
  pipeline_stages:
    - match:
        selector: '{job="nginxlogs"}'
        stages:
        - regex:
            expression: '^(?P<remote_addr>[w.]+) - (?P<remote_user>[^ ]*) [(?P<time_local>.*)] "(?P<method>[^ ]*) (?P<request>[^ ]*) (?P<protocol>[^ ]*)" (?P<status>[d]+) (?P<body_bytes_sent>[d]+) "(?P<http_referer>[^"]*)" "(?P<http_user_agent>[^"]*)"?'
        - labels:
            remote_addr:
            remote_user:
            time_local:
            method:
            request:
            protocol:
            status:
            body_bytes_sent:
            http_referer:
            http_user_agent:




* обратите внимание, что к имеющейся настройки мы добавили pipeline_stages:







Перезапускаем сервис для promtail:




systemctl restart promtail




Идем в Grafana — в Log labels мы должны увидеть новые критерии для фильтра по тегам:







Пробуем добавить, например, фильтр по статусу ответа веб-сервера:







Источник: https://www.dmosk.ru/instruktions.php?object=grafana-loki



Как работать с Terraform

В данной инструкции мы попробуем разобраться с тем, как работать с Terraform. Мы рассмотрим его установку и базовую настройку, немного синтаксиса и примеры работы с облачным провайдером Яндекс.Облако. Инструкция рассчитана на работу с Linux (Deb и RPM).




Регистрация на хостинге




Для работы с хостинг-провайдером нам заранее понадобятся авторизационные данные и идентификаторы ресурсов. Их мы будем прописывать в сценариях terraform.




Нам нужно зарегистрироваться на сервисе Yandex.Cloud (в нашем примере, мы будем работать, именно, с ним). После этого, нам нужно получить:




1. OAuth-токен. Используется в процедуре аутентификации для получения IAM-токена и нужен нам для прохождения авторизации при подключении terraform. Выдается на 1 год. Получить можно, отправив запрос со страницы документации Яндекс.




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







А справа от него будет идентификатор.




3. Идентификатор каталога. На той же странице контроль панели, ниже облака мы увидим каталог:







Также, справа мы можем скопировать его идентификатор.




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




Установка Terraform




Terraform является клиентом и необходимо выполнить установку на компьютер, с которого планируется управление инфраструктурой. Актуальная инструкция по развертыванию представлена на официальном сайте. На текущий момент клиент может быть установлен из репозитория, с использованием бинарника, собран из исходников, а также с помощью choco на Windows или brew на Mac OS. В нашем примере будут рассмотрены установка на Ubuntu и Rocky Linux из репозитория, а также загрузка бинарника.




Ubuntu (Debian)




Обновляем список пакетов:




apt update




Установим дополнительные пакеты:




apt install gnupg software-properties-common curl




* где:




  • gnupg — программа для шифровки и дешифровки цифровых подписей. Нужна для работы с репозиториями.
  • software-properties-common — утилита для работы с репозиториями.
  • curl — отправка GET, POST и других запросов.




Установим в систему ключ для репозитория:




curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add -




Добавляем репозиторий:




apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"




Обновляем список пакетов, чтобы загрузить списки с нового репозитория:




apt update




Можно устанавливать terraform:




apt install terraform




Rocky Linux




Устанавливаем утилиту для работы с репозиториями:




yum install yum-utils




Добавляем репозиторий:




yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo




Устанавливаем terraform:




yum install terraform




Скачиваем бинарник




Суть данного метода — скачать бинарный файл и перенести его в каталог /usr/local/bin.




Таким же образом устанавливаем terraform на Windows.




Для начала нам понадобятся утилиты unzip и wget. Устанавливаются они по-разному, в зависимости от дистрибутива Linux.




а) Ubuntu / Debian:




apt install unzip wget




б) Rocky Linux:




yum install unzip wget




Переходим к загрузке бинарного файла. Посмотреть ссылку на него можно на странице официального сайта:







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




wget https://releases.hashicorp.com/terraform/1.1.7/terraform_1.1.7_linux_amd64.zip




* в нашем примере будет загружена версия 1.1.7.




Распакуем архив командой:




unzip terraform_*_linux_amd64.zip




Перенесем распакованный бинарник в каталог:




mv terraform /usr/local/bin/




После установки




Убедимся, что terraform работает. Для этого вводим команду:




terraform -version




Мы должны получить что-то на подобие:




Terraform v1.1.7
on linux_amd64




Также рекомендуется установить автоподстановки:




terraform -install-autocomplete




Это позволит нам завершать команды terraform с помощью клавиши Tab.




Теперь создадим каталог, в котором будем работать со сценариями для тераформа:




mkdir -p /opt/terraform/yandex




* в моем примере я решил работать в каталоге /opt/terraform/yandex.




Перейдем в созданный каталог:




cd /opt/terraform/yandex




Мы готовы приступить непосредственно к работе с terraform.




Установка провайдера




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




На сайте Hashicorp можно найти все поддерживаемые провайдеры. Как говорилось выше, мы будем работать с Yandex.Cloud. Рассмотрим подробнее установку провайдера для работы с ним.




В нашем рабочем каталоге создаем первый файл:




vi main.tf




terraform {
  required_version = "= 1.1.7"

  required_providers {
    yandex = {
      source  = "yandex-cloud/yandex"
      version = "= 0.73"
    }
  }
}

provider "yandex" {
  token     = "<OAuth>"
  cloud_id  = "<идентификатор облака>"
  folder_id = "<идентификатор каталога>"
  zone      = "<зона доступности по умолчанию>"
}




* где:




  • terraform required_version — версия клиента terraform, для которого должен запускаться сценарий. Параметр не обязательный, но является правилом хорошего тона и может помочь избежать некоторых ошибок, которые возникнут из-за несовместимости при работе в команде.
  • required_providers version — версия провайдера. Мы можем указать, как в данном примере, необходимость использовать конкретную версию, а можно с помощью знака >= или <= указать не выше или не ниже определенной.
  • token — OAuth-токен для прохождения авторизации. Был нами получен после регистрации на хостинге (описание выше).
  • cloud_id — идентификатор для облака, в котором будут создаваться ресурсы. Также получен был нами заранее.
  • folder_id — идентификатор каталога, который также был получен в начале инструкции.
  • zone — ресурсы, которые хранятся на мощностях Яндекс разделены по зонам. Каждая зона — это определенная географическая локация центра обработки данных. Список доступных зон можно посмотреть на странице Зоны доступности.




Теперь выполним команду:




terraform init




Система загрузит нужные файлы и установит провайдер:




Initializing the backend...

Initializing provider plugins...
- Finding latest version of yandex-cloud/yandex...
- Installing yandex-cloud/yandex v0.73.0...
- Installed yandex-cloud/yandex v0.73.0 (self-signed, key ID E40F590B50BB8E40)
...
Terraform has been successfully initialized!
...




Мы готовы двигаться дальше.




Работа с ресурсами




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




Создание ресурсов




В нашем рабочем каталоге создадим новый файл:




vi infrastructure1.tf




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




data "yandex_compute_image" "ubuntu_image" {
  family = "ubuntu-2004-lts"
}

resource "yandex_compute_instance" "vm-test1" {
  name = "test1"

  resources {
    cores  = 2
    memory = 2
  }

  boot_disk {
    initialize_params {
      image_id = data.yandex_compute_image.ubuntu_image.id
    }
  }

  network_interface {
    subnet_id = yandex_vpc_subnet.subnet_terraform.id
    nat       = true
  }

  metadata = {
    user-data = "${file("./meta.yml")}"
  }

}

resource "yandex_vpc_network" "network_terraform" {
  name = "net_terraform"
}

resource "yandex_vpc_subnet" "subnet_terraform" {
  name           = "sub_terraform"
  zone           = "ru-central1-a"
  network_id     = yandex_vpc_network.network_terraform.id
  v4_cidr_blocks = ["192.168.15.0/24"]
}




* где:







** в нашем примере будет создана виртуальная машина с названием test1, 2 CPU, 2 Gb RAM в сети 192.168.15.0/24 на базе Ubuntu 20.04 LTS.
*** обратите внимание, что мы указали идентификатор той подсети для виртуальной машины, которую создали также с помощью нашего сценария terraform.




Создаем файл с метеданными:




meta.yml




#cloud-config
users:
  - name: dmosk
    groups: sudo
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh-authorized-keys:
      - ssh-rsa AAAAB3Nza..................UXFDCb/ujrK4KbpCyvk=




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







Попробуем испытать наш сценарий. Сначала вводим:




terraform plan




Если мы не ошиблись, утилита покажет, что terraform сделает в нашей облачной инфраструктуре. Очень важно внимательно просматривать изменения.




После того, как мы убедимся в корректности действий, применяем настройку:




terraform apply




Мы еще раз увидим, что будет выполнено, а также получим запрос на подтверждение действий — вводим yes:




Enter a value: yes




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




Редактирование данных




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




vi infrastructure1.tf




Внести нужные изменения, например:




  ...
  resources {
    cores  = 4
    memory = 4
  }
  ...




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




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




Error: Changing the `secondary_disk`, `resources`, `platform_id`, `network_acceleration_type` or `network_interfaces` on an instance requires stopping it. To acknowledge this action, please set allow_stopping_for_update = true in your config file.




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




...
resource "yandex_compute_instance" "vm-test1" {
  name = "test1"
  allow_stopping_for_update = true

...




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




Строим план:




terraform plan




Мы должны увидеть, что будет изменено в нашей инфраструктуре. В моем случае:




      ~ resources {
          ~ cores         = 2 -> 4
          ~ memory        = 2 -> 4
            # (2 unchanged attributes hidden)
        }




Применяем настройки:




terraform apply




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




Удаление ресурсов




Для удаления ресурса можно использовать разные приемы.




1. Например, можно указать count = 0:




resource "yandex_compute_instance" "vm-test1" {
  count = 0
  ...




2. Можно закомментировать или удалить строки ресурса из файла tf.




3. Если мы хотим оставить содержимое файлов нетронутым, но при этом удалить все ресурсы, вводим:




terraform destroy




Утилита пройдет по всем файлам tf в директории, найдет ресурсы и выполнит их удаление.




Файл state




Очень важно уметь работать с файлом состояния terraform, а также понять, что это. Данный файл появляется после первого применения сценария в том же рабочем каталоге:




ls




terraform.tfstate




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




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




Из вышесказанного делаем выводы:







Рассмотрим возможность хранения данного файла состояния на облачном хранилище Яндекс.




Сначала мы должны создать хранилище. Это можно сделать через веб-интерфейс, но мы это сделаем в terraform.




Но сначала мы сделаем файл:




vi variables.tf




variable "yandex_folder_id" {
  type        = string
  default     = "<идентификатор каталога>"
}




* где yandex_folder_id — название для нашей переменной; <идентификатор каталога> — тот идентификатор, который мы указали в файле main под аргументом folder_id.




Теперь откроем файл main:




vi main.tf




И отредактируем значение folder_id на:




  ...
  folder_id = var.yandex_folder_id
  ...




* в данном примере мы теперь задаем folder_id не явно, а через созданную переменную.




Теперь создадим файл:




vi yandex_storage_bucket.tf




resource "yandex_iam_service_account" "sa" {
  folder_id = var.yandex_folder_id
  name      = "sa-dmosk"
}

resource "yandex_resourcemanager_folder_iam_member" "sa-editor" {
  folder_id = var.yandex_folder_id
  role      = "storage.editor"
  member    = "serviceAccount:${yandex_iam_service_account.sa.id}"
}

resource "yandex_iam_service_account_static_access_key" "sa-static-key" {
  service_account_id = yandex_iam_service_account.sa.id
  description        = "Static access key for object storage"
}

resource "yandex_storage_bucket" "state" {
  bucket     = "tf-state-bucket-dmosk"
  access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key
  secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key
}




* рассмотрим файл немного подробнее:







Создаем еще один файл:




vi outputs.tf




output "access_key" {
  value = yandex_iam_service_account_static_access_key.sa-static-key.access_key
  sensitive = true
}
output "secret_key" {
  value = yandex_iam_service_account_static_access_key.sa-static-key.secret_key
  sensitive = true
}




* это делается для получения значений аргументов access_key и secret_key и сохранения данных значений в файле состояния. Если access_key можно посмотреть в панели Яндекса, то secret_key мы увидеть не можем.




Строим план и применяем настройки:




terraform plan




terraform apply




Заходим в контроль-панель Яндекса и видим, что у нас создалось хранилище. Его мы будем использовать для хранения файлов состояний terraform.




Открываем наш файл main:




vi main.tf




Добавляем:




terraform {
  ...

  backend "s3" {
    endpoint   = "storage.yandexcloud.net"
    bucket     = "tf-state-bucket-dmosk"
    region     = "ru-central1-a"
    key        = "terraform/infrastructure1/terraform.tfstate"
    access_key = "<access_key>"
    secret_key = "<secret_key >"

    skip_region_validation      = true
    skip_credentials_validation = true
  }
}




* в раздел terraform мы добавили инструкцию для хранения файла state. В нашем примере он будет размещен на бакете tf-state-bucket-dmosk по пути terraform/infrastructure1/terraform.tfstate.
** особое внимание обратите на access_key и secret_key. В разделе terraform мы не можем указать переменные, как это делали при создании хранилища. Сами значения можно найти в нашем локальном файле state.




Используем команду:




terraform init




Система снова инициализирует состояние текущего каталога и создаст файл state на удаленном хранилище. Чтобы убедиться, можно зайти в контроль панель, найти наше хранилище, а в нем — файл terraform/infrastructure1/terraform.tfstate.




Реальный пример




Мы развернем 2 веб-сервера и поместим их за Network load balancer.




Для этого мы создадим новый рабочий каталог:




mkdir -p /opt/terraform/yandex-network-load balancer




И перейдем в него:




cd /opt/terraform/yandex-network-load balancer




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




Мы создадим 5 файлов:




  1. main.tf — в нем мы опишем инструкции для init, а именно требования к версии клиента terraform, провайдера.
  2. web-servers.tf — сценарий для создания 2-х веб-серверов.
  3. network-load-balancer.tf — создание Network Load Balancer.
  4. variables.tf — описание переменных.
  5. outputs.tf — вывод значений после отработки terraform на экран и в файл состояния.




1. Создаем файл main.tf:




vi main.tf




terraform {
  required_version = "= 1.1.7"

  required_providers {
    yandex = {
      source  = "yandex-cloud/yandex"
      version = "= 0.73"
    }
  }
}
provider "yandex" {
  token     = "<OAuth>"
  cloud_id  = "<идентификатор облака>"
  folder_id = "<идентификатор каталога>"
  zone      = "<зона доступности по умолчанию>"
}




* это стандартный вариант файла main.tf, который мы разбирали в начале.




2. web-servers.tf:




vi web-servers.tf




data "yandex_compute_image" "lamp" {
  family = "lamp"
}

data "yandex_compute_image" "lemp" {
  family = "lemp"
}

resource "yandex_compute_instance" "vm-test1" {
  name                      = "vm-test1"
  allow_stopping_for_update = true

  resources {
    cores  = 2
    memory = 2
  }

  boot_disk {
    initialize_params {
      image_id = data.yandex_compute_image.lamp.id
    }
  }

  network_interface {
    subnet_id = yandex_vpc_subnet.subnet_terraform.id
    nat       = true
  }

}

resource "yandex_compute_instance" "vm-test2" {
  name                      = "vm-test2"
  allow_stopping_for_update = true

  resources {
    cores  = 2
    memory = 2
  }

  boot_disk {
    initialize_params {
      image_id = data.yandex_compute_image.lemp.id
    }
  }

  network_interface {
    subnet_id = yandex_vpc_subnet.subnet_terraform.id
    nat       = true
  }

}

resource "yandex_vpc_network" "network_terraform" {
  name = "network_terraform"
}

resource "yandex_vpc_subnet" "subnet_terraform" {
  name           = "subnet_terraform"
  zone           = "ru-central1-a"
  network_id     = yandex_vpc_network.network_terraform.id
  v4_cidr_blocks = ["192.168.15.0/24"]
}




* в данном примере мы создадим 2 виртуальные машины — одну с образом lamp (Apache), вторую на lemp (NGINX).




3. network-load-balancer.tf:




vi network-load-balancer.tf




resource "yandex_lb_network_load_balancer" "lb-dmosk" {
  name = "lb-dmosk"

  listener {
    name = "listener-web-servers"
    port = 80
    external_address_spec {
      ip_version = "ipv4"
    }
  }

  attached_target_group {
    target_group_id = yandex_lb_target_group.web-servers.id

    healthcheck {
      name = "http"
      http_options {
        port = 80
        path = "/"
      }
    }
  }
}

resource "yandex_lb_target_group" "web-servers" {
  name = "web-servers-target-group"

  target {
    subnet_id = yandex_vpc_subnet.subnet_terraform.id
    address   = yandex_compute_instance.vm-test1.network_interface.0.ip_address
  }

  target {
    subnet_id = yandex_vpc_subnet.subnet_terraform.id
    address   = yandex_compute_instance.vm-test2.network_interface.0.ip_address
  }
}




* в данном сценарии мы:







4. variables.tf:




vi variables.tf




variable "yandex_folder_id" {
  type        = string
  default     = "<folder_id>"
}




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




5. outputs.tf:




vi outputs.tf




output "lb_ip_address" {
  value = yandex_lb_network_load_balancer.lb-dmosk.*
}




* на самом деле, это не обязательно — информацию о созданном балансировщике можно посмотреть в контроль панели, но для примера мы решили это рассмотреть.




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




Источник: https://www.dmosk.ru/instruktions.php?object=terraform



Шпаргалка по написанию Gitlab Pipelines

В данной инструкции будут рассмотрены небольшие сценарии работы с Gitlab Pipelines. Мы приведем примеры использования наиболее востребованных опций при работе с CI/CD. По мере необходимости, база шаблонов будет пополняться.




Шаблоны




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




1. Минимальный сценарий. Для небольших заданий, состоящих из пары заданий:




stages:
  - build

TASK_NAME:
  stage: build
  script:
    - ./build_script.sh




* где:







2. Стандартный цикл при сборке. Обычно, процесс CI/CD включает следующие шаги:







Для написания такого сценария за основу можно взять шаблон:




stages:
  - build
  - test
  - delivery
  - deploy

build-job:
  stage: build
  script:
    - echo "Start build job"
    - build-script.sh

test-job:
  stage: test
  script:
    - echo "Start test job"
    - test-script.sh

delivery-job:
  stage: delivery
  script:
    - echo "Start delivery job"
    - delivery-script.sh

deploy-job:
  stage: deploy
  script:
    - echo "Start deploy job"
    - deploy-script.sh




Задания




В данном разделе мы рассмотрим опции, которые могут применяться при описании задания. Общий синтаксис:




<TASK_NAME>:
  <OPTION1>: ...
  <OPTION2>: ...




Мы перечислим лишь часто встречаемые опции. Полный список можно найти в официальной документации.




Stage







Опция указывает, к какой стадии относится задание. Например:




stages:
  - build
  - test

TASK_NAME:
  ...
  stage: build

TASK_NAME:
  ...
  stage: test




Сами же стадии описываются в общей директиве stages.




Также есть две стадии, которые не требуют предварительного определения в stages:







Например:




stages:
  - build
  - test

getVersion:
  stage: .pre
  script:
    - VERSION=$(cat VERSION_FILE")
    - echo "VERSION=${VERSION}" > variables.env
  artifacts:
    reports:
      dotenv: variables.env




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




Image







Задаем имя образа, если наше задание выполняется в контейнере docker:




TASK_NAME:
  ...
  image: debian:11




Before_script







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




TASK_NAME:
  ...
  before_script:
    - echo "Run before_script"




Script







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




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




TASK_NAME:
  ...
  script:
    - command1
    - command2




2. Длинные команды, разбитые на несколько строк. Нам может потребоваться выполнить команды в виде скрипта (с операторами сравнения, например). В этом случае будет удобна многострочная запись. Ее можно указать разными способами.




Индикатор | :




TASK_NAME:
  ...
  script:
    - |
      command_line1
      command_line2




* для него каждая новая строка является переходом к новой команде или части оператора. По сути, это близко к логике скрипта shell.




Индикатор > :




TASK_NAME:
  ...
  script:
    - >
      command_line1
      command_line1_continue

      command_line2
      command_line2_continue




* данный индикатор интерпретирует новую команду после пустой строки.




After_script







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




TASK_NAME:
  ...
  script:
    ...
  after_script:
    - command1
    - command2




Artifacts







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




1. Например, так можно указать, какие файлы или каталоги будут артефактами:




TASK_NAME:
  ...
  artifacts:
    paths:
      - ${PKG_NAME}.deb
      - ${PKG_NAME}.rpm
      - *.txt
      - configs/




* в моем примере, в артефакты попадут все файлы, название которых заканчивается на txt, файлы ${PKG_NAME}.deb и ${PKG_NAME}.rpm, а также каталог configs. Где ${PKG_NAME} — переменная (подробнее о переменных ниже).




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




TASK_NAME_2:
  ...
  script:
    - cat *.txt
    - yum -y localinstall ${PKG_NAME}.rpm
    - apt -y install ./${PKG_NAME}.deb




2. Также мы можем передать системные переменные, которые были нами переданы в файл:




TASK_NAME:
  ...
  script:
    - echo -e "VERSION=1.1.1" > variables.env
  ...
  artifacts:
    reports:
      dotenv: variables.env




* в данном примере мы передадим системную переменную VERSION со значением 1.1.1 через файл variables.env.




3. При необходимости, мы можем исключить из списка определенные файлы по названию или маске:




TASK_NAME:
  ...
  artifacts:
    paths:
      ...
    exclude:
      - ./.git/**/*




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




Extends







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




.my_extend:
  stage: build
  variables:
    USERNAME: my_user
  script:
    - extend script

TASK_NAME:
  extends: .my_extend
  variables:
    VERSION: 123
    PASSWORD: my_pwd
  script:
    - task script




И так, в нашем задании TASK_NAME мы используем extends. В результате, задание примет такой вид:




TASK_NAME:
  stage: build
  variables:
    VERSION: 123
    PASSWORD: my_pwd
    USERNAME: my_user
  script:
    - task script




Что произошло:







Environment







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




TASK_NAME:
  ...
  environment:
    RSYNC_PASSWORD: rpass
    EDITOR: vi




Release







Публикует релиз на портале Gitlab для нашего проекта.




TASK_NAME:
  ...
  release:
    name: 'Release $CI_COMMIT_TAG'
    tag_name: '$CI_COMMIT_TAG'
    description: 'Created using the release-cli'
    assets:
      links:
        - name: "myprogram-${VERSION}"
          url: "https://gitlab.com/master.dmosk/project/-/jobs/${CI_JOB_ID}/artifacts/raw/myprogram-${VERSION}.tar.gz"
  rules:
    - if: $CI_COMMIT_TAG




* обратите внимание, что мы применяем правило if (о нем ниже).




Директивы правил и ограничений




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




Rules







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




When





https://docs.gitlab.com/ee/ci/yaml/#when.




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




Needs





https://docs.gitlab.com/ee/ci/yaml/#needs.




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




Правила и условия




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




Rules




Регламентирует различные правила, определенные с помощью:







1. Оператор if. Позволяем проверить условие, например, если переменная равна определенному значению:




TASK_NAME:
  ...
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'




* в данном примере коммит должен быть выполнен в бранче по умолчанию.




2. Изменения затронули определенные файлы. Проверка выполняется с помощью опции changes.




В данном примере, файл script.sql:




TASK_NAME:
  ...
  rules:
    - changes:
        - script.sql




3. Несколько условий. Условий для начала выполнения задания может быть несколько. Рассмотрим несколько примеров.




а) При условии, что коммит выполнен в бранче по умолчанию И изменения затронули файл script.sql:




TASK_NAME:
  ...
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
      changes:
        - script.sql




б) При условии, что коммит выполнен в бранче по умолчанию ИЛИ изменения затронули файл script.sql




TASK_NAME:
  ...
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
    - changes:
        - script.sql




4. Проверка на существование файла. Определяется с помощью exists:




TASK_NAME:
  ...
  rules:
    - exists:
        - script.sql




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




5. Разрешить сбой задания. Задается с помощью allow_failure:




TASK_NAME:
  ...
  rules:
    - allow_failure: true




* в данном примере наш конвейер продолжит работу, если задание TASK_NAME будет выполнено с ошибкой.




6. Определение переменной в зависимости от условия. Для этого используются вместе if и variables:




TASK_NAME:
  ...
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
      variables:
        DEPLOY_VARIABLE: "production"
    - if: '$CI_COMMIT_BRANCH =~ demo'
      variables:
        DEPLOY_VARIABLE: "demo"




When




Определяет условия запуска задания. Возможные значения:







Разберем примеры.




1. Manual:




TASK_NAME:
  ...
  when: manual




* задание не начнет выполняться, пока мы не нажмем кнопку запуска в GitLab CI/CD.




2. Always:




TASK_NAME:
  ...
  when: always




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




3. On_failure:




TASK_NAME:
  ...
  on_failure: always




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




4. Delayed:




TASK_NAME:
  ...
  when: delayed
  start_in: 30 minutes




* запуск задания будет отложен на 30 минут.




5. Never:




TASK_NAME:
  ...
  when: never




* задание не будет выполняться.




6. Использование вместе с if:




TASK_NAME:
  ...
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
      when: manual




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




Needs




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




Рассмотрим примеры.




1. Artifacts. Принимает значение true (по умолчанию) и false. Для запуска задания нужно, чтобы на предыдущих этапах были загружены артефакты. Запись:




TASK_NAME:
  ...
  needs:
    - artifacts: false




… позволяет начать выполнение задания без этого.




2. Job. Позволяет начать выполнение задачи только после завершения другого задания:




TASK_NAME:
  ...
  needs:
    - job: createBuild




* в нашем примере задача начнет выполняться не раньше завершения задачи с названием createBuild.




Переменные




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




Пользовательские переменные




Задаются с помощью директивы variables.




Можно определить глобально для всех заданий:




variables:
  PKG_VER: "1.1.1"




Или для конкретного задания:




TASK_NAME:
  ...
  variables:
    PKG_VER: "1.1.1"




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




  script:
    - echo ${PKG_VER}




Переменные Gitlab




Данный тип переменных поможет нам управлять процессом сборки. Перечислим данные переменные с описанием их свойств:




ПеременнаяОписаниеПример
LOG_LEVELОпределяет уровень журнала. Варианты: debug, info, warn, error, fatal, и panic. Имеет более низкий приоритет, по сравнению с аргументами командной строки —debug, —log-level.LOG_LEVEL: warning
CI_DEBUG_TRACEВключение или отключение ведения журнала отладки. Принимает значения true или false.CI_DEBUG_TRACE: true
CONCURRENTОграничивает количество заданий, которые могут выполняться одновременно.CONCURRENT: 5
GIT_STRATEGYСпособ загрузки файлов из репозитория. Возможны варианты: clone, fetch, и none (не загружать).GIT_STRATEGY: none




Дополнительные параметры




В данном разделе мы рассмотрим различные опции, которые не вошли в другие разделы.




1. Workflow. Позволяем задать общие правила запуска для всего конвейера. Рассмотрим пример с официального сайта:




workflow:
  rules:
    - if: $CI_COMMIT_TITLE =~ /-draft$/
      when: never
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH




В данном примере конвейер:







2. Значения по умолчанию. Задаются в директиве default. Опции с данными значениями будут использоваться во всех заданиях или могут быть переопределены на уровне конкретного задания.




Пример:




default:
  image: centos:7
  tags:
    - ci-test




* мы определили опцию с именем образа (например, образа docker) и тег (теги могут быть необходимы для запуска некоторых runner).




3. Импорт конфигурации из другого файла yml. Может быть полезным, например, для написания общей части сценария, которую мы захотим применять ко всем pipeline или для разделения громоздкого сценария на составные части. Выполняется с помощью опции include. Имеет различные варианты подгрузки файлов. Рассмотрим их подробнее.




а) подключение локального файла (local):




include:
  - local: .gitlab/ci/build.yml




б) коллекции шаблонов (template):




include:
  - template: Custom/.gitlab-ci.yml




* в данном примере мы подключим к нашему сценарию содержимое файла Custom/.gitlab-ci.yml.




в) внешний файл доступный по HTTP (remote):




include:
  - remote: 'https://gitlab.dmosk.ru/main/build.yml'




г) другой проект:




include:
  - project: 'public-project'
    ref: main
    file: 'build.yml'




4. !reference tags. Позволяет описать сценарий и повторно его использовать для разных стадий и задач нашего CI/CD.




Например:




.apt-cache:
  script:
    - apt update
  after_script:
    - apt clean all

install:
  stage: install
  script:
    - !reference [.apt-cache, script]
    - apt install nginx

update:
  stage: update
  script:
    - !reference [.apt-cache, script]
    - apt upgrade
    - !reference [.apt-cache, after_script]




* давайте разберемся, что происходит в нашем примере.







Источник: https://www.dmosk.ru/miniinstruktions.php?mini=gitlab-pipeline



Prometheus + Grafana + Alertmanager в Docker

В данной инструкции мы рассмотрим пример docker-compose файла для организации системы мониторинга на базе Prometheus. Мы получим:




  • Базу данных Prometheus и интерфейс для выполнения PromQL.
  • Визуализацию с помощью Grafana.
  • Сбор метрик через Node Exporter.
  • Мониторинг HTTP с использованием Blackbox.
  • Отправку уведомлений в Telegram с помощью Alertmanager.




Мы будем работать в среде Linux, хотя полученный файл docker-compose можно применять где угодно. Останавливаться подробно на описании docker-compose мы не будем.




Подготовка системы




Подразумевается, что у нас установлен Docker и docker-compose, в противном случае, можно воспользоваться инструкцией Установка Docker на Linux.




Создаем каталоги, где будем создавать наши файлы:




mkdir -p /opt/prometheus_stack/{prometheus,grafana,alertmanager,blackbox}




Создаем файл:




touch /opt/prometheus_stack/docker-compose.yml




Переходим в каталог prometheus_stack:




cd /opt/prometheus_stack




Дальше будем работать относительно него.




Prometheus + Node Exporter




Открываем файл:




vi docker-compose.yml




version: '3.9'

services:

  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus:/etc/prometheus/
    container_name: prometheus
    hostname: prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
    ports:
      - 9090:9090
    restart: unless-stopped
    environment:
      TZ: "Europe/Moscow"
    networks:
      - default

  node-exporter:
    image: prom/node-exporter
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    container_name: exporter
    hostname: exporter
    command:
      - --path.procfs=/host/proc
      - --path.sysfs=/host/sys
      - --collector.filesystem.ignored-mount-points
      - ^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)
    ports:
      - 9100:9100
    restart: unless-stopped
    environment:
      TZ: "Europe/Moscow"
    networks:
      - default

networks:
  default:
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16




* в данном примере мы создаем 2 сервиса — prometheus и node-exporter. Также мы отдельно определили подсеть 172.28.0.0/16, в которой будут находиться наши контейнеры docker.




Создаем конфигурационный файл для prometheus:




vi prometheus/prometheus.yml




scrape_configs:
  - job_name: node
    scrape_interval: 5s
    static_configs:
    - targets: ['node-exporter:9100']




* в данном примере мы прописываем наш node-exporter в качестве таргета.




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




docker-compose up -d




Ждем несколько секунд и можно пробовать подключиться. Открываем браузер и переходим по адресу http://<IP-адрес сервера>:9090 — мы должны увидеть страницу Prometheus:







Переходим по адресу http://<IP-адрес сервера>:9100 — мы должны увидеть страницу Node Exporter:







Мы движемся в правильном направлении. Идем дальше.




Grafana




Добавим к нашему стеку графану.




Открываем файл:




vi docker-compose.yml




Добавляем:




version: '3.9'

services:
  ...
  grafana:
    image: grafana/grafana
    user: root
    depends_on:
      - prometheus
    ports:
      - 3000:3000
    volumes:
      - ./grafana:/var/lib/grafana
      - ./grafana/provisioning/:/etc/grafana/provisioning/
    container_name: grafana
    hostname: grafana
    restart: unless-stopped
    environment:
      TZ: "Europe/Moscow"
    networks:
      - default

...




* по аналогии с другими сервисами, мы добавили сервис для графаны.




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




docker-compose up -d




Открываем браузер и переходим по адресу http://<IP-адрес сервера>:3000 — мы должны увидеть стартовую страницу Grafana.




Для авторизации вводим admin / admin. После система потребует ввести новый пароль.




Настроим связку с Prometheus. Кликаем по иконке Configuration — Data Sources:







Переходим к добавлению источника, нажав по Add data source:







Среди списка источников данных находим и выбираем Prometheus, кликнув по Select:







Задаем параметры для подключения к Prometheus:







Сохраняем настройки, кликнув по Save & Test:







Добавим дашборд для мониторинга с node exporter. Для этого уже есть готовый вариант.




Кликаем по изображению плюса и выбираем Import:







Вводим идентификатор дашборда. Для Node Exporter это 1860:







Кликаем Load — Grafana подгрузит дашборд из своего репозитория — выбираем в разделе Prometheus наш источник данных и кликаем по Import:







Мы увидим страницу с настроенными показателями метрик. Можно пользоваться.




Настройка оповещений с AlertManager




В нашем примере мы настроим отправку уведомлений на телеграм бот. Само оповещение будет выполнять AlertManager, который интегрируется с Prometheus.




Для начала подготовим наш бот телеграм. Создадим нового — для этого открываем телеграм и ищем @my_id_bot:







Приложение покажет наш идентификатор. Записываем — он нам потребуется позже.




Теперь создаем бота. Ищем @BotFather:







Переходим в чат с найденным BotFather и запускаем бота:







Создаем бота, последовательно введя команду /newbot и отвечая на запросы мастера:







* в нашем примере мы создаем бота prometheus_alert с именем учетной записи DmoskPrometheusBot.




Переходим в чат с созданным ботом, кликнув по его названию:







Запускаем бота:







С ботом мы закончили. Переходим к docker.




Открываем наш файл docker-compose:




vi docker-compose.yml




И добавляем:




version: '3.9'
  ...

  alertmanager-bot:
    command:
      - --alertmanager.url=http://alertmanager:9093
      - --log.level=info
      - --store=bolt
      - --bolt.path=/data/bot.db
      - --telegram.admin=573454381
      - --telegram.token=5472129845:AAFTQRdujqIHgWHbbVtfYWQQvzvIN98KBqg
    image: metalmatze/alertmanager-bot:0.4.3
    user: root
    ports:
      - 8080:8080
    container_name: alertmanager-bot
    hostname: alertmanager-bot
    environment:
      TZ: "Europe/Moscow"
    restart: unless-stopped
    volumes:
      - ./data:/data
    networks:
      - default

  alertmanager:
    image: prom/alertmanager:v0.21.0
    user: root
    ports:
      - 127.0.0.1:9093:9093
    volumes:
      - ./alertmanager/:/etc/alertmanager/
    container_name: alertmanager
    hostname: alertmanager
    environment:
      TZ: "Europe/Moscow"
    restart: unless-stopped
    command:
      - '--config.file=/etc/alertmanager/config.yml'
      - '--storage.path=/etc/alertmanager/data'
    networks:
      - default

...




* мы добавили два сервиса — alertmanager-bot (телеграм бот для prometheus alertmanager) и alertmanager (система оповещений в prometheus).




Теперь открываем конфигурационный файл для prometheus:




vi prometheus/prometheus.yml




И добавим строки:




...

rule_files:
  - 'alert.rules'

alerting:
  alertmanagers:
  - scheme: http
    static_configs:
    - targets:
      - "alertmanager:9093"




* в данном примере мы указали, что наш сервер мониторинга должен использовать в качестве системы оповещения alertmanager, который доступен по адресу alertmanager:9093. Также мы добавили файл alert.rules с описанием правил оповещения.




Создаем файл с правилами оповещения:




vi prometheus/alert.rules




groups: 
- name: test
  rules:
  - alert: PrometheusTargetMissing
    expr: up == 0
    for: 0m
    labels:
      severity: critical
    annotations:
      summary: "Prometheus target missing (instance {{ $labels.instance }})"
      description: "A Prometheus target has disappeared. An exporter might be crashed. VALUE = {{ $value }}  LABELS: {{ $labels }}"




* в данном примере мы добавили правило, которое будет срабатывать при недоступности узла (node-exporter).




Переходим к конфигурированию alertmanager:




vi alertmanager/config.yml




route:
    receiver: 'alertmanager-bot'

receivers:
- name: 'alertmanager-bot'
  webhook_configs:
  - send_resolved: true
    url: 'http://alertmanager-bot:8080'




* данная конфигурация позволяет отправлять оповещения с помощью webhook на сервис alertmanager-bot:8080 (наш телеграм бот для alertmanager).




Запускаем новые сервисы docker:




docker-compose up -d




Открываем браузер и переходим по адресу http://<IP-адрес сервера>:9090 — на вкладке Alerts мы должны увидеть нашу настройку:







Попробуем проверить работу оповещения. Отключаем наш node exporter:




docker stop exporter




На телеграм должно прийти оповещение:







Отправка уведомлений настроена.




Blackbox exporter




Переходим к настройке мониторинга http сервисов. В нашем примере мы будем проверять работу сайта dmosk.ru.




Открываем наш файл docker-compose:




vi docker-compose.yml




Добавим в него:




version: '3.9'

services:
  ...

  blackbox:
    image: prom/blackbox-exporter
    container_name: blackbox
    hostname: blackbox
    ports:
      - 9115:9115
    restart: unless-stopped
    command:
      - "--config.file=/etc/blackbox/blackbox.yml"
    volumes:
      - ./blackbox:/etc/blackbox
    environment:
      TZ: "Europe/Moscow"
    networks:
      - default

  ...




* сервис blackbox является компонентом Prometheus для мониторинга сетевых сервисов по различным протоколам.




Открываем конфигурационный файл prometheus:




vi prometheus/prometheus.yml




И дописываем:




scrape_configs:
  ...
  - job_name: 'blackbox'
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
        - https://www.dmosk.ru
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox:9115

...




* подобная конфигурация позволит создать дополнительное задание мониторинга сайта https://www.dmosk.ru.




Создаем конфигурационный файл blackbox:




vi blackbox/blackbox.yml




modules:
  http_2xx:
    prober: http
    timeout: 5s
    http:
      valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
      valid_status_codes: [200]
      method: GET
      no_follow_redirects: true
      fail_if_ssl: false
      fail_if_not_ssl: false
      fail_if_body_matches_regexp:
        - "Could not connect to database"
      fail_if_body_not_matches_regexp:
        - "Download the latest version here"
      fail_if_header_matches: # Verifies that no cookies are set
        - header: Set-Cookie
          allow_missing: true
          regexp: '.*'
      fail_if_header_not_matches:
        - header: Access-Control-Allow-Origin
          regexp: '(*|example.com)'
      tls_config:
        insecure_skip_verify: false
      preferred_ip_protocol: "ip4"
      ip_protocol_fallback: false




* во многом, данный пример взят с официальной страницы на Github.




Теперь откроем конфигурационный файл с описанием правил для предупреждений:




vi prometheus/alert.rules




Добавим:




  ...

  - alert: BlackboxSlowProbe
    expr: avg_over_time(probe_duration_seconds[1m]) > 5
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: Blackbox slow probe (instance {{ $labels.instance }})
      description: "Blackbox probe took more than 1s to completen  VALUE = {{ $value }}n  LABELS = {{ $labels }}"

  - alert: BlackboxProbeHttpFailure
    expr: probe_http_status_code <= 199 OR probe_http_status_code >= 400
    for: 0m
    labels:
      severity: critical
    annotations:
      summary: Blackbox probe HTTP failure (instance {{ $labels.instance }})
      description: "HTTP status code is not 200-399n  VALUE = {{ $value }}n  LABELS = {{ $labels }}"




* в данном примере мы создали два правила:




  • BlackboxSlowProbe — предупреждать, если сайт открывается дольше 5 секунд.
  • BlackboxProbeHttpFailure — реагировать, в случае получения кода ответа с ошибкой работы сайта (более 400).




Запускаем добавленный в докер сервис:




docker-compose up -d




Для визуализации мониторинга с помощью blackbox есть готовый дашборд в графане. Снова открываем страницу импорта:







Вводим идентификатор 7587 и выбираем источник (как делали при добавлении дашборда node exporter).




Источник https://www.dmosk.ru/miniinstruktions.php?mini=prometheus-stack-docker#prometheus



2022-10-02T19:55:44
DevOps

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

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




Поэтому команда Kubernetes aaS от Mail.ru обновила и дополнила подборку. Предлагаем вашему вниманию список с почти сотней полезных инструментов, упрощающих жизнь тем, кто работает с Kubernetes.










Инструменты развертывания кластера




1. Keel




Оператор Kubernetes, который автоматизирует обновления DaemonSet, StatefulSet, Helm и Deployment. Одна команда, никаких зависимостей, конфигурационных файлов и блокировок.




2. Kube-prod-runtime




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




3. K3sup




После установки k3sup (произносится как ketchup) вы можете за считанные секунды сгенерировать kubeconfig на любой локальной или удаленной виртуальной машине.







4. Mail.Ru Cloud Solutions: Cloud Containers




На платформе можно развернуть кластеры Kubernetes в виде облачного сервиса: за несколько минут вы получите готовый к работе кластер без необходимости в настройке и обновите его до нужной версии. Также кластеры просто масштабировать — они работают на инфраструктуре Mail.Ru, рассчитанной на высоконагруженные сервисы.







5. Kubeadm




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




6. Kubespray




Набор ролей Ansible для развертывания и конфигурации Kubernetes. Работает на разных облачных платформах: AWS, GCE, Azure, Mail.Ru Cloud Solutions, OpenStack и bare metal IaaS. Это open source проект, построен на kubeadm. Подходит тем, кто хорошо знаком с Ansible — с этим инструментом вам ничего не нужно больше знать, чтобы развернуть все нужные ресурсы. 




7. Conjure-up 




Позволяет развертывать Kubernetes с помощью нескольких команд, поддерживает развертывания на локальном хосте, bare metal, в облачных средах, в том числе OpenStack.




8. Minikube




Хорошее начало для тех, кто только знакомится с Kubernetes. Инструмент позволяет пользователям легко запускать одноузловой кластер локально внутри виртуальной машины на ноутбуке пользователя. Поддерживается в Mac OS X, Windows и Linux.




9. MicroK8s 




Инструмент для пользователей Kubernetes, позволяющий развернуть автономный кластер на сервере Linux, хорошо подходит для Edge и IoT.




10. Bootkube 




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




11. RKE от Rancher




Сертифицированный CNCF дистрибутив Kubernetes, работающий внутри контейнеров. Позволяет упростить и автоматизировать установку Kubernetes, не зависеть от операционной системы и платформы, на которой вы работаете.




Инструменты мониторинга




12. Kube-state-metrics




Простая утилита для прослушивания сервера Kubernetes API, помогает в генерации метрик о состоянии объектов. Фокусируется на работоспособности различных объектов внутри кластера, включая узлы, поды и развертывания.




13. Kubebox




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







14. Rakess




Плагин Rakess (Review Access) показывает все права доступа к кластеру Kubernetes. Конечно, для отдельных ресурсов можно выполнить проверку командой kubectl auth can-i list deployments, но она не дает полную информацию обо всех ресурсах на сервере.




15. Kubetail




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




16. Stern




Еще один инструмент из категории «tail для подов в Kubernetes». Особенности: использование регулярных выражений для удобной фильтрации подов (не нужно знать конкретные ID), аналогично можно фильтровать отдельные контейнеры для запрашиваемых подов, есть стандартные и кастомные Go-шаблоны для выводимых логов, ограничение вывода логов по периоду времени или количеству строк и много чего еще.




17. Prometheus




Не можем снова не упомянуть этот опенсорсный инструмент для мониторинга и уведомлений, который давно стал стандартом для мониторинга Kubernetes. Он интегрирован со всеми популярными языками программирования, помогает создавать собственные метрики и содержит много готовых интеграций с популярными технологиями, например: PostgreSQL, MySQL, ETCD.




С помощью Prometheus Operator можно создавать экземпляры Prometheus в кластерах Kubernetes, в том числе тесную интеграцию с Grafana и Alertmanager.




18. Jaeger




Инструмент трассировки с открытым исходным кодом. Умеет мониторить транзакции и сервисные зависимости в распределенных системах, выявлять и устранять неполадки. Один из способов начать работу с ним в Kubernetes — использовать специальный оператор Jaeger




19. Searchlight




Оператор Kubernetes для Icinga. Умеет запускать периодические проверки на кластерах Kubernetes, а потом отправлять уведомления по электронной почте, СМС или в чат, если что-то идет не так. В инструмент по дефолту включен комплект проверок специально для Kubernetes. С его помощью можно расширить возможности мониторинга Prometheus, также он станет резервной системой, если внутренние системы мониторинга полностью откажут.




20. Kubernetes Operational View (Kube-ops-view)




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







21. Kubewatch 




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




22. Weave Scope 




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







23. Turbonomic/Kubeturbo 




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




Тестирование




24. Kubeval




Инструмент для проверки конфигурационного файла Kubernetes YAML или JSON. Проверка осуществляется с использованием схем, сгенерированных из Kubernetes OpenAPI. Это позволяет производить валидацию схем для разных версий Kubernetes.




25. Helm-kubeval




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




26. BotKube




BotKube может отслеживать, отлаживать и запускать проверки в кластерах Kubernetes. Инструмент также интегрируется в различные платформы для обмена сообщениями, такие как Slack и Mattermost. Преимущества — открытый исходный код и простота настройки.







27. Sonobuoy




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




28. Snyk Container




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







29. Kube-monkey




Следуя принципам хаос-инжиниринг, Kube-monkey случайным образом удалит модули Kubernetes в кластере и проверит разработку отказоустойчивых сервисов.




30. K8s-testsuite 




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




31. PowerfulSeal 




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







Безопасность




32. Harbor




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




33. Kubesec




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




34. Permission-Manager




Это приложение разработки компании SIGHUP позволяет легко управлять ролями доступа для Kubernetes через систему Role-Based Access Control. Создайте пользователей, назначьте пространство имен/разрешения, а также распространите файлы Kubeconfig YAML.







35. Kube-scan




Инструмент от компании Octarine фокусируется на оценке рисков в рабочих нагрузках Kubernetes. Kube-scan запускается как под в кластерах и оценивает 30 параметров безопасности, чтобы вывести максимально приемлемый уровень риска. Затем инструмент анализирует, какие параметры работают в тандеме, чтобы понять, какие комбинации уменьшат уровень угроз.







36. K-rail




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




37. KeyCloak




KeyCloak — опенсорсный инструмент управления доступом и идентификационной информацией пользователей. Он добавляет функцию аутентификации приложений и помогает минимальными усилиями обеспечить безопасность служб. Устраняет необходимость детально разбираться с ведением списка пользователей и их аутентификацией. Всё это теперь работает прямо из коробки.




38. Aquasec




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




С ним связан еще один open source инструмент  — Kube-Bench, проверяющий среду Kubernetes по тестам из документа CIS Kubernetes Benchmark.




39. Tigera




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




40. Klum




Klum, или Kubernetes Lazy User Manager, выполняет простые задачи, такие как создать/удалить/изменить пользователей. Он выдает файлы kubeconfig и управляет ролями юзеров.




41. StrongDM




StrongDM — это плоскость управления для проверки безопасности и доступа к вашим серверам и/или базам данных. Состоит из API аутентификации, прокси-сервера, поддерживающего протокол, и хранилища журналов. 




42. Falco




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




43. Sysdig Secure 




Платформа, обеспечивающая мониторинг безопасности микросервисов и контейнеров. Поддерживаются Kubernetes и Docker. Может быть использована в облаке и локально.




Полезные утилиты




44. Krew




Krew помогает разработчикам находить полезные плагины kubectl для программ и устанавливать, а потом управлять ими. Этот инструмент похож на APTDNF или Homebrew.




45. Ksniff




Плагин для kubectl, который эффективно использует Wireshark и tcpdump для удаленного захвата трафика с любого пода в кластере Kubernetes.







46. Kube-ps1




Скрипт Kube-ps1 добавляет текущий контекст Kubernetes и сконфигурированное пространство имен из kubectl в консоль Bash/Zsh, никаких команд не требуется.




47. Kubefwd




Если вы запускаете службы Kubernetes на удаленном кластере, то Kubefwd поможет перенаправить их на локальную рабочую станцию. Никаких модификаций не требуется: если вы используете kubectl, вы уже соответствуете всем требованиям.







48. Kubeterminal




Это скорее вспомогательный инструмент, который дополняет kubectl и вашу консоль в Kubernetes.







49. Skaffold




Skaffold — консольная утилита, помогающая обеспечить процесс непрерывной разработки приложений Kubernetes. Инструмент очень легкий и не требует компонентов на стороне кластера.




50. Kubectl-aliases




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




51. Kubectx/Kubens




Опенсорсная утилита, дополняет Kubectl, позволяет переключать контекст и подключаться одновременно к нескольким кластерам Kubernetes, а также перемещаться между пространствами имен. Есть поддержка автозаполнения в оболочках bash/zsh/fish.




kubectx помогает переключаться между кластерами вперед и назад:







kubens помогает плавно переключаться между пространствами имен Kubernetes:







52. Kube-shell




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







53. Tilt




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





https://embedd.srv.habr.com/iframe/5f9a63672c0608e1441a4051




54. Kail (Kubernetes Tail)




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




Инструменты разработки




55. Helm 




Пакетный менеджер, помогает управлять приложениями Kubernetes с помощью Helm Charts. Это позволяет пользователям создавать воспроизводимые сборки, которыми можно делиться.




56. Helm-2to3




Этот плагин помогает разработчикам перенести конфигурацию из Helm v2 в Helm v3 с соответствующей очисткой конфигурации.







57. Rook




Rook помогает автоматизировать различные задачи для хранилища данных, такие как развертывание, загрузка, масштабирование, обновление и так далее. Это гарантирует, что на Kubernetes будет стабильно работать решение любого поставщика (Ceph, EdgeFS, CockroachDB, Cassandra, NFS, Yugabyte DB).




58. Contour




Contour — ingress-контроллер Kubernetes, обеспечивает плоскость управления для Ingress и служебного прокси.




59. Shell-operator




Shell Operator упрощает создание операторов Kubernetes. Он обеспечивает интеграцию между событиями кластера Kubernetes и сценариями оболочки. Упрощает управление кластером. 




60. Helm-operator-get-started




Помогает управлять вашими релизами Helm.







61. Helmfile




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




62. Kudo




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




63. Helm-docs




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




64. Telepresence 




Позволяет локально отлаживать службу Kubernetes, упрощая процесс разработки.




65. Kubectl-debug




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




66. Ksync 




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




67. Squash 




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




Конвейер CI/CD




68. Rafay




Rafay — программный инструмент, который упрощает для компании или отдельного разработчика создание собственной платформы, системы автоматизации и управления жизненным циклом приложений. Rafay также способен запускать кластеры Kubernetes.




69. Rancher




Rancher — полноценная программная платформа, которая легко развертывает контейнерные среды, выходящие за рамки инсталляторов Kubernetes, таких как Kops и Kubespray. Предоставляет множество функций, включая управление инфраструктурой, планирование и оркестровку контейнеров, мониторинг, проверку работоспособности, ведение журналов, а также мощную систему управления доступом на основе ролей.




70. Draft




Утилита от разработчиков Helm. Ее цель — упростить приложения, которые разрабатываются для работы в Kubernetes. С помощью двух простых команд вы можете работать с контейнерными приложениями, даже не нуждаясь в установке Docker или Kubernetes.




71. Jenkins




Пожалуй, наиболее популярный open source CI/CD-сервер в мире. К нему есть бесплатный плагин, помогающий развертывать приложения в Kubernetes, обновлять их с минимальным простоем и обеспечивать Green/Blue-развертывание обновлений. 







72. TeamCity




Известный CI/CD сервис от JetBrains. Есть плагин, с которым можно использовать инфраструктуру кластера Kubernetes для запуска билд-агентов TeamCity (в версии 2017.1.x и новее). 




73. Apollo 




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







74. Werf




CLI-инструмент с открытым исходным кодом, написанный на Go, предназначен для упрощения и ускорения доставки приложений. Werf создает образы Docker с использованием Dockerfiles или альтернативного быстрого встроенного компоновщика на основе собственного синтаксиса. Он также удаляет неиспользуемые образы из реестра Docker. Потом Werf развертывает ваше приложение в Kubernetes, используя диаграмму в формате, совместимом с Helm, с удобными настройками и улучшенным механизмом отслеживания развертывания, обнаружения ошибок и вывода журнала.




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




75. Garden




Garden — инструмент для разработчиков, который автоматизирует ваши рабочие процессы и делает разработку и тестирование приложений Kubernetes быстрее и проще. Подходит для совместной разработки в удаленном кластере.







Сервисные сетки




76. Kiali




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




77. Kuma




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







78. Tenkai




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







Обнаружение служб




79. Обнаружение cлужб Vert.X




Репозиторий с множеством инструментов для обнаружения служб, которые видны из ваших приложений с микросервисами. Службы можно импортировать и из Kubernetes (а также из Docker и Consul).




Визуализация и управление




80. Octant




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




81. Kubernetic




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







82. Kubernetes Dashboard




Универсальный веб-интерфейс кластеров Kubernetes. С помощью этой нативной панели управления проще устранять неполадки и мониторить кластеры. 







83. Kubeapps




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





https://embedd.srv.habr.com/iframe/5f9a6367d4323713fd415876




84. Lens




Приложение для рабочего стола, работает в Windows, Mac и Linux. Может подключаться к локальному кластеру K8s, подходит для небольшого количества кластеров.







85. Kubevious




Программное обеспечение с открытым исходным кодом, удобный графический интерфейс. Отображает все конфигурации, относящиеся к приложению, в одном месте. Это экономит время, избавляя от необходимости искать настройки и копаться в селекторах и метках. Один из недостатков инструмента — он работает непосредственно на кластере K8s. Значит, вам придется развертывать Kubevious на каждом кластере, а не просто указывать на существующий.





https://embedd.srv.habr.com/iframe/5f9a6368905dc4e15aeed79b




86. Kubelive




Основанный на терминалах пользовательский интерфейс, использующий Node.js. Довольно прост в использовании, но в настоящее время ограничен несколькими командами kubectl. Позволяет легко перемещаться по различным пространствам имен кластера K8s и быстро отображать состояние заданного набора подов.







87. K9s




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




Инструменты для бессерверных вычислений/функций




88. Kubeless




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




89. Fission




Еще один открытый серверный фреймворк Kubernetes с открытым исходным кодом. Поддерживает все языки программирования. Напишите недолговечные функции на любом языке и сопоставьте их с HTTP-запросами (или другими триггерами событий) — инструмент позволяет развернуть функции мгновенно с помощью одной команды. Нет контейнеров для сборки и нет реестров Docker для управления.







90. Funktion




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




91. IronFunction




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




92. OpenFaaS




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




93. Nuclio




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




94. Virtual-Kubelet




Является открытой реализацией Kubernetes Kubelet. Запускается внутри контейнера в вашем текущем кластере и маскируется под узел. Оттуда он контролирует запланированные пакеты так, как это делает настоящий Kubelet.




На этом всё. Пишите в комментариях, если знаете другие полезные инструменты.




Источник: https://habr.com/ru/company/vk/blog/499676/



2022-08-31T19:40:06
DevOps