Memecahkan masalah sinkronisasi konfigurasi ke cluster

Halaman ini menunjukkan cara menyelesaikan masalah terkait sinkronisasi konfigurasi ke cluster Anda.

Memecahkan masalah error KNV 2009

Error KNV2009 menunjukkan bahwa Config Sync gagal menyinkronkan beberapa konfigurasi ke cluster. Bagian berikut menjelaskan beberapa penyebab paling umum dan cara mengatasinya.

Operasi pada resource tertentu dilarang

Karena Anda perlu memberikan RBAC kepada objek RepoSync, izin yang diperlukan untuk menerapkan resource mungkin tidak ada.

Anda dapat memverifikasi bahwa izin tersebut tidak ada dengan mendapatkan status resource RepoSync:

kubectl get reposync repo-sync -n NAMESPACE -o yaml

Ganti NAMESPACE dengan namespace tempat Anda membuat repositori namespace.

Anda juga dapat menggunakan perintah nomos status.

Jika Anda melihat pesan berikut dalam status, berarti rekonsiler di NAMESPACE tidak memiliki izin yang diperlukan untuk menerapkan resource:

KNV2009: deployments.apps "nginx-deployment" is forbidden: User "system:serviceaccount:config-management-system:ns-reconciler-default" cannot get resource "deployments" in API group "apps" in the namespace "default"

Untuk memperbaiki masalah ini, Anda harus mendeklarasikan konfigurasi RoleBinding yang memberikan izin rekonsiler ke akun layanan untuk mengelola resource yang gagal dalam namespace tersebut. Detail tentang cara menambahkan RoleBinding disertakan dalam Mengonfigurasi sinkronisasi dari beberapa repositori.

Masalah ini juga dapat memengaruhi objek RootSync jika Anda telah menggunakan spec.override.roleRefs untuk mengubah peran yang diberikan ke objek RootSync. Jika Anda belum menetapkan kolom ini, objek RootSync diberi peran cluster-admin secara default.

Objek ResourceGroup melebihi batas ukuran objek etcd

Jika Anda menerima error berikut saat rekonsiliasi mencoba menerapkan konfigurasi ke cluster, objek ResourceGroup melebihi batas ukuran objek etcd:

KNV2009: too many declared resources causing ResourceGroup.kpt.dev, config-management-system/root-sync failed to be applied: task failed (action: "Inventory", name: "inventory-add-0"): Request entity too large: limit is 3145728. To fix, split the resources into multiple repositories.

Sebaiknya Anda membagi repositori Git menjadi beberapa repositori. Jika Anda tidak dapat memecah repositori Git, karena objek sudah terlalu besar dan perubahan tidak dipertahankan, Anda dapat memitigasinya dengan mengonfigurasi RootSync atau RepoSync untuk menonaktifkan penulisan status objek ke ResourceGroup untuk sementara. Anda dapat melakukannya dengan menetapkan kolom .spec.override.statusMode dari objek RootSync atau RepoSync ke disabled. Dengan demikian, Config Sync akan berhenti memperbarui status resource terkelola pada objek ResourceGroup. Tindakan ini akan mengurangi ukuran objek ResourceGroup. Namun, Anda tidak dapat melihat status untuk resource terkelola dari nomos status atau gcloud alpha anthos config sync.

Jika Anda tidak melihat error apa pun dari objek RootSync atau RepoSync, berarti objek dari sumber tepercaya telah disinkronkan ke cluster. Untuk memeriksa apakah resource ResourceGroup melebihi batas ukuran objek etcd, periksa status resource ResourceGroup dan log pengontrol ResourceGroup:

  1. Periksa status ResourceGroup:

    • Untuk memeriksa objek RootSync, jalankan perintah berikut:

      kubectl get resourcegroup root-sync -n config-management-system
      
    • Untuk memeriksa objek RepoSync, jalankan perintah berikut:

      kubectl get resourcegroup repo-sync -n NAMESPACE
      

      Ganti NAMESPACE dengan namespace tempat Anda membuat repositori namespace.

    Outputnya mirip dengan contoh berikut:

    NAME        RECONCILING   STALLED   AGE
    root-sync   True          False     35m
    

    Jika nilai di kolom RECONCILING adalah True, artinya resource ResourceGroup masih melakukan rekonsiliasi.

  2. Periksa log untuk pengontrol ResourceGroup:

    kubectl logs deployment resource-group-controller-manager -c manager -n resource-group-system
    

    Jika Anda melihat error yang mirip dengan contoh berikut dalam output, berarti resource ResourceGroup terlalu besar dan melebihi batas ukuran objek etcd:

    "error":"etcdserver: request is too large"
    

Agar ResourceGroup tidak menjadi terlalu besar, kurangi jumlah resource di repositori Git Anda. Anda dapat membagi satu repositori root menjadi beberapa repositori root.

Waktu tunggu rekonsiliasi penerapan dependensi

Jika Anda menyinkronkan objek dengan dependensi, Anda mungkin menerima error yang serupa dengan contoh berikut saat rekonsiler mencoba menerapkan objek dengan anotasi config.kubernetes.io/depends-on ke cluster:

KNV2009: skipped apply of Pod, bookstore/pod4: dependency apply reconcile timeout: bookstore_pod3__Pod  For more information, see https://g.co/cloud/acm-errors#knv2009

Error ini berarti objek dependensi tidak direkonsiliasi dalam waktu tunggu rekonsiliasi default, yaitu lima menit. Config Sync tidak dapat menerapkan objek dependen karena dengan anotasi config.kubernetes.io/depends-on, Config Sync hanya menerapkan objek sesuai urutan yang Anda inginkan. Anda dapat mengganti waktu tunggu rekonsiliasi default ke waktu yang lebih lama dengan menetapkan spec.override.reconcileTimeout.

Ada kemungkinan bahwa dependensi tersebut akan direkonsiliasi setelah upaya sinkronisasi awal selesai. Dalam hal ini, dependensi harus terdeteksi sebagai direkonsiliasi pada upaya percobaan ulang sinkronisasi berikutnya, sehingga membatalkan penerapan dependensi apa pun. Jika ini terjadi, error tersebut mungkin akan dilaporkan secara singkat, lalu dihapus. Memperpanjang waktu tunggu rekonsiliasi dapat membantu menghindari error yang dilaporkan sesekali.

Info inventaris tidak ada

Jika Anda menerima error berikut saat rekonsiler mencoba menerapkan konfigurasi ke cluster, kemungkinan inventaris Anda tidak memiliki resource atau manifes memiliki anotasi tidak terkelola:

KNV2009: inventory info is nil\n\nFor more information, see https://g.co/cloud/acm-errors#knv2009

Untuk mengatasi masalah ini, coba langkah berikut:

  1. Hindari penyiapan sinkronisasi jika semua resource memiliki anotasi configmanagement.gke.io/managed: disabled, dengan memastikan setidaknya satu resource dikelola oleh Config Sync.
  2. Tambahkan anotasi configmanagement.gke.io/managed: disabled hanya setelah menyelesaikan sinkronisasi awal resource tanpa anotasi ini.

Beberapa template objek inventaris

Jika Anda menerima error berikut saat rekonsiler mencoba menerapkan konfigurasi ke cluster, kemungkinan Anda memiliki konfigurasi inventaris yang dihasilkan oleh kpt di sumber tepercaya, misalnya repositori Git:

KNV2009: Package has multiple inventory object templates.  The package should have one and only one inventory object template.   For more information, see https://g.co/cloud/acm-errors#knv2009

Masalah ini terjadi karena Config Sync mengelola konfigurasi inventarisnya sendiri. Untuk mengatasi masalah ini, hapus konfigurasi inventaris di sumber tepercaya.

Tidak dapat membuat perubahan pada kolom yang tidak dapat diubah

Anda tidak dapat mengubah kolom yang tidak dapat diubah dalam konfigurasi dengan mengubah nilai di sumber kebenaran. Mencoba perubahan tersebut akan menyebabkan error yang mirip dengan berikut:

KNV2009: failed to apply RESOURCE: admission webhook "deny-immutable-field-updates.cnrm.cloud.google.com" denied the request: cannot make changes to immutable field(s):

Jika Anda perlu mengupdate kolom yang tidak dapat diubah, hapus objek dalam cluster secara manual. Kemudian, Config Sync dapat membuat ulang objek dengan nilai kolom baru.

Penemuan API gagal

Jika melihat pesan error yang mirip dengan yang berikut ini, Anda mungkin mengalami error penemuan API:

KNV2002: API discovery failed: APIServer error: unable to retrieve the complete list of server APIs: external.metrics.k8s.io/v1beta1: received empty response for: external.metrics.k8s.io/v1beta1

Config Sync menggunakan penemuan Kubernetes API untuk mencari resource yang didukung oleh cluster. Tindakan ini memungkinkan Config Sync memvalidasi jenis resource yang ditentukan dalam sumber dan memantau resource tersebut untuk melihat perubahan pada cluster.

Sebelum Kubernetes versi 1.28, setiap kali backend APIService tidak responsif atau menampilkan hasil daftar kosong, Penemuan API akan gagal, sehingga menyebabkan Sinkronisasi Konfigurasi dan beberapa komponen Kubernetes lainnya mengalami error. Banyak backend APIService umum yang tidak terlalu tersedia, sehingga hal ini dapat terjadi secara relatif sering, cukup dengan mengupdate backend atau menjadwalkan ulang backend tersebut ke node lain.

Contoh backend APIService dengan replika tunggal mencakup metrics-server dan custom-metrics-stackdriver-adapter. Beberapa backend APIService selalu menampilkan hasil daftar kosong, seperti custom-metrics-stackdriver-adapter. Penyebab umum lainnya dari kegagalan penemuan API adalah webhook yang tidak responsif.

Setelah Kubernetes versi 1.28, dengan fitur Aggregated Discovery aktif, backend APIService yang tidak responsif tidak akan lagi menyebabkan error yang tidak tertangani. Sebagai gantinya, grup resource yang ditangani oleh APIService tersebut ditampilkan tidak memiliki resource. Hal ini memungkinkan sinkronisasi dilanjutkan, selama resource yang tidak aktif tidak ditentukan di sumber Anda.

Pemulihan diri tertunda

Pemulihan mandiri memantau resource terkelola, mendeteksi penyimpangan dari sumber kebenaran, dan mengembalikan penyimpangan tersebut.

Pemulihan mandiri dijeda saat sinkronisasi dicoba. Perilaku ini berarti pemulihan mandiri mungkin tertunda, terutama jika ada error sinkronisasi yang mencegah rekonsiler selesai. Untuk mengaktifkan kembali pemulihan mandiri, perbaiki semua error sinkronisasi yang dilaporkan.

Jumlah permintaan Kubernetes API yang tinggi

Config Sync menggunakan strategi multi-instancing untuk menskalakan dan mengisolasi tenant dan domain fault. Karena itu, setiap RootSync dan RepoSync mendapatkan instance rekonsilernya sendiri. Selain menyinkronkan setiap kali perubahan dilakukan pada sumber, setiap instance rekonsiler juga disinkronkan secara berkala sebagai bagian dari perilaku pemulihan mandiri, untuk mengembalikan setiap perubahan yang terlewatkan oleh perbaikan penyimpangan yang aktif. Saat Anda menambahkan objek RootSync atau RepoSync, hal ini menyebabkan peningkatan linear jumlah permintaan API yang dibuat oleh rekonsiler yang menyinkronkan resource ke Kubernetes. Jadi, jika Anda memiliki banyak objek RootSync dan RepoSync, hal ini terkadang dapat menyebabkan beban traffic yang signifikan pada Kubernetes API.

Untuk menjalankan sinkronisasi, Config Sync menggunakan Server-Side Apply. Tindakan ini akan menggantikan alur permintaan GET dan PATCH normal dengan satu permintaan PATCH, sehingga mengurangi jumlah total panggilan API, tetapi meningkatkan jumlah panggilan PATCH. Hal ini memastikan bahwa perubahan yang dibuat sudah benar, meskipun versi grup resource dalam sumber tidak cocok dengan versi grup resource default di cluster. Namun, Anda mungkin melihat permintaan PATCH di log audit, meskipun belum ada perubahan pada sumber atau penyimpangan dari status yang Anda inginkan. Hal ini normal, tetapi bisa mengejutkan.

Ketika terjadi error pada sinkronisasi, sinkronisasi akan dicoba lagi hingga berhasil. Namun, jika hal ini memerlukan interaksi manusia, Config Sync mungkin akan mengalami error dan mencoba lagi untuk sementara sehingga meningkatkan jumlah permintaan yang dibuat ke Kubernetes API. Percobaan ulang akan kembali secara eksponensial, tetapi jika banyak objek RootSync atau RepoSync gagal disinkronkan secara bersamaan, hal ini dapat menyebabkan beban traffic yang signifikan di Kubernetes API.

Untuk mengurangi masalah ini, coba salah satu opsi berikut:

  • Perbaiki error konfigurasi dengan cepat agar tidak menumpuk.
  • Gabungkan beberapa objek RootSync atau RepoSync untuk mengurangi jumlah rekonsiliasi yang membuat permintaan Kubernetes API.

Uninstal KubeVirt diblokir oleh finalr

KubeVirt adalah paket Kubernetes yang menggunakan beberapa resolver, sehingga memerlukan pengurutan penghapusan yang akurat untuk memfasilitasi pembersihan. Jika objek KubeVirt dihapus dalam urutan yang salah, penghapusan objek KubeVirt lainnya mungkin akan terhenti atau berhenti merespons tanpa batas waktu.

Jika Anda mencoba meng-uninstal KubeVirt dan kemudian diblokir, ikuti petunjuk untuk menghapus KubeVirt secara manual.

Untuk mengurangi masalah ini di masa mendatang, deklarasikan dependensi antar-objek resource untuk memastikan objek tersebut dihapus dalam urutan dependensi terbalik.

Penghapusan objek diblokir oleh finalizer

Kubernetesfinalr adalah entri metadata yang memberi tahu Kubernetes untuk tidak mengizinkan penghapusan objek hingga setelah pengontrol tertentu melakukan pembersihan. Hal ini dapat menyebabkan sinkronisasi atau rekonsiliasi gagal jika kondisi pembersihan tidak terpenuhi atau pengontrol yang melakukan pembersihan untuk resource tersebut tidak responsif atau telah dihapus.

Untuk mengurangi masalah ini, identifikasi resource mana yang masih selesai dan pengontrol mana yang harus melakukan pembersihan.

Jika pengontrol tidak responsif, memperbaiki akar masalah akan memungkinkan pembersihan resource selesai, sehingga membatalkan pemblokiran penghapusan objek.

Jika pengontrol responsif, pengontrol seharusnya menerapkan kondisi status pada objek yang dihapus untuk menjelaskan alasan pembersihan terhenti. Jika tidak, periksa log pengontrol untuk melihat indikasi akar masalah.

Sering kali, menghapus objek yang terhenti merupakan indikasi bahwa objek dihapus dalam urutan yang salah. Untuk mencegah masalah semacam ini di masa mendatang, deklarasikan dependensi antar-objek resource, untuk memastikan objek tersebut dihapus dalam urutan dependensi terbalik.

Kolom ResourceGroup terus berubah

Saat sinkronisasi dicoba, inventaris akan diperbarui untuk mengubah status resource menjadi tertunda. Jika sinkronisasi gagal, inventaris akan diperbarui untuk mengubah status resource menjadi gagal. Saat sinkronisasi dicoba lagi setelah gagal, pola ini akan terulang, sehingga menyebabkan pembaruan berkala pada inventaris. Hal ini menyebabkan resourceVersion ResourceGroup meningkat seiring setiap update dan status sinkronisasi dibalik. Hal ini normal, namun bisa mengejutkan.

Kegagalan sinkronisasi dapat disebabkan oleh sejumlah masalah. Salah satu alasan yang paling umum adalah izin yang tidak memadai untuk mengelola resource yang ditentukan dalam sumber. Untuk memperbaiki error ini, tambahkan RoleBindings atau ClusterRoleBinding yang sesuai untuk memberikan izin rekonsiler RepoSync atau RootSync guna mengelola resource yang gagal disinkronkan.

Penerapan sisi server tidak menghapus atau mengembalikan kolom yang tidak ditentukan di sumber

Config Sync menggunakan Penerapan Sisi Server untuk menerapkan manifes dari sumber ke Kubernetes. Hal ini diperlukan agar pengontrol lain dapat mengelola kolom metadata dan spec. Salah satu contohnya adalah Horizontal Pod Autoscaler, yang memperbarui jumlah replika dalam Deployment. Oleh karena itu, Config Sync hanya mengelola kolom yang ditentukan dalam manifes sumber. Hal ini memiliki efek samping karena mengadopsi objek resource yang sudah ada, kolom apa pun yang tidak ditentukan dalam sumber tidak akan diubah, yang terkadang dapat menyebabkan konfigurasi gabungan menjadi tidak valid atau salah.

Untuk menghindari masalah ini saat mengadopsi resource, gunakan kolom yang sama persis dalam sumber saat pertama kali mengadopsi, lalu ubah kolom di sumber setelah sinkronisasi, sehingga Config Sync akan menghapus kolom yang sebelumnya diterapkan dengan benar dan menggantinya dengan kolom baru dari sumber. Cara lain untuk menghindari masalah ini adalah dengan menghapus resource dari cluster terlebih dahulu dan mengizinkan Config Sync menerapkan versi baru.

Langkah selanjutnya

  • Jika Anda masih mengalami masalah, periksa apakah masalah Anda adalah masalah umum.