معرفی shell-operator: ایجاد اپراتور برای Kubernetes ساده تر شد

قبلاً مقالاتی در وبلاگ ما در مورد آن صحبت شده است قابلیت های اپراتور در Kubernetes و چطور خودتان یک اپراتور ساده بنویسید. این بار می‌خواهیم راه‌حل منبع باز خود را به شما معرفی کنیم که ایجاد اپراتورها را به سطح بسیار آسانی می‌برد - بررسی کنید اپراتور پوسته!

چرا؟

ایده یک اپراتور پوسته بسیار ساده است: در رویدادهایی از اشیاء Kubernetes مشترک شوید، و هنگامی که این رویدادها دریافت شدند، یک برنامه خارجی راه اندازی کنید و اطلاعات مربوط به رویداد را در اختیار آن قرار دهید:

معرفی shell-operator: ایجاد اپراتور برای 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:

$ cat Dockerfile
FROM flant/shell-operator:v1.0.0-beta.1-alpine3.9
ADD namespace-hook.sh /hooks

$ docker build -t registry.example.com/my-operator:v1 . 
$ docker push registry.example.com/my-operator:v1

دویدن در یک خوشه

بیایید دوباره به قلاب نگاه کنیم و این بار بنویسیم که چه اقداماتی و با چه اشیایی در خوشه انجام می دهد:

  1. در رویدادهای ایجاد فضای نام مشترک می شود.
  2. یک راز در فضای نامی غیر از فضایی که در آن راه اندازی شده است ایجاد می کند.

به نظر می رسد که غلافی که تصویر ما در آن راه اندازی می شود باید مجوز انجام این اقدامات را داشته باشد. این را می توان با ایجاد ServiceAccount خود انجام داد. مجوز باید به صورت ClusterRole و ClusterRoleBinding انجام شود، زیرا ما به اشیا از کل خوشه علاقه مندیم.

توضیحات نهایی در YAML چیزی شبیه به این خواهد بود:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: monitor-namespaces-acc

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: monitor-namespaces
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "create", "patch"]

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: monitor-namespaces
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: monitor-namespaces
subjects:
  - kind: ServiceAccount
    name: monitor-namespaces-acc
    namespace: example-monitor-namespaces

می توانید تصویر مونتاژ شده را به عنوان یک Deployment ساده راه اندازی کنید:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-operator
spec:
  template:
    spec:
      containers:
      - name: my-operator
        image: registry.example.com/my-operator:v1
      serviceAccountName: monitor-namespaces-acc

برای راحتی، یک فضای نام جداگانه ایجاد می شود که در آن shell-operator راه اندازی می شود و مانیفست های ایجاد شده اعمال می شوند:

$ kubectl create ns example-monitor-namespaces
$ kubectl -n example-monitor-namespaces apply -f rbac.yaml
$ kubectl -n example-monitor-namespaces apply -f deployment.yaml

همه چیز همین است: اپراتور پوسته شروع به کار می کند، در رویدادهای ایجاد فضای نام مشترک می شود و در صورت نیاز قلاب را اجرا می کند.

معرفی shell-operator: ایجاد اپراتور برای Kubernetes ساده تر شد

به این ترتیب، یک اسکریپت ساده پوسته به یک اپراتور واقعی برای Kubernetes تبدیل شد و به عنوان بخشی از یک خوشه کار می کند. و همه اینها بدون فرآیند پیچیده توسعه اپراتورها در Golang:

معرفی shell-operator: ایجاد اپراتور برای Kubernetes ساده تر شد

مثال دیگری نیز در این مورد وجود دارد ...معرفی shell-operator: ایجاد اپراتور برای Kubernetes ساده تر شد

معنای آن را با جزئیات بیشتر در یکی از نشریات زیر آشکار خواهیم کرد.

فیلتر

ردیابی اشیا خوب است، اما اغلب نیاز به واکنش وجود دارد تغییر برخی از ویژگی های شیبه عنوان مثال، برای تغییر تعداد replica ها در Deployment یا تغییر برچسب های شی.

هنگامی که یک رویداد می رسد، اپراتور پوسته مانیفست JSON شی را دریافت می کند. ما می‌توانیم ویژگی‌هایی را که به ما علاقه دارند در این JSON انتخاب کنیم و Hook را اجرا کنیم تنها وقتی تغییر می کنند زمینه ای برای این وجود دارد jqFilter، جایی که باید عبارت jq را که در مانیفست JSON اعمال می شود را مشخص کنید.

برای مثال، برای پاسخ به تغییرات برچسب‌ها برای اشیاء Deployment، باید فیلد را فیلتر کنید labels خارج از میدان metadata. کانفیگ به این صورت خواهد بود:

cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "deployment",
  "event":["update"],
  "jqFilter": ".metadata.labels"
}
]}
EOF

این عبارت jqFilter مانیفست بلند JSON Deployment را به JSON کوتاه با برچسب‌ها تبدیل می‌کند:

معرفی shell-operator: ایجاد اپراتور برای Kubernetes ساده تر شد

shell-operator تنها زمانی قلاب را اجرا می کند که این JSON کوتاه تغییر کند و تغییرات سایر ویژگی ها نادیده گرفته می شود.

زمینه راه اندازی قلاب

پیکربندی قلاب به شما امکان می دهد چندین گزینه را برای رویدادها مشخص کنید - به عنوان مثال، 2 گزینه برای رویدادها از Kubernetes و 2 برنامه:

{"onKubernetesEvent":[
  {"name":"OnCreatePod",
  "kind": "pod",
  "event":["add"]
  },
  {"name":"OnModifiedNamespace",
  "kind": "namespace",
  "event":["update"],
  "jqFilter": ".metadata.labels"
  }
],
"schedule": [
{ "name":"every 10 min",
  "crontab":"* */10 * * * *"
}, {"name":"on Mondays at 12:10",
"crontab": "* 10 12 * * 1"
]}

یک انحراف کوچک: بله، اپراتور پوسته پشتیبانی می کند اجرای اسکریپت های سبک crontab. جزئیات بیشتر را می توان در یافت مستندات.

برای تشخیص اینکه چرا قلاب راه اندازی شده است، اپراتور پوسته یک فایل موقت ایجاد می کند و مسیر آن را در یک متغیر به قلاب می دهد. BINDING_CONTEXT_TYPE. فایل حاوی توضیحات JSON در مورد دلیل اجرای هوک است. به عنوان مثال، هر 10 دقیقه یک قلاب با محتوای زیر اجرا می شود:

[{ "binding": "every 10 min"}]

... و روز دوشنبه با این شروع می شود:

[{ "binding": "every 10 min"}, { "binding": "on Mondays at 12:10"}]

برای onKubernetesEvent محرک های JSON بیشتری وجود خواهد داشت، زیرا شامل شرحی از شیء است:

[
 {
 "binding": "onCreatePod",
 "resourceEvent": "add",
 "resourceKind": "pod",
 "resourceName": "foo",
 "resourceNamespace": "bar"
 }
]

محتویات فیلدها را می توان از نام آنها فهمید و جزئیات بیشتر را می توان در آن مطالعه کرد مستندات. نمونه ای از گرفتن نام منبع از یک فیلد resourceName استفاده از jq قبلاً در قلابی نشان داده شده است که اسرار را تکرار می کند:

jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH

شما می توانید فیلدهای دیگر را به روشی مشابه دریافت کنید.

گام بعدی چیست؟

در مخزن پروژه، در / نمونه های دایرکتوری، نمونه هایی از قلاب هایی وجود دارد که آماده اجرا بر روی یک خوشه هستند. هنگام نوشتن قلاب های خود، می توانید از آنها به عنوان پایه استفاده کنید.

برای جمع آوری معیارها با استفاده از Prometheus پشتیبانی وجود دارد - معیارهای موجود در بخش توضیح داده شده است معیارهای.

همانطور که ممکن است حدس بزنید، اپراتور پوسته در Go نوشته شده و تحت یک مجوز منبع باز (Apache 2.0) توزیع شده است. ما قدردان هرگونه کمک توسعه خواهیم بود پروژه در GitHub: و ستاره ها، و مسائل، و درخواست های کششی.

با رفع حجاب محرمانه به اطلاع شما می رسانیم که اپراتور پوسته است کوچک بخشی از سیستم ما که می تواند افزونه های نصب شده در خوشه Kubernetes را به روز نگه دارد و اقدامات خودکار مختلفی را انجام دهد. در مورد این سیستم بیشتر بخوانید گفت به معنای واقعی کلمه دوشنبه در HighLoad++ 2019 در سن پترزبورگ - به زودی ویدیو و متن این گزارش را منتشر خواهیم کرد.

ما برنامه ای برای باز کردن بقیه این سیستم داریم: اپراتور افزونه و مجموعه ماژول ها و هوک ها. به هر حال، اپراتور افزونه قبلاً وجود دارد موجود در github، اما مستندات آن هنوز در راه است. انتشار مجموعه ماژول ها برای تابستان برنامه ریزی شده است.

گوش به زنگ باشید!

PS

در وبلاگ ما نیز بخوانید:

منبع: www.habr.com

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