User Namespaces
Kubernetes v1.30 [beta]Halaman ini menjelaskan bagaimana Namespace pengguna digunakan dalam pod Kubernetes. Namespace pengguna mengisolasi pengguna yang berjalan di dalam kontainer dari pengguna yang berada di host.
Proses yang berjalan sebagai root dalam kontainer dapat berjalan sebagai pengguna lain (non-root) di host; dengan kata lain, proses tersebut memiliki hak istimewa penuh untuk operasi di dalam Namespace pengguna, tetapi tidak memiliki hak istimewa untuk operasi di luar Namespace.
Kamu dapat menggunakan fitur ini untuk mengurangi kerusakan yang dapat ditimbulkan oleh kontainer yang disusupi terhadap host atau pod lain dalam node yang sama. Terdapat beberapa kerentanan keamanan yang dinilai HIGH atau CRITICAL yang tidak dapat dieksploitasi saat Namespace pengguna aktif. Namespace pengguna diharapkan juga akan memitigasi beberapa kerentanan di masa mendatang.
Sebelum kamu memulai
Ini adalah fitur khusus Linux dan dukungan diperlukan di Linux untuk pemasangan idmap pada sistem berkas yang digunakan. Artinya:
- Pada node, sistem berkas yang kamu gunakan untuk
/var/lib/kubelet/pods/, atau direktori khusus yang kamu konfigurasikan untuk ini, memerlukan dukungan pemasangan idmap. - Semua sistem berkas yang digunakan dalam volume pod harus mendukung pemasangan idmap.
Dalam praktiknya, ini berarti kamu memerlukan setidaknya Linux 6.3, karena tmpfs mulai mendukung pemasangan idmap pada versi tersebut. Ini biasanya diperlukan karena beberapa fitur Kubernetes menggunakan tmpfs (token akun layanan yang dipasang secara default menggunakan tmpfs, Secrets menggunakan tmpfs, dll.)
Beberapa sistem berkas populer yang mendukung pemasangan idmap di Linux 6.3 adalah: btrfs, ext4, xfs, fat, tmpfs, overlayfs.
Selain itu, runtime kontainer dan runtime OCI yang mendasarinya harus mendukung namespace pengguna. Runtime OCI berikut menawarkan dukungan:
Catatan:
Beberapa runtime OCI tidak menyertakan dukungan yang diperlukan untuk menggunakan namespace pengguna di pod Linux. Jika kamu menggunakan Kubernetes terkelola, atau telah mengunduhnya dari paket dan mengaturnya sendiri, ada kemungkinan node di klaster kamu menggunakan runtime yang tidak menyertakan dukungan ini.Untuk menggunakan namespace pengguna dengan Kubernetes, kamu juga perlu menggunakan CRI container runtime untuk menggunakan fitur ini dengan pod Kubernetes:
- containerd: versi 2.0 (dan yang lebih baru) mendukung namespace pengguna untuk kontainer.
- CRI-O: versi 1.25 (dan yang lebih baru) mendukung namespace pengguna untuk kontainer.
Kamu dapat melihat status dukungan namespace pengguna di cri-dockerd yang dilacak dalam issue di GitHub.
Pengenalan
Namespace pengguna adalah fitur Linux yang memungkinkan pemetaan pengguna di dalam kontainer ke pengguna lain di host. Lebih lanjut, kapabilitas yang diberikan kepada pod di namespace pengguna hanya valid di dalam namespace tersebut dan tidak berlaku di luarnya.
Sebuah pod dapat memilih untuk menggunakan namespace pengguna dengan menyetel kolom pod.spec.hostUsers
ke false.
Kubelet akan memilih UID/GID host tempat pod dipetakan, dan akan melakukannya dengan cara untuk menjamin bahwa tidak ada dua pod pada node yang sama yang menggunakan pemetaan yang sama.
Kolom runAsUser, runAsGroup, fsGroup, dll. di pod.spec selalu
merujuk ke pengguna di dalam kontainer. Pengguna ini akan digunakan untuk pemasangan volume
(ditentukan dalam pod.spec.volumes) dan oleh karena itu UID/GID host tidak akan
berpengaruh pada penulisan/pembacaan dari volume yang dapat dipasang oleh pod. Dengan kata lain,
inodes yang dibuat/dibaca dalam volume yang dipasang oleh pod akan sama seperti jika
pod tidak menggunakan namespace pengguna.
Dengan cara ini, sebuah pod dapat dengan mudah mengaktifkan dan menonaktifkan namespace pengguna (tanpa memengaruhi
kepemilikan berkas volumenya) dan juga dapat berbagi volume dengan pod tanpa namespace
pengguna hanya dengan mengatur pengguna yang sesuai di dalam kontainer
(RunAsUser, RunAsGroup, fsGroup, dll.). Ini berlaku untuk semua volume yang dapat dipasang oleh pod,
termasuk hostPath (jika pod diizinkan untuk memasang volume hostPath).
Secara default, UID/GID yang valid saat fitur ini diaktifkan adalah rentang 0-65535. Hal ini berlaku untuk berkas dan proses (runAsUser, runAsGroup, dll.).
Berkas yang menggunakan UID/GID di luar rentang ini akan dianggap sebagai milik
ID overflow, biasanya 65534 (dikonfigurasi dalam /proc/sys/kernel/overflowuid dan
/proc/sys/kernel/overflowgid). Namun, berkas
tersebut tidak dapat dimodifikasi, bahkan dengan menjalankannya sebagai pengguna/grup 65534.
Jika rentang 0-65535 diperluas dengan tombol konfigurasi, batasan yang disebutkan di atas berlaku untuk rentang yang diperluas tersebut.
Sebagian besar aplikasi yang perlu dijalankan sebagai root tetapi tidak mengakses namespace atau sumber daya host lain, seharusnya tetap berjalan dengan baik tanpa perlu perubahan apa pun jika namespace pengguna diaktifkan.
Memahami namespace pengguna untuk pod
Beberapa runtime kontainer dengan konfigurasi default-nya (seperti Docker Engine, containerd, CRI-O) menggunakan namespace Linux untuk isolasi. Teknologi lain juga tersedia dan dapat digunakan dengan runtime tersebut (misalnya, Kata Containers menggunakan VM, bukan namespace Linux). Halaman ini berlaku untuk runtime kontainer yang menggunakan namespace Linux untuk isolasi.
Saat membuat pod, secara default, beberapa namespace baru digunakan untuk isolasi: namespace jaringan untuk mengisolasi jaringan kontainer, namespace PID untuk mengisolasi tampilan proses, dll. Jika namespace pengguna digunakan, ini akan mengisolasi pengguna di kontainer dari pengguna di node.
Ini berarti kontainer dapat dijalankan sebagai root dan dipetakan ke pengguna non-root di
host. Di dalam kontainer, proses akan mengira dirinya berjalan sebagai root (dan
oleh karena itu, alat seperti apt, yum, dll. berfungsi dengan baik), padahal kenyataannya proses tersebut
tidak memiliki hak istimewa di host. Kamu dapat memverifikasi hal ini, misalnya, jika kamu
memeriksa pengguna mana yang dijalankan oleh proses kontainer dengan menjalankan ps aux dari
host. Pengguna yang ditampilkan ps tidak sama dengan pengguna yang kamu lihat jika kamu
mengeksekusi perintah id di dalam kontainer.
Abstraksi ini membatasi apa yang dapat terjadi, misalnya, jika kontainer berhasil keluar ke host. Mengingat kontainer berjalan sebagai pengguna tanpa hak istimewa di host, maka apa yang dapat dilakukannya terhadap host menjadi terbatas.
Lebih lanjut, karena pengguna di setiap pod akan dipetakan ke pengguna berbeda yang tidak tumpang tindih di host, maka apa yang dapat mereka lakukan terhadap pod lain juga terbatas.
Kemampuan yang diberikan kepada pod juga terbatas pada namespace pengguna pod dan sebagian besar tidak valid di luarnya, beberapa bahkan sepenuhnya batal. Berikut dua contoh:
CAP_SYS_MODULEtidak berpengaruh jika diberikan kepada pod menggunakan namespace pengguna, pod tersebut tidak dapat memuat modul kernel.CAP_SYS_ADMINterbatas pada namespace pengguna pod dan tidak valid di luarnya.
Tanpa menggunakan namespace pengguna, kontainer yang berjalan sebagai root, dalam kasus breakout kontainer, memiliki hak akses root pada node tersebut. Dan jika beberapa kemampuan diberikan kepada kontainer, kemampuan tersebut juga valid pada host. Semua hal ini tidak berlaku ketika kita menggunakan namespace pengguna.
Jika kamu ingin mengetahui detail lebih lanjut tentang perubahan apa saja yang terjadi ketika namespace pengguna digunakan, lihat man 7 user_namespaces.
Siapkan node untuk mendukung namespace pengguna
Secara default, kubelet menetapkan UID/GID pod di atas rentang 0-65535, berdasarkan asumsi bahwa berkas dan proses host menggunakan UID/GID dalam rentang ini, yang merupakan standar untuk sebagian besar distribusi Linux. Pendekatan ini mencegah tumpang tindih antara UID/GID host dan pod.
Menghindari tumpang tindih ini penting untuk mengurangi dampak kerentanan seperti CVE-2021-25741, di mana pod berpotensi membaca berkas sembarangan di host. Jika UID/GID pod dan host tidak tumpang tindih, apa yang dapat dilakukan pod akan terbatas: UID/GID pod tidak akan cocok dengan pemilik/grup berkas host.
Kubelet dapat menggunakan rentang khusus untuk ID pengguna dan ID grup untuk pod. Untuk mengonfigurasi rentang khusus, node harus memiliki:
- Pengguna
kubeletdi sistem (kamu tidak dapat menggunakan nama pengguna lain di sini) - Biner
getsubidsterpasang (bagian dari shadow-utils) dan diPATHuntuk biner kubelet. - Konfigurasi UID/GID subordinat untuk pengguna
kubelet(lihatman 5 subuiddanman 5 subgid).
Pengaturan ini hanya mengumpulkan konfigurasi rentang UID/GID dan tidak mengubah
pengguna yang menjalankan kubelet.
Kamu harus mengikuti beberapa batasan untuk rentang ID subordinat yang kamu tetapkan
kepada pengguna kubelet:
ID pengguna subordinat, yang memulai rentang UID untuk Pod, harus merupakan kelipatan 65536 dan juga harus lebih besar dari atau sama dengan 65536. Dengan kata lain, kamu tidak dapat menggunakan ID apa pun dari rentang 0-65535 untuk Pod; kubelet memaksakan batasan ini untuk mempersulit pembuatan konfigurasi yang tidak aman secara tidak sengaja.
Jumlah ID subordinat harus kelipatan 65536.
Jumlah ID subordinat harus minimal
65536 x <maxPods>di mana<maxPods>adalah jumlah maksimum pod yang dapat berjalan pada node tersebut.Kamu harus menetapkan rentang yang sama untuk ID pengguna dan ID grup. Tidak masalah jika pengguna lain memiliki rentang ID pengguna yang tidak sesuai dengan rentang ID grup.
Tidak ada rentang yang ditetapkan yang boleh tumpang tindih dengan penugasan lainnya.
Konfigurasi subordinat harus hanya satu baris. Dengan kata lain, kamu tidak dapat memiliki beberapa rentang.
Misalnya, kamu dapat mendefinisikan /etc/subuid dan /etc/subgid agar keduanya memiliki
entri berikut untuk pengguna kubelet:
# Formatnya adalah
# name:firstID:count of IDs
# di mana
# - firstID adalah 65536 (nilai minimum yang dimungkinkan)
# - count of IDs adalah 110 * 65536
# (110 adalah batas _default_ untuk jumlah pod pada node)
kubelet:65536:7208960
Jumlah ID untuk setiap Pod
Mulai Kubernetes v1.33, jumlah ID untuk setiap Pod dapat diatur di
KubeletConfiguration.
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
userNamespaces:
idsPerPod: 1048576
Nilai idsPerPod (uint32) harus kelipatan 65536.
Nilai default-nya adalah 65536.
Nilai ini hanya berlaku untuk kontainer yang dibuat setelah kubelet dimulai dengan
KubeletConfiguration ini.
Kontainer yang sedang berjalan tidak terpengaruh oleh konfigurasi ini.
Di Kubernetes sebelum v1.33, jumlah ID untuk setiap Pod dikodekan secara permanen ke 65536.
Integrasi dengan pemeriksaan penerimaan keamanan Pod
Kubernetes v1.29 [alpha]Untuk Pod Linux yang mengaktifkan namespace pengguna, Kubernetes melonggarkan penerapan
Standar Keamanan Pod secara terkendali.
Perilaku ini dapat dikendalikan oleh feature
gate
UserNamespacesPodSecurityStandards, yang memungkinkan pengguna akhir untuk memilih lebih awal. Admin harus memastikan bahwa namespace pengguna diaktifkan oleh semua node
di dalam klaster jika menggunakan feature gate.
Jika kamu mengaktifkan feature gate terkait dan membuat Pod yang menggunakan namespace pengguna, kolom-kolom berikut tidak akan dibatasi bahkan dalam konteks yang menerapkan standar keamanan pod
Baseline atau Restricted. Perilaku ini tidak
menimbulkan masalah keamanan karena root di dalam Pod dengan namespace pengguna
sebenarnya merujuk ke pengguna di dalam kontainer, yang tidak pernah dipetakan ke
pengguna istimewa di host. Berikut daftar kolom yang bukan diperiksa untuk Pod dalam
kondisi tersebut:
spec.securityContext.runAsNonRootspec.containers[*].securityContext.runAsNonRootspec.initContainers[*].securityContext.runAsNonRootspec.ephemeralContainers[*].securityContext.runAsNonRootspec.securityContext.runAsUserspec.containers[*].securityContext.runAsUserspec.initContainers[*].securityContext.runAsUserspec.ephemeralContainers[*].securityContext.runAsUser
Batasan
Saat menggunakan namespace pengguna untuk pod, penggunaan namespace host lain tidak diperbolehkan. Khususnya, jika kamu menetapkan hostUsers: false, kamu tidak
diizinkan untuk menetapkan salah satu dari:
hostNetwork: truehostIPC: truehostPID: true
Tidak ada kontainer yang dapat menggunakan volumeDevices (volume blok mentah, seperti /dev/sda).
Ini mencakup semua array kontainer dalam spesifikasi pod:
containersinitContainersephemeralContainers
Metrik dan Observabilitas
Kubelet mengekspor dua metrik Prometheus khusus untuk namespace pengguna:
started_user_namespaced_pods_total: penghitung yang melacak jumlah pod namespace pengguna yang dicoba dibuat.started_user_namespaced_pods_errors_total: penghitung yang melacak jumlah kesalahan saat membuat pod namespace pengguna.
Selanjutnya
Items on this page refer to third party products or projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for those third-party products or projects. See the CNCF website guidelines for more details.
You should read the content guide before proposing a change that adds an extra third-party link.