Comment faire pour que les scripts de démarrage cloud-init s'exécutent à chaque démarrage D'une instance EC2?
j'ai une instance EC2 qui exécute un AMI basé sur L'AMI Linux D'Amazon. Comme tous ces AMIs, il soutient le cloud-init système pour exécuter des scripts de démarrage basés sur les données de L'utilisateur passées dans chaque instance. Dans ce cas particulier, mon entrée de données utilisateur se trouve être un fichier Include qui génère plusieurs autres scripts de démarrage:
#include
http://s3.amazonaws.com/path/to/script/1
http://s3.amazonaws.com/path/to/script/2
la première fois que je démarre mon instance, le script de démarrage cloud-init fonctionne correctement. Cependant, si je fais un redémarrage doux de la exemple (en exécutant sudo shutdown -r now
, par exemple), l'instance de sauvegarder sans lancer le script de démarrage la deuxième fois. Si je vais dans les journaux système, je peux voir:
Running cloud-init user-scripts
user-scripts already ran once-per-instance
[ OK ]
ce n'est pas ce que je veux -- je peux voir l'utilité d'avoir des scripts de démarrage qui ne s'exécutent qu'une fois par instance pendant toute la durée de vie, mais dans mon cas ceux-ci devraient s'exécuter chaque fois que l'instance démarre, comme des scripts de démarrage normaux.
je me rends compte qu'une solution possible est d'manuellement demandez à mes scripts de s'insérer dans rc.local
après avoir couru la première fois. Cela semble toutefois lourd, puisque le cloud-init et le rc.les environnements d sont subtilement différents et je devrais maintenant déboguer les scripts sur le premier lancement et tous les lancements suivants séparément.
est ce que quelqu'un sait comment je peux cloud-init de toujours exécuter mes scripts? Cela ressemble certainement à quelque chose que les concepteurs de cloud-init auraient considéré.
5 réponses
en 11.10, 12.04 et plus tard, vous pouvez réaliser ceci en faisant 'scripts-user' exécuter 'always'. Dans /etc/nuage/cloud.cfg, vous verrez quelque chose comme:
cloud_final_modules:
- rightscale_userdata
- scripts-per-once
- scripts-per-boot
- scripts-per-instance
- scripts-user
- keys-to-console
- phone-home
- final-message
cela peut être modifié après le démarrage, ou les données de configuration du cloud qui supplantent cette strophe peuvent être insérées via les données utilisateur. C'est à dire, données utilisateur vous pouvez fournir:
#cloud-config
cloud_final_modules:
- rightscale_userdata
- scripts-per-once
- scripts-per-boot
- scripts-per-instance
- [scripts-user, always]
- keys-to-console
- phone-home
- final-message
cela peut aussi être '# included ' comme vous l'avez fait dans votre description. Malheureusement, pour le moment, vous ne pouvez pas modifier les 'cloud_final_modules', mais seulement le remplacer. J'espère pouvoir ajouter la possibilité de modifier les sections de configuration à un moment donné.
http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/view/head:/doc/examples/cloud-config.txtAlternativement, vous pouvez mettre des fichiers dans /var/lib/cloud/scripts/par-boot , et ils vont être exécutés par les "scripts-par-boot" chemin d'accès.
/etc/init.d/cloud-init-user-scripts
, modifiez cette ligne:
/usr/bin/cloud-init-run-module once-per-instance user-scripts execute run-parts ${SCRIPT_DIR} >/dev/null && success || failure
/usr/bin/cloud-init-run-module always user-scripts execute run-parts ${SCRIPT_DIR} >/dev/null && success || failure
Bonne chance !
une possibilité, bien que quelque peu hackish, est de supprimer le fichier de verrouillage que cloud-init utilise pour déterminer si oui ou non le script Utilisateur a déjà lancé. Dans mon cas (Amazon Linux AMI), ce fichier lock est situé dans /var/lib/cloud/sem/
et user-scripts.i-7f3f1d11
(la partie hachage à la fin change chaque boot). Par conséquent, l'utilisateur des données de script ajouté à la fin du fichier include fera l'affaire:
#!/bin/sh
rm /var/lib/cloud/sem/user-scripts.*
Je ne suis pas sûr que cela aura des effets négatifs sur quoi que ce soit d'autre, mais cela a fonctionné dans mes expériences.
cloud-init supporte cela maintenant nativement, voir les descriptions des commandes runcmd vs bootcmd dans la documentation (http://cloudinit.readthedocs.io/en/latest/topics/examples.html#run-commands-on-first-boot):
"runcmd":
#cloud-config
# run commands
# default: none
# runcmd contains a list of either lists or a string
# each item will be executed in order at rc.local like level with
# output to the console
# - runcmd only runs during the first boot
# - if the item is a list, the items will be properly executed as if
# passed to execve(3) (with the first arg as the command).
# - if the item is a string, it will be simply written to the file and
# will be interpreted by 'sh'
#
# Note, that the list has to be proper yaml, so you have to quote
# any characters yaml would eat (':' can be problematic)
runcmd:
- [ ls, -l, / ]
- [ sh, -xc, "echo $(date) ': hello world!'" ]
- [ sh, -c, echo "=========hello world'=========" ]
- ls -l /root
- [ wget, "http://slashdot.org", -O, /tmp/index.html ]
"la chaîne bootcmd":
#cloud-config
# boot commands
# default: none
# this is very similar to runcmd, but commands run very early
# in the boot process, only slightly after a 'boothook' would run.
# bootcmd should really only be used for things that could not be
# done later in the boot process. bootcmd is very much like
# boothook, but possibly with more friendly.
# - bootcmd will run on every boot
# - the INSTANCE_ID variable will be set to the current instance id.
# - you can use 'cloud-init-per' command to help only run once
bootcmd:
- echo 192.168.1.130 us.archive.ubuntu.com >> /etc/hosts
- [ cloud-init-per, once, mymkfs, mkfs, /dev/vdb ]
notez aussi l'exemple de commande" cloud-init-per " dans bootcmd. De il l'aide de:
Usage: cloud-init-per frequency name cmd [ arg1 [ arg2 [ ... ] ]
run cmd with arguments provided.
This utility can make it easier to use boothooks or bootcmd
on a per "once" or "always" basis.
If frequency is:
* once: run only once (do not re-run for new instance-id)
* instance: run only the first boot for a given instance-id
* always: run every boot
j'ai lutté avec cette question pendant presque deux jours, essayé toutes les solutions que j'ai pu trouver et finalement, combinant plusieurs approches, est venu avec ce qui suit:
MyResource:
Type: AWS::EC2::Instance
Metadata:
AWS::CloudFormation::Init:
configSets:
setup_process:
- "prepare"
- "run_for_instance"
prepare:
commands:
01_apt_update:
command: "apt-get update"
02_clone_project:
command: "mkdir -p /replication && rm -rf /replication/* && git clone https://github.com/awslabs/dynamodb-cross-region-library.git /replication/dynamodb-cross-region-library/"
03_build_project:
command: "mvn install -DskipTests=true"
cwd: "/replication/dynamodb-cross-region-library"
04_prepare_for_west:
command: "mkdir -p /replication/replication-west && rm -rf /replication/replication-west/* && cp /replication/dynamodb-cross-region-library/target/dynamodb-cross-region-replication-1.2.1.jar /replication/replication-west/replication-runner.jar"
run_for_instance:
commands:
01_run:
command: !Sub "java -jar replication-runner.jar --sourceRegion us-east-1 --sourceTable ${TableName} --destinationRegion ap-southeast-1 --destinationTable ${TableName} --taskName -us-ap >/dev/null 2>&1 &"
cwd: "/replication/replication-west"
Properties:
UserData:
Fn::Base64:
!Sub |
#cloud-config
cloud_final_modules:
- [scripts-user, always]
runcmd:
- /usr/local/bin/cfn-init -v -c setup_process --stack ${AWS::StackName} --resource MyResource --region ${AWS::Region}
- /usr/local/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource MyResource --region ${AWS::Region}
c'est la configuration pour le processus de réplication multi-régions de DynamoDb.