Beban kerja - Amazon EKS

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Beban kerja

Beban kerja berdampak pada seberapa besar skala klaster Anda. Beban kerja yang menggunakan Kubernetes APIs akan membatasi jumlah total beban kerja yang dapat Anda miliki dalam satu cluster, tetapi ada beberapa default yang dapat Anda ubah untuk membantu mengurangi beban.

Beban kerja di klaster Kubernetes memiliki akses ke fitur-fitur yang terintegrasi dengan Kubernetes API (misalnya Secrets and ServiceAccounts), tetapi fitur-fitur ini tidak selalu diperlukan dan harus dinonaktifkan jika tidak digunakan. Membatasi akses beban kerja dan ketergantungan pada bidang kontrol Kubernetes akan meningkatkan jumlah beban kerja yang dapat Anda jalankan di klaster dan meningkatkan keamanan klaster Anda dengan menghapus akses yang tidak perlu ke beban kerja dan menerapkan praktik hak istimewa yang paling sedikit. Silakan baca praktik terbaik keamanan untuk informasi lebih lanjut.

Gunakan IPv6 untuk jaringan pod

Anda tidak dapat mentransisikan VPC dari IPv4 ke IPv6 pengaktifan IPv6 sebelum menyediakan klaster adalah penting. Jika Anda mengaktifkan IPv6 dalam VPC, itu tidak berarti Anda harus menggunakannya dan jika pod dan layanan Anda digunakan, Anda masih dapat IPv6 merutekan lalu lintas ke dan dari IPv4 alamat. Silakan lihat praktik terbaik jaringan EKS untuk informasi lebih lanjut.

Menggunakan IPv6 di klaster Anda menghindari beberapa batas penskalaan klaster dan beban kerja yang paling umum. IPv6 menghindari kehabisan alamat IP di mana pod dan node tidak dapat dibuat karena tidak ada alamat IP yang tersedia. Ini juga memiliki peningkatan kinerja per node karena pod menerima alamat IP lebih cepat dengan mengurangi jumlah lampiran ENI per node. Anda dapat mencapai kinerja node yang serupa dengan menggunakan mode IPv4 awalan di VPC CNI, tetapi Anda masih perlu memastikan bahwa Anda memiliki cukup alamat IP yang tersedia di VPC.

Batasi jumlah layanan per namespace

Jumlah maksimum layanan di ruang nama adalah 5.000 dan jumlah maksimum layanan dalam sebuah cluster adalah 10.000. Untuk membantu mengatur beban kerja dan layanan, meningkatkan kinerja, dan untuk menghindari dampak cascading untuk sumber daya cakupan namespace, kami sarankan untuk membatasi jumlah layanan per namespace menjadi 500.

Jumlah aturan tabel IP yang dibuat per node dengan kube-proxy bertambah dengan jumlah total layanan di cluster. Menghasilkan ribuan aturan tabel IP dan paket routing melalui aturan tersebut memiliki dampak kinerja pada node dan menambahkan latensi jaringan.

Buat ruang nama Kubernetes yang mencakup satu lingkungan aplikasi selama jumlah layanan per namespace di bawah 500. Ini akan membuat penemuan layanan cukup kecil untuk menghindari batas penemuan layanan dan juga dapat membantu Anda menghindari tabrakan penamaan layanan. Lingkungan aplikasi (misalnya dev, test, prod) harus menggunakan cluster EKS terpisah alih-alih ruang nama.

Memahami Kuota Elastic Load Balancer

Saat membuat layanan Anda, pertimbangkan jenis load balancing yang akan Anda gunakan (misalnya Network Load Balancer (NLB) atau Application Load Balancer (ALB)). Setiap jenis penyeimbang beban menyediakan fungsionalitas yang berbeda dan memiliki kuota yang berbeda. Beberapa kuota default dapat disesuaikan, tetapi ada beberapa kuota maksimum yang tidak dapat diubah. Untuk melihat kuota dan penggunaan akun Anda, lihat dasbor Service Quotas di konsol AWS.

Misalnya, target ALB default adalah 1000. Jika Anda memiliki layanan dengan lebih dari 1000 titik akhir, Anda perlu menambah kuota atau membagi layanan menjadi beberapa ALBs atau menggunakan Kubernetes Ingress. Target NLB default adalah 3000, tetapi terbatas pada 500 target per AZ. Jika klaster Anda menjalankan lebih dari 500 pod untuk layanan NLB, Anda harus menggunakan beberapa AZs atau meminta peningkatan batas kuota.

Alternatif untuk menggunakan penyeimbang beban yang digabungkan ke layanan adalah dengan menggunakan pengontrol masuk. Pengontrol AWS Load Balancer dapat membuat sumber daya ingress, tetapi Anda dapat mempertimbangkan ALBs untuk menjalankan pengontrol khusus di klaster Anda. Pengontrol ingress in-cluster memungkinkan Anda mengekspos beberapa layanan Kubernetes dari penyeimbang beban tunggal dengan menjalankan proxy terbalik di dalam klaster Anda. Pengontrol memiliki fitur yang berbeda seperti dukungan untuk API Gateway yang mungkin memiliki manfaat tergantung pada berapa banyak dan seberapa besar beban kerja Anda.

Gunakan Route 53, Global Accelerator, atau CloudFront

Agar layanan menggunakan beberapa penyeimbang beban tersedia sebagai satu titik akhir, Anda perlu menggunakan Amazon, AWS Global Accelerator CloudFront, atau Amazon Route 53 untuk mengekspos semua penyeimbang beban sebagai satu titik akhir yang menghadap pelanggan. Setiap opsi memiliki manfaat yang berbeda dan dapat digunakan secara terpisah atau bersama-sama tergantung pada kebutuhan Anda.

Route 53 dapat mengekspos beberapa penyeimbang beban dengan nama umum dan dapat mengirim lalu lintas ke masing-masing berdasarkan bobot yang ditetapkan. Anda dapat membaca lebih lanjut tentang bobot DNS dalam dokumentasi dan Anda dapat membaca cara mengimplementasikannya dengan pengontrol DNS eksternal Kubernetes dalam dokumentasi AWS Load Balancer Controller.

Global Accelerator dapat merutekan beban kerja ke wilayah terdekat berdasarkan alamat IP permintaan. Ini mungkin berguna untuk beban kerja yang diterapkan ke beberapa wilayah, tetapi tidak meningkatkan perutean ke satu cluster di satu wilayah. Menggunakan Route 53 dalam kombinasi dengan Global Accelerator memiliki manfaat tambahan seperti pemeriksaan kesehatan dan failover otomatis jika AZ tidak tersedia. Anda dapat melihat contoh penggunaan Global Accelerator dengan Route 53 di posting blog ini.

CloudFront dapat digunakan dengan Route 53 dan Global Accelerator atau dengan sendirinya untuk merutekan lalu lintas ke beberapa tujuan. CloudFront menyimpan aset yang dilayani dari sumber asal yang dapat mengurangi persyaratan bandwidth tergantung pada apa yang Anda layani.

Gunakan EndpointSlices alih-alih Titik Akhir

Saat menemukan pod yang cocok dengan label layanan, Anda harus menggunakan EndpointSlicesalih-alih Titik Akhir. Endpoint adalah cara sederhana untuk mengekspos layanan dalam skala kecil tetapi layanan besar yang secara otomatis menskalakan atau memiliki pembaruan menyebabkan banyak lalu lintas di bidang kontrol Kubernetes. EndpointSlices memiliki pengelompokan otomatis yang memungkinkan hal-hal seperti petunjuk sadar topologi.

Tidak semua pengontrol menggunakan secara EndpointSlices default. Anda harus memverifikasi pengaturan pengontrol Anda dan mengaktifkannya jika diperlukan. Untuk AWS Load Balancer Controller, Anda harus mengaktifkan flag --enable-endpoint-slices opsional untuk digunakan. EndpointSlices

Gunakan rahasia abadi dan eksternal jika memungkinkan

Kubelet menyimpan cache kunci dan nilai saat ini untuk Secrets yang digunakan dalam volume untuk pod pada node tersebut. Kubelet mengatur arloji pada Rahasia untuk mendeteksi perubahan. Seiring dengan skala klaster, semakin banyak jam tangan dapat berdampak negatif pada kinerja server API.

Ada dua strategi untuk mengurangi jumlah jam tangan di Rahasia:

  • Untuk aplikasi yang tidak memerlukan akses ke sumber daya Kubernetes, Anda dapat menonaktifkan rahasia akun layanan pemasangan otomatis dengan menyetel Token: false automountServiceAccount

  • Jika rahasia aplikasi Anda statis dan tidak akan dimodifikasi di masa depan, tandai rahasianya sebagai tidak dapat diubah. Kubelet tidak memelihara API watch untuk rahasia yang tidak dapat diubah.

Untuk menonaktifkan pemasangan akun layanan secara otomatis ke pod, Anda dapat menggunakan pengaturan berikut di beban kerja Anda. Anda dapat mengganti pengaturan ini jika beban kerja tertentu memerlukan akun layanan.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: app
automountServiceAccountToken: true

Pantau jumlah rahasia di cluster sebelum melebihi batas 10.000. Anda dapat melihat jumlah total rahasia dalam sebuah cluster dengan perintah berikut. Anda harus memantau batas ini melalui alat pemantauan cluster Anda.

kubectl get secrets -A | wc -l

Anda harus mengatur pemantauan untuk mengingatkan admin klaster sebelum batas ini tercapai. Pertimbangkan untuk menggunakan opsi manajemen rahasia eksternal seperti AWS Key Management Service (AWS KMS) atau Hashicorp Vault dengan driver Secrets Store CSI.

Batasi riwayat Penerapan

Pod bisa lambat saat membuat, memperbarui, atau menghapus karena objek lama masih dilacak di cluster. Anda dapat mengurangi revisionHistoryLimit penerapan menjadi pembersihan yang lebih lama ReplicaSets yang akan menurunkan jumlah total objek yang dilacak oleh Kubernetes Controller Manager. Batas riwayat default untuk Deployment di 10.

Jika klaster Anda membuat banyak objek pekerjaan melalui CronJobs atau mekanisme lain, Anda harus menggunakan ttlSecondsAfterFinishedpengaturan untuk secara otomatis membersihkan pod lama di cluster. Ini akan menghapus pekerjaan yang berhasil dieksekusi dari riwayat pekerjaan setelah jangka waktu tertentu.

Ketika sebuah Pod berjalan pada Node, kubelet menambahkan satu set variabel lingkungan untuk setiap Service yang aktif. Proses Linux memiliki ukuran maksimum untuk lingkungan mereka yang dapat dicapai jika Anda memiliki terlalu banyak layanan di namespace Anda. Jumlah layanan per namespace tidak boleh melebihi 5.000. Setelah ini, jumlah variabel lingkungan layanan melebihi batas shell, menyebabkan Pod mogok saat startup.

Ada alasan lain Pod tidak boleh menggunakan variabel lingkungan layanan untuk penemuan layanan. Bentrokan nama variabel lingkungan, nama layanan bocor, dan ukuran lingkungan total adalah beberapa. Anda harus menggunakan CoreDNS untuk menemukan titik akhir layanan.

Batasi webhook penerimaan dinamis per sumber daya

Dynamic Admission Webhooks mencakup webhook masuk dan webhook yang bermutasi. Mereka adalah endpoint API yang bukan bagian dari Kubernetes Control Plane yang dipanggil secara berurutan ketika sebuah resource dikirim ke Kubernetes API. Setiap webhook memiliki batas waktu default 10 detik dan dapat meningkatkan jumlah waktu yang dibutuhkan permintaan API jika Anda memiliki beberapa webhook atau salah satu dari mereka batas waktu.

Pastikan webhook Anda sangat tersedia—terutama selama insiden AZ—dan FailurePolicy disetel dengan benar untuk menolak sumber daya atau mengabaikan kegagalan. Jangan panggil webhook saat tidak diperlukan dengan mengizinkan perintah --dry-run kubectl untuk melewati webhook.

apiVersion: admission.k8s.io/v1
kind: AdmissionReview
request:
  dryRun: False

Webhook yang bermutasi dapat memodifikasi sumber daya secara berurutan. Jika Anda memiliki 5 webhook yang bermutasi dan menyebarkan 50 sumber daya, etcd akan menyimpan semua versi setiap sumber daya hingga pemadatan berjalan—setiap 5 menit—untuk menghapus versi lama sumber daya yang dimodifikasi. Dalam skenario ini ketika etcd menghapus sumber daya yang digantikan, akan ada 200 versi sumber daya yang dihapus dari etcd dan tergantung pada ukuran sumber daya dapat menggunakan ruang yang cukup besar pada host etcd hingga defragmentasi berjalan setiap 15 menit.

Defragmentasi ini dapat menyebabkan jeda di etcd yang dapat memiliki pengaruh lain pada API dan pengontrol Kubernetes. Anda harus menghindari modifikasi sumber daya besar yang sering atau memodifikasi ratusan sumber daya secara berurutan.

Bandingkan beban kerja di beberapa cluster

Jika Anda memiliki dua cluster yang seharusnya memiliki kinerja serupa tetapi tidak, coba bandingkan metrik untuk mengidentifikasi alasannya.

Misalnya, membandingkan latensi cluster adalah masalah umum. Hal ini biasanya disebabkan oleh perbedaan volume permintaan API. Anda dapat menjalankan CloudWatch LogInsight kueri berikut untuk memahami perbedaannya.

filter @logStream like "kube-apiserver-audit"
| stats count(*) as cnt by objectRef.apiGroup, objectRef.apiVersion, objectRef.resource, userAgent, verb, responseStatus.code
| sort cnt desc
| limit 1000

Anda dapat menambahkan filter tambahan untuk mempersempitnya. misalnya berfokus pada semua permintaan daftar darifoo.

filter @logStream like "kube-apiserver-audit"
| filter verb = "list"
| filter user.username like "foo"
| stats count(*) as cnt by objectRef.apiGroup, objectRef.apiVersion, objectRef.resource, responseStatus.code
| sort cnt desc
| limit 1000