ansible安裝及教程3
playbook
模塊
# 在test組中的主機(jī)上,安裝httpd、php、php-mysqlnd
[root@control ansible]# vim pkg.yml
---
- name: install pkgs
? hosts: test
? tasks:
??? - name: install web pkgs? # 此任務(wù)通過(guò)yum安裝三個(gè)包
????? yum:
??????? name: httpd,php,php-mysqlnd
??????? state: present
# 安裝多個(gè)軟件包,還可以寫(xiě)為:
---
- name: install pkgs
? hosts: test
? tasks:
??? - name: install web pkgs
????? yum:
??????? name: [httpd,php,php-mysqlnd]
??????? state: present
# 安裝多個(gè)軟件包,還可以寫(xiě)為:
---
- name: install pkgs
? hosts: test
? tasks:
??? - name: install web pkgs
????? yum:
??????? name:
????????? - httpd
????????? - php
????????? - php-mysqlnd
??????? state: present
# 根據(jù)功能等,可以將一系列軟件放到一個(gè)組中,安裝軟件包組,將會(huì)把很多軟件一起安裝上。比如gcc、java等都是開(kāi)發(fā)工具,安裝開(kāi)發(fā)工具包組,將會(huì)把它們一起安裝。
[root@node1 ~]# yum grouplist?? # 列出所有的軟件包組
[root@node1 ~]# yum groupinstall "Development Tools"
# 如果列出的組名為中文,可以這樣進(jìn)行:
[root@node1 ~]# yum grouplist
# 繼續(xù)編輯pkg.yml,在test組中的主機(jī)上安裝Development tools組
[root@control ansible]# vim pkg.yml
---
- name: install pkgs
? hosts: test
? tasks:
??? - name: install web pkgs??? # 此任務(wù)通過(guò)yum安裝三個(gè)包
????? yum:
??????? name:
????????? - httpd
????????? - php
????????? - php-mysqlnd
??????? state: present
??? - name: install dev group??? # 此任務(wù)通過(guò)yum安裝一組包
????? yum:
??????? name: "@Development Tools"?? # @表示后面的名字是組名
??????? state: present
[root@control ansible]# ansible-playbook pkg.yml
# 系統(tǒng)升級(jí)命令
[root@control ansible]# yum update
# 繼續(xù)編輯pkg.yml,在test組中的主機(jī)上升級(jí)所有的包到最新版本
---
- name: install pkgs
? hosts: test
? tasks:
??? - name: install web pkgs
????? yum:
??????? name:
????????? - httpd
????????? - php
????????? - php-mysqlnd
??????? state: present
??? - name: install dev group
????? yum:
??????? name: "@Development Tools"
??????? state: present
??? - name: update system??? # 相當(dāng)于yum update命令
????? yum:
? ??????name: "*"?????? # 表示系統(tǒng)已經(jīng)安裝的所有包
??????? state: latest
[root@control ansible]# ansible-playbook pkg.yml
ansible變量
facts變量
????????????? facts翻譯過(guò)來(lái)就是事實(shí)。
????????????? facts變量是ansible自帶的預(yù)定義變量,用于描述被控端軟硬件信息。
????????????? facts變量通過(guò)setup模塊獲得。
# 通過(guò)setup模塊查看所有facts變量
[root@control ansible]# ansible test -m setup
????????????? facts變量是一個(gè)大的由{}構(gòu)成的鍵值對(duì)字典。在{}中,有很多層級(jí)的嵌套??梢酝ㄟ^(guò)參數(shù)過(guò)濾出第一個(gè)層級(jí)的內(nèi)容。
# 查看所有的IPV4地址,filter是過(guò)濾的意思
[root@control ansible]# ansible test -m setup -a "filter=ansible_all_ipv4_addresses"
# 查看可用內(nèi)存
[root@control ansible]# ansible test -m setup -a "filter=ansible_memfree_mb"
????????????? 常用的facts變量
–??????????? ansible_all_ipv4_addresses:所有的IPV4地址
–??????????? ansible_bios_version:BIOS版本信息
–??????????? ansible_memtotal_mb:總內(nèi)存大小
–??????????? ansible_hostname:主機(jī)名
????????????? 在playbook中使用變量
# 顯示遠(yuǎn)程主機(jī)的主機(jī)名和內(nèi)存大小。在ansible中,變量使用{{}}表示
# debug模塊用于輸出信息,常用的參數(shù)是msg,用于輸出指定內(nèi)容
[root@control ansible]# vim debug.yml
---
- name: display host info
? hosts: test
? tasks:
??? - name: display hostname and memory
????? debug:??? # debug是模塊,它的選項(xiàng)msg可以輸出指定信息
??????? msg: "hostname: {{ansible_hostname}}; mem: {{ansible_memtotal_mb}} MB"
[root@control ansible]# ansible-playbook debug.yml
自定義變量
????????????? 引入變量,可以方便Playbook重用。比如裝包的playbook,包名使用變量。多次執(zhí)行playbook,只要改變變量名即可,不用編寫(xiě)新的playbook。
????????????? ansible支持10種以上的變量定義方式。常用的變量來(lái)源如下:
–??????????? inventory變量。變量來(lái)自于主機(jī)清單文件
–??????????? facts變量。
–??????????? playbook變量。變量在playbook中定義。
–??????????? 變量文件。專門(mén)創(chuàng)建用于保存變量的文件。推薦變量寫(xiě)入單獨(dú)的文件。
# 使用inventory變量。
[root@control ansible]# vim hosts
[test]
node1 iname="nb"???? # 主機(jī)變量定義的方法。iname是自定義名稱
[proxy]
node2
[webserver]
node[3:4]
[database]
node5
[cluster:children]
webserver
database
[webserver:vars]?????? # 組變量定義方法。:vars是固定格式
iname="dachui"
# 通過(guò)變量創(chuàng)建用戶
[root@control ansible]# vim var1.yml
---
- name: test create user
? hosts: test
? tasks:
??? - name: create user
????? user:
??????? name: "{{iname}}"
??????? state: present
???????
- name: create user in webserver
? hosts: webserver
? tasks:
??? - name: create some users
????? user:
??????? name: "{{iname}}"
??????? state: present
[root@control ansible]# ansible-playbook var1.yml
# 上述兩個(gè)play也可以合并為一個(gè),如下:
[root@control ansible]# vim var1.yml
---
- name: test create user
? hosts: test,webserver??? # 指定執(zhí)行的目標(biāo)是test組和webserver組
? tasks:
??? - name: create user
????? user:
??????? name: "{{iname}}"
??????? state: present
???????
# 在playbook中定義變量
# 在test組中的主機(jī)上創(chuàng)建用戶jack,他的密碼是123456
[root@control ansible]# vim user_jack.yml
---
- name: create user
? hosts: test
? vars:??? # 固定格式,用于聲明變量
??? username: "jack"??? # 此處引號(hào)可有可無(wú)
??? mima: "123456"????? # 此處引號(hào)是需要的,表示數(shù)字字符
? tasks:
??? - name: create some users
????? user:
??????? name: "{{username}}"?? # {}出現(xiàn)在開(kāi)頭,必須有引號(hào)
??????? state: present
??????? password: "{{mima|password_hash('sha512')}}"
[root@control ansible]# ansible-playbook user_jack.yml
# 將變量定義在文件中
[root@control ansible]# vim vars.yml?? # 文件名自定義
---
yonghu: rose
mima: abcd
[root@control ansible]# vim user_rose.yml
---
- name: create user
? hosts: test
? vars_files: vars.yml?? # vars_files用于聲明變量文件
? tasks:
??? - name: create some users
????? user:
??????? name: "{{yonghu}}"?? # 這里的變量來(lái)自于vars.yml
??????? state: present
??????? password: "{{mima|password_hash('sha512')}}"
[root@control ansible]# ansible-playbook user_rose.yml
補(bǔ)充模塊
firewalld模塊
????????????? 用于配置防火墻的模塊
????????????? 常用選項(xiàng):
–??????????? port:聲明端口
–??????????? permanent:永久生效,但不會(huì)立即生效
–??????????? immediate:立即生效,臨時(shí)生效
–??????????? state:enabled,放行;disabled拒絕
????????????? 防火墻一般默認(rèn)拒絕,明確寫(xiě)入允許的服務(wù)。
????????????? 有一些服務(wù)有名字,有些服務(wù)沒(méi)有名字。但是最終都是基于TCP或UDP的某些端口。比如http服務(wù)基于TCP80端口。服務(wù)名和端口號(hào)對(duì)應(yīng)關(guān)系的說(shuō)明文件是:/etc/services
????????????? 配置服務(wù)器的防火墻,一般來(lái)說(shuō)只要配置開(kāi)放哪些服務(wù)或端口即可。沒(méi)有明確開(kāi)放的,都默認(rèn)拒絕。
????????????? 應(yīng)用
–??????????? 在test組中的主機(jī)上安裝并啟動(dòng)httpd
–??????????? 客戶端訪問(wèn)服務(wù)器的http服務(wù)
–??????????? 在test組中的主機(jī)上安裝并啟動(dòng)firewalld
–??????????? 客戶端訪問(wèn)服務(wù)器的http服務(wù)
–??????????? 在test組中的主機(jī)上開(kāi)放http服務(wù)
# 配置httpd服務(wù)
[root@control ansible]# vim firewall.yml
---
- name: configure test
? hosts: test
? tasks:
??? - name: install httpd pkg?? # 這里通過(guò)yum模塊裝httpd
????? yum:
??????? name: httpd
??????? state: present
??? - name: start httpd service?? # 這里通過(guò)service模塊啟httpd服務(wù)
????? service:
??????? name: httpd
??????? state: started
??????? enabled: yes
???????
[root@control ansible]# ansible-playbook firewall.yml
[root@control ansible]# curl http://192.168.4.11/? # 可訪問(wèn)
# 安裝并啟動(dòng)firewalld
[root@control ansible]# vim firewall.yml
---
- name: configure test
? hosts: test
? tasks:
??? - name: install httpd pkg?? # 這里通過(guò)yum模塊裝httpd
????? yum:
??????? name: httpd
??????? state: present
??? - name: start httpd service?? # 這里通過(guò)service模塊啟httpd服務(wù)
????? service:
??????? name: httpd
??????? state: started
??????? enabled: yes
?
??? - name: install firewalld pkg?? # 這里通過(guò)yum模塊裝firewalld
????? yum:
??????? name: firewalld
??????? state: present
??? - name: start firewalld service?? # 這里通過(guò)service模塊啟firewalld服務(wù)
????? service:
??????? name: firewalld
??????? state: started
??????? enabled: yes
?
[root@control ansible]# ansible-playbook firewall.yml
[root@control ansible]# curl http://192.168.4.11/? # 被拒絕
curl: (7) Failed to connect to 192.168.4.11 port 80: 沒(méi)有到主機(jī)的路由
# 配置防火墻規(guī)則,放行http協(xié)議
[root@control ansible]# vim firewall.yml
---
- name: configure test
? hosts: test
? tasks:
??? - name: install httpd pkg?? # 這里通過(guò)yum模塊裝httpd
????? yum:
??????? name: httpd
??????? state: present
??? - name: start httpd service?? # 這里通過(guò)service模塊啟httpd服務(wù)
????? service:
??????? name: httpd
??????? state: started
??????? enabled: yes
?
??? - name: install firewalld pkg?? # 這里通過(guò)yum模塊安裝firewalld
????? yum:
??????? name: firewalld
??????? state: present
??? - name: start firewalld service?? # 這里通過(guò)service模塊啟service服務(wù)
????? service:
??????? name: firewalld
??????? state: started
??????? enabled: yes
?
??? - name: set firewalld rules?? # 通過(guò)firewalld模塊開(kāi)放80端口
????? firewalld:
??????? port: 80/tcp
??????? permanent: yes
??????? immediate: yes
??????? state: enabled
[root@control ansible]# ansible-playbook firewall.yml
[root@control ansible]# curl http://192.168.4.11/? # 可訪問(wèn)
template模塊
????????????? copy模塊可以上傳文件,但是文件內(nèi)容固定
????????????? template模塊可以上傳具有特定格式的文件(如文件中包含變量)
????????????? 當(dāng)遠(yuǎn)程主機(jī)接收到文件之后,文件中的變量將會(huì)變成具體的值
????????????? template模塊上傳的文件,使用的語(yǔ)法叫Jinja2。
????????????? 常用選項(xiàng):
–??????????? src:要上傳的文件
–??????????? dest:目標(biāo)文件路徑
# 使用template模塊將含有變量的文件上傳到test組中的主機(jī)
[root@control ansible]# vim index.j2
Welcome to {{ansible_hostname}} on {{ansible_eth0.ipv4.address}}
[root@control ansible]# vim templ.yml
---
- name: upload index
? hosts: test
? tasks:
??? - name: create web index
????? template:
??????? src: index.j2
??????? dest: /var/www/html/index.html
[root@control ansible]# ansible-playbook templ.yml
[root@control ansible]# curl http://192.168.4.11/
Welcome to node1 on 192.168.4.11
[root@node1 ~]# cat /var/www/html/index.html
Welcome to node1 on 192.168.4.11
進(jìn)階語(yǔ)法
錯(cuò)誤處理
????????????? 當(dāng)Playbook中包含很多任務(wù)時(shí),當(dāng)某一個(gè)任務(wù)遇到錯(cuò)誤,它將崩潰,終止執(zhí)行
# 在test組中的主機(jī)上啟動(dòng)mysqld服務(wù),然后創(chuàng)建/tmp/service.txt
# 因?yàn)槟繕?biāo)主機(jī)上沒(méi)有mysqld服務(wù),所以它將崩潰,終止執(zhí)行。即,不會(huì)創(chuàng)建/tmp/service.txt文件
[root@control ansible]# vim myerr.yml
---
- name: my errors
? hosts: test
? tasks:
??? - name: start mysqld service? # 通過(guò)service模塊啟動(dòng)mysqld服務(wù)
????? service:
??????? name: mysqld
??????? state: started
??????? enabled: yes
???????
??? - name: touch a file?? # 通過(guò)file模塊創(chuàng)建文件
????? file:
??????? path: /tmp/service.txt
??????? state: touch
# 執(zhí)行playbook,第1個(gè)任務(wù)就會(huì)失敗
[root@control ansible]# ansible-playbook myerr.yml
# 到node1上查看,因?yàn)榈?個(gè)任務(wù)沒(méi)有執(zhí)行,所以文件不會(huì)創(chuàng)建
[root@node1 ~]# ls /tmp/service.txt
ls: cannot access '/tmp/service.txt': No such file or directory
????????????? 可以指定某一個(gè)任務(wù)如果出現(xiàn)錯(cuò)誤,則忽略它
# 編輯myerr.yml,如果myslqd服務(wù)無(wú)法啟動(dòng),則忽略它
[root@control ansible]# vim myerr.yml
---
- name: my errors
? hosts: test
? tasks:
??? - name: start mysqld service
????? service:
??????? name: mysqld
??????? state: started
??????? enabled: yes
????? ignore_errors: yes??? # 即使這個(gè)任務(wù)失敗了,也要繼續(xù)執(zhí)行下去
??? - name: touch a file
????? file:
??????? path: /tmp/service.txt
??????? state: touch
[root@control ansible]# ansible-playbook myerr.yml
[root@node1 ~]# ls /tmp/service.txt?? # 第2個(gè)任務(wù)已執(zhí)行
/tmp/service.txt
????????????? 通過(guò)全局設(shè)置,無(wú)論哪個(gè)任務(wù)出現(xiàn)問(wèn)題,都要忽略
[root@control ansible]# vim myerr.yml
---
- name: my errors
? hosts: test
? ignore_errors: yes
? tasks:
??? - name: start mysqld service
????? service:
??????? name: mysqld
??????? state: started
??????? enabled: yes
??? - name: touch a file
????? file:
??????? path: /tmp/mysql.txt
??????? state: touch
[root@control ansible]# ansible-playbook myerr.yml
[root@node1 ~]# ls /tmp/mysql.txt
/tmp/mysql.txt
觸發(fā)執(zhí)行任務(wù)
????????????? 通過(guò)handlers定義觸發(fā)執(zhí)行的任務(wù)
????????????? handlers中定義的任務(wù),不是一定會(huì)執(zhí)行的
????????????? 在tasks中定義的任務(wù),通過(guò)notify關(guān)鍵通知handlers中的哪個(gè)任務(wù)要執(zhí)行
????????????? 只有tasks中的任務(wù)狀態(tài)是changed才會(huì)進(jìn)行通知。
# 下載node1上的/etc/httpd/conf/httpd.conf
[root@control ansible]# vim get_conf.yml
---
- name: download httpd.conf
? hosts: test
? tasks:
??? - name: get httpd.conf
????? fetch:
??????? src: /etc/httpd/conf/httpd.conf
??????? dest: ./
??????? flat: yes??? # 直接下載文件,不要目錄
[root@control ansible]# ansible-playbook get_conf.yml
# 修改httpd.conf的端口為變量
[root@control ansible]# vim +45 httpd.conf
... ...
Listen {{http_port}}
... ...
# 修改httpd服務(wù)的端口為8000,重啟httpd
[root@control ansible]# vim trigger.yml
---
- name: configure httpd
? hosts: test
? vars:
??? http_port: "8000"?? # 定義httpd.conf中的變量和值
? tasks:
??? - name: upload httpd.conf?? # 上傳httpd.conf
????? template:
??????? src: ./httpd.conf
??????? dest: /etc/httpd/conf/httpd.conf
??? - name: restart httpd??? # 重啟服務(wù)
????? service:
??????? name: httpd
??????? state: restarted
# 第一次執(zhí)行trigger.yml,上傳文件和重啟服務(wù)兩個(gè)任務(wù)的狀態(tài)都是黃色changed
[root@control ansible]# ansible-playbook trigger.yml
# 第二次執(zhí)行trigger.yml,上傳文件的任務(wù)狀態(tài)是綠色的ok,重啟服務(wù)任務(wù)的狀態(tài)是黃色changed
[root@control ansible]# ansible-playbook trigger.yml
# 既然配置文件沒(méi)有改變,那么服務(wù)就不應(yīng)該重啟
# 修改Playbook,只有配置文件變化了,才重啟服務(wù)
[root@control ansible]# vim trigger.yml
---
- name: configure httpd
? hosts: test
? vars:
??? http_port: "80"
? tasks:
??? - name: upload httpd.conf
????? template:
??????? src: ./httpd.conf
??????? dest: /etc/httpd/conf/httpd.conf
????? notify: restart httpd?? # 通知restart httpd需要執(zhí)行
? handlers:
??? - name: restart httpd
????? service:
??????? name: httpd
??????? state: restarted
# 第一次運(yùn)行Playbook,因?yàn)榈?個(gè)任務(wù)是黃色的changed,所以handlers中的任務(wù)也被觸發(fā)執(zhí)行
[root@control ansible]# ansible-playbook trigger.yml
# 第二次運(yùn)行Playbook,因?yàn)榈?個(gè)任務(wù)是綠色的OK,也就不會(huì)再觸發(fā)執(zhí)行其他任務(wù)了
[root@control ansible]# ansible-playbook trigger.yml
when條件
????????????? 只有滿足某一條件時(shí),才執(zhí)行任務(wù)
????????????? 常用的操作符:
–??????????? ==:相等
–??????????? !=:不等
–??????????? >:大于
–??????????? <:小于
–??????????? <=:小于等于
–??????????? >=:大于等于
????????????? 多個(gè)條件或以使用and或or進(jìn)行連接
????????????? when表達(dá)式中的變量,可以不使用{{}}
# 當(dāng)test組中的主機(jī)內(nèi)存大于2G的時(shí)候,才安裝mariadb-server
[root@control ansible]# vim when1.yml
---
- name: install mariadb
? hosts: test
? tasks:
??? - name: install mariadb pkg
????? yum:
??????? name: mariadb-server
??????? state: present
????? when: ansible_memtotal_mb>2048
# 如果目標(biāo)主機(jī)沒(méi)有2GB內(nèi)存,則不會(huì)安裝mariadb-server
[root@control ansible]# ansible-playbook when1.yml
# 多條件。系統(tǒng)發(fā)行版是RedHat8才執(zhí)行任務(wù)
# /etc/motd中的內(nèi)容,將會(huì)在用戶登陸時(shí)顯示在屏幕上
[root@control ansible]# vim motd
?_____________
< hello world >
?-------------
??????? \?? ^__^
??????? ?\? (oo)\_______
??????????? (__)\?????? )\/\
??????????????? ||----w |
??????????????? ||???? ||
[root@control ansible]# vim when2.yml
---
- name: when condition
? hosts: test
? tasks:
??? - name: modify /etc/motd
????? copy:
??????? dest: /etc/motd
??? ????src: motd
????? when: >???? # 以下三行合并成一行
??????? ansible_distribution == "RedHat"
??????? and
??????? ansible_distribution_major_version == "8"
[root@control ansible]# ansible-playbook when2.yml
cowsay:
[root@node1 ~]# yum install -y cowsay-3.04-4.el7.noarch.rpm
[root@node1 ~]# cowsay hello world??? # 默認(rèn)是奶牛形象
[root@node1 ~]# cowsay -l?? # 查看可用形象
[root@node1 ~]# cowsay -f sheep hello world
[root@node1 ~]# cowsay -l > ss.txt
[root@node1 ~]# vim ss.txt??? # 刪除第1行的說(shuō)明
[root@node1 ~]# for i in $(cat ss.txt)
> do
> echo "--------------$i----------------"
> cowsay -f $i hello
> sleep 3
> echo "--------------------------------"
> done