رویکرد IaC (Infrastructure as Code) نه تنها شامل کدهایی است که در مخزن ذخیره می شود، بلکه شامل افراد و فرآیندهایی است که این کد را احاطه کرده اند. آیا امکان استفاده مجدد از رویکردها از توسعه نرم افزار تا مدیریت زیرساخت و شرح وجود دارد؟ بهتر است هنگام خواندن مقاله این ایده را در ذهن داشته باشید.
فرض کنید به یک پروژه جدید می آیید و آنها به شما می گویند: «ما داریم زیرساخت به عنوان کد". در واقعیت معلوم می شود زیرساخت به عنوان تاریخ bash یا مثلا مستندات به عنوان تاریخچه bash. این یک وضعیت بسیار واقعی است، به عنوان مثال، یک مورد مشابه توسط دنیس لیسنکو در یک سخنرانی توصیف شد چگونه کل زیرساخت را جایگزین کنیم و با آرامش شروع به خواب کنیم، او گفت که چگونه آنها یک زیرساخت منسجم برای پروژه از تاریخ bash بدست آورده اند.
با کمی میل می توانیم بگوییم زیرساخت به عنوان تاریخ bash این شبیه کد است:
تکرارپذیری: می توانید تاریخچه bash را بگیرید، دستورات را از آنجا اجرا کنید، و به هر حال، ممکن است یک پیکربندی کاری به عنوان خروجی دریافت کنید.
نسخه سازی: می دانید چه کسی وارد شده و چه کاری انجام داده است، باز هم، این یک واقعیت نیست که شما را به یک پیکربندی خروجی کاری هدایت کند.
история: داستان اینکه چه کسی چه کرده است. فقط در صورت از دست دادن سرور، نمی توانید از آن استفاده کنید.
چه کاری انجام دهید؟
زیرساخت به عنوان کد
حتی یک مورد عجیب مانند زیرساخت به عنوان تاریخ bash می توانید آن را از گوش ها بکشید زیرساخت به عنوان کد، اما وقتی می خواهیم کاری پیچیده تر از سرور خوب قدیمی LAMP انجام دهیم، به این نتیجه می رسیم که این کد باید به نحوی اصلاح، تغییر، بهبود یابد. در ادامه میخواهیم شباهتهای بین آنها را در نظر بگیریم زیرساخت به عنوان کد و توسعه نرم افزار
خشک
در یک پروژه توسعه سیستم ذخیره سازی، یک کار فرعی وجود داشت SDS را به صورت دوره ای پیکربندی کنید: ما در حال انتشار یک نسخه جدید هستیم - باید برای آزمایش بیشتر عرضه شود. کار بسیار ساده است:
در اینجا از طریق ssh وارد شوید و دستور را اجرا کنید.
فایل را در آنجا کپی کنید
تنظیمات را در اینجا اصلاح کنید
سرویس را از آنجا شروع کنید
...
سود!
برای منطق توصیف شده، bash بیش از حد کافی است، به خصوص در مراحل اولیه پروژه، زمانی که تازه شروع شده است. این بد نیست از bash استفاده کنید، اما با گذشت زمان درخواست هایی برای استقرار چیزی مشابه، اما کمی متفاوت وجود دارد. اولین چیزی که به ذهن می رسد کپی پیست است. و اکنون ما دو اسکریپت بسیار مشابه داریم که تقریباً یک کار را انجام می دهند. با گذشت زمان، تعداد اسکریپت ها افزایش یافت و ما با این واقعیت مواجه شدیم که منطق تجاری خاصی برای استقرار یک نصب وجود دارد که باید بین اسکریپت های مختلف هماهنگ شود، این بسیار پیچیده است.
به نظر می رسد که تمرینی مانند DRY (خودت را تکرار نکن) وجود دارد. ایده استفاده مجدد از کد موجود است. ساده به نظر می رسد، اما ما بلافاصله به این موضوع نرسیدیم. در مورد ما، این یک ایده پیش پا افتاده بود: جدا کردن تنظیمات از اسکریپت ها. آن ها منطق تجاری نحوه استقرار نصب به طور جداگانه، پیکربندی جداگانه.
جامد برای CFM
با گذشت زمان این پروژه رشد کرد و ادامه طبیعی ظهور Ansible بود. دلیل اصلی ظاهر آن این است که در تیم تخصص وجود دارد و bash برای منطق پیچیده طراحی نشده است. Ansible همچنین شروع به حاوی منطق پیچیده کرد. برای جلوگیری از تبدیل منطق پیچیده به هرج و مرج، اصولی برای سازماندهی کد در توسعه نرم افزار وجود دارد جامد همچنین، به عنوان مثال، گریگوری پتروف در گزارش خود با عنوان "چرا یک متخصص فناوری اطلاعات به یک برند شخصی نیاز دارد" این سوال را مطرح کرد که یک شخص به گونه ای طراحی شده است که کار با برخی از نهادهای اجتماعی برای او آسان تر است، در توسعه نرم افزار این موارد. اشیاء هستند. اگر این دو ایده را با هم ترکیب کنیم و به توسعه آنها ادامه دهیم، متوجه می شویم که می توانیم از آنها نیز استفاده کنیم جامد تا حفظ و اصلاح این منطق در آینده آسان تر شود.
اصل مسئولیت واحد
هر کلاس فقط یک کار را انجام می دهد.
بدون نیاز به ترکیب کد و ساختن هیولاهای اسپاگتی الهی یکپارچه. زیرساخت باید از آجرهای ساده تشکیل شده باشد. به نظر می رسد که اگر کتاب بازی Ansible را به قطعات کوچک تقسیم کنید، نقش های Ansible را بخوانید، نگهداری از آنها آسان تر است.
اصل بسته باز
اصل باز/بسته
Open to extension: به این معنی است که رفتار یک موجودیت را می توان با ایجاد انواع موجودیت جدید گسترش داد.
بسته به تغییر: در نتیجه گسترش رفتار یک موجودیت، هیچ تغییری نباید در کدی که از آن موجودیت ها استفاده می کند ایجاد شود.
در ابتدا، زیرساخت آزمایشی را روی ماشینهای مجازی مستقر کردیم، اما با توجه به اینکه منطق تجاری استقرار از پیادهسازی جدا بود، Rolling out را بدون هیچ مشکلی به baremetall اضافه کردیم.
اصل جایگزینی لیسکوف
اصل جایگزینی باربارا لیسکوف. اشیاء در یک برنامه باید با نمونه هایی از انواع فرعی خود بدون تغییر در اجرای صحیح برنامه قابل تعویض باشند.
اگر به طور گسترده تر به آن نگاه کنید، این ویژگی هیچ پروژه خاصی نیست که بتوان در آنجا اعمال کرد جامد، به طور کلی در مورد CFM است، به عنوان مثال، در یک پروژه دیگر لازم است یک برنامه جاوا جعبه ای در بالای جاواهای مختلف، سرورهای برنامه، پایگاه های داده، سیستم عامل و غیره مستقر شود. با استفاده از این مثال، اصول بیشتری را در نظر خواهم گرفت جامد
در مورد ما، توافقی در تیم زیرساخت وجود دارد که اگر نقش imbjava یا oraclejava را نصب کردهایم، یک فایل اجرایی باینری جاوا داریم. این امر ضروری است زیرا نقش های بالادستی به این رفتار بستگی دارد؛ آنها انتظار جاوا را دارند. در همان زمان، این به ما امکان می دهد بدون تغییر منطق استقرار برنامه، یک پیاده سازی/نسخه جاوا را با دیگری جایگزین کنیم.
مشکل در اینجا در این واقعیت نهفته است که اجرای آن در Ansible غیرممکن است، در نتیجه برخی توافقات در تیم ظاهر می شود.
اصل جداسازی رابط
اصل جداسازی رابط: «بسیاری از رابطهای خاص مشتری بهتر از یک رابط کاربری عمومی هستند.
در ابتدا، ما سعی کردیم همه تنوع استقرار برنامه را در یک کتاب بازی Ansible قرار دهیم، اما پشتیبانی از آن دشوار بود، و رویکرد زمانی که یک رابط خارجی داریم مشخص شده است (کلاینت از پورت 443 انتظار دارد)، سپس یک زیرساخت را می توان از فردی مونتاژ کرد. آجر برای اجرای خاص
اصل وارونگی وابستگی
اصل وارونگی وابستگی ماژولهای سطوح بالاتر نباید به ماژولهای سطوح پایینتر وابسته باشند. هر دو نوع ماژول باید به انتزاعات بستگی داشته باشند. انتزاع ها نباید به جزئیات بستگی داشته باشند. جزئیات باید به انتزاعات بستگی داشته باشد.
در اینجا مثال بر اساس یک آنتی الگو خواهد بود.
یکی از مشتریان یک ابر خصوصی داشت.
ما ماشین های مجازی داخل ابر سفارش دادیم.
اما با توجه به ماهیت ابر، استقرار برنامهها به Hypervisor مربوط به VM وابسته بود.
آن ها منطق استقرار برنامه های سطح بالا همراه با وابستگی ها به سطوح پایین تر هایپروایزر جریان داشت و این به معنای مشکلاتی در هنگام استفاده مجدد از این منطق بود. اینطوری انجام نده.
اثر متقابل
زیرساخت به عنوان کد نه تنها در مورد کد، بلکه در مورد رابطه بین کد و افراد، در مورد تعاملات بین توسعه دهندگان زیرساخت است.
فاکتور اتوبوس
بیایید فرض کنیم که شما Vasya را در پروژه خود دارید. واسیا همه چیز را در مورد زیرساخت شما می داند، اگر واسیا ناگهان ناپدید شود چه اتفاقی می افتد؟ این یک موقعیت بسیار واقعی است، زیرا ممکن است اتوبوس او را بزند. گاهی این اتفاق می افتد. اگر این اتفاق بیفتد و دانش در مورد کد، ساختار آن، نحوه کار، ظاهر و رمزهای عبور بین تیم توزیع نشود، ممکن است با تعدادی از موقعیتهای ناخوشایند مواجه شوید. برای به حداقل رساندن این خطرات و توزیع دانش در تیم، می توانید از رویکردهای مختلفی استفاده کنید
Devopsing جفت
اینطور نیست به عنوان یک شوخی، که ادمین ها آبجو می نوشند، رمز عبور را تغییر می دهند و برنامه نویسی آنالوگ جفت. آن ها دو مهندس پشت یک کامپیوتر، یک صفحه کلید می نشینند و با هم زیرساخت شما را راه اندازی می کنند: راه اندازی یک سرور، نوشتن یک نقش Ansible و غیره. خوب به نظر می رسد، اما برای ما کار نکرد. اما موارد خاص این عمل جواب داد. یک کارمند جدید می آید، مربی او یک کار واقعی را با او انجام می دهد، کار می کند و دانش را انتقال می دهد.
مورد خاص دیگر تماس حادثه است. در طول یک مشکل، گروهی از مأموران و دست اندرکاران جمع می شوند، یک رهبر منصوب می شود که صفحه نمایش خود را به اشتراک می گذارد و قطار افکار را به صدا در می آورد. سایر شرکتکنندگان افکار رهبر را دنبال میکنند، از ترفندهای کنسول جاسوسی میکنند، بررسی میکنند که خطی از گزارش را از دست ندادهاند، و چیزهای جدیدی در مورد سیستم یاد میگیرند. این رویکرد اغلب کارساز بود.
بررسی کد
از نظر ذهنی، انتشار دانش در مورد زیرساخت و نحوه عملکرد آن با استفاده از بررسی کد مؤثرتر بود:
زیرساخت با کد موجود در مخزن توضیح داده شده است.
تغییرات در یک شاخه جداگانه رخ می دهد.
در طول درخواست ادغام، می توانید دلتای تغییرات زیرساخت را مشاهده کنید.
نکته قابل توجه در اینجا این بود که داوران یک به یک بر اساس یک برنامه زمان بندی انتخاب شدند، یعنی. با درجاتی از احتمال، به یک زیرساخت جدید صعود خواهید کرد.
سبک کد
با گذشت زمان، دعواها در طول بررسی ها ظاهر شد، زیرا ... بازبین ها سبک خاص خود را داشتند و چرخش بازبینان آنها را با سبک های مختلف کنار هم می گذاشتند: 2 فاصله یا 4، camelCase یا snake_case. امکان اجرای آن به سرعت وجود نداشت.
ایده اول این بود که استفاده از لینتر را توصیه کنیم، بالاخره همه مهندس هستند، همه باهوش هستند. اما ویرایشگرهای مختلف، سیستم عامل، مناسب نیستند
این به رباتی تبدیل شد که برای هر commit مشکل دار می نوشت و خروجی لینتر را متصل می کرد. اما در بیشتر موارد کارهای مهم تری برای انجام وجود داشت و کد ثابت نمی ماند.
استاد ساخت سبز
زمان می گذرد و ما به این نتیجه رسیده ایم که commit هایی که تست های خاصی را پشت سر نمی گذارند نمی توانند وارد استاد شوند. وویلا! ما Green Build Master را اختراع کردیم که برای مدت طولانی در توسعه نرم افزار تمرین می شد:
توسعه در یک شعبه جداگانه در حال انجام است.
تست ها روی این تاپیک در حال اجراست.
اگر تستها ناموفق باشند، کد وارد Master نمیشود.
گرفتن این تصمیم بسیار دردناک بود، زیرا ... جنجال های زیادی به پا کرد، اما ارزشش را داشت، زیرا ... بررسی ها شروع به دریافت درخواست هایی برای ادغام بدون تفاوت در سبک کردند و با گذشت زمان تعداد مناطق مشکل شروع به کاهش کرد.
تست IaC
علاوه بر بررسی سبک، می توانید از چیزهای دیگری استفاده کنید، به عنوان مثال، برای بررسی اینکه زیرساخت شما واقعاً می تواند مستقر شود. یا بررسی کنید که تغییرات در زیرساخت منجر به از دست دادن پول نمی شود. چرا ممکن است این مورد نیاز باشد؟ سوال پیچیده و فلسفی است، بهتر است با یک داستان پاسخ دهیم که به نوعی یک مقیاس کننده خودکار در Powershell وجود داشت که شرایط مرزی را بررسی نمی کرد => ماشین های مجازی بیش از حد لازم ایجاد شد => مشتری بیش از برنامه ریزی شده پول خرج کرد. این خیلی خوشایند نیست، اما تشخیص این خطا در مراحل اولیه کاملاً ممکن است.
ممکن است پرسیده شود، چرا زیرساخت های پیچیده را پیچیده تر می کنیم؟ تستهای زیرساخت، درست مانند کد، در مورد سادهسازی نیستند، بلکه در مورد این هستند که بدانید زیرساخت شما چگونه باید کار کند.
هرم تست IaC
تست IaC: تجزیه و تحلیل استاتیک
اگر کل زیرساخت را به یکباره مستقر کنید و بررسی کنید که کار می کند، ممکن است متوجه شوید که زمان زیادی می برد و به زمان زیادی نیاز دارد. بنابراین، اساس باید چیزی باشد که به سرعت کار کند، تعداد زیادی از آن وجود دارد و بسیاری از مکان های ابتدایی را پوشش می دهد.
Bash مشکل است
بیایید به یک مثال بی اهمیت نگاه کنیم. تمام فایل های موجود در فهرست فعلی را انتخاب کرده و در مکان دیگری کپی کنید. اولین چیزی که به ذهن می رسد:
for i in * ; do
cp $i /some/path/$i.bak
done
اگر یک فاصله در نام فایل وجود داشته باشد چه؟ خوب، خوب، ما باهوشیم، می دانیم چگونه از نقل قول استفاده کنیم:
for i in * ; do cp "$i" "/some/path/$i.bak" ; done
آفرین؟ نه! چه می شود اگر چیزی در دایرکتوری وجود نداشته باشد، یعنی. globbing کار نخواهد کرد
find . -type f -exec mv -v {} dst/{}.bak ;
حالا خوب شد؟ نه... فراموش کرده اید که نام فایل چه چیزی می تواند باشد n.
touch x
mv x "$(printf "foonbar")"
find . -type f -print0 | xargs -0 mv -t /path/to/target-dir
ابزارهای تحلیل استاتیکی
مشکل مرحله قبل زمانی قابل تشخیص است که ما نقل قول ها را فراموش کردیم، برای این کار در طبیعت راه حل های زیادی وجود دارد. Shellcheck، به طور کلی تعداد زیادی از آنها وجود دارد، و به احتمال زیاد می توانید یک لنگر برای پشته خود در زیر IDE خود پیدا کنید.
همانطور که در مثال قبلی دیدیم، لینترها همه کاره نیستند و نمی توانند به همه مناطق مشکل اشاره کنند. علاوه بر این، با قیاس با آزمایش در توسعه نرم افزار، می توانیم تست های واحد را به یاد بیاوریم. چیزی که بلافاصله به ذهن می رسد این است اجتناب کردن, یونیت, rspec, دزدگیر. اما با ansible، سرآشپز، saltstack و امثال آنها چه باید کرد؟
در همان ابتدا در مورد آن صحبت کردیم جامد و اینکه زیرساخت های ما باید از آجرهای کوچک تشکیل شود. زمان آنها فرا رسیده است.
زیرساخت به آجرهای کوچک تقسیم می شود، به عنوان مثال، نقش های Ansible.
نوعی محیط مستقر شده است، خواه داکر یا ماشین مجازی.
ما نقش Ansible خود را در این محیط تست اعمال می کنیم.
ما بررسی می کنیم که همه چیز همانطور که انتظار داشتیم کار می کرد (تست ها را اجرا می کنیم).
ما تصمیم می گیریم خوب است یا نه.
IaC Testing: ابزارهای تست واحد
سوال، تست های CFM چیست؟ شما می توانید به سادگی اسکریپت را اجرا کنید یا می توانید از راه حل های آماده برای این کار استفاده کنید:
به عنوان مثال برای testinfra، بررسی کاربران test1, test2 وجود دارند و در یک گروه هستند sshusers:
def test_default_users(host):
users = ['test1', 'test2' ]
for login in users:
assert host.user(login).exists
assert 'sshusers' in host.user(login).groups
چه چیزی را انتخاب کنیم؟ سوال پیچیده و مبهم است، در اینجا نمونه ای از تغییرات در پروژه های github برای 2018-2019 آورده شده است:
چارچوب های تست IaC
این سوال پیش می آید: چگونه می توان همه آن را کنار هم گذاشت و راه اندازی کرد؟ می توان بگیر و خودت انجامش بده در صورت وجود تعداد کافی مهندس یا می توانید راه حل های آماده را انتخاب کنید ، اگرچه تعداد زیادی از آنها وجود ندارد:
مرحله بعدی انتقال به جنکینز / داکر / آنزیل / مولکول بود. از نظر ایدئولوژیک همه چیز یکسان است
کتاب های بازی لینت.
نقش ها را ردیف کنید.
کانتینر پرتاب
نقش های Ansible را اعمال کنید.
testinfra را اجرا کنید.
ناتوانی را بررسی کنید
پرز زدن برای 40 نقش و آزمایش برای یک دوجین حدود 15 دقیقه طول کشید.
اینکه چه چیزی را انتخاب کنید به عوامل زیادی مانند پشته استفاده شده، تخصص در تیم و غیره بستگی دارد. در اینجا هر کس برای خود تصمیم می گیرد که چگونه سوال تست واحد را ببندد
تست IaC: تست های یکپارچه سازی
مرحله بعدی در هرم تست زیرساخت، تست های یکپارچه سازی خواهد بود. آنها مشابه تست های واحد هستند:
زیرساخت به آجرهای کوچک تقسیم می شود، به عنوان مثال نقش های Ansible.
نوعی محیط مستقر شده است، خواه داکر یا ماشین مجازی.
برای این محیط تست اعمال شود مجموعه ای از نقش های قابل قبول
ما بررسی می کنیم که همه چیز همانطور که انتظار داشتیم کار می کرد (تست ها را اجرا می کنیم).
ما تصمیم می گیریم خوب است یا نه.
به طور کلی، ما عملکرد یک عنصر منفرد از سیستم را مانند تست های واحد بررسی نمی کنیم، ما نحوه پیکربندی سرور را به طور کلی بررسی می کنیم.
تست IaC: تست های پایان به پایان
در بالای هرم با آزمونهای End to End استقبال میشویم. آن ها ما عملکرد یک سرور جداگانه، یک اسکریپت جداگانه یا یک آجر جداگانه از زیرساخت خود را بررسی نمی کنیم. ما بررسی می کنیم که بسیاری از سرورها به هم متصل هستند، زیرساخت ما همانطور که انتظار داریم کار می کند. متأسفانه، من هرگز راه حل های جعبه ای آماده را ندیده ام، احتمالاً به دلیل ... زیرساخت اغلب منحصر به فرد است و قالب بندی و ایجاد چارچوبی برای آزمایش دشوار است. در نتیجه هرکس راه حل های خود را ایجاد می کند. تقاضا هست ولی جوابی نیست. بنابراین، من به شما خواهم گفت که چه چیزی وجود دارد تا دیگران را به افکار سالم وادار کنم یا بینی ام را بمالم در این واقعیت که همه چیز مدت ها قبل از ما اختراع شده است.
پروژه ای با سابقه ای غنی. در سازمان های بزرگ استفاده می شود و احتمالاً هر یک از شما به طور غیرمستقیم با آن برخورد کرده اید. این برنامه از بسیاری از پایگاه های داده، ادغام ها و غیره پشتیبانی می کند. دانستن اینکه زیرساخت ممکن است شبیه به چه شکلی باشد، فایلهای docker-compose زیادی است، و دانستن اینکه کدام آزمایشها در کدام محیط اجرا شوند، جنکینز است.
این طرح برای مدت طولانی کار کرد، تا اینکه در چارچوب پژوهش ما سعی نکرده ایم این را به Openshift منتقل کنیم. کانتینرها ثابت می مانند، اما محیط پرتاب تغییر کرده است (دوباره DRY سلام).
ایده تحقیق فراتر رفت و در openshift چیزی به نام APB (Ansible Playbook Bundle) پیدا کردند که به شما امکان می دهد دانش مربوط به نحوه استقرار زیرساخت را در یک کانتینر بسته بندی کنید. آن ها یک نقطه قابل تکرار و آزمایشی از دانش در مورد چگونگی استقرار زیرساخت وجود دارد.
همه اینها تا زمانی که به یک زیرساخت ناهمگن برخوردیم خوب به نظر می رسید: ما برای آزمایش به ویندوز نیاز داشتیم. در نتیجه، دانش چه، کجا، چگونه استقرار و آزمایش در جنکین ها وجود دارد.