簡介
Ansible是一款爲類Unix系統開發的自由開源的配置和自動化工具。它用Python寫成,類似於saltstack和Puppet,但是有一個不同和優點是我們不需要在節點中安裝任何客戶端。它使用SSH來和節點進行通信。
特點
1.部署簡單,只需在主控端部署Ansible環境,被控端無需做任何操作;
2.默認使用SSH協議對設備進行管理;
3.主從集中化管理;
4.配置簡單、功能強大、擴展性強;
5.支持API及自定義模塊,可通過Python輕鬆擴展;
6.通過Playbooks來定製強大的配置、狀態管理
7.對雲計算平臺、大數據都有很好的支持;
工作機制
Ansible 的組成由 5 個部分組成
Ansible :ansible核心
Modules :包括 Ansible 自帶的核心模塊及自定義模塊
Plugins :完成模塊功能的補充,包括連接插件、郵件插件等
Playbooks :劇本;定義 Ansible 多任務配置文件,由Ansible 自動執行
Inventory :定義 Ansible 管理主機的清單 [ˈɪnvəntri] 清單
安裝
環境
ansible 服務端 test63 192.168.1.63
ansible節點1 test62 192.168.1.62
ansible節點2 test63 192.168.1.63
在test63上安裝ansible
設置EPEL倉庫,Ansible倉庫默認不在yum倉庫中,因此我們需要使用下面的命令啓用epel倉庫。
[root@test63 ~]# yum install epel-release -y
[root@test63 ~]#yum install ansible -y #使用yum安裝Ansible
[root@test63 ~]# ansible –version
ansible命令參數
anisble命令語法: ansible [-i 主機文件] [-f 批次] [組名] [-m 模塊名稱] [-a 模塊參數]
ansible詳細參數:
-v,–verbose # 詳細模式,如果命令執行成功,輸出詳細的結果 (-vv –vvv -vvvv)
-i PATH, -inventory=PATH # 指定 host 文件的路徑,默認是在 /etc/ansible/hosts
inventory [ˈɪnvəntri] 庫存
-f NUM,-forks=NUM # NUM 是指定一個整數,默認是 5 ,指定 fork 開啓同步進程的個數。
-m NAME,-module-name=NAME # 指定使用的 module 名稱,默認使用 command模塊
-a,MODULE_ARGS #指定 module 模塊的參數
-k,-ask-pass #提示輸入 ssh 的密碼,而不是使用基於 ssh 的密鑰認證
-sudo # 指定使用 sudo 獲得 root 權限
-K,-ask-sudo-pass #提示輸入 sudo 密碼,與 -sudo 一起使用
-u USERNAME,-user=USERNAME # 指定移動端的執行用戶
-C,–check #測試此命令執行會改變什麼內容,不會真正的去執行
ansible-doc詳細參數:
ansible-doc -l #列出所有的模塊列表
ansible-doc -s 模塊名 #查看指定模塊的參數 -s, --snippet # [ˈsnɪpɪt] 片斷
定義主機清單
基於端口、密碼訪問主機清單
ansible基於ssh連接-i (inventory)參數後指定的遠程主機時,也可以寫端口,用戶,密碼。
vim /etc/ansible/hosts #文件 /etc/ansible/hosts 維護着Ansible中服務器的清單。在文件最後追加以下內容
[web-servers] #主機組名
192.168.1.63 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123456
ansible -i /etc/ansible/hosts web-servers -m ping #測試下主機的連通性, -i 指定 host 文件的路徑,默認是在 /etc/ansible/hosts, -m 指定使用的ping模塊。
192.168.1.63 | FAILED! => {
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
}
ssh [email protected] #手動連接一下/etc/ansible/hosts主機清單中的主機,這樣就可以在ansible服務器上保存目標主機的fingerprint指紋。後期可以正常連接了
[root@test63 ~]# ansible -i hosts web-servers -m ping #測試成功
192.168.1.64 | SUCCESS => { #表示成測試。通信成功。
"changed": false, #因爲ping命令不會改變被管理的服務器的狀態。所以是false正常
"ping": "pong"
}
基於ssh密鑰訪問主機清單
一般來說,使用明文密碼不安全,所以增加主機無密碼訪問。在Ansible服務端生成密鑰,並且複製公鑰到節點中。
[root@test63 ~]# ssh-keygen #使用ssh-keygen一直回車,不輸入密碼,在/root/.ssh/下會生成私鑰和公鑰
[root@test63 ~]# ssh-copy-id [email protected] #使用ssh-copy-id命令來複制Ansible公鑰到節點:test63和test63
[root@test63 ~]# ssh-copy-id [email protected]
[root@test63 ~]# ssh 192.168.1.64 #測試連接
[root@test64 ~]# exit
[root@test63 ~]# vim /etc/ansible/hosts #在文件的最後添加以下內容,刪除之前在最後添加的兩行主機清單:
[web-servers]
192.168.1.63
192.168.1.64
在Ansible服務端運行命令
ping模塊檢查網絡連通性
command模塊執行shell命令,command:作爲ansible的默認模塊,可以運行遠程權限範圍內的所有shell命令
例1:使用ping檢查‘web-servers’或者ansible節點的連通性。
[root@test63 ~]# ansible -i /etc/ansible/hosts 'web-servers' -m ping
或:
[root@test63 ~]# ansible 'web-servers' -m ping #不指定,默認使用/etc/ansible/hosts文件
192.168.1.63 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.64 | SUCCESS => {
"changed": false,
"ping": "pong"
}
例2:檢查Ansible節點的運行時間(uptime)
[root@test63 ~]# ansible -m command -a "uptime" 'web-servers' #也可以把主機清單組名寫到最後,這樣方便閱讀命令
192.168.1.63 | SUCCESS | rc=0 >>
12:45:23 up 32 min, 5 users, load average: 0.17, 0.11, 0.27
192.168.1.64 | SUCCESS | rc=0 >>
12:45:23 up 26 min, 2 users, load average: 0.03, 0.03, 0.10
例3:檢查節點的內核版本
[root@test63 ~]# ansible -m command -a "uname -r" 'web-servers'
例4:給節點增加用戶
[root@test63 ~]# ansible -m command -a "useradd mk123" 'web-servers'
192.168.1.64 | SUCCESS | rc=0 >>
192.168.1.63 | SUCCESS | rc=0 >>
[root@test63 ~]# ansible -m command -a "grep mk123 /etc/passwd" 'web-servers'
例5:將df命令在所有節點執行後,重定向輸出到本機的/tmp/command-output.txt文件中
[root@test63 ~]# ansible -m command -a "df -Th" 'web-servers' > /tmp/command-output.txt
[root@test63 ~]# cat /tmp/command-output.txt
模塊高級用法
3個遠程命令模塊的區別
1.command模塊爲ansible默認模塊,不指定-m參數時,使用的就是command模塊; comand模塊比較簡單,常見的命令都可以使用,但其命令的執行不是通過shell執行的,所以,像這些 “<”, “>”, “|”, and "&"操作都不可以,當然,也就不支持管道; 缺點:不支持管道,沒法批量執行命令;
2.shell模塊:使用shell模塊,在遠程命令通過/bin/sh來執行;所以,我們在終端輸入的各種命令方式,都可以使用。
例1:運行free -m 命令
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m shell -a "free -m"
注:但是我們自己定義在/.bashrc或/.bash_profile中的環境變量shell模塊由於沒有加載,所以無法識別;如果需要使用自定義的環境變量,就需要在最開始,執行加載自定義腳本的語句;
對shell模塊的使用可以分成兩塊:
- 如果待執行的語句少,可以直接寫在一句話中
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m shell -a "source ~/.bash_profile && df -h | grep sda3"
*如果在遠程待執行的語句比較多,可寫成一個腳本,通過copy模塊傳到遠端,然後再執行;但這樣就又涉及到兩次ansible調用;對於這種需求,ansible已經爲我們考慮到了,script模塊就是幹這事的;
3.scripts模塊
使用scripts模塊可以在本地寫一個腳本,在遠程服務器上執行
[root@test63 ~]# vim /etc/ansible/net.sh
#!/bin/bash
date
hostname
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m script -a "/etc/ansible/net.sh"
copy模塊
實現主控端向目標主機拷貝文件,類似scp功能
例1:把ansible主機上的/etc/hosts文件複製到主機組中機器的/tmp目錄下
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m copy -a "src=/etc/hosts dest=/tmp/ owner=root group=root mode=0755"
在test64上查看
[root@test64 ~]# ll /tmp/hosts
-rwxr-xr-x 1 root root 240 8月 24 16:09 /tmp/hosts
file模塊設置文件屬性。
例如:
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m file -a "path=/tmp/hosts mode=0777"
驗證:
[root@test63 ~]# ll /tmp/hosts
-rwxrwxrwx 1 root root 112 Aug 31 04:38 /tmp/hosts
stat模塊獲取遠程文件信息
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m stat -a "path=/tmp/hosts"
get_url模塊
實現遠程主機下載指定url到本地,支持sha256sum文件校驗。
例如:下載epel-release-latest-7.noarch.rpm到主機清單中的/tmp/目錄下
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m get_url -a "url=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm dest=/tmp/ mode=0440 force=yes"
注:url=https://xxx 的等號=前後不能有空格
擴展:查看force=yes的作用
[root@test63 ~]# ansible-doc -s get_url #在彈出的信息中找到force
如果force=yes,當下載文件時,如果所下的內容和原目錄下的文件內容不一樣,則替換原文件,如果一樣,就不下載了。
如果爲“否”,則僅在目標不存在時才下載文件。 一般來說,只有小型本地文件才應該爲“是”。 在0.6之前,該模塊表現爲默認爲“是”。
查看下載的文件:
[root@test63 ~]# ll /tmp/epel-release-latest-7.noarch.rpm
-r--r----- 1 root root 15080 8月 24 16:20 /tmp/epel-release-latest-7.noarch.rpm
測試:下載文件時,當文件不一樣時,會替換原來的文件
[root@test64 ~]# cp /etc/passwd /tmp/epel-release-latest-7.noarch.rpm
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m get_url -a "url=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm dest=/tmp/ mode=0440 force=yes"
192.168.1.63 | SUCCESS => {
"changed": false, #test63上原來的文件和當前的文件一樣,就沒有改變。執行成功,但沒有發生改變,那麼顯示綠色
}
192.168.1.64 | SUCCESS => {
"changed": true, #test64上的文件名字一樣,但是內容變,就會重新下載。執行成功,且發生改變,那麼顯示黃色
yum模塊linux平臺軟件包管理。
yum模塊可以提供的status狀態: latest ,present,installed #這3個代表安裝;removed, absent #後面2個是卸載
例子:安裝php軟件
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m yum -a "name=httpd state=latest"
cron模塊遠程主機crontab配置。
例如:增加每30分鐘執行ls /tmp
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m cron -a "name='list dir' minute='*/30' job='ls /tmp'"
在test63上查看
[root@test63 ~]# crontab -l
#Ansible: list dir
*/30 * * * * ls /tmp
service模塊遠程主機系統服務管理。
service模塊常用參數:
name參數:此參數用於指定需要操作的服務名稱,比如 nginx,httpd。
state參數:此參數用於指定服務的狀態,比如,我們想要啓動遠程主機中的httpd,則可以將 state 的值設置爲 started;如果想要停止遠程主機中的服務,則可以將 state 的值設置爲 stopped。此參數的可用值有 started、stopped、restarted(重啓)、reloaded。
enabled參數:此參數用於指定是否將服務設置爲開機 啓動項,設置爲 yes 表示將對應服務設置爲開機啓動,設置爲 no 表示不會開機啓動。
注:想使用service模塊啓動服務,被啓動的服務,必須可以使用service 命令啓動或關閉
例如:遠程啓動apache服務
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m service -a "name=httpd state=restarted"
sysctl模塊遠程主機sysctl配置。
例:開啓路由轉發功能
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m sysctl -a "name=net.ipv4.ip_forward value=1 reload=yes"
驗證:
[root@test63 ~]# cat /proc/sys/net/ipv4/ip_forward
1
user模塊遠程主機用戶管理
例如:
[root@test63 ~]# ansible -i /etc/ansible/hosts web-servers -m user -a "name=test6 state=present"
# present [ˈpreznt] 目前
驗證:
[root@test63 ~]# id test6
uid=1001(test6) gid=1001(test6) 組=1001(test6)
實戰-使用Playbook批量部署多臺LAMP環境
首先,我們可以在ansible服務器上安裝LAMP環境,然後,再將配置文件通過ansible拷貝到遠程主機上
[root@test63 ~]# yum install httpd –y#安裝httpd軟件
root@test63 ~]# yum install mariadb-server mariadb -y #安裝MySQL
[root@test63 ~]# mkdir -p /mydata/data #創建目錄作爲數據存放的位置
[root@test63 ~]# chown -R mysql:mysql /mydata/
[root@test63 ~]# vim /etc/my.cnf #改變數據存放目錄
改:2 datadir=/var/lib/mysql
爲:2 datadir=/mydata/data
[root@test63 ~]# systemctl start mariadb
[root@test63 ~]# yum install php php-mysql –y #安裝PHP和php-mysql模塊
[root@test63 ~]# vim /var/www/html/index.php #提供php的測試頁
<?php
phpinfo();
?>
[root@test63 ~]# systemctl restart httpd啓動httpd服務,在瀏覽器中訪問
[root@test63 ~]# iptables -F
確保已經出現上面的測試頁,而且,要看到MySQL已經被整合進來了,才能進行下一步操作
定義組名
[root@test63 ~]# vim /etc/ansible/hosts #還使用之前定義好的,這裏不用修改
[web-servers]
192.168.1.63
192.168.1.64
然後,將公鑰信息複製到被控制節點,ansible和兩個節點間通過ssh進行連接。下面3個命令之前已經做過,不用執行了。
[root@test63 ~]# ssh-keygen
[root@test63 ~]# ssh-copy-id [email protected]
[root@test63 ~]# ssh-copy-id [email protected]
使用playbook創建一個LAMP構建的任務
1.創建相關文件
[root@test63 ~]# mkdir -pv /etc/ansible/lamp/roles/{prepare,httpd,mysql,php}/{tasks,files,templates,vars,meta,default,handlers}
我們將上面搭建成功的LAMP環境的httpd和MySQL的配置文件拷貝到對應目錄下
Playbook常用文件夾作用:
files:存放需要同步到異地服務器的源碼文件及配置文件;
handlers:當服務的配置文件發生變化時需要進行的操作,比如:重啓服務,重新加載配置文件; ['hændləz] 處理程序
meta:角色定義,可留空; ['metə] 元
tasks:需要進行的執行的任務; #任務
templates:用於執行lamp安裝的模板文件,一般爲腳本; ['templɪts] 模板
vars:本次安裝定義的變量
[root@test63 ~]# cd /etc/ansible/
[root@test63 ~]# cp /etc/httpd/conf/httpd.conf lamp/roles/httpd/files/
[root@test63 ~]# cp /etc/my.cnf lamp/roles/mysql/files/
寫prepare(前期準備)角色的playbooks
[root@test63 ansible]# vim lamp/roles/prepare/tasks/main.yml #複製以下內容到文件中,配置好yum源
- name: delete yum config
shell: rm -rf /etc/yum.repos.d/* #刪除原有的yum配置文件
- name: provide yumrepo file
shell: wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo #下載新的yum配置文件
- name: clean the yum repo
shell: yum clean all #清除原有的yum緩存信息
- name: clean the iptables
shell: iptables -F #清除原有防火牆規則,不然後可能上不了網
2.構建httpd的任務
[root@test63 roles]# cd /etc/ansible/lamp/roles
[root@test63 roles]# mv /var/www/html/index.php httpd/files/
[root@test63 roles]# vim httpd/tasks/main.yml #將以下內容複製到文件中
- name: web server install
yum: name=httpd state=present #安裝httpd服務
- name: provide test page
copy: src=index.php dest=/var/www/html #提供測試頁
- name: delete apache config
shell: rm -rf /etc/httpd/conf/httpd.conf #刪除原有的apache配置文件,如果不刪除,下面的copy任務是不會執行的,因爲當源文件httpd.conf和目標文件一樣時,copy命令是不執行的。如果copy命令不執行,那麼notify將不調用handler。
- name: provide configuration file
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf #提供httpd的配置文件
notify: restart httpd #當前面的copy複製成功後,通過notify通知名字爲restart httpd的handlers運行。
擴展:notify和handlers notify [ˈnəʊtɪfaɪ] 通知
notify: 這個action可用於在每個play的最後被觸發,這樣可以避免多次有改變發生時,每次都執行指定的操作,取而代之,僅在所有的變化發生完成後一次性地執行指定操作。
在notify中列出的操作稱爲handler,也即notify中調用handler中定義的操作。
---- name: test.yml just for test
hosts: testserver
vars:
region: ap-southeast-1
tasks:
- name: template configuration
file template: src=template.j2 dest=/etc/foo.conf
notify:
- restart memcached
- restart apache
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=apache state=restarted
handlers概述:
Handlers 也是一些 task 的列表,通過名字來引用,它們和一般的 task 並沒有什麼區別。
Handlers 是由通知者進行notify, 如果沒有被 notify,handlers 不會執行。
不管有多少個通知者進行了notify,等到 play 中的所有 task 執行完成之後,handlers 也只會被執行一次。
Handlers 最佳的應用場景是用來重啓服務,或者觸發系統重啓操作.除此以外很少用到了。
3.構建httpd的handlers
[root@test63 roles]# vim httpd/handlers/main.yml
- name: restart httpd
service: name=httpd enabled=yes state=restarted
4.部署我們的mariadb數據庫
創建MySQL服務的任務,需要安裝MySQL服務,改變屬主信息,啓動MySQL
[root@test63 roles]# cd /etc/ansible/lamp/roles
[root@test63 roles]# vim mysql/tasks/main.yml
- name: install the mysql
yum: name=mariadb-server state=present #安裝mysql服務
- name: mkdir date directory
shell: mkdir -p /mydata/data #創建掛載點目錄
- name: provide configration file
copy: src=my.cnf dest=/etc/my.cnf #提供mysql的配置文件
- name: chage the owner
shell: chown -R mysql:mysql /mydata/* #更改屬主和屬組
- name: start mariadb
service: name=mariadb enabled=yes state=started #啓動mysql服務
5.構建PHP的任務
[root@test63 roles]# vim php/tasks/main.yml
- name: install php
yum: name=php state=present #安裝php
- name: install php-mysql
yum: name=php-mysql state=present #安裝php與mysql交互的插件
6.定義整個的任務
[root@test63 roles]# cd /etc/ansible/lamp/roles
[root@test63 roles]# vim site.yml #寫入以下內容
- name: LAMP build
remote_user: root
hosts: web-servers
roles:
- prepare
- mysql
- php
- httpd
注:所有yml的配置文件中,空格必須嚴格對齊
開始部署:
[root@test63 roles]# ansible-playbook -i /etc/ansible/hosts /etc/ansible/lamp/roles/site.yml
``
然後,在瀏覽器中訪問這兩臺節點主機,可以直接訪問成功。
http://192.168.1.63/index.php
http://192.168.1.64/index.php
注:
1、默認情況下,首次登陸一臺服務器,系統會提示是否要記住對端的指紋,用ansible也會這樣,這樣會導致需要手工輸入yes或no,ansible 纔可以往下執行。如需避免這種情況,需要在 /etc/ansible/ansible.cfg 文件中設置 host_key_checking = False
例1:
[root@test63 roles]# rm -rf /root/.ssh/known_hosts
[root@test63 roles]# ansible-playbook -i /etc/ansible/hosts ./site.yml #發現需要輸入yes,來保存對端的指紋
解決:
[root@test63 roles]# vim /etc/ansible/ansible.cfg
改:62 #host_key_checking = False #就是把前面的#號去了
爲:host_key_checking = False
[root@test63 roles]# rm -rf /root/.ssh/known_hosts
[root@test63 roles]# ansible-playbook -i /etc/ansible/hosts ./site.yml #發現不需要輸入yes,可以自動安裝了