IBM Cloud Docs
在 VPC 中的虛擬伺服器實例上安裝軟體

在 VPC 中的虛擬伺服器實例上安裝軟體

本指導教學可能會產生成本。 使用「成本估算器」根據您的預計用量生成成本估算。

本指導教學將全程指導您完成佈建 IBM Cloud® Virtual Private Cloud (VPC) 基礎架構,並使用 Terraform 和 Ansible 等基礎架構即程式碼 (IaC) 工具在虛擬伺服器實例 (VSI)上安裝軟體。

介紹完教程架構 後,您將為教程 準備環境,並在 IBM Cloud 中複 習軟體安裝的基本知識。 這時您可以決定評估所有的技術,或是跳到特定的獨立部分,例如 Terraform 或. Ansible.

目標

  • 瞭解 IBM 提供的作業系統軟體。
  • 利用更新作業系統軟體並安裝新軟體的手動步驟。
  • 瞭解如何使用 IBM Cloud CLI、Terraform 和 Ansible 來自動佈建資源和執行軟體安裝。

在本指導教學中,您將部署在另一個指導教學中引進的配置: Virtual Private Cloud 中的公用前端和專用後端。 您將佈建可透過公用網際網路存取的前端伺服器,用於與無網際網路連線功能的後端伺服器進行對話。

虛擬私有雲中公用前端與私有後端的架構
教學的架構圖

此配置還包括 一個堡壘主機,充當跳轉伺服器,允許與沒有公共 IP 位址的實例建立安全連線:

防禦主機的架構
防禦主機的架構

在佈建資源時,您還將在虛擬伺服器實例上部署應用程式。 在雲端中部署應用程式時,軟體可以來自不同的來源:

  1. 本端工作站的檔案系統 - 使用 Terraform 等工具來建立必要的基礎架構,或使用 Ansible、sshscp 在虛擬伺服器實例上安裝和配置軟體;
  2. IBM 鏡映 - 用於更新作業系統或安裝支援的套件;
  3. 網際網路或內部網路軟體儲存庫。

架構圖,顯示要安裝軟體的不同來源
架構圖,顯示要安裝軟體的不同來源

您將探索如何使用這些不同的來源。

開始之前

建立 VPC SSH 金鑰

佈建虛擬伺服器實例時,將向這些實例中注入 SSH 金鑰,以便稍後可以連接至伺服器。

  1. 如果本端機器上沒有 SSH 金鑰,請參閱 這些指示,以建立 VPC 的金鑰。 依預設,私密金鑰位於 $HOME/.ssh/id_rsa
  2. VPC 主控台中的運算 / SSH 金鑰下,新增 SSH 金鑰。 請務必在本指導教學中要建立其他資源的相同資源群組中建立金鑰。

設定環境變數

本指導教學隨附的範例程式碼說明在 VPC 環境中佈建資源以及安裝或更新軟體的不同選項。

此範例程式碼將全程指導您使用 Shell、terraformansible 在終端機上完成範例步驟。 在稍後步驟中將安裝這些工具。 要使 Script 能夠正常運作,您需要定義一組環境變數。

  1. 複製指導教學 原始碼儲存庫:

    git clone https://github.com/IBM-Cloud/vpc-tutorials.git
    
  2. 定義名為 CHECKOUT_DIR 的變數,以指向原始碼目錄:

    cd vpc-tutorials
    export CHECKOUT_DIR=$PWD
    
  3. 切換到指導教學目錄:

    cd $CHECKOUT_DIR/vpc-app-deploy
    
  4. 複製配置檔:

    cp export.template export
    
  5. 編輯 export 檔案,並設定環境變數值:

    • TF_VAR_ibmcloud_api_key 是 IBM Cloud API 金鑰。 您可以從主控台建立一個 API 金鑰。

    • TF_VAR_ssh_key_name 是先前區段中識別的 VPC SSH 公開金鑰的名稱。 這是將載入到虛擬服務實例,以透過工作站上的私密金鑰提供安全 SSH 存取的公開金鑰。 使用 CLI 來驗證它是否存在:

      ibmcloud is keys
      
    • TF_VAR_resource_group_name 是將在其中建立資源的資源群組。 請參閱建立和管理資源群組

    • TF_VAR_region 是將在其中建立資源的地區。 此指令將顯示區域:

      ibmcloud is regions
      
    • TF_VAR_zone 是將在其中建立資源的區域。 此指令將顯示區域:

      ibmcloud is zones
      
    • TF_VAR_ssh_agent 指出使用受通行詞組保護的 SSH 金鑰。 將變數解除註解,以啟用該變數。 然後,使用 ssh-add ~/.ssh/id_rsa 將 SSH 金鑰新增至鑑別代理程式。

  6. 將變數載入到環境中:

    source export
    

    確保在後續各區段中一律使用相同的終端機視窗,否則如果使用新視窗,需設定環境變數export 中的環境變數採用 Terraform 格式 (注意 TF_VAR_ 前綴),以方便使用。 後續各部分中將使用這些變數。

軟體安裝基礎知識

從基本映像檔佈建虛擬伺服器實例

佈建虛擬伺服器實例時,請從 IBM 提供的一組預先定義的作業系統映像檔中選取基本映像檔。 使用 ibmcloud is images 來尋找可用映像檔的清單。

IBM 有內部鏡映來支援 IBM 映像檔。 這些鏡映將在 IBM 提供的映像檔中包含軟體的新版本以及與發行套件關聯的選用套件。 鏡映是 IBM Cloud VPC可用的 服務端點 的一部分。 讀取鏡映沒有任何進入成本。

請考慮從這些鏡映更新已佈建實例可用的版本清單,以及升級已安裝的軟體。

使用 cloud-init 起始設定和自訂雲端實例

在配置虛擬伺服器實例時,您可以指定在伺服器初始化過程中執行的 cloud-init 指令碼。 cloud-init 是一個多發行套件的套件,用於處理雲端實例的早期起始設定。 cloud-init 定義了一組檔案格式,用於對雲端實例起始設定進行編碼。

在 IBM Cloud 中,佈建伺服器時,會在 user-data 參數中提供 cloud-init 檔案內容。 有關可接受的使用者資料內容,請參閱使用者資料 格式。 如果需要除錯 Script 執行,則 cloud-init 會在虛擬伺服器實例上的 /var/log/cloud-init-output.log 中記錄起始設定 Script 的輸出。

本教學使用一個名為 install.sh 作為初始化腳本:

#!/bin/bash
set -x
apt-get update
apt-get install -y nginx
indexhtml=/var/www/html/index.html

# Demonstrate the availability of internet repositories.  If www.python.org is availble then other software internet software like
# npm, pip, docker, ...  if isolated only the software from the ibm mirrors can be accessed
if curl -o /tmp/x -m 3 https://www.python.org/downloads/release/python-373/; then
    echo INTERNET > $indexhtml
else
    echo ISOLATED > $indexhtml
fi

在此 Script 中,使用作業系統提供的軟體安裝工具來升級已安裝的軟體,並安裝 nginx 和其他套件,這些作業示範即使隔離的實例也可以存取 IBM 提供的鏡映。 對於 Ubuntu,將使用 apt-get 指令來存取鏡映。

存取 www.python.org 的 curl 指令示範試圖從網際網路存取軟體並可能安裝軟體的作業。

根據主機是否具有網際網路連線功能,此 Script 會修改 index.html 提供的 nginx 頁面。

從文件系統上傳並在實例上執行

內部部署系統或 CI/CD 管線的文件系統上可能提供有資料和軟體,這些資料和軟體需要上傳到虛擬伺服器實例,然後加以執行。

在此類情況下,可以使用與伺服器的 SSH 連線透過 scp 上傳檔案,然後透過 ssh 在伺服器上執行 Script。 假設您在內部部署系統和雲端之間建立了連線,如 VPN,則這些 Script 還可以從網際網路或在內部部署系統中擷取軟體安裝程式。

教學代碼包含一個名為 uploaded.sh 的腳本,它會從您的工作站上傳到虛擬伺服器實例(手動或透過 Terraform 和 Ansible 等自動化方式)。

在接下來的章節中,您將使用腳本 test_provision.bash 來確認伺服器是否已成功佈建、是否能存取網際網路,以及 uploaded.sh 指令碼是否已正確執行。

使用 IBM Cloud CLI 和 Shell Script

IBM Cloud CLI 提供了用於與您可以在 IBM Cloud 中建立的所有資源互動的指令。 本節說明如何使用這些指令,但您不會建立任何資源。 建議使用 Terraform 來部署完整解決方案。

開始之前

藉由執行下列步驟,安裝指令行 (CLI) 工具。

佈建虛擬伺服器實例並安裝軟體

CLI 具有 適用於所有 VPC 相關功能的外掛程式,包括運算及網路資源。

  1. 在使用 VPC 資源之前,請設定現行資源群組及區域:

    ibmcloud target -g $TF_VAR_resource_group_name -r $TF_VAR_region
    
  2. 若要佈建虛擬伺服器實例,請執行 ibmcloud is instance-create CLI 指令。 在 shared/install.sh 是用來初始化前端和後端伺服器的 cloud-init 檔案。 您可以使用如下所示的 --user-data 參數來傳遞 Script:

    ibmcloud is instance-create ... --user-data @shared/install.sh
    
  3. 部署前端及後端 VSI 並處於維護模式時,您可以將 Script 傳送至 (例如,前端伺服器),然後執行 Script 以從網際網路安裝軟體。 向前端伺服器傳送 Script:

    scp -F ../scripts/ssh.notstrict.config -o ProxyJump=root@$BASTION_IP_ADDRESS shared/uploaded.sh root@$FRONT_NIC_IP:/uploaded.sh
    

    然後執行此 Script:

    ssh -F ../scripts/ssh.notstrict.config -o ProxyJump=root@$BASTION_IP_ADDRESS root@$FRONT_NIC_IP sh /uploaded.sh
    

    伺服器上的 ssh 服務可能需要幾分鐘才能初始化,而 cloud-init 指令碼也需要幾分鐘才能完成。 uploaded.sh Script 將等待起始設定完成,然後再結束。

使用 Terraform 佈建基礎架構

Terraform 可讓您安全且可預測地建立、變更及改進基礎架構。 Terraform 是一個開放程式碼工具,用於將 API 編碼為宣告的配置檔,這些檔案可以在團隊成員之間共用,視為程式碼,進行編輯、檢閱和版本化。

開始之前

遵循指示,在工作站上 安裝 Terraform 及 IBM Cloud Terraform 的提供者外掛程式

佈建單一虛擬伺服器實例

在部署更複雜的架構之前,為了驗證 Terraform 提供者安裝,請使用浮動 IP 來部署單一虛擬伺服器實例,然後透過 SSH 存取此伺服器。

檢查 main.tf 檔案中的 terraform 指令碼。 它利用的是先前定義的環境變數。

  1. 對於此範例,請切換到 Terraform Script 資料夾:

    cd $CHECKOUT_DIR/vpc-app-deploy/tfinstance
    
  2. 起始設定 Terraform:

    terraform init
    
  3. 套用 Terraform 方案:

    terraform apply
    

    此 Script 會建立 VPC、VSI 並啟用 SSH 存取。

  4. 檢視方案產生的輸出:

    terraform output
    
  5. 您可以複製並貼上先前指令的輸出,也可以如下所示使用 terraform output 透過 SSH 連接到 VSI。

    $(terraform output -raw sshcommand)
    

    套用了 Terraform 方案後,如果您希望在其他 Script 中重複使用資源內容,則使用 Terraform 中的輸出會非常方便。

  6. 移除 Terraform 建立的資源:

    terraform destroy
    

佈建子網路及虛擬伺服器實例

vpc-tutorials 資源庫 vpc-app-deploy/tf 資料夾下的 Terraform 檔案集實現了虛擬私有雲教學中公共前端和私有後端的架構。

腳本 vpc-app-deploy/tf/main.tf 包含資源的定義。 它導入了與其他教學共用的 Terraform 模組

   module vpc_pub_priv {
     source = "../../vpc-public-app-private-backend/tfmodule"
     basename = "${local.BASENAME}"
     ssh_key_name = "${var.ssh_key_name}"
     zone = "${var.zone}"
     backend_pgw = false
     profile = "${var.profile}"
     image_name = "${var.image_name}"
     resource_group_name = "${var.resource_group_name}"
     maintenance = "${var.maintenance}"
     frontend_user_data = "${file("../shared/install.sh")}"
     backend_user_data = "${file("../shared/install.sh")}"
   }

在此定義中:

  • backend_pgw 控制後端伺服器是否有權存取公用網際網路。 公用閘道可以連接至後端子網路。 前端指派有一個浮動 IP,用於提供針對網際網路的公用 IP 和閘道。 這將容許開啟網際網路存取以供軟體安裝。 後端無權存取網際網路。
  • frontend_user_databackend_user_data 指向 cloud-init 起始設定 Script。

對於 Terraform,所有資源都可以具有關聯的佈建者。 null_resource 佈建者不會佈建雲端資源,但可以用於將檔案複製到伺服器實例。 腳本中使用此結構複製 uploaded.sh 檔案,然後執行,如下所示。 為了連接到伺服器,Terraform 支援 使用本教學中配置的堡壘主機

   resource "null_resource" "copy_from_on_prem" {
     connection {
       type        = "ssh"
       user        = "root"
       host        = "${module.vpc_pub_priv.frontend_network_interface_address}"
       private_key = "${file("~/.ssh/id_rsa")}"
       bastion_user        = "root"
       bastion_host        = "${local.bastion_ip}"
       bastion_private_key = "${file("~/.ssh/id_rsa")}"
     }
     provisioner "file" {
       source      = "../shared/${local.uploaded}"
       destination = "/${local.uploaded}"
      }
     provisioner "remote-exec" {
       inline      = [
         "bash -x /${local.uploaded}",
        ]
     }
   }

若要佈建資源,請執行下列動作:

  1. 切換到 Terraform Script 資料夾:
    cd $CHECKOUT_DIR/vpc-app-deploy/tf
    
  2. 起始設定 Terraform:
    terraform init
    
  3. 套用 Terraform 方案:
    terraform apply
    
  4. 檢視方案產生的輸出:
    terraform output
    

測試虛擬伺服器的配置

既然 Terraform 已經部署了資源,現在可以驗證這些資源是否已正確佈建。

  1. 驗證可以聯繫前端虛擬伺服器實例,且它有對網際網路的出埠存取權:
    ../test_provision.bash $(terraform output -raw FRONT_IP_ADDRESS) INTERNET hi
    
    指令輸出應該為:
    success: httpd default file was correctly replaced with the following contents:
    INTERNET
    success: provision of file from on premises worked and was replaced with the following contents:
    hi
    
  2. 驗證可以透過防禦主機聯繫後端,且它不能存取網際網路:
    ../test_provision.bash $(terraform output -raw BACK_NIC_IP) ISOLATED hi "ssh -F ../../scripts/ssh.notstrict.config root@$(terraform output -raw FRONT_NIC_IP) -o ProxyJump=root@$(terraform output -raw BASTION_IP_ADDRESS)"
    
    指令輸出應該為:
    success: httpd default file was correctly replaced with the following contents:
    ISOLATED
    success: provision of file from on premises worked and was replaced with the following contents:
    hi
    

移除資源

  1. 移除 Terraform 建立的資源:
    terraform destroy
    

使用 Ansible 安裝軟體

Ansible 是一款配置管理和佈署工具,類似於 ChefPuppet,設計用於在雲端自動化多層應用程式的部署和佈署。 Ansible 用 Python 撰寫,並使用 YAML 語法來說明自動化作業,這使得 Ansible 易學易用。

雖然可以使用 Ansible 來佈建 VPC 資源和安裝軟體,但此區段使用 Terraform 來佈建 VPC 資源,使用 Ansible 來部署軟體。

開始之前

此區段同時使用 Terraform 和 Ansible。

  1. 遵循指示,在工作站上 安裝 Terraform 及 IBM Cloud Terraform 的提供者外掛程式
  2. 遵循 這些指示 來安裝 Ansible。

Ansible 教戰手冊

Ansible 教戰手冊提供要執行的作業。 以下範例具有安裝 nginx 和上傳 Script 所需的一組作業。 您將注意到這些作業與早先討論的 cloud-init Script 很類似。 uploaded.sh Script 完全相同。

- hosts: FRONT_NIC_IP BACK_NIC_IP
  remote_user: root
  tasks:
  - name: update apt cache manual
    # this should not be required but without it the error: Failed to lock apt for exclusive operation is generated
    shell: apt update
    args:
      executable: /bin/bash
  - name: update apt cache
    apt:
      update_cache: yes
  - name: ensure nginx is at the latest version
    apt:
      name: nginx
      state: latest
    notify:
    - restart nginx
  - name: execute init.bash
    script: ./init.bash
  - name: upload execute uploaded.sh
    script: ../shared/uploaded.sh
  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted

Ansible 清單

Ansible 可以同時針對基礎架構中的多個系統工作。 Ansible 清單包含這些系統的清單。 教程提供了一個腳本 inventory.bash 從 Terraform 輸出產生 Ansible 目錄。

#!/bin/bash
TF=tf
printf 'all:
  children:
    FRONT_NIC_IP:
      hosts:
        %s
    BACK_NIC_IP:
      hosts:
        %s
' $(cd $TF; terraform output -raw FRONT_NIC_IP) $(cd $TF; terraform output -raw BACK_NIC_IP)

佈建子網路及虛擬伺服器實例

目錄 vpc-app-deploy/ansible/tf 包含與上一節所述類似的 Terraform 配置,只是軟體安裝已被剝離。 Ansible Script 將從鏡映來安裝軟體,然後從工作站上傳軟體。

  1. 對於此範例,請切換到 Ansible Script 資料夾:
    cd $CHECKOUT_DIR/vpc-app-deploy/ansible/tf
    
  2. 起始設定 Terraform:
    terraform init
    
  3. 套用 Terraform 方案:
    terraform apply
    
  4. 檢視方案產生的輸出:
    terraform output
    
  5. 產生 Ansible 清單:
    cd .. && ./inventory.bash > inventory
    
  6. 在前端伺服器上佈建軟體:
    ansible-playbook -T 40 -l FRONT_NIC_IP -u root \
      --ssh-common-args "-F ../../scripts/ssh.notstrict.config -o ProxyJump=root@$(cd tf; terraform output -raw BASTION_IP_ADDRESS)" \
      -i inventory lamp.yaml
    
  7. 在後端伺服器上佈建軟體:
    ansible-playbook -T 40 -l BACK_NIC_IP -u root \
      --ssh-common-args "-F ../../scripts/ssh.notstrict.config -o ProxyJump=root@$(cd tf; terraform output -raw BASTION_IP_ADDRESS)" \
      -i inventory lamp.yaml
    

測試虛擬伺服器的配置

既然 Terraform 已經部署了資源並且 Ansible 安裝了軟體,現在可以驗證它們是否已正確佈建。

  1. 驗證可以聯繫前端虛擬伺服器實例,且它有對網際網路的出埠存取權:
    ../test_provision.bash $(cd tf && terraform output -raw FRONT_IP_ADDRESS) INTERNET hi
    
    指令輸出應該為:
    success: httpd default file was correctly replaced with the following contents:
    INTERNET
    success: provision of file from on premises worked and was replaced with the following contents:
    hi
    
  2. 驗證可以透過防禦主機聯繫後端,且它不能存取網際網路:
    ../test_provision.bash $(cd tf && terraform output -raw BACK_NIC_IP) ISOLATED hi "ssh -F ../../scripts/ssh.notstrict.config root@$(cd tf && terraform output -raw FRONT_NIC_IP) -o ProxyJump=root@$(cd tf && terraform output -raw BASTION_IP_ADDRESS)"
    
    指令輸出應該為:
    success: httpd default file was correctly replaced with the following contents:
    ISOLATED
    success: provision of file from on premises worked and was replaced with the following contents:
    hi
    

移除資源

  1. 移除 Terraform 建立的資源:

    cd $CHECKOUT_DIR/vpc-app-deploy/ansible/tf
    

    terraform destroy
    

視資源而定,它可能不會立即刪除,但會保留 (依預設會保留 7 天)。 您可以透過永久刪除資源或在保留期間內還原資源來收回資源。 請參閱本文件,以瞭解如何 使用資源收回