web-dev-qa-db-fra.com

Elastic IP sur l'application déployée à l'aide d'Elastic Beanstalk

Je suis un peu confus quant à l'utilisation du service Elastic IP proposé par Amazazon Web Services. Je suppose que l'idée principale est que je peux passer à une nouvelle version de l'application Web sans interruption en suivant cette procédure simple:

  1. Déployer la nouvelle version sur une nouvelle instance EC2
  2. Configurez correctement la nouvelle version et testez-la à l'aide d'une base de données intermédiaire
  3. Une fois correctement testée, faites en sorte que cette nouvelle version utilise la base de données en direct
  4. Associez l'IP élastique à cette instance
  5. Mettre fin à tous les services inutiles (base de données intermédiaire et ancienne instance EC2)

Est-ce la manière courante de déployer une nouvelle version d'une application Web?

Maintenant, que se passe-t-il si l'application est mise à l'échelle sur plusieurs instances? J'ai configuré la mise à l'échelle automatique dans les paramètres Elastic Beanstalk et cela a créé un équilibreur de charge (je peux le voir dans la section EC2 de l'AWS Management Console). Le problème est que je ne peux apparemment pas associer l'IP Elastic à l'équilibreur de charge, je dois l'associer à une instance existante. À quel cas dois-je l'associer? Je suis confus...

Désolé si certaines questions peuvent sembler stupides, mais je ne suis qu'un programmeur et c'est la première fois que je configure un système cloud.

Je vous remercie!

41
satoshi

Elastic Load Balancing (ELB) ne fonctionne pas avec adresses IP Amazon EC2 Elastic , en fait, les deux concepts ne vont pas du tout ensemble.

Élasticité via l'équilibrage de charge élastique

Au lieu de cela, ELB est généralement utilisé via enregistrements CNAME (mais voir ci-dessous), et cela fournit le premier niveau d'élasticité/disponibilité en permettant à l'adresse DNS aliasée de changer l'IP des ELB en cours d'utilisation , si besoin est. Le deuxième niveau d'élasticité/disponibilité est effectué par l'équilibreur de charge lors de la répartition du trafic entre les instances EC2 que vous avez enregistrées.

Pensez-y de cette façon: le CNAME ne change jamais (tout comme Adresse IP élastique) et le remplacement des instances EC2 est géré via l'équilibreur de charge, Auto Scaling , ou vous-même (en enregistrant/désinscrivant des instances).

Ceci est expliqué plus en détail dans l'excellente analyse de Shlomo Swidler "L'élastique" dans "Elastic Load Balancing": ELB Elasticity and How to Test it , qui à son tour se réfère à la récente fournie Best Practices in Evaluating Elastic Load Balancing par AWS, qui confirme son analyse et fournit une bonne lecture globale concernant L'architecture du service Elastic Load Balancing et son fonctionnement en soi (mais il manque exemples illustratifs étape par étape fournis par Shlomo).

Noms de domaine

Veuillez noter que l'ancienne limitation nécessitant un CNAME a été corrigée entre-temps par des ajouts respectifs à Amazon Route 5 pour permettre au domaine racine (ou Zone Apex) d'être également utilisé , consultez la section Alias ​​et Apex de la zone dans Aller de l'avant avec Amazon Route 5 pour un aperçu rapide et tilisation de noms de domaine avec équilibrage de charge élastique pour plus de détails.

Élasticité via Elastic Beanstalk

D'abord et avant tout, AWS Elastic Beanstalk utilise à tour de rôle Elastic Load Balancing comme décrit ci-dessus. En plus si cela, il ajoute la gestion du cycle de vie des applications:

AWS Elastic Beanstalk est un moyen encore plus simple pour vous de déployer et de gérer rapidement des applications dans le cloud AWS. Vous téléchargez simplement votre application et Elastic Beanstalk gère automatiquement les détails de déploiement du provisionnement de capacité, de l'équilibrage de charge, de la mise à l'échelle automatique et de la surveillance de l'intégrité de l'application. [...] [c'est moi qui souligne]

Ceci est réalisé en ajoutant le concept d'un Environnement dans le mélange, ce qui est expliqué dans Vue d'ensemble de l'architecture :

L'environnement est au cœur de l'application. [...] Lorsque vous créez un environnement, AWS Elastic Beanstalk provisionne les ressources nécessaires pour exécuter votre application. Les ressources AWS créées pour un environnement incluent un équilibreur de charge élastique (ELB dans le diagramme), un groupe Auto Scaling et une ou plusieurs instances Amazon EC2.

Veuillez noter que Chaque environnement a un CNAME (URL) qui pointe vers un équilibreur de charge, c'est-à-dire comme utiliser un ELB seul.

Tout cela est réuni dans Gestion et configuration des applications et des environnements , qui décrit en détail certaines des fonctionnalités les plus importantes d'AWS Elastic Beanstalk, y compris des exemples d'utilisation à l'aide d'AWS Management Console, CLI et les API.

Aucun temps d'arrêt

Il est difficile d'identifier la partie la plus pertinente à des fins d'illustration, mais Déploiement de versions avec zéro temps d'arrêt répond précisément à votre cas d'utilisation et implique toutes les étapes précédentes requises (par exemple Création de nouvelles versions d'application et Lancement de nouveaux environnements ), donc la lecture de la section AWS Management Console pourrait vous donner la meilleure image globale du fonctionnement de cette plateforme.

Bonne chance!

62
Steffen Opel

En plus des options décrites dans la réponse impressionnante de Steffen, Elastic Beanstalk semble avoir très récemment activé Elastic IP en option si vous n'avez pas besoin de l'intégralité fonctionnalités d'un Elastic Load Balancer (comme la mise à l'échelle automatique au-delà d'une instance).

Je décris l'option dans ma réponse à une question similaire . Elastic Beanstalk vous permet désormais de choisir entre deux types d'environnement , et l'option Single-instance crée une adresse IP élastique.

Dropdown with options "Single instance" and "Load balancing, autoscaling".


Je pense que l'utilisation d'un ELB sera l'option préférable dans la plupart des cas, mais par ex. pour un serveur de transfert, c'est bien d'avoir une alternative moins complexe (et moins chère).

14
lime

Toutes mes excuses pour avoir répondu à un message quelques années plus tard, cependant pour ceux qui ont réellement besoin d'un ensemble d'adresses IP statiques sur un ELB, il est possible de demander gentiment à AWS d'ajouter ce qu'ils appellent des adresses `` IP stables '' à un ELB, et ainsi lui donner cette fonction d'adresse IP statique.

Ils n'aiment pas du tout faire cela bien sûr - mais le feront si vous pouvez le justifier (la principale justification est lorsque vous avez des clients qui ont des restrictions de liste blanche IP sur les connexions sortantes via leurs pare-feu et qui ne veulent absolument pas bouger sur cette position).

Sachez simplement que l'option de mise à l'échelle automatique basée sur le trafic n'est plus simple - AWS ne pourrait pas ajouter dynamiquement plus de points de terminaison ELB à votre ELB comme ils le font avec la solution prête à l'emploi et vous devez passer par la douleur d'ouvrir de nouvelles adresses IP avec vos clients au fil du temps.

Pour la question d'origine cependant, EB utilisant un ELB pour faire face aux instances EC2 où les adresses IP statiques ne sont pas réellement requises (pas de problèmes de pare-feu sortant du client) est le meilleur moyen selon la réponse acceptée.

4
PhillipHolmes

J'ai écrit n article décrivant comment accomplir cela en utilisant une règle Cloudwatch lorsqu'une nouvelle instance est lancée et une fonction lambda. Voici le code de la fonction 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);
  }
};

0
Alex Sharp