Habilite o Carregamento de Imagem de Contêiner Preguiçoso no Oracle Cloud Infrastructure Kubernetes Engine (OKE) Usando o Stargz Store

Introdução

O carregamento de imagem de contêiner preguiçoso (às vezes chamado de puxar preguiçoso ou carregamento de imagem sob demanda) é uma técnica que permite que um contêiner comece a ser executado antes que a imagem completa seja baixada. Somente as partes da imagem necessárias no tempo de execução são extraídas, reduzindo o tempo de inicialização, especialmente para imagens grandes.

Normalmente, quando você executa um contêiner:

  1. O tempo de execução do contêiner (por exemplo, CRI-O, containerd) baixa toda a imagem do registro.
  2. Descompacta todas as camadas de imagem.
  3. Somente depois que todas as camadas são baixadas e descompactadas, o contêiner é iniciado.

Com carga preguiçosa:

  1. O contêiner é iniciado imediatamente, usando um sistema de arquivos virtual (a imagem ainda não está presente localmente).
  2. Quando o aplicativo acessa um arquivo, o runtime extrai apenas o conteúdo necessário do registro remoto sob demanda.
  3. Arquivos adicionais são baixados somente quando realmente usados.
  4. A imagem completa do contêiner é extraída em segundo plano.

As imagens do contêiner precisam ser reembaladas para suportar o carregamento lento. Usando o formato eStargz, a imagem é reempacotada em pedaços pequenos e descompactáveis independentemente. Isso permite que o runtime do contêiner extraia apenas os blocos necessários quando o contêiner é iniciado.

As imagens eStargz contêm um arquivo especial chamado TOC (Table of Contents), que registra metadados (por exemplo, nome, tipo de arquivo, proprietários, deslocamento) de todas as entradas de arquivo na camada eStargz, exceto o próprio TOC. Os tempos de execução do contêiner podem usar o TOC para montar o sistema de arquivos do contêiner sem fazer download de todo o conteúdo da camada.

Neste tutorial, você aprenderá a:

  1. Reembalar uma imagem de contêiner existente para usar o formato Stargz
  2. Configurar o CRI-O do Oracle Cloud Infrastructure Kubernetes Engine (OKE) para usar o plug-in Stargz Store
  3. Execute uma carga de trabalho de amostra para demonstrar as melhorias no tempo de inicialização do contêiner

Pré-requisitos

Configurar

Recriar a imagem do contêiner usando nerdctl para usar o formato eStargz

  1. Crie um repositório de imagens no OCI Registry (OCIR). Neste tutorial, o tenancy-namespace é idxzjcdxqj e criaremos um repo chamado vllm/vllm-openai.

    Repositório do OCIR

    Você pode seguir estas instruções para se autenticar no OCIR e criar um novo repositório: Enviando Imagens Usando a CLI do Docker.

    Certifique-se de substituir o iad.ocir.io pelo domínio do OCIR da região do OCI na qual você está trabalhando. Aqui está uma lista das chaves de região.

    docker login iad.ocir.io
  2. Faça download da versão mais recente de nerdctl na máquina com o 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 no OCIR.

    ./nerdctl login iad.ocir.io
  4. Converta a imagem do contêiner vllm para o 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. Envie a imagem do contêiner eStargz vllm para o OCIR.

    ./nerdctl image push iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-esgz
  6. Você pode usar o docker para extrair/enviar a imagem regular para o OCIR usando o 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

Instalar o Plug-in de Armazenamento Stargz nos Nós do OKE

Considerando que o OKE usa CRI-O, precisamos configurar o plug-in Stargz Store. Esta é uma implementação de um plug-in adicional de armazenamento de camadas para CRI-O/Podman. A Stargz Store fornece camadas eStargz remotamente montadas para CRI-O/Podman.

  1. Conecte-se via SSH a um dos nós de trabalho e faça download da versão mais recente na 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. Extraia o stargz-store para /usr/local/bin.

    tar -C /usr/local/bin -xvf stargz-snapshotter-v0.18.2-linux-amd64.tar.gz stargz-store
  3. Atualize o arquivo /etc/containers/storage.conf para incluir o additionallayerstores na seção [storage.options].

    [storage]
    driver = "overlay"
    graphroot = "/var/lib/containers/storage"
    runroot = "/run/containers/storage"
    
    [storage.options]
    additionallayerstores = ["/var/lib/stargz-store/store:ref"]
  4. Certifique-se de que fuse esteja instalado e carregado.

    apt-get install fuse
    modprobe fuse
  5. Ative o serviço 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 se os serviços crio e stargz-store estão em execução.

    systemctl status stargz-store
    systemctl status crio

Avaliar o desempenho

  1. Atualize o nodeName e o image no manifesto abaixo e crie as implantações de teste:

    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. Monitore a hora de início do recipiente.

    kubectl get pods -w
  3. Limpar recursos.

    kubectl delete deploy test-regular-cpu
    kubectl delete deploy test-estargz-cpu
  4. Para uma implantação de teste usando a GPU, atualize o nodeName e o image neste manifesto yaml e aplique-o usando o comando abaixo:

    kubectl apply -f test-manifest-gpu.yaml

Resultados

Os resultados a seguir são baseados em testes executados em uma forma BM.GPU4.8 usando um modelo de linguagem grande de 30B parâmetros.

  1. O horário inicial do pod é 33s para eStargz e 4m para imagem regular.

    $ 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. O aplicativo é iniciado no pod usando a imagem eStargz no 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. O aplicativo é iniciado no pod usando a imagem regular em 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. O pod que usa a imagem eStargz está pronto para atender ao tráfego 1m22s mais rápido que o normal.

Conclusões

A implementação da extração de imagem preguiçosa usando o formato eStargz no OKE demonstra melhorias significativas no tempo de inicialização do pod, reduzindo a inicialização do contêiner de 4 minutos para apenas 33 segundos, uma redução de 87%. Enquanto o tempo de inicialização do aplicativo dentro do contêiner eStargz leva aproximadamente 1 minuto a mais do que a imagem normal (1m27s vs 32s), o tempo geral para o estado pronto ainda é 1m22s mais rápido, tornando o pod disponível para o tráfego mais rapidamente. Esse trade-off se mostra particularmente valioso em ambientes de produção em que escalonamento rápido, reprogramação de pods ou partidas a frio são críticos, pois a redução substancial no tempo de extração inicial do contêiner supera o aumento modesto na sobrecarga de inicialização de aplicativos. Para cargas de trabalho que usam imagens de contêiner grandes, especialmente cargas de trabalho de IA, a extração preguiçosa com o eStargz oferece uma solução prática para acelerar a implementação sem exigir alterações no código do aplicativo ou modificações significativas na infraestrutura.

  1. Documentação de instalação do Stargz Snapshotter
  2. Experimentando com a extração de imagem eStargz no OpenShift
  3. nerdctl Documentação do Stargz

Confirmações

Mais Recursos de Aprendizado

Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal do Oracle Learning no YouTube. Além disso, acesse education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.

Para obter a documentação do produto, visite o Oracle Help Center.