

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 Seekable OCI (SOCI) 的延遲載入容器映像
<a name="lambda-managed-instances-seekable-oci"></a>

對於部署為 Lambda 受管執行個體上容器映像的 Lambda 事件函數，Lambda 會在啟動執行環境之前下載並解壓縮每個執行個體上的映像。對於大型映像，此提取是發佈函數版本或向外擴展，以及處理其第一個調用的執行環境之間的最大部分。使用 Seekable OCI (SOCI)，Lambda 可以在下載整個映像之前啟動執行環境。

SOCI 是一種由 開發的[開放原始碼技術](https://github.com/awslabs/soci-snapshotter) AWS。它使用 索引，將影像中的每個檔案映射到影像圖層中的位置。當函數讀取檔案時，Lambda 會使用索引僅隨需擷取檔案，而不是在啟動容器之前下載和解壓縮完整映像。容器映像通常會綁定廣泛的程式庫和相依性集，並非所有程式庫和相依性都是在啟動或任何單一調用期間讀取。延遲載入透過僅擷取函數實際讀取的內容、縮短第一次調用的時間，並使啟動時間對總影像大小較不敏感。優點最大適用於數個 GB 的影像，其中您的函數每次調用只會讀取一部分的內容，例如封裝機器學習架構的影像。

## SOCI 如何在 Lambda 受管執行個體上運作
<a name="lambda-managed-instances-seekable-oci-how-it-works"></a>

1. 您可以為映像建立 SOCI 索引，並將其與映像一起推送至 Amazon ECR。結果是 Open Container Initiative (OCI) 影像索引，參考兩個成品：原始影像資訊清單和 SOCI 索引。

1. 您可以使用指向影像索引的影像 URI 來建立或更新函數。Lambda 會偵測 SOCI 索引，並為該函數的執行環境啟用延遲載入。您不需要變更任何其他函數組態。

1. Lambda 會隨需擷取影像內容。初始化期間會擷取您的初始化程式碼讀取的檔案。您的處理常式第一次讀取的檔案會在該調用期間擷取。Lambda 不會在背景下載影像的其餘部分。

**注意**  
如果您的函數在調用期間第一次讀取檔案，而不是在初始化期間，Lambda 會在第一次調用時擷取該檔案，這會增加調用的持續時間。若要保持調用持續時間的一致性，請在初始化程式碼中匯入所有程式庫並讀取函數所需的所有檔案，而不是在處理常式中。建議您使用和不使用 SOCI 測試函數，以比較工作負載的啟動時間和調用持續時間。

## 為您的映像建立 SOCI 索引
<a name="lambda-managed-instances-seekable-oci-create-index"></a>

下列範例會在 Amazon Linux 2023 上執行。它會安裝 SOCI 快照器、容器化和 nerdctl，然後為 Amazon ECR 中的現有映像建立 SOCI 索引，並推送結果。將預留位置值替換為自訂值。如需建立和推送 SOCI 索引的其他方法，請參閱 GitHub [上的 SOCI 快照器入門](https://github.com/awslabs/soci-snapshotter/blob/main/docs/getting-started.md)。

```
sudo yum install -y soci-snapshotter containerd nerdctl
sudo systemctl start soci-snapshotter
sudo systemctl restart containerd

ACCOUNT_ID="111122223333"
REGION="us-east-2"
REPOSITORY_NAME="my-function"
ORIGINAL_IMAGE_TAG="v1"
SOCI_IMAGE_TAG="v1-soci"
REGISTRY="$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com"

aws ecr get-login-password --region $REGION | sudo nerdctl login -u AWS --password-stdin $REGISTRY

sudo nerdctl pull $REGISTRY/$REPOSITORY_NAME:$ORIGINAL_IMAGE_TAG
sudo nerdctl image convert --soci $REGISTRY/$REPOSITORY_NAME:$ORIGINAL_IMAGE_TAG $REGISTRY/$REPOSITORY_NAME:$SOCI_IMAGE_TAG
sudo nerdctl push --platform linux/arm64 $REGISTRY/$REPOSITORY_NAME:$SOCI_IMAGE_TAG
```

**注意**  
此範例會建置 `arm64`(AWS Graviton) 映像。Lambda 僅支援單一架構容器映像，因此映像必須以單一指令集架構為目標，且`--platform`值必須符合函數的架構。如需詳細資訊，請參閱[選取和設定 Lambda 函數的指令集架構](foundation-arch.md)。

當您建立或更新函數時，請使用 `$REGISTRY/$REPOSITORY_NAME:$SOCI_IMAGE_TAG`做為映像 URI。然後發佈函數版本。Lambda 會將函數版本解析為影像索引，並啟用延遲載入。

## 要求與限制
<a name="lambda-managed-instances-seekable-oci-requirements"></a>

SOCI 索引版本  
Lambda 僅支援 SOCI 索引資訊清單 v2 （媒體類型 `application/vnd.amazon.soci.index.v2+json`)。Lambda 不支援 SOCI 索引資訊清單 v1 索引。上一節中的 `nerdctl image convert --soci`命令會產生 v2 索引。

影像索引格式  
影像索引必須只包含兩個項目：SOCI 索引和一個 OCI 影像資訊清單。

映像 URI  
將函數的影像 URI 指向 SOCI 索引標籤 （例如 `my-function:v1-soci`)，而不是原始影像標籤。Lambda 會將函數版本解析為影像索引。若要變更映像或索引，請推送新的 SOCI 索引標籤，並更新函數的映像 URI。

可用性  
SOCI 僅適用於在 Lambda 受管執行個體上執行的容器映像函數。