ایده یک اپراتور پوسته بسیار ساده است: در رویدادهایی از اشیاء Kubernetes مشترک شوید، و هنگامی که این رویدادها دریافت شدند، یک برنامه خارجی راه اندازی کنید و اطلاعات مربوط به رویداد را در اختیار آن قرار دهید:
نیاز به آن زمانی بوجود آمد که در حین عملکرد خوشه ها، کارهای کوچکی ظاهر شد که ما واقعاً می خواستیم به روش صحیح آنها را خودکار کنیم. همه این کارهای کوچک با استفاده از اسکریپت های bash ساده حل شدند، اگرچه همانطور که می دانید بهتر است عملگرها را در Golang بنویسید. بدیهی است که سرمایه گذاری در توسعه یک اپراتور در مقیاس کامل برای هر کار کوچکی بی اثر خواهد بود.
اپراتور در 15 دقیقه
بیایید به نمونهای نگاه کنیم که چه چیزی را میتوان در یک خوشه Kubernetes خودکار کرد و چگونه اپراتور پوسته میتواند کمک کند. یک مثال می تواند به صورت زیر باشد: تکرار یک راز برای دسترسی به رجیستری docker.
پادهایی که از تصاویر یک رجیستری خصوصی استفاده می کنند باید در مانیفست خود پیوندی به یک راز با داده هایی برای دسترسی به رجیستری داشته باشند. این راز باید قبل از ایجاد پادها در هر فضای نام ایجاد شود. این کار را میتوان به صورت دستی انجام داد، اما اگر محیطهای پویا را راهاندازی کنیم، فضای نام یک برنامه بسیار زیاد میشود. و اگر 2-3 برنامه نیز وجود نداشته باشد ... تعداد اسرار بسیار زیاد می شود. و یک چیز دیگر در مورد اسرار: من می خواهم کلید دسترسی به رجیستری را هر از چند گاهی تغییر دهم. در نهایت، عملیات دستی به عنوان یک راه حل کاملا بی اثر - ما باید ایجاد و بهروزرسانی اسرار را خودکار کنیم.
اتوماسیون ساده
بیایید یک اسکریپت پوسته بنویسیم که هر N ثانیه یک بار اجرا شود و فضای نام را برای وجود یک راز بررسی کند و اگر رازی وجود نداشته باشد، ایجاد می شود. مزیت این راه حل این است که مانند یک اسکریپت پوسته در cron به نظر می رسد - یک رویکرد کلاسیک و قابل درک برای همه. نکته منفی این است که در فاصله زمانی بین راه اندازی آن می توان فضای نام جدیدی ایجاد کرد و برای مدتی بدون راز باقی می ماند که منجر به خطا در راه اندازی pods می شود.
اتوماسیون با اپراتور پوسته
برای اینکه اسکریپت ما به درستی کار کند، هنگام اضافه شدن فضای نام، راهاندازی کلاسیک cron باید با یک راهاندازی جایگزین شود: در این صورت، میتوانید قبل از استفاده از آن یک راز ایجاد کنید. بیایید ببینیم که چگونه این را با استفاده از shell-operator پیاده سازی کنیم.
ابتدا بیایید به فیلمنامه نگاه کنیم. به اسکریپت ها در اصطلاح عملگر پوسته، هوک می گویند. هر قلاب زمانی که با یک پرچم اجرا می شود --config اپراتور پوسته را در مورد اتصالات خود مطلع می کند، یعنی. در مورد چه رویدادهایی باید راه اندازی شود. در مورد ما استفاده خواهیم کرد onKubernetesEvent:
#!/bin/bash
if [[ $1 == "--config" ]] ; then
cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "namespace",
"event":["add"]
}
]}
EOF
fi
در اینجا توضیح داده شده است که ما علاقه مند به اضافه کردن رویدادها هستیم (add) اشیاء از نوع namespace.
اکنون باید کدی را اضافه کنید که هنگام وقوع رویداد اجرا می شود:
#!/bin/bash
if [[ $1 == "--config" ]] ; then
# конфигурация
cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "namespace",
"event":["add"]
}
]}
EOF
else
# реакция:
# узнать, какой namespace появился
createdNamespace=$(jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH)
# создать в нём нужный секрет
kubectl create -n ${createdNamespace} -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
...
data:
...
EOF
fi
عالی! نتیجه یک فیلمنامه کوچک و زیبا بود. برای "احیای" آن، دو مرحله باقی مانده است: تصویر را آماده کنید و آن را در خوشه راه اندازی کنید.
تهیه تصویر با قلاب
اگر به اسکریپت نگاه کنید، می بینید که از دستورات استفاده شده است kubectl и jq. این بدان معنی است که تصویر باید موارد زیر را داشته باشد: هوک ما، یک اپراتور پوسته که رویدادها را نظارت می کند و قلاب را اجرا می کند، و دستورات استفاده شده توسط هوک (kubectl و jq). Hub.docker.com قبلاً یک تصویر آماده دارد که در آن shell-operator، kubectl و jq بسته بندی شده اند. تنها چیزی که باقی می ماند اضافه کردن یک قلاب ساده است Dockerfile:
بیایید دوباره به قلاب نگاه کنیم و این بار بنویسیم که چه اقداماتی و با چه اشیایی در خوشه انجام می دهد:
در رویدادهای ایجاد فضای نام مشترک می شود.
یک راز در فضای نامی غیر از فضایی که در آن راه اندازی شده است ایجاد می کند.
به نظر می رسد که غلافی که تصویر ما در آن راه اندازی می شود باید مجوز انجام این اقدامات را داشته باشد. این را می توان با ایجاد ServiceAccount خود انجام داد. مجوز باید به صورت ClusterRole و ClusterRoleBinding انجام شود، زیرا ما به اشیا از کل خوشه علاقه مندیم.
همه چیز همین است: اپراتور پوسته شروع به کار می کند، در رویدادهای ایجاد فضای نام مشترک می شود و در صورت نیاز قلاب را اجرا می کند.
به این ترتیب، یک اسکریپت ساده پوسته به یک اپراتور واقعی برای Kubernetes تبدیل شد و به عنوان بخشی از یک خوشه کار می کند. و همه اینها بدون فرآیند پیچیده توسعه اپراتورها در Golang:
مثال دیگری نیز در این مورد وجود دارد ...
معنای آن را با جزئیات بیشتر در یکی از نشریات زیر آشکار خواهیم کرد.
فیلتر
ردیابی اشیا خوب است، اما اغلب نیاز به واکنش وجود دارد تغییر برخی از ویژگی های شیبه عنوان مثال، برای تغییر تعداد replica ها در Deployment یا تغییر برچسب های شی.
هنگامی که یک رویداد می رسد، اپراتور پوسته مانیفست JSON شی را دریافت می کند. ما میتوانیم ویژگیهایی را که به ما علاقه دارند در این JSON انتخاب کنیم و Hook را اجرا کنیم تنها وقتی تغییر می کنند زمینه ای برای این وجود دارد jqFilter، جایی که باید عبارت jq را که در مانیفست JSON اعمال می شود را مشخص کنید.
برای مثال، برای پاسخ به تغییرات برچسبها برای اشیاء Deployment، باید فیلد را فیلتر کنید labels خارج از میدان metadata. کانفیگ به این صورت خواهد بود:
یک انحراف کوچک: بله، اپراتور پوسته پشتیبانی می کند اجرای اسکریپت های سبک crontab. جزئیات بیشتر را می توان در یافت مستندات.
برای تشخیص اینکه چرا قلاب راه اندازی شده است، اپراتور پوسته یک فایل موقت ایجاد می کند و مسیر آن را در یک متغیر به قلاب می دهد. BINDING_CONTEXT_TYPE. فایل حاوی توضیحات JSON در مورد دلیل اجرای هوک است. به عنوان مثال، هر 10 دقیقه یک قلاب با محتوای زیر اجرا می شود:
محتویات فیلدها را می توان از نام آنها فهمید و جزئیات بیشتر را می توان در آن مطالعه کرد مستندات. نمونه ای از گرفتن نام منبع از یک فیلد resourceName استفاده از jq قبلاً در قلابی نشان داده شده است که اسرار را تکرار می کند:
jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH
شما می توانید فیلدهای دیگر را به روشی مشابه دریافت کنید.
گام بعدی چیست؟
در مخزن پروژه، در / نمونه های دایرکتوری، نمونه هایی از قلاب هایی وجود دارد که آماده اجرا بر روی یک خوشه هستند. هنگام نوشتن قلاب های خود، می توانید از آنها به عنوان پایه استفاده کنید.
برای جمع آوری معیارها با استفاده از Prometheus پشتیبانی وجود دارد - معیارهای موجود در بخش توضیح داده شده است معیارهای.
همانطور که ممکن است حدس بزنید، اپراتور پوسته در Go نوشته شده و تحت یک مجوز منبع باز (Apache 2.0) توزیع شده است. ما قدردان هرگونه کمک توسعه خواهیم بود پروژه در GitHub: و ستاره ها، و مسائل، و درخواست های کششی.
با رفع حجاب محرمانه به اطلاع شما می رسانیم که اپراتور پوسته است کوچک بخشی از سیستم ما که می تواند افزونه های نصب شده در خوشه Kubernetes را به روز نگه دارد و اقدامات خودکار مختلفی را انجام دهد. در مورد این سیستم بیشتر بخوانید گفت به معنای واقعی کلمه دوشنبه در HighLoad++ 2019 در سن پترزبورگ - به زودی ویدیو و متن این گزارش را منتشر خواهیم کرد.
ما برنامه ای برای باز کردن بقیه این سیستم داریم: اپراتور افزونه و مجموعه ماژول ها و هوک ها. به هر حال، اپراتور افزونه قبلاً وجود دارد موجود در github، اما مستندات آن هنوز در راه است. انتشار مجموعه ماژول ها برای تابستان برنامه ریزی شده است.