Activation du chargement d'images de conteneur paresseux dans Oracle Cloud Infrastructure Kubernetes Engine (OKE) à l'aide de la banque Stargz

Introduction

Le chargement d'images de conteneur paresseux (parfois appelé tirage paresseux ou chargement d'images à la demande) est une technique qui permet à un conteneur de commencer à s'exécuter 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. L'exécution de conteneur (par exemple, CRI-O, containerd) télécharge l'image entière à partir du registre.
  2. Il déballe toutes les couches d'image.
  3. Une fois toutes les couches téléchargées et décompressées, 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 uniquement le contenu requis du registre distant à la demande.
  3. Les fichiers supplémentaires sont téléchargés uniquement 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 paresseux. En utilisant le format eStargz, l'image est reconditionnée en petits morceaux décompressibles indépendamment. Cela permet au conteneur d'exécuter uniquement les blocs nécessaires au démarrage du conteneur.

Les images eStargz contiennent un fichier spécial appelé table des matières, 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 exécutions de conteneur peuvent utiliser la table des matières pour monter le système de fichiers du conteneur sans télécharger l'intégralité du contenu de la couche.

Dans ce tutoriel, vous allez apprendre à :

  1. Recompiler une image de conteneur existante pour utiliser le format Stargz
  2. Configurer Oracle Cloud Infrastructure Kubernetes Engine (OKE) CRI-O pour utiliser le module d'extension de banque Stargz
  3. Exécuter un exemple de charge globale pour illustrer les améliorations du temps de démarrage du conteneur

Prérequis

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 OCI Registry (OCIR). Dans ce tutoriel, tenancy-namespace est idxzjcdxqj et nous allons créer un élément 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 l'ordinateur sur lequel 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 sur 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. Poussez l'image du conteneur eStargz vllm vers OCIR.

    ./nerdctl image push iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-esgz
  6. Vous pouvez utiliser docker pour extraire/envoyer l'image standard 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

Installation du module d'extension Stargz Store sur les noeuds OKE

Étant donné qu'OKE utilise CRI-O, nous devons configurer le plugin Stargz Store. Il s'agit d'une implémentation d'un module d'extension de stockage de couches supplémentaire pour CRI-O/Podman. Stargz Store fournit des couches eStargz montées à distance au CRI-O/Podman.

  1. Connectez-vous via SSH à l'un des noeuds de processus actif 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. Extrayez stargz-store vers /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

Evaluer 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. Nettoyez les ressources.

    kubectl delete deploy test-regular-cpu
    kubectl delete deploy test-estargz-cpu
  4. Pour un déploiement de test utilisant le 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 grand modèle de langage avec paramètres 30B.

  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 en utilisant 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

L'implémentation de l'extraction d'images paresseuses au format eStargz dans OKE démontre des améliorations significatives du temps d'initialisation du pod, réduisant ainsi le démarrage du conteneur 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 standard (1m27s vs 32s), le temps total de préparation est encore 1m22s plus rapide, ce qui rend 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 replanification des pods ou les démarrages à froid sont essentiels, car la réduction substantielle du temps d'extraction initial des conteneurs l'emporte sur la modeste 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 des applications ou d'importantes modifications de l'infrastructure.

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

Accusés de réception

Ressources de formation supplémentaires

Explorez d'autres ateliers sur docs.oracle.com/learn ou accédez à d'autres contenus d'apprentissage gratuits sur la chaîne YouTube Oracle Learning. En outre, visitez le site education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.

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