Infrastruktur sebagai kode, kami menang dalam skala besar (Kirill Vetchinkin, TYME)

Model Infrastructure as Code (IaC), kadang-kadang disebut sebagai "infrastruktur yang dapat diprogram", adalah model di mana proses konfigurasi infrastruktur mirip dengan proses pemrograman perangkat lunak. Pada dasarnya, ini menandai awal dari menghilangkan batas antara menulis aplikasi dan menciptakan lingkungan untuk aplikasi ini. Aplikasi dapat berisi skrip yang membuat dan mengelola mesin virtual mereka sendiri. Ini adalah dasar dari komputasi awan dan bagian integral dari DevOps.


Infrastruktur sebagai kode memungkinkan Anda mengelola mesin virtual di tingkat perangkat lunak. Ini menghilangkan kebutuhan untuk konfigurasi manual dan pembaruan untuk masing-masing komponen peralatan. Infrastruktur menjadi sangat "tangguh," yaitu, dapat direproduksi dan terukur. Satu operator dapat menggunakan dan mengelola satu dan 1000 mesin menggunakan serangkaian kode yang sama. Di antara manfaat infrastruktur yang dijamin sebagai kode adalah kecepatan, efektivitas biaya, dan pengurangan risiko.


Inilah yang dimaksud dengan decoding laporan Kirill Vetchinkin di DevOpsDays Moscow 2018. Laporan: penggunaan kembali modul Ansible, penyimpanan di Git, tinjau, pembangunan kembali, manfaat finansial, penskalaan horizontal 1-klik.



Siapa yang peduli, tolong, di bawah kucing.


Halo semuanya. Seperti yang sudah dikatakan, saya Vetchinkin Kirill. Saya bekerja di TYME dan hari ini kita akan berbicara tentang infrastruktur sebagai kode. Kami juga akan berbicara tentang bagaimana kami belajar menghemat praktik ini, karena itu cukup mahal. Menulis banyak kode cukup mahal untuk mengatur infrastruktur.


Saya akan berbicara singkat tentang perusahaan. Saya bekerja di TYME. Kami memiliki rebranding. Sekarang kita disebut PaySystem - seperti namanya, kita terlibat dalam sistem pembayaran. Kami memiliki solusi kami sendiri - ini adalah prosesing, dan pengembangan kustom. Pengembangan kustom adalah perbankan elektronik, penagihan, dan sejenisnya. Dan seperti yang Anda tahu, jika ini adalah pengembangan kustom, maka ini adalah sejumlah besar proyek setiap tahun. Proyek berjalan setelah proyek. Semakin banyak proyek, semakin banyak infrastruktur dari jenis yang sama harus ditingkatkan. Karena proyek sering kali dimuat banyak, kami menggunakan arsitektur microservice. Oleh karena itu, dalam satu proyek ada banyak, banyak sub proyek kecil.



Karenanya, mengelola seluruh kebun binatang ini tanpa DevOps penuh sangat sulit. Oleh karena itu, perusahaan kami telah menerapkan berbagai praktik DevOps. Secara alami, kami bekerja di kanban, di SCRUM, kami menyimpan semuanya di git. Setelah melakukan, ada integrasi terus menerus, tes dijalankan. Penguji menulis tes ujung ke ujung pada PyTest yang dimulai setiap malam. Unit-test dimulai setelah setiap komit. Kami menggunakan proses build dan deploy yang terpisah: assembled, kemudian deploy ke berbagai lingkungan berkali-kali. Kami berada di windows. Di windows kami menggunakan menggunakan Octopus, tahun ini kami mengembangkan di DotNet Core. Karena itu, kami sekarang dapat menjalankan perangkat lunak pada sistem Linux. Kami meninggalkan Octopus dan tiba di Ansible. Hari ini kita akan membicarakan bagian ini, yang merupakan praktik baru yang kami kembangkan tahun ini, sesuatu yang belum pernah kami lakukan sebelumnya. Ketika Anda memiliki tes, ketika Anda tahu cara membangun aplikasi dengan baik, menempatkannya di suatu tempat tidak masalah. Tetapi jika Anda memiliki dua lingkungan yang dikonfigurasi secara berbeda, maka Anda masih akan jatuh, dan jatuh pada produksi. Oleh karena itu, mengelola konfigurasi adalah praktik yang sangat penting. Itulah yang akan kita bicarakan hari ini.



Saya akan menjelaskan secara singkat bagaimana ekonomi tenaga kerja produk dibangun: 60 persen dihabiskan untuk pengembangan , analitik membutuhkan sekitar 10 persen, QA (pengujian) memakan waktu sekitar 20 persen, dan segala sesuatu yang lain dialokasikan untuk konfigurasi. Ketika sistem berjalan dalam aliran penuh, mereka memiliki banyak perangkat lunak pihak ketiga, sistem operasi itu sendiri dikonfigurasi dengan cara yang hampir sama. Kami menghabiskan waktu ekstra untuk melakukan ini, pada dasarnya melakukan hal yang sama. Ada ide untuk mengotomatisasi segalanya dan mengurangi biaya konfigurasi infrastruktur. Tugas serupa diotomatiskan, debugged dengan baik dan tidak mengandung operasi manual.



Setiap aplikasi berfungsi dalam beberapa jenis lingkungan. Mari kita lihat terdiri dari apa semua itu. Minimal, kita harus memiliki sistem operasi , perlu dikonfigurasi, ada beberapa aplikasi pihak ketiga yang juga perlu dikonfigurasi, aplikasi itu sendiri harus menerima konfigurasi, tetapi untuk seluruh produk untuk bekerja, aplikasi itu sendiri harus mulai, yang beroperasi di seluruh sistem ini. Ada juga jaringan yang juga perlu dikonfigurasi, tetapi kami tidak akan berbicara tentang jaringan hari ini, karena kami memiliki pelanggan yang berbeda, perangkat jaringan yang berbeda. Kami juga mencoba mengotomatiskan konfigurasi jaringan, tetapi karena perangkatnya berbeda, tidak ada manfaat khusus dari ini, kami menghabiskan lebih banyak sumber daya untuk ini. Tetapi kami mengotomatiskan sistem operasi, aplikasi pihak ketiga, dan transfer parameter konfigurasi ke aplikasi itu sendiri.



Ada dua pendekatan untuk bagaimana Anda dapat mengkonfigurasi server: dengan tangan - jika Anda mengonfigurasinya dengan tangan, Anda mungkin akan mendapatkan situasi sedemikian rupa sehingga Anda telah mengonfigurasi produksi dengan satu cara, tes yang lain, semuanya berwarna hijau pada pengujian, tes berwarna hijau. Anda menyebarkan ke produksi, dan tidak ada kerangka kerja di sana - tidak ada yang berhasil untuk Anda. Contoh lain: tiga server Aplikasi dikonfigurasikan dengan tangan. Satu server aplikasi dikonfigurasikan dalam satu cara, server aplikasi lain dengan cara yang berbeda. Server dapat bekerja dengan berbagai cara. Contoh lain: ada situasi ketika satu server Panggung benar-benar berhenti bekerja untuk kami. Kami mulai membuat server baru menggunakan dan setelah 30 server siap. Contoh lain: server baru saja berhenti bekerja. Jika Anda mengaturnya dengan tangan Anda, maka Anda perlu mencari orang yang tahu cara mengkonfigurasinya, Anda perlu meningkatkan dokumentasi. Seperti yang kita ketahui, dokumentasi hampir tidak relevan. Ini adalah masalah besar. Dan, yang paling penting, ini adalah audit, yaitu, secara kasar, Anda memiliki sepuluh administrator, masing-masing mengatur sesuatu dengan tangannya, tidak terlalu jelas apakah mereka mengaturnya dengan benar atau salah, dan bagaimana memahami apakah kemudian pengaturan, mereka bisa meletakkan sesuatu yang berlebihan, buka beberapa port yang tidak perlu.



Ada opsi alternatif - inilah yang kita bicarakan hari ini - ini adalah konfigurasi dari kode. Artinya, kami memiliki repositori git di mana seluruh infrastruktur disimpan. Semua skrip disimpan di sana, dengan bantuan yang akan kami konfigurasikan. Karena ini semua ada di git, kita mendapatkan semua manfaat dari manajemen kode, seperti dalam pengembangan, yaitu, kita dapat melakukan tinjauan, audit, mengubah sejarah, siapa yang melakukannya, mengapa melakukannya, komentar, kita dapat memutar kembali. Untuk bekerja dengan kode Anda perlu menggunakan pipa perakitan terus menerus - pipa penyebaran. Agar suatu sistem tertentu dapat membuat perubahan pada server, yaitu, tidak seorang pun akan melakukan sesuatu dengan tangannya, tetapi sistem akan melakukannya secara eksklusif.



Sebagai sistem yang melakukan perubahan, kami menggunakan Ansible. Karena kami tidak memiliki banyak server, sangat cocok untuk kami. Jika Anda memiliki 100-200 server di sana, maka Anda akan memiliki masalah kecil, karena itu (mis. Ansible) masih terhubung ke masing-masing dan mengkonfigurasinya secara bergantian - ini adalah masalah. Lebih baik menggunakan cara lain yang tidak mendorong, tetapi menarik. Tetapi untuk sejarah kami, ketika kami memiliki banyak proyek, tetapi tidak lebih dari 20 server, ini sangat cocok untuk kami. Ansible memiliki nilai tambah besar - ini merupakan ambang masuk yang rendah. Artinya, secara harfiah setiap spesialis TI dalam tiga minggu dapat sepenuhnya menguasainya. Dia memiliki banyak modul. Artinya, Anda dapat mengelola cloud, jaringan, file, menginstal program, menyebarkan - benar-benar segalanya. Jika tidak ada modul, Anda dapat menulis sendiri, Anda akhirnya dapat menulis sesuatu menggunakan modul shell atau perintah Ansible.



Secara umum, kami akan mempertimbangkan secara singkat tampilannya secara umum, alat ini. Ansible memiliki modul yang sudah saya bicarakan. Artinya, mereka dapat disampaikan, ditulis sendiri, yang sedang melakukan sesuatu. Ada inventaris - ini adalah tempat kami akan menggulirkan perubahan kami, yaitu, ini adalah host, alamat IP mereka, variabel khusus untuk host ini. Dan, karenanya, peran. Peran adalah apa yang akan kita putar di server ini. Dan juga host kita dikelompokkan ke dalam grup, yaitu, dalam hal ini kita melihat bahwa kita memiliki dua grup: server database dan server aplikasi. Di setiap grup kami memiliki tiga mobil. Mereka terhubung melalui ssh. Jadi, kami memecahkan masalah yang kami bicarakan sebelumnya, bahwa sejak awal server kami dikonfigurasi secara identik, karena peran yang sama bergulir ke server. Dan dengan cara yang sama, jika kita menjalankan peran ini pada beberapa mesin, maka untuk masing-masing itu akan bekerja dengan cara yang sama.



Jika kita melihat lebih dalam pada bagaimana proyek Ansible terstruktur, maka di sini kita melihat bahwa host dapat diterima untuk inventaris produksi. Grup ini ditunjukkan dan ada dua server di dalamnya. Jika kita pergi ke server tertentu, kita melihat bahwa alamat IP mesin ini ditunjukkan di sini. Parameter lain juga dapat ditunjukkan di sana - variabel spesifik untuk lingkungan ini. Jika kita melihat perannya. Peran itu berisi beberapa tugas yang akan dilakukan. Dalam hal ini, ini adalah peran untuk menginstal PostgreSQL. Artinya, kita menginstal aplikasi yang diperlukan, membuat database. Di sini kita menggunakan perulangan. Mereka (basis data) akan dibuat sedikit. Kemudian kami membuat koneksi yang diperlukan - alamat IP yang dapat masuk ke database ini. Dan, karenanya, kami mengonfigurasi di bagian paling akhir firewall. Pengaturan akan diterapkan ke semua server dalam grup.



Cukup dekati masalahnya sendiri: kami mempelajari cara mengkonfigurasi server menggunakan Ansible dan semuanya baik-baik saja. Tetapi, seperti yang saya katakan, kami memiliki banyak proyek. Mereka hampir semuanya sama. Beberapa sistem ini terlibat dalam setiap proyek (k8s, RabbitMQ, Vault, ELK, PostgreSQL, HAProxy). Untuk masing-masing, kami menulis peran. Kita bisa menggulungnya dari tombol.



Tetapi kami memiliki banyak proyek, dan masing-masing proyek pada dasarnya tumpang tindih. Yaitu, di satu set seperti itu, di set kedua, di set ketiga. Kami mendapatkan titik persimpangan di mana peran yang sama di berbagai proyek.



Kami memiliki repositori dengan aplikasi, kami memiliki repositori dengan infrastruktur untuk proyek tersebut. Proyek kedua persis sama. Infrastruktur yang berkelanjutan. Dan yang ketiga. Jika kita menerapkan hal yang sama, maka pada dasarnya copy-paste akan berubah. Kami akan melakukan peran yang sama di 10 tempat. Kemudian, jika ada kesalahan, kami akan memerintah di 10 tempat.



Apa yang kami lakukan: kami mengambil setiap peran yang umum untuk semua proyek dan semua konfigurasinya yang datang dari luar ke repositori terpisah dan menempatkannya di git di folder terpisah - kami disebut TYME Infrastructure. Di sana kami memiliki peran untuk PostgreSQL, untuk ELK, untuk menyebarkan kluster Kubernetes. Jika kita perlu memasukkan beberapa proyek, katakanlah PostgreSQL yang sama, kemudian nyalakan saja sebagai submodule, tulis ulang inventaris, yaitu, secara kasar, konfigurasi tempat untuk menjalankan peran ini. Kami tidak menulis ulang peran itu sendiri: sudah ada. Dan dengan mengklik tombol, PostgreSQL muncul di semua proyek baru. Jika Anda perlu menaikkan kluster Kubernetes - hal yang sama.



Dengan demikian, ternyata mengurangi biaya peran menulis. Yaitu, mereka menulis sekali - mereka menggunakannya 10 kali. Ketika proyek berjalan setelah proyek - itu sangat nyaman. Tetapi karena kita sekarang bekerja dengan infrastruktur sebagai kode, kita tentu membutuhkan pipa yang kita bicarakan. Orang-orang berkomitmen pada git, mereka dapat melakukan semacam kesalahan - kita perlu melacak ini semua. Oleh karena itu, kami telah membangun pipa semacam itu. Artinya, pengembang melakukan skrip Ansible di git. Teamity melacak mereka dan mentransfernya ke Ansible. Teamcity diperlukan di sini hanya untuk satu alasan: pertama, ia memiliki antarmuka visual (ada versi gratis Ansible Tower - AWX, yang memecahkan masalah yang sama - kira-kira.) Tidak seperti Ansible gratis dan, pada prinsipnya, kami memiliki Teamcity sebagai satu Ci. Jadi, pada prinsipnya, Ansible memiliki modul yang dengan sendirinya dapat melacak git. Tetapi dalam hal ini mereka melakukannya hanya dalam gambar dan rupa. Dan begitu dia melacaknya, ia mentransfer semua kode ke Ansible dan Ansible, masing-masing, meluncurkannya di server integrasi dan mengubah konfigurasi. Jika proses ini dilanggar, maka kami menganalisis apa yang salah, mengapa skrip ditulis dengan buruk.



Poin kedua adalah bahwa ada infrastruktur khusus, di sini kita memiliki infrastruktur yang digunakan secara terpisah, aplikasi ini digunakan secara terpisah. Tetapi ada infrastruktur khusus untuk setiap aplikasi, yaitu, yang perlu digunakan sebelum kita meluncurkannya. Di sini, karenanya, tidak mungkin untuk mentransfernya ke saluran pipa yang berbeda. Anda harus menempatkan ini di wadah yang sama dengan aplikasi itu sendiri. Yaitu, katakanlah, kerangka kerja adalah hal yang populer ketika Anda perlu menginstal satu kerangka kerja untuk aplikasi baru dan menempatkan kerangka kerja lain untuk yang lain. Begini caranya dengan situasi ini. Atau Anda perlu membersihkan cache. Misalnya, Ansible juga bisa memanjat, membersihkan cache.



Tapi di sini kita menggunakan buruh pelabuhan dalam kombinasi dengan Ansible. Artinya, infrastruktur spesifik kita adalah di buruh pelabuhan, non-spesifik di Ansible. Jadi, kami membagi delta kecil ini di docker, yang lainnya, fundamental - dalam Ansible.



Poin yang sangat penting - jika Anda menggulung infrastruktur melalui beberapa jenis skrip, melalui kode, maka jika Anda masih memiliki manipulasi server manual, maka ini adalah kerentanan potensial. Karena katakanlah Anda meletakkan java di server pengujian, menulis peran ELK, menggulungnya. Menyebarkan dalam tes berhasil. Menyebarkan dalam produksi, tetapi tidak ada java. Dan Anda tidak menentukan java dalam skrip - penyebaran dalam produksi jatuh. Karena itu, Anda perlu mengambil hak dari semua server dari administrator sehingga mereka tidak merangkak ke dalamnya dengan tangan Anda dan membuat semua perubahan melalui git. Semua conveyor yang kami lalui sendiri. Ada satu hal tetapi - jangan mengencangkan mur terlalu banyak. Artinya, perlu untuk memperkenalkan proses semacam itu secara bertahap. Karena masih mentah. Dalam kasus kami, kami meninggalkan akses ke semua sistem di kepala administrator utama jika terjadi insiden yang tidak terduga. Akses diberikan dengan ketentuan bahwa itu tidak akan mengkonfigurasi apa pun dengan tangan.



Bagaimana cara kerja pengembangan? Peluncuran dalam pementasan, produksi harus bebas dari kesalahan. Sesuatu bisa pecah di sini. Jika peluncuran di lingkungan integrasi terus-menerus jatuh pada kesalahan, itu akan menjadi buruk. Ini mirip dengan aplikasi debug pada mesin jarak jauh. Ketika seorang pengembang pertama kali mengembangkan segala sesuatu pada mesin, kompilasi itu. Jika semuanya dikompilasi, maka kirimkan ke repositori. Ini menggunakan pendekatan yang sama. Pengembang menggunakan Visual Studio Code dengan plugins Ansible, Vagrant, Docker, dll. Pengembang menguji kode infrastruktur mereka pada gelandangan lokal. Ada sistem operasi yang bersih. Script sendiri untuk meningkatkan mesin ini juga ada dalam repositori ini dengan infrastruktur yang kita bicarakan. Pengembang mulai menginstal server FTP di atasnya. Jika terjadi kesalahan, ia cukup menghapusnya, memuatnya kembali, dan kembali mencoba menginstal perangkat lunak yang diperlukan menggunakan skrip penerapan. Setelah men-debug skrip penerapan, itu membuat Permintaan Gabung ke cabang utama. Setelah menggabungkan Permintaan Gabung, CI mengembalikan perubahan ini ke server integrasi.



Karena semua skrip adalah kode, kita dapat menulis tes. Katakanlah kita menginstal PostgreSQL. Kami ingin memeriksa apakah berfungsi atau tidak. Untuk melakukan ini, gunakan modul Ansible assert. Bandingkan versi PostgreSQL yang diinstal dengan versi di skrip. Dengan demikian, kami memahami bahwa itu diinstal, umumnya berjalan, itu adalah versi yang kami harapkan.



Kami melihat bahwa tes tersebut lulus. Jadi buku pedoman kami berfungsi dengan benar. Anda dapat menulis sebanyak mungkin tes yang Anda inginkan. Mereka idempoten. Idempotency (operasi yang, jika diterapkan pada nilai apa pun beberapa kali, selalu menghasilkan nilai yang sama dengan satu aplikasi). Jika Anda menulis skrip gratis untuk instalasi dan konfigurasi, maka pastikan skrip Anda selalu mendapatkan nilai yang sama jika Anda menjalankannya beberapa kali.



Ada jenis tes lain yang tidak secara langsung terkait dengan pengujian infrastruktur. Tetapi mereka tampaknya secara tidak langsung mempengaruhi dirinya. Ini adalah tes ujung ke ujung. Kami memiliki infrastruktur dan aplikasi itu sendiri diinstal pada server yang sama, yang diuji oleh penguji. Jika kita menggulung beberapa jenis infrastruktur yang salah, maka kita hanya tes kompleks yang tidak akan lulus. Artinya, aplikasi kita entah bagaimana akan bekerja secara salah. Dalam contoh ini, kami memasang versi baru pada produksi - aplikasi berfungsi. Kemudian komit dibuat dalam git dan tes end-to-end, yang berlangsung pada malam hari, dilacak bahwa di sini kita tidak memiliki file di ftp. Kami membongkar kasus ini dan melihat bahwa masalahnya ada di pengaturan ftp. Kami memperbaiki skrip dalam kode, menyebarkan lagi dan semuanya berubah hijau. Kisah yang sama dengan kode. Kode dan infrastruktur infrastruktur diuji secara tidak langsung dengan satu atau lain cara. Kami kemudian dapat menggunakannya untuk produksi.



Ketika kami memperkenalkan pendekatan ini, CI (Teamcity), yang meluncurkan perubahan ke server integrasi, turun 8 kali dari 10. Tidak ada yang memperhatikannya karena tidak ada umpan balik. Untuk pengembang, proses ini telah diimplementasikan untuk waktu yang lama, tetapi pesan tidak mencapai OPS (administrator sistem). Oleh karena itu, kami menambahkan Dashboard dengan rakitan proyek ini ke monitor besar di tempat yang menonjol di kantor. Di atasnya, berbagai proyek disorot dalam warna hijau - ini berarti bahwa segala sesuatunya sesuai dengannya. Jika disorot dengan warna merah berarti semuanya buruk dengannya. Kami melihat bahwa beberapa tes gagal. Pada presentasi, di sisi kiri yang kedua, dari atas kita melihat hasil dari depot penyebaran infrastruktur. . , , , . : - . . Slack , - - - .



Ok, , , - , . trunk based . Master — . Master CI (Teamcity) integration . CI , integration . release candidate. . . , end-to-end , staging . production. , staging .



. ? , PostgreSQL. 5 . , . 1-2 . . , PostgreSQL . PostgreSQL , staging, production 4 . , , . , . - .



git submodule Ansible . , . git submodule Ansible . inventories , . 30 . git submodule .



: , . , , , staging , . , , , , , , staging. — , , - .



6 . — 10 . . . , . - git submodule, . . , , , . , , .



.


-, , : , Ansible git , : “ , - ”. ? git . , . 100% . . .


, . . , RabbitMQ, ELK, . , ELK . , , ELK. ELK, , ELK .


, , , , . , , , , . , . .


. , , , , , , . git. , — git, , : , - . .


, , , code review. , , . , . , , , , , . , : . . . , - - .


, .


: , git submodule, . - , latest . inventories. — , . , , .. . — . .


: - Ansible ( A B, B C A, )? , ?


: . . , - IP , , , , . . , , , , , . , - , , , RabbitMQ RabbitMQ, . - , .


PS github . github . github — Pull request .

Source: https://habr.com/ru/post/id438748/


All Articles