imagePullPolicy
هنگام ساختن پاد در کوبرنتیز میشه با استفاده از فیلد imagePullPolicy تعیین کرد که چه رفتاری با imageی که برای ساختن کانتینر مشخص شده داشته باشه. در حالت کلی این فیلد سه مقدار Always، IfNotPresent و Never رو میتونه داشته باشه. یه مرور کوتاه میکنیم به خاصیتی که هر کدوم از این مقادیر دارن.
- Always: باعث میشه image فارغ از اینکه روی سرور وجود داره یا نه دوباره از ریجستری pull بشه.
- IfNotPresent: در این حالت ابتدا سرور چک میشه و اگر image به صورت لوکال وجود نداشته باشه اقدام به pull کردن از ریجستری میکنه.
- Never: در این حالت فقط لوکال رو به دنبال image میگرده و اگر وجود نداشته باشه هیچ تلاشی برای pull کردن اون از هیچ ریجستری انجام نمیشه.
نکتهی مهمی که باید بهش توجه داشته باشیم این هست که برای همهی imageهایی که با تگ latest مشخص میشن مقدار پیشفرض این فیلد Always در نظر گرفته میشه و برای همهی حالات دیگه IfNotPresent!
طبق داکیومنتهای خود Kubernetes میتونیم یکی از موارد زیر رو انجام بدیم:
- مقدار imagePullPolicy رو برابر Always قرار بدیم.
- از نوشتن فیلد imagePullPolicy صرف نظر کنید و image را با تگ latest استفاده کنید.
- از نوشتن فیلد imagePullPolicy صرف نظر کنید و image را بدون تگ استفاده کنید.
- ادمیشن کنترلر AlwaysPullImage را فعال کنید.
امّا باید در نظر داشته باشیم که طبق Best Practices شرایط زیر اتفاق میافته:
- اگر فیلد imagePullPolicy با ifNotPresent مقدار دهی شده باشد ایمیج فقط زمانی pull میشود که به صورت localy وجود نداشته باشد.
- اگر فیلد imagePullPolicy با Always مقداردهی شده باشد ایمیج هر زمانی که پاد شروع به کار میکند pull میشود.
- اگر از نوشتن فیلد imagePullPolicy صرفنظر شده باشد و تگ image برابر latest بوده و یا کلاً تگ استفاده نشده باشد، مقدار آن Always در نظر گرفته میشود.
- اگر از نوشتن فیلد imagePullPolicy صرفنظر شده باشد و تگ image با مقداری غیر از latest وجود داشته باشد، مقدار آن ifNotPresent در نظر گرفته میشود.
- اگر برای فیلد imagePullPolicy از مقدار Never استفاده شده باشد از imageهای موجود به صورت localy استفاده میشود و هیچ تلاشی برای pull کردن آنها انجام نمیگیرد.
امّا چیزی که باعث شد من بخوایم این بحث رو به صورت عمیق بررسی کنم یک داستان مجزاست. رویهی ما در تیم DevOps به این شکل هست که برای اجتناب از ایجاد کانفلیکت در منیفستها اونها رو داخل یک دایرکتوری به اسم همون پروژه بر روی یک مخزن گیت نگهداری میکنیم و کلیهی اعضا برای ایجاد تغییرات باید پس از انجام تغییرات بر روی فایل منیفست اون رو apply بکنه. مشکل از اونجایی شروع شد که همیشه قبل از apply کردن منیفیستهای deployment و امثالهم باید تگ آخرین image مورد استفادهی پاد رو پیدا کرده و داخل منیفست آپدیت میکردیم. برای حل این مشکل اومدیم هر بار که image جدید بیلد میشه به همراه تگ ورژن معمول یک تگ latest هم ایجاد کردیم و push کردیم داخل ریجستری. ظاهراً مشکل حل شد. امّا در واقع مشکل دیگهای درست کرده بودیم اون هم زمانی که که ما مقدار فیلد imagePullPolicy رو به درستی انتخاب نکرده باشیم. یعنی اینکه اگر مقدار این فیلد برابر ifNotPresent باشه موقع apply کردن منیفست با تگ latest ممکنه پاد بر روی ورکری schedule بشه که این image با تگ latest موجود بر روی اون به نسخهی قدیمیتر image اشاره داشته باشه چون در اینصورت همون image به اشتباه دیپلوی میشه و کار خیلی بد پیش میره و ممکنه ساعتها درگیرمون بکنه. البته میتونیم با استفاده از مقدار Always برای فیلد مورد بحث مشکل رو رفع کنیم ولی چرا باید برای pull کردن خیلی از imageهایی که لازم داریم و بر روی ورکر داریمشون منابع صرف کنیم؟ پس میریم سراغ راهحل بهتر.
امّا در گزینههای بالا جواب مشکلی که داریم داده شده. به دو مورد آخر در قسمت best practiceها توجه کنید! بهترین روش صرفنظر کردن از فیلد imagePullPolicy هست. در این حالت اگر image تگ latest داشته باشد یا کلاً بدون تگ باشد (که همان معنی latest رو داره) image همیشه pull گرفته میشه (Always) و اگر image تگ ورژنی (هر چیزی غیر از latest) داشته باشه مقدار فیلد imagePullPolicy برابر ifNotPresent در نظر گرفته میشه و در صورت وجود image دیگه نیازی به pull کردن اون نداریم.