Bagaimana cara menghemat biaya cloud saat bekerja dengan Kubernetes? Tidak ada satu solusi yang tepat, namun artikel ini menjelaskan beberapa alat yang dapat membantu Anda mengelola sumber daya dengan lebih efektif dan mengurangi biaya komputasi awan.
Saya menulis artikel ini dengan mempertimbangkan Kubernetes untuk AWS, tetapi artikel ini akan berlaku (hampir) sama persis dengan penyedia cloud lainnya. Saya berasumsi cluster Anda sudah memiliki konfigurasi penskalaan otomatis (penskala otomatis cluster). Menghapus sumber daya dan mengurangi penerapan Anda hanya akan menghemat uang jika hal ini juga mengurangi armada node pekerja Anda (instans EC2).
Bekerja di lingkungan yang serba cepat adalah hal yang bagus. Kami menginginkan organisasi teknologi dipercepat. Pengiriman perangkat lunak yang lebih cepat juga berarti lebih banyak penerapan PR, lingkungan pratinjau, prototipe, dan solusi analitik. Semuanya diterapkan di Kubernetes. Siapa yang punya waktu untuk membersihkan penerapan pengujian secara manual? Sangat mudah untuk melupakan penghapusan eksperimen yang berumur seminggu. Tagihan cloud akan naik karena sesuatu yang lupa kita tutup:
(Henning Jacobs:
Zhiza:
(kutipan) Corey Quinn:
Mitos: Akun AWS Anda adalah fungsi dari jumlah pengguna yang Anda miliki.
Fakta: Skor AWS Anda merupakan fungsi dari jumlah insinyur yang Anda miliki.
Ivan Kurnosov (sebagai tanggapan):
Fakta sebenarnya: Skor AWS Anda adalah fungsi dari jumlah hal yang lupa Anda nonaktifkan/hapus.)
Petugas Kebersihan Kubernetes (kube-janitor) membantu membersihkan cluster Anda. Konfigurasi petugas kebersihan fleksibel untuk penggunaan global dan lokal:
Aturan di seluruh klaster dapat menentukan waktu hidup maksimum (TTL) untuk penerapan PR/pengujian.
Sumber daya individual dapat dianotasi dengan petugas kebersihan/ttl, misalnya untuk menghapus lonjakan/prototipe secara otomatis setelah 7 hari.
Aturan umum ditentukan dalam file YAML. Jalurnya melewati parameter --rules-file di kube-petugas kebersihan. Berikut adalah contoh aturan untuk menghapus semua namespace -pr- atas nama setelah dua hari:
Contoh berikut mengatur penggunaan label aplikasi pada pod Deployment dan StatefulSet untuk semua Deployment/StatefulSet baru pada tahun 2020, namun pada saat yang sama memungkinkan pelaksanaan pengujian tanpa label ini selama seminggu:
- id: require-application-label
# удалить deployments и statefulsets без метки "application"
resources:
- deployments
- statefulsets
# см. http://jmespath.org/specification.html
jmespath: "!(spec.template.metadata.labels.application) && metadata.creationTimestamp > '2020-01-01'"
ttl: 7d
Jalankan demo berbatas waktu selama 30 menit pada cluster yang menjalankan kube-janitor:
kubectl run nginx-demo --image=nginx
kubectl annotate deploy nginx-demo janitor/ttl=30m
Sumber lain peningkatan biaya adalah volume persisten (AWS EBS). Menghapus StatefulSet Kubernetes tidak menghapus volume persistennya (PVC - PersistentVolumeClaim). Volume EBS yang tidak terpakai dapat dengan mudah menimbulkan biaya ratusan dolar per bulan. Kubernetes Janitor memiliki fitur untuk membersihkan PVC yang tidak terpakai. Misalnya, aturan ini akan menghapus semua PVC yang tidak dipasang oleh modul dan tidak direferensikan oleh StatefulSet atau CronJob:
# удалить все PVC, которые не смонтированы и на которые не ссылаются StatefulSets
- id: remove-unused-pvcs
resources:
- persistentvolumeclaims
jmespath: "_context.pvc_is_not_mounted && _context.pvc_is_not_referenced"
ttl: 24h
Kubernetes Janitor dapat membantu Anda menjaga cluster Anda tetap bersih dan mencegah biaya komputasi awan menumpuk secara perlahan. Untuk petunjuk penerapan dan konfigurasi, ikuti README kube-petugas kebersihan.
Kurangi penskalaan di luar jam kerja
Sistem pengujian dan pementasan biasanya diharuskan beroperasi hanya selama jam kerja. Beberapa aplikasi produksi, seperti alat back office/admin, juga hanya memerlukan ketersediaan terbatas dan mungkin dinonaktifkan dalam semalam.
Penurunan Skala Kubernetes (kube-downscaler) memungkinkan pengguna dan operator untuk memperkecil skala sistem di luar jam kerja. Deployment dan StatefulSets dapat menskalakan hingga nol replika. CronJobs mungkin ditangguhkan. Kubernetes Downscaler dikonfigurasi untuk seluruh cluster, satu atau lebih namespace, atau sumber daya individual. Anda dapat mengatur “waktu menganggur” atau, sebaliknya, “waktu kerja”. Misalnya, untuk mengurangi penskalaan sebanyak mungkin pada malam hari dan akhir pekan:
image: hjacobs/kube-downscaler:20.4.3
args:
- --interval=30
# не отключать компоненты инфраструктуры
- --exclude-namespaces=kube-system,infra
# не отключать kube-downscaler, а также оставить Postgres Operator, чтобы исключенными БД можно было управлять
- --exclude-deployments=kube-downscaler,postgres-operator
- --default-uptime=Mon-Fri 08:00-20:00 Europe/Berlin
- --include-resources=deployments,statefulsets,stacks,cronjobs
- --deployment-time-annotation=deployment-time
Berikut adalah grafik untuk menskalakan node pekerja cluster pada akhir pekan:
Mengurangi skala dari ~13 menjadi 4 node pekerja tentu saja membuat perbedaan nyata pada tagihan AWS Anda.
Namun bagaimana jika saya harus bekerja selama "waktu henti" cluster? Penerapan tertentu dapat dikecualikan secara permanen dari penskalaan dengan menambahkan anotasi downscaler/exclude: true. Penerapan dapat dikecualikan untuk sementara menggunakan anotasi downscaler/exclude-until dengan stempel waktu absolut dalam format YYYY-MM-DD HH:MM (UTC). Jika perlu, seluruh cluster dapat diperkecil dengan men-deploy pod yang dilengkapi anotasi downscaler/force-uptime, misalnya dengan meluncurkan nginx blank:
kubectl run scale-up --image=nginx
kubectl annotate deploy scale-up janitor/ttl=1h # удалить развертывание через час
kubectl annotate pod $(kubectl get pod -l run=scale-up -o jsonpath="{.items[0].metadata.name}") downscaler/force-uptime=true
Lihat README kube-downscaler, jika Anda tertarik dengan petunjuk penerapan dan opsi tambahan.
Gunakan penskalaan otomatis horizontal
Banyak aplikasi/layanan menghadapi pola pemuatan dinamis: terkadang modulnya menganggur, dan terkadang bekerja pada kapasitas penuh. Mengoperasikan armada pod permanen untuk mengatasi beban puncak maksimum tidaklah ekonomis. Kubernetes mendukung penskalaan otomatis horizontal di seluruh sumber daya Penskala OtomatisPod Horisontal (HPA). Penggunaan CPU sering kali merupakan indikator yang baik untuk penskalaan:
Zalando telah membuat komponen untuk dengan mudah menghubungkan metrik khusus untuk penskalaan: Adaptor Metrik Kube (kube-metrics-adapter) adalah adaptor metrik umum untuk Kubernetes yang dapat mengumpulkan dan menyajikan metrik khusus dan eksternal untuk penskalaan otomatis pod secara horizontal. Ini mendukung penskalaan berdasarkan metrik Prometheus, antrian SQS, dan pengaturan lainnya. Misalnya, untuk menskalakan penerapan Anda ke metrik khusus yang diwakili oleh aplikasi itu sendiri sebagai JSON di /metrics gunakan:
Mengonfigurasi penskalaan otomatis horizontal dengan HPA harus menjadi salah satu tindakan default untuk meningkatkan efisiensi layanan tanpa kewarganegaraan. Spotify memiliki presentasi dengan pengalaman dan rekomendasi mereka untuk HPA: skalakan penerapan Anda, bukan dompet Anda.
Mengurangi pemesanan sumber daya yang berlebihan
Beban kerja Kubernetes menentukan kebutuhan CPU/memorinya melalui “permintaan sumber daya”. Sumber daya CPU diukur dalam inti virtual atau lebih umum dalam “milicore”, misalnya 500m berarti 50% vCPU. Sumber daya memori diukur dalam byte, dan sufiks umum dapat digunakan, seperti 500Mi, yang berarti 500 megabita. Permintaan sumber daya "mengunci" kapasitas pada node pekerja, yang berarti sebuah pod dengan permintaan CPU 1000m pada sebuah node dengan 4 vCPU hanya akan menyisakan 3 vCPU yang tersedia untuk pod lain. [1]
Slack (kelebihan cadangan) adalah perbedaan antara sumber daya yang diminta dan penggunaan sebenarnya. Misalnya, sebuah pod yang meminta memori sebesar 2 GiB namun hanya menggunakan 200 MiB memiliki memori “kelebihan” sebesar ~1,8 GiB. Kelebihan membutuhkan uang. Secara kasar dapat diperkirakan bahwa 1 GiB memori redundant berharga ~$10 per bulan. [2]
Laporan Sumber Daya Kubernetes (kube-resource-report) menampilkan kelebihan cadangan dan dapat membantu Anda menentukan potensi penghematan:
Laporan Sumber Daya Kubernetes menunjukkan kelebihan yang dikumpulkan berdasarkan aplikasi dan perintah. Hal ini memungkinkan Anda menemukan tempat di mana kebutuhan sumber daya dapat dikurangi. Laporan HTML yang dihasilkan hanya memberikan gambaran singkat penggunaan sumber daya. Anda harus melihat penggunaan CPU/memori dari waktu ke waktu untuk menentukan permintaan sumber daya yang memadai. Berikut adalah diagram Grafana untuk layanan "khas" yang banyak menggunakan CPU: semua pod menggunakan kurang dari 3 inti CPU yang diminta:
Mengurangi permintaan CPU dari 3000m menjadi ~400m akan membebaskan sumber daya untuk beban kerja lain dan memungkinkan cluster menjadi lebih kecil.
Tapi apakah kita benar-benar ingin orang mengubah nilai dalam file YAML? Tidak, mesin bisa melakukannya dengan lebih baik! Kubernet Penskala Otomatis Pod Vertikal (VPA) melakukan hal itu: mengadaptasi permintaan dan batasan sumber daya sesuai dengan beban kerja. Berikut ini contoh grafik permintaan CPU Prometheus (garis biru tipis) yang diadaptasi oleh VPA dari waktu ke waktu:
Goldilocks dari Fairwind adalah alat yang membuat VPA untuk setiap penerapan di namespace dan kemudian menampilkan rekomendasi VPA di dasbornya. Ini dapat membantu pengembang mengatur permintaan CPU/memori yang benar untuk aplikasi mereka:
Yang terakhir, biaya AWS EC2 dapat dikurangi dengan menggunakan instans Spot sebagai node pekerja Kubernetes [3]. Instans spot tersedia dengan diskon hingga 90% dibandingkan harga Sesuai Permintaan. Menjalankan Kubernetes di EC2 Spot adalah kombinasi yang baik: Anda perlu menentukan beberapa jenis instans berbeda untuk ketersediaan yang lebih tinggi, yang berarti Anda bisa mendapatkan node yang lebih besar dengan harga yang sama atau lebih rendah, dan peningkatan kapasitas tersebut dapat digunakan oleh beban kerja Kubernetes yang terkontainer.
Bagaimana cara menjalankan Kubernetes di EC2 Spot? Ada beberapa opsi: gunakan layanan pihak ketiga seperti SpotInst (sekarang disebut "Spot", jangan tanya kenapa), atau cukup tambahkan Spot AutoScalingGroup (ASG) ke cluster Anda. Misalnya, berikut cuplikan CloudFormation untuk ASG Spot yang "dioptimalkan kapasitas" dengan beberapa jenis instans:
Apa praktik terbaik Anda untuk menghemat biaya cloud di Kubernetes? Tolong beritahu saya di Twitter (@coba_kecuali_).
[1] Faktanya, kurang dari 3 vCPU akan tetap dapat digunakan karena throughput node dikurangi dengan sumber daya sistem yang dicadangkan. Kubernetes membedakan antara kapasitas node fisik dan sumber daya yang "disediakan" (Node Dapat Dialokasikan).
[2] Contoh perhitungan: satu instance m5.large dengan memori 8 GiB adalah ~$84 per bulan (eu-central-1, On-Demand), mis. memblokir 1/8 node kira-kira ~$10/bulan.
[3] Masih banyak lagi cara untuk mengurangi tagihan EC2 Anda, seperti Reserved Instances, Savings Plan, dll. - Saya tidak akan membahas topik tersebut di sini, namun Anda harus memperhatikannya!