یکی از موضوع‌های چالش‌برانگیز توی کانتینرها، موضوع حافظه پایداره.
شما اگر بخواین یک برنامه‌ی stateful بسازین، حتما به وجود اون نیاز دارین.
(یعنی برنامه‌ای که دارای state باشه و توی هر state به اطلاعات و داده‌های state قبلی نیاز داشته باشیم.)
توی این پست می‌خوایم چالش‌هایی که در مورد حافظه پایدار توی کانتینرها وجود داره رو بررسی کنیم.

تجدید نظر در مورد حافظه

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

  • نیاز کاربردی به نوعی حافظه برای استفاده در کانتینر

Taskهای نرم‌افزاری زیادی وجود داره که برای پردازش به یک حافظه موقت احتیاج دارن.
با این حال می‌شه این taskها رو بدون استفاده از حافظه پردازش کرد اما این کار باعث میشه که پیچیدگی‌هایی غیرضروری توی اجرای برنامه به وجود بیاد.

  • استفاده طولانی مدت از کانتینرها: 

در عمل ما از کانتینرها برای مدت زمان‌های طولانی مثل چند ساعت و یا حتی بیشتر از اون استفاده می‌کنیم.
هرچقدر که یک کانتینر بیشتر مورد استفاده قرار داشته باشه، احتمال اینکه به حافظه نیاز پیدا کنه بیشتر میشه.
مثلا برای ذخیره‌سازی موقت محاسبات یا نگهداری اطلاعات مرتبط با یک وضعیت و یا هر هدف دیگه‌ای.

  • نیاز کانتینرها به اشتراک گذاری داده ها:

از همه مهمتر، در اکثر مواقع لازمه که چند کانتینر باهمدیگه کار کنن و معمولا "با هم کار کردن" به معنیِ اشتراک گذاری داده‌هاست.
آسونترین و بهترین راه هم برای اشتراک‌گذاری داده، استفاده از یک حافظه‌ی اشتراکیه. کمبود یا نبود این نوع حافظه باعث میشه که کار اشتراک‌گذاری، خیلی سخت بشه.

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

تیم داکر، توسعه‌دهنده‌های شخص سوم و ارائه‌دهنده‌های فضای ذخیره‌سازی، سعی کردن راه‌کارهای مختلفی رو برای حل کردن چالش فضای حافظه‌ی پایدار توی کانتینرها ارائه بدن، که با هم اون‌ها رو بررسی می‌کنیم:

حافظه‌ی بلوکی انعطاف پذیر آمازون (Amazon Elastic Block Store)

حافظه‌ی بلوکی انعطاف پذیر آمازون (Amazon EBS) به صورت بلوکی فضاهای ذخیره‌سازی رو برای استفاده توی نمونه‌های Amazon EC2 ارائه میده.
هر فضا از این حافظه‌ها به صورت خودکار توی مناطق جغرافیایی مختلف کپی و تکرار میشه تا هم دسترسی پذیری و ماندگاری رو بالا بره و هم در مقابل خرابی از برنامه‌های شما محافظت بشه. 
 به طور کلی حافظه‌های بلوکی آمازون یکپارچه و بدون تاخیر عمل می‌کنن و گزینه مناسبی برای اجرای workload های مختلف هستن.
شما میتونین با استفاده از این سرویس در کمترین زمان ممکن میزان مصرفتون رو تغییر بدین.
همینطور فقط برای اون چیزی که استفاده کردین هزینه پرداخت کنین.

بهتره بگیم Amazon EBS برای برنامه هایی طراحی شده که از تعادل بین عملکرد، هزینه و ظرفیت، سود می برن.
موارد معمول استفاده از این سرویس شامل موارد زیر هستن:
موتورهای آنالیز بیگ دیتا
(مانند اکوسیستم Hadoop/HDFS و کلاسترAmazon EMR)
پایگاه داده های رابطه ای NoSQL
(مانند Microsoft SQL Server و MySQL یا Cassandra و MongoDB)
نرم افزار های پردازش گزارش ها و جریان ها
(مانند Kafkaو Splunk)
نرم افزارهای ذخیره و انبارسازی داده
(مانند Verticaو Teradata)

Kubernetes

این روزا Kubernetes یکی از محبوب‌ترین ابزارهای مدیریت کانتینره و طرفدارای زیادی داره. 
Kubernetesیک فضای پایداررو مورد استفاده قرار میده و یک APIدر اختیار کاربران و ادمین‌ها قرار می‌ده که جزئیات نحوه‌ی ارائه فضای ذخیره سازی رو از چگونگی مصرف اون فضا مجزا می‌کنه.

چریل هانگ در مورد حافظه پایدار با Kubernetes صحبت های جالبی کرده.
اگر دوست داشته باشین می‌تونین این مصاحبه رو از طریق این لینک مشاهده کنین.
از طریق  این لینک هم می‌تونین به آموزش چگونگی کانفیگ کردن Pod برای استفاده از حافظه پایدار، دسترسی داشته باشین.

فضاهای داده‌ای داکر

داکر برای حافظه‌ی استفاده شده توی کانتینرهای شخصی، فضاهای داده‌ای رو ارائه میده.
این فضاها به کانتینر این امکان رو میدن تا بتونه از یک حافظه مجازی پایدار که از حافظه میزبان جداست، استفاده کنه.

این فضاهای مجازی توی یک ساختمان فایل کانتینر استاندارد تجمیع شدن که این باعث میشه دسترسی به اون‌ها راحت بشه.
البته این داده‌ها نمی‌تونن با سایر کانتینرها به اشتراک گذاشته بشن و یا به وسیله‌ی نمونه‌های بعدی همون کانتینر مورد استفاده قرار بگیرن.

استفاده از سیستم فایل میزبان(host) 

روش‌های دیگه‌ای هم توی زمینه حافظه پایدار وجود داره که این امکان رو به کانتینر میده  که به طور مستقیم‌تری از سیستم فایل میزبان استفاده کنه و از اون لایه‌ی جداکننده‌ی فضاهای داده داکر خبری نباشه.
بستگی به روشی که در مورد دسترسی به سیستم فایل میزبان ارائه میشه، کانتینر میتونه داده‌ها رو با سایر کانتینرها به اشتراک بذاره و یا در اختیار نمونه‌های دیگه‌ای از همون کانتینر قرار بده.
البته اگه مدیریت حافظه و فایل به خوبی با کانتینر و سیستم میزبان هماهنگ نشه، ممکنه داده‌ها overwrite بشن و یا خرابی‌های دیگه‌ای بوجود بیاد.

همه می‌تونن از فضای ذخیره‌سازی استفاده کنن

یک روش پیچیده ولی فراگیر، اینه که بیایم یک سیستم از حافظه‌های مجازی درست کنیم که بتونه به وسیله چند کانتینر مورد استفاده قرار بگیره و در طول زمان حتی با وجود از بین رفتن یک کانتینر از بین نره.
فضای ذخیره‌سازی توی این مدل توسط یک پلاگین مدیریت میشه که به عنوان یک درایور سیستم حافظه سطح بالا عمل می‌کنه.
این پلاگین یک یا چند لایه‌ی انتزاعی بین سیستم فایل‌های میزبان و سیستم فایلی که به وسیله‌ی کانتینر دیده میشه، قرار میده.

در حال حاضر پلاگین‌ها و روش‌های بسته‌بندی حافظه مبتنی بر پلاگین مختلفی وجود داره که به وسیله‌ی فروشنده‌ها و سرویس‌دهنده‌های شخص ثالث ارائه می‌شن.
این پلاگین‌ها به کانتینرها این امکان رو میدن  تا بتونن از گستره کلی سیستم‌های ذخیره سازی مبتنی بر ابر مثل block storage و object storage، استفاده کنن.

یک پلاگین معمولا سیستم حافظه انتزاعی خودش رو روی حافظه سیستم میزبان ایجاد میکنه.
اما چی میشه اگر که یک کانتینر به طور خودکار به یک سرور دیگه منتقل بشه؟
این موضوع میتونه یه مساله جدی باشه!
چرا که کانتینرها ممکنه دفعات زیاد و به دلایل مختلف جابه جا بشن.

اگر پلاگینی روی یک سرور خاص درحال اجرا باشه و به حافظه‌ی اون سرور اشاره کنه؛کانتینری که در حال استفاده از اون پلاگین باشه اگر به سرور دیگه‌ای انتقال داده بشه، نمی‌تونه به حافظه‌ی پایدار سرور قبلی دسترسی داشته باشه.
پلاگین هایی مثل Rook یا StorageOs (یا NFS برای مصارف داخلی) اجازه می‌دن تا حافظه پایدار به صورت مجزا به همراه کانتینر جا به جا بشه.
پس ارتباط کانتینر و حافظه قطع نمی‌شه. 

کنترل بهتر 

انتظار میره که حافظه پایدار به یک حافظه مجزا و مجازی، با لایه های پیچیده برای مدیریت حافظه سیستم میزبان در سطح سخت افزاری، تبدیل بشه.
مثلا یک سیستم حافظه ممکنه با توجه به نوع داده و نیاز نرم افزار کانتینر شده به دسترسی سریع به داده‌ها، داده ها رو بین حافظه پر سرعت SSD و حافظه کم سرعت آرشیوی جا به جا کنه.

استراتژی کنونی سکو 

در حال حاضر، شرایط همچنان پیچیده باقی مونده.
ما با طیف گسترده ای از راه حل‌ها برای استفاده از حافظه پایدار رو به رو  هستیم. همونطور که بالاتر اشاره کردیم چند کانتینر ممکنه نیاز داشته باشن به یک فضا دسترسی داشته باشن.
اما ممکنه این کانتینرها بین میزبان‌های مختلف جابجا بشن!
پس ما به یک فضای مشترک قابل دسترسی برای همه‌ی کانتینر‌ها  که بین همه‌ی میزبان‌هامون جابجا میشن، نیاز داریم که بتونیم داده‌های کاربر رو ذخیره کنیم!


سکو با استفاده از پلاگین‌های معرفی شده و شخصی‌سازی اون‌ها، یک حافظه‌ی ثابت به برنامه شما تخصیص می‌ده.
این حافظه بین همه‌ی کانتینرهای برنامه شما مشترک و قابل دسترسیه!
به عنوان مثال شما برای برنامتون مشخص می‌کنین که داده‌های مسیر mnt/app/ ، بین همه کانتینرها مشترک باشه و با جابجایی کانتینر یا اجرای مجدد برنامه، این داده‌ها از بین نره!
در‌واقع سکو فضای اشتراکی رو به عنوان Storage as a Service در اختیار برنامه‌هایی قرار می‌ده که نیاز به این فضای اشتراکی دارن!