Operator Kubernetes dengan Python tanpa kerangka kerja dan SDK
Go saat ini memonopoli bahasa pemrograman yang dipilih orang untuk menulis pernyataan untuk Kubernetes. Ada alasan obyektif untuk ini, seperti:
Ada kerangka kerja yang kuat untuk mengembangkan operator di Go - SDK Operator.
Aplikasi pengubah permainan seperti Docker dan Kubernetes ditulis dalam Go. Menulis operator Anda di Go berarti berbicara dalam bahasa yang sama dengan ekosistem.
Aplikasi Go berkinerja tinggi dan alat sederhana untuk bekerja dengan konkurensi di luar kotak.
NB: Omong-omong, bagaimana cara menulis pernyataan Anda sendiri di Go, kami sudah dijelaskan dalam salah satu terjemahan kami oleh penulis asing.
Namun bagaimana jika Anda terhambat untuk belajar Go karena kurangnya waktu atau sederhananya, motivasi? Artikel ini memberikan contoh bagaimana Anda dapat menulis pernyataan yang baik menggunakan salah satu bahasa paling populer yang diketahui hampir setiap insinyur DevOps - Ular sanca.
Temui: Mesin Fotokopi - Operator Fotokopi!
Sebagai contoh, pertimbangkan untuk mengembangkan pernyataan sederhana yang dirancang untuk menyalin ConfigMap ketika namespace baru muncul atau ketika salah satu dari dua entitas berubah: ConfigMap dan Secret. Dari sudut pandang praktis, operator dapat berguna untuk memperbarui konfigurasi aplikasi secara massal (dengan memperbarui ConfigMap) atau untuk memperbarui data rahasia - misalnya, kunci untuk bekerja dengan Docker Registry (saat menambahkan Rahasia ke namespace).
Dengan demikian, apa yang seharusnya dimiliki oleh operator yang baik:
Interaksi dengan operator dilakukan dengan menggunakan Definisi Sumber Daya Kustom (selanjutnya disebut CRD).
Operator dapat dikonfigurasi. Untuk melakukan ini, kita akan menggunakan flag baris perintah dan variabel lingkungan.
Pembuatan container Docker dan diagram Helm dirancang agar pengguna dapat dengan mudah (secara harfiah hanya dengan satu perintah) menginstal operator ke dalam cluster Kubernetes mereka.
CRD
Agar operator mengetahui sumber daya apa yang harus dicari dan di mana mencarinya, kita perlu menetapkan aturan untuknya. Setiap aturan akan direpresentasikan sebagai satu objek CRD. Bidang apa yang harus dimiliki CRD ini?
Jenis sumber daya, yang akan kita cari (ConfigMap atau Secret).
Daftar namespace, di mana sumber daya harus ditempatkan.
Pemilih, yang dengannya kita akan mencari sumber daya di namespace.
Dan kami akan segera membuatnya aturan sederhana β untuk mencari di namespace dengan nama default semua ConfigMap dengan label seperti copyrator: "true":
Siap! Sekarang kita perlu mendapatkan informasi tentang aturan kita. Izinkan saya segera membuat reservasi bahwa kami sendiri tidak akan menulis permintaan ke Server API cluster. Untuk melakukan ini, kita akan menggunakan perpustakaan Python yang sudah jadi kubernetes-klien:
import kubernetes
from contextlib import suppress
CRD_GROUP = 'flant.com'
CRD_VERSION = 'v1'
CRD_PLURAL = 'copyrators'
def load_crd(namespace, name):
client = kubernetes.client.ApiClient()
custom_api = kubernetes.client.CustomObjectsApi(client)
with suppress(kubernetes.client.api_client.ApiException):
crd = custom_api.get_namespaced_custom_object(
CRD_GROUP,
CRD_VERSION,
namespace,
CRD_PLURAL,
name,
)
return {x: crd[x] for x in ('ruleType', 'selector', 'namespace')}
Sebagai hasil dari menjalankan kode ini, kami mendapatkan yang berikut:
Hebat: kami berhasil mendapatkan aturan untuk operator. Dan yang paling penting, kami melakukan apa yang disebut dengan cara Kubernetes.
Variabel atau tanda lingkungan? Kami mengambil semuanya!
Mari beralih ke konfigurasi operator utama. Ada dua pendekatan dasar untuk mengonfigurasi aplikasi:
gunakan opsi baris perintah;
menggunakan variabel lingkungan.
Opsi baris perintah memungkinkan Anda membaca pengaturan dengan lebih fleksibel, dengan dukungan dan validasi tipe data. Pustaka standar Python memiliki modul argparser, yang akan kita gunakan. Detail dan contoh kemampuannya tersedia di dokumentasi resmi.
Untuk kasus kami, seperti inilah contoh pengaturan tanda baris perintah pembacaan:
Di sisi lain, dengan menggunakan variabel lingkungan di Kubernetes, Anda dapat dengan mudah mentransfer informasi layanan tentang pod di dalam container. Misalnya, kita bisa mendapatkan informasi tentang namespace tempat pod berjalan dengan konstruksi berikut:
Untuk memahami cara memisahkan metode bekerja dengan ConfigMap dan Secret, kami akan menggunakan peta khusus. Kemudian kita dapat memahami metode apa yang kita perlukan untuk melacak dan membuat objek:
Logika utamanya sudah siap! Sekarang kita perlu mengemas semua ini ke dalam satu paket Python. Kami menyiapkan filenya setup.py, tulis informasi meta tentang proyek di sana:
from sys import version_info
from setuptools import find_packages, setup
if version_info[:2] < (3, 5):
raise RuntimeError(
'Unsupported python version %s.' % '.'.join(version_info)
)
_NAME = 'copyrator'
setup(
name=_NAME,
version='0.0.1',
packages=find_packages(),
classifiers=[
'Development Status :: 3 - Alpha',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
author='Flant',
author_email='[email protected]',
include_package_data=True,
install_requires=[
'kubernetes==9.0.0',
],
entry_points={
'console_scripts': [
'{0} = {0}.cli:main'.format(_NAME),
]
}
)
NB: Klien kubernetes untuk Python memiliki versinya sendiri. Informasi lebih lanjut tentang kompatibilitas antara versi klien dan versi Kubernetes dapat ditemukan di matriks kompatibilitas.
Dockerfile akan sangat sederhana: ambil gambar dasar python-alpine dan instal paket kami. Mari kita tunda pengoptimalannya hingga waktu yang lebih baik:
FROM python:3.7.3-alpine3.9
ADD . /app
RUN pip3 install /app
ENTRYPOINT ["copyrator"]
Begitulah, tanpa rasa takut, celaan, atau mempelajari Go, kami dapat membangun operator kami sendiri untuk Kubernetes dengan Python. Tentu saja, ia masih memiliki ruang untuk berkembang: di masa depan ia akan mampu memproses banyak aturan, bekerja di banyak thread, memantau perubahan dalam CRD-nya secara mandiri...
Untuk memberi Anda gambaran lebih dekat tentang kodenya, kami telah memasukkannya repositori publik. Jika Anda ingin contoh operator yang lebih serius diimplementasikan menggunakan Python, Anda dapat mengalihkan perhatian Anda ke dua operator untuk menerapkan mongodb (ΠΏΠ΅ΡΠ²ΡΠΉ ΠΈ kedua).
PS Dan jika Anda terlalu malas untuk menangani event Kubernetes atau Anda lebih terbiasa menggunakan Bash, rekan kami telah menyiapkan solusi siap pakai dalam bentuk operator shell (Kami diumumkan itu pada bulan April).