简体   繁体   English

使用 Elastic Beanstalk 部署的应用程序上的 Elastic IP

[英]Elastic IP on application deployed using Elastic Beanstalk

I'm a bit confused about the use of the Elastic IP service offered by Amazazon Web Services.我对亚马逊 Web 服务提供的 Elastic IP 服务的使用有点困惑。 I guess the main idea is that I can switch to a new version of the web application with no downtime following this simple procedure:我想主要的想法是我可以按照这个简单的过程切换到 web 应用程序的新版本而无需停机:

  1. Deploy the new version on a new EC2 instance在新的 EC2 实例上部署新版本
  2. Configure the new version properly and test it using a staging DB正确配置新版本并使用暂存数据库对其进行测试
  3. Once properly tested, make this new version use the live DB正确测试后,让这个新版本使用实时数据库
  4. Associate the Elastic IP to this instance将 Elastic IP 关联到此实例
  5. Terminate all the useless services (staging DB and old EC2 instance)终止所有无用的服务(暂存数据库和旧的 EC2 实例)

Is this the common way to deploy a new version of a web application?这是部署新版本 web 应用程序的常用方法吗?

Now, what if the application is scaled on more instances?现在,如果应用程序在更多实例上扩展怎么办? I configured the auto scaling in the Elastic Beanstalk settings and this created a load balancer (I can it see in the EC2 section of the AWS Management Console).我在 Elastic Beanstalk 设置中配置了自动缩放,这创建了一个负载均衡器(我可以在 AWS 管理控制台的 EC2 部分看到它)。 The problem is that I apparently cannot associate the Elastic IP with the load balancer, I have to associate it with an existing instance.问题是我显然无法将 Elastic IP 与负载均衡器相关联,我必须将其与现有实例相关联。 To which instance should I associate it to?我应该将它关联到哪个实例? I'm confused...我糊涂了...

Sorry if some questions may sound stupid but I'm only a programmer and this is the first time I set up a cloud system.对不起,如果有些问题听起来很愚蠢,但我只是一名程序员,这是我第一次建立云系统。

Thank you!谢谢!

Elastic Load Balancing (ELB) does not work with Amazon EC2 Elastic IP addresses , in fact the two concepts do not go together at all. Elastic Load Balancing (ELB)不适用于Amazon EC2 弹性 IP 地址,实际上这两个概念根本不适合。

Elasticity via Elastic Load Balancing通过 Elastic Load Balancing 实现弹性

Rather, ELB is usually used via CNAME records (but see below), and this provides the first level of elasticity/availability by allowing the aliased DNS address to change the IP of the ELB(s) in use, if need be.相反,ELB 通常通过CNAME 记录使用(但见下文),如果需要,这通过允许别名 DNS 地址更改正在使用的 ELB 的 IP 来提供第一级弹性/可用性。 The second level of elasticity/availability is performed by the load balancer when distributing the traffic between the EC2 instances you have registered.第二级弹性/可用性由负载均衡器在您注册的 EC2 实例之间分配流量时执行。

Think of it this way: The CNAME never changes (just like the Elastic IP address ) and the replacement of EC2 instances is handled via the load balancer, Auto Scaling , or yourself (by registering/unregistering instances).可以这样想:CNAME 永远不会改变(就像弹性 IP 地址一样)并且 EC2 实例的替换是通过负载均衡器、 Auto Scaling或您自己(通过注册/取消注册实例)来处理的。

This is explained in more detail within Shlomo Swidler's excellent analysis The “Elastic” in “Elastic Load Balancing”: ELB Elasticity and How to Test it , which in turn refers to the recently provided Best Practices in Evaluating Elastic Load Balancing by AWS, which confirm his analysis and provide a good overall read regarding the Architecture of the Elastic Load Balancing Service and How It Works in itself (but lacks the illustrative step by step samples Shlomo provides).这在 Shlomo Swidler 出色的分析“Elastic Load Balancing”中的“Elastic”:ELB Elasticity and How to Test it中有更详细的解释,这反过来又指最近提供的 AWS评估 Elastic Load Balancing最佳实践,这证实了他的分析并提供了关于Elastic Load Balancing Service架构及其本身的工作原理的良好整体阅读(但缺少 Shlomo 提供的说明性分步示例)。

Domain Names网站域名

Please note that the former limitation requiring a CNAME has meanwhile been addressed by respective additions to Amazon Route 53 to allow the root domain (or Zone Apex ) being used as well, see section Aliases and the Zone Apex within Moving Ahead With Amazon Route 53 for a quick overview and Using Domain Names with Elastic Load Balancing for details.请注意,之前要求 CNAME 的限制同时已通过对Amazon Route 53的相应添加得到解决,以允许也使用根域(或Zone Apex ),请参阅“ Moving Ahead With Amazon Route 53”中的别名和区域 Apex部分了解快速概览和将域名与 Elastic Load Balancing 结合使用以了解详细信息。

Elasticity via Elastic Beanstalk通过 Elastic Beanstalk 实现弹性

First and foremost, AWS Elastic Beanstalk uses Elastic Load Balancing in turn as described above.首先, AWS Elastic Beanstalk如上所述依次使用 Elastic Load Balancing。 On top if that, it adds application lifecycle management:最重要的是,它添加了应用程序生命周期管理:

AWS Elastic Beanstalk is an even easier way for you to quickly deploy and manage applications in the AWS cloud. AWS Elastic Beanstalk 是一种更简单的方法,可让您在 AWS 云中快速部署和管理应用程序 You simply upload your application, and Elastic Beanstalk automatically handles the deployment details of capacity provisioning, load balancing, auto-scaling, and application health monitoring.您只需上传应用程序,Elastic Beanstalk 就会自动处理容量供应、负载平衡、自动扩展和应用程序运行状况监控的部署细节。 [...] [emphasis mine] [...] [强调我的]

This is achieved by adding the concept of an Environment into the mix, which is explained in the Architectural Overview :这是通过将环境的概念添加到组合中来实现的,这在架构概述中进行了解释:

The environment is the heart of the application.环境是应用程序的核心。 [...] When you create an environment, AWS Elastic Beanstalk provisions the resources required to run your application. [...] 当您创建环境时,AWS Elastic Beanstalk 会预置运行您的应用程序所需的资源。 AWS resources created for an environment include one elastic load balancer (ELB in the diagram), an Auto Scaling group, and one or more Amazon EC2 instances.为环境创建的 AWS 资源包括一个弹性负载均衡器(图中的 ELB)、一个 Auto Scaling 组和一个或多个 Amazon EC2 实例。

Please note that Every environment has a CNAME (URL) that points to a load balancer , ie just like using an ELB on its own.请注意,每个环境都有一个指向负载均衡器的 CNAME (URL) ,即就像单独使用 ELB 一样。

All this comes together in Managing and Configuring Applications and Environments , which discusses some of the most important features of AWS Elastic Beanstalk in detail, including usage examples using the AWS Management Console, CLI, and the APIs .所有这些都集中在管理和配置应用程序和环境中,其中详细讨论了 AWS Elastic Beanstalk 的一些最重要的功能,包括使用 AWS 管理控制台、CLI 和 API 的使用示例

Zero Downtime零停机时间

Its hard to identify the most relevant part for illustration purposes, but Deploying Versions With Zero Downtime precisely addresses your use case and implies all required preceding steps (eg Creating New Application Versions and Launching New Environments ), so reading section AWS Management Console might give you the best overall picture how this platform works.出于说明目的,很难确定最相关的部分,但在零停机时间部署版本准确地解决了您的用例并暗示了所有必需的先前步骤(例如, 创建新的应用程序版本启动新环境),因此阅读AWS 管理控制台部分可能会给您该平台如何运作的最佳整体画面。

Good luck!祝你好运!

In addition to the options described in Steffen's awesome answer, Elastic Beanstalk seems to have very recently enabled Elastic IP as an option if you don't need the full features of an Elastic Load Balancer (like auto-scaling beyond one instance).除了 Steffen 的精彩回答中描述的选项之外,如果您不需要 Elastic Load Balancer 的全部功能(例如自动扩展超过一个实例),Elastic Beanstalk 似乎最近启用了弹性 IP作为选项。

I describe the option in my answer to a similar question .我在对类似问题的回答中描述了该选项。 Elastic Beanstalk now allows you to choose between two Environment Types , and the Single-instance option creates an Elastic IP. Elastic Beanstalk 现在允许您在两种环境类型之间进行选择,并且单实例选项会创建一个弹性 IP。

带有“单实例”和“负载平衡、自动缩放”选项的下拉菜单。


I think using an ELB will be the preferable option in most cases, but eg for a staging server it is nice to have an alternative that is less complex (and cheaper).我认为在大多数情况下使用 ELB 将是更可取的选择,但例如对于登台服务器,最好有一个不那么复杂(而且更便宜)的替代方案。

Apologies for answering a post a few years later, however for those that do actually need a set of static IP addresses on an ELB, it is possible to ask AWS nicely to add what they call 'Stable IP' addresses to an ELB, and thereby give it that static IP address feature.很抱歉几年后回答了一个帖子,但是对于那些确实需要 ELB 上的一组静态 IP 地址的人,可以很好地要求 AWS 将他们所谓的“稳定 IP”地址添加到 ELB,从而给它静态 IP 地址功能。

They don't like doing this at all of course - but will if you can justify it (the main justification is when you have clients that have IP whitelist restrictions on outbound connections via their firewalls and are completely unwilling to budge on that stance).他们当然不喜欢这样做 - 但如果你能证明它是合理的(主要的理由是当你的客户通过他们的防火墙对出站连接有 IP 白名单限制并且完全不愿意在这种立场上让步时)。

Just be aware that the 'auto scaling' based on traffic option isn't straight forward any more - AWS would be unable to dynamically add more ELB endpoints to your ELB as they do with the out of the box solution and you have to go through the pain of opening up new IP addresses with your customers over time.请注意,基于流量选项的“自动缩放”不再是直截了当的 - AWS 将无法像使用开箱即用的解决方案那样向您的 ELB 动态添加更多 ELB 端点,您必须通过随着时间的推移,向客户开放新 IP 地址的痛苦。

For the original question though, EB using an ELB to front EC2 instances where static IP addresses are not actually required (no client outbound firewall issues) is the best way as per the accepted answer.不过,对于最初的问题,EB 使用 ELB 来前置 EC2 实例,其中实际上不需要静态 IP 地址(没有客户端出站防火墙问题)是根据接受的答案的最佳方法。

In the case that none of the above solutions works, one alternative is to attach a NAT gateway to a private subnet and associate an EIP with the NAT gateway.如果上述解决方案都不起作用,一种替代方法是将 NAT 网关附加到私有子网,并将 EIP 与 NAT 网关关联。 In this case you're able to use the ELB, use auto-scaling, and have a reserved EIP.在这种情况下,您可以使用 ELB,使用自动缩放,并拥有一个保留的 EIP。

This is a bit more expensive though, especially for large throughput use cases.不过,这有点贵,尤其是对于大吞吐量用例。 Also, SSHing into the instance to debug becomes a bit more complex.此外,通过 SSH 连接到实例进行调试变得有点复杂。

You can set the environment as a Single Instance as stated in the already accepted answer, or if you want to use an Elastic IP that you have already created, you can do the following.您可以按照已接受的答案中的说明将环境设置为单实例,或者如果您想使用已经创建的 Elastic IP,则可以执行以下操作。

Inside of the .ebextensions folder at the root of your project, make a file called setup.config and paste in the following:在项目根目录的.ebextensions文件夹中,创建一个名为setup.config的文件并粘贴以下内容:

container_commands:
    00_setup_elastic_ip:
        command: |
            export AWS_ACCESS_KEY_ID={YOUR-ACCESS-KEY-ID}
            export AWS_SECRET_ACCESS_KEY={YOUR-SECRET-ACCESS-KEY}
            export AWS_DEFAULT_REGION=us-east-1    
            INSTANCE_ID=$(ec2-metadata -i)
            words=( $INSTANCE_ID )
            EC2_ID="${words[1]}"
            aws ec2 associate-address --instance-id $EC2_ID --allocation-id {eipalloc-ID-TO-THE-IP}

All you have to do is replace the 3 parts contained inside of the {} and you are good to go. This will replace the IP of your Elastic Beanstalk instance with the Elastic IP of your choosing.您所要做的就是替换{}中包含的 3 个部分,您可以使用 go。这会将您的 Elastic Beanstalk 实例的 IP 替换为您选择的 Elastic IP。

The parts contained in {} are (get rid of the {} though, that is just there to show you which parts to replace with your info): {}中包含的部分是(尽管去掉了 {},那只是为了告诉您哪些部分要替换为您的信息):

  1. Your AWS Access Key ID您的 AWS 访问密钥 ID
  2. Your AWS Secret Access Key您的 AWS 秘密访问密钥
  3. the allocation ID of the Elastic IP you want to assign to your Elastic Beanstalk environment's instance.您要分配给 Elastic Beanstalk 环境实例的 Elastic IP 的分配 ID。

I wrote a post describing how to accomplish this using a Cloudwatch rule when a new instance is launched, and a lambda function.我写了一篇文章,描述了如何在启动新实例时使用 Cloudwatch 规则和 lambda 函数来完成此操作。 Here's the lambda function code:这是 lambda 函数代码:

const AWS = require('aws-sdk');
const ec2 = new AWS.EC2();
const PROD_ENV_NAME = 'my-prod-env-name';

// Example Event
// {
//   "version": "0",
//   "id": "ee376907-2647-4179-9203-343cfb3017a4",
//   "detail-type": "EC2 Instance State-change Notification",
//   "source": "aws.ec2",
//   "account": "123456789012",
//   "time": "2015-11-11T21:30:34Z",
//   "region": "us-east-1",
//   "resources": [
//     "arn:aws:ec2:us-east-1:123456789012:instance/i-abcd1111"
//   ],
//   "detail": {
//     "instance-id": "i-abcd1111",
//     "state": "running"
//   }
// }

exports.handler = async (event) => {
  console.log("EVENT:", event);

  // The newly launched instance ID.
  const instanceId = event.detail['instance-id'];

  // Fetch info about the newly launched instance
  const result = await ec2.describeInstances({
    Filters: [ { Name: "instance-id", Values: [instanceId] } ]
  }).promise()

  // The instance details are buried in this object
  const instance = result.Reservations[0].Instances[0];
  const isAttached = instance.NetworkInterfaces.find(int => int.Association.IpOwnerId !== 'amazon');

  // Bail if the instance is already attached to another EIP
  if (isAttached) {
    console.log("This instance is already assigned to an elastic IP")
    return { statusCode: 200, body: '' }
  }

  // In elastic beanstalk, the instance name gets assigned to the enviroment name.
  // There is also an environment name tag, which could be used here.
  const name = instance.Tags.find(t => t.Key === 'Name').Value;

  // Only assign EIPs to production instances
  if (name !== PROD_ENV_NAME) {
    console.log('Not a production instance. Not assigning. Instance name:', name)
    return { statusCode: 200, body: ''}
  }

  // Get a list of elastic IP addresses
  const addresses = await ec2.describeAddresses().promise();

  // Filter out addresses already assigned to instances
  const availableAddresses = addresses.Addresses.filter(a => !a.NetworkInterfaceId);

  // Raise an error if we have no more available IP addresses
  if (availableAddresses.length === 0) {
    console.log("ERROR: no available ip addresses");
    return { statusCode: 400, body: JSON.stringify("ERROR: no available ip addresses") }
  }

  const firstAvail = availableAddresses[0]
  try {
    // Associate the instance to the address
    const result = await ec2.associateAddress({
      AllocationId: firstAvail.AllocationId,
      InstanceId: instanceId
    }).promise();

    console.log('allocation result', result)

    return { statusCode: 200, body: JSON.stringify('Associated IP address.') };
  } catch (err) {
      console.log("ERROR: ", err);
  }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Flask 应用程序未在 AWS elastic beanstalk 上部署 - Flask Application is not getting deployed at AWS elastic beanstalk 使用 Puma 在 Elastic Beanstalk 上部署的 Rails 应用程序失败 - 每个请求都出现 502 错误 - Rails application deployed on Elastic Beanstalk with Puma fails - 502 errors on every request 使用 api-platform 动态路由的 symfony 6.2 在@localhost 上工作,但在使用 elastic beanstalk 部署在 AWS 上时不起作用 - symfony 6.2 using api-platform dynamic routes work @localhost but not when deployed on AWS using elastic beanstalk 无法在弹性 beantalk 中运行后台应用程序 - Failed to run a background application in elastic beanstalk 在一个应用程序 Elastic Beanstalk 中测试和生产版本? - Test and Prod Version in One Application Elastic Beanstalk? 无法使用已安装的弹性文件系统部署 Elastic Beanstalk 应用程序 - Unable to deploy Elastic Beanstalk Application with mounted Elastic File System Github 动作将 django 应用程序部署到弹性 beanstalk - Github actions deploy django application to elastic beanstalk 带有 HTTPS 的 Elastic Beanstalk 应用程序上的 502 Bad Gateway - 502 Bad Gateway on Elastic Beanstalk application with HTTPS 部署到 AWS elastic beanstalk 时,CSRF 验证失败并出现 403 错误 - CSRF verification failed with 403 error when deployed to AWS elastic beanstalk 速率限制 a Flask API 部署在 AWS Elastic Beanstalk - Rate limit a Flask API deployed on AWS Elastic Beanstalk
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM