準(zhǔn)備(前戲)
安裝
yum install ansible
查看與ansible相關(guān)的文件信息
rpm -ql ansible|less
命令與選項(xiàng)
hosts基本語(yǔ)法
主機(jī)與組
[webserver] www.exaple.com test.exaple.com [dbserver] one.example.com two.example.com
備注:端口號(hào)不是默認(rèn)的時(shí)候,可以表示為
www.exaple.com:5122
主機(jī)別名
如果有些靜態(tài)IP地址,希望設(shè)置一些別名,但不是在系統(tǒng)的host文件中做解析
test_name ansible_ssh_port=5122 ansible_ssh_host=192.168.100.1
主機(jī)名擴(kuò)展
可以像bash那樣設(shè)置一組名稱類(lèi)似的主機(jī)
[webserver] web[01:50].example.com db-[a:f].example.com
自定連接
對(duì)于每一個(gè)host,還可以選擇連接類(lèi)型和連接用戶名
[targets] other1.example.com ansible_connection=ssh ansible_ssh_user=sam other2.example.com ansible_connection=ssh ansible_ssh_user=mdehaan
主機(jī)變量
在hosts中給主機(jī)設(shè)置變量,這樣可以在playbook中使用
[web] host1 http_port=80 maxRequestsPerChild=808 host2 http_port=303 maxRequestsPerChild=909
組變量
通過(guò)關(guān)鍵字vars
[webserver] host1 host2 [webserver:vars] ntp_server=ntp.atlanta.example.com proxy=proxy.atlanta.example.com
把一個(gè)組作為另個(gè)組的子成員
[webserver] host1 host2 [dbserver] host3 host4 [saas:children] webserver dbserver [saas:vars] some_server=foo.southeast.example.com halon_system_timeout=30 self_destruct_countdown=60 escape_pods=2
Inventory參數(shù)說(shuō)明
要連接的遠(yuǎn)程主機(jī)與設(shè)定的主機(jī)別名不同時(shí)
ansible_ssh_host
指定ssh端口號(hào)
ansible_ssh_port
指定連接用戶名
ansible_ssh_user
指定連接密碼(建議使用–ask-pass)
ansible_ssh_pass
指定sudo密碼(建議–ask-sudo-pass)
ansibl_sudo_pass
指定sudo執(zhí)行命令的路徑
ansible_sudo_exe
指定與主機(jī)的連接類(lèi)型
ansible_connection
使用指定密鑰文件
ansible_privte_key_file
指定目標(biāo)系統(tǒng)的shell類(lèi)型
ansible_shell_type
指定目標(biāo)主機(jī)的python路徑(相同的方式可以指定ruby、perl)
ansible_python_interpreter
常用指令與選項(xiàng)
ansible
-u # 指定用戶名 -k # 提示密碼 -i # 使用指定主機(jī)清單 -m # 使用指定module,默認(rèn)command -a # module參數(shù)
ansible-doc
-l # 列出所有module -s # 列出指定模塊的使用方法
常用模塊及使用方法
(1)配置hosts文件
[webserver] 192.168.100.131 192.168.100.132 [dbserver] 192.168.100.133
(2)配置ansible主機(jī)與個(gè)客戶機(jī)間密鑰認(rèn)證(這里直接使用copy模塊完成)
copy模塊
ansible all -m copy -a 'src="/root/.ssh/id_rsa.pub" dest="/root/.ssh/authorized_keys" mode=600 backup="yes"' --ask-pass 說(shuō)明: src # 源文件或文件夾(如果是源文件以/結(jié)尾,則只拷貝該目錄下的內(nèi)容) dest # 目標(biāo)文件或目錄(父目錄不存在時(shí)會(huì)報(bào)錯(cuò)) mode # 權(quán)限 backup # 是否需要備份目標(biāo)目錄原來(lái)的文件
command模塊
該模塊是默認(rèn)模塊,示例分顯示所有主機(jī)的時(shí)間
ansible all -m command -a "date"
user模塊、group模塊
例:在webserver組的每臺(tái)主機(jī)上創(chuàng)建一個(gè)用戶web1
ansible webserver -m user -a "name='web1' home='/home/test' system='yes' state='present'" 說(shuō)明: name # 用戶名 home # 用戶home目錄 system # 是否為系統(tǒng)用戶 state # present或absent(present添加,absent刪除)
cron模塊
例:創(chuàng)建每周一12點(diǎn)執(zhí)行echo "sam 你好"
ansible webserver -m cron -a "minute=0 hour=12 weekday=1 job='echo "sam 你好"' name='echo' state='present'" 說(shuō)明: minute # 分鐘(0-59,*/2) hour # 小時(shí)(0-23,*/2) day # 日(1-31,*/2) month # 月(1-12,*/2) weekday # 星期(0-6) name # 任務(wù)名稱 backup # 是否需要備份原來(lái)的任務(wù)
copy模塊
例:拷貝/etc/fstab到/tmp/fstab.ansible
ansible webserver -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible owner=root mode=644" 說(shuō)明: src # 源文件 dest # 目標(biāo)文件 owner # 文件屬主 mode # 權(quán)限 content # 為目標(biāo)文件指定內(nèi)容,此時(shí)省略src ansible webserver -m copy -a "content='Hello sam' dest=/tmp/sam.txt "
file模塊
例如:將webserver服務(wù)器/tmp/fstab.ansible 的文件權(quán)限更改為600
ansible webserver -m file -a "path=/tmp/fstab.ansible mode=600" 說(shuō)明: path # 源文件(可以用name,dest) mode # 權(quán)限 owner # 屬主 state # 如果是link,則表示要?jiǎng)?chuàng)建軟連接(此時(shí)源文件用src表示) src # 源文件 ansible webserver -m file -a "path=/tmp/fstab.link state=link src=/tmp/fstab.ansible"
yum模塊
例如:在webserver組安裝httpd服務(wù)
ansible webserver -m yum -a "name=httpd state=present " ansible dbserver -m yum -a "name='*' state=latest" 說(shuō)明: name # 包名稱,如果state=latest,那么name可以為*表示運(yùn)行yum update -y ;如果state=present,那么name可以指定本地的一個(gè)軟件包路徑; 也可以是一個(gè)用 逗號(hào) 分隔的軟件包列表 state # (`present' or `installed', `latest'), or remove (`absent' or `removed') list # 等效于yum list
service模塊
例如:?jiǎn)?dòng)webserver組的httpd服務(wù),并設(shè)置為開(kāi)機(jī)啟動(dòng)
ansible webserver -m service -a "name=httpd enabled=yes state=started " 說(shuō)明: name # 服務(wù)名稱 enabled # 是否開(kāi)機(jī)啟動(dòng) state # started,stopped,restarted,reloaded
shell模塊
例如:查看正在運(yùn)行的httpd服務(wù)的進(jìn)程號(hào)
ansible webserver -m shell -a "ps axu|grep httpd"
script模塊
首先創(chuàng)建一個(gè)shell腳本文件test.sh,內(nèi)容如下:
#!/bin/bash a=`pwd` echo "This is $a" echo "Hello sam ansible from script" >/tmp/script.txt
然后執(zhí)行ansible調(diào)用該腳本
ansible webserver -m script -a "/tmp/test.sh" 說(shuō)明: 參數(shù)為腳本名,可以是絕對(duì)路徑
功能模塊ping、setup
ansible webserver -m ping 說(shuō)明: 測(cè)試ansible主機(jī)與其他節(jié)點(diǎn)的連通性,成功返回 pong ansible webserver -m setup 說(shuō)明: 返回節(jié)點(diǎn)的facts信息,這些變量可以在playbook中直接使用
playbook使用與配置
注意這里對(duì)于yml的配置文件有著嚴(yán)格的語(yǔ)法要求,縮進(jìn)必須是2個(gè)空格(由于基礎(chǔ)較差坑了我2個(gè)小時(shí),python的4空格縮進(jìn)0.0)
1、一個(gè)簡(jiǎn)單的playbook劇本:(注意復(fù)制的時(shí)候一定注意格式,縮進(jìn)2個(gè)用空格)
- hosts: webserver # 主機(jī)組 remote_user: root # 遠(yuǎn)程連接用戶 tasks: # 任務(wù)列表關(guān)鍵字 - name: Test connection # 任務(wù)名稱 ping: # 模塊名稱
2、在webserver組創(chuàng)建一個(gè)組賬戶名稱為nginx-group,創(chuàng)建個(gè)賬戶為nginx-user,并且nginx-user的基本組為nginx-group;然后拷貝當(dāng)前主機(jī)/etc/fstab文件到dbserver組的/tmp目錄并命名為fstab-name.ansible。
- hosts: webserver remote_user: root tasks: - name: Add nginx-group group: name=nginx-group gid=2018 system=yes - name: Add nginx-user user: name=nginx-user uid=2018 system=yes group=nginx-group home=/home/nginx shell=/bin/nologin - hosts: dbserver remote_user: root tasks: - name: Copy File to dbserver copy: src=/etc/fstab dest=/tmp/fstab-name.ansible mode=600
HANDLERS
1、現(xiàn)在我們需要在webserver組安裝httpd服務(wù),并且需要將其啟動(dòng)并設(shè)置為開(kāi)機(jī)自啟,并且使用我當(dāng)前機(jī)器上httpd.conf文件作為其配置文件。
- hosts: webserver remote_user: root tasks: - name: Instarll httpd yum: name=httpd state=present - name: Configuration httpd file copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf - name: Start service httpd service: name=httpd state=started enabled=yes
2、繼續(xù)上面操我現(xiàn)在修改下本地的httpd.conf的監(jiān)聽(tīng)端口為8080,然后重新執(zhí)行playbook,并查看websever服務(wù)器的httpd端口啟動(dòng)情況。
[root@localhost ~]# ansible-playbook httpd.yml PLAY [webserver] ******************************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************** ok: [192.168.100.131] ok: [192.168.100.132] TASK [Instarll httpd] *************************************************************************************************************************** ok: [192.168.100.131] ok: [192.168.100.132] TASK [Configuration httpd file] ***************************************************************************************************************** changed: [192.168.100.132] changed: [192.168.100.131] TASK [Start service httpd] ********************************************************************************************************************** ok: [192.168.100.131] ok: [192.168.100.132] PLAY RECAP ************************************************************************************************************************************** 192.168.100.131 : ok=4 changed=1 unreachable=0 failed=0 192.168.100.132 : ok=4 changed=1 unreachable=0 failed=0 [root@localhost ~]# ansible webserver -a "ss -tnpl" 192.168.100.131 | SUCCESS | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* users:(("sshd",pid=968,fd=3)) LISTEN 0 100 127.0.0.1:25 *:* users:(("master",pid=1079,fd=13)) LISTEN 0 128 :::80 :::* users:(("httpd",pid=2550,fd=4),("httpd",pid=2549,fd=4),("httpd",pid=2548,fd=4),("httpd",pid=2547,fd=4),("httpd",pid=2546,fd=4),("httpd",pid=2545,fd=4)) LISTEN 0 128 :::22 :::* users:(("sshd",pid=968,fd=4)) LISTEN 0 100 ::1:25 :::* users:(("master",pid=1079,fd=14)) 192.168.100.132 | SUCCESS | rc=0 >> State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* users:(("sshd",pid=971,fd=3)) LISTEN 0 100 127.0.0.1:25 *:* users:(("master",pid=1078,fd=13)) LISTEN 0 128 :::80 :::* users:(("httpd",pid=2519,fd=4),("httpd",pid=2518,fd=4),("httpd",pid=2517,fd=4),("httpd",pid=2516,fd=4),("httpd",pid=2515,fd=4),("httpd",pid=2514,fd=4)) LISTEN 0 128 :::22 :::* users:(("sshd",pid=971,fd=4)) LISTEN 0 100 ::1:25 :::* users:(("master",pid=1078,fd=14))
如上所示,配置文件發(fā)生了更改但是httpd服務(wù)的啟動(dòng)端口并未發(fā)生更改,原因在于更了配置文件,可是httpd服務(wù)并未重啟。
這時(shí)候我們就需要用HANDLERS功能,簡(jiǎn)單點(diǎn)說(shuō)該功能就是在某個(gè)任務(wù)執(zhí)行完成后自動(dòng)觸發(fā)指定任務(wù)。據(jù)說(shuō)不僅僅可以使用任務(wù)觸發(fā)還可以使用某些主機(jī)觸發(fā)(比如某些主機(jī)執(zhí)行完一些任務(wù)后,主要區(qū)別在于notify的位置),下面我就用任務(wù)觸發(fā)舉個(gè)例子
- hosts: webserver remote_user: root tasks: - name: Instarll httpd yum: name=httpd state=present - name: Configuration httpd file copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf notify: # handlers觸發(fā)關(guān)鍵字 - Restart httpd # handlers中的任務(wù)名 - name: Start service httpd service: name=httpd state=started enabled=yes handlers: # 和tasks同級(jí) - name: Restart httpd service: name=httpd state=restarted
playbook中使用變量
自定義變量
我們現(xiàn)在定義兩個(gè)變量,分別為package_name、service_name,然后分別給這兩個(gè)變量賦值,最后通過(guò)引用這兩個(gè)變量在執(zhí)行playbook。
1、例如:現(xiàn)在我需要停掉webserver組服務(wù)器的httpd服務(wù),最后要卸載httpd服務(wù)(其實(shí)引用變量的方法很簡(jiǎn)單就是{{變量名}})
- hosts: webserver remote_user: root vars: - package_name: httpd - service_name: httpd tasks: - name: Stopped {{service_name}} service: name={{service_name}} state=stopped - name: remove {{package_name}} yum: name={{package_name}} state=removed
facts中的變量
1、例如,我們將webserver中每臺(tái)主機(jī)的IP地址寫(xiě)到/tmp/ip.txt文件(這里借助copy模塊中content完成)
- hosts: webserver remote_user: root tasks: - name: copy file for ip address copy: content={{ansible_all_ipv4_addresses}} dest=/tmp/ip.txt mode=600
playbook中使用條件測(cè)試
我們繼續(xù)上面的例子,在webserver組中,刪除ip地址為192.168.74.131主機(jī)的/tmp目錄下的ip.txt文件
- hosts: webserver remote_user: root tasks: - name: Delete ip.txt shell: rm -rf /tmp/ip.txt when: ansible_all_ipv4_addresses==["192.168.100.131"]
playbook中使用迭代
1、例如:要在webserver組分別創(chuàng)建web1和sam1賬戶(當(dāng)然你也可以建立多個(gè)tasks任務(wù),顯然這不是我們希望的樣子)
- hosts: webserver remote_user: root tasks: - name: Add web1 sam1 user: name={{item}} state=present # 使用關(guān)鍵字變量item with_items: # 定義關(guān)鍵字變量值的列表 - web1 - sam1
2、除了單個(gè)變量的迭代,還可以支持成組的變量迭代,比如創(chuàng)建用戶web2并且所數(shù)組為web3,創(chuàng)建用戶sam2,所屬組為sam3
- hosts: webserver remote_user: root tasks: - name: Add group sam3 web3 group: name={{item}} state=present with_items: - sam3 - web3 - name: Add web1 sam1 user: name={{item.name}} group={{item.group}} state=present # 用item引用字典的鍵做變量 with_items: # 以字典序列的形式定義變量 - {name: sam2, group: sam3} - {name: web2, group: web3}
在playbook中使用Templates
簡(jiǎn)單描述下,Templates
(1)用定義的變量替換模板中的具體參數(shù)
(2)在plabook中用關(guān)鍵字template代替copy模塊名
例:我們?cè)趆osts文件中為兩個(gè)webserver分別指定不同的httpd端口,并且希望httpd配置文件中的hostname為本機(jī)的fqdn
(1)首先我們先在INVENTORY文件中分別為兩個(gè)webserver主機(jī)創(chuàng)建兩個(gè)變量,httpd_port、web_root分別為httpd的端口、網(wǎng)站根目錄并且定義ServerName為本機(jī)主機(jī)名(引用ansible facts中的ansible_fqdn變量)
[webserver] 192.168.100.131 http_port=9000 web_root="/home/web1" 192.168.100.132 http_port=8000 web_root="/home/web2"
(2)在兩臺(tái)webserver分別創(chuàng)建網(wǎng)站根目錄/home/web1、/home/web2
ansible 192.168.100.131 -a "mkdir /home/web1" ansible 192.168.100.132 -a "mkdir /home/web2"
我們需要在ansible服務(wù)端創(chuàng)建一個(gè)/tmp/httpd.conf.j2格式的模板文件,我們直接選用httpd.conf的配置文件為基礎(chǔ)模板,只在下面幾個(gè)特殊地方寫(xiě)入變量代替
Listen {{http_port}} ServerName {{ansible_fqdn}} DocumentRoot "{{web_root}}"
playbook中使用tags(標(biāo)簽)
在playbook中可以為某個(gè)或某些任務(wù)定義一個(gè)“標(biāo)簽”,在執(zhí)行此playbook時(shí),通過(guò)為ansible-playbook命令使用–tags選項(xiàng)能實(shí)現(xiàn)僅運(yùn)行指定的taks而非所有的。
例如
- hosts: webserver remote_user: root tasks: - name: Uninstarll httpd yum: name=httpd state=absent - name: Configuration httpd file template: src=/tmp/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf notify: - Restart httpd - name: Stop service httpd service: name=httpd state=stopped tags: # 關(guān)鍵字 - stop # 標(biāo)簽名 handlers: - name: Restart httpd service: name=httpd state=restarted
運(yùn)行方式:
ansible-playbook template.yml --tags='start'
roles
(1)目錄名同角色名
(2)目錄結(jié)構(gòu)有固定格式:files、templates、tasks、handlers、vars、meta
(3)site.yml中定義playbook,額外也可以定義其它的yml文件。
例:
(1)定義個(gè)web角色
(2)該角色包含安裝httpd服務(wù),
(3)定義該服務(wù)一個(gè)httpd的模板文件,使httpd的ServerName為啟動(dòng)服務(wù)器的本機(jī)名
(4)并且在vars中定義個(gè)變量http_port,web_root分別為"81","/home"
(5)啟動(dòng)該服務(wù),并設(shè)置開(kāi)機(jī)自
(6)先使用webserver組調(diào)用該角色,然后在使用dbserver調(diào)用該角色
(1)創(chuàng)建角色及相關(guān)目錄
mkdir -pv /etc/ansible/roles/web/{tasks,files,templates,meta,handlers,vars}
(2)編輯/etc/ansible/roles/web/tasks/main.yml文件
- name: Install httpd yum: name=httpd state=present - name: Install httpd.conf template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf notify: - Restart httpd - name: Start httpd service: name=httpd state=started enabled=yes
(3)編輯/etc/ansible/roles/web/handlers/main.yml文件
- name: Restart httpd service: name=httpd state=restarted
(4)編輯/etc/ansible/roles/web/templates/httpd.conf.j2
我們需要在ansible服務(wù)端創(chuàng)建一個(gè)/tmp/httpd.conf.j2格式的模板文件,我們直接選用httpd.conf的配置文件為基礎(chǔ)模板,只在下面幾個(gè)特殊地方寫(xiě)入變量代替
Listen {{http_port}} ServerName {{ansible_fqdn}} DocumentRoot "{{web_root}}"
(5)編輯/etc/ansible/roles/web/vars/main.yml
http_port: 81 web_root: "/home"
(7)編輯/etc/ansible/roles/site.yml
- hosts: webserver remote_user: root roles: - web - hosts: dbserver remote_user: root roles: - web
(8)執(zhí)行playbook
ansible-playbook /etc/ansible/roles/site.yml
生活真難,因?yàn)楣ぷ髟虬疽沟?,連續(xù)3天才總結(jié)出來(lái),如果你學(xué)會(huì)了點(diǎn)個(gè)贊吧。