【问题标题】:User-data scripts is not running on my custom AMI, but working in standard Amazon linux用户数据脚本未在我的自定义 AMI 上运行,但在标准 Amazon linux 中运行
【发布时间】:2015-01-21 02:11:07
【问题描述】:

这几天我搜索了很多关于“user-data script is not working”的话题,但是直到现在我还没有对我的情况有任何了解,请帮我弄清楚发生了什么,谢谢很多!

根据AWSUser-data解释:

当您在 Amazon EC2 中启动实例时,您可以选择将用户数据传递给实例,这些数据可用于执行常见的自动化配置任务,甚至在实例启动后运行脚本。

所以我尝试在实例启动时传递我自己的用户数据,这是我的用户数据:

\#!/bin/bash

echo 'test' > /home/ec2-user/user-script-output.txt

但是这个路径下没有文件:/home/ec2-user/user-script-output.txt

我检查了/var/lib/cloud/instance/user-data.txt,该文件存在并且与我的用户数据脚本相同。

另外我检查了/var/log/cloud-init.log的登录,没有错误信息。

但是如果我使用 Amazon linux(2014.09.01) 启动一个新实例,用户数据脚本就可以工作,但我不确定我的 AMI(基于 Amazon linux)和 Amazon linux 之间有什么区别。

我看到的唯一不同的部分是如果我运行这个脚本:

sudo yum list installed | grep cloud-init

我的 AMI:

cloud-init.noarch 0.7.2-8.33.amzn1 @amzn-main

亚马逊 Linux:

cloud-init.noarch 0.7.2-8.33.amzn1 已安装

我不确定是不是这个原因?

如果您需要更多信息,我很乐意提供,请告诉我在我自己的 AMI 中发生了什么以及如何修复它?

非常感谢

更新

刚刚从这个post找到答案,

如果我在用户数据文件的顶部添加#cloud-boothook,它会起作用!

#cloud-boothook
#!/bin/bash
echo 'test' > /home/ec2-user/user-script-output.txt

但仍然不知道为什么。

【问题讨论】:

标签: linux amazon-web-services amazon-ec2 user-data


【解决方案1】:

User_data 仅在第一次启动时运行。由于您的图像是自定义图像,我想它已经启动过一次,因此 user_data 已停用。

对于 Windows,可以通过选中 Ec2 Services Properties 中的框来完成。我正在研究如何在自定义图像创建结束时以自动方式执行此操作。

对于linux,我想机制是一样的,需要在你的自定义镜像上重新激活user_data。

#cloud-boothook 使其工作,因为它将脚本从 user_data 机制更改为 cloud-boothook 机制,每次启动都会运行。


编辑:

这是使用 powershell 在 windows 上重新激活启动的代码:

$configFile = "C:\\Program Files\\Amazon\\Ec2ConfigService\\Settings\\Config.xml"
[xml] $xdoc = get-content $configFile
$xdoc.SelectNodes("//Plugin") |?{ $_.Name -eq "Ec2HandleUserData"} |%{ $_.State = "Enabled" }
$xdoc.SelectNodes("//Plugin") |?{ $_.Name -eq "Ec2SetComputerName"} |%{ $_.State = "Enabled" }
$xdoc.OuterXml | Out-File -Encoding UTF8 $configFile

$configFile = "C:\\Program Files\\Amazon\\Ec2ConfigService\\Settings\\BundleConfig.xml"
[xml] $xdoc = get-content $configFile
$xdoc.SelectNodes("//Property") |?{ $_.Name -eq "AutoSysprep"} |%{ $_.Value = "Yes" }
$xdoc.OuterXml | Out-File -Encoding UTF8 $configFile

(我知道问题集中在 linux,但它可以帮助其他人......)

【讨论】:

    【解决方案2】:

    正如我测试的那样,/var/lib/cloud 目录中有一些引导数据。 清除该目录后,用户数据脚本正常工作。

    rm -rf /var/lib/cloud/*
    

    【讨论】:

      【解决方案3】:

      我在 Ubuntu 16.04 hvm AMI 上也遇到了同样的问题。我已将问题提交给 AWS 支持,但我仍然找不到影响它的确切原因/错误。

      但我仍有一些东西可以帮助你。

      在使用 AMI 之前删除 /var/lib/cloud 目录(每次)。然后在创建 Image 时,将其设置为 no-reboot。

      如果这些方法仍然不起作用,您可以通过强制用户数据手动运行来进一步测试它。还有 tailf /var/log/cloud-init-output.log 用于 cloud-init 状态。它应该以 modules:final 之类的东西结尾,以使您的用户数据运行。它不应该停留在 modules:config 上。

      sudo rm -rf /var/lib/cloud/* sudo cloud-init init sudo cloud-init modules -m final

      我不太清楚上述命令是否可以在 CentOS 上运行。我已经在 Ubuntu 上测试过了。

      就我而言,我也尝试过删除 /var/lib/cloud 目录,但在我们的场景中仍然无法执行用户数据。但我想出了不同的解决方案。我们所做的是我们使用上述命令创建了脚本,并让该脚本在系统启动时运行。

      我在 /etc/rc.local 中添加了以下行来实现它。

      sudo bash /home/ubuntu/force-user-data.sh || exit 1

      但这里有个问题,它会在每次启动时执行脚本,这样您的用户数据就会在每次启动时运行,就像 #cloud-boothook 一样。不用担心,您可以通过在最后删除 force-user-data.sh 本身来调整它。所以你的 force-user-data.sh 看起来像

      #!/bin/bash sudo rm -rf /var/lib/cloud/* sudo cloud-init init sudo cloud-init modules -m final sudo rm -f /home/ubuntu/force-user-data.sh exit 0

      如果有人能说明为什么它无法执行用户数据,我将不胜感激。

      【讨论】:

      • 太棒了。你为我节省了很多时间!
      【解决方案4】:

      以答案为例:确保标题中只有#!/bin/bash

      #!/bin/bash
      yum update -y
      yum install httpd mod_ssl
      service httpd start
      chkconfig httpd on
      

      【讨论】:

        【解决方案5】:

        我在这方面遇到了很多麻烦。我将提供详细的演练。

        另外一个问题是我使用 terraform 通过启动配置和自动缩放组来实例化主机。

        我无法通过在 lc.tf 中添加内联脚本来使其工作

        user_data                   = DATA <<
        "
        #cloud-boothook
        #!/bin/bash
        echo 'some crap'\'
        "
        DATA
        

        我可以从用户数据中获取它,

        wget http://169.254.169.254/latest/user-data
        

        但注意到我得到它时仍然包含引号。

        这就是我让它工作的方式:我改为从模板中提取它,因为所见即所得。

        user_data                   = "${data.template_file.bootscript.rendered}"
        

        这意味着我还需要像这样声明我的模板文件:

        data "template_file" "bootscript" {
          template = "${file("bootscript.tpl")}"
        
        }
        

        但我仍然在云初始化日志中收到错误 /var/log/cloud-init.log [警告]:未处理的非多部分(文本/x-not-multipart)用户数据:'Content-Type: text/cloud...'

        然后我找到了this article about user data formatting user,这是有道理的,如果用户数据可以分为多个部分,也许 cloud-init 需要 cloud-init 命令在一个地方,而脚本在另一个地方。

        所以我的 bootscript.tpl 看起来像这样:

        Content-Type: multipart/mixed; boundary="//"
        MIME-Version: 1.0
        
        --//
        Content-Type: text/cloud-config; charset="us-ascii"
        MIME-Version: 1.0
        Content-Transfer-Encoding: 7bit
        Content-Disposition: attachment; filename="cloud-config.txt"
        
        #cloud-config
        cloud_final_modules:
        - [scripts-user, always]
        
        --//
        Content-Type: text/x-shellscript; charset="us-ascii"
        MIME-Version: 1.0
        Content-Transfer-Encoding: 7bit
        Content-Disposition: attachment; filename="userdata.txt"
        
        #!/bin/bash
        echo "some crap"
        --//
        

        【讨论】:

          【解决方案6】:

          在 ubuntu 16 上,删除 /var/lib/cloud/* 不起作用。我只从文件夹 /var/lib/cloud/ 中删除了实例,然后它对我来说运行良好

          我跑了:

          sudo rm /var/lib/cloud/instance
          sudo rm /var/lib/cloud/instances
          

          然后我重试了我的用户数据脚本,它运行良好

          【讨论】:

          • 这在 Ubuntu 上对我有用,但我需要运行 sudo rm -r /var/lib/cloud/instances,因为 instances 是一个目录。
          【解决方案7】:

          我使用的是 CentOS,用户数据的逻辑很简单:

          • 在文件 /etc/rc.local 中有一个对 initial.sh 脚本的调用,但它首先查找一个标志:

            if [ -f /var/tmp/initial ]; then
                /var/tmp/initial.sh &
            fi
            

          initial.sh 是执行用户数据的文件,但最后它删除了标志。因此,如果您希望新的 AMI 再次执行用户数据,只需在创建映像之前再次创建标志:

          touch /var/tmp/initial
          

          【讨论】:

            【解决方案8】:

            只需在用户数据脚本的末尾添加 --// 即可,例如:

            #!/bin/bash
            #Upgrade ec2 instance
            sudo yum update -y 
            
            #Start docker service 
            sudo service docker start 
            
             --//
            

            【讨论】:

            • 你能解释一下这是做什么的吗?
            【解决方案9】:

            用户数据应该可以在不使用#cloud-boothook(用于在启动过程中尽早激活用户数据)的情况下正常执行。

            我启动了一个新的 Amazon Linux AMI 并使用了您的用户数据,以及一些额外的:

            #!/bin/bash
            
            echo 'bar' > /tmp/bar
            echo 'test' > /home/ec2-user/user-script-output.txt
            echo 'foo' > /tmp/foo
            

            这成功创建了三个文件。

            用户数据脚本以root 执行,因此它应该有权在任何位置创建文件。

            我注意到在您提供的代码中,一个示例引用了/home/ec2-user/user-script/output.txt(带有子目录),一个示例引用了/home/ec2-user/user-script-output.txt(没有子目录)。如果您尝试在不存在的目录中创建文件,该命令会失败,这是可以理解的,但您的“更新”示例似乎表明它确实有效。

            【讨论】:

            • 感谢您的回答,对此感到抱歉,/home/ec2-user/user-script/output.txt 是错字,已经修复,现在我仍然不知道为什么它没有如果我删除#cloud-boothook 将无法正常工作,但仍在尝试解决
            【解决方案10】:

            !/bin/bash

            不要在行首留下任何空白。使用确切的命令。否则它可能会在 AMAZON Linux AMI 中运行,但不会在 RHEL 中运行。

            【讨论】:

              【解决方案11】:

              我让它工作的唯一方法是在 #!/bin/bash 之前添加 #cloud-boothook

              这是一个典型的用户数据脚本,用于在新创建的实例上安装 Apache Web 服务器

              #cloud-boothook
              #!/bin/bash
              
              yum update -y 
              yum install -y httpd.x86_64 
              systemctl start httpd.service 
              systemctl enable httpd.service 
              

              没有#cloud-boothook 它不起作用,但有了它,它就可以工作。似乎不同的用户有不同的体验。有些人可以在没有它的情况下让它工作,不知道为什么。

              【讨论】:

                【解决方案12】:

                另外, 如果我们使用像

                这样的用户交互命令
                sudo yum install java-1.8.0-devel
                

                然后,我们需要使用 -y 之类的标志

                sudo yum install java-1.8.0-devel -y
                

                您可以在 EC2 文档的 Run commands at launch 下找到此内容。

                参考:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#user-data-shell-scripts

                【讨论】:

                  猜你喜欢
                  • 2014-11-27
                  • 2018-05-30
                  • 2014-01-25
                  • 1970-01-01
                  • 2014-06-27
                  • 2019-06-01
                  • 2014-09-25
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多