识别 ECS 实例的硬编码 DNS 记录

如何解决识别 ECS 实例的硬编码 DNS 记录

我有一个需要部署的 docker 镜像,同时保持一致的 DNS 记录。最重要的是,我想要一个硬编码的实例数量(例如,2)。我喜欢 ECS 的易用性以及 ECS 代理保持正常运行时间,但负载均衡器对于单个实例来说太过分了。到目前为止,我只是创建了一个最小/最大/期望为 1 的 ASG,因此没有任何冲突问题。

反对在自动缩放组中对实例进行编号的争论非常激烈(here 就是一个例子),这是有道理的,但我认为这是一个非常可靠的用例,无法避免。

>

我已经成功地修改了 meltwater/terraform-aws-asg-dns-handler,为 ASG 中的单个 ECS 实例提供了一个硬编码的 DNS 记录(比如 instance-1.example.com),尽管它不是很漂亮。为了让两个实例正常工作(instance-1.example.cominstance-2.example.com),我想我有两个选择:

  • 创建一个 hacky 解决方案来读取我的 Lambda 函数中现有的 Route53 记录,以“确定性地”决定在 ASG 生命周期挂钩中为我的实例分配哪个索引(this 可能是一个好的开始)
  • 创建两个 ECS 集群,每个集群都有一个实例,并使用两个单独的 Lambda 函数

对我来说,这些都不是非常可靠的选择,所以我想知道是否有更好的方法以类似 ECS 的方式部署单个 Docker 容器,我可以将 DNS 记录附加到。

就上下文而言,“两个 ECS 集群”方法可以正常工作,但我将执行三到四次,因此我最终会在其他几个集群之上使用 8 个 ECS 集群,这就是至少可以说不方便。

解决方法

如果您使用 Auto Scaling 组和带有用户数据的启动配置或模板...这是我在用户数据中添加的内容,以便在新的任何时候自动保持 Route53 DNS 记录最新实例旋转起来,带有一个计数器。希望这可以帮助!

## --------------------------------------------------------------------------------------------------------------- ##
## --- AUTO SCALING LOGIC for user-data -------------------------------------------------------------------------- ##
## --------------------------------------------------------------------------------------------------------------- ##
## --- Get ip addresses of existing app DNS Entries (that point to app nodes,not load balancer) ----- ##
## --- Get this ip address --------------------------------------------------------------------------------------- ##
## --- If this IP Address matches any in existing list,do not create a new DNS record --------------------------- ##
## --- If this IP Address does not match any in existing list,create a new DNS record --------------------------- ##
## --------------------------------------------------------------------------------------------------------------- ##

region="us-east-1"
hosted_zone="ROUTE53-HOSTED-ZONE-ID"
vpc="vpc-ID"
r53_domain="example.com"
asg_desired="2"
application="app"

echo "USING EC2 INSTANCE META DATA TO OBTAIN IP ADDRESS ..."
echo "IF YOU ARE NOT USING DEFAULT AMZN INSTANCE,USE ifconfig OR ANOTHER METHOD TO OBTAIN THIS INSTANCE IP ..."

# CHOOSE THE PRIVATE (local-ipv4) OR PUBLIC IP DEPENDING ON USE CASE 
#this_ip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
this_ip=`curl http://169.254.169.254/latest/meta-data/public-ipv4`
echo $this_ip > /tmp/this-ip.txt

# FILTER BASED ON UNIQUE TAGS FOR YOUR TARGETED INSTANCE(S)
# THIS IS USING Application Tag. 
aws --region $region ec2 describe-instances --query "Reservations[*].Instances[? Tags[? (Key=='Application') && Value=='$application']].PublicIpAddress" --output text >> /tmp/existing-ec2-ips.txt

counter=1
until [ $counter -gt $asg_desired ]
do
  aws --region $region route53 list-resource-record-sets --hosted-zone-id $hosted_zone --query "ResourceRecordSets[?Name == 'instance-$counter.$r53_domain.'].ResourceRecords" --output text >> /tmp/existing-ips.txt
  aws --region $region route53 list-resource-record-sets --hosted-zone-id $hosted_zone --query "ResourceRecordSets[?Name == 'instance-$counter.$r53_domain.']" --output text >> /tmp/existing-records.txt
  ((counter++))
done

diff /tmp/existing-ips.txt /tmp/this-ip.txt

echo "Does this instance IP exist in a $application route53 record?"
this_ip_result=`grep $this_ip /tmp/existing-ips.txt | wc -l`

if [[ $this_ip_result -gt 0 ]]
then
  echo "Yes,this instance IP already exists in a $application route53 record."
  echo "Nothing left to do"
else
  echo "No,this instance IP does not exist in a $application route53 record."
  echo "Adding route53 record... "
  counter=1
    until [ $counter -gt $asg_desired ]
    do
        grep -L instance-$counter.$r53_domain /tmp/existing-records.txt > /tmp/instance-$counter.$r53_domain.txt
        if [ -s /tmp/instance-$counter.$r53_domain.txt ]
            then
                echo "instance-$counter.$r53_domain does not exist... Adding!"
                aws --region $region route53 change-resource-record-sets --hosted-zone-id $hosted_zone --change-batch '{ "Comment": "Auto Scaling Creating Record Set","Changes": [ { "Action": "CREATE","ResourceRecordSet": { "Name": "instance-'$counter'.'$r53_domain'","Type": "A","TTL": 120,"ResourceRecords": [ { "Value": "'"$this_ip"'" } ] } } ] }'
            else
                echo "Updating Record Set!"
                echo "Updating Route53 Records with the following IPs ..."
                diff /tmp/existing-ec2-ips.txt /tmp/existing-ips.txt | grep ">" | sed 's/> //g'
                ip_update=`diff /tmp/existing-ec2-ips.txt /tmp/existing-ips.txt | grep ">" | sed 's/> //g'`
                record_update=`grep -B 1 $ip_update /tmp/existing-records.txt | grep $application | awk '{print $1}' | awk 'FNR == 1 {print}'`
                aws --region $region route53 change-resource-record-sets --hosted-zone-id $hosted_zone --change-batch '{ "Comment": "Auto Scaling Updating Record Set","Changes": [ { "Action": "UPSERT","ResourceRecordSet": { "Name": "'"$record_update"'","ResourceRecords": [ { "Value": "'"$this_ip"'" } ] } } ] }'
            fi
        ((counter++))
    done
fi

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?