Ansible 菜鳥入門 & module詳解
ansible
安裝
yum install -y ansible
配置
兩種方法:
- 祕鑰
- 直接在 /etc/ansible/hosts 填入對應伺服器賬號密碼
[myself]
192.168.94.134 ansible_ssh_user="root" ansible_ssh_pass="zzh" ansible_su_pass="zzh"
[myhost]
192.168.94.135 ansible_ssh_user="root" ansible_ssh_pass="zzh" ansible_su_pass="zzh"
測試
[[email protected] ansible]# ansible all -m command -a "who" 192.168.94.135 | SUCCESS | rc=0 >> root pts/0 2018-09-17 13:39 (192.168.94.134) 192.168.94.134 | SUCCESS | rc=0 >> root tty1 2018-09-17 10:34 root pts/0 2018-09-17 13:34 (192.168.94.1) root pts/1 2018-09-17 10:53 (192.168.94.1) root pts/6 2018-09-17 13:39 (192.168.94.134)
命令說明
命令格式:
ansible <pattern_goes_here> -m <module_name> -a <arguments> #例如: ansible all -m copy -a 'src=/etc/my.cnf dest=/etc/' #幾個重要引數的含義: -i #指定inventory檔案(主機定義檔案) ??? all #表示在host檔案中定義的所有的主機,可以替換成響應的組名或IP地址 #針對於主機可以使用匹配規則(所有的匹配都基於配置檔案中的主機) IP地址: ansible 192.168.239.132 IP匹配: ansible 192.168.239.* IP匹配: ansible * 組匹配: ansible 組名:&hostname <表示這個組跟其他組的一個主機> 組匹配: ansible 組名:!hostname <表示這個組但是出除去這個組的這個主機> #類似的匹配還很多,幾乎能想到的匹配都能支援,具體參照http://docs.ansible.com/intro_patterns.html -m #指定使用哪個模組,預設採用command模組 -a #指定模組的引數,每個模組都有相應的模組引數 -u #指定遠端機器的使用者
command模組與shell模組的區別
shell功能全面但執行效率低
command不支援:邏輯運算子、條件判斷符號、重定向命令或管道
ansible srvs -m command -a 'echo "$HOSTNAME"'
ansible srvs -m shell -a 'echo "$HOSTNAME"'
使用command模組會報錯
ansible srvs -m command -a 'cat /etc/issue > /tmp/issue.tmp'
使用shell模組則不會
ansible srvs -m shell -a 'cat /etc/issue > /tmp/issue.tmp' ansible srvs -m command -a 'cat /tmp/issue.tmp'
檔案傳輸模組:copy、fetch、template
copy模組:複製本機檔案,傳輸至遠端主機,並修改屬主、屬組和許可權
注意:可以在引數中增加 backup=yes ,可以實現備份的功能
實現copy功能
ansible srvs -m copy -a 'src=/etc/yum.repos.d/CentOS-Base.repo dest=/etc/yum.repos.d/CentOS-Base.repo owner=root group=root mode=0644'
ansible srvs -m command -a 'yum clean all'
ansible srvs -m command -a 'yum repolist'
實現備份功能
ansible srvs -m copy -a 'src=/root/test.txt dest=/root/ backup=yes'
fetch模組:複製遠端檔案,傳輸至本機(僅支援傳輸檔案,如果傳輸目錄可以先歸檔或壓縮為一個檔案後傳輸)
在n2(從機)的/root目錄下建立檔案f1,在n3(另一個從機)的/root目錄下建立檔案f2,假設n2主機的/root目錄下沒有f2這個檔案,假設n3主機的/root目錄下沒有f1這個檔案,如果我們想從n2中傳輸f1這個檔案至n1的/root目錄下
注意:使用fetch模組傳輸至本地主機的檔案,全部會儲存在目錄,檔案實際儲存路徑為: /”dest引數指定的目錄”/”原始檔所在主機的IP地址”/”執行命令的使用者名稱”/”傳輸的檔案” #在n1主機執行命令 ansible srvs -m fetch -a 'src=/root/f1 dest=/root/ backup=yes' #f1檔案的路徑 ls 172.16.254.89/root/f1
cron模組
增加計劃任務
設定每天的3:15,執行磁碟空間檢視命令,並將命令結果儲存至指定位置
ansible srvs -m cron -a 'name="disk check loger" minute=15 hour=3 job="df -hT >> /tpm/df.log"'
#驗證結果
ansible srvs -m command -a 'crontab -l'
ansible srvs -m command -a 'cat /tmp/df.log'
移除指定計劃任務
ansible srvs -m cron -a 'name="disk check loger" state=absent'
#驗證
ansible srvs -m command -a 'crontab -l'
yum模組
安裝epel源
ansible srvs -m yum -a 'name=epel-release state=latest'
安裝應用
ansible srvs -m yum -a 'name=nginx state=latest'
ansible srvs -m yum -a 'name=ntpdate state=latest'
ansible srvs -m command -a 'ntpdate 172.16.0.1'
管理各種服務:service模組
ansible srvs -m service -a 'name=nginx state=started'
service模組中的state支援的選擇有:started, stopped, restarted, reloaded
ansible srvs -m service -a 'name=nginx state=restarted'
setup 模組
自動從遠端主機上獲取可用與playbook中的變數
獲取所有可用變數
ansible srvs -m setup
對變數進行過濾,僅獲取符合匹配要求的變數
查詢與系統版本相關的變數
“ansible_distribution”: “CentOS”
“ansible_distribution_major_version”: “7”
#方法1
ansible srvs -m setup -a 'filter=*distribut*'
#方法2
ansible srvs -m setup | grep -i distribut
debug 模組
可以通過debug模組呼叫變數顯示想要的資訊
tasks:
- name: show hosts information
tags: info
debug: msg="{{ ansible_distribution }}-{{ ansible_distribution_major_vers
ion }}-{{ ansible_distribution_release }}"
驗證結果
ansible-playbook /root/ansible/httpd-manager-j2.yml --tags=info
#結果為
ok: [172.16.254.89] => {
"msg": "CentOS-7-Core"
}
script 模組
準備測試指令碼
vim /root/test.sh
#!/bin/bash
#
touch /tmp/test.log
echo `date` >> /tmp/test.log
ls -l /tmp/test.log
cat /tmp/test.log
在所有主機執行指令碼
ansible srvs -m script -a '/root/test.sh'
ansible-vault 命令
加密 .yml 檔案
#準備一個.yml檔案
ansible-vault encrypt test.yml
#輸入密碼並確認
此時無法使用普通方法檢視test.yml檔案
檢視加密的.yml檔案
ansible-vault view test.yml
#輸入密碼
解密.yml檔案
ansible-vault decrypt test.yml
#輸入密碼
此時可以使用普通方法檢視.yml檔案內容
ansible-galaxy 命令
檔案下載至/etc/ansible/roles目錄下
注意:下載其他人共享的roles,在執行前應稽核一遍檔案內容,防止危險操作
安裝並使用其他人共享的roles檔案
ansible-galaxy install devops.nginx
ls /etc/ansible/roles/devops.nginx
想刪除下載的roles檔案,將install替換為delete即可
ansible-console 命令
ansible的互動式命令工具ansible-console
進入
ansible-console 的命令提示符
[email protected] (4)[f:5]$ cd srvs
[email protected] (4)[f:5]$ forks 4
[email protected] (4)[f:4]$ list
172.16.253.184
172.16.254.89
172.16.253.47
172.16.253.30
其中:
root :當前執行使用者
@ :分隔符
all :分組的組名
(4) :當前分組內的主機數量
[f:4] :併發執行緒數
ansible-console 的使用 ansible-console工具可自動補全選項,使用格式為:
模組名 選項1=value 選項2=value
???
service name=nginx state=started
yum name=tree state=latest
command tree -L 1 /
ansible-playbook命令及YAML語法
YAML語法
YAML :YAML ain’t a Markup Language ,以資料為中心、而不是以標記語言為重點的一種語言
- 首行以 “—” 開始,且需頂格書寫
- 次行開始寫playbook的正文,建議寫明playbook的功能等描述資訊
- 註釋符為"#"
- 格式非常嚴格,嚴格控制縮排統一,不能和空格或Tab混用
- 縮排級別必須一致,縮排級別相同代表同級別,級別的判斷是通過縮排結合換行實現的
- YAML檔案內容和Linux系統大小寫的判斷方式保持一致,是區分大小寫的,k/v的值均對大小寫敏感
- k/v的值可同行寫,也可換行寫,同行書寫使用分隔符":",換行寫分隔符 " - "
- 一個完整的程式碼塊所必需包含的元素:name、task 一個name只能包括一個task
test.yml 示例
vim /root/test.yml
#檔案內容
---
- hosts: myself
remote_user: root
tasks:
- name: adduser test
user: name=test shell=/bin/bash home=/home/test
playbook 核心元素
hosts :指定執行任務的目標主機
tasks :任務列表
variables :變數
templates :模板
handlers :動作執行探測器,探測到指定條件,觸發執行動作
roles :按照固定目錄結構組成的playbook
playbook中tags、notify、handlers的使用
playbook例項 :httpd-manager.yml
---
- hosts: srvs
remote_user: root
tasks:
- name: install httpd
tags: install
yum: name=httpd state=latest
- name: start httpd.service
tags: start
service: name=httpd state=started
- name: start httpd.service
tags: restart
service: name=httpd state=restarted
- name: stop httpd.service
tags: stop
service: name=httpd state=stopped
- name: config httpd
tags: config
copy: src=/root/ansible/httpd.conf dest=/etc/httpd/conf/ backup=yes
when: ansible_distribution_major_version == "7"
notify: restart httpd
handlers:
- name: restart httpd
service: name=httpd state=restarted
實現功能:
單獨呼叫其中一個功能
ansible-playbook httpd-server-deploy.yml --tags=start
同時呼叫多個功能
ansible-playbook httpd-server-deploy.yml --tags="stop,config"
針對某一單個成員執行某一功能
ansible-playbook httpd-server-deploy.yml --tags="start,stop" -l 172.16.253.30
playbook中變數的使用
定義變數
在/etc/ansible/hosts檔案中定義變數,可針對某臺主機定義變數,也可以對整個分組定義變數 組變數和主機變數的生效優先順序為:如果針對主機定義了變數(無論是否定義了組變數),主機變數生效;如果未定義主機變數,僅定義了組變數,組變數生效。
vim /etc/ansible/hosts
#組變數
[srvs:vars]
webport=80
#主機變數
[srvs]
172.16.253.184 webport=10080 hostname=node1
172.16.254.89 webport=10180 hostname=node2
172.16.253.47 webport=10280 hostname=node3
172.16.253.30 webport=10380 hostname=node4
呼叫變數
呼叫變數的兩種方式的生效優先順序:在命令列下直接定義的變數優先順序高於在hosts檔案中定義的變數(主機變數或分組變數)
- 可以在命令列模式直接使用”ansible-playbook test.yml -e “webport=2000”
- 呼叫在hosts檔案中定義好的變數
引用變數注意:使用雙大括號 “{{ VAR-NAME }}” ,且括號前後要有空格
eg. 修改主機名
ansible srvs -m hostname -a 'name=“name-{{ hostname }}-port-{{ webport }}"'
ansible srvs -m command -a 'hostname'
#執行結果
172.16.253.30 | SUCCESS | rc=0 >>
name-node4-port-10380
172.16.253.184 | SUCCESS | rc=0 >>
name-node1-port-10080
172.16.253.47 | SUCCESS | rc=0 >>
name-node3-port-10280
172.16.254.89 | SUCCESS | rc=0 >>
name-node2-port-10180
ansible-playbook 之強大的 template
jianja2語法格式:
支援算術運算:+ , - , * , / , **
支援比較操作符:== , >= , != , <= , > , <
支援邏輯運算子: and , or , not
支援流表示式:for , if , while
使用template在配置檔案中呼叫變數
設定template配置檔案
#設定jianja2檔案
cp /root/ansible/httpd.conf /root/ansible/httpd.conf.j2
vim /root/ansible/httpd.conf.j2
#修改Listen一項的值為 "{{ webport }}"
Liten {{ webport }}
#重新設定yml檔案
cp /root/ansible/httpd-manager.yml /root/ansible/httpd-manager-j2.yml
vim /root/ansible/httpd-manager-j2.yml
#修改config配置塊中的copy指令為template指令,其他部分不變,示例如下:
- name: config httpd
tags: config
template: src=/root/ansible/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution_major_version == "7"
notify: restart httpd
執行playbook
ansible-playbook /root/ansible/httpd-manager-j2.yml --tags=config
#執行結果:對分組中不同的主機採用不同的埠
ansible srvs -m shell -a 'ss -tnlp | grep httpd'
template還支援算術運算
將所有埠加1
vim /root/ansible/httpd.conf.j2
#修改以下內容
Listen {{ webport+1 }}
通過template在配置檔案中使用for迴圈和if語句
定義基於不同域名的多個虛擬主機
#查詢主機名變數
ansible srvs -m setup | grep hostname
#修改httpd.conf.j2檔案
Listen {{ webport }}
<VirtualHost *.{{ webport }}>
ServerName {{ ansible_hostname }}.achudk.com
DocumentRoot /var/www/html
<Directory "/var/www">
Require all granted
</Directory>
</VirtualHost>
#驗證結果
ansible-playbook /root/ansible/httpd-manager-j2.yml --tags=config
curl curl 172.16.254.89:10180
使用for迴圈生成多個基於不同域名且不同埠的虛擬主機,並使用if判斷條件
#修改httpd.conf.j2檔案
vim httpd.conf.j2
{% for vport in vports %}
<VirtualHost *.{{ vport }}>
ServerName {{ ansible_hostname }}.achudk.com
DocumentRoot /var/www/html
<Directory "/var/www">
Require all granted
</Directory>
{% if errorlog is not defined %}
ErrorLog "{{ errorlog | default('/web/httpd/log/vh1/error_log') }}"
{% endif %}
</VirtualHost>
{% endfor %}
#修改httpd-manager-j2.yml檔案,在起始處增加vars指令,餘下內容不變,如下:
vim httpd-manager-j2.yml
#正文如下
---
- hosts: srvs
remote_user: root
vars:
- vport:
- 80
- 443
- 8080
- errorlog:
- "/web/httpd/log/vh1/error_log"
#驗證結果
ansible-playbook /root/ansible/httpd-manager-j2.yml --tags=config
when條件判斷
#當系統為CentOS7時,才啟用該配置片段
- name: config httpd
tags: config
template: src=/root/ansible/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution == "CentOS"
when: ansible_distribution_major_version == "7"
notify: restart httpd
when指令的多條件聯合判斷 多個條件之間使用 “and” 連線
tasks:
- name: show hosts information tags: info debug: msg={{ ansible_distribution }},msg={{ ansible_distribution_major_v ersion }} when: ansible_distribution == "CentOS" and ansible_distribution_major_ver sion == "6"
最終例項
將所學內容綜合起來使用,形成具有管理功能的yml檔案
---
- hosts: myself
remote_user: root
vars:
- vports:
- 80
- 443
- 8080
- errorlog:
- "/web/httpd/log/vh1/error_log"
tasks:
- name: show hosts information
tags: info
debug: msg="{{ ansible_distribution }}-{{ ansible_distribution_major_version }}-{{ ansible_distribution_release }}"
- name: install httpd
tags: install
yum: name=httpd state=latest
- name: start httpd.service
tags: start
service: name=httpd state=started
- name: start httpd.service
tags: restart
service: name=httpd state=restarted
- name: stop httpd.service
tags: stop
service: name=httpd state=stopped
- name: config httpd
tags: config
template: src=/root/ansible/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution == "CentOS" and ansible_distribution_major_ver
sion == "7"
notify: restart httpd
handlers:
- name: restart httpd
service: name=httpd state=restarted