В обширном интервью для прессы региона EMEA на прошлой неделе руководитель Intel Пэт Гелсингер ответил на вопросы по многочисленным темам, связанным с производством, продажами и технологиями. «Разжигание подлинной страсти» — вот последний вопрос. Нам интересно, как Intel планирует защититься от продолжающихся масштабных инвестиций в глобальное производство микросхем в период снижения продаж и мрачных перспектив.
Не судите меня по ежеквартальным отчетам
Особое упоминание и гнев были зарезервированы для Уолл-стрит, а Гелсингер прокомментировал реакцию рынка на краткосрочные финансовые результаты. «У вас уходит четыре года, чтобы построить фабрику. Могу ли я принять решение о финансовых перспективах этого квартала относительно того, собираюсь ли я делать четырехлетние инвестиции или нет? Нет!», — ругался босс, в его голосе слышалось разочарование. «[Уолл-стрит] у вас плохой квартал, Intel, можете ли вы продвинуть свои планы капиталовложений на вторую половину десятилетия? Это самый глупый вопрос!
«Вы должны принимать долгосрочные решения. Давайте поместим это в контекст на секунду. Вы не получите ни цента дохода за первые четыре года строительства фабрики при инвестициях в 20 миллиардов долларов. Фабрика не окупается даже в течение еще одного года или 18 месяцев после этого. Ни пенни прибыли до шестого года. Вы не можете принимать эти решения на основе квартальных циклов. Вы должны быть убеждены в своей стратегии и видении, когда смотрите на вторую половину десятилетия».
Подчеркивая масштабы инвестиций, необходимых для передовых фабрик, Гелсингер сослался на общую долю в 30 миллиардов долларов на одном предприятии, включая технологии и инструменты, до того, как предполагаемая прибыль начнет поступать на шестой год. Это чертовски рискованная игра, и Гелсингер не питает иллюзий относительно связанного с этим риска. «Это довольно безумно [имеется в виду 30 миллиардов долларов], как вести такой бизнес? Вам лучше провести его с учетом возможностей спроса во второй половине десятилетия».
И в этом заключается загвоздка. Уолл-Стрит хочет видеть большие цифры уже сейчас, хотя Intel знает, что ее производственное видение принесет плоды, а стратегия IDM 2.0 не окупится в ближайшие годы.
«Теперь ты знаешь мою дилемму. Я раз в квартал разговариваю с аналитиками с Уолл-стрит, которые никогда ничего не запускали, и спрашивают меня о результатах и инвестиционных ставках, которые я делаю», — продолжил глава Intel. Расходящиеся взгляды, которые, если читать между строк, означают, что Гелсингера не слишком беспокоит текущая цена акций Intel в $25,77.
Здание для двойного ТАМ
Так почему же Intel делает большие ставки на будущее производства, если бизнес по изготовлению продукции стоит десятки миллиардов долларов и связан со значительным подразумеваемым риском?
Большинство аналитиков сходятся во мнении, что к концу десятилетия рынок полупроводников вырастет с нынешних 600 миллиардов долларов до более чем триллиона долларов . Долгосрочная производственная стратегия Gelsinger основана на концепции быстрорастущего TAM (общий доступный рынок) в течение следующих нескольких лет, ссылаясь на потребность в огромных, рассчитанных инвестициях сейчас, с должным знанием времени, необходимого для обеспечения полной работоспособности заводов и мощность процветает.
«На планете есть ровно три компании, способные создавать передовые технологические процессы. Я один из них, и я единственный западный», — высказал мнение Гелсингер, не называя TSMC и Samsung в качестве двух других главных героев.
Именно здесь Гелсингер делает ставку на пресловутую ферму, что его стратегия ускорения развития производства путем установки пяти узлов за четыре года может окупиться. «Географическая устойчивость, сбалансированность и коридоры емкости гарантируют, что Intel завоюет множество клиентов-производителей», что еще больше усиливает достоинства стратегии IDM 2.0.
Если вы построите его, они придут
Не говоря уже о том, кого Intel нацелила на крупномасштабное литейное производство в ближайшем будущем, Гелсингер представила, кто есть кто в мире технологий. «Представьте, что вы Криштиану [Амон] в Qualcomm, Дженсен [Хуанг] в Nvidia, Тим [Кук] в Apple; У Intel самые лучшие транзисторы, доступная емкость, поэтому вы можете разработать лучший продукт вместе с Intel».
Г-н Гелсингер выразил уверенность в том, что Intel снова станет мощным производственным центром. «Ты хочешь создать лучший iPhone, Тим? Это становится очень просто, если у меня есть лучшая технология, поэтому очень важно, чтобы мы реализовали стратегию на этих пяти узлах за четыре года».
Понимаемые в этом контексте и связанные с Европой, ошеломляюще огромные инвестиции в Магдебург, Германия, продолжающаяся многомиллиардная экспансия в Ирландии и, по слухам, инвестиции в Вигасио, Италия, являются необходимыми частями этого десятилетнего видения стать лидером литейного производства. в бизнесе на триллион долларов. Легендарная карьера и наследие Гелсингера в Intel будут определяться тем, окупится ли его смелая стратегия.
Сегодня научимся блокировать IP адреса сети TOR с помощью утилиты Fail2Ban.В качестве подопытного Я буду использовать Ubuntu Server 20.04 LTS. Возникла ситуация заблокировать доступ TOR сети к моей внутренней сети и серверу. Для блокировки буду использовать утилиту Fail2Ban.
В данной инструкции попробуем охватить как можно больше примеров работы с Hashicorp Vault. Мы выполним установку на системы Linux, настоим сервер, сохраним несколько секретов и попробуем получить доступ к данным секретам из различных систем. В качестве Linux рассмотрим Debian и CentOS 7 и 8.
Подготовка
Прежде чем начать, приведем наш сервер в готовность. Установим необходимые пакеты, настроим время и систему безопасности.
Установка пакетов
Нам понадобятся некоторые утилиты. Команды для их установки зависят от используемой системы.
* в нашем примере мы комментируем адреса 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.
Разрешаем автозапуск службы и если она не запущена, стартуем ее:
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:
* так как для 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 ключей необходимо выдать пяти ответственным за безопасность сотрудникам. После перезагрузки, трое из них должны будут ввести свои данные. Это правильно с точки зрения безопасности.
Однако, если у нас есть причины автоматически поднимать сервер после перезагрузки, рассмотрим, как это сделать.
Данный способ противоречит безопасности, однако, реальная эксплуатация систем не всегда вписывается в рамки идеальных концепций.
* где w1SgHSWyXm+7kwmYk4bFX2rBLG5jKxIn01DMkj57071D, 38s4+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
* в данном примере мы выполняем одну команду при запуске сервиса — запуск скрипта /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/, если данный механизм уже разрешен в нашей системе.
test — имя базы, для которой vault сможет создать временную учетную запись.
plugin_name — имя плагина для создания учетной записи. Важный параметр, который должен правильно быть подобран в зависимости от версии СУБД. Ниже будет комментарий, с какой ошибкой мы можем столкнуться, выбрав неправильный плагин.
test-role — роль, которая будет использоваться vault (ее создадим ниже).
vaultuser — пользователь, под которым мы подключаемся к СУБД (создали выше).
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"
* где:
db_name — имя базы данных, для которой мы будем создавать пользователя.
creation_statements — команды SQL для создания нового пользователя. {{name}} и {{password}} являются специальными переменными, вместо которых vault подставит сгенерированные значения. Обратите внимание, что в данном примере создается пользователь с правами подключения с любого хоста, однако, в зависимости от версии MariaDB, именно с локального хоста подключиться под данным пользователем будет нельзя. При такое необходимости, меняем % на localhost.
default_ttl — время, в течение которого будет действовать пароль.
max_ttl — время, в течение которого пользователю можно будет обновлять пароль.
И так, теперь давайте создадим пользователя и пароль:
vault read database/creds/test-role
* после ввода команды vault сгенерирует и создаст в базе нового пользователя и пароль.
* Если мы увидим ошибку, на подобие 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 запрос:
* где 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).
* в данной политике мы разрешаем чтение всех секретов в 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 мы можем создать пользователя с паролем и привязать к нему политику. Администратор сможем входить в систему под учетной записью, а не с помощью токена.
cidr_list — подсеть, для которой будет разрешен доступ. Это должна быть подсеть компьютеров, на которых мы будем проходить аутентификацию по одноразовому паролю.
На сервере, пока, все. Переходим к настройке клиента.
Настройка на клиенте
На клиенте необходимо выполнить настройку, которая позволит выполнять две задачи:
Создавать одноразовые пароли на стороне Vault.
Осуществлять проверку подлинности при подключении по SSH.
Данной задачей занимается vault-ssh-helper. Рассмотрим процесс его установки и настройки.
Нам понадобится пакет для распаковки zip-архивов. В зависимости от системы ставим его одной из команд ниже.
а) для Debian / Ubuntu:
apt-get install unzip
б) для CentOS / Red Hat / Fedora:
yum install unzip
Установка vault-ssh-helper выполняется простым копированием бинарника. Переходим на официальный сайт для загрузки и выбираем последнюю версию пакета. На следующей страницы копируем ссылку на нужный вариант архива, в зависимости от архитектуры нашего сервера:
ssh_mount_point — путь на стороне Vault, по которому будут храниться секреты. Настраивается при включении механизма SSH.
tls_skip_verify — стоит ли пропускать проверку подлинности сертификата. Так как у нас еще не настроен валидный сертификат, устанавливаем значение в true.
allowed_roles — на стороне сервера можно создавать разным пользователей от разных ролей. В данной настройке мы можем определить, пользователям с какой ролью будет разрешен вход по SSH.
* в данной конфигурации мы, по-прежнему, сможем авторизоваться под учетными записями, созданными на самом сервере. Если необходимо это отключить, разрешив вход только с OTP, комментируем @include common-auth и меняем sufficient на required.
Наконец, редактируем конфигурационный файл sshd. Открываем его:
* в данном примере мы создаем одноразовый пароль для компьютера с 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.
* в данном примере мы сгенерируем необходимые ключи по пути /etc/ssl/vault; обязательно, нужно поменять значения vault.dmosk.local на имя сервера, который используется у вас.
Если команда вернет ошибку, проверяем, что у нас обновленная версия openssl, которая поддерживает ключ addext.
Теперь откроем конфигурационный файл hashicorp vault:
* необходимо поменять пути до файлов 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 из официального образа. Рассмотрим вкратце данный вопрос.
Задаем системную переменную для подключения к vault по http:
export VAULT_ADDR=http://127.0.0.1:8200
Инициализируем сервер:
vault operator init
… и так далее.
Установка клиента и удаленное подключение
Мы можем управлять нашим сервером с удаленного компьютера из командной строки. Для этого необходимо установить клиента и настроить системное окружение.
Установка клиента ничем не отличается от установки сервера. Только нам не нужно инициализировать систему и запускать ее в качестве сервиса. Операции отличаются в зависимости от установленной операционной системы.
* обратите внимание, что мы подключаемся уже по https. Имя нашего сервера должно разрешаться в DNS или быть прописано в файле hosts на компьютере управления.
Также, если у нас самоподписанный сертификат, вводим:
export VAULT_SKIP_VERIFY=true
* данная системная переменная указывает системе не проверять валидность сертификата.
Пробуем посмотреть статус удаленного сервера:
vault status
Регистрируемся в системе:
vault login -method=userpass username=dmosk
* в данном примере мы заходим под пользователем dmosk. Также мы можем войти с использованием токена.
В нашей инструкции мы рассмотрим процесс установки и настройки 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.
Воспользовавшись ссылкой, скачиваем архив на наш сервер:
* на момент написания инструкции, последняя версия была 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_config, working_directory и ruler storage на /opt/loki.
Открываем браузер и переходим по адресу 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
Проверить, что он запустился и работает можно командой:
systemctl status loki
Установка серверной части завершена.
Отправка логов на сервер
В нашем примере мы передадим логи веб-сервера NGINX в нашу Grafana Loki. Для этого переходим на сервер с NGINX и выполним следующие действия.
Установка Promtail
Promtail — агент, который читает и отправляет логи на сервер. Его установка во многом напоминает установку сервера — получаем бинарник и добавляем его в автозагрузку. В нашем примере мы загрузим уже скомпилированный файл для запуска.
Для начала, установим следующие пакеты:
yum install unzip wget
* unzip нужен для распаковки архива с бинарником; wget — для скачивания архива.
* в нашем примере загружается бинарник на систему 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:
На клиенте в настройки брандмауэра добавляем правило на разрешение порта 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 работает. Можно приступать к сбору логов.
job — метка для имени задания. Важный параметр для выборки данных.
__path__ — путь до файлов с логами.
Перезапускаем сервис 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.
* обратите внимание, что к имеющейся настройки мы добавили pipeline_stages:
selector — тег для отбора логов, которые нужно парсить.
expression — регулярное выражение для парсинга логов.
labels — список тегов, которые мы будем передавать в loki. Обратите внимание, что названия данных тегов соответствую названиям, которые мы задали в expression.
Перезапускаем сервис для promtail:
systemctl restart promtail
Идем в Grafana — в Log labels мы должны увидеть новые критерии для фильтра по тегам:
Пробуем добавить, например, фильтр по статусу ответа веб-сервера:
В данной инструкции мы попробуем разобраться с тем, как работать с 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 — утилита для работы с репозиториями.
Убедимся, что 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. Рассмотрим подробнее установку провайдера для работы с ним.
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"
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"] }
* где:
data — позволяет запрашивать данные. В данном примере мы обращаемся к ресурсу yandex_compute_image с целью поиска идентификатора образа, с которого должна загрузиться наша машина.
yandex_compute_image — ресурс образа. Его название определено провайдером.
ubuntu_image — произвольное название ресурса. Его мы определили сами и будем использовать в нашем сценарии.
ubuntu-2004-lts — в нашем примере мы запрашиваем данные ресурса, который ищем по family с названием ubuntu-2004-lts. Данное название можно посмотреть в контроль панели хостинга — нужно выбрать образ и кликнуть по нему. Откроется страница с дополнительной информацией. В данном случае ubuntu-2004-lts соответствуем Ubuntu 20.04 LTS.
resource — позволяет создавать различные ресурсы.
yandex_compute_instance — ресурс виртуальной машины. Его название определено провайдером.
vm-test1 — наше название ресурса для виртуальной машины.
subnet_terraform — наше название для ресурса подсети.
metadata — обратите особое внимание на передачу метеданных. В данном примере мы передаем содержимое файла, а сам файл рассмотрим ниже.
** в нашем примере будет создана виртуальная машина с названием test1, 2 CPU, 2 Gb RAM в сети 192.168.15.0/24 на базе Ubuntu 20.04 LTS. *** обратите внимание, что мы указали идентификатор той подсети для виртуальной машины, которую создали также с помощью нашего сценария terraform.
* в данном файле мы опишем пользователя, под которым мы сможем подключиться к нашему серверу по SSH:
#cloud-config — как выяснилось, этот комментарий обязательный.
name — имя пользователя, который будет создан на виртуальной машине.
groups — в какую группу добавить пользователя.
shell — оболочка shell по умолчанию.
sudo — правило повышения привилений.
ssh-authorized-keys — список ключей, которые будут добавлены в authorized_keys.
Попробуем испытать наш сценарий. Сначала вводим:
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.
Мы должны явно разрешить для конкретных ресурсов выполнение остановки их работы для внесения изменений. В нашем файле для конкретного ресурса добавим:
* для нашей машины test1 мы указали опцию allow_stopping_for_update, которая говорит о том, что работу ресурса можно останавливать для внесения изменений.
Строим план:
terraform plan
Мы должны увидеть, что будет изменено в нашей инфраструктуре. В моем случае:
2. Можно закомментировать или удалить строки ресурса из файла tf.
3. Если мы хотим оставить содержимое файлов нетронутым, но при этом удалить все ресурсы, вводим:
terraform destroy
Утилита пройдет по всем файлам tf в директории, найдет ресурсы и выполнит их удаление.
Файл state
Очень важно уметь работать с файлом состояния terraform, а также понять, что это. Данный файл появляется после первого применения сценария в том же рабочем каталоге:
ls
terraform.tfstate
В нем содержатся все изменения, которые происходили с применением terraform. Без него последний не будет знать, что уже было сделано — на практике это приведет к дублированию инфраструктуры, то есть, если мы создали сервер, потеряли файл состояния и снова запустили terraform, он создаст еще один сервер. Для больших инфраструктур с большой историей все намного критичнее.
И так, файл состояния важен с точки зрения понимания инфраструктуры самим terraform. Также у него есть еще одна функция — блокировка параллельных выполнений. Это важно для работы в командах, где одновременные действия могут привести к неожиданным последствиям. Чтобы этого не произошло, terraform создает блокировку, которая запрещает выполнения, если уже идет процесс применения плана.
Из вышесказанного делаем выводы:
Файлы состояния нужно бэкапить.
Они должны находиться в надежном месте.
У всех инженеров, которые работают с инфраструктурой должен быть доступ к файлу состояния. Они не должны его копировать на свои компьютеры и использовать индивидуально.
Рассмотрим возможность хранения данного файла состояния на облачном хранилище Яндекс.
Сначала мы должны создать хранилище. Это можно сделать через веб-интерфейс, но мы это сделаем в terraform.
* где yandex_folder_id — название для нашей переменной; <идентификатор каталога> — тот идентификатор, который мы указали в файле main под аргументом folder_id.
Теперь откроем файл main:
vi main.tf
И отредактируем значение folder_id на:
... folder_id = var.yandex_folder_id ...
* в данном примере мы теперь задаем folder_id не явно, а через созданную переменную.
yandex_iam_service_account — создание ресурса для учетной записи. В нашем примере она будет иметь название sa-dmosk и входить в системный каталог yandex_folder_id (переменная, которую мы создали ранее).
yandex_resourcemanager_folder_iam_member — создание роли. Она будет иметь доступ для редактирования хранилищ. В состав роли войдет созданная запись sa (с именем sa-dmosk).
yandex_iam_service_account_static_access_key — создаем ключ доступа для нашей сервисной учетной записи.
yandex_storage_bucket — создаем хранилище с названием tf-state-bucket-dmosk.
Создаем еще один файл:
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.
* в раздел 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.
Подразумевается, что все инфраструктура создается с нуля, поэтому нужно либо удалить предыдущие наработки, либо создать новый сервисный аккаунт для storage.
Мы создадим 5 файлов:
main.tf — в нем мы опишем инструкции для init, а именно требования к версии клиента terraform, провайдера.
web-servers.tf — сценарий для создания 2-х веб-серверов.
network-load-balancer.tf — создание Network Load Balancer.
variables.tf — описание переменных.
outputs.tf — вывод значений после отработки terraform на экран и в файл состояния.
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.* }
* на самом деле, это не обязательно — информацию о созданном балансировщике можно посмотреть в контроль панели, но для примера мы решили это рассмотреть.
Готово. После применения данного сценария мы получим то, что хотели — две виртуальные машины + балансировщик сети, который будет распределять запросы между данными серверами.
В данной инструкции будут рассмотрены небольшие сценарии работы с Gitlab Pipelines. Мы приведем примеры использования наиболее востребованных опций при работе с CI/CD. По мере необходимости, база шаблонов будет пополняться.
Шаблоны
В данном разделе напишем несколько готовых шаблонов, которые можно взять за основы при написании своего сценария.
1. Минимальный сценарий. Для небольших заданий, состоящих из пары заданий:
* в данном примере мы до того, как начнем проходить по всем заданиям сборки, определим переменную с версией, прочивав ее из файла, и передадим артефактом в качестве системной переменной VERSION.
Image
https://docs.gitlab.com/ee/ci/yaml/#image.
Задаем имя образа, если наше задание выполняется в контейнере docker:
Основная часть, где выполняются задания сценария, описана в опции script. Рассмотрим ее подробнее.
1. Описание массива команд. Мы просто перечисляем списком те команды, которые необходимо последовательно выполнить нашему сценарию в конкретной задаче:
TASK_NAME: ... script: - command1 - command2
2. Длинные команды, разбитые на несколько строк. Нам может потребоваться выполнить команды в виде скрипта (с операторами сравнения, например). В этом случае будет удобна многострочная запись. Ее можно указать разными способами.
* в моем примере, в артефакты попадут все файлы, название которых заканчивается на txt, файлы ${PKG_NAME}.deb и ${PKG_NAME}.rpm, а также каталог configs. Где ${PKG_NAME} — переменная (подробнее о переменных ниже).
В других заданиях, которые будут выполняться после можно использовать артефакты, обращаясь к ним по именам, например:
* в данном примере мы исключаем каталог .git, в котором, как правило, хранятся метаданные репозитория. ** обратите внимание, что в отличие от paths, exclude не берет файлы и каталоги рекурсивно и нужно явно указывать объекты.
Extends
https://docs.gitlab.com/ee/ci/yaml/#extends.
Позволяет вынести часть сценария в отдельный блок и объединить его с заданием. Чтобы это лучше понять, рассмотрим конкретный пример:
* обратите внимание, что мы применяем правило if (о нем ниже).
Директивы правил и ограничений
Для управления поведением выполнения задач могут использоваться директивы с правилами и условиями. Подробнее мы их рассмотрим ниже, а в данном разделе просто перечислим их.
Rules
https://docs.gitlab.com/ee/ci/yaml/#rules.
Правила, при соблюдении которых наше задание может быть запущено. Примеры работы с директивой rules приведены ниже.
When
https://docs.gitlab.com/ee/ci/yaml/#when.
Определяет условия запуска задания, например, только ручной запуск или через определенный интервал времени. Примеры работы приведены ниже.
Needs
https://docs.gitlab.com/ee/ci/yaml/#needs.
Тоже набор правил, требующий определенных условий для запуска задачи. Все директивы условий и правил описаны ниже.
Правила и условия
Мы можем выполнять или пропускать задания, в зависимости от выполнения определенных условий. Для этого существует несколько полезных директив, которые мы рассмотрим в данном разделе.
Rules
Регламентирует различные правила, определенные с помощью:
if.
changes.
exists.
allow_failure.
variables.
1. Оператор if. Позволяем проверить условие, например, если переменная равна определенному значению:
* в данном примере задание будет выполняться, если коммит прошел в основной ветке и если администратор подтвердил запуск.
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. Позволяем задать общие правила запуска для всего конвейера. Рассмотрим пример с официального сайта:
Не будет запущен, если название коммита содержит текст draft.
Будет запущен, если пайплайн сработал после merge request.
Будет запущен, если изменения внесены в основную ветку репозитория.
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.
* давайте разберемся, что происходит в нашем примере.
Мы создали задачу apt-cache. Точка в начале названия говорит системе, что данную задачу не нужно стартовать автоматически при запуске pipeline. Созданная задача состоит из двух секций script и after_script. Секций может быть больше.
Мы выполняем стадию install. В одной из строк выполнения мы вызываем apt-cache (только команды из раздела script).
При выполнении стадии update мы вызываем apt-cache два раза — первый выполняет команды раздела script, второй — after_script.