
Jika Anda bekerja dengan lingkungan Kubernetes maka Anda mungkin menggunakan beberapa alat templating yang ada, beberapa dari mereka menjadi bagian dari manajer paket seperti Helm atau Ksonnet , atau hanya bahasa templating (Jinja2, Go template dll). Semua dari mereka memiliki kelemahannya sendiri serta kelebihannya dan kami akan membahasnya dan menulis alat kami sendiri yang akan mencoba menggabungkan fitur-fitur terbaik.
Jadi, mengapa tidak Helm?
Ada sejumlah artikel yang mengkritik Helm (mis. Salah satunya saja: Berpikir dua kali sebelum menggunakan Helm ). Masalah utama dengan Helm adalah bahwa ia bekerja dengan representasi string dan manifes Kubernetes adalah objek (json) . Neraka sebenarnya untuk pengembang Helm chart dimulai ketika dia perlu menghitung indentasi untuk manifes yaml
, kadang-kadang terlihat seperti ini (ini adalah contoh nyata dari bagan saya):
spec: jobTemplate: spec: template: spec: containers: - name: my-awesome-container resources: {{ toYaml .Values.resources | indent 14 }}

Tapi Helm hari ini adalah de-facto standar untuk kemasan aplikasi Kubernetes. Keuntungan utama dari Helm adalah komunitas besar dan sejumlah besar repositori publik dengan grafik. Dan baru-baru ini pengembang Helm telah mengumumkan hub Helm . Jadi Helm hari ini seperti Docker - ini bukan satu-satunya tetapi memiliki komunitas dan dukungan.
Ada perubahan yang menjanjikan dengan rilis Helm 3 tetapi tidak ada yang tahu kapan itu bisa terjadi.
Untuk menyimpulkan, keunggulan Helm:
- Komunitas besar dan sejumlah bagan publik
- (Relatif) sintaks yang ramah manusia. Setidaknya itu yaml + go templat;)
Kekurangan:
- Bekerja dengan string dan bukan objek
- Jumlah operator dan fungsi terbatas yang dapat Anda gunakan
Oke, mungkin Ksonnet?
Jika Anda membandingkan Helm dengan Ksonnet, yang terakhir memiliki keunggulan besar, yaitu bekerja dengan objek. Ksonnet adalah alat berbasis bahasa JSON templating Jsonnet. Fitur keren lainnya tentang Ksonnet adalah memiliki pustaka Jsonnet yang kompatibel dengan Kubernetes-API yang dapat Anda impor ke template Anda dan bekerja dengan objek Kubernetes seperti dalam bahasa OOP:
local k = import "k.libsonnet"; local deployment = k.apps.v1beta1.deployment; local appDeployment = deployment .new( params.name, params.replicas, container .new(params.name, params.image) .withPorts(containerPort.new(targetPort)), labels);
Terlihat mengesankan, bukan?
Agak kurang rapi ketika Anda bekerja bukan dengan objek API tetapi dengan hanya objek json yang diimpor dari file yaml
/ json
:
{ global: {}, components: { "deployment-nginx-deployment-dkecx"+: { spec+: { replicas: 10, template+: { spec+: { containers+: [ { name: "nginx", image: "nginx:latest", ports: [ { containerPort: 80, }, ], }, ], }, }, }, }, }, }
Tapi tetap saja itu adalah sesuatu dan itu lebih baik daripada bekerja dengan string di Helm. Kerugian dari Ksonnet adalah ia memiliki komunitas yang lebih kecil dan paket yang lebih sedikit daripada Helm (meskipun Anda dapat mengimpor grafik Helm ke proyek Ksonnet Anda, tetapi Anda akan bekerja dengan mereka sebagai objek json, bukan sebagai objek jsonnet-library). Dan sebagai hasil dari komunitas yang lebih kecil dan kontribusi ada kekurangan beberapa fitur ketika Anda mencoba untuk menulis bagan Anda sendiri. Salah satunya saya alami sendiri: Anda tahu bahwa di Helm Anda dapat membangun ConfigMap
dari direktori yang berisi sejumlah file konfigurasi dengan cara ini:
apiVersion: v1 kind: ConfigMap metadata: name: conf data: {{- (.Files.Glob "foo/*").AsConfig | nindent 2 }}
Anda dapat membayangkan frustrasi saya ketika saya mengetahui bahwa tidak ada fitur seperti itu di Ksonnet. Namun ada beberapa solusi. Tapi intinya adalah itu hanya contoh dari situasi ketika Anda dengan senang hati menulis bagan Anda dan tiba-tiba kurangnya fitur menghentikan Anda di tengah jalan.
Secara total, keunggulan Ksonnet:
- Bekerja dengan benda
- Perpustakaan Jsonnet yang kompatibel dengan Kubernetes-API
- Dukungan impor grafik helm
Kekurangan:
- Komunitas yang lebih kecil dan jumlah paket asli Ksonnet yang lebih sedikit
- Kurangnya beberapa fungsi yang dapat Anda gunakan di Helm
- Sintaks baru => peningkatan waktu belajar => peningkatan faktor bus
- Sintaks kadang-kadang bisa menjadi jelek dan kurang dapat dibaca manusia (terutama ketika membuat solusi untuk kekurangan fitur)
Berikut adalah beberapa kriteria untuk alat templating "ideal":
- Ini harus bekerja dengan objek, bukan string
- Seharusnya memiliki kemampuan untuk bekerja dengan objek yang kompatibel dengan Kubernetes-API
- Seharusnya memiliki serangkaian fungsi yang layak untuk bekerja dengan string
- Ini harus bekerja dengan baik dengan format json dan yaml
- Itu harus ramah manusia
- Itu harus sederhana
- Seharusnya memiliki kemampuan untuk mengimpor grafik Helm yang ada (karena ini adalah kenyataan dan kami ingin memanfaatkan komunitas Helm)
Cukup untuk sekarang. Saya membaca daftar ini di kepala saya dan berpikir dalam hati: oke, mengapa tidak mencoba Python? Mari kita lihat apakah itu sesuai dengan kriteria kami:
- Bekerja dengan benda, bukan string . Ya, kita bisa menggunakan tipe
dict
dan list
untuk itu. - Memiliki kemampuan untuk bekerja dengan objek yang kompatibel dengan Kubernetes-API . Ya,
from kubernetes import client
- Memiliki serangkaian fungsi yang layak untuk bekerja dengan string . Banyak!
- Bekerja dengan baik dengan format json dan yaml . Dengan sangat baik.
- Ramah manusia Tidak ada apa-apa.
- Sederhana Ya
- Kemampuan untuk mengimpor grafik Helm yang ada . Itu, kita akan menambahkan diri kita sendiri.
Ok, terlihat menjanjikan. Saya memutuskan untuk menulis alat templating sederhana di atas perpustakaan klien Python Resmi untuk kubernetes dan sekarang izinkan saya menunjukkan kepada Anda apa yang keluar darinya.
Temui karavel
Tidak ada yang istimewa atau rumit tentang alat ini. Saya baru saja mengambil perpustakaan Kubernetes (yang memberi saya kemampuan untuk bekerja dengan objek Kubernetes) dan menulis beberapa fungsionalitas dasar untuk grafik Helm yang ada (sehingga orang dapat mengambilnya dan menambahkannya ke grafik mereka sendiri). Jadi, mari kita melakukan tur.
Pertama-tama, alat ini dapat diakses di repo Github dan Anda dapat menemukan direktori dengan contoh di sana.
Mulai cepat dengan gambar Docker
Jika Anda ingin mencobanya, cara paling sederhana adalah dengan menggunakan gambar buruh pelabuhan ini :
$ docker run greegorey/karavel -h usage: karavelcli.py [-h] subcommand ... optional arguments: -h, --help show this help message and exit list of subcommands: subcommand template generates manifests from template ensure ensure helm dependencies
Tentu saja, jika Anda ingin membuat templat bagan, Anda perlu memasang direktori bagan Anda:
$ cd example $ docker run -v $PWD:/chart greegorey/karavel template .
Jadi, mari kita lihat struktur grafik. Ini sangat mirip dengan salah satu Helm:
$ cd example $ tree . . βββ dependencies βββ prod.yaml βββ requirements.yaml βββ templates β βββ custom-resource.py β βββ deployment.py β βββ service-helm.py βββ values.yaml 2 directories, 6 files
Seperti Helm, ia memiliki file requirements.yaml
dengan tata letak yang sama:
dependencies: - name: mysql version: 0.13.1 repository: https://kubernetes-charts.storage.googleapis.com/
Di sini Anda cukup mendaftar dependensi Helm yang ingin Anda impor ke bagan. Dependensi pergi ke direktori dependencies
. Untuk mengambil atau memperbaruinya gunakan perintah sure:
$ karavel ensure .
Setelah itu direktori dependencies
Anda akan terlihat seperti ini:
$ tree dependencies dependencies βββ mysql-0.13.1 βββ mysql βββ Chart.yaml βββ README.md βββ templates β βββ NOTES.txt β βββ _helpers.tpl β βββ configurationFiles-configmap.yaml β βββ deployment.yaml β βββ initializationFiles-configmap.yaml β βββ pvc.yaml β βββ secrets.yaml β βββ svc.yaml β βββ tests β βββ test-configmap.yaml β βββ test.yaml βββ values.yaml 4 directories, 13 files
Sekarang setelah kita memastikan dependensi kita mari kita lihat templat. Pertama, kami membuat penyebaran nginx sederhana:
from kubernetes import client from karavel.helpers import Values def template(): values = Values().values
Jadi, agar templat menjadi valid, Anda harus memiliki fungsi template()
yang mengembalikan objek Kubernetes tunggal atau list
/ tupelnya. Anda dapat menemukan daftar objek API untuk klien Python di sini .
Seperti yang Anda lihat, kodenya bersih, sederhana, mudah dibaca. Anda bisa bertanya-tanya dari mana berasal values.nginx.image.repository
? Ia mendapat nilai dari file nilai yang Anda lewati saat menyusun bagan, seperti di Helm: karavel template -f one.yaml --values two.yaml
. Kita akan melihatnya nanti.
Oke, bagaimana dengan grafik Helm?
Sekarang, kami membuat Penempatan kami sendiri. Tetapi bagaimana jika kita ingin mengimpor Helm bag atau bagian dari bagan? Mari kita lihat templates/service-helm.py
:
from kubernetes import client from karavel.helm import HelmChart from karavel.helpers import Values def template(): values = Values().values
Sederhana ya Perhatikan baris ini: service = chart.get(name='svc', obj_class=client.V1Service)
- kami membuat objek kelas V1Service
dari file Helm yaml
. Jika Anda tidak ingin / perlu melakukan itu - Anda selalu dapat bekerja dengan dict
.
Bagaimana jika saya ingin membuat sumber daya khusus?
Nah, ada masalah kecil dengan itu. API Kubernetes tidak menambahkan objek CRD ke definisi json /openapi/v2
di /openapi/v2
, dan objek Python-client dibuat berdasarkan definisi ini. Tetapi Anda masih dapat dengan mudah bekerja dengan objek-objek dict
. Seperti ini:
from kubernetes import client def template(): resource = { 'apiVersion': 'stable.example.com/v1', 'kind': 'Whale', 'metadata': client.V1ObjectMeta( name='my-object', ), 'spec': { 'image': 'my-whale-image:0.0.1', 'tail': 1, 'fins': 4, } } return resource
Masih terlihat bagus, bukan?
Bisakah saya memiliki nilai untuk lingkungan yang berbeda, misalnya dev / prod?
Ya kamu bisa!
Mari kita lihat values.yaml
terlebih dahulu:
nginx: image: repository: nginx tag: 1.15-alpine mysql: port: 3307 protocol: TCP helm: releaseName: my-release namespace: prod imageTag: '5.7.14' service: type: NodePort
Catat kunci helm
di dalam mysql
dict: kami menggunakannya ketika menentukan nilai untuk bagan helm: chart = HelmChart(name='mysql', version='0.13.1', values=values.mysql.helm)
. Beberapa grafik Helm memerlukan releaseName
untuk penamaan aplikasi dan namespace
untuk kebijakan RBAC. Kedua nilai ini diteruskan ke Helm sebagai argumen --namespace
dan NAME
dalam helm template
.
Sekarang, Anda dapat menentukan file tambahan untuk prod env, dan templat semua contoh kami:
$ karavel template -f values.yaml -f prod.yaml . --- # Source: templates/custom-resource.py apiVersion: stable.example.com/v1 kind: Whale metadata: name: my-object spec: fins: 4 image: my-whale-image:0.0.1 tail: 1 --- # Source: templates/deployment.py apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 template: metadata: labels: app: nginx spec: containers: - image: nginx:1.14-alpine name: nginx ports: - containerPort: 80 --- # Source: templates/service-helm.py apiVersion: v1 kind: Service metadata: annotations: null labels: app: prod-release-mysql chart: mysql-0.13.1 release: prod-release-suffix name: prod-release-mysql spec: ports: - name: my-custom-port port: 3308 protocol: TCP targetPort: 39000 selector: app: prod-release-mysql type: NodePort
Setelah itu Anda bisa melakukan kubeclt apply
dan menyebarkan objek-objek ini ke dalam cluster.
Keren! Bagaimana dengan encoding dan base64?
import base64
Bagaimana dengan menggunakan Vault untuk rahasia?
import hvac
Mengambil url?
import importlib
Fungsi hash aman?
import Crypto
Kamu mendapatkannya. Dengan Python Anda dapat melakukan banyak hal dengan manifes Kubernet Anda.
Apakah itu sindrom NIH?
Tidak :)
Saya dengan senang hati menggunakan Helm dalam proyek saya saat ini. Ada beberapa hal yang saya rindukan. Saya menggunakan Ksonnet di beberapa proyek saya juga.
Saya ingin menganggap alat ini sebagai bukti konsep bahwa kita dapat memiliki alat templating lebih baik daripada Helm dan tidak terlalu sulit untuk mengembangkannya menggunakan Python. Jika ada minat / kebutuhan masyarakat akan alat semacam itu, kita dapat bersama-sama terus mengembangkannya. Atau kita bisa menunggu rilis Helm 3;)
Kesimpulan
Saya telah menunjukkan kepada Anda alat templating berbasis Python untuk Kubernetes yang mendukung dan mendukung objek yang kompatibel dengan Kubernetes-API untuk mengimpor grafik Helm. Setiap komentar dan diskusi dari komunitas dipersilahkan, dan sekali lagi selamat datang di repo .
Terima kasih telah membaca ini dan semoga harimu menyenangkan!
Referensi