

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 容器在 Amazon GameLift Servers 中的工作原理
<a name="containers-howitworks"></a>

Amazon GameLift Servers 容器实例集旨在让您能够灵活地部署和扩展容器化应用程序。它使用 Amazon Elastic Container Service（Amazon ECS）来管理 Amazon GameLift Servers 实例集的任务部署和执行。本主题介绍了在 Amazon GameLift Servers 托管式实例集上运行容器的基本结构元素，说明了常见的架构，并概述了一些核心概念。

**借助以下托管容器工具加快入门速度：**  
[容器入门工具包](https://github.com/aws/amazon-gamelift-toolkit/tree/main/containers-starter-kit)可简化集成和实例集设置。它为游戏服务器添加核心游戏会话管理功能，并通过预配置的模板构建容器实例集和游戏服务器的自动化部署管道。部署完成后，可通过 Amazon GameLift Servers 控制台和 API 工具监控实例集性能、管理游戏会话并分析指标。
对于 Unreal Engine 或 Unity 开发者，可使用 [Amazon GameLift Servers 插件](https://github.com/amazon-gamelift/)在游戏引擎的开发环境内集成游戏服务器并构建容器实例集。该插件提供的引导式工作流程可帮助您借助托管容器创建基于云的快速、简单的托管解决方案。然后，在此基础上扩展，为游戏创建自定义托管方案。

## 容器实例集组件
<a name="containers-howitworks-components"></a>

**Fleet**  
容器实例集是 Amazon EC2 实例的集合，用于托管容器化游戏服务器。这些实例由 Amazon GameLift Servers 代为管理。创建实例集时，您需要配置如何将包含游戏服务器软件的容器架构部署到每个实例集实例。您可以创建包含单个或多个地理位置实例的容器实例集，并借助 Amazon GameLift Servers 扩展工具，根据所托管的游戏会话和玩家数量自动调整容器实例集的容量。

**实例**  
Amazon EC2 实例是为游戏托管提供计算容量的虚拟服务器。使用 Amazon GameLift Servers，您可以从一系列实例类型中进行选择。每种实例类型在 CPU、内存、存储和网络容量方面提供不同的组合配置。  
创建容器实例集时，Amazon GameLift Servers 会根据您选择的实例类型和实例集配置来部署容器。每个已部署的实例集实例均完全相同，并且以相同的方式运行您的容器化游戏服务器软件。实例集中的实例数决定了实例集的规模和游戏托管容量。

**容器组**  
Amazon GameLift Servers 使用容器组概念来描述和管理一组容器。容器组类似于容器“任务”或“pod”。在每个容器组中，您可以定义容器的行为方式、设置依赖关系以及共享可用的 CPU 和内存资源。  
每个实例集实例可以包含以下类型的容器组：  
+ **游戏服务器容器组**管理运行游戏服务器应用程序和支持软件的容器。容器实例集必须包含一个此类容器组，才能托管游戏会话和玩家。游戏服务器容器组可以在实例集实例之间进行复制。每个实例集实例的游戏服务器组副本数量取决于您的软件的计算要求和实例上可用的计算资源。
+ **每个实例的容器组**是可选的，支持您在每个实例集实例上运行其他软件。它们对于运行后台服务或实用程序非常有用，例如用于监控。您的游戏服务器软件不直接依赖于每个实例组中的进程。每个实例集实例仅部署一个每实例容器组副本。
容器实例集中的每个容器组都有一个被指定为“必备”的容器。必备容器主导着容器组的生命周期。如果必备容器出现故障，整个容器组将会重启。

**Container**  
容器是基于容器的架构中最基本的元素。它包含一个具有软件可执行文件和依赖文件的容器映像。通过定义容器，您可以配置软件的运行方式及其与 Amazon GameLift Servers 的交互方式。  
Amazon GameLift Servers 定义了两种类型的容器：  
+ **游戏服务器容器**包含运行游戏服务器进程和为玩家托管游戏会话所需的一切，包括游戏服务器生成包和依赖软件。需为实例集的游戏服务器容器组定义一个游戏服务器容器。该容器会被自动认定为容器组的必备容器。
+ **支持容器**用于运行其他软件来支持游戏服务器，其概念类似于“sidecar”容器。您可以选择与游戏服务器并行运行和扩展支持软件，同时将其作为单独的容器进行管理。在游戏服务器容器组中，您可以定义零个或多个支持容器。在每个实例容器组中，所有容器均为支持容器。任何支持容器都可指定为必备容器。

**计算**  
计算表示实例集实例上游戏服务器容器组的副本。

## 常见架构
<a name="containers-howitworks-architecture"></a>

下图展示了最简单的容器实例集结构。在此结构中，实例集中的每个实例均维护一个游戏服务器容器组的副本。该容器组包含一个游戏服务器容器，用于运行一个游戏服务器进程。在此示例中，容器实例集配置为每个实例放置一个游戏服务器容器组副本。采用此架构时，每个实例运行一个游戏服务器进程。

![\[一个简单的容器架构示例，游戏服务器容器组中只有一个游戏服务器容器。\]](http://docs.aws.amazon.com/zh_cn/gameliftservers/latest/developerguide/images/container_architecture_simple.png)


第二张图展示了一种更为复杂的容器实例集架构。在此结构中，实例集同时包含游戏服务器容器组和每个实例容器组。游戏服务器容器组包含单独的容器，分别用于游戏服务器进程和支持进程。实例集配置为在每个实例集实例上放置三个游戏服务器容器组副本。每个实例容器组则不会进行复制。在此示例中，容器实例集配置为每个实例放置三个游戏服务器容器组副本。采用此架构时，每个实例运行三个游戏服务器进程。

![\[容器架构示例，其游戏服务器容器组中有多个容器，每个实例容器组中有一个容器。\]](http://docs.aws.amazon.com/zh_cn/gameliftservers/latest/developerguide/images/container_architecture_complex.png)


## 核心功能
<a name="containers-howitworks-concepts"></a>

本节总结了 Amazon GameLift Servers 如何实现一些基本的容器概念。有关如何使用容器实例集的说明，请参阅本指南中的相关主题。

### 活动实例集更新
<a name="containers-howitworks-concepts-updating"></a>

托管容器提供高级支持，帮助您管理托管软件和容器架构的生命周期。您可以更新容器定义（包括容器映像），并将更改部署到现有实例集。借助此功能，可以更快速、更轻松地在开发过程中对容器进行迭代更改。它还提供一些功能，可帮助您持续构建、部署并跟踪软件版本更新。这些功能包括：
+ 管理容器组定义更新和版本控制。您可以更新容器组定义的几乎所有属性，包括容器映像和配置设置。每当您更新容器时，Amazon GameLift Servers 都会自动为该更新分配版本号，且默认保留所有版本。您可以访问任何特定版本，也可以根据需要删除版本。创建容器实例集时，需要指定要部署的容器组定义和版本。
+ 使用新的容器组定义和配置设置更新现有容器实例集。您可以将容器更新部署到已部署至实例集实例的实例集。您可以使用 AWS 管理控制台 或 AWS SDK 和 CLI 跟踪每个队列位置的更新部署状态。
+ 配置实例集更新在活跃实例集中的部署方式。
  + 游戏会话保护。选择保护包含活跃游戏会话的实例集实例，直至游戏会话结束（安全部署）。或者，也可以选择无论游戏会话活动如何，都替换实例集实例（非安全部署）。在开发和测试阶段使用非安全部署可以缩短部署时间。
  + 最低运行正常百分比。指定要在部署期间维护的正常运行任务的百分比。此功能允许您决定部署期间受影响的实例集实例数量。较低的数值会优先保证部署速度，而较高的数值则可确保游戏服务器在整个部署过程中保持较高的可用性。
  + 部署失败策略。决定部署失败时要采取的措施。部署失败指部分更新后的容器未通过状态检查，被判定为异常状态。您可以将部署设置为自动将所有实例集实例回滚到先前部署的状态。或者，您也可以选择保留部分异常的实例集实例以用于调试。

当您想为游戏服务器软件部署更新时，更新活跃实例集的功能非常有用。为游戏服务器构建新的容器映像后，部署流程分为两步：第一步，使用新映像更新容器组定义；第二步，更新容器实例集。Amazon GameLift Servers 会根据需要处理所有其他任务。

### 容器打包
<a name="containers-howitworks-concepts-packing"></a>

在开发用于部署到容器实例集中的容器结构时，核心目标之一是优化可用计算资源的利用率。为实现这一目标，需要将尽可能多的游戏服务器容器组打包到每个实例集实例上。

Amazon GameLift Servers 通过根据以下信息计算每个实例的最大游戏服务器容器组数来帮助实现此目的：
+ 实例集的实例类型及其 vCPU 和内存资源。
+ 游戏服务器容器组中所有容器的 vCPU 和内存要求。

  每个实例容器组（如果有）中所有容器的 vCPU 和内存要求。

创建容器实例集时，您可以使用计算得出的最大值，也可以指定所需的数量。作为最佳实践，应计划对容器化游戏服务器软件进行试验，以确定资源需求，实现最佳游戏服务器性能。

### 容量扩展
<a name="containers-howitworks-concepts-scaling"></a>

实例集容量衡量实例集可以同时托管的游戏会话数量。您也可以根据实例集可以支持的并发玩家数量来衡量容量。要增加或减少实例集的托管容量，您可以添加或移除实例集实例。

容器实例集配置为在每个实例集实例上运行特定数量的并发游戏服务器进程。（您可以根据（1）每个实例的游戏服务器容器组和（2）每个容器组中运行的游戏服务器进程数来计算此值。） 每个实例的并发游戏服务器数量可表明增减单个实例集实例所产生的影响。例如，如果您的容器实例集在每个游戏服务器容器组中运行 1 个游戏服务器进程，并且每个实例集实例包含 100 个游戏服务器容器组，则以 100 为增量增加或减少实例集托管并发游戏会话的容量。如果每个游戏会话包含 10 个玩家席位，则实例集的玩家承载容量将以 1000 为单位增减。

对于容器实例集，您可以使用 Amazon GameLift Servers 提供的任何容量扩展方法。这些方法包括：
+ 通过设置所需的实例集实例数来手动设置实例集容量。
+ 通过设定所需的可用实例缓冲区来设置自动扩展（目标跟踪）。此方法会自动维护一定数量的闲置托管资源，以便新玩家可以快速进入游戏。随着玩家需求的增加或减少，该缓冲区的大小会不断调整。
+ 使用自定义扩缩规则设置自动扩缩（高级功能）。此方法允许您根据自己选择的实例集指标进行扩展。

### 游戏 client/server 连接
<a name="containers-howitworks-concepts-networking"></a>

借助 Amazon GameLift Servers 托管实例集，游戏客户端可以直接连接到云托管游戏服务器。当游戏客户端要求加入游戏时，Amazon GameLift Servers 会找到游戏会话，并向游戏客户端提供连接信息（IP 和端口）。您可以通过为实例集开放特定端口范围（入站权限）来控制对实例集实例的外部访问。入站权限决定了哪些端口对传入流量开放。您可以快速关闭所有端口、仅开放少数端口，或者开放所有端口。

托管容器实例集需额外配置一项设置，以允许访问容器中运行的进程。创建容器定义时，需要指定一组端口，每个连接的进程对应一个端口。这包括：
+ 将在游戏服务器容器中同时运行的所有游戏服务器进程。所有游戏服务器进程都必须允许游戏客户端连接，以便其能够加入游戏会话。
+ 支持容器中需要外部源连接的任何进程。例如，您可以远程连接到测试应用程序。

设置面向内部的容器端口设置时，Amazon GameLift Servers使用它们来计算游戏客户端和其他应用程序可以连接的面向外部的入站权限。 Amazon GameLift Servers还管理入站权限和各个容器端口之间的映射，允许玩家访问容器中的游戏会话。这种内部映射通过防止直接访问容器端口，为游戏服务器提供了一层安全保护。您可以根据需要选择自定义实例集的面向外部的端口设置。有关手动设置容器实例集端口的更多信息，请参阅[配置网络连接](containers-design-fleet.md#containers-custom-network)。

您可以随时修改容器实例集的端口设置。此更改需要部署实例集更新。

下图展示了容器实例集中端口连接的作用。如图所示，您在各个容器上设置端口后，Amazon GameLift Servers 使用此信息在实例集实例上配置足够的端口，以映射到每个容器端口。除非您选择手动设置，否则面向外部的实例入站权限和面向内部的连接端口均由 Amazon GameLift Servers 为实例集计算。

![\[容器实例集的端口设置图示。端口映射使外部流量能够连接到实例集实例，并访问该实例上的单个容器。\]](http://docs.aws.amazon.com/zh_cn/gameliftservers/latest/developerguide/images/container_design_networking.png)


### 容器日志记录
<a name="containers-howitworks-concepts-logging"></a>

在托管容器实例集中，会捕获所有容器的标准输出（和标准错误）流。这包括游戏服务器的游戏会话日志。您可以将容器实例集配置为使用以下几个选项之一来处理输出流：
+ 将容器输出保存为 Amazon CloudWatch 日志流。每个日志流都引用实例集 ID 和容器。如果您为队列选择此日志记录选项，则可以指定一个 CloudWatch 日志组，该组将组织队列中的所有日志流。然后，您可以根据需要使用 CloudWatch 功能来搜索和分析日志数据。
+ 将容器输出保存到 Amazon Simple Storage Service（Amazon S3）存储桶中。您可以根据需要查看、共享或下载内容。
+ 禁用日志记录。在此情况下，不会保存容器输出。

Amazon GameLift Servers将托管集装箱船队的日志数据发送到您 AWS 账户中的 CloudWatch 或 Amazon S3 服务。要查看您的数据，请登录您的 AWS 账户并使用各项服务，使用 AWS 管理控制台 或其他工具。通过为容器实例集创建服务角色，您可以将有限的访问权限扩展到 Amazon GameLift Servers 以执行这些操作。

您可以随时修改容器实例集的日志记录配置。此更改需要部署实例集更新。

### 容器实例集和 Amazon GameLift Servers 代理
<a name="containers-howitworks-concepts-agent"></a>

常用的容器架构会在每个容器中运行一个进程。在 Amazon GameLift Servers 容器实例集中，游戏服务器容器组有一个游戏服务器容器，其中运行一个游戏服务器进程。采用此架构时，Amazon GameLift Servers 会管理实例集实例上每个游戏服务器容器组中单个游戏服务器进程的生命周期。

如果您选择构建在每个游戏服务器容器组中运行多个游戏服务器进程的容器架构，则需要一种方法来管理所有进程的生命周期。这包括根据需要启动、关闭和替换进程、管理要同时运行的所需数量的进程以及处理故障状态等任务。

您可以选择使用 Amazon GameLift Servers 代理来执行这些任务。对于容器实例集，该代理会执行运行时指令，指定要运行的可执行文件（以及运行数量），提供启动参数并设置游戏服务器激活规则。例如，运行时指令可能会指示代理维护 10 个用于生产环境的游戏服务器进程，以及一个带有特殊启动参数、用于测试的游戏服务器进程。

要在容器实例集中使用代理，请将代理添加到您的容器映像中，并附上一组运行时说明。有关代理的更多信息，请参阅[使用 Amazon GameLift Servers 代理](integration-dev-iteration-agent.md)。