2011-06-25 6 views
41

Mam instancji EC2 z uruchomionym AMI opartym na AMI Amazon Linux. Podobnie jak wszystkie takie AMI, obsługuje system cloud-init do uruchamiania skryptów startowych opartych na danych użytkownika przekazywanych do każdej instancji. W tym konkretnym przypadku, mój Wprowadzanie danych użytkownika zdarza się być Dołącz plik, który kilka innych źródeł skryptów startowych:W jaki sposób mogę uruchamiać skrypty uruchamiania przy uruchamianiu w chmurze za każdym razem, gdy uruchamiana jest moja instancja EC2?

#include 
http://s3.amazonaws.com/path/to/script/1 
http://s3.amazonaws.com/path/to/script/2 

Pierwszy raz uruchomić moje wystąpienie, skrypt startowy chmury startowych przebiega prawidłowo. Jeśli jednak wykonam miękkie ponowne uruchomienie instancji (na przykład, uruchamiając sudo shutdown -r now), instancja ponownie pojawi się bez uruchamiania skryptu startowego za drugim razem. Jeśli pójdę do logów systemowych, widzę:

Running cloud-init user-scripts 
user-scripts already ran once-per-instance 
[ OK ] 

To nie jest to, co chcę - Widzę użyteczność posiadania skryptów startowych, które uruchamiane tylko raz za przykład życia, ale w moim przypadku te powinny uruchamiane przy każdym uruchomieniu instancji, podobnie jak zwykłe skrypty startowe.

Zdaję sobie sprawę, że jednym z możliwych rozwiązań jest ręczne umieszczenie moich skryptów w rc.local po pierwszym uruchomieniu. Wydaje się to jednak uciążliwe, ponieważ środowiska cloud-init i rc.d są nieco różne i teraz musiałbym debugować skrypty przy pierwszym uruchomieniu i wszystkie kolejne uruchomienia oddzielnie.

Czy ktoś wie, w jaki sposób mogę powiedzieć cloud-init, aby zawsze uruchamiał moje skrypty? To z pewnością brzmi jak coś, co pomyśliliby twórcy chmurowego inicjatora.

Odpowiedz

42

W 11.10, 12.04 i późniejszych można to osiągnąć, ustawiając "skrypts-user" zawsze ". W /etc/cloud/cloud.cfg zobaczysz coś takiego:

cloud_final_modules: 
- rightscale_userdata 
- scripts-per-once 
- scripts-per-boot 
- scripts-per-instance 
- scripts-user 
- keys-to-console 
- phone-home 
- final-message 

ten może być zmodyfikowany po wystartowaniu systemu lub danych cloud-config nadrzędne ten zwrotka można wprowadzić poprzez dane użytkowników. Np. W danych użytkownika możesz podać:

#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 

Może to być również "#include", tak jak w opisie. Niestety, teraz nie można modyfikować "cloud_final_modules", ale tylko go przesłonić. Mam nadzieję, że dodam możliwość modyfikowania sekcji konfiguracji w pewnym momencie.

Jest nieco więcej informacji na ten temat w dokumencie cloud-config w http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/view/head:/doc/examples/cloud-config.txt

Alternatywnie, można umieścić pliki w/var/lib/Chmura/skrypty/per-bagażniku, i będą uruchamiane przez ścieżkę "scripts-per-boot".

+1

> Mam nadzieję, że dodam możliwość modyfikowania sekcji konfiguracji w pewnym momencie. Czy ta funkcja została dodana teraz? Widzę, że w najnowszym cloud-init jest funkcja "fuzji", ale nie mogłem wymyślić, jak to wykorzystać, aby zmienić tylko linię "scripts-user". To po prostu zastąpi całą listę, niezależnie od opcji, które przeszły. – Meta

+2

Oto jedna linijka, która dokonuje modyfikacji w linii: 'sed -i 's/scripts-user $/\ [scripts-user, always \] /'/etc/cloud/cloud.cfg' – wjordan

+0

Umieszczanie plików w '/ var/lib/cloud/scripts/per-boot' wydaje się dużo łatwiejszy, mogę go użyć do ustawienia [automatycznego zamykania ec2] (http://stackoverflow.com/a/38186787/4058484). – hyip

7

Jedną z możliwości, choć nieco hackish, jest usunięcie pliku blokady, który jest używany przez chmurę-init do ustalenia, czy skrypt użytkownika już się uruchomił. W moim przypadku (Amazon Linux AMI) ten plik blokady znajduje się w /var/lib/cloud/sem/ i nosi nazwę user-scripts.i-7f3f1d11 (część hash na końcu zmienia każde uruchomienie). Dlatego poniższy skrypt użytkownika dane dodawane do końca plik include rade:

#!/bin/sh 
rm /var/lib/cloud/sem/user-scripts.* 

Nie jestem pewien, czy będzie to miało negatywnego wpływu na cokolwiek innego, ale to działa w moim eksperymenty.

+1

"Część hash" wydaje się być identyfikatorem maszyny amazon - nie jest? – theist

+1

Wygląda jak identyfikator instancji AWS, w którym to przypadku zmieniłaby się przy każdym uruchomieniu instancji, ale pozostała taka sama w przypadku zatrzymań i ponownych uruchomień tej samej instancji. – froggythefrog

18

W /etc/init.d/cloud-init-user-scripts, edytować ten wiersz:

/usr/bin/cloud-init-run-module once-per-instance user-scripts execute run-parts ${SCRIPT_DIR} >/dev/null && success || failure 

do

/usr/bin/cloud-init-run-module always user-scripts execute run-parts ${SCRIPT_DIR} >/dev/null && success || failure 

Powodzenia!

+4

Działa również dla AMI Amazon ... – rbawaskar

4

chmury startowych obsługuje to teraz natywnie, zobacz runcmd vs opisy komend bootcmd w dokumentacji (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 ] 

również zwrócić uwagę na przykład polecenia "cloud-init-per" w bootcmd. Z niego za pomocą:

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 
+0

zaktualizuj odpowiedź z odpowiednimi cytatami z oficjalnej dokumentacji i połącz z oryginalną dokumentacją tylko w celach informacyjnych. –

+1

Część bootcmd jest wykonywana w systemie, który nie jest w pełni uruchomiony i może nie działać zgodnie z oczekiwaniami. – Nico

0

zmagałem się z tym problemem przez prawie dwa dni, próbował wszystkich rozwiązań udało mi się znaleźć i wreszcie, łącząc kilka podejść, przyszedł z poniższym:

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} 

To jest konfiguracja procesu replikacji międzyregionalnej DynamoDb.

Powiązane problemy