返回文章列表

Ansible自動化佈署與組態管理實戰

本文深入淺出地介紹了 Ansible 的核心概念和使用方法,包含 Playbook 的撰寫、Inventory 檔案的管理、以及如何利用 Ansible 自動化佈署 PHP、nginx 和 MySQL 等軟體套件。文章從 Vagrant 環境設定開始,逐步引導讀者理解 Ansible

DevOps 系統管理

Ansible 是一款功能強大的自動化工具,能有效簡化 DevOps 流程中的佈署和組態管理工作。本文將逐步示範如何使用 Ansible 建立和執行 Playbook,並探討 Inventory 檔案的應用。首先,我們會以一個簡單的 Playbook 為例,示範如何在 Vagrant 虛擬機器上安裝 PHP CLI 工具。接著,我們將逐步擴充套件 Playbook 的功能,加入安裝 nginx 和 MySQL 等常用軟體套件的任務。過程中,我們會探討如何處理許可權問題,並使用 become 選項以提升許可權執行特定任務。為了提高 Playbook 的可讀性和 maintainability,我們將學習如何使用 with_items 來簡化重複的任務。最後,我們將深入研究 Ansible 的 Inventory 檔案,學習如何定義主機、群組、變數等,並探討如何在沒有 Vagrant 的環境下,直接使用 Ansible 管理遠端主機。

使用Vagrant與Ansible建立虛擬機器

在嘗試執行vagrant up指令時,您可能會遇到錯誤,因為尚未建立必要的設定檔。錯誤訊息如下:

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
There are errors in the configuration of this machine. Please fix
the following errors and try again:
ansible provisioner:
* `playbook` for the Ansible provisioner does not exist on the host system:
/Users/michael/ansible-book/provisioning/playbook.yml

為瞭解決這個問題,您需要在專案目錄下建立一個名為provisioning的資料夾,並在其中建立一個名為playbook.yml的檔案。完成後,您可以再次執行vagrant provision,但此時會出現另一個錯誤,因為playbook.yml不是一個有效的YAML檔案:

ERROR! playbooks must be a list of plays
Ansible failed to complete successfully. Any error output should be
visible above. Please fix these errors and try again.

Ansible Playbook簡介

Ansible Playbook是一種特殊的YAML檔案,用於定義Ansible應該執行的任務。這些檔案使用特定的語法來描述所需的系統狀態,而不是像程式語言那樣逐步描述執行的過程。Playbook可以同步或非同步地執行任務,並且它們的格式易於人類和電腦閱讀。

編寫第一個Playbook

首先,您需要在provisioning資料夾下建立一個名為playbook.yml的檔案。這個檔案的第一行應該是`

,表示檔案的開始。接下來,您需要指定Ansible應該在哪個主機群組上執行任務。在這個例子中,我們將使用- hosts: all`來指定所有可用的主機。

---
- hosts: all
  tasks:
    - ping:

這個Playbook定義了一個名為tasks的區段,其中包含一個簡單的ping任務,用於測試Ansible是否能夠連線到目標主機。

程式碼解密:

---
- hosts: all  # 指定Ansible執行任務的主機群組
  tasks:       # 定義要執行的任務列表
    - ping:    # 使用ping模組測試連線
  1. **`

**: YAML檔案的開始標記。 2. **- hosts: all**: 指定這個Playbook應該在所有可用的主機上執行。 3. **tasks:**: 定義任務列表的開始。 4. **- ping:`**: 執行ping任務,用於測試連線。

執行vagrant provision後,您應該會看到類別似以下的輸出:

$ vagrant provision
==> default: Running provisioner: ansible...
PLAY [all] *********************************************************************
GATHERING FACTS ***************************************************************
ok: [default]
TASK: [ping] *******************************************************************
ok: [default]
PLAY RECAP *********************************************************************
default : ok=2 changed=0 unreachable=0 failed=0

為任務新增名稱

為了使輸出更易讀,您可以為每個任務新增一個名稱。例如:

---
- hosts: all
  tasks:
    - name: 確保能夠連線到機器
      ping:

這樣,當Ansible執行這個任務時,它將顯示您指定的名稱,而不是預設的任務名稱。

程式碼解密:

---
- hosts: all
  tasks:
    - name: 確保能夠連線到機器  # 為任務新增名稱,使輸出更易讀
      ping:                      # 執行ping任務
  1. name:: 為任務指定一個名稱。
  2. ping:: 執行ping模組,用於測試連線。

安裝軟體套件

現在,您已經可以連線到虛擬機器,接下來可以定義更多的任務來安裝所需的軟體套件。這將使您的虛擬機器變得更加實用。

自動化佈署與組態管理:Ansible 實戰入門

簡介與基礎安裝

在現代化的 DevOps 流程中,自動化佈署與組態管理扮演著至關重要的角色。Ansible 作為一款開源的自動化工具,能夠幫助開發者與維運團隊簡化複雜的佈署流程。本篇文章將帶領讀者一步步瞭解如何使用 Ansible 撰寫 Playbook 來自動化安裝 PHP、nginx 和 MySQL,並探討相關技術細節。

建立初始 Playbook

首先,我們需要建立一個基本的 Playbook 檔案 playbook.yml。這個檔案將定義我們要對目標主機執行的任務。在這個範例中,我們將安裝 PHP CLI 工具。

---
- hosts: all
  tasks:
    - name: 確保我們可以連線到虛擬機器
      ping:
    - name: 安裝 PHP
      apt: name=php5-cli state=present update_cache=yes

內容解密:

  1. hosts: all 表示這個 Playbook 將對所有在 inventory 中定義的主機執行。
  2. tasks 下定義了兩個任務:第一個是使用 ping 模組測試連線,第二個是使用 apt 模組安裝 PHP。
  3. apt 模組的引數 name=php5-cli 指定了要安裝的套件名稱,state=present 表示該套件應該存在,update_cache=yes 則會在安裝前更新套件快取。

處理許可權問題與擴充套件 Playbook

執行 vagrant provision 後,我們可能會遇到許可權問題,因為預設情況下 Ansible 使用 Vagrant 使用者登入,該使用者沒有安裝套件的許可權。這時,我們需要使用 become 選項來提升許可權。

---
- hosts: all
  become: true
  tasks:
    - name: 確保我們可以連線到虛擬機器
      ping:
    - name: 安裝 PHP
      apt: name=php5-cli state=present update_cache=yes
    - name: 安裝 nginx
      apt: name=nginx state=present
    - name: 安裝 MySQL
      apt: name=mysql-server-5.6 state=present

內容解密:

  1. 在 Playbook 層級新增 become: true 表示所有任務都將以提升的許可權執行。
  2. 新增了兩個任務來安裝 nginx 和 MySQL,進一步擴充套件了 Playbook 的功能。

簡化 Playbook 與最佳化

為了簡化 Playbook,我們可以移除不必要的任務,例如初始的 ping 測試。並且,利用 with_items 將多個 apt 任務合併為一個。

---
- hosts: all
  become: true
  tasks:
    - name: 安裝必要的套件
      apt: name={{item}} state=present update_cache=yes
      with_items:
        - php5-cli
        - nginx
        - mysql-server-5.6

內容解密:

  1. 使用 with_items 提供了一個套件名稱列表,Ansible 將為列表中的每個專案執行一次 apt 任務。
  2. {{item}} 是 Ansible 中的特殊變數,用於表示當前正在處理的列表專案。

Ansible 入門:理解 Inventory 檔案的重要性

在前一章中,我們已經建立了一個簡單的 Ansible Playbook,並透過 Vagrant 指令成功執行於虛擬機器上。現在,我們將進一步探討如何使用 ansible-playbook 指令直接對任何具備 SSH 服務的機器執行 Playbook。首先,我們需要了解 Ansible 的 Inventory 檔案。

何謂 Inventory?

在組態管理中,管理工具需要知道應該在哪台機器上執行操作,這被稱為 Inventory(清單)。沒有 Inventory 的話,我們雖然有一組定義了系統期望狀態的 Playbooks,但卻不知道應該對哪些機器執行這些操作。

與 Puppet 和 Chef 不同,Ansible 沒有中央伺服器來儲存這類別資訊。因此,我們需要另一種方式將所有必要資訊傳遞給執行程式碼以強制執行期望狀態。這就是 Inventory 檔案的作用。

Inventory 檔案的預設與自定義使用

預設情況下,Ansible 會讀取 /etc/ansible/hosts 作為其預設的 Inventory 檔案。然而,不建議使用這個檔案。建議為每個專案維護一個不同的 Inventory 檔案,並透過 -i 選項將其傳遞給 ansibleansible-playbook 指令。以下是一個傳遞自定義 Inventory 檔案給 ansible 以執行 ping 模組的範例:

ansible all -i /path/to/inventory -m ping

Inventory 檔案格式

Ansible 的 Inventory 檔案可以是 INI 格式或 JSON 格式。大多數範例使用 INI 格式,而 JSON 格式通常用於動態生成 Inventory 的情況。使用 INI 格式意味著 Inventory 檔案通常非常簡單,可以簡單到只是列出要執行的主機名稱。以下是一個簡單的 Inventory 檔案範例:

host1.example.com
host2.example.com
host3.example.com
192.168.9.29

詳細解析

Inventory 檔案讓 Ansible 知道哪些機器需要被管理,以及如何連線到這些機器。這對於管理大量機器尤其重要,因為它允許你明確指定哪些機器應該被包含在特定的操作中。

使用場景與未來趨勢

在實際應用中,Inventory 檔案可以根據需求進行擴充套件,例如新增變數、群組等,以滿足更複雜的管理需求。隨著基礎設施即程式碼(Infrastructure as Code)理念的推廣,像 Ansible 這樣的工具將變得越來越重要,而 Inventory 檔案的管理也將成為 DevOps 工作流程中的關鍵部分。

本章重點回顧
  • Inventory 是 Ansible 用來識別和管理機器的關鍵檔案。
  • Ansible 支援 INI 和 JSON 格式的 Inventory 檔案。
  • 可以透過 -i 選項指定自定義的 Inventory 檔案路徑。
  • 正確使用 Inventory 檔案對於管理大量機器至關重要。
下一步

接下來,我們將探討如何利用 Ansible 的 Playbook 對指定的主機群組進行組態管理,進一步提高自動化佈署的效率。

Ansible Inventory 檔案詳解

Ansible 的 Inventory 檔案是用來定義要管理的遠端主機清單。本章將探討 Inventory 檔案的格式、功能及應用。

簡單的 Inventory 檔案

最基本的 Inventory 檔案是一個主機名稱的清單。例如:

host1.example.com
host2.example.com
192.168.9.29

Ansible 將按照清單中的順序,依次連線每個主機。

自定義 SSH 連線埠

如果遠端主機的 SSH 服務不是使用預設的 22 連線埠,可以在主機名稱後面加上冒號和連線埠號碼來指定。例如:

host1.example.com:50822

範圍擴充套件

Ansible 支援範圍擴充套件功能,可以簡化大量具有相似名稱的主機清單。例如:

host[1:3].example.com

等同於:

host1.example.com
host2.example.com
host3.example.com

範圍擴充套件也支援前導零(例如 [01:03])和字母範圍(例如 [a:z])。然而,字母範圍只支援單一字母,例如 [a:z],而不支援像 [aa:dz] 這樣的多字母範圍。

自定義 SSH 連線選項

在某些情況下,需要為不同的主機指定不同的 SSH 連線選項,例如使用者名稱、私鑰檔案路徑等。Ansible 允許在 Inventory 檔案中指定這些選項。例如:

192.168.33.10 ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/default/virtualbox/private_key

常見的 Inventory 組態選項

表 2-1 列出了常見的 Inventory 組態選項:

組態選項說明
ansible_host指定主機的實際 IP 地址或網域名稱
ansible_user指定連線主機的使用者名稱
ansible_port指定 SSH 連線埠號碼
ansible_ssh_private_key_file指定私鑰檔案路徑
ansible_ssh_pass指定 SSH 連線密碼(不建議使用)

設定範例

alpha ansible_host=192.168.33.10

表示將主機 alpha 對應到 IP 地址 192.168.33.10

ansible_user=Michael

等同於使用 ssh [email protected] 連線主機。

在沒有 Vagrant 的情況下執行 Ansible

雖然 Vagrant 可以方便地執行 Ansible,但有時需要直接執行 Ansible 而不依賴 Vagrant。這需要手動建立 Inventory 檔案並指定相關引數。

首先,需要在 Vagrantfile 中啟用私有網路,以便可以透過 SSH 連線到虛擬機器。然後,可以建立一個 Inventory 檔案,內容如下:

192.168.33.10 ansible_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/default/virtualbox/private_key

接著,可以使用以下命令執行 Ansible:

ansible-playbook –i inventory provisioning/playbook.yml

內容解密:

此命令會讀取 inventory 檔案中的主機清單和連線選項,然後執行 provisioning/playbook.yml 中的 Playbook。其中:

  • -i inventory 指定了 Inventory 檔案的路徑。
  • provisioning/playbook.yml 是 Playbook 檔案的路徑。

此範例展示瞭如何手動執行 Ansible 而不依賴 Vagrant,並且如何使用 Inventory 檔案指定連線選項。

Ansible Inventory 檔案詳解

Ansible 的 Inventory 檔案是用於定義和管理受控節點的清單,本章將探討 Inventory 檔案的各種組態選項及其應用。

自定義主機變數

在 Inventory 檔案中,可以為每個主機設定特定的變數,以滿足不同的連線需求。以下是一個範例:

alpha.example.com ansible_user=bob ansible_port=50022
bravo.example.com ansible_user=mary ansible_ssh_private_key_file=/path/to/mary.key
frontend.example.com ansible_port=50022
yellow.example.com ansible_host=192.168.33.10

在這個範例中,我們為不同的主機設定了不同的連線使用者、埠號和私鑰檔案。

內容解密:

  • ansible_user:指定連線到主機的使用者名稱。
  • ansible_port:指定連線到主機的 SSH 埠號,預設為 22。
  • ansible_ssh_private_key_file:指定用於 SSH 連線的私鑰檔案路徑。
  • ansible_host:指定主機的實際 IP 位址或網域名稱。

SSH 連線引陣列態

Ansible 提供了多種引數來控制 SSH 連線的行為,如下表所示:

組態選項說明
ansible_ssh_common_args提供給 SSH、SFTP 或 SCP 命令的額外引數。
ansible_ssh_extra_args僅在執行 SSH 命令時使用的額外引數。
ansible_sftp_extra_args僅在執行 SFTP 命令時使用的額外引數。
ansible_scp_extra_args僅在執行 SCP 命令時使用的額外引數。

例如:

ansible_ssh_common_args='-o ForwardAgent=yes'

這個設定等同於執行 ssh -o ForwardAgent=yes host1.example.com

許可權提升選項

在某些情況下,需要使用提升的許可權來執行某些任務,Ansible 提供了相關的組態選項:

組態選項說明
ansible_become_method指定提升許可權的方法,預設為 sudo
ansible_become_user指定提升許可權後的使用者,預設為 root

範例:

alpha.example.com ansible_become_user=automation
bravo.example.com ansible_become_user=automation
frontend.example.com ansible_become_user=ansible
yellow.example.com

在這個範例中,當在 Playbook 中設定 become: true 時,alphabravo 將使用 automation 使用者,而 frontend 將使用 ansible 使用者。

內容解密:

  • ansible_become_method:可用值包括 sudosupbrunpfexecdoas
  • ansible_become_user:可以用來指定特定的使用者來執行任務,而不是預設的 root

自定義變數

除了 Ansible 預定義的變數外,還可以在 Inventory 檔案中定義自定義變數。例如:

host1.example.com vhost=staging.example.com

這樣就可以在 Playbook 中使用 vhost 變數。

實務應用:

這種方法適用於需要在同一台主機上區分不同環境(如 staging 和 production)的情況。例如:

$ cat staging-inventory
alpha.example.com database_name=staging_db

$ cat production-inventory
alpha.example.com database_name=prod

執行 Ansible Playbook 時,可以透過 -i 引數指定不同的 Inventory 檔案:

ansible-playbook -i production-inventory playbook.yml

Inventory 群組

在實際環境中,通常需要將伺服器分成不同的群組(如 web 伺服器、資料函式庫伺服器等)。Ansible 的 Inventory 檔案支援使用 INI 格式的段落標題來定義群組:

[web]
host1.example.com
host2.example.com

[database]
db.example.com

這種分組方式使得對特定型別的伺服器執行任務變得更加容易。

內容解密:

  • 使用方括號 [] 定義群組名稱。
  • 將主機名稱列在群組名稱下方,即可將這些主機加入該群組。