Mengisolasi workload Anda di node pool khusus

Halaman ini menunjukkan cara mengisolasi workload container Anda pada node pool khusus di Google Distributed Cloud (GDC) dengan air gap untuk memberi Anda lebih banyak kontrol atas pod Anda. Isolasi workload memberikan beberapa manfaat, seperti:

  • Mengurangi risiko serangan eskalasi akses di cluster Kubernetes Anda.
  • Kontrol yang lebih besar atas pod yang memerlukan resource tambahan.

Untuk kasus ini, pertimbangkan untuk mengisolasi workload container Anda agar mendapatkan kontrol dan pengoptimalan yang lebih baik.

Mengapa saya harus memisahkan workload saya?

Mengisolasi workload Anda di node pool khusus tidak diperlukan, tetapi dapat menjadi tindakan yang bijaksana untuk menghindari potensi masalah. Namun, perlu diketahui bahwa mengelola kumpulan node khusus memerlukan pengawasan yang lebih ketat, dan sering kali tidak diperlukan.

Cluster Kubernetes menggunakan workload khusus yang dikelola GDC untuk mengaktifkan kemampuan 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 beban kerja ini bersama beban kerja yang dikelola GDC dengan hak istimewa berarti penyerang yang keluar dari container yang disusupi dapat menggunakan kredensial beban kerja istimewa pada node untuk mengeskalasikan hak istimewa di cluster Anda.

Kumpulan node khusus juga berguna saat Anda harus menjadwalkan pod yang memerlukan lebih banyak resource daripada yang lain, seperti lebih banyak memori atau lebih banyak ruang disk lokal.

Anda dapat menggunakan mekanisme berikut untuk menjadwalkan workload di kumpulan node khusus:

Taint node memberi tahu cluster Kubernetes Anda untuk menghindari penjadwalan beban kerja tanpa toleransi yang sesuai, seperti beban kerja yang dikelola GDC, pada node tersebut. Afinitas node pada beban kerja Anda sendiri memberi tahu cluster 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 di node tersebut.

  • Menggunakan kumpulan node 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 GDC harus berjalan di setiap node di cluster Anda, dan dikonfigurasi untuk menoleransi semua taint.

  • Jika Anda men-deploy resource DaemonSet yang memiliki izin yang lebih tinggi dan dapat menoleransi taint apa pun, 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:

  1. Taint dan beri label kumpulan node untuk beban kerja Anda.

  2. Perbarui beban kerja Anda dengan aturan toleransi dan afinitas node yang sesuai.

Panduan ini mengasumsikan bahwa Anda memulai dengan satu kumpulan node 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 menjalankan tugas berikut:

  • Pilih nama tertentu untuk taint node dan label node yang ingin Anda gunakan untuk kumpulan node khusus. Misalnya, workloadType=untrusted.

  • Jika perlu, minta Admin IAM Organisasi Anda untuk memberi Anda peran User Cluster Developer (user-cluster-developer), yang tidak terikat ke namespace.

Taint dan beri label pada node pool baru

Saat Anda menerapkan taint atau label ke node pool baru, semua node, termasuk node yang ditambahkan nanti, akan otomatis mendapatkan taint dan label yang ditentukan.

Untuk menambahkan taint dan label ke node pool baru, selesaikan langkah-langkah berikut:

  1. Edit bagian nodePools resource kustom Cluster secara langsung saat membuat node pool:

    nodePools:
      ...
      - machineTypeName: n2-standard-2-gdc
        name: nodepool-1
        nodeCount: 3
        taints: TAINT_KEY=TAINT_VALUE:TAINT_EFFECT
        labels: LABEL_KEY=LABEL_VALUE
    

    Ganti kode berikut:

    • TAINT_KEY=TAINT_VALUE: pasangan nilai kunci yang terkait dengan penjadwalan TAINT_EFFECT. Misalnya, workloadType=untrusted.
    • TAINT_EFFECT: salah satu nilai efek berikut:
      • NoSchedule: pod yang tidak menoleransi taint ini tidak dijadwalkan di node; pod yang ada tidak dikeluarkan dari node.
      • PreferNoSchedule: Kubernetes menghindari penjadwalan pod yang tidak menoleransi taint ini ke node.
      • NoExecute: pod dikeluarkan dari node jika sudah berjalan di node, dan tidak dijadwalkan ke node jika belum berjalan di node.
    • LABEL_KEY=LABEL_VALUE: pasangan nilai kunci untuk label node, yang sesuai dengan pemilih yang Anda tentukan dalam manifes workload.
  2. Terapkan resource Cluster untuk membuat node pool baru:

    kubectl apply -f cluster.yaml \
        --kubeconfig MANAGEMENT_API_SERVER
    

    Ganti MANAGEMENT_API_SERVER dengan jalur kubeconfig server API zonal tempat cluster Kubernetes dihosting. Jika Anda belum membuat file kubeconfig untuk server API di zona target, lihat Login untuk mengetahui detailnya.

Memberi taint dan label pada node pool yang ada

Untuk menerapkan taint atau label ke node pool yang ada, Anda harus menerapkan perubahan ke setiap node yang ada. Anda tidak dapat mengupdate konfigurasi node pool secara dinamis.

Untuk menambahkan taint dan label ke node pool yang ada, selesaikan langkah-langkah berikut:

  1. Cantumkan node di node pool khusus:

    kubectl get node --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG \
        -l baremetal.cluster.gke.io/node-pool=NODE_POOL_NAME
    

    Ganti variabel berikut:

    • KUBERNETES_CLUSTER_KUBECONFIG: jalur kubeconfig untuk cluster Kubernetes.
    • NODE_POOL_NAME: nama node pool khusus Anda.

    Catat setiap ID node dari semua node di node pool dari output.

  2. Untuk setiap node di node pool, terapkan taint:

    kubectl taint nodes NODE_ID \
        TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    Ganti variabel berikut:

    • NODE_ID: ID node pekerja di node pool khusus.
    • TAINT_KEY=TAINT_VALUE: pasangan nilai kunci yang terkait dengan TAINT_EFFECT penjadwalan. Contohnya, workloadType=untrusted.
    • TAINT_EFFECT: salah satu nilai efek berikut:
      • NoSchedule: pod yang tidak menoleransi taint ini tidak dijadwalkan di node; pod yang ada tidak dikeluarkan dari node.
      • PreferNoSchedule: Kubernetes menghindari penjadwalan pod yang tidak menoleransi taint ini ke node.
      • NoExecute: pod dikeluarkan dari node jika sudah berjalan di node, dan tidak dijadwalkan ke node jika belum berjalan di node.
    • KUBERNETES_CLUSTER_KUBECONFIG: jalur kubeconfig untuk cluster Kubernetes.
  3. Untuk setiap node di kumpulan node, terapkan label yang sesuai dengan pemilih yang akan Anda tentukan dalam beban kerja penampung:

    kubectl label NODE_ID \
        LABEL_KEY:LABEL_VALUE \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    Ganti variabel berikut:

    • NODE_ID: ID node pekerja di node pool khusus.
    • LABEL_KEY:LABEL_VALUE: pasangan nilai kunci untuk label node, yang sesuai dengan pemilih yang Anda tentukan dalam manifes workload.
    • KUBERNETES_CLUSTER_KUBECONFIG: jalur kubeconfig untuk cluster Kubernetes.

Menambahkan aturan toleransi dan afinitas node

Setelah Anda melakukan taint pada kumpulan node khusus, tidak ada beban kerja yang dapat dijadwalkan pada kumpulan tersebut kecuali memiliki toleransi yang sesuai dengan taint yang Anda tambahkan. Tambahkan toleransi ke spesifikasi beban kerja Anda agar pod tersebut dapat dijadwalkan pada kumpulan node yang tercemar.

Jika memberi label pada kumpulan node khusus, Anda juga dapat menambahkan aturan afinitas node untuk memberi tahu GDC agar hanya menjadwalkan beban kerja Anda pada kumpulan node tersebut.

Untuk mengonfigurasi workload container agar berjalan di node pool khusus, selesaikan langkah-langkah berikut:

  1. Tambahkan bagian berikut ke bagian .spec.template.spec dari workload container Anda:

    kind: Deployment
    apiVersion: apps/v1
        ...
        spec:
        ...
          template:
            spec:
              tolerations:
              - key: TAINT_KEY
                operator: Equal
                value: TAINT_VALUE
                effect: TAINT_EFFECT
              affinity:
                nodeAffinity:
                  requiredDuringSchedulingIgnoredDuringExecution:
                    nodeSelectorTerms:
                    - matchExpressions:
                      - key: LABEL_KEY
                        operator: In
                        values:
                        - "LABEL_VALUE"
              ...
    

    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.
    • TAINT_EFFECT: salah satu nilai efek berikut:
      • NoSchedule: pod yang tidak menoleransi taint ini tidak dijadwalkan di node; pod yang ada tidak dikeluarkan dari node.
      • PreferNoSchedule: Kubernetes menghindari penjadwalan pod yang tidak menoleransi taint ini ke node.
      • NoExecute: pod dikeluarkan dari node jika sudah berjalan di node, dan tidak dijadwalkan ke node jika belum berjalan di node.
    • LABEL_KEY: kunci label node yang Anda terapkan ke node pool khusus.
    • LABEL_VALUE: nilai label node yang Anda terapkan ke node pool khusus.

    Misalnya, resource Deployment 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: workloadType
            operator: Equal
            value: untrusted
            effect: NoExecute
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: workloadType
                    operator: In
                    values:
                    - "untrusted"
          containers:
          - name: my-app
            image: harbor-1.org-1.zone1.google.gdc.test/harborproject/my-app
            ports:
            - containerPort: 80
          imagePullSecrets:
          - name: SECRET
    
  2. Perbarui deployment Anda:

    kubectl apply -f deployment.yaml -n NAMESPACE \
        --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG
    

    Ganti variabel berikut:

    • NAMESPACE: namespace project workload penampung Anda.
    • KUBERNETES_CLUSTER_KUBECONFIG: jalur kubeconfig untuk cluster Kubernetes.

GDC akan membuat ulang pod yang terpengaruh. 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 beban kerja Anda berada di kumpulan node khusus:

kubectl get pods -o=wide -n NAMESPACE \
    --kubeconfig KUBERNETES_CLUSTER_KUBECONFIG

Rekomendasi dan praktik terbaik

Setelah menyiapkan isolasi node, sebaiknya lakukan hal berikut:

  • Saat membuat kumpulan node baru, cegah sebagian besar beban kerja yang dikelola GDC agar tidak berjalan pada node tersebut dengan menambahkan taint Anda sendiri ke kumpulan node 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.