Masalah dan cakupan
Ini adalah pertanyaan system design control-plane untuk platform engineer dan Kubernetes engineer. Kubernetes v1.36 memperkenalkan List dan Watch ter-shard di sisi server sebagai fitur alfa di balik gate ShardedListAndWatch. Perlakukan fitur ini sebagai opsional dan rancang controller yang tetap berjalan dengan benar saat gate dinonaktifkan.
Apa yang dievaluasi oleh pewawancara
- Model kepemilikan shard yang mencakup seluruh keyspace tepat satu kali.
- List awal yang benar, penanganan resource-version, dan perilaku penyambungan ulang (reconnect) Watch.
- Deteksi API server yang mengabaikan selector.
- Resharding, churn replika, dan trade-off antara tumpang tindih (overlap) dan celah (gap).
- Penalaran kapasitas untuk CPU API server, jaringan, memori informer, dan recovery storm.
Apa kunci kepemilikannya?
Implementasi alfa mendukung object.metadata.uid dan object.metadata.namespace. Hashing UID memberikan distribusi yang stabil; hashing namespace dapat mempertahankan lokalitas tenant tetapi bisa timpang (skewed). Pilihan ini mengubah penyeimbangan, batas keamanan, dan biaya migrasi.
Apa target kebenarannya?
Tanyakan apakah rekonsiliasi at-least-once dapat diterima dan apakah pemrosesan duplikat bersifat idempoten. Jika efek samping bisnis tidak dapat mentolerir duplikat, tambahkan work key yang persisten dan fencing daripada hanya mengandalkan aliran event saja.
Bisakah semua API server dan klien ditingkatkan bersamaan?
Asumsikan versi campuran kecuali tim platform membuktikan sebaliknya. Controller harus memeriksa metadata respons dan melakukan fallback ke pemfilteran sisi klien tanpa secara diam-diam mengklaim adanya pengurangan beban.
Kerangka jawaban 30 detik
“Saya akan mempartisi ruang hash 64-bit yang deterministik ke dalam rentang-rentang yang tidak tumpang tindih dan menetapkan setiap rentang ke satu replika controller. Setiap informer mengirimkan shard selector pada List maupun Watch, lalu memverifikasi bahwa respons berisi metadata shard yang sesuai. Pengakuan (acknowledgment) yang hilang akan memicu fallback aman ke aliran penuh atau menonaktifkan pengoptimalan. Resharding menggunakan generasi dan protokol serah terima (handoff) dengan tumpang tindih, rekonsiliasi yang idempoten, serta metrik untuk cakupan, duplikat, lag, dan lalu lintas fallback.”
Desain langkah demi langkah
Partisi dan penetapan
Representasikan kepemilikan sebagai rentang setengah terbuka [start, end) pada cincin 64-bit. Simpan generasi, pemilik, dan lease untuk setiap rentang. Penerapan dua replika dapat membagi cincin menjadi dua; replika yang lebih banyak menggunakan tabel rentang yang dikelola controller. Jangan menurunkan kepemilikan dari ordinal replika saja karena restart dapat menimbulkan celah.
Replica A: [0000..., 8000...)
Replica B: [8000..., 1000...)Jadikan List dan Watch satu protokol
List awal dan setiap penyambungan ulang Watch harus membawa selector yang sama dan sebuah resource version. Informer mengganti penyimpanan lokalnya hanya setelah list awal selesai, lalu memulai watch dari resource version yang dikembalikan. Eror 410 Gone atau versi yang kedaluwarsa menyebabkan list baru untuk shard tersebut, bukan pemutaran ulang secara membabi buta dari rentang lain.
Verifikasi dukungan server
Blog v1.36 menjelaskan kolom respons shardInfo yang menggemakan kembali selector yang diterapkan. Jika kolom tersebut tidak ada, asumsikan server mengembalikan seluruh koleksi. Klien dapat memfilter secara lokal demi kebenaran, tetapi harus memancarkan metrik fallback dan menerapkan backpressure agar server yang tidak mendukung tidak melipatgandakan penggunaan memori di seluruh replika.
Resharding tanpa celah
Buat generasi rentang yang baru. Selama serah terima, pemilik lama tetap melakukan rekonsiliasi sementara pemilik baru menghangatkan list dan menunggu watch pada resource version yang diketahui. Lakukan komit perubahan kepemilikan hanya setelah kedua belah pihak melaporkan kesiapan; event duplikat dapat diterima jika rekonsiliasi bersifat idempoten. Jika kesiapan gagal, habiskan masa berlaku lease dan pertahankan pemilik lama.
Kapasitas dan jalur kegagalan
Pemfilteran sisi server mengurangi byte dan deserialisasi untuk objek yang dibuang, tetapi API server sekarang melakukan evaluasi hashing dan selector. Lindungi server dengan feature gate, batas konkurensi per-controller, dan canary rollout. Jika API server mengalami kelebihan beban, batasi koneksi ulang dan gunakan exponential backoff; jangan pernah membiarkan semua replika melakukan relist sekaligus.
Contoh jawaban berkualitas tinggi
“Saya akan menggunakan tabel rentang berstempel generasi di atas hash deterministik UID. Informer menyertakan selector tersebut pada List dan Watch serta memerlukan shardInfo sebelum menganggap pengoptimalan aktif. Kolom yang hilang akan fallback ke pemfilteran lokal dengan anggaran konkurensi global. Resharding membuat generasi baru, menghangatkan pemilik baru dari resource version, dan mengalihkan lease hanya setelah kesiapan; rekonsiliasi bersifat idempoten sehingga tumpang tindih aman. Saya akan melakukan canary pada feature gate dan membandingkan CPU API, byte, latensi list, penyambungan ulang watch, cakupan shard, duplikat, dan tingkat fallback.”
Kesalahan umum
- Menetapkan shard berdasarkan indeks replika → Restart mengubah kepemilikan dan membuat celah → pertahankan tabel rentang berstempel generasi.
- Menerapkan selector hanya pada Watch → List awal tetap membebani server dan dapat tidak sesuai dengan aliran → gunakan selector dan aturan resource-version yang sama untuk keduanya.
- Mempercayai server yang tidak mendukung → Setiap replika menerima aliran penuh → wajibkan
shardInfodan ekspos lalu lintas fallback. - Memindahkan rentang secara instan → Event dapat terlewat selama serah terima → tumpang-tindihkan pemilik, lakukan fencing dengan generasi, dan buat rekonsiliasi menjadi idempoten.
- Hanya mengukur CPU controller → Hashing API server atau badai koneksi ulang tetap tidak terlihat → pantau metrik control-plane dan klien secara bersamaan.
Rubrik penilaian dan pemeriksaan mandiri
Beri nilai pada kebenaran partisi, semantik list-watch, fallback, resharding, kapasitas, dan observabilitas. Jawaban yang kuat menyatakan invarian: setiap objek termasuk dalam satu generasi rentang aktif, dan setiap serah terima memiliki batas resource-version. Jawaban tersebut juga menjelaskan mengapa duplikat lebih aman daripada celah ketika rekonsiliasi bersifat idempoten.
Tindak lanjut dan ekstensi
Bagaimana jika satu namespace jauh lebih besar dari yang lain?
Pilih hashing UID untuk keseimbangan, atau bagi namespace yang padat ke dalam beberapa rentang UID. Ukur beban rentang alih-alih mengasumsikan jumlah objek yang sama.
Bagaimana Anda mendeteksi celah yang tersembunyi (silent gap)?
Bandingkan jumlah sampel objek global dengan gabungan jumlah shard, catat generasi selector, dan jalankan objek sintetis berkala melalui setiap rentang. Berikan peringatan pada lag atau pergeseran cakupan.
Apa yang terjadi selama peningkatan versi API server?
Biarkan feature gate dinonaktifkan sampai canary mengamati shardInfo dari setiap endpoint yang melayani. Respons yang bercampur memicu fallback dan laju koneksi ulang yang dibatasi.
Bisakah controller memproses objek yang sama dua kali?
Ya, selama tumpang tindih atau koneksi ulang. Gunakan versi objek dan work key yang persisten untuk membuat efek samping menjadi idempoten; jangan pernah menukar rekonsiliasi duplikat dengan risiko kehilangan status yang tak terbatas.