Lazy Container Image Loading in Oracle Cloud Infrastructure Kubernetes Engine (OKE) mit Stargz Store aktivieren

Einführung

Lazy Container Image Loading (manchmal auch als Lazy Pulling oder On-Demand Image Loading bezeichnet) ist eine Technik, mit der ein Container gestartet werden kann, bevor das vollständige Image heruntergeladen wird. Nur die zur Laufzeit erforderlichen Teile des Images werden abgerufen, wodurch die Startzeit verkürzt wird, insbesondere bei großen Images.

Normalerweise, wenn Sie einen Container ausführen:

  1. Die Containerlaufzeit (z.B. CRI-O, containerd) lädt das gesamte Image aus der Registry herunter.
  2. Es entpackt alle Bildebenen.
  3. Erst nachdem alle Layer heruntergeladen und entpackt wurden, wird der Container gestartet.

Mit Lazy Loading:

  1. Der Container wird sofort mit einem virtuellen Dateisystem gestartet (das Abbild ist noch nicht lokal vorhanden).
  2. Wenn die Anwendung auf eine Datei zugreift, ruft die Laufzeit nur den erforderlichen Inhalt aus der Remote-Registry bei Bedarf ab.
  3. Zusätzliche Dateien werden nur heruntergeladen, wenn sie tatsächlich verwendet werden.
  4. Das vollständige Containerimage wird im Hintergrund abgerufen.

Containerimages müssen neu verpackt werden, um Lazy Loading zu unterstützen. Mit dem eStargz-Format wird das Bild in kleine, selbstständig dekomprimierbare Blöcke umgepackt. Dadurch kann die Containerlaufzeit nur die erforderlichen Chunks abrufen, wenn der Container gestartet wird.

eStargz-Bilder enthalten eine spezielle Datei namens TOC (Table of Contents), die Metadaten (z. B. Name, Dateityp, Eigentümer, Offset) aller Dateieinträge in der eStargz-Schicht mit Ausnahme des Inhaltsverzeichnisses selbst aufzeichnet. Container-Laufzeiten können das Inhaltsverzeichnis verwenden, um das Dateisystem des Containers zu mounten, ohne den gesamten Layer-Inhalt herunterzuladen.

In diesem Tutorial erfahren Sie, wie Sie folgende Aktionen durchführen:

  1. Vorhandenes Containerimage neu packen, um das Stargz-Format zu verwenden
  2. Oracle Cloud Infrastructure Kubernetes Engine (OKE) CRI-O für die Verwendung des Stargz Store-Plug-ins konfigurieren
  3. Beispiel-Workload ausführen, um Verbesserungen der Container-Startzeit zu demonstrieren

Voraussetzungen

Setup

Erstellen Sie das Containerimage mit nerdctl neu, um das eStargz-Format zu verwenden

  1. Erstellen Sie ein Image Repository in OCI Registry (OCIR). In diesem Tutorial lautet der tenancy-namespace idxzjcdxqj. Dann erstellen wir einen repo namens vllm/vllm-openai.

    OCIR-Repository

    Sie können die folgenden Anweisungen befolgen, um sich bei OCIR zu authentifizieren und ein neues Repository zu erstellen: Images mit der Docker-CLI pushen.

    Ersetzen Sie iad.ocir.io durch die OCIR-Domain der OCI-Region, an der Sie arbeiten. Im Folgenden finden Sie eine Liste der Regionsschlüssel.

    docker login iad.ocir.io
  2. Laden Sie die neueste Version von nerdctl auf dem Rechner herunter, auf dem Docker installiert ist.

    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. Authentifizieren Sie nerdctl bei OCIR.

    ./nerdctl login iad.ocir.io
  4. Konvertieren Sie das vllm-Containerimage in das eStargz-Format.

    ./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. Senden Sie das eStargz-vllm-Containerimage an OCIR.

    ./nerdctl image push iad.ocir.io/idxzjcdxqj/vllm/vllm-openai:v0.11.0-esgz
  6. Mit Docking können Sie das reguläre Image per Docking per Pull/Push an OCIR übertragen.

    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

Stargz Store Plugin auf den OKE-Knoten installieren

Wenn OKE CRI-O verwendet, müssen wir das Stargz Store-Plugin einrichten. Dies ist eine Implementierung eines zusätzlichen Layer Store Plugins für CRI-O/Podman. Stargz Store bietet CRI-O/Podman remote montierte eStargz-Layer.

  1. Greifen Sie mit SSH auf einen der Worker-Knoten zu, und laden Sie die neueste Version von der stargz-snapshotter-Github-Seite herunter.

    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. Extrahieren Sie stargz-store in /usr/local/bin.

    tar -C /usr/local/bin -xvf stargz-snapshotter-v0.18.2-linux-amd64.tar.gz stargz-store
  3. Aktualisieren Sie die Datei /etc/containers/storage.conf so, dass additionallayerstores in den Abschnitt [storage.options] aufgenommen wird.

    [storage]
    driver = "overlay"
    graphroot = "/var/lib/containers/storage"
    runroot = "/run/containers/storage"
    
    [storage.options]
    additionallayerstores = ["/var/lib/stargz-store/store:ref"]
  4. Stellen Sie sicher, dass fuse installiert und geladen ist.

    apt-get install fuse
    modprobe fuse
  5. Aktivieren Sie den stargz-store-Service.

    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. Stellen Sie sicher, dass die Services crio und stargz-store ausgeführt werden.

    systemctl status stargz-store
    systemctl status crio

Bewerten der Performance

  1. Aktualisieren Sie nodeName und image im folgenden Manifest, und erstellen Sie die Test-Deployments:

    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. Überwachen Sie die Containerstartzeit.

    kubectl get pods -w
  3. Bereinigen Sie Ressourcen.

    kubectl delete deploy test-regular-cpu
    kubectl delete deploy test-estargz-cpu
  4. Aktualisieren Sie für ein Test-Deployment mit der GPU nodeName und image in diesem YAML-Manifest, und wenden Sie es mit dem folgenden Befehl an:

    kubectl apply -f test-manifest-gpu.yaml

Ergebnisse

Die folgenden Ergebnisse basieren auf Tests, die auf einer BM.GPU4.8-Ausprägung mit einem großen Sprachmodell mit 30B-Parametern ausgeführt werden.

  1. Podstartzeit ist 33s für eStargz und 4m für reguläres Image.

    $ 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. Die Anwendung wird auf dem Pod mit dem eStargz-Image in 1m27s gestartet.

    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. Die Anwendung wird auf dem Pod mit dem regulären Image in 32s gestartet.

    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. Der Pod, der das eStargz-Image verwendet, ist bereit, Traffic 1m22s schneller als der normale zu verarbeiten.

Schlussfolgerungen

Die Implementierung von Lazy Image Pulling mit dem eStargz-Format in OKE zeigt signifikante Verbesserungen der Pod-Initialisierungszeit, wodurch der Containerstart von 4 Minuten auf nur 33 Sekunden reduziert wird, was einer Reduzierung um 87% entspricht. Während die Initialisierungszeit der Anwendung innerhalb des eStargz-Containers etwa 1 Minute länger dauert als das normale Bild (1m27s vs 32s), ist die Gesamtzeit bis zum Bereitschaftszustand immer noch 1m22s schneller, wodurch der Pod schneller für den Datenverkehr verfügbar ist. Dieser Kompromiss erweist sich besonders in Produktionsumgebungen, in denen schnelle Skalierung, Pod-Neuplanung oder Kaltstarts von entscheidender Bedeutung sind, da die erhebliche Reduzierung der anfänglichen Container-Ziehzeit den bescheidenen Anstieg des Overheads beim Start der Anwendung überwiegt. Für Workloads, die große Containerimages verwenden, insbesondere KI-Workloads, bietet das Lazy Pulling mit eStargz eine praktische Lösung, um die Bereitstellung zu beschleunigen, ohne dass Änderungen am Anwendungscode oder wesentliche Infrastrukturänderungen erforderlich sind.

  1. Stargz Snapshotter Installationsdokumentation
  2. Experimentieren mit eStargz-Bildziehen auf OpenShift
  3. nerdctl Stargz-Dokumentation

Bestätigungen

Weitere Lernressourcen

Sehen Sie sich weitere Übungen auf docs.oracle.com/learn an, oder greifen Sie auf weitere kostenlose Lerninhalte im YouTube-Kanal von Oracle Learning zu. Besuchen Sie außerdem education.oracle.com/learning-explorer, um ein Oracle Learning Explorer zu werden.

Die Produktdokumentation finden Sie im Oracle Help Center.