gpt4 book ai didi

cloud-init - 在 AWS 中,user_data 是否在 cloud-init 之前执行?

转载 作者:行者123 更新时间:2023-12-04 12:25:08 28 4
gpt4 key购买 nike

我使用 terraform 创建一个 EC2 实例,我使用 user_data将文件放入 /var/lib/cloud/scripts/per-once .这没有执行 - 我现在的问题是:是否在 user_data 之前运行了 cloud-init ?

===编辑===

对 Dude0001 非常有用的答案的较长回复:

我现在尝试了以下方法 - 这是我的 user_data :

#!/bin/bash
cat >/var/lib/cloud/scripts/per-once/install_mysql <<!
#cloud-config

package_update: true

packages:
- mysql-server

!

cat >>/root/.bashrc <<!
set -o vi
unalias -a
alias ll='ls -lp'
!

cat >>/home/admin/.bashrc <<!
set -o vi
unalias -a
alias ll='ls -lp'
!

cat /root/.vimrc <<!
set t_ti= t_te=
set compatible
set expandtab ts=2 sw=2 ai
!

cat >/home/admin/.vimrc <<!
set t_ti= t_te=
set compatible
set expandtab ts=2 sw=2 ai
!


这会按预期创建所有文件(我真的很老式,不喜欢 vim 的大多数新功能)。创建实例后,我尝试重新启动:没有 mysqld。我更改了权限,chmod 755/var/lib/cloud/scripts/per-once/install_mysql,然后重新启动:也没有结果(我更改权限的原因是它从 python 代码中出现,cloud-init 只查找可执行文件)。

===编辑===

对我的 user_data的一些解释以上:

这种结构可能会让一些人感到困惑,因为它不太常见:
cat >/some/path/to/a/file <<!
...
!
cat是一个简单地从标准输入读取并写入标准输出而不更改的命令 - 它通常与重定向一起使用 <> .在上面的构造中,我将任何输出定向到文件 /some/path/to/a/file .另一部分,涉及 <<!!被称为 here 文档,我怀疑它起源于大型机上使用的 JCL 语言,但它确实很有用。意思是读取以下几行直到结束标记(此处: ! ,但它可以是任何字符串)。所以,总而言之,它说创建一个包含以下内容的文件:....

第一个文件, /var/lib/cloud/scripts/per-once/install_mysql ,包含:
#cloud-config

package_update: true

packages:
- mysql-server

我希望这应该告诉 cloud-init 更新软件包存储库并安装 mysql-server - 这不会发生。

接下来的 4 个文件只是 root 中的一些设置和 admin用户环境;基本上,我创建了一个 .vimrc并向 .bashrc 添加几行以确保某些事情按照我的喜好进行设置。

所有文件都已创建,但带有 #cloud-config 的文件似乎根本没有被触动。我昨天做了一些实验,把这个文件放在 /var/lib/cloud/scripts/下的不同目录下。 ,但看起来好像这些文件在 cloud-init 读取目录时没有到位。通读 cloud-init的源代码,看起来好像经历了 10 个阶段 - user_data是在第5阶段取的,应该在第7阶段读取。我也可以看到它似乎需要设置执行权限位;但是,这是重新启动后日志中的内容:
2019-10-02 08:06:52,884 - handlers.py[DEBUG]: start: modules-final/config-scripts-per-boot: running config-scripts-per-boot with frequency always
2019-10-02 08:06:52,884 - helpers.py[DEBUG]: Running config-scripts-per-boot using lock (<cloudinit.helpers.DummyLock object at 0x7f677362acc0>)
2019-10-02 08:06:52,885 - util.py[DEBUG]: Running command ['/var/lib/cloud/scripts/per-boot/install_mysql'] with allowed return codes [0] (shell=False, capture=False)
2019-10-02 08:06:52,887 - util.py[WARNING]: Failed running /var/lib/cloud/scripts/per-boot/install_mysql [-]
2019-10-02 08:06:52,887 - util.py[DEBUG]: Failed running /var/lib/cloud/scripts/per-boot/install_mysql [-]
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/cloudinit/util.py", line 1992, in subp
env=env, shell=shell)
File "/usr/lib/python3.7/subprocess.py", line 775, in __init__
restore_signals, start_new_session)
File "/usr/lib/python3.7/subprocess.py", line 1522, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
OSError: [Errno 8] Exec format error: b'/var/lib/cloud/scripts/per-boot/install_mysql'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/cloudinit/util.py", line 835, in runparts
subp(prefix + [exe_path], capture=False)
File "/usr/lib/python3/dist-packages/cloudinit/util.py", line 2000, in subp
stderr="-" if decode else b"-")
cloudinit.util.ProcessExecutionError: Exec format error. Missing #! in script?
Command: ['/var/lib/cloud/scripts/per-boot/install_mysql']
Exit code: -
Reason: [Errno 8] Exec format error: b'/var/lib/cloud/scripts/per-boot/install_mysql'
Stdout: -
Stderr: -
2019-10-02 08:06:52,897 - cc_scripts_per_boot.py[WARNING]: Failed to run module scripts-per-boot (per-boot in /var/lib/cloud/scripts/per-boot)
2019-10-02 08:06:52,898 - handlers.py[DEBUG]: finish: modules-final/config-scripts-per-boot: FAIL: running config-scripts-per-boot with frequency always
2019-10-02 08:06:52,898 - util.py[WARNING]: Running module scripts-per-boot (<module 'cloudinit.config.cc_scripts_per_boot' from '/usr/lib/python3/dist-packages/cloudinit/config/cc_scripts_per_boot.py'>) failed
2019-10-02 08:06:52,898 - util.py[DEBUG]: Running module scripts-per-boot (<module 'cloudinit.config.cc_scripts_per_boot' from '/usr/lib/python3/dist-packages/cloudinit/config/cc_scripts_per_boot.py'>) failed
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/cloudinit/stages.py", line 800, in _run_modules
freq=freq)
File "/usr/lib/python3/dist-packages/cloudinit/cloud.py", line 54, in run
return self._runners.run(name, functor, args, freq, clear_on_fail)
File "/usr/lib/python3/dist-packages/cloudinit/helpers.py", line 187, in run
results = functor(*args)
File "/usr/lib/python3/dist-packages/cloudinit/config/cc_scripts_per_boot.py", line 41, in handle
util.runparts(runparts_path)
File "/usr/lib/python3/dist-packages/cloudinit/util.py", line 842, in runparts
% (len(failed), len(attempted)))
RuntimeError: Runparts: 1 failures in 1 attempted commands

所以,它肯定不喜欢文件的格式——它想看到一个 #!...或者可能是二进制可执行文件。

我现在将更详细地尝试 Dude0001 的建议。

===编辑===

最后,正如 Dude0001 所建议的那样,使用 multipart/mixed 格式是有效的:
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
package_update: yes
package_upgrade: all

packages:
- mariadb-server
- apt-file

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
cat >>/root/.bashrc <<!
set -o vi
unalias -a
alias ll='ls -lp'
!

cat >>/home/admin/.bashrc <<!
set -o vi
unalias -a
alias ll='ls -lp'
!

cat /root/.vimrc <<!
set t_ti= t_te=
set compatible
set expandtab ts=2 sw=2 ai
!

cat >/home/admin/.vimrc <<!
set t_ti= t_te=
set compatible
set expandtab ts=2 sw=2 ai
!

--//

只需指定 #cloud-config似乎不起作用,但这种方式确实有效。对我来说,至少。在当下。

最佳答案

简答 :

一个 user_data设置为 shell 脚本的值将导致在 cloud-init 的最后阶段运行给定的 shell 脚本(我相信在您引用的一次性文件夹中的 cloud-init 指令之后)。

如果您想在 EC2 中使用自定义 cloud-init 指令和 shell 脚本 user_data您需要使用多部分/混合 MIME 格式的属性 https://aws.amazon.com/premiumsupport/knowledge-center/execute-user-data-ec2/

长答案 :
user_data可以保存要通过 EC2 元数据、脚本或 cloud-init 指令读取的原始数据。此外,您可以将其设置为多部分/混合 MIME 类型并提供其中的每一个。

user_data是原始数据,可以在 EC2 实例中使用 curl 命令获取。由调用命令来解释数据,它可以是用户选择的任何内容。
[ec2-user ~]$ curl http://169.254.169.254/latest/user-data
user_data是一个脚本(例如第一行中的 #!/bin/bash),它在 cloud-init https://cloudinit.readthedocs.io/en/latest/topics/boot.html#final 的最后阶段作为 cloud-init 中的一个步骤运行.

user_data是一个 cloud-init 指令(例如第一行中的 #cloud-config),它作为指定的 cloud-init 指令运行。

来自 https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#user-data-cloud-init

“要将 cloud-init 指令传递给具有 user_data 的实例...在 user_data 文本中输入您的 cloud-init 指令文本。”

像这样

#cloud-config
repo_update: true
repo_upgrade: all

packages:
- httpd
- mariadb-server

runcmd:
- [ sh, -c, "amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2" ]
- systemctl start httpd
- sudo systemctl enable httpd
- [ sh, -c, "usermod -a -G apache ec2-user" ]
- [ sh, -c, "chown -R ec2-user:apache /var/www" ]
- chmod 2775 /var/www
- [ find, /var/www, -type, d, -exec, chmod, 2775, {}, \; ]
- [ find, /var/www, -type, f, -exec, chmod, 0664, {}, \; ]
- [ sh, -c, 'echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php' ]

此处描述了多部分/混合 MIME 格式 https://aws.amazon.com/premiumsupport/knowledge-center/execute-user-data-ec2/ , 举个例子
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
/bin/echo "Hello World" >> /tmp/testfile.txt
--//

关于cloud-init - 在 AWS 中,user_data 是否在 cloud-init 之前执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58171489/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com