【问题标题】:Call to 169.254.169.254/latest/meta-data/instance-id fails in AWS deployment script在 AWS 部署脚本中调用 169.254.169.254/latest/meta-data/instance-id 失败
【发布时间】:2017-07-24 13:23:03
【问题描述】:

我正在使用一些基于http://blog.brianbeach.com/2014/07/setting-hostname-in-syspreped-ami.html 的脚本来设置从 AMI 创建的新 Windows 实例的主机名作为实例的名称标签。它运行的不是指向 windeploy.exe 的 HKLM:\System\Setup,而是运行一个脚本:

$InstanceName = 'WebServerNew'

Try 
{
    Start-Transcript -Path D:\WebServerUtility\SysPrep\Windeploy.log -Append
    Write-Host "Discovering instance identity from meta-data web service"
    $InstanceId = (Invoke-RestMethod 'http://169.254.169.254/latest/meta-data/instance-id').ToString()
    $AvailabilityZone = (Invoke-RestMethod 'http://169.254.169.254/latest/meta-data/placement/availability-zone').ToString()
    $Region = $AvailabilityZone.Substring(0,$AvailabilityZone.Length-1)

    Write-Host "Getting Tags for the instance"
    $Tags = Get-EC2Tag -Filters @{Name='resource-id';Value=$InstanceId} -Region $Region
    $InstanceName = ($Tags | Where-Object {$_.Key -eq 'Name'}).Value
    Write-Host "`tFound Instance Name: $InstanceName"    
}
Catch
{
    Write-Host $_
    $InstanceName = 'WebServerError'
}

try
{ 
    If($InstanceName -ne $null) {
          Write-Host "Setting the machine name to $InstanceName"
          $AnswerFilePath = "C:\Windows\Panther\unattend.xml"
          $AnswerFile = [xml](Get-Content -Path $AnswerFilePath) 
          $ns = New-Object System.Xml.XmlNamespaceManager($AnswerFile.NameTable)
          $ns.AddNamespace("ns", $AnswerFile.DocumentElement.NamespaceURI)
          $ComputerName = $AnswerFile.SelectSingleNode('/ns:unattend/ns:settings[@pass="specialize"]/ns:component[@name="Microsoft-Windows-Shell-Setup"]/ns:ComputerName', $ns)
          $ComputerName.InnerText = $InstanceName
          $AnswerFile.Save($AnswerFilePath)
    }
}
Catch
{
    Write-Host $_
}
Finally
{
    Stop-Transcript
}

然后它调用 WinDeploy.exe 来完成特化。

问题在于这条线

    Write-Host "Discovering instance identity from meta-data web service"
    $InstanceId = (Invoke-RestMethod 'http://169.254.169.254/latest/meta-data/instance-id').ToString()

失败并显示“无法连接到远程服务器”。

知道为什么它无法连接到那个吗?

【问题讨论】:

    标签: amazon-web-services amazon-ec2 sysprep


    【解决方案1】:

    您需要将此添加到脚本的顶部:

    Start-Service -Name 'Dhcp'
    route add 169.254.169.254 MASK 255.255.255.255 0.0.0.0
    

    触发脚本时 DHCP 客户端停止。这就是你没有 IP 的原因。

    您还需要向元数据服务添加路由。 Sysprep 删除这些路由。

    【讨论】:

    • 谢谢!我没有看到这个答案,而且我已经不再关心自动化这部分服务器设置了,但是你现在可以有一个可以接受的答案,当我找到它时我会测试它=)
    • 天才,拯救了我的一天!
    • 不,这不起作用仍然是同样的错误。
    【解决方案2】:

    看起来很奇怪... URL 看起来是正确的。让我们尝试调试一下。让我们隔离问题,看看是脚本问题还是其他问题。

    1. 尝试 telnet 169.254.169.254 80

    如果显示已连接或未连接

    1. 还可以在浏览器上尝试http://169.254.169.254/latest/meta-data/instance-id 并查看输出..

    另外,尝试在系统初始化后运行脚本...可能是脚本运行的时间;此本地 IP 未初始化。

    每次系统启动时; EC2 向主网络适配器添加自定义路由,以在连接多个 NIC 时启用以下 IP 地址:169.254.169.254。你的这个脚本在 NIC 连接之前被执行。于是就有了问题。

    【讨论】:

    • 实例运行时运行良好。只是在启动脚本中失败了。
    【解决方案3】:

    您的脚本非常适合我。

    问题是您的实例上的某些东西阻止了对该 IP 地址的访问,例如防火墙。

    检查您的系统配置以查看 Windows 防火墙是否阻止访问,或者是否安装了任何其他阻止访问的安全软件。

    尝试Invoke-RestMethod 'http://google.com' 也是一个很好的测试。

    【讨论】:

    • 实例运行时运行良好。它只是在启动脚本中失败。我将尝试禁用 Windows 防火墙并创建一个新映像。我也会添加一个调用以获取 Google,看看它是否有效。
    • 是的,也适合我。 @BenCurthoys,也许您的脚本在界面启动之前执行;在执行时您甚至可能没有 IP 地址,因此无法访问元数据服务器。也许你可以尝试进入一个重试循环。
    【解决方案4】:

    DHCP 已启动,但接口未间歇性分配 IP,以下是完成此操作的解决方法

    Function Get-IP{
        $global:initializedIP=netsh interface ip show address $interfaceName | where { $_ -match "IP Address"} | %{ $_ -replace "^.*IP Address:\W*", ""}
        Write-host "`tInitialized IP: $initializedIP"
    }
    
    Function InitializeNetwork{
        $global:interfaceName = netsh interface ipv4 show interfaces | where { $_ -match "Ethernet"}| %{ $_ -replace "^.*Connected\W*",""}  
        write-host "`tInterface name: $interfaceName"
        $status = Invoke-Command -Command { netsh interface ipv4 set interface $interfaceName mtu=1460 }
        Write-host "`tInitializing $interfaceName : $status"
        Write-Host "`tStarting Service: DHCP"
        Start-Service -Name 'Dhcp'    
        $r_status = Invoke-Command -Command { route /p add 169.254.169.254 mask 255.255.255.255 0.0.0.0 if 6 metric 1}
        Write-Host "`tAdding metadata route $r_status"
    }    
      
    Try {
        Start-Transcript -Path C:\Temp\Windeploy.log -Append
        Write-Host "[Meta-Data] Discovering instance identity from meta-data web service"
        Set-Variable -Name "interfaceName" -value "Ethernet 2" -scope global
        Set-Variable -Name "initializedIP" -value "169.254.169.254" -scope global
        Write-Host "[Network] Initializing default network"
        InitializeNetwork
        Get-IP
        While (-not ($initializedIP -like "10.*.*.*"))
        {
            Write-Host "`tGetting IP for $interfaceName"
            Invoke-Command -Command {ipconfig /renew $interfaceName}    
            Get-IP    
        }
        
        $Global:InstanceInfo = Invoke-WebRequest 'http://169.254.169.254/latest/dynamic/instance-identity/document/' -UseBasicParsing | ConvertFrom-Json
        $AccountId = $InstanceInfo.accountId
        $AWSRegion = $InstanceInfo.region
        $InstanceId = $InstanceInfo.instanceId
        Write-Host "[Instance-Tags] Getting Tags for the instance"    
        $Tags = Get-EC2Tag -Filters @{Name='resource-id';Value=$InstanceId} -Region $AWSRegion
        Write-Host "`t$Tags"
    
        #Generate windows hostname with lowercase letters/numbers only if meta-data not available
        Write-Host "[ComputerName] Auto generate the default computer name." 
        $instanceName = "WIN-" + -join ((48..57) + (97..122) | Get-Random -Count 11 | % {[char]$_})
        Write-Host "`tAuto Instance Name: $InstanceName"
        If ($null -eq $Tags.Where( { $_.Key -eq "hostname" }).Value){
            $instanceName="{0}{1}" -F $Tags.Where( {($_.Key).ToLower() -eq "appcode" }).Value, $InstanceId.Remove(0,($InstanceId.Length - 9))
        }else{
            $InstanceName = ($Tags | Where-Object {$_.Key -eq 'hostname'}).Value
        }
        Write-Host "`tFound Instance Name: $InstanceName"
        If($InstanceName) {
            Write-Host "[Unattend] Setting the machine name to $InstanceName"
            $AnswerFilePath = "C:\Windows\Panther\Unattend.xml"
            $AnswerFile = [xml](Get-Content -Path $AnswerFilePath)
            $ns = New-Object System.Xml.XmlNamespaceManager($answerFile.NameTable)
            $ns.AddNamespace("ns", $AnswerFile.DocumentElement.NamespaceURI)
            $ComputerName = $AnswerFile.SelectSingleNode('/ns:unattend/ns:settings[@pass="specialize"]/ns:component[@name="Microsoft-Windows-Shell-Setup"]/ns:ComputerName', $ns)
            $ComputerName.InnerText = $InstanceName
            $AnswerFile.Save($AnswerFilePath)
            Write-host "[Unattend] ComputerName is added."
        }else{
            Write-host "[Unattend] Unable to Set Instance Name"
        }
        Write-host "[BootMGR] Setting 0 Timeout to Boot Manager"
        Invoke-Command -Command { bcdedit.exe /set "{bootmgr}" timeout 0 }    
    }
    Catch {
        Write-Host $_
    }
    Finally
    {   
        Write-host "[Start-up] Starting OOBE Setup"
        Start-Process C:\windows\system32\oobe\windeploy.exe -Wait
        Stop-Transcript
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 1970-01-01
      • 2013-07-24
      • 2016-07-10
      • 2021-11-03
      相关资源
      最近更新 更多