簡體   English   中英

如何讓 AWS ECS 自動將我的容器的端口映射到主機(EC2)

[英]How to have AWS ECS automatically map ports of my container to the host machine(EC2)

語境:

我正在使用 Circle CI 的aws-ecs/deploy-service-update orb 通過拉取 AWS ECR 中的最新映像來部署我的 docker 容器,並將其部署在帶有 AWS EC2 實例的 AWS ECS 中。 這個容器是一個機器學習模型,它在 TCP 端口 3000 接受 API 請求(我為此使用了fastAPI )並返回預測。 部署后,我無法向在端口 3000 部署容器的任務的容器實例的公共 IP 發送請求(此 IP 不是我的 EC2 實例的公共 IP;它只有私有 IP,公共 IP 已禁用) .

調試

  1. 我檢查了我的安全組並確保端口 3000 已打開以接收來自所有 IP(0.0.0.0)的請求,作為入站規則的一部分。
  2. 我停止了任務(它會自動停止在 EC2 實例中運行的容器),認為 Circle CI 可能出了問題。 然后,根據 AWS ECS 的服務配置(1 個所需任務)和任務定義,自動啟動了一個新任務(因此是容器)。 但是,我也無法向其發送請求。
  3. 我通過 SSH 連接到我的 EC2 實例以了解端口 3000 是否打開。 這是我了解到端口根本沒有映射的時候: 在此處輸入圖片說明
    如您所見,容器的 PORTS 列是空的,容器必須接受來自命令的端口 3000 的請求。

以下是 EC2 實例的開放端口: 在此處輸入圖片說明 如您所見,此處未列出端口 3000。


這是您在上面的docker ps屏幕截圖中看到的帶有端口映射的任務,它部署了容器(到 AWS ECS): 在此處輸入圖片說明
在任務定義中,可以看到我為容器定義的端口映射。


這是在我的 EC2 實例上運行的任務,其任務定義如上所示,我使用的網絡模式是“awsvpc”: 在此處輸入圖片說明


這是與任務關聯的 ENI 的“網絡”選項卡,以及與在其中運行任務的 EC2 實例關聯的安全組的入站規則,它接受來自所有 IP 的端口 3000 上的請求。 在此處輸入圖片說明

編輯 1:

我做了之后

docker run -p 3000:3000 <my-image:my-tag>

在 EC2 機器內部(通過從我的筆記本電腦通過 SSH 連接),我可以發送 API 請求並接收到容器的正確響應到它的 AWS ECS 集群的公共 IP。 這意味着僅當我手動運行容器時才會映射端口。

當我使用 FARGATE 時,當我從 Circle CI 更新服務時,甚至當我手動啟動任務時,端口都沒有問題。

那么,當從 AWS ECS 服務儀表板或 Circle CI 運行任務時,如何自動映射端口? 如果我手動運行 docker 容器,我將無法從 AWS Cloudwatch 自動獲取日志,也無法從 AWS ECS 儀表板停止它。 在 EC2 實例中運行的 AWS 的另一個容器將處理這些事情。 它將日志路由到 Cloudwatch 並接受停止現有的和啟動命令以使用存儲在 AWS ECR 中的新圖像啟動一個新容器,而無需每次我想查看日志或啟動/停止容器時都使用 SSH。

這里出了什么問題,導致端口未映射以及如何修復它並正確映射端口,以便我能夠將 API 請求發送到我的容器。

對於awsvpc網絡模式端口映射工作有點不同。 這里的hostPort不是有效選項,創建的 ENI 會將容器端口公開給 VPC。

此模式有幾個先決條件,例如 ECS 代理版本、實例類型(ENI 計數限制)、實例配置文件……查看 AWS 官方文檔: https : //docs.aws.amazon.com/AmazonECS/latest/developerguide /task-networking.html

您是否檢查了 ENI 連接以及這些 ENI 上打開了哪些端口?

我犯的錯誤是使用了 FARGATE 優化集群和其中的 EC2 實例; 這可能導致我的應用程序沒有網絡模式(默認、橋接、主機、awsvpc 和無)工作。 所以,當我像上次一樣重新做所有事情時,但使用 EC2 優化的集群類型時, bridge網絡模式按預期工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM