全部产品
Search
文档中心

Container Service for Kubernetes:Aktifkan pemasangan disk paralel untuk mempercepat startup pod

更新时间:Jul 06, 2025

Dalam skenario yang melibatkan penyebaran padat aplikasi stateful (seperti database) atau sejumlah besar kontainer berumur pendek (seperti integrasi berkelanjutan dan pemrosesan batch), setiap pod memerlukan banyak disk untuk menyimpan data secara persisten. Ketika banyak pod dijadwalkan ke node yang sama secara bersamaan, metode pemasangan seri default meningkatkan waktu startup pod. Untuk mengatasi masalah ini, Anda dapat mengaktifkan fitur pemasangan disk paralel.

Prasyarat

Catatan penggunaan

  • Anda hanya dapat mengaktifkan fitur pemasangan paralel untuk disk yang memiliki nomor seri. Untuk informasi lebih lanjut tentang cara memeriksa nomor seri disk, lihat Kueri Nomor Seri Perangkat Penyimpanan Blok.

    Disk yang dibuat sebelum 10 Juni 2020 tidak memiliki nomor seri yang dapat dikenali. Jika Anda mengaktifkan fitur pemasangan paralel untuk disk-disk tersebut, kegagalan pemasangan akan terjadi.

  • Ketika beberapa disk dilepas dari node yang sama, disk tersebut dilepas dalam mode seri.

  • Setelah Anda mengaktifkan pemasangan paralel, bidang Device yang dikembalikan oleh API seperti ECS DescribeDisks, serta titik pemasangan yang ditampilkan di konsol mungkin tidak akurat. Jangan gunakan jalur pemasangan ini dalam bisnis Anda. Anda dapat menggunakan nomor seri disk untuk memastikan jalur pemasangan aktual.

Prosedur

Anda dapat mengaktifkan pemasangan disk paralel secara manual atau menggunakan skrip otomatis untuk mengaktifkan fitur ini.

Gunakan skrip otomatis

  1. Simpan skrip berikut sebagai file bernama enable_parallel_attach.sh.

    Lihat Skrip

    #!/bin/bash
    
    set -e
    set -o pipefail
    
    readonly REQUIRED_VERSION="v1.30.4"
    CLUSTER_ID=$1
    
    if [ -z "$CLUSTER_ID" ]; then
        echo "Penggunaan: enable_parallel_attach.sh <cluster-id>"
        exit 1
    fi
    
    check_version() {
        local ADDONS VERSION
        ADDONS=$(aliyun cs GET "/clusters/${CLUSTER_ID}/addon_instances")
    
        VERSION=$(echo "$ADDONS" | jq -r '.addons[] | select(.name=="csi-plugin") | .version')
        if !  printf "%s\n" "$REQUIRED_VERSION" "$VERSION" | sort -V -C; then
            echo "Versi csi-plugin $VERSION tidak didukung, harap tingkatkan ke $REQUIRED_VERSION atau lebih baru"
            exit 1
        fi
    
        PROVISIONER=managed-csiprovisioner
        VERSION=$(echo "$ADDONS" | jq -r '.addons[] | select(.name=="managed-csiprovisioner") | .version')
        if [ -z "$VERSION" ]; then
            PROVISIONER=csi-provisioner
            VERSION=$(echo "$ADDONS" | jq -r '.addons[] | select(.name=="csi-provisioner") | .version')
        fi
        if !  printf "%s\n" "$REQUIRED_VERSION" "$VERSION" | sort -V -C; then
            echo "Versi $PROVISIONER $VERSION tidak didukung, harap tingkatkan ke $REQUIRED_VERSION atau lebih baru"
            exit 1
        fi
    }
    
    update_node_pool() {
        local NODE_POOL_DOC
        NODE_POOL_DOC=$(aliyun cs GET "/clusters/${CLUSTER_ID}/nodepools/$1")
    
        if [ -n "$(echo "$NODE_POOL_DOC" | jq -r '(.scaling_group.tags // [])[] | select(.key=="supportConcurrencyAttach")')" ]; then
            echo "node pool sudah memiliki tag supportConcurrencyAttach"
            return
        fi
    
        aliyun cs PUT "/clusters/${CLUSTER_ID}/nodepools/$1" --header "Content-Type=application/json" \
            --body "$(echo "$NODE_POOL_DOC" | jq -c '{
        "scaling_group": {
            "tags": ((.scaling_group.tags // []) + [{
                "key": "supportConcurrencyAttach",
                "value": "true"
            }])
        }
    }')"
    }
    
    # Konfigurasikan node yang ada.
    update_nodes() {
        local PAGE=1
        local IDX TOTAL NODES_DOC ARGS
        while :; do
            echo "menandai node, halaman $PAGE"
            NODES_DOC=$(aliyun cs GET "/clusters/${CLUSTER_ID}/nodes" --pageSize 50 --pageNumber $PAGE)
            TOTAL=$(echo "$NODES_DOC" | jq -r '.page.total_count')
    
            ARGS=()
            IDX=0
            for node in $(echo "$NODES_DOC" | jq -r '.nodes[] | select(.is_aliyun_node) | .instance_id'); do
                IDX=$((IDX+1))
                ARGS+=("--ResourceId.$IDX" "$node")
            done
            if [ "$IDX" != "0" ]; then
                aliyun ecs TagResources --region "$ALIBABA_CLOUD_REGION_ID" --ResourceType Instance "${ARGS[@]}" \
                    --Tag.1.Key supportConcurrencyAttach --Tag.1.Value true
                echo "selesai node $(( (PAGE-1)*50+IDX ))/$TOTAL"
            fi
    
            if [[ $(( PAGE*50 )) -ge $TOTAL ]]; then
                break
            fi
            PAGE=$((PAGE+1))
        done
    }
    
    update_addon() {
        local ADDON=$1
        shift
        local CONFIG STATE
        CONFIG=$(aliyun cs GET "/clusters/${CLUSTER_ID}/addon_instances/${ADDON}" | \
            jq -c '.config | fromjson | (.FeatureGate // "" | split(",")) as $fg | .FeatureGate = ($fg + $ARGS.positional | unique | join(",")) | {config: . | tojson}' --args "$@")
    
        aliyun cs POST "/clusters/${CLUSTER_ID}/components/${ADDON}/config" --header "Content-Type=application/json" --body "$CONFIG"
    
        echo "Menunggu konfigurasi $ADDON selesai"
        while true; do
            STATE=$(aliyun --secure cs GET "/clusters/${CLUSTER_ID}/addon_instances/${ADDON}" | jq -r '.state')
            echo "status: $STATE"
            if [ "$STATE" != "updating" ]; then
                break
            fi
            sleep 5
        done
        if [ "$STATE" != "active" ]; then
            echo "Gagal memperbarui konfigurasi $ADDON"
            return 1
        fi
    }
    
    check_version
    
    aliyun cs GET "/clusters/${CLUSTER_ID}/nodepools" | jq -r '.nodepools[]|.nodepool_info|"\(.nodepool_id)\t\(.name)"' | \
    while read -r NODE_POOL_ID NODE_POOL_NAME; do
        echo "Memperbarui tag untuk node pool $NODE_POOL_NAME ($NODE_POOL_ID)"
        update_node_pool "$NODE_POOL_ID"
    done
    
    ALIBABA_CLOUD_REGION_ID=$(aliyun cs GET "/clusters/${CLUSTER_ID}" | jq -r .region_id)
    
    update_nodes
    
    update_addon $PROVISIONER DiskADController=true DiskParallelAttach=true
    update_addon csi-plugin DiskADController=true
    
    echo "Semua selesai! Sekarang disk dapat dipasang secara bersamaan ke node yang sama."
  2. Jalankan skrip untuk memasang disk dalam mode paralel.

    bash enable_parallel_attach.sh <Cluster ID>

Aktifkan fitur secara manual

  1. Tambahkan sebuah ECS tag ke pool node klaster. Atur kunci tag menjadi supportConcurrencyAttach dan nilai tag menjadi true. Pastikan bahwa tag ditambahkan ke instance ECS baru.

    1. Masuk ke konsol ACK. Di panel navigasi di sebelah kiri, klik Clusters.

    2. Di halaman Clusters, temukan klaster yang ingin dikelola dan klik namanya. Di panel navigasi di sebelah kiri, pilih Nodes > Node Pools.

    3. Di halaman Pool Node, temukan pool node yang ingin dimodifikasi dan klik Edit di kolom Actions.

    4. Di bagian bawah halaman, temukan bagian Opsi Lanjutan dan tambahkan sebuah ECS tag. Atur kuncinya menjadi supportConcurrencyAttach dan nilainya menjadi true.

  2. Tambahkan tag ke instance ECS semua node yang ada di klaster. Atur kuncinya menjadi supportConcurrencyAttach dan nilainya menjadi true. Untuk informasi lebih lanjut, lihat Tambahkan Tag Kustom.

  3. Di panel navigasi di sebelah kiri, pilih Operations > Add-ons. Klik tab Storage, temukan komponen csi-provisioner, klik Konfigurasi di sudut kanan bawah komponen, dan atur parameter FeatureGate menjadi DiskADController=true,DiskParallelAttach=true.

    Catatan

    Setelah Anda menentukan DiskADController=true, operasi attach dan detach terkait dengan disk dilakukan oleh csi-provisioner. Setelah Anda menentukan DiskParallelAttach=true, fitur pemasangan disk paralel diaktifkan.

  4. Setelah Anda mengonfigurasi csi-provisioner, atur parameter FeatureGate komponen csi-plugin menjadi DiskADController=true.

Verifikasi bahwa fitur pemasangan disk paralel diaktifkan

Dalam contoh ini, pod dengan sejumlah besar disk yang dipasang dibuat di node yang sama untuk memverifikasi percepatan startup pod setelah pemasangan paralel diaktifkan.

Penting

Statistik yang disediakan dalam topik ini hanya nilai teoretis. Nilai sebenarnya mungkin berbeda berdasarkan lingkungan Anda.

  1. Tambahkan node yang mendukung banyak disk ke klaster ACK. Misalnya, Anda dapat memasang hingga 56 disk ke instance tipe ecs.g7se.16xlarge.

  2. Buat file uji bernama attach-stress.yaml dan salin konten berikut ke file. Ganti attach-stress.yaml dengan nama sebenarnya dari node.

    Lihat File attach-stress.yaml

    ---
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: alibabacloud-disk
    provisioner: diskplugin.csi.alibabacloud.com
    parameters:
      type: cloud_auto
    volumeBindingMode: WaitForFirstConsumer
    reclaimPolicy: Delete
    allowVolumeExpansion: true
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: attach-stress
    spec:
      selector:
        matchLabels:
          app: attach-stress
      serviceName: attach-stress
      replicas: 1
      podManagementPolicy: Parallel
      persistentVolumeClaimRetentionPolicy:
        whenScaled: Retain
        whenDeleted: Delete
      template:
        metadata:
          labels:
            app: attach-stress
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: kubernetes.io/hostname
                    operator: In
                    values:
                    - <YOUR-HOSTNAME> # Ganti parameter ini dengan nama sebenarnya dari node.
          hostNetwork: true
          containers:
          - name: attach-stress
            image: registry-cn-hangzhou.ack.aliyuncs.com/acs/busybox
            command: ["/bin/sh", "-c", "trap exit TERM; while true; do date > /mnt/0/data; sleep 1; done"]
            volumeMounts:
            - name: volume-0
              mountPath: /mnt/0
            - name: volume-1
              mountPath: /mnt/1
      volumeClaimTemplates:
      - metadata:
          name: volume-0
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: alibabacloud-disk
          resources:
            requests:
              storage: 1Gi
      - metadata:
          name: volume-1
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: alibabacloud-disk
          resources:
            requests:
              storage: 1Gi
  3. Jalankan perintah berikut untuk mengonfirmasi bahwa aplikasi mulai seperti yang diharapkan. Kemudian, kurangi jumlah pod menjadi 0 untuk mempersiapkan tes pemasangan batch selanjutnya.

    kubectl apply -f attach-stress.yaml
    kubectl rollout status sts attach-stress
    kubectl scale sts attach-stress --replicas 0

    Output yang Diharapkan:

    storageclass.storage.k8s.io/alibabacloud-disk created
    statefulset.apps/attach-stress created
    partitioned roll out complete: 1 new pods have been updated...
    statefulset.apps/attach-stress scaled
  4. Jalankan perintah berikut untuk memulai tes pemasangan batch dan hitung waktu yang diperlukan untuk memulai pod:

    Catatan

    Dalam kasus ini, pemasangan paralel dinonaktifkan untuk klaster. Sesuaikan jumlah pod untuk tes berdasarkan jumlah maksimum disk yang didukung oleh node Anda.

    date && \
      kubectl scale sts attach-stress --replicas 28 && \
      kubectl rollout status sts attach-stress && \
      date

    Output yang Diharapkan:

    Selasa Oktober 15 19:21:36 CST 2024
    statefulset.apps/attach-stress scaled
    Menunggu 28 pod siap...
    Menunggu 27 pod siap...
    <Dihilangkan...>
    Menunggu 3 pod siap...
    Menunggu 2 pod siap...
    Menunggu 1 pod siap...
    partitioned roll out complete: 28 new pods have been updated...
    Selasa Oktober 15 19:24:55 CST 2024

    Output menunjukkan bahwa lebih dari 3 menit diperlukan untuk memulai semua 28 pod ketika pemasangan paralel dinonaktifkan.

  5. Aktifkan pemasangan paralel dengan mengikuti petunjuk di bagian Prosedur.

  6. Jalankan perintah berikut untuk menghapus pod sebelumnya dan mempersiapkan putaran pengujian berikutnya:

    Catatan

    Perhatikan sumber daya volumeattachments di klaster. Setelah sumber daya dihapus, disk dilepas. Proses ini membutuhkan beberapa menit.

    kubectl scale sts attach-stress --replicas 0
  7. Jalankan perintah berikut lagi untuk menghitung waktu yang diperlukan untuk memulai pod setelah pemasangan paralel diaktifkan. Waktu yang diharapkan adalah sekitar 40 detik, yang jauh lebih cepat daripada 3 menit ketika pemasangan paralel dinonaktifkan.

    date && \
      kubectl scale sts attach-stress --replicas 28 && \
      kubectl rollout status sts attach-stress && \
      date

    Output yang Diharapkan:

    Selasa Oktober 15 20:02 54 CST 2024
    statefulset.apps/attach-stress scaled
    Menunggu 28 pod siap...
    Menunggu 27 pod siap...
    <Dihilangkan...>
    Menunggu 3 pod siap...
    Menunggu 2 pod siap...
    Menunggu 1 pod siap...
    partitioned roll out complete: 28 new pods have been updated...
    Selasa Oktober 15 20:03:31 CST 2024
  1. Jalankan perintah berikut untuk menghapus aplikasi uji di klaster:

    kubectl delete -f attach-stress.yaml