啟動時在您的 Linux 執行個體上執行命令 - Amazon Elastic Compute Cloud

啟動時在您的 Linux 執行個體上執行命令

當您在 Amazon EC2 上啟動執行個體時,您可以選擇將使用者資料傳遞給執行個體,用來執行常見的自動化組態任務,甚至在執行個體啟動之後執行指令碼。您可以將兩種類型的使用者資料傳遞給 Amazon EC2:shell 指令碼和 cloud-init 指示詞。您也可以將這項資料以純文字、檔案 (在使用命令列工具啟動執行個體時很有用) 或 Base64 編碼文字 (適用於 API 呼叫) 傳遞給啟動精靈。

若您對更複雜的自動化案例有興趣,請考慮使用 AWS CloudFormation 和 AWS OpsWorks。如需詳細資訊,請參閱《AWS CloudFormation 使用者指南》和 AWS OpsWorks User Guide

如需在啟動時於您的 Windows 執行個體上執行命令的資訊,請參閱《Windows 執行個體的 Amazon EC2 使用者指南》中的在啟動時於您的 Windows 執行個體上執行命令管理 Windows 執行個體組態

在以下範例中,來自在 Amazon Linux 2 上安裝 LAMP Web 伺服器的命令會轉換成 shell 指令碼及一組 cloud-init 指示詞,其會在執行個體啟動時執行。在每個範例中,以下任務都會由使用者資料執行:

  • 更新分佈軟體套件。

  • 安裝必要 Web 伺服器、phpmariadb 套件。

  • 透過 systemctl 啟動並開啟 httpd 服務。

  • ec2-user 即會新增至 apache 群組。

  • 接著便會為 Web 目錄和其中包含的檔案設定適當的所有權和檔案許可。

  • 一的簡單的網頁便會建立,用於測試 Web 伺服器和 PHP 引擎。

先決條件

以下範例假設您的執行個體具有公有 DNS 名稱,且可從網際網路連線。如需更多詳細資訊,請參閱 步驟 1:啟動執行個體。您也必須設定您的安全群組,允許 SSH (連接埠 22)、HTTP (連接埠 80) 和 HTTPS (連接埠 443) 連線。如需這些先決條件的詳細資訊,請參閱 設定 Amazon EC2

此外,這些說明適用於搭配使用 Amazon Linux 2,因此命令和指示詞可能無法在其他 Linux 發行版本上運作。如需其他分佈的詳細資訊,例如支援 cloud-init 的情形,請參閱其特定文件。

使用者資料與 Shell 指令碼

如果您熟悉 Shell 指令碼,這是在啟動時將指令傳送至執行個體的最簡單且最完整的方式。在開機階段新增這些任務也會增加開機執行個體所需要的時間長度。任務完成需要多花幾分鐘的時間,接著您便可以測試使用者指令碼是否已成功完成。

重要

根據預設,使用者資料指令碼和 cloud-init 指示詞只會在您第一次啟動執行個體時,在開機過程中執行。您可以更新組態,以確保使用者資料指令碼和 cloud-init 指示詞在您每次重新啟動執行個體時執行。如需詳細資訊,請參閱 AWS 知識中心的如何在每次重新啟動 EC2 執行個體時執行使用者資料?

使用者資料 shell 指令碼必須以 #! 字元,以及您希望讀取指令碼 (通常是 /bin/bash)) 的解譯器路徑做為開頭。如需 shell 指令碼的完整介紹,請參閱位於 Linux Documentation Project (tldp.org) 的 BASH Programming HOW-TO

做為使用者資料輸入的指令碼會以 root 使用者的身分執行,因此請不要在指令碼中使用 sudo 命令。請記得,任何您建立的檔案都會由 root 擁有;若您需要讓非超級使用者擁有檔案存取權,建議您根據需求在指令碼中修改許可。此外,因為指令碼不會以互動方式執行,您無法包含需要使用者意見回饋的命令 (例如不帶有 -y 標記的 yum update)。

cloud-init 輸出日誌檔 (/var/log/cloud-init-output.log) 會擷取主控台輸出,因此,若執行個體在啟動後未以您想要的方式運作,則可輕鬆地對您的指令碼進行除錯。

處理使用者資料指令碼時,會將其複製到 /var/lib/cloud/instances/instance-id/ 並從中執行。在執行指令碼之後,不會將其刪除。務必從 /var/lib/cloud/instances/instance-id/ 中刪除使用者資料指令碼,然後再從執行個體中建立 AMI。否則,從 AMI 啟動任何執行個體時,指令碼將存在於這個目錄中。

使用者資料與主控台

您可以在啟動執行個體時指定執行個體使用者資料。若執行個體的根磁碟區為 EBS 磁碟區,您也可以停止執行個體並更新其使用者資料。

在啟動時指定執行個體使用者資料

遵循使用啟動執行個體精靈啟動執行個體中啟動執行個體的程序,但當您到達該程序中的步驟 3:設定執行個體詳細資訊時,請複製位於 User data (使用者資料) 欄位中的 shell 指令碼,然後完成啟動程序。

在以下範例指令碼中,指令碼會建立並設定我們的 Web 伺服器。

#!/bin/bash yum update -y amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2 yum install -y httpd mariadb-server systemctl start httpd systemctl enable httpd usermod -a -G apache ec2-user 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 {} \; echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php

給予執行個體充分的時間啟動及執行您指令碼中的命令,然後檢查您的指令碼是否已完成您預計執行的任務。

針對我們的範例,在 Web 瀏覽器中,輸入指令碼建立之 PHP 測試檔案的 URL。此 URL 為您執行個體的公有 DNS 地址,其後跟隨斜線和檔案名稱。

http://my.public.dns.amazonaws.com/phpinfo.php

您現在應該會看見 PHP 資訊頁面。如果您未看見 PHP 資訊頁面,請檢查您使用的安全群組是否包含允許 HTTP (連接埠 80) 流量的規則。如需更多詳細資訊,請參閱 新增規則至安全群組

(選用) 若您的指令碼並未完成您預期執行的任務,或您只希望確認您的指令碼已順利完成,而沒有發生任何錯誤,請檢查位於 /var/log/cloud-init-output.log 的 cloud-init 輸出日誌檔案,並在輸出中查看是否有錯誤訊息。

如需額外的偵錯資訊,您可以使用以下指示詞建立包含 cloud-init 資料區段的 Mime 分段封存:

output : { all : '| tee -a /var/log/cloud-init-output.log' }

這個指示詞會將您指令碼的命令輸出傳送到 /var/log/cloud-init-output.log。如需 cloud-init 資料格式和建立 Mime 多部分封存的詳細資訊,請參閱 cloud-init 格式

檢視及更新執行個體使用者資料

修改執行個體使用者資料

  1. https://console.aws.amazon.com/ec2/ 開啟 Amazon EC2 主控台。

  2. 在導覽窗格中,選擇 Instances (執行個體)。

  3. 選取執行個體,並選擇 Actions (動作)Instance State (執行個體狀態)Stop (停止)

    警告

    停止執行個體時,在任何執行個體存放區磁碟區的資料都會清除。若要避免將資料放在執行個體存放區磁碟區上,請務必將它備份至持久性儲存。

  4. 出現確認提示時,請選擇 Yes, Stop (是,停止)。停止執行個體可能需要幾分鐘。

  5. 在仍然選取執行個體的情況下,選擇 Actions (動作)Instance Settings (執行個體設定)View/Change User Data (檢視/變更使用者資料)。您無法在執行個體仍在執行中時變更使用者資料,但您可以檢視它。

  6. View/Change User Data (檢視/變更使用者資料) 對話方塊中,更新使用者資料,然後選擇 Save (儲存)

  7. 重新啟動執行個體。新的使用者資料便會在重新啟動之後出現在您的執行個體上;但使用者資料指令碼並未執行。

使用者資料與 cloud-init 指示詞

cloud-init 套件會在啟動時設定新 Amazon Linux 執行個體的特定部分;最明顯的是,它會設定 ec2-user 的 .ssh/authorized_keys 檔案,讓您可以使用自己的私有金鑰登入。如需更多詳細資訊,請參閱cloud-init

cloud-init 使用者指示詞可在啟動時,以傳遞指令碼相同的方式傳遞到執行個體,雖然語法不同。如需 cloud-init 的詳細資訊,請前往 http://cloudinit.readthedocs.org/en/latest/index.html

重要

根據預設,使用者資料指令碼和 cloud-init 指示詞只會在您第一次啟動執行個體時,在開機過程中執行。您可以更新組態,以確保使用者資料指令碼和 cloud-init 指示詞在您每次重新啟動執行個體時執行。如需詳細資訊,請參閱 AWS 知識中心的如何在每次重新啟動 EC2 執行個體時執行使用者資料?

在開機階段新增這些任務也會增加開機執行個體所需要的時間長度。任務完成需要多花幾分鐘的時間,接著您便可以測試您的使用者資料指示詞是否已完成。

使用使用者資料將 cloud-init 指示詞傳遞給執行個體

  1. 遵循使用啟動執行個體精靈啟動執行個體中啟動執行個體的程序,但當您到達該程序中的步驟 3:設定執行個體詳細資訊時,請在 User data (使用者資料) 欄位中輸入您的 cloud-init 指示詞文字,然後完成啟動程序。

    在以下範例中,指示詞會在 Amazon Linux 2 上建立及設定 Web 伺服器。頂端的 #cloud-config 為將命令識別為 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' ]
  2. 給予執行個體充分的時間啟動及執行您使用者資料中的指示詞,然後檢查您的指示詞是否已完成您預計執行的任務。

    針對我們的範例,在 Web 瀏覽器中,輸入指示詞建立之 PHP 測試檔案的 URL。此 URL 為您執行個體的公有 DNS 地址,其後跟隨斜線和檔案名稱。

    http://my.public.dns.amazonaws.com/phpinfo.php

    您現在應該會看見 PHP 資訊頁面。如果您未看見 PHP 資訊頁面,請檢查您使用的安全群組是否包含允許 HTTP (連接埠 80) 流量的規則。如需更多詳細資訊,請參閱 新增規則至安全群組

  3. (選用) 若您的指示詞並未完成您預期執行的任務,或您只希望確認您的指示詞已順利完成,而沒有發生任何錯誤,請檢查位於 /var/log/cloud-init-output.log 的 cloud-init 輸出日誌檔案,並在輸出中查看是否有錯誤訊息。如需其他偵錯資訊,您可以為您的指示詞新增下行:

    output : { all : '| tee -a /var/log/cloud-init-output.log' }

    這個指示詞會將 runcmd 的輸出傳送到 /var/log/cloud-init-output.log

使用者資料與 AWS CLI

您可以使用 AWS CLI 指定、修改和檢視您執行個體的使用者資料。如需使用執行個體中繼資料檢視您執行個體中使用者資料的資訊,請參閱擷取執行個體使用者資料

在 Windows 上,您可以使用 適用於 Windows PowerShell 的 AWS 工具 而非使用 AWS CLI。如需詳細資訊,請參閱《Windows 執行個體的 Amazon EC2 使用者指南》中的使用者資料和 適用於 Windows PowerShell 的 工具

範例:在啟動時指定使用者資料

若要在啟動您的執行個體時指定使用者資料,請搭配 --user-data 參數使用 run-instances 命令。使用 run-instances 時,AWS CLI 會為您執行使用者資料的 base64 編碼。

以下範例顯示如何在命令列上將指令碼指定為字串:

aws ec2 run-instances --image-id ami-abcd1234 --count 1 --instance-type m3.medium \ --key-name my-key-pair --subnet-id subnet-abcd1234 --security-group-ids sg-abcd1234 \ --user-data echo user data

以下範例顯示如何使用文字檔案指定指令碼。請確認使用 file:// 前綴來指定檔案。

aws ec2 run-instances --image-id ami-abcd1234 --count 1 --instance-type m3.medium \ --key-name my-key-pair --subnet-id subnet-abcd1234 --security-group-ids sg-abcd1234 \ --user-data file://my_script.txt

以下是具有 shell 指令碼的範例文字檔案。

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

範例:修改已停止執行個體的使用者資料

您可以使用 modify-instance-attribute 命令修改已停止執行個體的使用者資料。使用 modify-instance-attribute 時,AWS CLI 不會為您執行使用者資料的 base64 編碼。

  • Linux 電腦上,請使用 base64 命令來編碼使用者資料。

    base64 my_script.txt >my_script_base64.txt
  • Windows 電腦上,請使用 certutil 命令編碼使用者資料。在您搭配 AWS CLI 使用此檔案前,您必須先移除第一行 (BEGIN CERTIFICATE) 和最後一行 (END CERTIFICATE)。

    certutil -encode my_script.txt my_script_base64.txt notepad my_script_base64.txt

請使用 --attribute--value 參數,使用已編碼的文字檔案來指定使用者資料。請確認使用 file:// 前綴來指定檔案。

aws ec2 modify-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData --value file://my_script_base64.txt

範例:清除已停止執行個體的使用者資料

若要刪除現有的使用者資料,請使用 modify-instance-attribute 命令,如下所示:

aws ec2 modify-instance-attribute --instance-id i-1234567890abcdef0 --user-data Value=

範例:檢視使用者資料

若要擷取執行個體的使用者資料,請使用 describe-instance-attribute 命令。使用 describe-instance-attribute 時,AWS CLI 不會為您執行使用者資料的 base64 解碼。

aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData

下列為已使用 base64 編碼之使用者資料的範例輸出。

{ "UserData": { "Value": "IyEvYmluL2Jhc2gKeXVtIHVwZGF0ZSAteQpzZXJ2aWNlIGh0dHBkIHN0YXJ0CmNoa2NvbmZpZyBodHRwZCBvbg==" }, "InstanceId": "i-1234567890abcdef0" }
  • Linux 上,請使用 --query 選項取得已編碼的使用者資料,並使用 base64 命令將其解碼。

    aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData --output text --query "UserData.Value" | base64 --decode
  • Windows 電腦上,使用 --query 選項以取得已編碼的使用者資料,並使用 certutil 命令將其解碼。請注意,編碼輸出會存放在檔案中,解碼輸出則會存放在另一個檔案中。

    aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData --output text --query "UserData.Value" >my_output.txt certutil -decode my_output.txt my_output_decoded.txt type my_output_decoded.txt

下列為範例輸出。

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