Activer le chargement d'images de conteneur paresseux dans Oracle Cloud Infrastructure Kubernetes Engine (OKE) à l'aide du magasin Stargz

Présentation

Le chargement d'image de conteneur paresseux (parfois appelé extraction paresseuse ou chargement d'image à la demande) est une technique qui permet à un conteneur de commencer à fonctionner avant le téléchargement de l'image complète. Seules les parties de l'image nécessaires à l'exécution sont extraites, ce qui réduit le temps de démarrage, en particulier pour les images volumineuses.

Normalement, lorsque vous exécutez un conteneur :

  1. Le module d'exécution du conteneur (par exemple, CRI-O, containerd) télécharge l'image entière à partir du registre.
  2. Il dépile toutes les couches d'image.
  3. Ce n'est qu'après le téléchargement et le déballage de toutes les couches que le conteneur démarre.

Avec chargement paresseux :

  1. Le conteneur démarre immédiatement à l'aide d'un système de fichiers virtuel (l'image n'est pas encore présente localement).
  2. Lorsque l'application accède à un fichier, l'exécution extrait à la demande uniquement le contenu requis du registre distant.
  3. Les fichiers supplémentaires ne sont téléchargés que lorsqu'ils sont réellement utilisés.
  4. L'image complète du conteneur est extraite en arrière-plan.

Les images de conteneur doivent être reconditionnées pour prendre en charge le chargement différé. En utilisant le format eStargz, l'image est reconditionnée en petits morceaux décompressibles indépendamment. Cela permet au module d'exécution du conteneur d'extraire uniquement les fragments nécessaires au démarrage du conteneur.

Les images eStargz contiennent un fichier spécial appelé table des matières (TOC), qui enregistre les métadonnées (par exemple, nom, type de fichier, propriétaires, décalage) de toutes les entrées de fichier dans la couche eStargz, à l'exception de la table des matières elle-même. Les environnements d'exécution de conteneur peuvent utiliser la table des matières pour monter le système de fichiers du conteneur sans télécharger le contenu complet de la couche.

Ce tutoriel explique comment :

  1. Remballer une image de conteneur existante pour utiliser le format Stargz
  2. Configurer l'interface de ligne de commande d'Oracle Cloud Infrastructure Kubernetes Engine (OKE) pour utiliser le plugiciel du magasin Stargz
  3. Exécuter un exemple de charge globale pour démontrer les améliorations du temps de démarrage du conteneur

Conditions requises

Configuration

Recréez l'image du conteneur à l'aide de nerdctl pour utiliser le format eStargz

  1. Créez un référentiel d'images dans le registre OCI (OCIR). Dans ce tutoriel, tenancy-namespace est idxzjcdxqj et nous allons créer un repo nommé vllm/vllm-openai.

    Référentiel OCIR

    Vous pouvez suivre ces instructions pour vous authentifier auprès d'OCIR et créer un référentiel : Transmission d'images à l'aide de l'interface de ligne de commande Docker.

    Veillez à remplacer iad.ocir.io par le domaine OCIR de la région OCI sur laquelle vous travaillez. Voici la liste des clés de région.

    docker login iad.ocir.io
  2. Téléchargez la dernière version de nerdctl sur la machine sur laquelle Docker est installé.

    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. Authentifiez nerdctl vers OCIR.

    ./nerdctl login iad.ocir.io
  4. Convertissez l'image du conteneur vllm au format 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. Pousser l'image de conteneur vllm eStargz vers OCIR.

    ./nerdctl image push iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-esgz
  6. Vous pouvez utiliser docker pour extraire/pousser l'image normale vers OCIR à l'aide de 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

Installer le plugiciel Stargz Store sur les noeuds OKE

Considérant qu'OKE utilise CRI-O, nous devons configurer le plugin Stargz Store. Il s'agit d'une mise en oeuvre d'un plugiciel de magasin de couches supplémentaire pour CRI-O/Podman. Stargz Store fournit des couches eStargz montées à distance à CRI-O/Podman.

  1. Accédez par SSH à l'un des noeuds de travail et téléchargez la dernière version à partir de la page Github de stargz-snapshotter.

    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. Extraire la valeur stargz-store à /usr/local/bin.

    tar -C /usr/local/bin -xvf stargz-snapshotter-v0.18.2-linux-amd64.tar.gz stargz-store
  3. Mettez à jour le fichier /etc/containers/storage.conf pour inclure additionallayerstores dans la section [storage.options].

    [storage]
    driver = "overlay"
    graphroot = "/var/lib/containers/storage"
    runroot = "/run/containers/storage"
    
    [storage.options]
    additionallayerstores = ["/var/lib/stargz-store/store:ref"]
  4. Assurez-vous que fuse est installé et chargé.

    apt-get install fuse
    modprobe fuse
  5. Activez le service 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. Vérifiez que les services crio et stargz-store sont en cours d'exécution.

    systemctl status stargz-store
    systemctl status crio

Évaluer la performance

  1. Mettez à jour nodeName et image dans le manifeste ci-dessous et créez les déploiements de 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. Surveillez l'heure de début du conteneur.

    kubectl get pods -w
  3. Nettoyer les ressources.

    kubectl delete deploy test-regular-cpu
    kubectl delete deploy test-estargz-cpu
  4. Pour un déploiement de test à l'aide du GPU, mettez à jour nodeName et image dans ce manifeste yaml et appliquez-le à l'aide de la commande ci-dessous :

    kubectl apply -f test-manifest-gpu.yaml

résultats

Les résultats suivants sont basés sur des tests exécutés sur une forme BM.GPU4.8 à l'aide d'un modèle de langage de paramètres 30B volumineux.

  1. L'heure de début du pod est 33s pour eStargz et 4m pour l'image standard.

    $ 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'application démarre sur le pod à l'aide de l'image eStargz dans 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'application démarre sur le pod à l'aide de l'image standard dans 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. Le pod utilisant l'image eStargz est prêt à desservir le trafic 1m22s plus rapidement que le pod standard.

Conclusions

La mise en œuvre de l'extraction d'images paresseuses à l'aide du format eStargz dans OKE démontre des améliorations significatives du temps d'initialisation des pods, réduisant le démarrage des conteneurs de 4 minutes à seulement 33 secondes, soit une réduction de 87%. Alors que le temps d'initialisation de l'application dans le conteneur eStargz prend environ 1 minute de plus que l'image normale (1m27s contre 32s), le temps total de préparation est encore 1m22s plus rapide, rendant le pod disponible pour le trafic plus rapidement. Ce compromis s'avère particulièrement utile dans les environnements de production où la mise à l'échelle rapide, la reprogrammation des pods ou les démarrages à froid sont critiques, car la réduction substantielle du temps d'extraction initial des conteneurs l'emporte sur la légère augmentation des frais généraux de démarrage des applications. Pour les charges de travail utilisant des images de conteneur volumineuses, en particulier les charges de travail d'IA, l'extraction paresseuse avec eStargz offre une solution pratique pour accélérer le déploiement sans nécessiter de modifications du code d'application ou d'importantes modifications d'infrastructure.

  1. Documentation d'installation de Stargz Snapshotter
  2. Expérimentation de l'extraction de l'image eStargz sur OpenShift
  3. documentation sur nerdctl Stargz

Remerciements

Ressources d'apprentissage supplémentaires

Explorez d'autres laboratoires sur le site docs.oracle.com/learn ou accédez à plus de contenu d'apprentissage gratuit sur la chaîne YouTube d'Oracle Learning. De plus, visitez education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.

Pour obtenir la documentation sur le produit, visitez Oracle Help Center.