کانتینرهای اینیت کانتینرهایی هستن که قبل از اپلیکیشن اصلی داخل یک پاد اجرا میشن؛ یکسری کار انجام میدن و پس از مدتی اجراشون تموم میشه. همونطور که میدونیم یک پاد میتونه از یک یا چند کانتینر تشکیل شده باشه که در کنار هم اجرا میشن. اما کانتینرهای اینیت قبل از کانتینرهای دیگه اجرا میشن و پس از مدتی که اجراشون به پایان رسید، نوبت به اجرای کانتینرهای دیگه میرسه. اما اجرای این کانتینرها چه فایدهای داره؟ معمولا این کانتینرها شامل ابزارها یا اسکریپتهایی میشن که در image اپلیکیشن وجود نداره و لزومی نداره که وجود داشته باشه.
پس کانتینرهای اینیت مثل بقیهی کانتینرها هستن با دو تفاوت اصلی:
بنابراین اگه اینیت با موفقیت به پایان نرسه، کوبرنتیز تا زمانی که این اتفاق بیوفته پاد رو restart میکنه. هرچند اگه restartPolicy پاد Never باشه کوبرنتیز پاد رو restart نمیکنه.
اما به جز اون دو تفاوت اصلی که بیان شد، این کانتینرها دیگه چه فرقهایی با کانتینرهای معمولی دارن؟ این کانتینرها موارد زیر رو پشتیبانی نمیکنن:
دلیل اصلیش اینه که این کانتینرها قراره که اجراشون تموم بشه. بنابراین معنی نداره که مثلا برای این کانتینر livenessProbe تعریف کنیم.
اگر چند اینیت کانتینر تعریف کنین، Kubelet اونها رو به صورت متوالی اجرا میکنه. یعنی اجرای یک اینیت کانتینر باید با موفقیت به پایان برسه تا اجرای اینیت کانتینر بعدی شروع بشه. و وقتی که اجرای همهی اینیت کانتینرها تمام شد، Kubelet کانتینرهای اپلیکیشن رو شروع به اجرا میکنه.
اهداف کلی از اجرای اینیت کانتینرها چیه؟
یک مورد که میشه از اینیت کانتینرها استفاده کرد:
یک مدت زمانی صبر کنیم تا سرویس مورد نظرمون ایجاد بشه بعد کانتینر اپلیکیشن رو شروع کنیم. این مورد با یک خط اسکریپت بش قابل پیادهسازیه:
for i in {1..100};
do
sleep 1
if dig service
then
exit 0
fi
done
exit 1
فایل پایین که مشخصات یک پاد رو مشخص میکنه شامل دو اینیت کانتینر هست. اینیت اول منتظر سرویس myservice میشه و اینیت دوم منتظر mydb. وقتی که هر دوی اینیت کانتینرها اجراشون با موفقیت به پایان رسید، پاد اجرای کانتینر اپ رو شروع میکنه.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
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', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
با اجرای این فایل وضعیت پاد در ابتدا به شکل زیر میشه
همونطور که در قسمت STATUS مشخصه دو کانتینر Init وجود داره که اجرای هیچکدومشون به پایان نرسیده.
اگر لاگ اینیت کانتینر اول رو بررسی کنیم (kubectl logs myapp-pod -c init-myservice)، از اونجایی که سرویس myservice زو نمیتونه ریزالو کنه، اجراش به پایان نمیرسه:
اما اگه سرویسهای مد نظر اینیت کانتینرها رو ایجاد کنیم، اجراشون به پایان میرسه و کانتینر اصلی اپ شروع به اجرا میکنه:
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
حالا اگه وضعیت پاد رو بررسی کنیم:
خب طبق تصویر بالا مشخصه که اجرای کانتینر اصلی پاد شروع شده.