基于AWS CodeDeploy与负载均衡的多应用多端口部署问题咨询
Alright, let's break down how to make this work for your multi-port EC2 setup with AWS CodeDeploy and a load balancer—no dropped requests guaranteed. Here's a step-by-step approach tailored to your 4 instances running 3 apps each on ports 81/82/83:
First, you need to map each app to its own target group (since each runs on a unique port):
- Create 3 target groups:
app1-tg(port 81),app2-tg(port 82),app3-tg(port 83) - Add all 4 EC2 instances to each target group (each instance will be registered with its respective port for each group)
- For each target group:
- Set a drain timeout (under Target Group Attributes) to 60-120 seconds—this gives the load balancer time to finish processing in-flight requests before stopping traffic to the instance
- Configure health checks to match each app's health endpoint (e.g.,
/healthon port 81 for app1)
When setting up your CodeDeploy deployment group:
- Select EC2/On-premises as the platform
- Under "Load balancing", check "Enable load balancing" and select your load balancer type (ALB/NLB)
- Add all 3 target groups you created earlier—this tells CodeDeploy to manage instance registration/deregistration across all groups for your multi-port apps
- Choose a rolling deployment strategy (e.g.,
CodeDeployDefault.HalfAtATimeor a custom rule) to ensure only a subset of instances are taken down at once, keeping the rest online to handle traffic - Ensure your EC2 instances have the CodeDeploy agent installed and an IAM role with permissions for
elasticloadbalancing:RegisterTargets,elasticloadbalancing:DeregisterTargets, and CodeDeploy operations
Your appspec.yml will orchestrate the instance drain/register process across all three ports. Here's a working template:
version: 0.0 os: linux hooks: # Deregister instance from all target groups before installing new code BeforeInstall: - location: scripts/deregister_all_targets.sh timeout: 300 runas: root # Start your updated app processes ApplicationStart: - location: scripts/start_all_apps.sh timeout: 300 runas: root # Re-register instance once apps are healthy AfterApplicationStart: - location: scripts/register_all_targets.sh timeout: 300 runas: root
Example Scripts
deregister_all_targets.sh
This script pulls the current instance ID and removes it from all three target groups, then waits for connections to drain:
#!/bin/bash set -e # Get current EC2 instance ID INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) # Replace these ARNs with your actual target group ARNs TG_ARN_APP1="arn:aws:elasticloadbalancing:us-east-1:YOUR_ACCOUNT_ID:targetgroup/app1-tg/YOUR_TG_ID" TG_ARN_APP2="arn:aws:elasticloadbalancing:us-east-1:YOUR_ACCOUNT_ID:targetgroup/app2-tg/YOUR_TG_ID" TG_ARN_APP3="arn:aws:elasticloadbalancing:us-east-1:YOUR_ACCOUNT_ID:targetgroup/app3-tg/YOUR_TG_ID" # Deregister from each target group with the correct port aws elbv2 deregister-targets --target-group-arn $TG_ARN_APP1 --targets Id=$INSTANCE_ID,Port=81 aws elbv2 deregister-targets --target-group-arn $TG_ARN_APP2 --targets Id=$INSTANCE_ID,Port=82 aws elbv2 deregister-targets --target-group-arn $TG_ARN_APP3 --targets Id=$INSTANCE_ID,Port=83 # Wait for drain timeout (match your target group's drain setting) sleep 90
register_all_targets.sh
This script re-registers the instance to all target groups once apps are running:
#!/bin/bash set -e INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) TG_ARN_APP1="arn:aws:elasticloadbalancing:us-east-1:YOUR_ACCOUNT_ID:targetgroup/app1-tg/YOUR_TG_ID" TG_ARN_APP2="arn:aws:elasticloadbalancing:us-east-1:YOUR_ACCOUNT_ID:targetgroup/app2-tg/YOUR_TG_ID" TG_ARN_APP3="arn:aws:elasticloadbalancing:us-east-1:YOUR_ACCOUNT_ID:targetgroup/app3-tg/YOUR_TG_ID" # Register instance with each app's port aws elbv2 register-targets --target-group-arn $TG_ARN_APP1 --targets Id=$INSTANCE_ID,Port=81 aws elbv2 register-targets --target-group-arn $TG_ARN_APP2 --targets Id=$INSTANCE_ID,Port=82 aws elbv2 register-targets --target-group-arn $TG_ARN_APP3 --targets Id=$INSTANCE_ID,Port=83
start_all_apps.sh
Customize this to start your three app processes (example for systemd-managed apps):
#!/bin/bash set -e # Stop existing app processes first systemctl stop app1.service app2.service app3.service # Deploy new code (e.g., unzip your artifact) unzip /tmp/deployment-package.zip -d /opt/apps/ # Start updated apps systemctl start app1.service app2.service app3.service # Wait for apps to become healthy (adjust based on your app's startup time) sleep 10
- Monitor the CodeDeploy console to confirm instances are being deregistered, updated, and re-registered correctly
- Check your load balancer's target group metrics (in CloudWatch) to ensure instances transition from
drainingtohealthywithout gaps - Test traffic during deployment using your load balancer's DNS name to verify no requests are dropped
内容的提问来源于stack exchange,提问作者Mahantesh M Ambi

