Mengonfigurasi penskalaan otomatis Pod vertikal

Penskalaan otomatis Pod vertikal mengotomatiskan penetapan permintaan dan batas resource CPU dan memori untuk container dalam Pod Kubernetes. Penskalaan otomatis Pod vertikal menganalisis penggunaan resource historis dan saat ini untuk memberikan rekomendasi, yang dapat ditampilkan atau diterapkan secara otomatis dengan memperbarui Pod. Fitur ini meningkatkan stabilitas dan efisiensi biaya dengan menyesuaikan ukuran alokasi resource.

Sebelum memulai

Sebelum mengonfigurasi Penskalaan Otomatis Pod Vertikal, pastikan Anda memenuhi prasyarat berikut:

  • Anda memiliki cluster bare metal yang sedang berjalan.
  • Anda memiliki akses kubectl ke cluster.
  • Metrics Server tersedia di cluster. Cluster bare metal menyertakan Metrics Server secara default.

Mengaktifkan penskalaan otomatis Pod vertikal

Aktifkan penskalaan otomatis Pod vertikal di cluster bare metal Anda dengan menyetel anotasi pratinjau dan mengonfigurasi spesifikasi cluster:

  1. Tambahkan atau perbarui anotasi pratinjau pada resource kustom Cluster.

    Edit resource kustom Cluster secara langsung atau ubah file konfigurasi cluster dan gunakan bmctl update.

    metadata:
      annotations:
        preview.baremetal.cluster.gke.io/vertical-pod-autoscaler: enable
    
  2. Ubah spec resource kustom Cluster untuk menyertakan kolom verticalPodAutoscaling dan tentukan mode enableUpdater dan enableMemorySaver:

    apiVersion: baremetal.cluster.gke.io/v1
    kind: Cluster
    metadata:
      name: cluster1
      namespace: cluster-cluster1
      annotations:
        preview.baremetal.cluster.gke.io/vertical-pod-autoscaler: enable
    spec:
      # ... other cluster spec fields
      verticalPodAutoscaling:
        enableUpdater: true       # Set to true for automated updates
        enableMemorySaver: true   # Set to true to reduce recommender memory usage
    
  3. Jika Anda mengubah file konfigurasi cluster, terapkan perubahan menggunakan perintah berikut:

    bmctl update cluster -c CLUSTER_NAME --kubeconfig KUBECONFIG
    

    Ganti kode berikut:

    • CLUSTER_NAME: nama cluster Anda.

    • KUBECONFIG: jalur file kubeconfig cluster Anda.

Membuat resource kustom VerticalPodAutoscaler

Setelah mengaktifkan penskalaan otomatis Pod vertikal di cluster, tentukan resource kustom VerticalPodAutoscaler untuk menargetkan workload tertentu:

  1. Tentukan resource VerticalPodAutoscaler di namespace yang sama dengan target workload.

    Resource kustom ini menentukan Pod mana yang ditargetkan menggunakan targetRef dan kebijakan resource apa pun.

    apiVersion: "autoscaling.k8s.io/v1"
    kind: VerticalPodAutoscaler
    metadata:
      name: hamster-vpa
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind: Deployment
        name: hamster
      resourcePolicy:
        containerPolicies:
          -   containerName: '*'
            minAllowed:
              cpu: 100m
              memory: 50Mi
            maxAllowed:
              cpu: 1
              memory: 500Mi
            controlledResources: ["cpu", "memory"]
    
  2. Terapkan manifes VerticalPodAutoscaler menggunakan perintah berikut:

    kubectl apply -f VPA_MANIFEST \
        --kubeconfig KUBECONFIG
    

    Ganti kode berikut:

    • VPA_MANIFEST: jalur file manifes VerticalPodAutoscaler.

    • KUBECONFIG: jalur file kubeconfig cluster.

Memahami mode penskalaan otomatis Pod vertikal

Penskalaan otomatis Pod vertikal beroperasi dalam berbagai mode yang mengontrol cara penerapan rekomendasi resource.

Mode rekomendasi

Dalam mode rekomendasi, penskalaan otomatis Pod vertikal menginstal komponen pemberi rekomendasi. Komponen ini menganalisis penggunaan resource dan memublikasikan nilai yang direkomendasikan untuk permintaan dan batas CPU serta memori di bagian status resource kustom VerticalPodAutoscaler yang Anda buat.

Untuk melihat rekomendasi permintaan dan batas resource, gunakan perintah berikut:

kubectl describe vpa VPA_NAME \
    --kubeconfig KUBECONFIG \
    -n CLUSTER_NAMESPACE
Replace the following:

*   `VPA_NAME`: the name of the `VerticalPodAutoscaler`
    that's targeting the workloads for which you are considering resource
    adjustments.

*   `KUBECONFIG`: the path of the cluster kubeconfig
    file.

*   `CLUSTER_NAMESPACE`: the name of the cluster that's
    running vertical Pod autoscaling.

Respons harus berisi bagian Status yang mirip dengan contoh berikut:

Status:
  Conditions:
    Last Transition Time:  2025-08-04T23:53:32Z
    Status:                True
    Type:                  RecommendationProvided
  Recommendation:
    Container Recommendations:
      Container Name:  hamster
      Lower Bound:
        Cpu:     100m
        Memory:  262144k
      Target:
        Cpu:     587m
        Memory:  262144k
      Uncapped Target:
        Cpu:     587m
        Memory:  262144k
      Upper Bound:
        Cpu:     1
        Memory:  500Mi

Pod tidak diperbarui secara otomatis dalam mode ini. Gunakan rekomendasi ini untuk memperbarui konfigurasi Pod Anda secara manual. Ini adalah perilaku default jika enableUpdater tidak ditetapkan atau false.

Mode update otomatis

Saat Anda menyetel enableUpdater enableUpdater ke true, pengontrol siklus proses bare metal akan men-deploy komponen updater dan pengontrol penerimaan penskalaan otomatis Pod vertikal selain recommender. Updater memantau Pod yang permintaan resource saat ini sangat berbeda dari rekomendasi.

Kebijakan update di resource VerticalPodAutoscaler menentukan cara pengupdate menerapkan rekomendasi. Secara default, mode update adalah Auto, yang menentukan bahwa updater menetapkan setelan resource yang diupdate saat pembuatan Pod. Contoh VerticalPodAutoscaler berikut menunjukkan cara menyetel mode pembaruan ke Initial:

apiVersion: "autoscaling.k8s.io/v1"
kind: VerticalPodAutoscaler
metadata:
  name: hamster-vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: hamster
  resourcePolicy:
  updatePolicy:
    updateMode: "Initial"
    ...

Pengupdate mendukung lima mode berikut:

  • Auto: Pengupdate mengeluarkan Pod. Pengontrol penerimaan mencegat permintaan pembuatan Pod baru dan mengubahnya untuk menggunakan nilai CPU dan memori yang direkomendasikan oleh pemberi rekomendasi. Mengupdate resource memerlukan pembuatan ulang Pod, yang dapat menyebabkan gangguan. Gunakan Pod Disruption Budgets, yang dipatuhi updater, untuk mengelola proses penghapusan. Mode ini setara dengan Recreate.

  • Recreate: Updater mengeluarkan Pod dan menetapkan permintaan dan batas resource yang direkomendasikan saat Pod dibuat ulang.

  • InPlaceOrRecreate(alfa): Updater mencoba update di tempat dengan upaya terbaik, tetapi mungkin kembali membuat ulang Pod jika update di tempat tidak memungkinkan. Untuk mengetahui informasi selengkapnya, lihat dokumentasi pengubahan ukuran pod di tempat.

  • Initial: Updater hanya menetapkan permintaan resource saat pembuatan Pod dan tidak pernah mengubahnya nanti.

  • Off: Updater tidak otomatis mengubah persyaratan resource Pod. Rekomendasi tersebut dihitung dan dapat diperiksa di objek VerticalPodAutoscaler.

Untuk mengetahui informasi selengkapnya tentang resource kustom VerticalPodAutoscaler, gunakan kubectl untuk mengambil definisi resource kustom verticalpodautoscalercheckpoints.autoscaling.k8s.io yang diinstal pada cluster versi 1.33.0 atau yang lebih baru.

Contoh berikut menunjukkan cara rekomendasi resource dapat muncul di bagian Status untuk penampung hamster. Contoh ini juga menunjukkan contoh peristiwa penghapusan Pod, yang terjadi saat updater menghapus Pod sebelum otomatis menetapkan konfigurasi resource yang direkomendasikan ke Pod yang dibuat ulang:

Spec:
  Resource Policy:
    Container Policies:
      Container Name:  *
      Controlled Resources:
        cpu
        memory
      Max Allowed:
        Cpu:     1
        Memory:  500Mi
      Min Allowed:
        Cpu:     100m
        Memory:  50Mi
  Target Ref:
    API Version:  apps/v1
    Kind:         Deployment
    Name:         hamster
  Update Policy:
    Update Mode:  Auto
Status:
  Conditions:
    Last Transition Time:  2025-08-04T23:53:32Z
    Status:                True
    Type:                  RecommendationProvided
  Recommendation:
    Container Recommendations:
      Container Name:  hamster
      Lower Bound:
        Cpu:     100m
        Memory:  262144k
      Target:
        Cpu:     587m
        Memory:  262144k
      Uncapped Target:
        Cpu:     587m
        Memory:  262144k
      Upper Bound:
        Cpu:     1
        Memory:  500Mi
Events:
  Type    Reason      Age   From         Message
  ----    ------      ----  ----         -------
  Normal  EvictedPod  49s   vpa-updater  VPA Updater evicted Pod hamster-7cb59fb657-lkrk4 to apply resource recommendation.

Mode penghemat memori

Mode penghemat memori mengurangi jejak memori komponen pemberi rekomendasi penskalaan otomatis Pod vertikal. Saat Anda menyetel enableMemorySaver ke true, pemberi rekomendasi hanya melacak dan menghitung agregasi untuk Pod yang memiliki resource kustom VerticalPodAutoscaler yang cocok.

Sebagai gantinya, saat Anda membuat resource kustom VerticalPodAutoscaler baru untuk workload yang ada, pemberi rekomendasi memerlukan waktu (hingga 24 jam) untuk mengumpulkan histori yang cukup guna memberikan rekomendasi yang akurat. Mode ini adalah false secara default untuk sebagian besar jenis cluster, tetapi defaultnya adalah true untuk cluster edge.

Menggunakan Prometheus sebagai penyedia histori persisten

Secara default, komponen pemberi rekomendasi mempertahankan histori konsumsi resource workload yang berjalan di cluster dalam memori, dan secara berkala, menyimpan statusnya ke resource kustom VerticalPodAutoscalerCheckpoint di etcd untuk memberikan ketahanan terhadap mulai ulang.

Mulai dari Google Distributed Cloud versi 1.34, Anda dapat menggunakan instance Prometheus Anda sendiri sebagai penyedia histori persisten untuk data konsumsi resource, yaitu metrik penggunaan CPU dan memori. Jika integrasi ini diaktifkan, pemberi rekomendasi dapat mengkueri server Prometheus saat startup atau dimulai ulang untuk mengambil data penggunaan resource historis jangka panjang untuk semua Pod yang dikelola. Pengambilan data ini memungkinkan sistem pemberi rekomendasi untuk segera membangun status internalnya dengan kumpulan data yang kaya, sehingga menghasilkan rekomendasi yang lebih tepat dan akurat sejak awal.

Menggunakan Prometheus sebagai penyedia histori persisten memberikan keuntungan berikut:

  • Mengoptimalkan pemanfaatan resource: menghasilkan rekomendasi yang akurat dan didasarkan pada informasi yang memadai segera setelah dimulai sehingga Anda dapat mengoptimalkan pemanfaatan resource cluster.

  • Mencegah error Kehabisan Memori (OOM): Prometheus menghilangkan kebutuhan untuk menyimpan status internal pemberi rekomendasi dalam VerticalPodAutoscalerCheckpoint resource kustom (CR) sehingga penggunaan memori ETCD menjadi lebih efisien. Saat komponen pemberi rekomendasi dimulai ulang, komponen tersebut akan kehilangan data historis dalam memori. Saat Anda menggunakan Prometheus sebagai penyedia histori, pemberi rekomendasi akan mengambil metrik histori dari Prometheus saat dimulai ulang, sehingga tidak memerlukan CR VerticalPodAutoscalerCheckpoint dan menghemat memori ETCD.

Anda dapat mengaktifkan dan menonaktifkan penggunaan Prometheus sebagai penyedia histori persisten kapan saja.

Prasyarat untuk menggunakan Prometheus dengan penskalaan otomatis Pod vertikal

Untuk menggunakan instance Prometheus Anda sendiri sebagai penyedia histori untuk penskalaan otomatis Pod vertikal, Anda harus mengonfigurasinya untuk menyalin metrik yang diperlukan, yang mencakup langkah-langkah berikut:

  1. Jika diperlukan, deploy Prometheus Operator di cluster yang ingin Anda gunakan sebagai penyedia histori persisten untuk penskalaan otomatis Pod vertikal. Untuk mengetahui informasi selengkapnya, lihat Cara men-deploy dan mengonfigurasi Prometheus Operator di Kubernetes.

  2. Mengonfigurasi izin untuk meng-scraping metrik.

    Untuk mengizinkan Prometheus meng-scrape metrik dari cAdvisor menggunakan file konfigurasi, Anda harus memberikan izin tambahan ke akun layanan yang digunakan server Prometheus. Buat atau perbarui ClusterRole yang berisi aturan ini dan pastikan ClusterRole tersebut terikat ke akun layanan Prometheus yang benar menggunakan ClusterRoleBinding:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
       name: prometheus-role
       labels:
          app: prometheus-server
    rules:
       - apiGroups: [""]
         resources:
           - nodes
         verbs:
           - get
           - list
           - watch
       - apiGroups: [""]
         resources:
           - nodes/proxy
           - nodes/metrics
         verbs:
           - get
        ---
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: prometheus-binding
      labels:
        app: prometheus-server
    subjects:
      - kind: ServiceAccount
        name: prometheus-server        # Service account being used by prometheus
        namespace: prometheus          # Service account's namespace
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: prometheus-role            # Name of the ClusterRole created above
    
  3. Perbarui file konfigurasi Prometheus untuk meng-scrape metrik berikut dari cAdvisor:

    • container_cpu_usage_seconds_total
    • container_memory_working_set_bytes

    Baris berikut menentukan detail pengambilan data untuk metrik cAdvisor:

    - job_name: 'kubernetes-cadvisor'
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      kubernetes_sd_configs:
        - role: node
      relabel_configs:
        - action: labelmap
          regex: __meta_kubernetes_node_label_(.+)
        - target_label: __address__
          replacement: kubernetes.default.svc:443
        - source_labels: [__meta_kubernetes_node_name]
          regex: (.+)
          target_label: __metrics_path__
          replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
    
      metric_relabel_configs:
      # Keep only the metrics VPA uses to save disk space
        - source_labels: [__name__]
          regex: (container_cpu_usage_seconds_total|container_memory_working_set_bytes)
          action: keep
    
  4. Perbarui file konfigurasi Prometheus untuk melakukan scraping metrik berikut dari Layanan kube-state-metrics:

    • kube_pod_labels
    1. Deploy Layanan kube-state-metrics di cluster Anda.

      Anda dapat menggunakan perintah Helm berikut untuk menginstal Layanan baru:

      helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
      helm repo update
      
    2. Buat file ksm-values.yaml dengan konten berikut:

      fullnameOverride: vpa-kube-state-metrics
      metricAllowlist:
        - kube_pod_labels
      metricLabelsAllowlist:
        - "pods=[*]"
      
    3. Instal diagram Helm berdasarkan file nilai dari langkah sebelumnya:

      helm install vpa-ksm prometheus-community/kube-state-metrics \
          -f ksm-values.yaml --namespace kube-system
      
    4. Tambahkan baris berikut ke file konfigurasi Prometheus untuk meng-scrape metrik kube_pod_labels dari Service kube-state-metrics yang diinstal:

      - job_name: 'kube-state-metrics'
        static_configs:
          - targets: ['vpa-kube-state-metrics.kube-system.svc.cluster.local:8080']
        metric_relabel_configs:
          - source_labels: [ __name__ ]
            regex: 'kube_pod_labels'
            action: keep
      

Mengaktifkan dan menggunakan Prometheus

Penskalaan otomatis Pod vertikal mendukung autentikasi dasar dan autentikasi berbasis token pembawa untuk terhubung ke Prometheus. Saat menggunakan autentikasi, Anda perlu membuat Secret yang berisi kredensial yang diperlukan di namespace cluster. Pengontrol meneruskan Secret ini ke target cluster dan memasangnya sebagai volume atau variabel lingkungan di Pod pemberi rekomendasi. Anda juga dapat menggunakan Prometheus tanpa autentikasi.

Untuk mengaktifkan dan menggunakan instance Prometheus Anda sendiri dengan penskalaan otomatis Pod vertikal, Anda harus mengonfigurasi bagian verticalPodAutoscaling dalam spesifikasi cluster dengan detail untuk terhubung ke instance Prometheus Anda.

Berikut contoh konfigurasi dalam spesifikasi cluster untuk digunakan dengan token pembawa:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: cluster1
  namespace: cluster-cluster1
  annotations:
    preview.baremetal.cluster.gke.io/vertical-pod-autoscaler: enable
spec:
  # ... other existing cluster configurations ...
  verticalPodAutoscaling:
    # ... other vertical Pod autoscaling configurations ...
    # Add this new section to configure the vpa to use prometheus using bearer token authentication as history provider
    prometheus:
      url: "http://prometheus.prometheus.monitoring.svc.cluster.local:9090"
      auth:
        bearerTokenAuth:
            name: prom-bearer-creds
            key: bearertoken

Untuk mengaktifkan Prometheus agar dapat digunakan dengan penskalaan otomatis Pod vertikal:

  1. Pastikan instance Prometheus Anda disiapkan untuk melakukan scraping metrik yang diperlukan seperti yang diuraikan dalam Prasyarat untuk menggunakan Prometheus dengan penskalaan otomatis Pod vertikal.

  2. Perbarui resource kustom Cluster spec sehingga kolom verticalPodAutoscaling.prometheus menentukan setelan koneksi untuk server Prometheus Anda.

  3. Tambahkan url ke bagian prometheus dan setel ke nama domain yang sepenuhnya memenuhi syarat (FQDN) untuk terhubung ke Prometheus dari dalam cluster:

    spec:
      # ... other existing cluster configurations ...
      verticalPodAutoscaling:
        # ... other vpa configurations ...
        # Add this new section to configure the vpa to use prometheus as history provider
        prometheus:
          # Required: The URL of the Prometheus server
          url: "http://prometheus.prometheus.svc.cluster.local:9090"
    
  4. Tentukan detail koneksi:

    Penskalaan otomatis Pod vertikal mendukung tiga metode koneksi berikut:

    • Tidak ada autentikasi
    • Autentikasi dasar (nama pengguna, sandi)
    • Autentikasi token pemilik

    Tidak ada autentikasi

    Jika instance Prometheus Anda tidak memerlukan autentikasi, Anda sudah selesai. Bagian prometheus hanya boleh menyertakan kolom url.

    Autentikasi dasar

    Gunakan langkah-langkah berikut untuk menentukan autentikasi dasar untuk Prometheus:

    1. Buat Secret yang berisi nama pengguna dan sandi di bagian stringData dan anotasi baremetal.cluster.gke.io/mark-source: "true".

      Contoh berikut menunjukkan Secret yang mendukung autentikasi dasar:

      apiVersion: v1
      kind: Secret
      metadata:
        name: prom-basic-creds
        namespace: <cluster-namespace>
        annotations:
          baremetal.cluster.gke.io/mark-source: "true"
      type: Opaque
      stringData:
        username: admin
        password: pwd
      

      Anotasi diperlukan untuk memastikan bahwa secret sumber dan secret di cluster target selalu sinkron. Secret diperbarui saat secret sumber diperbarui.

    2. Perbarui bagian prometheus.auth.basicAuth dari spesifikasi cluster untuk mereferensikan nama pengguna dan sandi dari kolom data di Secret.

      Contoh berikut menunjukkan bagian basicAuth yang mereferensikan nama pengguna dan sandi di Secret dari langkah sebelumnya:

      # ... other vpa configurations ...
      prometheus:
        url: "http://prometheus.prometheus.svc.cluster.local:9090"
        auth:
          basicAuth:
            usernameRef:
              name: prom-basic-creds
              key: username
            passwordRef:
              name: prom-basic-creds
              key: password
      

      Nama pengguna dan sandi harus berada di Secret yang sama. Kunci harus berupa kunci yang valid dari kolom data Secret.

    Instance Prometheus akan mulai berfungsi sebagai penyedia histori untuk penskalaan otomatis Pod vertikal saat resource kustom Cluster diperbarui.

    Autentikasi token pemilik

    Gunakan langkah-langkah berikut untuk menentukan autentikasi token pembawa untuk Prometheus:

    1. Buat Secret yang berisi token pembawa di bagian stringData dan anotasi baremetal.cluster.gke.io/mark-source: "true".

      Contoh berikut menunjukkan Secret yang mendukung autentikasi token pembawa:

      apiVersion: v1
      kind: Secret
      metadata:
        name: prom-bearer-creds
        namespace: <cluster-namespace>
        annotations:
          baremetal.cluster.gke.io/mark-source: "true"
      type: Opaque
      stringData:
        bearertoken: "SAMPLE_TOKEN"
      

      Anotasi diperlukan untuk memastikan bahwa secret sumber dan secret di cluster target selalu sinkron. Secret diperbarui saat secret sumber diperbarui.

    2. Perbarui bagian prometheus.auth.bearerTokenAuth spesifikasi cluster untuk mereferensikan token pembawa dari kolom data di Secret.

      Contoh berikut menunjukkan bagian bearerTokenAuth yang mereferensikan token pembawa di Secret dari langkah sebelumnya:

      # ... other vertical Pod autoscaling configurations ...
      prometheus:
        url: "http://prometheus.prometheus.svc.cluster.local:9090"
        auth:
          bearerTokenAuth:
              name: prom-bearer-creds
              key: bearertoken
      

      Kunci harus berupa kunci yang valid dari kolom data Secret.

    Instance Prometheus akan mulai berfungsi sebagai penyedia histori untuk penskalaan otomatis Pod vertikal saat resource kustom Cluster diperbarui.

Menonaktifkan penggunaan Prometheus

Untuk menonaktifkan penggunaan Prometheus dengan penskalaan otomatis Pod vertikal, hapus bagian prometheus dari bagian verticalPodAutoscaling resource kustom Cluster.

Menonaktifkan penskalaan otomatis Pod vertikal

Nonaktifkan Penskalaan Otomatis Pod Vertikal dengan menghapus resource kustom dan konfigurasinya dari cluster Anda:

  1. Hapus resource kustom VerticalPodAutoscaler yang telah Anda buat.

  2. Ubah resource kustom Cluster dan hapus seluruh bagian verticalPodAutoscaling dari spec.

    Anda dapat mengedit resource kustom Cluster secara langsung atau mengubah file konfigurasi cluster dan menggunakan bmctl update.

  3. Hapus anotasi preview.baremetal.cluster.gke.io/vertical-pod-autoscaler dari resource kustom Cluster.

Batasan

Pertimbangkan batasan berikut saat menggunakan Penskalaan Otomatis Pod Vertikal:

  • Penskalaan otomatis Pod vertikal belum siap digunakan untuk workload berbasis JVM karena visibilitas yang terbatas ke penggunaan memori aktual workload.
  • Updater memerlukan minimal dua replika Pod untuk Deployment guna mengganti Pod dengan nilai resource yang direvisi.
  • Updater tidak mengupdate Pod dengan cepat yang mengalami loop error karena error Kehabisan Memori (OOM).
  • Kebijakan update InPlaceOrRecreate untuk Pod adalah fitur alfa dalam penskalaan otomatis Pod vertikal. Proses ini mencoba melakukan update di tempat dengan upaya terbaik, tetapi mungkin melakukan penggantian Pod jika update di tempat tidak memungkinkan.

Langkah berikutnya