Como faço com que os scripts de inicialização do cloud-init corram sempre que as minhas botas de instância EC2?
eu tenho uma instância EC2 rodando um AMI baseado no Amazon Linux AMI. Como todos esses AMIs, ele suporta o sistema cloud-init para executar scripts de inicialização com base nos dados do Usuário passados em cada instância. Neste caso em particular, a minha entrada de dados do Utilizador é um ficheiro de inclusão que obtém vários outros programas de arranque:
#include
http://s3.amazonaws.com/path/to/script/1
http://s3.amazonaws.com/path/to/script/2
a primeira vez que inicializo a minha instância, o programa de inicialização do cloud-init corre correctamente. No entanto, se eu fizer um reboot suave da instância (por executando sudo shutdown -r now
, por exemplo), a instância volta a subir sem executar o programa inicial da segunda vez. Se eu entrar nos registos do sistema, Posso ver:
Running cloud-init user-scripts
user-scripts already ran once-per-instance
[ OK ]
isto não é o que eu quero -- eu posso ver a utilidade de ter scripts de inicialização que só correm uma vez por instância durante a vida, mas no meu caso estes devem correr sempre que a instância começa, como scripts de inicialização normais.
eu percebo que uma solução possível é ter manualmente os meus scripts a inserir-se. depois de correr da primeira vez. Isto parece-me, no entanto, penoso, uma vez que o cloud-init e o rc.ambientes d são sutilmente diferentes e eu teria agora que depurar scripts no primeiro lançamento e todos os lançamentos subsequentes separadamente.
Alguém sabe como posso dizer ao cloud-init para correr sempre os meus guiões? Isso certamente soa como algo que os designers do cloud-init teriam considerado.5 answers
Em 11.10, 12.04 e mais tarde, você pode conseguir isso fazendo o' scripts-user 'executar ' sempre'. Em/etc/cloud / cloud.cfg você vai ver algo como: [[4]}
cloud_final_modules:
- rightscale_userdata
- scripts-per-once
- scripts-per-boot
- scripts-per-instance
- scripts-user
- keys-to-console
- phone-home
- final-message
Isto pode ser modificado após o arranque, ou os dados de configuração da nuvem que substituem esta estrofe podem ser inseridos através de dados do utilizador. Ie, nos dados do utilizador pode fornecer:
#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
Isso também pode ser '#incluido' como você fez na sua descrição. Infelizmente, neste momento, não é possível modificar os modelos cloud_ final_, mas apenas sobrepô-los. Espero que sim. para adicionar a capacidade de modificar seções de configuração em algum momento.
Há um pouco mais de informação sobre isto no doc cloud-config em http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/view/head:/doc/examples/cloud-config.txt
Em alternativa, poderá colocar os ficheiros no /var/lib/cloud/scripts / por-boot , e eles serão executados pela localização 'scripts-per-boot'.
Em /etc/init.d/cloud-init-user-scripts
, edite esta linha:
/usr/bin/cloud-init-run-module once-per-instance user-scripts execute run-parts ${SCRIPT_DIR} >/dev/null && success || failure
A
/usr/bin/cloud-init-run-module always user-scripts execute run-parts ${SCRIPT_DIR} >/dev/null && success || failure
Boa sorte !
Uma possibilidade, embora um pouco hackish, é apagar o arquivo de bloqueio que o cloud-init usa para determinar se o script do usuário já foi executado ou não. No meu caso (Amazon Linux AMI), este ficheiro de bloqueio está localizado em /var/lib/cloud/sem/
e chama-se user-scripts.i-7f3f1d11
(a parte hash no fim muda cada arranque). Portanto, o seguinte script de dados de usuário adicionado ao final do arquivo Include irá fazer o truque:
#!/bin/sh
rm /var/lib/cloud/sem/user-scripts.*
Não tenho a certeza se isto terá quaisquer efeitos adversos em qualquer outra coisa, mas tem trabalhou nas minhas experiências.
O Cloud-init suporta isto agora de forma nativa, veja as descrições de comandos do runcmd vs bootcmd na documentação (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 ]
"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 ]
Note também o exemplo de comando "cloud-init-per" no bootcmd. Da sua ajuda.
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
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}
Esta é a configuração para o processo de replicação transversal do DynamoDb.