آیا داکر یک اسباب بازی است یا نه؟ یا هنوز درسته؟

خوش آمدید!

من واقعاً می خواهم مستقیماً به موضوع بپردازم، اما درست تر است که کمی در مورد داستان خود بگویم:

ورود

من یک برنامه نویس با تجربه در توسعه اپلیکیشن های تک صفحه ای frontend، scala/java و nodej در سرور هستم.

برای مدت طولانی (قطعاً یکی دو یا سه سال)، من بر این عقیده بودم که Docker یک مانا از بهشت ​​است و به طور کلی یک ابزار بسیار جالب است و مطلقاً هر توسعه دهنده ای باید بتواند از آن استفاده کند. و از این نتیجه می شود که هر توسعه دهنده باید Docker را روی دستگاه محلی خود نصب کند. نظر من چیه، جاهای خالی که در همون hh پست شده رو نگاه کن. هر ثانیه حاوی ذکری از داکر است و اگر مالک آن هستید، این مزیت رقابتی شما خواهد بود

در مسیرم با افراد زیادی آشنا شدم که نگرش های متفاوتی نسبت به داکر و اکوسیستم آن داشتند. برخی گفتند که این یک چیز راحت است که عملکرد چند پلتفرمی را تضمین می کند. دومی ها نفهمیدند چرا باید در کانتینرها بدوند و چه سودی از آن حاصل می شود، سومی اصلاً اهمیتی نمی دهد و اذیت نمی شود (فقط کد را نوشتند و به خانه رفتند - من به آنها حسادت می کنم. مسیر :)

دلایل استفاده

چرا از داکر استفاده کردم؟ احتمالا به دلایل زیر:

  • راه اندازی پایگاه داده، 99٪ از برنامه ها از آنها استفاده می کنند
  • راه اندازی nginx برای توزیع فرانت اند و پروکسی به باطن
  • شما می توانید برنامه را در یک تصویر داکر بسته بندی کنید، به این ترتیب برنامه من در هر کجا که داکر وجود داشته باشد کار می کند، مشکل توزیع بلافاصله حل می شود
  • کشف سرویس خارج از جعبه، شما می توانید میکروسرویس ایجاد کنید، هر ظرف (متصل به یک شبکه مشترک) می تواند به راحتی از طریق نام مستعار به دیگری برسد، بسیار راحت
  • ایجاد یک ظرف و "بازی" در آن سرگرم کننده است.

چیزی که من همیشه در مورد داکر دوست ندارم:

  • برای اینکه برنامه من کار کند، به خود Docker روی سرور نیاز دارم. اگر برنامه های من روی jre یا nodejs اجرا می شوند و محیط آنها از قبل روی سرور است، چرا به این نیاز دارم؟
  • اگر بخواهم تصویر (خصوصی) محلی خود را روی یک سرور راه دور اجرا کنم، به مخزن docker خودم نیاز دارم، به رجیستری نیاز دارم تا در جایی کار کند و همچنین باید https را پیکربندی کنم، زیرا docker cli فقط روی https کار می کند. اوه لعنتی... البته گزینه هایی برای ذخیره تصویر به صورت محلی از طریق وجود دارد docker save و فقط تصویر را از طریق scp بفرستید... اما این حرکات بدن زیاد است. و علاوه بر این، تا زمانی که مخزن خود شما ظاهر شود، مانند یک راه حل "عصا" به نظر می رسد
  • docker-compose. فقط برای اجرای ظروف مورد نیاز است. همین. او کار دیگری نمی تواند بکند. Docker-compose مجموعه ای از نسخه های فایل های خود، نحو خاص خود را دارد. هر چقدر هم که اعلامی باشد، نمی خواهم مستندات آنها را بخوانم. هیچ جای دیگه ای بهش نیاز نخواهم داشت
  • هنگام کار در یک تیم، اکثر مردم یک Dockerfile را بسیار کج می نویسند، نمی دانند چگونه آن را در حافظه پنهان ذخیره می کنند، هر آنچه را که نیاز دارند و نیازی ندارند به تصویر اضافه می کنند، از تصاویری که در Dockerhub یا یک مخزن خصوصی نیستند ارث می برند، برخی از آنها را ایجاد می کنند. docker-compose فایل ها با پایگاه داده و هیچ چیز باقی نمی ماند. در همان زمان، توسعه دهندگان با افتخار اعلام می کنند که Docker عالی است، همه چیز به صورت محلی برای آنها کار می کند، و HR به طور مهمی در جای خالی می نویسد: "ما از Docker استفاده می کنیم و به یک نامزد با چنین تجربه کاری نیاز داریم."
  • من دائماً درگیر افکاری در مورد بالا بردن همه چیز در Docker هستم: postgresql، kafka، redis. حیف که همه چیز در کانتینرها کار نمی کند، پیکربندی و اجرا همه چیز آسان نیست. این توسط توسعه دهندگان شخص ثالث پشتیبانی می شود و نه توسط خود فروشندگان. و به هر حال، بلافاصله این سوال مطرح می شود: فروشندگان نگران نگهداری محصولات خود در Docker نیستند، چرا اینطور است، شاید آنها چیزی می دانند؟
  • این سوال همیشه در مورد تداوم داده های کانتینر مطرح می شود. و سپس شما فکر می کنید، آیا من فقط دایرکتوری میزبان را سوار کنم یا یک حجم داکر ایجاد کنم یا یک محفظه داده بسازم که اکنون deprecated? اگر دایرکتوری را مونت کنم، باید مطمئن شوم که uid و gid کاربر در کانتینر با شناسه کاربری که کانتینر را راه اندازی کرده است مطابقت دارد، در غیر این صورت فایل های ایجاد شده توسط کانتینر با حقوق ریشه ایجاد می شوند. اگر استفاده کنم volume سپس داده ها به سادگی در برخی ایجاد می شوند /usr/* و همان داستان با uid و gid مانند مورد اول وجود خواهد داشت. اگر کامپوننت شخص ثالثی را راه‌اندازی می‌کنید، باید مستندات را بخوانید و به دنبال پاسخ این سؤال بگردید: «کامپوننت در کدام فهرست‌های کانتینر فایل‌ها را می‌نویسد؟»

من همیشه از این واقعیت خوشم نمی آمد که باید برای مدت طولانی با داکر سر و کله بزنم در مرحله اولیه: من متوجه شدم که چگونه کانتینرها را راه اندازی کنم، از چه تصاویری راه اندازی کنم، Makefiles ساختم که حاوی نام مستعار برای دستورات طولانی Docker است. من از docker-compose متنفر بودم زیرا نمی‌خواستم ابزار دیگری را در اکوسیستم docker یاد بگیرم. و docker-compose up من را آزار می داد، به خصوص اگر آنها هنوز آنجا ملاقات می کردند build ساخت و سازها، به جای تصاویر از قبل مونتاژ شده. تنها چیزی که واقعاً می خواستم این بود که فقط یک محصول کارآمد و سریع بسازم. اما نتونستم بفهمم چطور از داکر استفاده کنم.

معرفی Ansible

اخیرا (سه ماه پیش)، من با یک تیم DevOps کار کردم که تقریباً همه اعضای آن نگرش منفی نسبت به Docker داشتند. به دلایل:

  • docker قوانین iptables (اگرچه می توانید آن را در daemon.json غیرفعال کنید)
  • داکر باگ است و ما آن را در مرحله تولید اجرا نخواهیم کرد
  • اگر داکر دیمون از کار بیفتد، تمام کانتینرهای دارای زیرساخت بر این اساس خراب می شوند
  • بدون نیاز به داکر
  • چرا داکر اگر Ansible و ماشین های مجازی وجود دارد

در همان کار، با ابزار دیگری آشنا شدم - Ansible. من یک بار در مورد آن شنیده بودم، اما سعی نکردم کتاب های بازی خودم را بنویسم. و حالا شروع کردم به نوشتن وظایفم و بعد دیدم کاملا عوض شد! چون متوجه شدم: Ansible ماژول هایی برای اجرای همان داکر کانتینرها، ساخت تصاویر، شبکه ها و غیره دارد و کانتینرها نه تنها به صورت محلی، بلکه روی سرورهای راه دور نیز قابل اجرا هستند! لذت من هیچ حد و مرزی نداشت - یک ابزار NORMAL پیدا کردم و فایل های Makefile و docker-compose خود را دور انداختم، آنها با وظایف yaml جایگزین شدند. کد با استفاده از ساختارهایی مانند کاهش یافت loop, when، و غیره

داکر برای اجرای اجزای شخص ثالث مانند پایگاه داده

اخیرا با تونل های ssh آشنا شدم. معلوم شد که انتقال پورت یک سرور راه دور به یک پورت محلی بسیار آسان است. سرور راه دور می تواند یک ماشین در فضای ابری یا یک ماشین مجازی در حال اجرا در VirtualBox باشد. اگر من یا همکارم به یک پایگاه داده (یا یک مؤلفه شخص ثالث دیگر) نیاز داریم، می توانیم به سادگی سرور را با این مؤلفه راه اندازی کنیم و در صورت عدم نیاز به سرور، آن را خاموش کنیم. ارسال پورت همان اثری را می دهد که یک پایگاه داده در یک کانتینر داکر اجرا می شود.

این دستور پورت محلی من را به یک سرور راه دور در حال اجرا postgresql هدایت می کند:

ssh -L 9000:localhost:5432 [ایمیل محافظت شده]

استفاده از سرور راه دور مشکل توسعه تیم را حل می کند. چنین سروری می تواند توسط چندین توسعه دهنده به طور همزمان استفاده شود؛ آنها نیازی به پیکربندی postgresql، درک Docker و سایر پیچیدگی ها ندارند. در یک سرور راه دور، اگر نصب یک نسخه خاص دشوار است، می توانید همان پایگاه داده را در خود داکر نصب کنید. تنها چیزی که توسعه دهندگان نیاز دارند ارائه دسترسی ssh است!

اخیراً خواندم که تونل های SSH یک عملکرد محدود یک VPN معمولی هستند! شما می توانید به سادگی OpenVPN یا سایر پیاده سازی های VPN را نصب کنید، زیرساخت را راه اندازی کنید و آن را برای استفاده در اختیار توسعه دهندگان قرار دهید. این خیلی باحاله!

خوشبختانه، AWS، GoogleCloud و دیگران به شما یک سال استفاده رایگان می دهند، بنابراین از آنها استفاده کنید! اگر زمانی که استفاده نمی کنید آنها را خاموش کنید ارزان هستند. من همیشه فکر می کردم که چرا به یک سرور راه دور مانند gcloud نیاز دارم، به نظر می رسد که آنها را پیدا کردم.

به عنوان یک ماشین مجازی محلی، می توانید از همان Alpine استفاده کنید که به طور فعال در کانتینرهای docker استفاده می شود. خوب، یا برخی توزیع های سبک وزن دیگر برای اینکه دستگاه سریعتر بوت شود.

خط پایین: شما می‌توانید و باید پایگاه‌های داده و سایر موارد زیرساختی را روی سرورهای راه دور یا در جعبه مجازی اجرا کنید. من برای این اهداف نیازی به داکر ندارم.

کمی در مورد تصاویر داکر و توزیع

قبلاً نوشتم یک مقاله که در آن می خواستم بگویم که استفاده از تصاویر داکر هیچ تضمینی را ارائه نمی دهد. تصاویر Docker فقط برای ایجاد یک داکر کانتینر مورد نیاز است. اگر در حال ارتقا به یک تصویر docker هستید، پس در حال ارتقا برای استفاده از کانتینرهای docker هستید و فقط از آنها استفاده خواهید کرد.

آیا جایی دیده‌اید که توسعه‌دهندگان نرم‌افزار محصولات خود را فقط در یک تصویر داکر منتقل کنند؟
نتیجه اکثر محصولات فایل های باینری برای یک پلتفرم خاص است؛ آنها به سادگی به تصویر داکر اضافه می شوند که از پلتفرم مورد نظر به ارث رسیده است. آیا تا به حال فکر کرده اید که چرا این همه تصاویر مشابه در dockerhub وجود دارد؟ برای مثال وارد nginx شوید، 100500 تصویر از افراد مختلف خواهید دید. این افراد خود nginx را توسعه ندادند، آنها به سادگی nginx رسمی را به تصویر داکر خود اضافه کردند و آن را با تنظیمات خود چاشنی کردند تا به راحتی در راه اندازی کانتینرها استفاده شود.

به طور کلی، شما می توانید آن را به سادگی در tgz ذخیره کنید، اگر کسی نیاز دارد آن را در docker اجرا کند، سپس اجازه دهید tgz را به Dockerfile اضافه کند، از محیط مورد نظر ارث ببرد و bun های اضافی ایجاد کند که خود برنامه را در tgz تغییر ندهد. هر کسی که یک تصویر docker ایجاد کند، می داند tgz چیست و برای کار به چه چیزی نیاز دارد. این روشی است که من از داکر استفاده می کنم اینجا

خط آخر: من به رجیستری docker نیازی ندارم، از نوعی S3 یا فقط ذخیره سازی فایل مانند google drive/dropbox استفاده خواهم کرد.

داکر در CI

تمام شرکت هایی که من در آنها کار کرده ام شبیه به هم هستند. آنها معمولا خواربار فروشی هستند. یعنی یک برنامه کاربردی دارند، یک پشته فناوری (خوب، شاید چند یا سه زبان برنامه نویسی).

این شرکت ها از داکر در سرورهای خود استفاده می کنند که در آن فرآیند CI اجرا می شود. سوال: چرا باید پروژه ها را در یک داکر کانتینر روی سرورهای خود بسازید؟ چرا فقط یک محیط برای بیلد آماده نمی کنید، مثلاً یک Ansible playbook بنویسید که نسخه های ضروری nodejs، php، jdk، کپی کلیدهای ssh و غیره را روی سروری که ساخت در آن انجام می شود نصب کند؟

حالا فهمیدم که این تیراندازی به پای خودم است، زیرا داکر با انزوا کردنش هیچ سودی به همراه ندارد. مشکلاتی که من با CI در داکر مواجه شدم:

  • دوباره برای ساختن به یک تصویر داکر نیاز دارید. شما باید به دنبال یک تصویر بگردید یا فایل docker خود را بنویسید.
  • 90% این است که شما باید برخی از کلیدهای ssh را فوروارد کنید، داده‌های مخفی که نمی‌خواهید روی تصویر داکر بنویسید.
  • ظرف ایجاد می شود و می میرد، تمام حافظه های پنهان همراه با آن از بین می روند. ساخت بعدی همه وابستگی های پروژه را دوباره دانلود می کند که زمان بر و بی اثر است و زمان پول است.

توسعه‌دهندگان پروژه‌ها را در کانتینرهای docker نمی‌سازند (من زمانی چنین طرفدار بودم، واقعاً در xD گذشته برای خودم متاسفم). در جاوا این امکان وجود دارد که چندین نسخه داشته باشید و با یک دستور آنها را به نسخه مورد نیاز خود تغییر دهید. در nodejs هم همینطور است، nvm وجود دارد.

نتیجه

من معتقدم که docker یک ابزار بسیار قدرتمند و انعطاف پذیر است، این نقطه ضعف آن است (به نظر عجیب می رسد، بله). با کمک آن، شرکت ها می توانند به راحتی به آن قلاب شوند و در جاهایی که لازم است و غیر ضروری از آن استفاده کنند. توسعه‌دهندگان کانتینرها، برخی از محیط‌هایشان را راه‌اندازی می‌کنند، سپس همه به آرامی وارد CI و تولید می‌شوند. تیم DevOps در حال نوشتن نوعی کد برای اجرای این کانتینرها است.

فقط روی داکر استفاده کنید تازه ترین مرحله در گردش کار خود را، در ابتدا آن را به پروژه بکشید. مشکلات تجاری شما را حل نخواهد کرد. او فقط مشکلات را به سطح دیگری منتقل می کند و راه حل های خود را ارائه می دهد، شما کار مضاعف انجام خواهید داد.

زمانی که داکر مورد نیاز است: من به این نتیجه رسیدم که داکر در بهینه سازی یک فرآیند معین بسیار خوب است، اما در ساخت عملکردهای اساسی نه

اگر هنوز تصمیم به استفاده از docker دارید، پس:

  • بسیار مراقب باشید
  • توسعه دهندگان را مجبور به استفاده از docker نکنید
  • استفاده از آن را در یک مکان محلی کنید، آن را در تمام مخازن Dockfile و docker-compose پخش نکنید

PS:

از خواندن شما متشکرم، برای شما آرزوی تصمیمات شفاف در امور و روزهای کاری پربار دارم!

منبع: www.habr.com

اضافه کردن نظر