کانتینرهای init

کانتینرهای اینیت کانتینرهایی هستن که قبل از اپلیکیشن اصلی داخل یک پاد اجرا می‌شن؛ یکسری کار انجام میدن و پس از مدتی اجراشون تموم میشه. همونطور که میدونیم یک پاد میتونه از یک یا چند کانتینر تشکیل شده باشه که در کنار هم اجرا میشن. اما کانتینرهای اینیت قبل از کانتینرهای دیگه اجرا میشن و پس از مدتی که اجراشون به پایان رسید، نوبت به اجرای کانتینرهای دیگه میرسه. اما اجرای این کانتینرها چه فایده‌ای داره؟ معمولا این کانتینرها شامل ابزارها یا اسکریپت‌هایی میشن که در image اپلیکیشن وجود نداره و لزومی نداره که وجود داشته باشه.پس کانتینرهای اینیت مثل بقیه‌ی کانتینرها هستن با دو تفاوت اصلی:اجراشون همیشه به پایان میرسه.هر کدام از کانتینرهای اینیت باید با موفقیت به پایان برسن تا کانتینرهای دیگه بتونن شروع به کار کنن.بنابراین اگه اینیت با موفقیت به پایان نرسه، کوبرنتیز تا زمانی که این اتفاق بیوفته پاد رو restart میکنه. هرچند اگه restartPolicy پاد Never باشه کوبرنتیز پاد رو restart نمیکنه.اما به جز اون دو تفاوت اصلی که بیان شد، این کانتینرها دیگه چه فرق‌هایی با کانتینرهای معمولی دارن؟ این کانتینرها موارد زیر رو پشتیبانی نمیکنن:lifecyclelivenessProbereadinessProbestartupProbeدلیل اصلیش اینه که این کانتینرها قراره که اجراشون تموم بشه. بنابراین معنی نداره که مثلا برای این کانتینر livenessProbe تعریف کنیم.استفاده از کانتینرهای اینیتاگر چند اینیت کانتینر تعریف کنین، Kubelet اونها رو به صورت متوالی اجرا میکنه. یعنی اجرای یک اینیت کانتینر باید با موفقیت به پایان برسه تا اجرای اینیت کانتینر بعدی شروع بشه. و وقتی که اجرای همه‌ی اینیت کانتینرها تمام شد، Kubelet کانتینرهای اپلیکیشن رو شروع به اجرا میکنه.اهداف کلی از اجرای اینیت کانتینرها چیه؟اینیت کانتینرها میتونن شامل ابزاری باشن که معمولا در image اپلیکیشن وجود نداره. مثلا شما به هر دلیلی اگر بخواید از sed یا awk استفاده کنید، دلیلی نداره که توی قسمت FROM داکرفایل ایپلیکیشن از یک image دیگه استفاده کنید. این کار رو میتونید به عهده‌ی اینیت بسپرید.اینیتن کانتیرها میتونن view متفاوتی نسبت به کانتینرهای اپلیکیشن نسبت به فایل‌سیستم داشته باشن. مثلا میشه به اونها دسترسی به Secretهایی داد که اپلیکیشن نباید بهشون دسترسی داشته باشه.از اونجایی که قبل از اجرای اپلیکیشن اجرای اینیت کانتینرها باید تموم شده باشه، میشه از این قضیه به عنوان یک مکانیزم برای اجرای با تاخیر اپلیکیشن استفاده کرد. فایده‌ی این کار اینه که میتونیم مطمئن بشیم یکسری پیش‌شرطها و نیازمندی‌ها که برای اجرای اپلیکیشن مورد نیازه، برطرف شده.اینیت کانتینرها میتونن شامل ابزار یا کدهایی باشن که اگه در image اپلیکیشن وجود داشته باشن امنیت اونها رو پایین میارن. بنابراین با جدا کردن این ابزارهای غیر ضروری میتونیم “attack surface” یک اپلیکیشن رو محدود کنیم.یک مورد که میشه از اینیت کانتینرها استفاده کرد:یک مدت زمانی صبر کنیم تا سرویس مورد نظرمون ایجاد بشه بعد کانتینر اپلیکیشن رو شروع کنیم. این مورد با یک خط اسکریپت بش قابل پیاده‌سازیه:for i in {1..100};do sleep 1 if dig service then exit 0 fidoneexit 1فایل پایین که مشخصات یک پاد رو مشخص میکنه شامل دو اینیت کانتینر هست. اینیت اول منتظر سرویس myservice میشه و اینیت دوم منتظر mydb. وقتی که هر دوی اینیت کانتینرها اجراشون با موفقیت به پایان رسید، پاد اجرای کانتینر اپ رو شروع میکنه.apiVersion: v1kind: Podmetadata: name: myapp-pod labels: app: myappspec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', &quotuntil nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done&quot] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', &quotuntil nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done&quot]با اجرای این فایل وضعیت پاد در ابتدا به شکل زیر میشههمونطور که در قسمت STATUS مشخصه دو کانتینر Init وجود داره که اجرای هیچکدومشون به پایان نرسیده. اگر لاگ اینیت کانتینر اول رو بررسی کنیم (kubectl logs myapp-pod -c init-myservice)، از اونجایی که سرویس myservice زو نمیتونه ریزالو کنه، اجراش به پایان نمیرسه:اما اگه سرویس‌های مد نظر اینیت کانتینرها رو ایجاد کنیم، اجراشون به پایان میرسه و کانتینر اصلی اپ شروع به اجرا میکنه:---apiVersion: v1kind: Servicemetadata: name: myservicespec: ports: - protocol: TCP port: 80 targetPort: 9376---apiVersion: v1kind: Servicemetadata: name: mydbspec: ports: - protocol: TCP port: 80 targetPort: 9377حالا اگه وضعیت پاد رو بررسی کنیم:خب طبق تصویر بالا مشخصه که اجرای کانتینر اصلی پاد شروع شده.