Activación de la carga lenta de imágenes de contenedor en Oracle Cloud Infrastructure Kubernetes Engine (OKE) mediante Stargz Store

Introducción

La carga lenta de imágenes de contenedor (a veces llamada extracción lenta o carga de imágenes bajo demanda) es una técnica que permite que un contenedor comience a ejecutarse antes de descargar la imagen completa. Solo se recuperan las partes de la imagen que se necesitan en tiempo de ejecución, lo que reduce el tiempo de inicio, especialmente para imágenes grandes.

Normalmente, cuando se ejecuta un contenedor:

  1. El tiempo de ejecución del contenedor (por ejemplo, CRI-O, containerd) descarga toda la imagen del registro.
  2. Desempaqueta todas las capas de imagen.
  3. Solo después de descargar y desempaquetar todas las capas se inicia el contenedor.

Con carga perezosa:

  1. El contenedor se inicia inmediatamente mediante un sistema de archivos virtual (la imagen aún no está presente localmente).
  2. Cuando la aplicación accede a un archivo, el tiempo de ejecución recupera solo el contenido necesario del registro remoto bajo demanda.
  3. Los archivos adicionales se descargan solo cuando se utilizan realmente.
  4. La imagen completa del contenedor se extrae en el fondo.

Es necesario volver a empaquetar las imágenes del contenedor para soportar la carga lenta. Utilizando el formato eStargz, la imagen se vuelve a empaquetar en trozos pequeños y descompresibles de forma independiente. Esto permite que el tiempo de ejecución del contenedor recupere solo los fragmentos necesarios cuando se inicia el contenedor.

Las imágenes de eStargz contienen un archivo especial llamado TOC (Tabla de Contenido), que registra metadatos (por ejemplo, nombre, tipo de archivo, propietarios, desplazamiento) de todas las entradas de archivo en la capa de eStargz, excepto el propio TOC. Los tiempos de ejecución del contenedor pueden utilizar la tabla de contenido para montar el sistema de archivos del contenedor sin descargar todo el contenido de la capa.

En este tutorial, aprenderá a:

  1. Reempaquetar una imagen de contenedor existente para utilizar el formato Stargz
  2. Configurar Oracle Cloud Infrastructure Kubernetes Engine (OKE) CRI-O para utilizar el plugin de Stargz Store
  3. Ejecutar una carga de trabajo de ejemplo para demostrar las mejoras en el tiempo de inicio del contenedor

Requisitos

Configuración

Reconstruir la imagen de contenedor mediante nerdctl para utilizar el formato eStargz

  1. Cree un repositorio de imágenes en OCI Registry (OCIR). En este tutorial, tenancy-namespace es idxzjcdxqj y crearemos un repo denominado vllm/vllm-openai.

    Repositorio de OCIR

    Puede seguir estas instrucciones para autenticarse en OCIR y crear un nuevo repositorio: Transferencia de imágenes mediante la CLI de Docker.

    Asegúrese de sustituir iad.ocir.io por el dominio de OCIR de la región de OCI en la que está trabajando. Aquí se muestra una lista de las claves de región.

    docker login iad.ocir.io
  2. Descargue la última versión de nerdctl en la máquina con Docker instalado.

    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. Autenticar nerdctl en OCIR.

    ./nerdctl login iad.ocir.io
  4. Convierta la imagen del contenedor vllm al 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. Transfiera la imagen del contenedor vllm de eStargz a OCIR.

    ./nerdctl image push iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-esgz
  6. Puede utilizar docker para extraer/empujar la imagen normal a OCIR mediante 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

Instalación del plugin de la tienda Stargz en los nodos de OKE

Teniendo en cuenta que OKE utiliza CRI-O, necesitamos configurar el plugin de Stargz Store. Se trata de una implementación de un plugin de almacenamiento de capas adicional para CRI-O/Podman. Stargz Store proporciona capas de eStargz montadas de forma remota a CRI-O/Podman.

  1. Utilice SSH en uno de los nodos de trabajador y descargue la última versión de la página Stargz-snapshotter Github.

    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. Extraiga stargz-store a /usr/local/bin.

    tar -C /usr/local/bin -xvf stargz-snapshotter-v0.18.2-linux-amd64.tar.gz stargz-store
  3. Actualice el archivo /etc/containers/storage.conf para incluir additionallayerstores en la sección [storage.options].

    [storage]
    driver = "overlay"
    graphroot = "/var/lib/containers/storage"
    runroot = "/run/containers/storage"
    
    [storage.options]
    additionallayerstores = ["/var/lib/stargz-store/store:ref"]
  4. Asegúrese de que fuse esté instalado y cargado.

    apt-get install fuse
    modprobe fuse
  5. Active el servicio 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. Confirme que los servicios crio y stargz-store se están ejecutando.

    systemctl status stargz-store
    systemctl status crio

Evaluar el rendimiento

  1. Actualice nodeName y image en el manifiesto que aparece a continuación y cree los despliegues de prueba:

    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. Supervise la hora de inicio del contenedor.

    kubectl get pods -w
  3. Limpiar recursos.

    kubectl delete deploy test-regular-cpu
    kubectl delete deploy test-estargz-cpu
  4. Para un despliegue de prueba mediante la GPU, actualice nodeName y image en este manifiesto de yaml y aplíquelo mediante el siguiente comando:

    kubectl apply -f test-manifest-gpu.yaml

Resultados

Los siguientes resultados se basan en pruebas ejecutadas en una unidad BM.GPU4.8 con un modelo de lenguaje grande de parámetros 30B.

  1. La hora de inicio del pod es 33s para eStargz y 4m para la imagen normal.

    $ 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. La aplicación se inicia en el pod mediante la imagen de eStargz en 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. La aplicación se inicia en el pod mediante la imagen normal en 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. El pod que utiliza la imagen de eStargz está listo para servir al tráfico 1m22s más rápido que el normal.

Conclusiones

La implementación de la extracción de imágenes perezosas utilizando el formato eStargz en OKE demuestra mejoras significativas en el tiempo de inicialización del pod, reduciendo el inicio del contenedor de 4 minutos a solo 33 segundos, una reducción del 87%. Mientras que el tiempo de inicialización de la aplicación en el contenedor eStargz tarda aproximadamente 1 minuto más que la imagen normal (1m27s frente a 32s), el tiempo general hasta el estado de lista sigue siendo 1m22s más rápido, lo que hace que el pod esté disponible para el tráfico más rápidamente. Esta compensación resulta particularmente valiosa en entornos de producción donde la escalabilidad rápida, la reprogramación de pods o los inicios en frío son críticos, ya que la reducción sustancial del tiempo de extracción inicial del contenedor supera el modesto aumento de la sobrecarga de inicio de aplicaciones. Para las cargas de trabajo que utilizan imágenes de contenedor de gran tamaño, especialmente las cargas de trabajo de IA, la extracción lenta con eStargz ofrece una solución práctica para acelerar el despliegue sin necesidad de realizar cambios en el código de la aplicación ni realizar modificaciones significativas de la infraestructura.

  1. Documentación de instalación de Stargz Snapshotter
  2. Experimentando con la imagen de eStargz tirando en OpenShift
  3. documentación de nerdctl Stargz

Acuses de recibo

Más recursos de aprendizaje

Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal de YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en un explorador de Oracle Learning.

Para obtener documentación sobre el producto, visite Oracle Help Center.