Hardening isolasi workload dengan GKE Sandbox


Halaman ini menjelaskan cara menggunakan GKE Sandbox untuk melindungi kernel host pada node saat container di Pod mengeksekusi kode yang tidak dikenal atau tidak tepercaya, atau memerlukan isolasi ekstra dari node.

Ketersediaan GKE Sandbox

GKE Sandbox siap digunakan di cluster Autopilot yang menjalankan GKE versi 1.27.4-gke.800 dan yang lebih baru. Untuk mulai men-deploy beban kerja Autopilot di sandbox, lanjutkan ke Bekerja dengan GKE Sandbox.

Untuk menggunakan GKE Sandbox di cluster GKE Standard baru atau yang sudah ada, Anda harus mengaktifkan GKE Sandbox di cluster secara manual.

Workload GPU didukung di GKE Sandbox pada versi 1.29.2-gke.11080000 dan yang lebih baru.

Sebelum memulai

Sebelum memulai, pastikan Anda telah menjalankan tugas berikut:

  • Aktifkan Google Kubernetes Engine API.
  • Aktifkan Google Kubernetes Engine API
  • Jika ingin menggunakan Google Cloud CLI untuk tugas ini, instal lalu initialize gcloud CLI. Jika sebelumnya Anda telah menginstal gcloud CLI, dapatkan versi terbaru dengan menjalankan gcloud components update.

Mengaktifkan GKE Sandbox di cluster Standard baru

Node pool default, yang dibuat saat Anda membuat cluster baru, tidak dapat menggunakan GKE Sandbox jika itu adalah satu-satunya node pool di cluster, karena workload sistem yang dikelola GKE harus berjalan terpisah dari workload dengan sandbox yang tidak tepercaya. Untuk mengaktifkan GKE Sandbox selama pembuatan cluster, Anda harus menambahkan minimal satu node pool tambahan ke cluster.

Konsol

Untuk melihat cluster Anda, buka menu Google Kubernetes Engine di Konsol Google Cloud.

  1. Buka halaman Google Kubernetes Engine di Konsol Google Cloud.

    Buka Google Kubernetes Engine

  2. Klik Create.

  3. Opsional tetapi direkomendasikan: Dari menu navigasi, di bagian Cluster, klik Features, lalu pilih kotak centang berikut sehingga pesan gVisor dicatat ke dalam log:

    • Cloud Logging
    • Cloud Monitoring
    • Layanan Terkelola untuk Prometheus
  4. Klik Add Node Pool.

  5. Dari menu navigasi, di bagian Node Pools, luaskan kumpulan node baru, lalu klik Nodes.

  6. Konfigurasikan setelan berikut untuk node pool:

    1. Dari menu drop-down Image type, pilih Container-Optimized OS with Containerd (cos_containerd). Ini adalah satu-satunya jenis image yang didukung untuk GKE Sandbox.
    2. Di bagian Machine Configuration, pilih Series dan Machine type.
    3. Secara opsional, jika Anda menjalankan versi GKE yang didukung, pilih jenis GPU. Jenis ini harus berupa salah satu dari jenis berikut:
      • nvidia-tesla-t4
      • nvidia-tesla-a100
      • nvidia-a100-80gb
      • nvidia-l4
      • nvidia-h100-80gb.
    4. Jika menggunakan GPU di GKE Sandbox, pilih atau instal varian driver latest.
  7. Dari menu navigasi, dengan nama node pool yang Anda konfigurasi, klik Security lalu centang kotak Enable sandbox with gVisor.

  8. Lanjutkan untuk mengonfigurasi cluster dan kumpulan node sesuai kebutuhan.

  9. Klik Create.

gcloud

GKE Sandbox tidak dapat diaktifkan untuk node pool default, dan tidak dapat membuat node pool tambahan bersamaan dengan membuat cluster baru menggunakan perintah gcloud. Sebagai gantinya, buat cluster seperti biasa. Meskipun opsional, sebaiknya Anda mengaktifkan Logging dan Monitoring agar pesan gVisor dicatat ke dalam log.

Selanjutnya, gunakan perintah gcloud container node-pools create, dan tetapkan flag -- sandbox ke type=gvisor. Jenis image node harus berupa cos_containerd untuk GKE Sandbox.

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --machine-type=MACHINE_TYPE \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Ganti variabel berikut:

  • NODE_POOL_NAME: nama node pool baru.
  • CLUSTER_NAME: nama cluster Anda.
  • NODE_VERSION: versi yang akan digunakan untuk node pool.
  • MACHINE_TYPE: jenis mesin yang akan digunakan untuk node.

Untuk membuat pool node GPU dengan GKE Sandbox, jalankan perintah berikut:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --machine-type=MACHINE_TYPE \
  --accelerator=type=GPU_TYPE,gpu-driver-version=latest \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Ganti kode berikut:

Mengaktifkan GKE Sandbox di cluster Standard yang ada

Anda dapat mengaktifkan GKE Sandbox pada cluster Standard yang sudah ada dengan menambahkan node pool baru dan mengaktifkan fitur untuk node pool tersebut.

Konsol

Untuk membuat node pool baru dengan GKE Sandbox yang diaktifkan:

  1. Buka halaman Google Kubernetes Engine di konsol Google Cloud.

    Buka Google Kubernetes Engine

  2. Klik nama cluster yang ingin diubah.

  3. Klik Add Node Pool.

  4. Konfigurasikan halaman Detail node pool seperti yang dipilih.

  5. Dari menu navigasi, klik Nodes, lalu konfigurasikan setelan berikut:

    1. Dari menu drop-down Image type, pilih Container-Optimized OS with Containerd (cos_containerd). Ini adalah satu-satunya jenis image yang didukung untuk GKE Sandbox.
    2. Di bagian Machine Configuration, pilih Series dan Machine type.
    3. Secara opsional, jika Anda menjalankan versi GKE yang didukung, pilih jenis GPU. Jenis ini harus berupa salah satu dari jenis berikut:
      • nvidia-tesla-t4
      • nvidia-tesla-a100
      • nvidia-a100-80gb
      • nvidia-l4
      • nvidia-h100-80gb.
    4. Jika menggunakan GPU di GKE Sandbox, pilih atau instal varian driver latest.
  6. Dari menu navigasi, klik Security lalu pilih kotak centang Enable sandbox with gVisor.

  7. Klik Create.

gcloud

Untuk membuat node pool baru dengan GKE Sandbox yang diaktifkan, gunakan perintah seperti berikut:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --machine-type=MACHINE_TYPE \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Jenis image node harus cos_containerd untuk GKE Sandbox.

Untuk membuat pool node GPU dengan GKE Sandbox, jalankan perintah berikut:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --machine-type=MACHINE_TYPE \
  --accelerator=type=GPU_TYPE,gpu-driver-version=latest \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Ganti kode berikut:

Opsional: Mengaktifkan pemantauan dan logging

Tindakan ini bersifat opsional, tetapi sebaiknya Anda mengaktifkan Cloud Logging dan Cloud Monitoring di cluster, sehingga pesan gVisor dicatat ke dalam log. Layanan ini diaktifkan secara default untuk cluster baru.

Anda dapat menggunakan Konsol Google Cloud untuk mengaktifkan fitur ini di cluster yang sudah ada.

  1. Buka halaman Google Kubernetes Engine di konsol Google Cloud.

    Buka Google Kubernetes Engine

  2. Klik nama cluster yang ingin diubah.

  3. Di bagian Features, pada kolom Cloud Logging, klik Edit Cloud Logging.

  4. Centang kotak Enable Cloud Logging.

  5. Klik Simpan Perubahan.

  6. Ulangi langkah yang sama untuk kolom Cloud Monitoring dan Managed Service for Prometheus untuk mengaktifkan fitur tersebut.

Menggunakan GKE Sandbox di Autopilot dan Standard

Di cluster Autopilot dan di cluster Standard dengan GKE Sandbox yang diaktifkan, Anda meminta lingkungan dengan sandbox untuk Pod dengan menentukan RuntimeClass gvisor dalam spesifikasi Pod.

Untuk cluster Autopilot, pastikan Anda menjalankan GKE versi 1.27.4-gke.800 atau yang lebih baru.

Menjalankan aplikasi di sandbox

Agar Deployment berjalan pada node dengan GKE Sandbox yang diaktifkan, tetapkan spec.template.spec.runtimeClassName ke gvisor, seperti yang ditunjukkan pada contoh berikut:

# httpd.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd
  labels:
    app: httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      runtimeClassName: gvisor
      containers:
      - name: httpd
        image: httpd

Membuat Deployment:

kubectl apply -f httpd.yaml

Pod di-deploy ke node dengan GKE Sandbox aktif. Untuk memverifikasi deployment, temukan node tempat Pod di-deploy:

kubectl get pods

Outputnya mirip dengan hal berikut ini:

NAME                    READY   STATUS    RESTARTS   AGE
httpd-db5899bc9-dk7lk   1/1     Running   0          24s

Dari output, temukan nama Pod di output, lalu periksa nilai untuk RuntimeClass:

kubectl get pods POD_NAME -o jsonpath='{.spec.runtimeClassName}'

Outputnya adalah gvisor.

Atau, Anda dapat mencantumkan RuntimeClass setiap Pod, dan mencari Pod yang disetel ke gvisor:

kubectl get pods -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.runtimeClassName}\n{end}'

Outputnya adalah sebagai berikut:

POD_NAME: gvisor

Metode verifikasi bahwa Pod berjalan di sandbox ini dapat dipercaya karena tidak bergantung pada data apa pun dalam sandbox itu sendiri. Apa pun yang dilaporkan dari dalam sandbox tidak dapat dipercaya, karena dapat rusak atau berbahaya.

Menjalankan pod dengan GPU di GKE Sandbox

Untuk menjalankan beban kerja GPU di GKE Sandbox, tambahkan kolom runtimeClassName: gvisor ke manifes Anda seperti dalam contoh berikut:

  • Contoh manifes untuk Pod GPU mode Standar:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-gpu-pod
    spec:
      runtimeClassName: gvisor
      containers:
      - name: my-gpu-container
        image: nvidia/samples:vectoradd-cuda10.2
        resources:
          limits:
          nvidia.com/gpu: 1
    
  • Contoh manifes untuk Pod GPU mode Autopilot:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-gpu-pod
    spec:
      runtimeClassName: gvisor
      nodeSelector:
        cloud.google.com/compute-class: "Accelerator"
        cloud.google.com/gke-accelerator: nvidia-tesla-t4
      - name: my-gpu-container
        image: nvidia/samples:vectoradd-cuda10.2
        resources:
          limits:
            nvidia.com/gpu: 1
    

Anda dapat menjalankan Pod GPU mode Standar atau Autopilot yang memenuhi persyaratan versi dan jenis GPU di GKE Sandbox dengan menambahkan kolom runtimeClassName: gvisor ke manifes. Untuk mengetahui petunjuk cara menjalankan Pod GPU di GKE, lihat referensi berikut:

Menjalankan Pod reguler bersama dengan Pod dengan sandbox

Langkah-langkah di bagian ini berlaku untuk workload mode Standard. Anda tidak perlu menjalankan Pod reguler bersama Pod sandbox dalam mode Autopilot, karena model harga Autopilot tidak perlu mengoptimalkan jumlah Pod yang dijadwalkan secara manual pada node.

Setelah mengaktifkan GKE Sandbox pada node pool, Anda dapat menjalankan aplikasi tepercaya pada node tersebut tanpa menggunakan sandbox menggunakan taint dan toleransi node. Pod ini disebut sebagai "Pod reguler" untuk membedakannya dari Pod dengan sandbox.

Pod reguler, seperti Pod dengan sandbox, dicegah mengakses layanan Google Cloud atau metadata cluster lainnya. Pencegahan ini adalah bagian dari konfigurasi node. Jika Pod reguler atau Pod dengan sandbox memerlukan akses ke layanan Google Cloud, gunakan Workload Identity Federation for GKE.

GKE Sandbox menambahkan label dan taint berikut ke node yang dapat menjalankan Pod dengan sandbox:

labels:
  sandbox.gke.io/runtime: gvisor
taints:
- effect: NoSchedule
  key: sandbox.gke.io/runtime
  value: gvisor

Selain setelan afinitas dan toleransi node apa pun dalam manifes Pod, GKE Sandbox menerapkan afinitas dan toleransi node berikut ke semua Pod dengan RuntimeClass yang ditetapkan ke gvisor:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: sandbox.gke.io/runtime
          operator: In
          values:
          - gvisor
tolerations:
  - effect: NoSchedule
    key: sandbox.gke.io/runtime
    operator: Equal
    value: gvisor

Untuk menjadwalkan Pod reguler pada node dengan GKE Sandbox aktif, terapkan secara manual afinitas node dan toleransi yang dijelaskan sebelumnya dalam manifes Pod Anda.

  • Jika pod Anda dapat berjalan pada node yang telah mengaktifkan GKE Sandbox, tambahkan tolerasi.
  • Jika pod Anda harus berjalan di node dengan GKE Sandbox yang diaktifkan, tambahkan afinitas dan toleransi node.

Misalnya, manifes berikut mengubah manifes yang digunakan dalam Menjalankan aplikasi di sandbox sehingga akan berjalan sebagai Pod biasa pada node dengan Pod yang di-sandbox, dengan menghapus runtimeClass dan menambahkan taint dan toleransi yang dijelaskan sebelumnya.

# httpd-no-sandbox.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-no-sandbox
  labels:
    app: httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      containers:
      - name: httpd
        image: httpd
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: sandbox.gke.io/runtime
                operator: In
                values:
                - gvisor
      tolerations:
        - effect: NoSchedule
          key: sandbox.gke.io/runtime
          operator: Equal
          value: gvisor

Pertama, pastikan Deployment tidak berjalan di sandbox:

kubectl get pods -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.runtimeClassName}\n{end}'

Outputnya mirip dengan:

httpd-db5899bc9-dk7lk: gvisor
httpd-no-sandbox-5bf87996c6-cfmmd:

Deployment httpd yang dibuat sebelumnya berjalan di sandbox, karena runtimeClass-nya adalah gvisor. Deployment httpd-no-sandbox tidak memiliki nilai untuk runtimeClass, sehingga tidak berjalan di sandbox.

Selanjutnya, pastikan Deployment tanpa sandbox berjalan pada node dengan GKE Sandbox dengan menjalankan perintah berikut:

kubectl get pod -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.nodeName}\n{end}'

Nama node pool disematkan dalam nilai nodeName. Pastikan Pod berjalan pada node di node pool dengan GKE Sandbox diaktifkan.

Memverifikasi perlindungan metadata

Untuk memvalidasi pernyataan bahwa metadata dilindungi dari node yang dapat menjalankan Pod dengan sandbox, Anda dapat menjalankan pengujian:

  1. Buat Deployment dengan sandbox dari manifes berikut, menggunakan kubectl apply -f. Kode ini menggunakan gambar fedora, yang menyertakan perintah curl. Pod menjalankan perintah /bin/sleep untuk memastikan bahwa Deployment berjalan selama 10.000 detik.

    # sandbox-metadata-test.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: fedora
      labels:
        app: fedora
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: fedora
      template:
        metadata:
          labels:
            app: fedora
        spec:
          runtimeClassName: gvisor
          containers:
          - name: fedora
            image: fedora
            command: ["/bin/sleep","10000"]
    
  2. Dapatkan nama Pod menggunakan kubectl get pods, lalu gunakan kubectl exec untuk terhubung ke Pod secara interaktif.

    kubectl exec -it POD_NAME /bin/sh
    

    Anda terhubung ke container yang berjalan di Pod, dalam sesi /bin/sh.

  3. Dalam sesi interaktif, coba akses URL yang menampilkan metadata cluster:

    curl -s "http://169.254.169.254/computeMetadata/v1/instance/attributes/kube-env" -H "Metadata-Flavor: Google"
    

    Perintah tersebut hang dan akhirnya habis waktu, karena paketnya tiba-tiba hilang.

  4. Tekan Ctrl+C untuk menghentikan perintah curl, dan ketik exit untuk memutuskan koneksi dari Pod.

  5. Hapus baris RuntimeClass dari manifes YAML dan deploy ulang Pod menggunakan kubectl apply -f FILENAME. Pod yang di-sandbox akan dihentikan dan dibuat ulang pada node tanpa GKE Sandbox.

  6. Dapatkan nama Pod baru, hubungkan ke Pod menggunakan kubectl exec, dan jalankan lagi perintah curl. Kali ini, hasilnya akan ditampilkan. Contoh output ini terpotong.

    ALLOCATE_NODE_CIDRS: "true"
    API_SERVER_TEST_LOG_LEVEL: --v=3
    AUTOSCALER_ENV_VARS: kube_reserved=cpu=60m,memory=960Mi,ephemeral-storage=41Gi;...
    ...
    

    Ketik exit untuk memutuskan koneksi dari Pod.

  7. Hapus deployment:

    kubectl delete deployment fedora
    

Menonaktifkan GKE Sandbox

Anda tidak dapat menonaktifkan GKE Sandbox di cluster GKE Autopilot atau di node pool GKE Standard. Jika Anda ingin berhenti menggunakan GKE Sandbox, hapus node pool.

Langkah selanjutnya