Halaman ini menunjukkan cara mengurangi risiko serangan eskalasi akses di cluster Anda dengan memberi tahu Google Kubernetes Engine (GKE) untuk menjadwalkan beban kerja Anda pada node pool khusus yang terpisah dan jauh dari aktivitas beban kerja kelolaan GKE dengan hak istimewa. Anda sebaiknya menggunakan pendekatan ini hanya jika Anda tidak dapat menggunakan GKE Sandbox. GKE Sandbox adalah pendekatan yang direkomendasikan untuk isolasi node. GKE Sandbox juga memberikan manfaat pengerasan lainnya untuk workload Anda.
Halaman ini ditujukan bagi spesialis Keamanan yang memerlukan lapisan isolasi pada workload, tetapi tidak dapat menggunakan GKE Sandbox. Untuk mempelajari lebih lanjut peran umum dan contoh tugas yang kami referensikan dalam konten Google Cloud , lihat Peran dan tugas pengguna GKE umum.
Halaman ini berlaku untuk cluster Standard tanpa node auto-provisioning. Untuk memisahkan workload di cluster Autopilot dan di cluster Standard dengan node auto-provisioning yang diaktifkan, lihat Mengonfigurasi pemisahan workload di GKE.
Ringkasan
Cluster GKE menggunakan workload khusus yang dikelola GKE untuk mengaktifkan fungsionalitas dan fitur cluster tertentu, seperti pengumpulan metrik. Beban kerja ini diberi izin khusus agar dapat berjalan dengan benar di cluster.
Beban kerja yang Anda deploy ke node mungkin berpotensi disusupi oleh entity berbahaya. Menjalankan workload ini bersama workload yang dikelola GKE dengan hak istimewa berarti penyerang yang keluar dari container yang disusupi dapat menggunakan kredensial workload istimewa pada node untuk mengeskalasikan hak istimewa di cluster Anda.
Mencegah terurainya container
Pertahanan utama Anda semestinya aplikasi yang Anda miliki. GKE memiliki beberapa fitur yang dapat Anda gunakan untuk memperkuat cluster dan Pod. Pada kebanyakan kasus, kami sangat merekomendasikan untuk menggunakan GKE Sandbox untuk mengisolasi beban kerja Anda. GKE Sandbox didasarkan pada project open source gVisor, dan mengimplementasikan Linux kernel API di userspace. Setiap Pod berjalan pada kernel khusus yang melakukan sandbox aplikasi untuk mencegah akses ke panggilan sistem dengan hak istimewa dalam kernel host. Beban kerja yang berjalan di GKE Sandbox akan otomatis dijadwalkan di node terpisah, yang diisolasi dari beban kerja lain.
Anda juga harus mengikuti rekomendasi di Meningkatkan keamanan cluster.
Menghindari serangan eskalasi akses
Jika Anda tidak dapat menggunakan GKE Sandbox, dan menginginkan lapisan isolasi tambahan selain tindakan hardening lainnya, Anda dapat menggunakan taint node dan afinitas node untuk menjadwalkan beban kerja Anda pada node pool khusus. Taint node memberi tahu GKE untuk menghindari penjadwalan beban kerja tanpa toleransi yang sesuai (seperti beban kerja yang dikelola GKE) pada node tersebut. Afinitas node pada beban kerja Anda sendiri memberi tahu GKE untuk menjadwalkan Pod Anda pada node khusus.
Batasan isolasi node
- Penyerang masih dapat memulai serangan Denial-of-Service (DoS) dari node yang disusupi.
- Node yang disusupi masih dapat membaca banyak resource, termasuk semua Pod dan namespace dalam cluster.
- Node yang disusupi dapat mengakses Rahasia dan kredensial yang digunakan oleh setiap Pod yang berjalan pada node tersebut.
- Menggunakan node pool terpisah untuk mengisolasi beban kerja dapat memengaruhi efisiensi biaya, penskalaan otomatis, dan penggunaan resource.
- Node yang disusupi masih dapat mengabaikan kebijakan jaringan egress.
- Beberapa beban kerja yang dikelola GKE harus berjalan pada setiap node di cluster Anda, dan dikonfigurasi untuk menoleransi semua taint.
- Jika Anda men-deploy DaemonSets yang memiliki izin yang lebih tinggi dan dapat menoleransi setiap taint, Pod tersebut dapat menjadi jalur untuk eskalasi hak istimewa dari node yang disusupi.
Cara kerja isolasi node
Guna menerapkan isolasi node untuk workload, Anda harus melakukan hal berikut:
- Terapkan taint dan beri label pada node pool untuk workload Anda.
- Perbarui beban kerja Anda dengan aturan toleransi dan afinitas node yang sesuai.
Panduan ini mengasumsikan bahwa Anda memulai dengan satu node pool di cluster. Penggunaan afinitas node selain taint node tidak wajib, tetapi sebaiknya Anda mendapatkan manfaat dari kontrol yang lebih ketat terhadap penjadwalan.
Sebelum memulai
Sebelum memulai, pastikan Anda telah melakukan tugas berikut:
- Aktifkan Google Kubernetes Engine API. Aktifkan Google Kubernetes Engine API
- Untuk menggunakan Google Cloud CLI untuk tugas ini,
instal lalu
lakukan inisialisasi
gcloud CLI. Jika sebelumnya Anda telah menginstal gcloud CLI, dapatkan versi terbaru dengan menjalankan perintah
gcloud components update. Versi gcloud CLI yang lebih lama mungkin tidak mendukung menjalankan perintah dalam dokumen ini.
- Pilih nama tertentu untuk taint node dan label node yang ingin Anda gunakan untuk node pool khusus.
Taint dan beri label pada node pool untuk beban kerja Anda
Buat node pool baru untuk beban kerja Anda, lalu terapkan taint node dan label node. Saat Anda menerapkan taint atau label di level node pool, setiap node baru, seperti yang dibuat oleh penskalaan otomatis, akan otomatis mendapatkan taint dan label yang ditentukan.
Anda juga dapat menambahkan taint node dan label node ke node pool yang ada. Jika Anda menggunakan efek NoExecute, GKE akan mengeluarkan semua Pod yang berjalan pada node tersebut yang tidak memiliki toleransi terhadap taint baru.
Untuk isolasi beban kerja, selalu gunakan awalan node-restriction.kubernetes.io/
untuk label node dan untuk pemilih yang sesuai dalam manifes Pod Anda.
Awalan ini mencegah penyerang menggunakan kredensial node untuk menetapkan atau
mengubah label yang menggunakan awalan ini. Untuk mengetahui informasi selengkapnya, lihat
Isolasi/pembatasan node
dalam dokumentasi Kubernetes.
Untuk menambahkan taint dan label ke node pool baru, jalankan perintah berikut:
gcloud container node-pools create POOL_NAME \
--cluster=CLUSTER_NAME \
--node-taints=TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
--node-labels=node-restriction.kubernetes.io/LABEL_KEY=LABEL_VALUE
Ganti kode berikut:
POOL_NAME: nama node pool baru untuk beban kerja Anda.CLUSTER_NAME: nama cluster GKE Anda.TAINT_KEY=TAINT_VALUE: pasangan nilai kunci yang terkait denganTAINT_EFFECTpenjadwalan. Contohnya,workloadType=untrusted.TAINT_EFFECT: salah satu dari nilai efek berikut:NoSchedule,PreferNoSchedule, atauNoExecute.NoExecutememberikan jaminan pengusiran yang lebih baik daripadaNoSchedule.node-restriction.kubernetes.io/LABEL_KEY=LABEL_VALUE: pasangan nilai kunci untuk label node, yang sesuai dengan pemilih yang Anda tentukan dalam manifes workload. Awalannode-restriction.kubernetes.io/mencegah kredensial node digunakan untuk menetapkan pasangan kunci-nilai ini pada node.
Tambahkan aturan toleransi dan afinitas node ke beban kerja Anda
Setelah Anda melakukan taint pada node pool khusus, tidak ada workload yang dapat dijadwalkan pada node pool tersebut kecuali memiliki toleransi yang sesuai dengan taint yang Anda tambahkan. Tambahkan toleransi ke spesifikasi workload Anda agar Pod tersebut dapat dijadwalkan pada node pool yang tercemar.
Jika Anda memberi label pada node pool khusus, Anda juga dapat menambahkan aturan afinitas node untuk memberi tahu GKE agar hanya menjadwalkan workload pada node pool tersebut.
Contoh berikut menambahkan toleransi untuk
taint workloadType=untrusted:NoExecute dan aturan afinitas node untuk
label node workloadType=untrusted.
kind: Deployment
apiVersion: apps/v1
metadata:
name: my-app
namespace: default
labels:
app: my-app
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
tolerations:
- key: TAINT_KEY
operator: Equal
value: TAINT_VALUE
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-restriction.kubernetes.io/LABEL_KEY
operator: In
values:
- "LABEL_VALUE"
containers:
- name: sleep
image: ubuntu
command: ["/bin/sleep", "inf"]
Ganti kode berikut:
TAINT_KEY: kunci taint yang Anda terapkan ke node pool khusus.TAINT_VALUE: nilai taint yang Anda terapkan ke node pool khusus.LABEL_KEY: kunci label node yang Anda terapkan ke node pool khusus.LABEL_VALUE: nilai label node yang Anda terapkan ke node pool khusus.
Saat Anda mengupdate Deployment dengan kubectl apply, GKE
akan membuat ulang Pod yang terdampak. Aturan afinitas node memaksa Pod ke
kumpulan node khusus yang Anda buat. Toleransi hanya mengizinkan Pod tersebut
ditempatkan di node.
Memastikan pemisahan berfungsi
Untuk memverifikasi bahwa penjadwalan berfungsi dengan benar, jalankan perintah berikut dan periksa apakah workload Anda berada di node pool khusus:
kubectl get pods -o=wide
Rekomendasi dan praktik terbaik
Setelah menyiapkan isolasi node, sebaiknya lakukan hal berikut:
- Batasi node pool tertentu ke workload yang dikelola GKE hanya dengan
menambahkan taint
components.gke.io/gke-managed-components. Dengan menambahkan taint ini, akan mencegah Pod Anda melakukan penjadwalan pada node tersebut, sehingga meningkatkan isolasi. - Saat membuat node pool baru, cegah sebagian besar workload yang dikelola GKE agar tidak berjalan pada node tersebut dengan menambahkan taint Anda sendiri ke node pool tersebut.
- Setiap kali Anda men-deploy beban kerja baru ke cluster, seperti saat menginstal alat pihak ketiga, audit izin yang diperlukan Pod. Jika memungkinkan, hindari men-deploy beban kerja yang menggunakan izin dengan tingkat lebih tinggi ke node bersama.
Langkah berikutnya
- Pelajari GKE Sandbox lebih lanjut.
- Pelajari GKE Autopilot, yang mengimplementasikan banyak fitur keamanan GKE secara default.