容器技術的核心概念是將應用程式及其所有依賴項封裝成一個獨立的容器映像,確保應用程式在不同環境中具有一致性,從而簡化佈署流程並提高效率。隨著容器技術的普及,容器協調工具如 Kubernetes 和 Docker Swarm 也應運而生,以管理和協調多個容器的執行。AWS 提供了 Amazon ECS 和 Amazon EKS 等服務,方便開發者在雲端環境中佈署和管理容器化應用程式。此外,Amazon ECR 提供了安全的容器映像儲存函式庫,並支援漏洞掃描功能,以確保容器映像的安全性。在實際操作中,可以透過 AWS CLI 或 Docker Desktop 等工具來構建、標記和推播容器映像到 Amazon ECR,並利用 Amazon ECR 的掃描功能來檢測潛在的安全漏洞。最後,可以將容器映像佈署到 Amazon Lightsail 等服務,快速啟動和執行容器化應用程式。

容器技術的基礎與應用

容器技術是一種將應用程式及其依賴項封裝成單一容器的技術,稱為容器映像。透過這種方式,可以在開發、測試和執行應用程式時保持控制和一致性。無論容器在哪裡執行,都能確保執行環境的一致性,從而減少構建和佈署的時間。

容器的特點與優勢

容器是一種完全獨立的環境,能夠利用主機的計算和記憶體資源。在同一台主機上,可以執行多個容器而不會產生衝突。同時,多個容器之間也可以進行通訊。例如,可以執行一個前端網頁應用程式容器,該容器可以存取另一個執行後端的容器,以處理更多的流量。

然而,執行多個容器並確保其高用性可能會帶來一些挑戰,因此需要使用容器協調工具。常見的容器協調工具包括Kubernetes和Docker Swarm。

在AWS上執行容器

AWS提供了多種選項來執行容器,例如Amazon Elastic Container Service(Amazon ECS)和Amazon Elastic Kubernetes Service(Amazon EKS)作為容器協調工具,以及Amazon Elastic Cloud Compute(Amazon EC2)用於具有自定義需求的佈署。這些服務可以與AWS CodeDeploy、AWS CodePipeline和Amazon Elastic Container Registry等服務整合,以簡化開發流程並提供自動化功能。

設定工作站

要驗證組態和設定所需的環境變數,請按照「CLI配方的工作站一般設定步驟」進行操作。然後,克隆章節程式碼儲存函式庫:

git clone https://github.com/AWSCookbook/Containers

Docker安裝和驗證

Docker Desktop是Windows和Mac使用者的推薦選擇;Docker Linux Engine是Linux使用者的推薦選擇。在下面的配方中,您將使用Docker在特定平台上建立一致的工作環境。請務必為您的作業系統安裝最新穩定的Docker版本。

MacOS

  1. 按照Docker Desktop的說明進行安裝:https://docs.docker.com/docker-for-mac/install。
  2. 安裝後執行Docker Desktop應用程式。

Windows

  1. 按照Docker Desktop的說明進行安裝:https://docs.docker.com/desktop/windows/install。
  2. 安裝後執行Docker Desktop應用程式。

Linux

  1. 按照Docker Desktop的說明進行安裝:https://docs.docker.com/engine/install。
  2. 在您的發行版上啟動Docker守護程式。

使用以下命令驗證Docker的安裝:

docker --version

您應該會看到類別似以下的輸出:

Docker version 19.03.13, build 4484c46d9d

6.1 將容器映像構建、標記並推播到Amazon ECR

問題

您需要一個儲存函式庫來儲存構建和標記的容器映像。

解決方案

首先,您將在Amazon ECR中建立一個儲存函式庫。接下來,您將建立一個Dockerfile並使用它來構建Docker映像。最後,您將對容器映像應用兩個標籤並將它們推播到新建立的ECR儲存函式庫中。

步驟

  1. 登入AWS管理控制檯並搜尋Elastic Container Registry。點選「建立儲存函式庫」按鈕。 給您的儲存函式庫命名,保持所有預設設定,然後滾動到底部並再次點選「建立儲存函式庫」以完成。

或者,您也可以從命令列建立ECR儲存函式庫:

REPO=aws-cookbook-repo && \
aws ecr create-repository --repository-name $REPO

您應該會看到類別似以下的輸出:

{
    "repository": {
        "repositoryArn": "arn:aws:ecr:us-east-1:111111111111:repository/aws-cookbook-repo",
        "registryId": "1111111111111",
        "repositoryName": "aws-cookbook-repo",
        "repositoryUri": "611652777867.dkr.ecr.us-east-1.amazonaws.com/aws-cookbook-repo",
        "createdAt": "2021-10-02T19:57:56-04:00",
        "imageTagMutability": "MUTABLE",
        "imageScanningConfiguration": {
            "scanOnPush": false
        },
        "encryptionConfiguration": {
            "encryptionType": "AES256"
        }
    }
}
  1. 建立一個簡單的Dockerfile:
echo FROM nginx:latest > Dockerfile

內容解密:

此步驟建立了一個名為Dockerfile的檔案,該檔案包含了一條指令:FROM nginx:latest。這條指令告訴Docker使用最新版本的Nginx映像作為基礎映像來構建新的Docker映像。

將容器映像檔建置、標記並推播至 Amazon ECR

在應用程式開發過程中,擁有一個存放容器映像檔的儲存函式庫是基礎建設的重要環節。使用私有儲存庫存放容器映像檔能提升應用程式開發過程的安全性。Amazon ECR 支援熱門的 Docker Image Manifest V2、Schema 2,以及最新的 Open Container Initiative(OCI)映像檔,並且可以在提取時進行格式轉換。

步驟一:建立 Amazon ECR 儲存函式庫

首先,需要建立一個 Amazon ECR 儲存函式庫來存放容器映像檔。可以使用 AWS CLI 執行以下命令:

aws ecr create-repository --repository-name aws-cookbook-repo

內容解密:

  • aws ecr create-repository:此命令用於建立 Amazon ECR 儲存函式庫。
  • --repository-name aws-cookbook-repo:指定儲存函式庫的名稱為 aws-cookbook-repo

步驟二:建立 Dockerfile

接下來,建立一個 Dockerfile 以定義容器映像檔的內容。在本例中,Dockerfile 只有一行,指定使用 nginx:latest 作為基礎映像檔。

FROM nginx:latest

內容解密:

  • FROM nginx:latest:此指令指定使用 Docker Hub 中的 nginx:latest 映像檔作為基礎映像檔。

步驟三:建置並標記映像檔

執行以下命令以建置並標記映像檔:

docker build . -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:latest
docker tag $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:latest $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:1.0

內容解密:

  • docker build . -t:建置當前目錄下的 Dockerfile,並將映像檔標記為指定的名稱。
  • $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:latest:指定映像檔的完整名稱,包括 AWS 帳戶 ID、區域和儲存函式庫名稱。
  • docker tag:為已存在的映像檔新增額外的標籤。

步驟四:推播映像檔至 Amazon ECR

在推播映像檔之前,需要先登入 Amazon ECR:

aws ecr get-login-password | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com

然後,推播映像檔:

docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:latest
docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:1.0

內容解密:

  • aws ecr get-login-password:取得登入 Amazon ECR 的密碼。
  • docker login:使用取得的密碼登入 Amazon ECR。
  • docker push:將標記好的映像檔推播至 Amazon ECR。

驗證檢查

推播完成後,可以在 Amazon ECR 控制檯或使用 AWS CLI 檢視已推播的映像檔:

aws ecr list-images --repository-name aws-cookbook-repo

輸出結果應包含已推播映像檔的詳細資訊。

清理資源

完成驗證後,請依照章節程式碼儲存函式庫中的指示清理資源。

自動掃描推播至 Amazon ECR 的映像檔以尋找安全漏洞

步驟一:啟用自動掃描

首先,在 Amazon ECR 中啟用儲存函式庫的自動掃描功能:

REPO=aws-cookbook-repo && aws ecr put-image-scanning-configuration --repository-name $REPO --image-scanning-configuration scanOnPush=true

內容解密:

  • aws ecr put-image-scanning-configuration:設定儲存函式庫的映像檔掃描組態。
  • --image-scanning-configuration scanOnPush=true:啟用在推播映像檔時自動掃描安全漏洞。

步驟二:推播映像檔並檢視掃描結果

提取一個舊版本的 NGINX 映像檔,並標記後推播至 Amazon ECR:

docker pull nginx:1.14.1
docker tag nginx:1.14.1 $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:old
docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/aws-cookbook-repo:old

推播完成後,使用以下命令檢視掃描結果:

aws ecr describe-image-scan-findings --repository-name aws-cookbook-repo --image-id imageTag=old

輸出結果將顯示掃描發現的安全漏洞詳細資訊。

在 Amazon ECR 和 Amazon Lightsail 上佈署容器化應用程式

使用 Amazon ECR 掃描容器映像中的漏洞

Amazon Elastic Container Registry(ECR)提供了一個安全機制,能夠掃描容器映像中的漏洞。這些漏洞會根據 Common Vulnerability Scoring System(CVSS)評分進行評估,從而幫助您檢測和修復容器映像中的安全問題。

步驟

  1. 建立 Amazon ECR 儲存函式庫:首先,您需要在 Amazon ECR 中建立一個儲存函式庫來存放您的容器映像。

  2. 推播容器映像:將您的容器映像推播到剛剛建立的 Amazon ECR 儲存函式庫中。

  3. 掃描映像:Amazon ECR 提供了映像掃描功能,可以檢測映像中的漏洞。

    aws ecr describe-image-scan-findings --repository-name 您的儲存函式庫名稱 --image-id imageTag=latest
    

    您可能會看到類別似以下的輸出,其中包含了發現的漏洞詳細資訊:

    {
      "imageScanFindings": {
        "findings": [
          {
            "name": "CVE-2019-3462",
            "description": "apt 版本 1.4.8 及更早版本在 HTTP 傳輸方法中的 302 重定向欄位清理不正確,可能導致 MITM 攻擊者注入內容,從而可能在目標機器上執行遠端程式碼。",
            "uri": "https://security-tracker.debian.org/tracker/CVE-2019-3462",
            "severity": "CRITICAL",
            "attributes": [
              {
                "key": "package_version",
                "value": "1.4.8"
              }
            ]
          }
        ]
      }
    }
    

程式碼範例與解析

以下是一個使用 AWS CLI 命令掃描 Amazon ECR 映像的範例:

aws ecr describe-image-scan-findings --repository-name 您的儲存函式庫名稱 --image-id imageTag=latest

內容解密:

  1. aws ecr describe-image-scan-findings:此命令用於取得 Amazon ECR 中指定映像的掃描結果。
  2. --repository-name 您的儲存函式庫名稱:指定要查詢的 Amazon ECR 儲存函式庫名稱。
  3. --image-id imageTag=latest:指定要掃描的映像標籤,在此範例中為 latest
  4. 該命令會傳回指定映像的掃描結果,包括發現的漏洞、嚴重性等資訊。

將容器佈署到 Amazon Lightsail

Amazon Lightsail 提供了一種簡便的方式來佈署容器化應用程式。以下是使用 Amazon Lightsail 佈署 NGINX 容器的步驟:

步驟

  1. 安裝 Lightsail 控制外掛:首先,您需要為 AWS CLI 安裝 Lightsail 控制外掛(lightsailctl)。

  2. 建立容器服務:使用以下命令建立一個新的容器服務。

    aws lightsail create-container-service --service-name awscookbook --power nano --scale 1
    
  3. 提取 NGINX 容器映像:提取一個基本的 NGINX 容器映像。

    docker pull nginx
    
  4. 推播容器映像到 Lightsail:將 NGINX 映像推播到剛剛建立的 Lightsail 容器服務。

    aws lightsail push-container-image --service-name awscookbook --label awscookbook --image nginx
    
  5. 建立佈署組態檔案(lightsail.json):建立一個名為 lightsail.json 的檔案,內容如下:

    {
      "serviceName": "awscookbook",
      "containers": {
        "awscookbook": {
          "image": ":awscookbook.awscookbook.1",
          "ports": {
            "80": "HTTP"
          }
        }
      },
      "publicEndpoint": {
        "containerName": "awscookbook",
        "containerPort": 80
      }
    }
    
  6. 佈署容器服務:使用以下命令佈署容器服務。

    aws lightsail create-container-service-deployment --service-name awscookbook --cli-input-json file://lightsail.json
    
  7. 驗證佈署結果:存取 Lightsail 提供的端點 URL,您應該能夠看到 NGINX 的歡迎頁面。

圖表解析

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 容器技術佈署與安全漏洞掃描實踐

package "Docker 架構" {
    actor "開發者" as dev

    package "Docker Engine" {
        component [Docker Daemon] as daemon
        component [Docker CLI] as cli
        component [REST API] as api
    }

    package "容器運行時" {
        component [containerd] as containerd
        component [runc] as runc
    }

    package "儲存" {
        database [Images] as images
        database [Volumes] as volumes
        database [Networks] as networks
    }

    cloud "Registry" as registry
}

dev --> cli : 命令操作
cli --> api : API 呼叫
api --> daemon : 處理請求
daemon --> containerd : 容器管理
containerd --> runc : 執行容器
daemon --> images : 映像檔管理
daemon --> registry : 拉取/推送
daemon --> volumes : 資料持久化
daemon --> networks : 網路配置

@enduml

此圖示說明瞭從建立 Amazon ECR 儲存函式庫到佈署容器化應用程式到 Amazon Lightsail 的流程,並包括了映像漏洞掃描和修復的步驟。