Route 53 是不是指向实例而不是 IP 或 CNAME?

Posted

技术标签:

【中文标题】Route 53 是不是指向实例而不是 IP 或 CNAME?【英文标题】:Have Route 53 point to an instance instead of an IP or CNAME?Route 53 是否指向实例而不是 IP 或 CNAME? 【发布时间】:2012-04-23 04:57:17 【问题描述】:

我们使用 Route 53 DNS 指向 EC2 实例。有没有办法让 Route 53 直接指向实例,而不是指向弹性 IP 或 CNAME?

我有多种原因:

    我不想烧掉 IP。

    CNAME 是不可靠的,因为如果实例出现故障并重新启动,全名 ec2-X-X-X-X.compute-1.amazonaws.com 将会改变。

    将来,我需要以编程方式启动实例并使用子域对其进行寻址,我认为使用弹性 IP 或 CNAME 都没有简单的方法。

最好的方法是什么?

【问题讨论】:

这可能不会得到回答,但我也对答案感兴趣。如果我拥有“example.com”并拥有自己的 DNS 服务器,我可以将“foo.example.com”定向到 EC2 实例吗? 好吧,为了回答我自己的元问题,我为我的实例分配了一个弹性 IP,然后为它创建了一个 A 记录。您还可以为实例的公有 DNS 名称创建 CNAME 记录,但这并不稳定,因为当您停止并重新启动实例时,公有 DNS 名称会发生​​变化。 其实,一旦你分配了一个弹性IP,你就可以预测将要创建的公共DNS名称:ec2-Elastic IP.AWS AZ.compute.amazonaws.com .如果您在路由 53 中为该 DNS 分配 cname,它应该始终正确指向您分配 EIP 的实例。这样做的好处是当您在 EC2 网络内部时解析到内部 EC2 ip,而在外部时解析到正确的公共弹性 IP。 【参考方案1】:

使用 Route 53,您可以创建映射到弹性负载均衡器 (ELB) 的别名记录:

http://docs.amazonwebservices.com/Route53/latest/DeveloperGuide/HowToAliasRRS.html

【讨论】:

这是一种解决问题的昂贵方法,因为它需要你必须支付的 ELB……我真的很惊讶亚马逊没有为这个非常常见的问题提供解决方案! !! 有一个解决办法。您可以使用免费的弹性 IP(如果正在使用)。如果您需要超过 5 个,您可以请求增加您帐户的限制。【参考方案2】:

如果您坚持使用 route53,您可以编写一个脚本,在该实例每次重新启动时更新其 CNAME 记录。

看到这个 -> http://cantina.co/automated-dns-for-aws-instances-using-route-53/(披露,我没有创建这个,虽然我用它作为类似情况的跳跃点)

更好的是,因为您提到能够以编程方式启动实例,所以这种方法应该可以指导您实现这一目标。

另见 -> http://docs.pythonboto.org/en/latest/index.html

【讨论】:

【参考方案3】:

我为这个问题编写了自己的解决方案,因为我对这里介绍的其他方法不满意。使用 Amazon CLI 工具很好,但恕我直言,它们往往比使用其他 Amazon API 库(例如 Ruby)的直接 API 调用要慢。

这是我的AWS Route53 DNS instance update Gist 的链接。它包含一个 IAM 策略和一个 Ruby 脚本。您应该在 IAM 面板中创建一个新用户,使用附加的策略(其中包含您的区域 ID)对其进行更新,并在 Ruby 脚本中设置凭证和参数。第一个参数是托管区域中实例的主机名别名。实例的私有主机名别名为<hostname>.<domain>,实例的公共主机名别名为<hostname>-public.<domain>

更新:这是实例启动时AWS Route53 DNS instance update init.d script 注册主机名的链接。如果想以类似的方式使用AWS Route53 DNS load-balancing,这是另一个。

【讨论】:

当然,这是您必须管理的额外资源。这有不同的目的。【参考方案4】:

我没有尝试过 aws EC2 实例,但它也应该可以工作。 我编写了一个小型 Java 程序,用于检测机器的公共 IP 并更新 aws route 53 上的某个记录。

唯一的要求是您需要在 EC2 实例上安装 Java。

该项目托管在https://github.com/renatodelgaudio/awsroute53,您也可以在需要时随意修改它

您可以将其配置为在启动时运行或作为 crontab 作业运行,以便按照类似于这些的说明使用新的公共 IP 更新您的记录 Linux manual installation steps

【讨论】:

【参考方案5】:

如果您将至少部分 dns 托管在 Route53 中,那么也可以选择结合使用 Cloudwatch、Route53 和 Lambda。这样做的好处是您不需要在实例本身上运行任何应用程序。

要使用这种方法,您需要配置一条 Cloudwatch 规则,以便在 EC2 实例的状态变为运行时触发 Lambda 函数。然后 Lambda 函数可以检索实例的公共 IP 地址并更新 Route53 中的 dns 记录。

Lambda 可能看起来像这样(使用 Node.js 运行时):

var AWS = require('aws-sdk');

var ZONE_ID = 'Z1L432432423';
var RECORD_NAME = 'testaws.domain.tld';
var INSTANCE_ID = 'i-423423ccqq';

exports.handler = (event, context, callback) => 
    var retrieveIpAddressOfEc2Instance = function(instanceId, ipAddressCallback) 
        var ec2 = new AWS.EC2();

        var params = 
                InstanceIds: [instanceId]
        ;

        ec2.describeInstances(params, function(err, data) 
            if (err) 
                callback(err);                
             else 
                ipAddressCallback(data.Reservations[0].Instances[0].PublicIpAddress);
                        
        );
    

    var updateARecord = function(zoneId, name, ip, updateARecordCallback) 
        var route53 = new AWS.Route53();

        var dnsParams = 
                ChangeBatch: 
                    Changes: [
                        
                            Action: "UPSERT", 
                            ResourceRecordSet: 
                                Name: name, 
                                ResourceRecords: [
                                    
                                        Value: ip
                                    
                                    ], 
                                    TTL: 60, 
                                    Type: "A"
                            
                        
                        ], 
                        Comment: "updated by lambda"
                ,
                HostedZoneId: zoneId
        ;

        route53.changeResourceRecordSets(dnsParams, function(err, data) 
            if (err) 
                callback(err, data);
             else 
                updateARecordCallback();
                        
        );
    

    retrieveIpAddressOfEc2Instance(INSTANCE_ID, function(ip) 
        updateARecord(ZONE_ID, RECORD_NAME, ip, function() 
            callback(null, 'record updated with: ' + ip);
        );
    );

您需要使用有权描述 EC2 实例和更新 Route53 中的记录的角色来执行 Lambda。

【讨论】:

【参考方案6】:

我使用这个 cli53 工具让 EC2 实例在启动期间为自己创建一条 A 记录。

https://github.com/barnybug/cli53

我在rc.local 中添加了以下几行文件(请检查您的 linux 在启动期间是否调用了此脚本):

IP=$(curl http://169.254.169.254/latest/meta-data/public-ipv4)
/usr/local/bin/cli53 rrcreate example.com "play 30 A $IP" --wait --replace

它会创建一条 A 记录 play.example.com 指向 EC2 实例的当前公共 IP。

您需要为 EC2 实例分配一个 IAM 角色,这允许该实例操作 Route 53。在最简单的情况下,只需使用预定义的策略 AmazonRoute53FullAccess 创建一个 IAM 角色。然后将此角色分配给 EC2 实例。

【讨论】:

以上是关于Route 53 是不是指向实例而不是 IP 或 CNAME?的主要内容,如果未能解决你的问题,请参考以下文章

当您使用 Route 53 作为 DNS 时,Lightsail 实例在您点击 http://[domain].com 而不是 www.[domain].com 时工作

在 Route 53 中使用弹性 IP 地址不起作用

Route53 域名不起作用(godaddy 域)

Laravel route() 返回裸 IP 地址而不是域

将 Amazon 的 CloudFront 指向 A 记录而不是 CNAME

Route53私有托管域——轻松管理你私有ip和域名