在 Amazon Lightsail 上部署容器化 Web 应用程序

教程

模块 4:部署新容器版本

在本模块中,您将学习更新已部署的容器

概述

应用程序的整个生命周期内会被更新很多次。在本模块中,您将学习如何更新部署,以及在新的应用程序版本出现问题的情况下如何回滚部署。

学习目标

在本模块中,您将:

  • 更新应用程序代码并构建新的本地容器镜像
  • 将更新后的容器镜像推送到 Amazon Lightsail
  • 部署应用程序的新版本
  • 在出现问题时回滚部署

 时长

10 分钟

 模块学习前期准备

  • 具有管理员级别访问权限的 AWS 账户*
  • 推荐的浏览器:最新版本的 Chrome 或 Firefox

*在过去 24 小时内新创建的账户可能无法使用本教程所需的服务。

操作步骤

更新应用程序代码并构建新的容器镜像

假设应用程序首页上的城市名称不正确,需要修改。

打开 code/templates/index.html 文件。搜索 Las Vegas 并将其替换为 Paris

接下来,按模块 2 中所述步骤,重新构建和测试容器。打开终端,运行以下命令:

docker build -t demo-flask-signup .
docker run -p 8080:80 --rm -v ~/.aws:/root/.aws demo-flask-signup:latest

容器运行后,打开浏览器,访问容器地址:http://localhost:8080。您将看到应用程序主屏幕,其中包含新设置的城市名称。

将更新后的容器镜像推送到 Amazon Lightsail

构建好容器后,下一步就是将这个新容器镜像推送到 Amazon Lightsail。

打开终端,运行以下命令:

aws lightsail push-container-image --region eu-west-3 --service-name signup-application --label latest  --image demo-flask-signup:latest

该命令输出如下类似结果:

# aws lightsail push-container-image --region eu-west-3 --service-name signup-application --label latest --image demo-flask-signup:latest

df0f7d33bb59: Pushed 
951ffe99d911: Pushed 
cee40450fe90: Pushed 
1327150a5178: Pushed 
4bc5d67b6427: Layer already exists 
ce8ffb5c560e: Layer already exists 
4226d5d0360f: Layer already exists 
9d1af766c818: Layer already exists 
d97733c0a3b6: Layer already exists 
c553c6ba5f13: Layer already exists 
48b4a40de359: Layer already exists 
ace9ed9bcfaf: Layer already exists 
764055ebc9a7: Layer already exists 
Digest: sha256:42d2e19ee7340bc7f028593318e9b7406e9e70fb4785618d3f6c78443e097a87
Image "demo-flask-signup:latest" registered.
Refer to this image as ":signup-application.latest.2" in deployments.

输出中的最后一行是容器的内部名称。请记下这个名称,因为我们在将容器部署到容器服务上时会用到该名称。在后续阶段,如果要查看该容器名称,可以运行以下命令:

aws lightsail get-container-images --region eu-west-3 --service-name signup-application

该命令输出如下类似结果:

# aws lightsail get-container-images --region eu-west-3 --service-name signup-application

{
    "containerImages": [
        {
            "image": ":signup-application.latest.2",
            "digest": "sha256:42d2e19ee7340bc7f028593318e9b7406e9e70fb4785618d3f6c78443e097a87",
            "createdAt": "2024-03-13T14:20:08-04:00"
        },
        {
            "image": ":signup-application.latest.1",
            "digest": "sha256:128f84907d30a1fb47c1888720485fa8050cc99bc1034e0cfd1f46d3b6e57e19",
            "createdAt": "2024-03-13T13:23:08-04:00"
        }
    ]
}

执行命令查看部署状态。

注意容器的当前状态显示为 "state": "DEPLOYING"。稍等片刻后,该状态就会变成 ACTIVE。部署过程需要几分钟才能完成。您可以运行以下命令来检查部署的状态:

aws lightsail get-container-services --region eu-west-3 --query "containerServices[].nextDeployment.state"
aws lightsail get-container-services --region eu-west-3 --query "containerServices[].currentDeployment.state" 

测试部署

要测试部署情况,首先查看 Lightsail 创建的容器服务地址 URL。打开终端,运行以下命令:

aws lightsail get-container-services --region eu-west-3 --query "containerServices[].url"

该命令输出如下类似结果:

# aws lightsail get-container-services --region eu-west-3 --query "containerServices[].url"

[
    "https://signup-application.me04fvc6dbk4e.eu-west-3.cs.amazonlightsail.com/"
]

现在,我们有两个版本的容器镜像::signup-application.latest.1:signup-application.latest.2

部署应用程序的新版本

容器镜像存储在 Amazon Lightsail 上后,我们就可以使用上一个模块部署容器 中所述的命令,将该镜像部署到容器服务上。

编辑 lc.json 文件,将要使用的镜像名称从 :signup-application.latest.1 替换为新版本名称 :signup-application.latest.2

lc.json 文件内容如下所示:

{
    "serviceName": "signup-application",
    "containers": {
        "signup-app-container": {
            "image": ":signup-application.latest.2",
            "ports": {
                "80": "HTTP"
            }
        }
    },
    "publicEndpoint": {
        "containerName": "signup-app-container",
        "containerPort": 80
    }
}

接下来,运行以下命令部署容器:

aws lightsail create-container-service-deployment --region eu-west-3 --cli-input-json file://lc.json

该命令输出如下类似结果:

# aws lightsail create-container-service-deployment --region eu-west-3 --cli-input-json file://lc.json

{
    "containerService": {
        "containerServiceName": "signup-application",
        "arn": "arn:aws:lightsail:eu-west-3:012345678901:ContainerService/528a0bcf-fd14-42d4-a09a-943a241adc51",
        "createdAt": "2024-03-15T11:43:10-04:00",
        "location": {
            "availabilityZone": "all",
            "regionName": "eu-west-3"
        },
        "resourceType": "ContainerService",
        "tags": [],
        "power": "nano",
        "powerId": "nano-1",
        "state": "DEPLOYING",
        "scale": 2,
        "nextDeployment": {
            "version": 1,
            "state": "ACTIVATING",
            "containers": {
                "signup-app-container": {
                    "image": ":signup-application.latest.2",
                    "command": [],
                    "environment": {},
                    "ports": {
                        "80": "HTTP"
                    }
                }
            },
            "publicEndpoint": {
                "containerName": "signup-app-container",
                "containerPort": 80,
                "healthCheck": {
                    "healthyThreshold": 2,
                    "unhealthyThreshold": 2,
                    "timeoutSeconds": 2,
                    "intervalSeconds": 5,
                    "path": "/",
                    "successCodes": "200-499"
                }
            },
            "createdAt": "2024-03-15T11:43:10-04:00"
       },
        "isDisabled": false,
        "principalArn": "arn:aws:iam::577312533299:role/amazon/lightsail/eu-west-3/containers/signup-application/1jetjd21p8qshe57seuh71tnrnn29ps77lnno20sbgl2ghbuc0r0",
        "privateDomainName": "signup-application.service.local",
        "url": "https://signup-application.me04fvc6dbk4e.eu-west-3.cs.amazonlightsail.com/"
    }
}

测试部署

这一步,我们测试新部署。回到浏览器窗口,刷新上一模块实验中访问的容器服务页面。

如果您已退出该页面,并且忘记了该地址,您可以在终端上运行以下命令来查看 URL:

aws lightsail get-container-services --region eu-west-3 --query "containerServices[].url"

该命令输出如下类似结果:

# aws lightsail get-container-services --region eu-west-3 --query "containerServices[].url"

[
    "https://signup-application.me04fvc6dbk4e.eu-west-3.cs.amazonlightsail.com/"
]

回滚部署

新部署并不会覆盖应用程序的前一个版本,而是创建了一个新版本。如果最新部署出现了问题,可以回滚到之前的版本。

如果要查看可用的版本,可在终端上运行以下命令:

aws lightsail get-container-service-deployments --region eu-west-3 --service-name signup-application

该命令输出如下类似结果:

# aws lightsail get-container-service-deployments --region eu-west-3 --service-name signup-application

{
    "deployments": [
        {
            "version": 1,
            "state": "ACTIVE",
            "containers": {
                "signup-app-container": {
                    "image": ":signup-application.latest.1",
                    "command": [],
                    "environment": {},
                    "ports": {
                        "80": "HTTP"
                    }
                }
            },
            "publicEndpoint": {
                "containerName": "signup-app-container",
                "containerPort": 80,
                "healthCheck": {
                    "healthyThreshold": 2,
                    "unhealthyThreshold": 2,
                    "timeoutSeconds": 2,
                    "intervalSeconds": 5,
                    "path": "/",
                    "successCodes": "200-499"
                }
            },
            "createdAt": "2024-03-13T14:21:30-04:00"
        }
    ]
}

从命令的输出结果中,可以看到有两个部署版本。版本 1 处于 INACTIVE 状态,版本 2 处于 ACTIVE 状态。

运行以下命令可查看指定部署的概览信息:

aws lightsail get-container-service-deployments --region eu-west-3 --service-name signup-application --query 'deployments[].{version: version, state: state, image:containers.\"signup-app-container\".image}'

该命令输出如下类似结果:

# aws lightsail get-container-service-deployments --region eu-west-3 --service-name signup-application --query 'deployments[].{version: version, state: state, image:containers.\"signup-app-container\".image}'

[
    {
        "version": 2,
        "state": "ACTIVE",
        "image": ":signup-application.latest.2"
    },
    {
        "version": 1,
        "state": "INACTIVE",
        "image": ":signup-application.latest.1"
    }
]

假设您刚刚部署的上一版本应用程序未正常运行。但是,在测试过程中并没有出现错误。

您可以访问容器日志。在终端上运行以下命令:

aws lightsail get-container-log --region eu-west-3 --service-name signup-application --container-name signup-app-container --output text

该命令输出如下类似结果:

# aws lightsail get-container-log --region eu-west-3 --service-name signup-application --container-name signup-app-container --output text

LOGEVENTS       2024-03-18T10:29:28-04:00       [deployment:1] Creating your deployment
LOGEVENTS       2024-03-18T10:30:03-04:00       Starting NGinx
LOGEVENTS       2024-03-18T10:30:03-04:00       2024/03/18 14:30:03 [notice] 13#13: using the "epoll" event method
LOGEVENTS       2024-03-18T10:30:03-04:00       2024/03/18 14:30:03 [notice] 13#13: nginx/1.25.4
LOGEVENTS       2024-03-18T10:30:03-04:00       2024/03/18 14:30:03 [notice] 13#13: built by gcc 12.2.0 (Debian 12.2.0-14)
...

要快速回滚部署并重新部署先前版本的应用程序,需要更改 lc.json 文件,配置使用第一个版本的容器镜像,然后重新部署此镜像。

按如下所示修改 lc.json 文件:

{
    "serviceName": "signup-application",
    "containers": {
        "signup-app-container": {
            "image": ":signup-application.latest.1",
            "ports": {
                "80": "HTTP"
            }
        }
    },
    "publicEndpoint": {
        "containerName": "signup-app-container",
        "containerPort": 80
    }
}

然后,在终端上运行以下命令:

aws lightsail create-container-service-deployment --region eu-west-3 --cli-input-json file://lc.json

该命令输出如下类似结果:

# aws lightsail create-container-service-deployment --region eu-west-3 --cli-input-json file://lc.json

{
    "containerService": {
        "containerServiceName": "signup-application",
        "arn": "arn:aws:lightsail:eu-west-3:607950359977:ContainerService/d9203026-b87b-4e6a-8a91-df2540dbfe86",
        "createdAt": "2024-03-18T10:25:22-04:00",
        "location": {
            "availabilityZone": "all",
            "regionName": "eu-west-3"
        },
        "resourceType": "ContainerService",
        "tags": [],
        "power": "nano",
        "powerId": "nano-1",
        "state": "DEPLOYING",
        "scale": 2,
        "currentDeployment": {
            "version": 2,
            "state": "ACTIVE",
            "containers": {
                "signup-app-container": {
                    "image": ":signup-application.latest.2",
                    "command": [],
                    "environment": {},
                    "ports": {
                        "80": "HTTP"
                    }
                }
            },
            "publicEndpoint": {
                "containerName": "signup-app-container",
                "containerPort": 80,
                "healthCheck": {
                    "healthyThreshold": 2,
                    "unhealthyThreshold": 2,
                    "timeoutSeconds": 2,
                    "intervalSeconds": 5,
                    "path": "/",
                    "successCodes": "200-499"
                }
            },
            "createdAt": "2024-03-18T10:41:11-04:00"
        },
        "nextDeployment": {
            "version": 3,
            "state": "ACTIVATING",
            "containers": {
                "signup-app-container": {
                    "image": ":signup-application.latest.1",
                    "command": [],
                    "environment": {},
                    "ports": {
                        "80": "HTTP"
                    }
                }
            },
            "publicEndpoint": {
                "containerName": "signup-app-container",
                "containerPort": 80,
                "healthCheck": {
                    "healthyThreshold": 2,
                    "unhealthyThreshold": 2,
                    "timeoutSeconds": 2,
                    "intervalSeconds": 5,
                    "path": "/",
                    "successCodes": "200-499"
                }
            },
            "createdAt": "2024-03-18T10:55:42-04:00"
        },
        "isDisabled": false,
        "principalArn": "arn:aws:iam::844358175455:role/amazon/lightsail/eu-west-3/containers/signup-application/1jetjd21p8qshe57seuh71tnrnn29ps77lnno20sbgl2ghbuc0r0",
        "privateDomainName": "signup-application.service.local",
        "url": "https://signup-application.oh6a4qb72ia80.eu-west-3.cs.amazonlightsail.com/",
        "privateRegistryAccess": {
            "ecrImagePullerRole": {
                "isActive": false,
                "principalArn": ""
            }
        }
    }
}

稍等片刻后,部署版本变为 v3,且状态为 ACTIVE,而容器镜像版本为 v1。部署 v2 和 v1 变为 INACTIVE 状态。

打开浏览器,访问容器服务的 URL,验证该版本部署是否成功。

总结

本教程到此结束。在离开之前,请务必清理环境,以免实验过程中创建的 AWS 资源继续产生费用。

下一项:清理资源