Sudah ada artikel di blog kita bercakap tentang dan bagaimana . Kali ini kami ingin membentangkan kepada perhatian anda penyelesaian Sumber Terbuka kami, yang membawa penciptaan pengendali ke tahap yang sangat mudah - lihat !
Mengapa?
Idea pengendali shell agak mudah: langgan acara dari objek Kubernetes, dan apabila acara ini diterima, lancarkan program luaran, memberikannya maklumat tentang acara itu:

Keperluan untuk itu timbul apabila, semasa operasi kluster, tugas-tugas kecil mula kelihatan bahawa kami benar-benar mahu mengautomasikan dengan cara yang betul. Semua tugas kecil ini diselesaikan menggunakan skrip bash mudah, walaupun, seperti yang anda ketahui, adalah lebih baik untuk menulis operator di Golang. Jelas sekali, melabur dalam pembangunan skala penuh pengendali untuk setiap tugas kecil itu akan menjadi tidak berkesan.
Operator dalam 15 minit
Mari lihat contoh perkara yang boleh diautomatikkan dalam kelompok Kubernetes dan cara pengendali shell boleh membantu. Contohnya adalah seperti berikut: mereplikasi rahsia untuk mengakses pendaftaran docker.
Pod yang menggunakan imej daripada pendaftaran peribadi mesti mengandungi dalam manifesnya pautan ke rahsia dengan data untuk mengakses pendaftaran. Rahsia ini mesti dibuat dalam setiap ruang nama sebelum membuat pod. Ini boleh dilakukan secara manual, tetapi jika kita menyediakan persekitaran dinamik, maka ruang nama untuk satu aplikasi akan menjadi banyak. Dan jika tidak ada juga 2-3 permohonan... bilangan rahsia menjadi sangat besar. Dan satu lagi perkara tentang rahsia: Saya ingin menukar kunci untuk mengakses pendaftaran dari semasa ke semasa. Akhirnya, operasi manual sebagai penyelesaian sama sekali tidak berkesan — kita perlu mengautomasikan penciptaan dan pengemaskinian rahsia.
Automasi mudah
Mari tulis skrip shell yang dijalankan sekali setiap N saat dan semak ruang nama untuk kehadiran rahsia, dan jika tiada rahsia, maka ia dicipta. Kelebihan penyelesaian ini ialah ia kelihatan seperti skrip shell dalam cron - pendekatan klasik dan mudah difahami oleh semua orang. Kelemahannya ialah dalam selang waktu antara pelancarannya, ruang nama baharu boleh dibuat dan untuk beberapa waktu ia akan kekal tanpa rahsia, yang akan membawa kepada ralat dalam melancarkan pod.
Automasi dengan pengendali shell
Untuk skrip kami berfungsi dengan betul, pelancaran cron klasik perlu digantikan dengan pelancaran apabila ruang nama ditambahkan: dalam kes ini, anda boleh mencipta rahsia sebelum menggunakannya. Mari lihat bagaimana untuk melaksanakan ini menggunakan shell-operator.
Pertama, mari kita lihat skrip. Skrip dalam istilah pengendali shell dipanggil cangkuk. Setiap cangkuk apabila dijalankan dengan bendera --config memberitahu pengendali shell tentang pengikatannya, i.e. mengenai acara apa yang patut dilancarkan. Dalam kes kami, kami akan menggunakan onKubernetesEvent:
#!/bin/bash
if [[ $1 == "--config" ]] ; then
cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "namespace",
"event":["add"]
}
]}
EOF
fi Diterangkan di sini bahawa kami berminat untuk menambah acara (add) objek jenis namespace.
Sekarang anda perlu menambah kod yang akan dilaksanakan apabila acara itu berlaku:
#!/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
fiHebat! Hasilnya ialah skrip yang kecil dan cantik. Untuk "menghidupkannya semula", terdapat dua langkah lagi: sediakan imej dan lancarkannya dalam kelompok.
Menyediakan imej dengan cangkuk
Jika anda melihat skrip, anda boleh melihat bahawa arahan digunakan kubectl и jq. Ini bermakna imej mesti mempunyai perkara berikut: cangkuk kami, pengendali cangkerang yang akan memantau acara dan menjalankan cangkuk, dan arahan yang digunakan oleh cangkuk (kubectl dan jq). Hub.docker.com sudah mempunyai imej siap sedia di mana shell-operator, kubectl dan jq dibungkus. Yang tinggal hanyalah menambah cangkuk mudah 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:v1Berlari dalam kelompok
Mari kita lihat cangkuk sekali lagi dan kali ini tuliskan tindakan apa dan dengan objek apa yang dilakukannya dalam kelompok:
- melanggan acara penciptaan ruang nama;
- mencipta rahsia dalam ruang nama selain daripada tempat ia dilancarkan.
Ternyata pod tempat imej kami akan dilancarkan mesti mempunyai kebenaran untuk melakukan tindakan ini. Ini boleh dilakukan dengan mencipta Akaun Perkhidmatan anda sendiri. Kebenaran mesti dilakukan dalam bentuk ClusterRole dan ClusterRoleBinding, kerana kami berminat dengan objek daripada keseluruhan kluster.
Penerangan akhir dalam YAML akan kelihatan seperti ini:
---
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-namespacesAnda boleh melancarkan imej yang dipasang sebagai Deployment yang mudah:
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-accUntuk kemudahan, ruang nama yang berasingan dibuat di mana pengendali shell akan dilancarkan dan manifes yang dibuat akan digunakan:
$ kubectl create ns example-monitor-namespaces
$ kubectl -n example-monitor-namespaces apply -f rbac.yaml
$ kubectl -n example-monitor-namespaces apply -f deployment.yaml
Itu sahaja: pengendali shell akan bermula, melanggan acara penciptaan ruang nama dan menjalankan cangkuk apabila diperlukan.
![]()
Oleh itu, skrip shell mudah bertukar menjadi pengendali sebenar untuk Kubernetes dan berfungsi sebagai sebahagian daripada kluster. Dan semua ini tanpa proses yang kompleks untuk membangunkan pengendali di Golang:

Terdapat satu lagi ilustrasi mengenai perkara ini...
Kami akan mendedahkan maksudnya dengan lebih terperinci dalam salah satu penerbitan berikut.
penapisan
Menjejak objek adalah baik, tetapi selalunya terdapat keperluan untuk bertindak balas menukar beberapa sifat objek, sebagai contoh, untuk menukar bilangan replika dalam Deployment atau untuk menukar label objek.
Apabila acara tiba, pengendali shell menerima manifes JSON objek. Kita boleh memilih sifat yang menarik minat kita dalam JSON ini dan menjalankan cangkuk sahaja apabila mereka berubah. Terdapat medan untuk ini jqFilter, di mana anda perlu menentukan ungkapan jq yang akan digunakan pada manifes JSON.
Contohnya, untuk bertindak balas terhadap perubahan dalam label untuk objek Deployment, anda perlu menapis medan labels keluar dari padang metadata. Konfigurasi akan menjadi seperti ini:
cat <<EOF
{
"onKubernetesEvent": [
{ "kind": "deployment",
"event":["update"],
"jqFilter": ".metadata.labels"
}
]}
EOFUngkapan jqFilter ini menukar manifes JSON yang panjang Deployment menjadi JSON pendek dengan label:

shell-operator hanya akan menjalankan cangkuk apabila JSON pendek ini berubah, dan perubahan pada sifat lain akan diabaikan.
Konteks pelancaran cangkuk
Konfigurasi cangkuk membolehkan anda menentukan beberapa pilihan untuk acara - contohnya, 2 pilihan untuk acara daripada Kubernetes dan 2 jadual:
{"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"
]}Penyimpangan kecil: ya, shell-operator menyokong menjalankan skrip gaya crontab. Butiran lanjut boleh didapati di .
Untuk membezakan sebab cangkuk dilancarkan, pengendali shell mencipta fail sementara dan menghantar laluan kepadanya dalam pembolehubah kepada cangkuk BINDING_CONTEXT_TYPE. Fail itu mengandungi penerangan JSON tentang sebab menjalankan cangkuk. Sebagai contoh, setiap 10 minit cangkuk akan berjalan dengan kandungan berikut:
[{ "binding": "every 10 min"}]... dan pada hari Isnin ia akan bermula dengan ini:
[{ "binding": "every 10 min"}, { "binding": "on Mondays at 12:10"}] Untuk onKubernetesEvent Akan ada lebih banyak pencetus JSON, kerana ia mengandungi penerangan tentang objek:
[
{
"binding": "onCreatePod",
"resourceEvent": "add",
"resourceKind": "pod",
"resourceName": "foo",
"resourceNamespace": "bar"
}
] Kandungan medan boleh difahami daripada namanya, dan butiran lanjut boleh dibaca . Contoh mendapatkan nama sumber daripada medan resourceName menggunakan jq telah ditunjukkan dalam cangkuk yang mereplikasi rahsia:
jq -r '.[0].resourceName' $BINDING_CONTEXT_PATHAnda boleh mendapatkan medan lain dengan cara yang sama.
Apa seterusnya?
Dalam repositori projek, dalam , terdapat contoh cangkuk yang sedia untuk dijalankan pada kelompok. Apabila menulis cangkuk anda sendiri, anda boleh menggunakannya sebagai asas.
Terdapat sokongan untuk mengumpul metrik menggunakan Prometheus - metrik yang tersedia diterangkan dalam bahagian .
Seperti yang anda mungkin rasa, pengendali shell ditulis dalam Go dan diedarkan di bawah lesen Sumber Terbuka (Apache 2.0). Kami akan berterima kasih atas sebarang bantuan pembangunan : dan bintang, dan isu, dan permintaan tarik.
Mengangkat tabir kerahsiaan, kami juga akan memberitahu anda bahawa shell-operator adalah kecil sebahagian daripada sistem kami yang boleh memastikan alat tambah dipasang dalam kelompok Kubernetes terkini dan melakukan pelbagai tindakan automatik. Baca lebih lanjut mengenai sistem ini secara literal pada hari Isnin di HighLoad++ 2019 di St. Petersburg - kami akan menerbitkan video dan transkrip laporan ini tidak lama lagi.
Kami mempunyai rancangan untuk membuka seluruh sistem ini: pengendali tambahan dan koleksi cangkuk dan modul kami. By the way, addon-operator sudah pun , tetapi dokumentasi untuknya masih dalam proses. Pengeluaran koleksi modul dirancang untuk musim panas.
Tinggal!
PS
Baca juga di blog kami:
- «»;
- «»;
- «»;
- «»;
- «'.
Sumber: www.habr.com
