Abilita caricamento immagine contenitore ritardato in Oracle Cloud Infrastructure Kubernetes Engine (OKE) mediante l'area di memorizzazione Stargz

Introduzione

Il caricamento pigro dell'immagine del contenitore (a volte chiamato lazy pulling o caricamento on-demand dell'immagine) è una tecnica che consente a un contenitore di iniziare a funzionare prima che l'immagine completa venga scaricata. Vengono recuperate solo le parti dell'immagine necessarie in fase di esecuzione, riducendo i tempi di avvio, soprattutto per le immagini di grandi dimensioni.

Normalmente, quando si esegue un contenitore:

  1. Il runtime del contenitore (ad esempio, CRI-O, containerd) scarica l'intera immagine dal registro.
  2. Disimballa tutti i livelli di immagine.
  3. Solo dopo che tutti i livelli sono stati scaricati e decompressi, il contenitore viene avviato.

Con caricamento pigro:

  1. Il contenitore inizia immediatamente, utilizzando un file system virtuale (l'immagine non è ancora presente localmente).
  2. Quando l'applicazione accede a un file, il runtime recupera solo il contenuto richiesto dal registro remoto su richiesta.
  3. I file aggiuntivi vengono scaricati solo se effettivamente utilizzati.
  4. L'immagine completa del contenitore viene estratta in background.

Le immagini dei container devono essere riconfezionate per supportare il caricamento pigro. Utilizzando il formato eStargz, l'immagine viene riconfezionata in piccoli pezzi decomprimibili in modo indipendente. Ciò consente al runtime del contenitore di recuperare solo i blocchi necessari all'avvio del contenitore.

Le immagini eStargz contengono un file speciale chiamato sommario (TOC), che registra i metadati (ad esempio nome, tipo di file, proprietari, offset) di tutte le voci di file nel livello eStargz, ad eccezione del sommario stesso. I runtime dei container possono utilizzare il sommario per eseguire il MOUNT del file system del contenitore senza scaricare l'intero contenuto del layer.

In questo tutorial, imparerai come:

  1. Reimballare un'immagine contenitore esistente per utilizzare il formato Stargz
  2. Configurare CRI-O di Oracle Cloud Infrastructure Kubernetes Engine (OKE) per utilizzare il plugin Stargz Store
  3. Eseguire un carico di lavoro di esempio per dimostrare i miglioramenti apportati all'ora di avvio del contenitore

Prerequisiti

Impostazione

Ricreare l'immagine del contenitore utilizzando nerdctl per utilizzare il formato eStargz

  1. Creare un repository di immagini in OCI Registry (OCIR). In questo tutorial, il tenancy-namespace è idxzjcdxqj e creeremo un repo denominato vllm/vllm-openai.

    Repository OCIR

    Per eseguire l'autenticazione a OCIR e creare un nuovo repository, attenersi alle istruzioni riportate di seguito. Push delle immagini mediante l'interfaccia CLI Docker.

    Assicurarsi di sostituire iad.ocir.io con il dominio OCIR dell'area OCI su cui si sta lavorando. Ecco una lista di chiavi area.

    docker login iad.ocir.io
  2. Scaricare la versione più recente di nerdctl sul computer con Docker installato.

    export NERDCTL_VERSION=2.2.2
    wget https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz
    tar -xf nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz
  3. Autenticare nerdctl in OCIR.

    ./nerdctl login iad.ocir.io
  4. Convertire l'immagine del contenitore vllm nel formato eStargz.

    ./nerdctl image convert --estargz --oci docker.io/vllm/vllm-openai:v0.11.0 iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-esgz
  5. Spingere l'immagine del contenitore vllm eStargz a OCIR.

    ./nerdctl image push iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-esgz
  6. È possibile utilizzare il docker per estrarre/spingere l'immagine normale su OCIR utilizzando il docker.

    docker image pull docker.io/vllm/vllm-openai:v0.11.0
    docker image tag docker.io/vllm/vllm-openai:v0.11.0 iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-regular
    docker image push iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-regular

Installa plugin negozio Stargz sui nodi OKE

Considerando che OKE utilizza CRI-O, è necessario impostare il plugin Stargz Store. Questa è un'implementazione di un plugin aggiuntivo per layer store per CRI-O/Podman. Stargz Store fornisce livelli eStargz montati in remoto a CRI-O/Podman.

  1. Eseguire l'accesso SSH a uno dei nodi di lavoro e scaricare la versione più recente dalla pagina Github dello snapshot stargz.

    export STARGZ_SNAPSHOTTER_VERSION=v0.18.2
    wget https://github.com/containerd/stargz-snapshotter/releases/download/${STARGZ_SNAPSHOTTER_VERSION}/stargz-snapshotter-${STARGZ_SNAPSHOTTER_VERSION}-linux-amd64.tar.gz
  2. Estrarre il valore stargz-store in /usr/local/bin.

    tar -C /usr/local/bin -xvf stargz-snapshotter-v0.18.2-linux-amd64.tar.gz stargz-store
  3. Aggiornare il file /etc/containers/storage.conf per includere additionallayerstores nella sezione [storage.options].

    [storage]
    driver = "overlay"
    graphroot = "/var/lib/containers/storage"
    runroot = "/run/containers/storage"
    
    [storage.options]
    additionallayerstores = ["/var/lib/stargz-store/store:ref"]
  4. Assicurarsi che fuse sia installato e caricato.

    apt-get install fuse
    modprobe fuse
  5. Abilitare il servizio stargz-store.

    wget -O /etc/systemd/system/stargz-store.service https://raw.githubusercontent.com/containerd/stargz-snapshotter/main/script/config-cri-o/etc/systemd/system/stargz-store.service
    systemctl daemon-reload
    systemctl restart stargz-store crio
  6. Verificare che i servizi crio e stargz-store siano in esecuzione.

    systemctl status stargz-store
    systemctl status crio

Valuta le prestazioni

  1. Aggiornare nodeName e image nel file manifesto seguente e creare le distribuzioni di test:

    kubectl apply -f - <<EOF
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: test-estargz-cpu
      namespace: default
      labels:
        app: test-estargz
    spec:
      strategy:
        type: Recreate
      replicas: 1
      selector:
        matchLabels:
          app: test-estargz
      template:
        metadata:
          labels:
            app: test-estargz
        spec:
          containers:
            ## Update the image to your own container repository
          - image: iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-esgz
            name: test
            command: ["/bin/bash", "-c", "echo started && sleep infinity"]
          ## Replace the nodename with the name of the node where stargz-store is configured.
          nodeName: 10.140.34.52
          tolerations:
          - key: nvidia.com/gpu
            operator: Exists
            effect: NoSchedule
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: test-regular-cpu
      namespace: default
      labels:
        app: test-regular
    spec:
      strategy:
        type: Recreate
      replicas: 1
      selector:
        matchLabels:
          app: test-regular
      template:
        metadata:
          labels:
            app: test-regular
        spec:
          containers:
            ## Update the image to your own container repository
          - image: iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-regular
            name: test
            command: ["/bin/bash", "-c", "echo started && sleep infinity"]
            env:
            - name: HF_HOME
              value: "/workspace"
          ## Replace the nodename with the name of the node where stargz-store is configured.
          nodeName: 10.140.34.52
          tolerations:
          - key: nvidia.com/gpu
            operator: Exists
            effect: NoSchedule
    EOF
  2. Monitorare l'ora di inizio del contenitore.

    kubectl get pods -w
  3. Eseguire il cleanup delle risorse.

    kubectl delete deploy test-regular-cpu
    kubectl delete deploy test-estargz-cpu
  4. Per una distribuzione di test che utilizza la GPU, aggiornare nodeName e image in questo file manifesto yaml e applicarlo utilizzando il comando riportato di seguito.

    kubectl apply -f test-manifest-gpu.yaml

Risultati

I seguenti risultati si basano su test eseguiti su una forma BM.GPU4.8 utilizzando un modello di linguaggio di grandi dimensioni con parametri 30B.

  1. L'ora di inizio del pod è 33s per eStargz e 4m per l'immagine regolare.

    $ kubectl get pods -w
    NAME                            READY   STATUS              RESTARTS   AGE
    test-estargz-5699988945-2zxmh   0/1     ContainerCreating   0          8s
    test-regular-55fbdf64c8-hn6hg   0/1     ContainerCreating   0          7s
    test-estargz-5699988945-2zxmh   1/1     Running             0          33s
    test-regular-55fbdf64c8-hn6hg   1/1     Running             0          4m
  2. L'applicazione viene avviata sul pod utilizzando l'immagine eStargz in 1m27s.

    INFO 12-11 07:59:02 [__init__.py:216] Automatically detected platform cuda.
    (APIServer pid=1) INFO 12-11 07:59:26 [api_server.py:1839] vLLM API server version 0.11.0
    (APIServer pid=1) INFO 12-11 07:59:26 [utils.py:233] non-default args: {'model_tag': 'cpatonn/Qwen3-30B-A3B-Instruct-2507-AWQ-4bit', 'max_model_len': 8192, 'enforce_eager': True}
    ...
    (APIServer pid=1) INFO 12-11 08:00:29 [launcher.py:42] Route: /metrics, Methods: GET
    (APIServer pid=1) INFO:     Started server process [1]
    (APIServer pid=1) INFO:     Waiting for application startup.
    (APIServer pid=1) INFO:     Application startup complete.
  3. L'applicazione viene avviata sul pod utilizzando l'immagine normale in 32s.

    INFO 12-11 08:01:19 [__init__.py:216] Automatically detected platform cuda.
    (APIServer pid=1) INFO 12-11 08:01:22 [api_server.py:1839] vLLM API server version 0.11.0
    (APIServer pid=1) INFO 12-11 08:01:22 [utils.py:233] non-default args: {'model_tag': 'cpatonn/Qwen3-30B-A3B-Instruct-2507-AWQ-4bit', 'max_model_len': 8192, 'enforce_eager': True}
    ...
    (APIServer pid=1) INFO 12-11 08:01:51 [launcher.py:42] Route: /metrics, Methods: GET
    (APIServer pid=1) INFO:     Started server process [1]
    (APIServer pid=1) INFO:     Waiting for application startup.
    (APIServer pid=1) INFO:     Application startup complete.
  4. Il pod che utilizza l'immagine eStargz è pronto a servire il traffico 1m22s più velocemente di quello normale.

Conclusioni

L'implementazione del pull di immagini pigre utilizzando il formato eStargz in OKE dimostra miglioramenti significativi nel tempo di inizializzazione dei pod, riducendo l'avvio dei container da 4 minuti a soli 33 secondi, una riduzione dell'87%. Mentre il tempo di inizializzazione dell'applicazione all'interno del contenitore eStargz richiede circa 1 minuto in più rispetto all'immagine normale (1m27s vs 32s), il tempo complessivo per lo stato pronto è ancora 1m22s più veloce, rendendo il pod disponibile per il traffico più rapidamente. Questo trade-off si rivela particolarmente prezioso negli ambienti di produzione in cui la rapida scalabilità, la riprogrammazione dei pod o l'avvio a freddo sono fondamentali, poiché la sostanziale riduzione dei tempi di pull iniziale dei container supera il modesto aumento del sovraccarico di avvio delle applicazioni. Per i carichi di lavoro che utilizzano immagini di container di grandi dimensioni, in particolare i carichi di lavoro AI, il lazy pulling con eStargz offre una soluzione pratica per accelerare lo sviluppo senza richiedere modifiche al codice dell'applicazione o modifiche significative all'infrastruttura.

  1. Documentazione sull'installazione di Stargz Snapshotter
  2. Sperimentare con l'immagine eStargz su OpenShift
  3. documentazione di nerdctl Stargz

Conferme

Altre risorse di apprendimento

Esplora altri laboratori su docs.oracle.com/learn o accedi a più contenuti di formazione gratuiti sul canale YouTube di Oracle Learning. Inoltre, visitare education.oracle.com/learning-explorer per diventare Oracle Learning Explorer.

Per la documentazione del prodotto, visitare Oracle Help Center.