Skip to main content
BlogSecurity

Perubahan Keamanan Kubernetes 1.36: userns, kubelet, gitRepo

Perubahan keamanan Kubernetes 1.36: user namespaces GA, kubelet authz, gitRepo dihapus, externalIPs deprecated, plus script audit untuk hari Senin.

Matthews Wong

Software Engineer

Oktober 202612 menit baca
Perubahan Keamanan Kubernetes 1.36: userns, kubelet, gitRepo

Ringkasan Utama

Kubernetes 1.36 membawa empat perubahan keamanan: user namespaces dan fine-grained kubelet authorization masuk GA, volume gitRepo dinonaktifkan permanen, dan externalIPs pada Service dideprekasi dengan rencana penghapusan di v1.43. Hanya gitRepo yang langsung merusak manifest lama. Sisanya opt-in atau punya jadwal, jadi audit grant nodes/proxy, volume gitRepo, dan Service externalIPs sebelum upgrade.

Release post Kubernetes 1.36 mencantumkan 70 enhancement, dan pekerjaan keamanannya tersebar seperti uang receh di saku jaket. User namespaces ada di satu post, kubelet authorization di post lain, satu tipe volume dihapus diam-diam di post ketiga, dan field Service lama dideprekasi di post keempat. Saya ingin satu halaman yang menjelaskan mana dari empat perubahan ini yang bisa merusak manifest saat hari upgrade, dan mana yang hanya peluang.

Tulisan ini adalah pembacaan sumber primer: release post resmi 1.36, sneak peek, tiga post fitur dari blog Kubernetes, dan halaman docs terbaru untuk user namespaces, kubelet authorization, dan volumes. Saya tidak menjalankan satu pun dari ini di cluster untuk tulisan ini, jadi setiap angka dan perilaku di bawah dikaitkan ke halaman asalnya, dan script-nya adalah bahan untuk Anda sesuaikan, bukan benchmark. Cakupannya sengaja lebih sempit dari ulasan rilis 1.37 yang sudah ada di situs ini: hanya apa yang dilakukan 1.36 terhadap attack surface Anda.

Empat perubahan, satu tema: berhenti memercayai default

Pengumuman rilis 1.36 menghitung 70 enhancement: 18 naik ke Stable, 25 masuk Beta, dan 25 di Alpha, serta mengarahkan pembaca ke deprecation dan removal secara terpisah. Empat item keamanan mengikuti satu pola. Masing-masing mengambil sesuatu yang dulu serba longgar secara default, entah root di dalam container, permission kubelet yang tampak read-only, tipe volume yang menjalankan git sebagai root di node, atau field Service yang membiarkan user mana pun mengklaim IP mana pun, lalu menggantinya dengan yang lebih sempit.

Tabel ini adalah seluruh tulisan dalam satu layar. Kolom terpenting adalah kolom ketiga: hanya satu dari empat perubahan yang mengubah workload yang sudah ada pada hari Anda upgrade.

PerubahanStatus di 1.36Dampak pada cluster yang adaTindakan Anda
User namespacesStable. Gate UserNamespacesSupport terkunci. Opt-in per pod dengan hostUsers bernilai falseTidak ada sampai ada pod yang opt-inCoba di satu node pool yang memenuhi minimum kernel dan runtime
Fine-grained kubelet authorizationStable. Gate KubeletFineGrainedAuthz terkunci aktifTidak ada. Grant nodes/proxy yang ada tetap jalan lewat fallbackPindahkan RBAC monitoring ke subresource sempit, lalu hapus nodes/proxy
Volume gitRepoDinonaktifkan permanen, tidak bisa dihidupkan lagiPod yang mendeklarasikan volume gitRepo rusakCari sebelum upgrade dan pindahkan proses clone ke init container
Service externalIPsDeprecated. Warning sekarang, penghapusan direncanakan di v1.43Masih jalan, tetapi mengeluarkan warningInventarisasi, rencanakan pengganti, blokir pemakaian baru dengan admission controller

Fine-grained kubelet authorization: get pada nodes/proxy tidak pernah read-only

Perubahan paling berguna bagi kebanyakan platform team justru yang paling tidak glamor. Kubelet membuka API HTTPS di node berisi daftar pod, metrics, log, dan kemampuan menjalankan perintah di dalam container. Dengan webhook authorization aktif, hampir semua path dulu dipetakan ke satu subresource nodes/proxy, sehingga agen monitoring yang hanya butuh metrics memerlukan permission yang sama dengan yang bisa exec ke container mana pun di node.

Halaman kubelet authentication dan authorization kini menyatakannya terang-terangan: sebagian endpoint memakai protokol Websocket lewat HTTP GET yang diotorisasi dengan verb get, sehingga get pada nodes/proxy bukan permission read-only dan mengizinkan eksekusi perintah di container mana pun di node. Post blog Kubernetes tentang GA menambahkan bahwa hal ini didemonstrasikan pada awal 2026 dan polanya muncul di RBAC default puluhan Helm chart yang banyak dipakai. Fiturnya masuk sebagai alpha di v1.32, beta aktif default di v1.33, dan GA di v1.36 lewat KEP-2862.

Cara kerjanya: untuk path yang terdaftar, kubelet lebih dulu mengirim SubjectAccessReview untuk subresource spesifik, dan hanya jika gagal ia mencoba ulang dengan nodes/proxy yang kasar demi backward compatibility. Fallback itulah sebabnya tidak ada yang rusak saat upgrade, dan juga sebabnya tidak ada yang lebih aman sampai grant lama dihapus.

Path kubeletSubresource yang dicek lebih duluArtinya untuk RBAC
/stats/*nodes/statsMembaca stats tanpa kemampuan exec
/metrics/*nodes/metricsGrant yang sebenarnya dibutuhkan scraper ala Prometheus
/logs/*nodes/logAkses log, tetap tanpa exec
/podsnodes/pods, then nodes/proxyFallback ke nodes/proxy jika pengecekan sempit gagal
/healthznodes/healthz, then nodes/proxyPengecekan ganda yang sama, fine-grained lebih dulu
/exec/* and all othersnodes/proxySisanya, termasuk exec, tetap butuh nodes/proxy
# Wrong: what most monitoring charts shipped. "get" on nodes/proxy is not
# read-only, because a Websocket handshake is an HTTP GET to the kubelet.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-agent
rules:
- apiGroups: [""]
  resources: ["nodes/proxy"]
  verbs: ["get"]
---
# Right: only what a scraper reads. Nothing here can exec into a container.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-agent
rules:
- apiGroups: [""]
  resources: ["nodes/metrics", "nodes/stats"]
  verbs: ["get"]

# Find the ClusterRoles that still grant nodes/proxy (or a wildcard that
# includes it). Built-in admin roles will show up; read the rest.
kubectl get clusterroles -o json | jq -r '
  .items[]
  | select(any(.rules[]?; any((.resources // [])[];
      . == "nodes/proxy" or . == "nodes/*" or . == "*")))
  | .metadata.name'

# Confirm the gate is on, from a pod whose ServiceAccount may read nodes/metrics.
# The docs print: kubernetes_feature_enabled{name="KubeletFineGrainedAuthz",stage="GA"} 1
curl -sk -H "Authorization: Bearer $TOKEN" https://$NODE_IP:10250/metrics \
  | grep kubernetes_feature_enabled | grep KubeletFineGrainedAuthz

Docs juga mencatat bahwa ClusterRole bawaan system:kubelet-api-admin diperbarui untuk mencakup subresource baru, sehingga kubelet client milik API server tidak terpengaruh apa pun status gate-nya. Post Kubernetes menyebut arah jangka panjangnya adalah adopsi ekosistem, ketika agen seperti Prometheus dan Datadog menyediakan RBAC default yang lebih sempit, dan policy engine menandai binding nodes/proxy saat alternatif fine-grained tersedia. Itu prediksi mereka, bukan sesuatu yang saya verifikasi di chart mana pun.

Grant sempit yang ditambahkan di samping grant nodes/proxy lama tidak menghapus apa pun. Kubelet mengecek subresource sempit dulu lalu fallback ke nodes/proxy, jadi agen yang terkompromi dan masih memegang nodes/proxy tetap bisa exec. Risikonya baru turun saat grant lama dihapus.

User namespaces: root di container tidak lagi berarti root di node

User namespaces masuk GA di 1.36, dan docs mencantumkan gate UserNamespacesSupport pertama tersedia di v1.28. Masalah yang diselesaikannya dinyatakan di blog Kubernetes: proses yang berjalan sebagai root di dalam container dilihat kernel sebagai root di host, sehingga breakout lewat bug kernel atau mount yang salah mendarat sebagai root. Dengan hostUsers bernilai false, container tetap merasa dirinya root, jadi tool seperti apt dan dnf tetap jalan, tetapi host melihat user tanpa privilege, dan kubelet memilih mapping yang tidak dipakai pod lain di node itu.

Docs menyebut beberapa kerentanan berperingkat HIGH atau CRITICAL tidak bisa dieksploitasi saat user namespaces aktif, dan capability seperti CAP_SYS_ADMIN dibatasi pada user namespace milik pod. Bagian yang memakan waktu bertahun-tahun adalah kepemilikan volume: ID-mapped mounts, yang diperkenalkan di Linux 5.12, membiarkan kernel memetakan ulang kepemilikan saat mount alih-alih kubelet melakukan chown rekursif pada volume besar. Mount itulah alasan kebutuhan node di bawah ini seperti adanya.

KomponenMinimum menurut docsKenapa penting
Linux kernel6.3tmpfs mendapat dukungan idmap mount di 6.3, dan token service account serta Secret memakai tmpfs
runc1.2OCI runtime harus mendukung user namespaces
crun1.9 (1.13+ advised)Docs menyarankan versi 1.13 atau lebih baru
containerd2.0CRI runtime juga harus mendukungnya
CRI-O1.25CRI runtime lain yang didukung di docs

Sisi pod hanya satu field. Sisi node punya satu jebakan yang perlu diketahui sebelum Anda mengaktifkannya luas: secara default kubelet memberi pod ID di atas rentang 0 sampai 65535 agar tidak tumpang tindih dengan user host, dan hanya jika Anda ingin rentang kustom Anda butuh user kubelet, getsubids, dan file subordinate ID. Docs mewajibkan rentang dimulai dari kelipatan 65536 yang minimal 65536, dengan jumlah minimal 65536 dikali maxPods Anda.

# Pod side: one field. The container still sees uid 0, the host does not.
apiVersion: v1
kind: Pod
metadata:
  name: isolated-workload
spec:
  hostUsers: false          # the opt-in; hostNetwork/hostPID/hostIPC must stay unset
  containers:
  - name: app
    image: fedora:42
    securityContext:
      runAsUser: 0

# Node side, preflight. None of this is needed for the default ID range.
uname -r                    # needs 6.3+ for idmap mounts on tmpfs
runc --version              # 1.2+, or: crun --version (1.9+)
containerd --version        # 2.0+

# Only if you want a CUSTOM range: a user literally named "kubelet", and
# getsubids (shadow-utils) on the kubelet's PATH. Format is name:firstID:count.
# 65536 is the smallest legal start; 110 pods * 65536 = 7208960.
# /etc/subuid and /etc/subgid, one line each, identical:
kubelet:65536:7208960

# KubeletConfiguration, v1.33+: IDs per pod, a multiple of 65536 (default 65536).
userNamespaces:
  idsPerPod: 1048576

# Verify: "id" inside the container says uid=0, but the process on the host
# (ps -o user= -p <host pid>) must NOT be root.
kubectl exec isolated-workload -- id

Dengan hostUsers bernilai false, capability seperti CAP_NET_ADMIN menjadi namespaced. Blog Kubernetes menyebut ini memungkinkan workload yang dulu butuh container privileged penuh, layak dilirik jika Anda menjalankan network tooling di pod.

gitRepo sudah hilang, dan migrasinya adalah init container

Tipe volume gitRepo sudah deprecated sejak v1.11. Di 1.36 plugin-nya dinonaktifkan permanen dan tidak bisa dihidupkan lagi, karena pemakaiannya bisa membiarkan penyerang menjalankan kode sebagai root di node. Docs volumes saat ini, yang ditulis untuk 1.37, menyatakan versi terakhir yang menyediakan cara memakai driver itu adalah v1.35, sejalan dengan itu: tidak ada flag untuk dibalik.

Release post dan docs volumes memberi pengganti yang sama: mount emptyDir ke init container yang meng-clone repository, lalu mount emptyDir yang sama ke container aplikasi. Release post juga menyebut tool bergaya git-sync untuk kasus ketika konten harus terus diperbarui. Biayanya nyata dan perlu disebut: gitRepo tidak butuh image sendiri, sedangkan init container butuh image yang berisi git dan keputusan soal credential.

Lakukan scan sebelum upgrade, karena Deployment yang pod template-nya masih mendeklarasikan gitRepo akan membuat pod yang gagal. Ekspresi ValidatingAdmissionPolicy di akhir blok diambil dari docs volumes dan menolak pemakaian baru.

# Before: removed in 1.36. A pod declaring this will not start.
volumes:
- name: src
  gitRepo:
    repository: https://git.example.com/team/site.git
    revision: v1.4.0

# After: clone once in an init container, share through emptyDir.
spec:
  volumes:
  - name: src
    emptyDir: {}
  initContainers:
  - name: clone
    image: registry.example.com/tools/git:PINNED_TAG   # your own pinned image
    args: ["clone", "--depth=1", "--branch", "v1.4.0",
           "https://git.example.com/team/site.git", "/src"]
    volumeMounts:
    - name: src
      mountPath: /src
  containers:
  - name: app
    image: registry.example.com/team/site:1.4.0
    volumeMounts:
    - name: src
      mountPath: /srv/site
      readOnly: true

# Find offenders in running objects AND controller templates. A scaled-to-zero
# Deployment has no pods but will fail the moment it scales up.
kubectl get pods,deploy,sts,ds,rs,job,cronjob -A -o json | jq -r '
  .items[]
  | select([.. | objects | select(has("gitRepo"))] | length > 0)
  | .kind + " " + .metadata.namespace + "/" + .metadata.name'

# Block re-introduction: CEL for a ValidatingAdmissionPolicy, from the volumes docs.
!has(object.spec.volumes) || !object.spec.volumes.exists(v, has(v.gitRepo))

externalIPs: deprecated sekarang, tiga langkah bertanggal

Field externalIPs pada Service adalah upaya awal memberi perilaku load balancer untuk cluster non-cloud. Blog Kubernetes menyebut API ini mengasumsikan setiap user di cluster sepenuhnya tepercaya, yang memungkinkan eksploitasi man-in-the-middle jika asumsi itu tidak berlaku, seperti dijelaskan di CVE-2020-8554. Proyek ini sudah menyarankan untuk menonaktifkannya sejak 1.21 dan menambahkan admission controller DenyServiceExternalIPs untuk itu, tetapi saat itu menilai pemblokiran default terlalu besar sebagai breaking change.

Blog memberi timeline kasar, dan perhatikan pilihan katanya: v1.40 paling cepat untuk kube-proxy berhenti mendukungnya dengan opsi opt-in kembali, lalu v1.43 paling cepat untuk penghapusan penuh tanpa jalan kembali. Release post menyebut penghapusan direncanakan di v1.43. Hanya field .spec.externalIPs yang terpengaruh, bukan tipe alamat Node bernama ExternalIP dan bukan kolom EXTERNAL-IP yang dicetak kubectl untuk Service LoadBalancer.

  • 1.36: field dideprekasi, warning saat dipakai
  • 1.40 paling cepat: dukungan kube-proxy dimatikan, dengan opsi opt-in untuk memulihkannya
  • 1.43 paling cepat: dukungan dihapus total, tanpa opt-in
PenggantiYang diberikan menurut postKekurangannya
LoadBalancer yang dikelola manualPerilaku sama, tetapi IP berada di status, yang tidak bisa diedit user biasa dengan RBAC defaultPost menyebutnya opsi termudah sekaligus terburuk: user yang diberi izin tetap bisa mereplikasi CVE-2020-8554, tanpa pengecekan bahwa satu user tidak mencuri IP user lain
Load balancer controller seperti MetalLBAdmin menentukan address pool dan controller mencegah dua Service memakai IP yang samaKomponen baru untuk dijalankan, dan loadBalancerIP, yang masih didukung MetalLB, adalah field yang juga sudah deprecated
Gateway APIResource Gateway membawa alamat, dan RBAC bisa membatasi siapa yang mengelola GatewayAnda berpindah dari Service ke Gateway dan HTTPRoute, dan butuh implementasi Gateway terpasang
# Inventory: every Service that still sets spec.externalIPs.
kubectl get svc -A -o json | jq -r '
  .items[]
  | select((.spec.externalIPs // []) | length > 0)
  | .metadata.namespace + "/" + .metadata.name + "  " + (.spec.externalIPs | join(","))'

# Block new use now. Append to your EXISTING plugin list, do not replace it.
# kube-apiserver flag:
--enable-admission-plugins=DenyServiceExternalIPs

# Replacement with MetalLB: the admin owns the pool, users just ask for a LoadBalancer.
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: production
  namespace: metallb-system
spec:
  addresses:
  - 192.0.2.0/24
  autoAssign: true

Jika Anda tidak memakai field itu di mana pun, post menyatakan deprecation ini tidak berlaku untuk Anda, tetapi tetap menyarankan mengaktifkan DenyServiceExternalIPs sebagai pencegahan pemakaian di masa depan. Itu perubahan satu baris yang layak dilakukan di cluster tempat tenant bisa membuat Service.

Di mana ini gagal: lima failure mode yang diperingatkan docs

Tidak ada dari empat perubahan ini yang berbahaya sendirian. Kegagalan muncul dari celah antara perubahan itu dan cluster Anda, dan setiap poin di bawah dinyatakan di sumber, bukan hasil pengamatan saya.

  • Menambah RBAC sempit tanpa menghapus nodes/proxy. Anda punya manifest yang lebih baik tetapi eksposur yang sama, karena fallback.
  • Menyetel hostUsers false pada pod yang butuh hostNetwork, hostIPC, hostPID, atau raw block volumeDevices. Docs melarang keempat kombinasi itu.
  • Mengaktifkan user namespaces di node tanpa dukungan filesystem. Filesystem node untuk direktori pod kubelet dan setiap volume yang di-mount pod harus mendukung idmap mounts, yang dalam praktik berarti Linux 6.3 atau lebih baru.
  • Mengubah rentang subordinate ID di node yang sedang jalan. Docs meminta drain dulu, karena kubelet gagal start jika tidak bisa memenuhi konfigurasi baru untuk pod user-namespace yang sudah ada.
  • Menganggap hostUsers false sebagai pengganti Pod Security. Kubernetes melonggarkan pengecekan runAsNonRoot dan runAsUser untuk pod semacam itu bahkan di Baseline dan Restricted, dengan alasan root di dalam tidak pernah dipetakan ke user host berprivilege. Alasannya masuk akal, tetapi artinya audit policy yang menghitung runAsNonRoot kini akan melewatkan pod terisolasi.

Trade-off yang jujur: user namespaces memberi defence in depth dengan harga syarat node dan jenis kegagalan scheduling baru, sedangkan tiga perubahan lain menuntut kerja migrasi dan langsung memberi blast radius yang lebih kecil.

gitRepo adalah satu-satunya perubahan di sini yang gagal secara terang-terangan pada hari upgrade. Jika scan pra-upgrade menemukan volume gitRepo di template Deployment, StatefulSet, atau CronJob, perbaiki lebih dulu. Pod yang sedang jalan bisa tidak muncul di scan khusus pod jika controller-nya sudah di-scale ke nol.

Yang dikerjakan hari Senin

Enam langkah, berurutan dari pengurangan risiko termurah. Script di bawah menjalankan audit read-only untuk langkah satu sampai tiga dan tidak mencetak apa pun yang destruktif.

  1. Jalankan script audit di setiap cluster sebelum upgrade apa pun, dan lampirkan outputnya ke tiket perubahan.
  2. Ganti setiap volume gitRepo dengan emptyDir plus init container, dan deploy perubahan itu di versi yang Anda pakai sekarang.
  3. Tambahkan DenyServiceExternalIPs ke admission plugin API server, lalu buat tiket untuk setiap Service dengan externalIPs yang ditemukan audit.
  4. Tulis ulang ClusterRole monitoring ke nodes/metrics, nodes/stats, dan nodes/pods, rollout, dan baru setelah itu hapus aturan nodes/proxy.
  5. Cek satu node pool terhadap syarat user namespaces, dan coba hostUsers false pada workload stateless di sana.
  6. Tambahkan ValidatingAdmissionPolicy untuk gitRepo agar tipe volume itu tidak bisa masuk lagi lewat chart usang.
#!/usr/bin/env bash
# k8s-136-audit.sh: read-only. Run per cluster, attach output to the change ticket.
set -euo pipefail

echo "== ClusterRoles granting nodes/proxy (built-ins included) =="
kubectl get clusterroles -o json | jq -r '
  .items[]
  | select(any(.rules[]?; any((.resources // [])[];
      . == "nodes/proxy" or . == "nodes/*" or . == "*")))
  | .metadata.name'

echo "== Objects declaring a gitRepo volume =="
kubectl get pods,deploy,sts,ds,rs,job,cronjob -A -o json | jq -r '
  .items[]
  | select([.. | objects | select(has("gitRepo"))] | length > 0)
  | .kind + " " + .metadata.namespace + "/" + .metadata.name'

echo "== Services using spec.externalIPs =="
kubectl get svc -A -o json | jq -r '
  .items[]
  | select((.spec.externalIPs // []) | length > 0)
  | .metadata.namespace + "/" + .metadata.name'

echo "== Node kernels (user namespaces need 6.3+) =="
kubectl get nodes -o custom-columns=NAME:.metadata.name,KERNEL:.status.nodeInfo.kernelVersion,RUNTIME:.status.nodeInfo.containerRuntimeVersion

Langkah empat dan lima yang biasanya terlewat, karena tidak ada yang rusak jika dilewati. Itu justru alasan untuk menjadwalkannya.

Aturan yang saya bawa dari rilis ini: baca verb-nya, bukan namanya. Get pada nodes/proxy bertahun-tahun terdengar read-only dan ternyata bukan, user root di container terdengar terkurung dan ternyata bukan, dan field bernama externalIPs terdengar seperti plumbing padahal ia adalah asumsi kepercayaan. Kubernetes 1.36 memberi alat yang lebih sempit untuk masing-masing, tetapi hanya gitRepo yang memaksa migrasi. Kerjakan sisanya sesuai jadwal Anda, sebelum insiden orang lain yang menentukan jadwalnya.

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Perubahan keamanan apa yang dirilis di Kubernetes 1.36?

Kubernetes 1.36, dirilis pada 22 April 2026, menaikkan user namespaces dan fine-grained kubelet API authorization ke GA. Rilis ini juga menonaktifkan driver volume gitRepo secara permanen dan mendeprekasi .spec.externalIPs pada Service, dengan penghapusan direncanakan di v1.43. Totalnya ada 70 enhancement: 18 Stable, 25 Beta, dan 25 Alpha.

Apakah get pada nodes/proxy itu permission read-only di Kubernetes?

Tidak. Docs kubelet menyatakan sebagian endpoint memakai protokol Websocket lewat HTTP GET yang diotorisasi dengan verb get, sehingga get pada nodes/proxy bisa mengizinkan eksekusi perintah di container mana pun di node. Fine-grained authorization memungkinkan agen monitoring memakai nodes/metrics, nodes/stats, atau nodes/pods sebagai gantinya.

Apakah upgrade ke Kubernetes 1.36 merusak pod yang memakai volume gitRepo?

Ya. Plugin gitRepo dinonaktifkan permanen di 1.36 dan tidak bisa dihidupkan lagi, sehingga pod yang mendeklarasikan tipe volume itu akan gagal. Ganti dengan volume emptyDir yang diisi init container yang meng-clone repository, atau pakai tool bergaya git-sync jika kontennya harus terus diperbarui.

Bagaimana cara mengaktifkan user namespaces untuk pod di Kubernetes 1.36?

Setel hostUsers ke false di spec pod. Node butuh Linux 6.3 atau lebih baru untuk idmap mounts pada tmpfs, OCI runtime seperti runc 1.2 atau crun 1.9, dan CRI runtime seperti containerd 2.0 atau CRI-O 1.25. Pod yang memakai hostNetwork, hostIPC, hostPID, atau raw block volumeDevices tidak bisa mengaktifkannya.

Kapan externalIPs pada Service berhenti berfungsi di Kubernetes?

Field ini deprecated di 1.36 dan mengeluarkan warning. Menurut blog Kubernetes, dukungan kube-proxy dimatikan paling cepat di v1.40 dengan opsi untuk mengaktifkannya kembali, dan dihapus total paling cepat di v1.43. Alternatifnya adalah Service LoadBalancer dengan controller seperti MetalLB, atau Gateway API.