我有一个VPC
带有公共子网和私有子网的子网。
- 公共子网包含我的
Nating
和Bastion
实例 - 私有子网包含我的应用服务器(3 个
ec2
实例,运行带有我的项目 war 文件的 tomcat7)。这 3 个实例位于ELB
每当我想要更新 war 文件时,我可以用两种方式来实现。
手动的
- 我将新的 war 文件上传到 S3 bucket
- SSH 到
Bastion
服务器(只有这可以通过 SSH 连接) - 从这里 SSH 到私有实例
- 从 S3 下载 war 文件,停止 tomcat7 替换旧 war(并删除目录)
- 启动 tomcat
我对每个实例重复上述步骤(目前有 3 个实例)
半手动 步骤如下
- 将新战争上传到S3存储桶
- 终止一个实例(从 AWS 网站的控制面板)
- 缩放和启动配置自动启动,以维持最低数量的实例。这将启动一个新实例并执行一个脚本,该脚本实际上从 S3 下载 war 以及一些其他环境设置和文件夹等。
- 当我看到新实例已创建、启动并运行并添加到 ELB 时,我会终止另一个旧实例。
- 这样,我就可以逐个杀死所有旧实例,并用最新升级的新实例替换它们。
第一种方法很快,但需要很多手动步骤。通过 SSH 进出实例(仅允许从 BASTION 服务器在实例上使用 SSH)。下载、停止、替换、启动。
第二种方法很慢,而且实际上不是自动的。旧实例终止时间 + 新实例启动时间 + 部署新战争
我想实现以下目标
- 自动化升级过程(单击按钮)
- 非开发人员(例如 QA 和支持人员)无需访问 AWS 网站或 SSH 密钥即可进行升级
- 快速升级
- 失败时回滚
有人可能会想为什么我不使用 Beanstalk,它很简单,只需上传新的 war 文件,如果出现任何问题,使用回滚功能自动升级所有实例?
以下是我的理由(有些事情可能只是我的假设或缺乏知识)。
- 应用程序的总体架构是复杂的,VPC 包含 9 个子网,以及私有子网和公共子网中的大量 ec2 实例。以及使用安全组的复杂安全配置
- 我自己命名习俗对于子网 (Public_Subnet_A、Public_Subnet_B、Private_WEB_A、Private_WEB_B、Private_API_A、SG_GLOBAL、SG_BASTION、SG_BASTION 等等)。我没有看到在 ElasticBeanstalk 中执行此操作的方法。
- Beanstalk 仅支持有限预定义模板用于预定义环境。比如我希望我的实例基于 Ubuntu,有 Tomcat7,运行 Java6 或 7 以及其他一些。
- Beanstalk for Java 应用程序运行 tomcat8、amazon-instance,它还将 tomcat 置于 Apache 后面(我认为桥接是通过完成的
mode_jk
),然后这个 Apache 位于 ELB 后面。我认为 ELB->Apache-mode_jk->tomcat 有点过头了(我错了)。 - 我正在使用 ELB->tomcat 方法
- 我的出站流量是通过NATing服务器,理论上,外界没有办法知道实例。
- 在 beanstalk 实例中可以直接访问。但在我的环境中这是不可能的,你只能 ssh堡垒使用 ssh-key 和一些 sudo-random 用户名(我认为很难猜)从特定 IP 连接实例,而私有实例只能通过 BASTION 进行 SSH(自定义安全组配置)。
- 类似地,我的 RDS 实例也位于我指定的私有子网之一中,并且只有应用程序的 API 实例可以连接到数据库(告诉您很多自定义配置)。
- 还有一些其他的。
现在您已经了解了背景。让我们继续讨论我在上面解释的示例的简单版本。
我希望升级能够快速且自动,并且不要使用第三方工具与这些工具共享我的凭据(我听说过一些基于云的工具可以为您提供透明度并在您选择的云环境中执行所有任务)。
我唯一能想到的就是编写一个 ANT 脚本或一些 Java 代码,它可以执行第一种方法中解释的所有步骤。但不确定他们是否被允许在 aws 上执行这些操作。
答案1
同样的问题,在花了大约两天多的时间后,我意识到有一个名为“通过 SSH 发布 jenkins 工件”的插件(如果您有 CI),并进行了一些配置更改以允许 NAT 与 jenkins 服务器通信,至少这对我来说是有效的。
我确实有相同的设置,作为私有子网中的服务器和公共子网中的 NAT,从那里我通过 ssh 将 war 部署到私有机器。
希望这可以帮助!
答案2
使用 CodeDeploy,你已经在 S3 存储桶中拥有了 war,所以你唯一需要的就是 aws clihttps://docs.aws.amazon.com/cli/latest/reference/deploy/create-deployment.html命令。
为了实现此功能,您需要在实例上使用 CodeDeploy 代理 - 您可以按照此操作https://docs.aws.amazon.com/codedeploy/latest/userguide/codedeploy-agent-operations-install-linux.html
CodeDeploy 代理需要一个简单的配置文件和至少一个配置脚本(将 .war 文件复制到 Tomcat + 重新加载服务)。
CodeDeploy 可以根据标签或自动扩展组更新实例。我还建议将您的实例放入自动扩展组中,但这可以作为第二步完成。
可以在更新前从 ELB(备用)中删除实例,并在更新后将其放回,这样您就可以实现零停机时间。结合健康检查,您可以获得完全自动化的解决方案。
使用 CodeDeploy,您可以获得与 Beanstalk 类似的功能,同时仍可保持直接访问实例和使用自己的模板的灵活性。这些实例也根本不需要通过互联网访问。