Новости
- Що таке Terraform
- підготовка
- Приступаємо до роботи
- зміна конфігурації
- Сценарії використання Terraform
- висновок
Сьогодні ми публікуємо гостьовий пост, написаний нашим клієнтом. Олексій - технічний директор компанії. Компанія займається розробкою однойменної освітньої платформи, а також проводить інтерактивні олімпіади для школярів. Вся інфраструктура Учі.Ру побудована на базі нашого сервісу « Віртуальне приватне хмара ».
Олексій Вахов докладно розповідає про те, як він і його колеги використовують утиліту для автоматизації налаштування і підтримки віртуальної інфраструктури. Сподіваємося, що його досвід буде цікавий і іншим користувачам нашого хмари.
Ось уже більше чотирьох років ми створюємо онлайн-платформу для шкільної освіти. Сотні тисяч учнів зі всієї Росії вирішують інтерактивні завдання, беруть участь в регулярних олімпіадах, і все це відбувається в рамках нашої платформи. Зараз система складається з більш десяти продакшенів, частина яких обслуговує зовнішніх відвідувачів з навантаженнями 500-800 запитів в секунду, на інших працюють додатки для внутрішнього використання.
Наш флагманський продукт - це сайт. Крім роботи над сайтом ми проводимо онлайн-олімпіади з математики, підприємництву і російській мові. Продакшени олімпіад, як і будь-яких заходів з чіткими датами проведення, відрізняються сильно нерівномірним трафіком. Під час основного туру сайт навантажений сильно, і на нас лежить висока відповідальність і важливо, щоб технічно сталося все гладко. А після нагородження та підбиття підсумків продакшен олімпіади працює в спокійному режимі.
Близько року тому ми перевели майже всю нашу інфраструктуру з виділених серверів в хмару і дуже задоволені. Можливість швидко докупити будь-яку кількість серверів особливо актуальна для олімпіад, так як там пікове навантаження тримається всього пару тижнів, і на цей час ми піднімаємо ферму з пари десятків серверів, а потім її розформовуємо. Однак і для всіх інших продакшенів можливість швидко підкрутити ресурси дуже цінна.
В хмарі помінялися навіть принципи організації інфраструктури. На залізних серверах доводилося комбінувати по кілька ролей на бокс, так як вони великі і досить дорогі, до того ж підключення нового сервера завжди займає кілька днів. Система з часом ставала крихкою і не гнучкою. Зараз ми виділяємо кожен продакшен в окремий ізольований проект зі своєю підмережею і під кожну роль заводимо окремий сервер. Наприклад, під VPN доступ беремо найменші, на одне ядро і 512 мегабайт пам'яті, а під сервери додатків і бази даних найчастіше купуємо сервер максимального розміру.
Коли кількість серверів зросла до декількох десятків, ми зіткнулися з новою проблемою: управляти конфігурацією через графічний інтерфейс стало некомфортно.
Коли з графічної панеллю працюють кілька людей, починає проявлятися людський фактор: уявімо собі, наприклад, ситуацію, коли хтось щось поміняв і не повідомив про це колегам (та й як про це повідомити?).
Скажімо з 8 серверів, які повинні бути однакові, один може мати іншу версію операційної системи або трохи інша кількість оперативної пам'яті. Завдання клонування або підняття нового продакшена з нуля також мала на увазі багато ручної роботи. Тому ми вирішили автоматизувати роботу з налаштування та підтримки нашої інфраструктури за допомогою утиліти Terraform ..
У цій статті я розповім для чого потрібен Terraform, покажу, як налаштувати оточення і створити тестовий сервер в будь-якому OpenStack-хмарі на прикладі хмари Селектел. Також ми обговоримо особливості використання утиліти на живому продакшені.
Що таке Terraform
- це чудова утиліта від компанії (творці Vagrant, Consul і деяких інших широко відомих у вузьких колах інструментів). З її допомогою можна моделювати, зберігати і змінювати хмарну інфраструктуру у вигляді простих шаблонів мовою HCL (HashiCorp Configuration Language). Хоча створення своєї мови - зазвичай дуже погана ідея, HCL мені подобається. Він являє собою надбудову над JSON, яку легко і приємно читати.
Наведу спрощений приклад (в реальності потрібно вказати трохи більше атрибутів) для створення сервера в хмарі «Селектел», практично повністю пояснює всі тонкощі синтаксису, які нам знадобляться:
resource "openstack_blockstorage_volume_v1" "disk" {name = "disk" region = "ru-1" size = 10} resource "openstack_compute_instance_v2" "server" {name = "server" flavor_name = "flavor-1024-1" region = "ru -1 "block_device {uuid =" $ {openstack_blockstorage_volume_v1.disk.id} "}}Якщо зберегти наведений вище код в файл з розширенням .tf, налаштувати необхідні токени для доступу і викликати в консолі команду `terraform apply`, то станеться рівно те, що очікується: Terraform створить диск і тільки після цього створить сервер, на основі цього свіжого диска .
Якщо запустити `terraform apply` ще раз, то утиліта побачить, що такий диск і сервер вже є, і нічого робити не буде. Також легко додати пам'яті на сервер, помінявши `flavor_name` на` flavor-2048-1` і знову викликавши `terraform apply`. Terraform передбачувано оновить тільки пам'ять, а диск чіпати не буде. Команда `terraform destroy` видалить всі створені ресурси (і можна забути про висять в порожнечу DNS-записи тестових серверів, забуті диски та інші артефакти, які дратують будь-якого перфекціоніста).
Перш ніж приступати до роботи з Terraform, уважно вивчіть офіційну документацію (вона дуже хороша і зрозуміла, читається на одному диханні) і кілька днів поекспериментуйте з тестовими інфраструктурами, бажано на окремих акаунтах. Це дуже важливо: нерозуміння тонкощів роботи з Terraform може привести до непоправних наслідків. Експерименти якраз і допоможуть вам розібратися, як Terraform працює станом.
Розглянемо сценарії роботи з Terraform більш докладно.
підготовка
Для початку необхідно налаштувати оточення. Я розповім, як це робимо ми, але, думаю, якщо ви вже скріптуете свою інфраструктуру, то напевно знаєте які моменти вимагають автоматизації. Рекомендую вивчити, там є дуже несподівані представники - Grafana, PostgreSQL, Heroku і багато інших. Може бути, щось стане в нагоді при моделюванні вашої інфраструктури.
Ми поки управляємо тільки серверами і DNS-записами.
Для роботи нам знадобляться:
- проект з необхідною кількістю квот;
- користувач з доступом до даного проекту;
- консольні утиліти OpenStack;
- ідентифікатор образу операційної системи;
- підготовлений набір змінних оточення.
Новий проект, користувача і квоти налаштуйте через GUI (хоча це теж можна скріптовать, але вже не через Terraform). Збережіть ID проекту: він буде використовуватися під час налаштування доступу OpenStack-провайдера. Зайдіть в проект і створіть локальну мережу, якщо вона ще не створена (в хмарі Selectel локальна мережа створюється автоматично, якщо ви замовите плаваючий IP-адреса).
Далі встановіть консольні утиліти для отримання деяких внутрішніх ідентифікаторів, які недоступні через GUI. У статті " Робота з API віртуального приватного хмари: консольні клієнти »Докладно написано, як їх встановити і використовувати. Для зручності ми завернули їх в контейнер і використовуємо в такий спосіб:
docker run --rm \ -e OS_AUTH_URL = https: //api.selvpc.ru/identity/v3 \ -e OS_PROJECT_ID = # {...} \ -e OS_USER_DOMAIN_NAME = # {...} \ -e OS_USERNAME = # {...} \ -e OS_PASSWORD = # {...} \ -e OS_REGION_NAME = # {...} \ uchiru / ostack: v2 команда, яку необхідно запуститиДе OS_USER_DOMAIN_NAME - логін в панелі «Селектел» (номер договору), PROJECT_ID - ідентифікатор проекту, OS_REGION_NAME - регіон (ru-1 для Санкт-Петербурга, ru-2 - Москва), OS_USERNAME / OS_PASSWORD - логін / пароль користувача (не забувайте, що у нього повинен бути доступ до проекту).
Щоб отримати ідентифікатор способу, запустіть команду glance image-list і знайдіть потрібний вам образ:
root @ 2118c4e58238: / # glance image-list | grep 16.04 eecd3d0f-6968-40ea-bed6-4c2949bbac3d | Ubuntu-16.04 LTS 32-bit ce532860-acef-40cd-b3c7-699c22b4dfd6 | Ubuntu-16.04 LTS 64-bit Тепер залишилося створити потрібні Флавор. Зазвичай OpenStack-провайдери надають фіксований набір конфігурацій, проте «Селектел» в цьому плані більш гнучкий, так як дозволяє зібрати довільну конфігурацію для кожного сервера (при роботі в UI Флавор створюється автоматично на кожен новий сервер). Ми ж будемо створювати Флавор за допомогою команди nova. Відразу ж прийміть схему іменування, якій будете слідувати. Розумно вибрати щось типу flavor-1024-2 -двухядерний сервер з гігабайтом пам'яті.
Формат команди:
Нарешті, для коректної роботи Terraform знадобиться експортувати кілька змінних оточення:
export TF_VAR_SELECTEL_ACCOUNT = 112233 # ваш логін від облікового запису Selectel export TF_VAR_PROJ_ID = 5b1b496 .. # ідентифікатор проекту export TF_VAR_USER = ... # логін користувача export TF_VAR_PASSWORD = ... # пароль цього користувачаОт і все! Тепер у вас є всі компоненти для того, щоб створити свій перший сервер.
Приступаємо до роботи
Створіть файл provider.tf (ім'я файлу, природно, може бути будь-яким) з доступом до хмари:
provider "openstack" {domain_name = "$ {var.SELECTEL_ACCOUNT}" auth_url = "https://api.selvpc.ru/identity/v3" tenant_name = "$ {var.PROJ_ID}" tenant_id = "$ {var.PROJ_ID } "user_name =" $ {var.USER} "password =" $ {var.PASSWORD} "}Додайте файл variables.tf:
variable "image_list" {type = "map" default = { "ubuntu-x64-1604" = "2de94623-a2a2-49e3-984d-3e6ca85e2b84"}} # змінні необхідно оголосити variable "PROJ_ID" {} variable "SELECTEL_ACCOUNT" {} variable "USER" {} variable "PASSWORD" {} # плаваючий IP і ідентифікатор мережі можна скопіювати з UI variable "box01-floating-ip" {default = "..."} variable "network-id" {default = ". .. "} variable" box01-ip "{default =" 192.168.0.4 "}І, нарешті, файл box01.tf з описом сервера:
resource "openstack_blockstorage_volume_v1" "disk-for-box01" {name = "disk-for-box01" region = "ru-1" size = 10 image_id = "# $ {var.image_list [" ubuntu-x64-1604 "]} "volume_type =" basic.ru-1a "} resource" openstack_compute_instance_v2 "" box01 "{name =" box01 "flavor_name =" flavor-1024-1 "region =" ru-1 "network {uuid =" $ {var.network -id} "fixed_ip_v4 =" $ {var.box01-ip} "floating_ip =" $ {var.box01-floating-ip} "} metadata = {" x_sel_server_default_addr "=" {\ "ipv4 \": \ "\" } "} block_device {uuid =" $ {openstack_blockstorage_volume_v1.disk-for-box01.id} "source_type =" volume "boot_index = 0 destination_type =" volume "}}Потім виконайте команду `terraform apply` - і через кілька секунд ваш перший сервер готовий! Ми роздаємо IP-адреси вручну для більшої контрольованості, плюс при зміні ресурсів OpenStack видасть нову адресу, якщо він не вказаний явно, що не завжди зручно.
Синтаксис Terraform досить самодокументірованний. Ви з цеглинок-ресурсів складаєте ті конструкції, які вам потрібні. Утиліта сама прораховує залежності і, наприклад, створить сервер тільки після того, як створений диск. Однак те, що можна зробити паралельно - буде робити паралельно.
Звичайно, один-єдиний сервер набагато швидше і зручніше створити через GUI. Я думаю, що реальна користь від Terraform починається від пари десятків серверів, особливо якщо також скріптовать DNS-записи, Бакета S3 і інші сервіси.
зміна конфігурації
Додати або прибрати згадку (або диски) дуже просто: змініть Флавор і викличте команду `terraform apply`. Зверніть увагу: в результаті виконання цієї команди сервер перезавантажиться!
Розмір диска слід міняти акуратно, так як Terraform пересоздаст його з нуля, якщо робити через скрипти. Але вихід є: збільште розмір через UI і в відповідному tf-скрипті. Terraform вас зрозуміє правильно і чіпати диск не буде.
Додати сервер найпростіше, скопіювавши файл box01.tf і оновивши соответсnвующіе змінні. Для наших проектів в 10-20 серверів ми зберігаємо tf-файли плоско (Не формуючи ієрархію з файлів по будь-якою ознакою): скільки серверів - стільки файлів.
Сценарії використання Terraform
Повторюся ще раз: за рівнем бід, які можна накоїти на живому продакшені (причому, дуже, дуже швидко) Terraform залишить далеко позаду навіть `truncate table`. Мабуть, це самий небезпечний інструмент, з яким я коли-небудь працював. Тому дуже важливо добре розуміти принципи його роботи.
З технічної точки зору Terraform є один-єдиний бінарний файл на Go, його можна скомпілювати, розібратися, налагодити. Вся магія реалізована через файл стану і різноманіття провайдерів для роботи з різними сервісами.
Типовий сценарій виглядає так. Ви задаєте бажану конфігурацію в tf-скриптах. Файл стану в цей момент порожній. Набираєте команду `terraform plan`.Ето найприємніша і безпечна команда: вона нічого не змінює, просто пише, які зміни утиліта внесе, якщо запустити команду` terraform apply`.
Далі ви запускаєте `terraform apply` і тільки тоді будуть створені реальні сервери, диски, записи в DNS і так далі. Інформація про ці ресурси буде збережена в файл стану (JSON-файл з досить простим синтаксисом). При подальшій роботі утиліта буде використовувати файл стану, також збирати інформацію з реального світу і порівнювати її з вашими скриптами.
Причиною всіх непорозумінь є те, що Terraform працює з трьома об'єктами одночасно:
- tf-скрипти - це те, що ви хочете бачити;
- файл стану - це те, як виглядає інфраструктура на думку Terraform;
- реальний стан справ - як насправді виглядає інфраструктура.
У момент планування запиту (а apply команда відрізняється від plan тільки тим, що зміни реально застосовуються), Terraform зчитує файл стану, оновлює властивості кожного об'єкта по його ID (в будь-якому сервісі у кожного ресурсу є унікальний ідентифікатор, саме його використовує Terraform для ідентифікації) і порівнює отримані атрибути.
Грубо кажучи, можна вважати, що стан - це перелік ідентифікаторів ресурсів, якими управляє даний проект. Якщо ви додасте сервер або DNS-запис руками, то Terraform про неї не дізнається. Необхідно буде помістити її в стан явно. Якщо видаліть сервер через GUI, то Terraformу також потрібно буде оновити стан за допомогою команди `terraform state rm <віддалені ресурси>`.
У попередньому розділі я рекомендував збільшувати диск через UI і в tf-скрипті. Як це працює? Припустимо, спочатку в tf-скрипті вказаний диск 10ГБ. Terraform створив його і записав id свіжого диска, а також його розмір у файл стану. Ви поміняли розмір через UI на 20ГБ. Якщо запустити `terraform plan` зараз, то Terraform дізнається у OpenStack, що розмір диска 20ГБ, а в tf-файлі - 10ГБ, і запропонує його перебудувати. Якщо ви поміняєте розмір диска на 20ГБ, то Terraform переконається, що диск реально 20ГБ і в скриптах - 20ГБ і нічого робити не буде. Може здатися, що зберігати в стані факт, що колись диск був 10ГБ і не потрібно, так як Terraform не використовує цей атрибут. Насправді, це так і є, але особливість реалізації деяких провайдерів вимагає збереження деяких додаткових атрибутів (наприклад, регіон для всіх OpenStack-ресурсів), підозрюю, що саме тому автори вирішили зберігати в стані останні значення всіх властивостей кожного ресурсу.
Щоб Terraform працював коректно, необхідно зберігати файл стану централізовано. Ми зберігаємо прямо в репозиторії, також можна зберігати на S3, в комерційному сервісі Atlas, в Consul і деяких інших сховищах, повний список яких також є в.
висновок
У цій статті ми розглянули особливості роботи з Terraform дуже коротко. На жаль, за рамками нашого розгляду залишилася цікава тема з імпорту вже існуючої інфраструктури. Скажу коротко. Можна скористатися командою `terraform import`, яка, правда, з'явилася недавно, реалізована далеко не для всіх провайдерів і поки відверто сирувата. Робочий варіант на сьогодні - додати ресурс з правильним типом і ідентифікатором прямо в файл стану і викликати `terraform refresh`.
Отже, якщо ви активно користуєтеся хмарними сервісами, часто створюєте і видаляєте різні сутності через GUI, рекомендую спробувати. ви знайдете повний комплект скриптів зі статті, достатній для закладу свого сервера за допомогою Terraform. Хоча утиліта молода, з досить високим порогом входу, після впровадження відчуття порядку і контролю сильно зросте. Буду радий відповісти на будь-які питання і зауваження в коментарях і поштою [email protected] .
Дякую команду «Селектелa» за пропозицію написати гостьовий пост. Також запрошую всіх читачів відвідати. Кожен робочий день публікую маленьку історію про розробку, думки, інструменти і все таке.
Дякую за увагу!
А й як про це повідомити?Як це працює?