Memantau perubahan topologi layanan Kubernetes secara real time
Memantau perubahan topologi layanan Kubernetes secara real time
[ad_1]
Penyimpanan data yang dapat diskalakan secara horizontal seperti Elasticsearch, Cassandra, dan CockroachDB mendistribusikan datanya ke beberapa node menggunakan teknik seperti hashing yang konsisten. Saat node ditambahkan atau dihapus, data diacak ulang untuk memastikan bahwa beban didistribusikan secara merata ke seluruh kumpulan node baru.
Saat diterapkan pada cluster bare metal atau mesin virtual cloud, administrator database bertanggung jawab untuk menambah dan menghapus node dalam sistem cluster, menjadwalkan perubahan selama periode beban rendah untuk meminimalkan gangguan pada beban kerja produksi.
Dalam dunia aplikasi yang berjalan pada platform orkestrasi container seperti Kubernetes, container dapat dihentikan atau dimulai ulang karena seringnya penerapan, masalah penjadwalan, kegagalan node, masalah jaringan, dan perubahan tak terduga lainnya. Pada artikel ini, kita akan melihat bagaimana aplikasi yang mempertahankan status terdistribusi dapat melacak node yang masuk dan keluar dari cluster.
Manajemen beban kerja
Aplikasi di Kubernetes dijalankan sebagai container di dalam pod. Mengelola masing-masing pod untuk aplikasi terdistribusi merupakan hal yang rumit, sehingga Kubernetes menyediakan abstraksi tingkat tinggi yang mengelola pod untuk Anda.
- Penerapan cocok untuk menjalankan aplikasi stateless seperti server web, yang semua podnya sama dan tidak dapat dibedakan. Tidak ada pod yang memiliki identitas tertentu dan tidak dapat diganti secara bebas.
- Himpunan Berstatus lebih cocok untuk aplikasi stateful, dimana pod diharapkan memiliki identitas yang berbeda dan tidak dapat dipertukarkan secara bebas.
StatefulSets adalah pilihan manajemen beban kerja yang sesuai untuk contoh aplikasi penyimpanan data khusus kita. Selain itu, buat Kubernetes Melayani akan mengekspos aplikasi terdistribusi ke klien sebagai satu aplikasi jaringan bernama.
Memantau siklus hidup pod dalam suatu layanan
Anda memiliki StatefulSet yang berfungsi dengan layanan yang dapat diajak bicara oleh pelanggan, yang akhirnya membawa kita ke masalah utama dalam melacak pembuatan pod: penghapusan dan pengeditan waktu nyata.
Kubernetes menugaskan a nama host yang stabil ke setiap pod dalam StatefulSet. Kelemahan utama penggunaan nama host untuk mengalamatkan pod secara langsung adalah hasil DNS disimpan dalam cache, termasuk hasil kueri gagal yang dibuat pada pod yang tidak tersedia.
Masukkan API EndpointSlicesyang menyediakan pemantauan terukur terhadap titik akhir jaringan dalam cluster Kubernetes. Dengan penyeleksi yang sesuai, hal ini dapat digunakan untuk melacak siklus hidup pod dalam layanan tertentu, asalkan layanan tersebut memiliki pemilih tertentu.
Lebih tepatnya, aplikasi dapat memanggil Daftar Dan Jam tangan Titik akhir API.
Pertama, aplikasi membuat klien API Kubernetes.
import (
...
discovery "k8s.io/api/discovery/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
...
)
func main() {
ctx, cancel := base.InitContext()
defer cancel()
// Create a kubernetes API clientset
k8sRestConfig, err := rest.InClusterConfig()
if err != nil {
log.Fatalf("error getting in-cluster config: %v", err)
}
k8sClient, err := kubernetes.NewForConfig(k8sRestConfig)
if err != nil {
log.Fatalf("error creating k8s client: %v", err)
}
Kemudian aplikasi memanggil List
titik akhir untuk mengambil backend yang tersedia saat ini. Perhatikan bahwa label aplikasi adalah nilai label pemilih layanan. Hal ini memastikan bahwa List dan Watch API menargetkan pod layanan spesifik kami.
appLabel := "your-service-label"
podNamespace := "your-service-namespace"
// List the current service endpoints.
endpointSlice, err := k8sClient.DiscoveryV1().EndpointSlices(podNamespace).List(ctx, metav1.ListOptions{
LabelSelector: appLabel,
Watch: true,
})
if err != nil {
log.Fatalf("error listing endpoint slices: %v", err)
}
Kini setelah aplikasi memiliki kumpulan alamat saat ini, aplikasi dapat memantau perubahan dari status ini dengan memanggil Watch API. Hal ini dilakukan dalam satu lingkaran di latar belakang untuk memungkinkan aplikasi melanjutkan sisa pekerjaannya. Daftar API menyediakan pos pemeriksaan yang disebut ResourceVersion
dari sana kita dapat meminta arloji untuk mulai mengamati peristiwa.
Watch API mengirimkan hasilnya ke ResultChan
saluran.
// ResourceVersion is like a checkpoint that we're instructing the Watch to start from.
resourceVersion := endpointSlice.ResourceVersion
go func() {
// Start a watch on the service endpoints
watch, err := k8sClient.DiscoveryV1().EndpointSlices(podNamespace).Watch(ctx, metav1.ListOptions{
LabelSelector: appLabel,
Watch: true,
// Start watching from the appropriate resource version
ResourceVersion: resourceVersion,
})
if err != nil {
log.Fatalf("error watching endpoint slices: %v", err)
}
// Loop until the context is done
for {
select {
case <-ctx.Done():
break
case event := <-watch.ResultChan():
handleWatchEvent(watch);
}
}
}()
// Start the server / do other work
}
Aplikasi kemudian dapat menangani acara Tontonan dengan tepat.
func handleWatchEvent(event watch.Event) {
// Cast the event into an EndpointSlice event
endpointSlice, ok := event.Object.(*discovery.EndpointSlice)
if !ok {
log.Fatalf("unexpected event object")
}
// From
// Object is:
// * If Type is Added or Modified: the new state of the object.
// * If Type is Deleted: the state of the object immediately before deletion.
// * If Type is Bookmark: the object (instance of a type being watched) where
// only ResourceVersion field is set. On successful restart of watch from a
// bookmark resourceVersion, client is guaranteed to not get repeat event
// nor miss any events.
// * If Type is Error: *api.Status is recommended; other types may make sense
// depending on context.
switch event.Type {
case watch.Added:
// Handle Added event
case watch.Modified:
// Handle Modified event
case watch.Deleted:
// Handle Deleted event
case watch.Error:
// Handle Error event
}
}
Penting untuk dicatat dalam dokumentasi bahwa Added
Dan Modified
peristiwa mengirimkan keadaan objek yang baru secara lengkap. Oleh karena itu, jika aplikasi mengelola alamat titik akhir secara internal, tidak perlu memperbaruinya secara bertahap.
Langkah terakhir adalah memastikan bahwa aplikasi Anda memiliki izin yang diperlukan untuk memanggil sumber daya API EndpointSlices.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: server-endpoints-role
rules:
- apiGroups: ["discovery.k8s.io"]
resources: ["endpointslices"]
verbs: ["list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: server-endpoints-rolebinding
subjects:
- kind: ServiceAccount
name: server
roleRef:
kind: Role
name: server-endpoints-role
apiGroup: rbac.authorization.k8s.io
Kesimpulan
EndpointSlices Kubernetes API menyediakan cara yang terukur, dapat diperluas, dan nyaman untuk memantau peristiwa siklus hidup pod di layanan Kubernetes secara real-time, sehingga memungkinkan penyeimbangan beban yang transparan dalam aplikasi terdistribusi yang stateful.
[ad_2]