Flazzo memiliki fokus utama untuk menambah nilai bisnis Anda.

Blog

Memantau perubahan topologi layanan Kubernetes secara real time

18015911-thumb.jpg
Blog

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]