Ansible 自動化部署工具
前言:
Ansible 是和先前介紹的 Chef 一樣, DevOps 中用來快速部署 Server,實現 Infrastructure as Code 管控與設定 Server 的一套工具。
為什麼要介紹 Ansible 呢?
目前在 DevOps 管控設定的工具中,以 Puppe、Chef、Salt、Ansible 四者最有名,而 Puppe 跟 Chef 兩者概念上接近(基於 Ruby ), Salt 則與 Ansible 相近(基於 Python),在 2016 DevOps 的統計中,Ansible 是使用率相對是上升較快的一個工具,並且以簡單的特色為人喜愛。
基本上 Ansible 很多哲學上就是 python,Chef 就很像 ruby。
主要的優點如下:
- 以 YML 格式編寫,容易上手與維護。
- 完全使用 SSH 與遠端 Server 溝通。
- 不需要中間代理。
- 在 Client 端不需要安裝。
缺點如下:
- 執行速度較慢。
- 官方沒有一套簡易的教學(但也許是很簡單?)。
Ansible 使用教學:
1. 安裝 Ansible
- 透過 apt(ubuntu):
sudo apt-get install -y ansible
- 透過 yum:
sudo yum install ansible
- Mac
brew install ansible
2. Ansible 基本檔案與概念介紹:
以下先簡單列出 Ansible 的一些用詞,後面會再用範例詳述。
- ansible.cfg:Ansible 主要的設定檔。
- Inventory:遠端 Server 的資訊。
- Playbooks:我們會需要自動化的東西都會寫在裡面。(類似 Chef 中的 Recipe)
- Task:單個需要自動化執行的程序。(類似 Chef Recipe中的一個 function )
- Handler:用來觸發服務的狀態,例如:重啟,停止服務。
- Role:用來把 Playbooks 跟其他相依檔案一起整合起來當成 module 使用。(類似 Chef 中的 Cookbooks)
3. 如何用 Ansible —— 以部署 Apache 為例(概略)
設定
首先,我們需要先建立一個 Ansible 的專案新目錄:
mkdir ansible-apache
然後到在目錄下
cd ~/ansible-apache/
初始化一個 Ansible 設定檔 ansible.cfg
[defaults]
hostfile = hosts # 設定 hostfile 為目錄下名稱為 hosts 檔案。
用來設定一些 Ansible 專案的一些檔案位置、參數或變數預設值。
Host 資訊
接著,我們創建一個 hosts 檔案來管理我們需要部署的 Server 資訊,這個檔案可以用中括號表示群組名稱,之後可以在 playbook 設定我們只要在哪一個群組執行就好。
[apache] # Group Name
server_ip ansible_ssh_user=username ansible_ssh_private_key_file=key
上面例子需要填入實際的:
- server_ip
- username
- key(如果是用 pem 認證 server 的話。)
再來,你可以用以下指令先測試是否可以與設定的主機連結:
ansible apache -m ping
若可以看到 success
訊息,就表示連線成功,ansible 可以 ssh 部署。
我們就可以開始建立一個 Playbook,安裝 apache
編寫 playbook 安裝 apache
在同樣目錄下,新增一個 apache.yml
---
- hosts: apache # 需要執行的主機
become: true # use sudo
tasks:
- name: install apache2
apt: name=apache2 update_cache=yes state=latest
其中,apt 參數裡的 update_cache yes 表示執行前確保有 apt-get update ,
然後,我們就可以透過以下指令安裝 apache 到 server:
ansible-playbook apache.yml
再來我們可以新增 task 和 handle,用來啟用 apache
---
- hosts: apache
sudo: yes
tasks:
- name: install apache2
apt: name=apache2 update_cache=yes state=latest
- name: enabled mod_rewrite
apache2_module: name=rewrite state=present
notify:
- restart apache2
handlers:
- name: restart apache2
service: name=apache2 state=restarted
一樣下指令
ansible-playbook apache.yml
就會更新遠端的 Server 狀態。
Ansible 內建提供 apt、copy、yum、git 等指令可以簡易描述我們希望 task 要做什麼事,同時也有 shell,可以直接輸入 shell script。
使用變數、模板
在 playbook 中,我們還可以使用 var、template 拆解與彈性化我們的 yml 檔案:
例如,apache 中我們會需要設定virtualhost.conf
這個檔案,我們可以就可以先建立一個 virtualhost.conf
在我們的目錄下
virtualhost.conf
<VirtualHost *:{{ http_port }}>
ServerAdmin webmaster@{{ domain }}
ServerName {{ domain }}
ServerAlias www.{{ domain }}
DocumentRoot /var/www/{{ domain }}
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
然後在 playbook 使用 var、template 將它 include,並用 src, dest 描述要複製到遠端哪一個檔案。
---
- hosts: apache
sudo: yes
vars:
http_port: 80
domain: example.com
tasks:
- name: install apache2
... - name: create virtual host file
template: src=virtualhost.conf dest=/etc/apache2/sites-available/{{ domain }}.conf
只要使用以上的東西,
我們就已經可以用 Ansible 部署一些簡單的環境設定流程了 :)
模組化
而當你需要部署更複雜的設定時,最好的方法是使用 Role 來模組化你的 Ansible 專案,例如需要部署 wordpress 我們需要先有 server、php、mysql、wordpress,我們就可以將你的 Ansible 專案變成以下結構:
[.]
|_ playbook.yml
|_ hosts
|_ [roles]
|_ [server]
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
|_ [php]
|_ ...
|_ [mysql]
|_ ...
|_ [wordpress]
|_ ...
這裡的每個 role 就是一個 app 的部分,裡面的檔案是上面 playbook 的細項(tasks、handler、vars…等),Ansible 會自動 include 對應的檔案,而你只需要在根目錄的 playbook.yml 中 include 需要的 roles 就可以。
- hosts: wordpress
roles:
- server
- php
- mysql
- wordpress
這樣我們就已經可以寫出部署大型應用的專案了!
From Chef to Ansible & Docker 補充:
補充幾個在 Chef 中對應到 Ansible 的東西
- Ansible Galaxy <-> supermarket
- kitchen <-> kitchen-ansible (第三方套件)
另外Ansible 官方似乎並沒有提供類似 kitchen 的東西,但有提供 check (Dry Run)機制,可以告訴你 playbook 執行後對遠端 Server 的變化,而不會真的改變遠端的 Server。
而關於 Docker官方在 playbook 有提供可以使用的指令,讓我們可以結合 Ansible 快速部署 Docker 在 Server 上(可以看參考資源)。