Ansible之Playbook詳解
介紹
簡單命令可以使用ad-hoc
(呼叫各種模組,通過命令列來執行命令)命令可以方便的解決問題,但是對於複雜場景或需要大量的操作時候,執行的ad-hoc
命令是不適合的,這時最好使用playbook
,它類似於Shell,檔案格式是YAML(教程:YAML)
Inventory:主機列表,表示劇本中的任務要應用在哪些主機上
Tasks:具體任務,即呼叫哪些模組完成操作,可以配置多個任務
Variables:變數,包含內建變數和自定義變數
Templates:模板,即使用模板語法來靈活變更的配置檔案
Handlers與notify:觸發器,由某事件觸發執行的操作,比如修改配置檔案後自動重啟服務
Playbook的語法要求
1、playbook本質是包含了一個或多個play的YAML配置檔案,通常以.yaml或者.yml結尾
2、在單一的一個playbook檔案中,使用連續的三個中橫線(---)作為每個play的區分
3、縮排必須統一,不能空格和tab混合使用,縮排級別需要一致,同樣的縮排代表同樣的級別
ansible具有冪等性
再次執行的時候ansible會檢測這個task是否已經執行過,如果這個task任務執行過,它不會再次執行task任務,而是直接顯示ok狀態
執行順序
play的主體部分是task list, task list中的各任務按次序逐個在hosts中指定的所有主機上執行,即在所有主機上完成第一個任務後在開始第二個任務,在執行自上而下某個playbook時,如果中途發生錯誤,所有已經執行的任務都會回滾,因此,在更正playbook後重新執行一次即可。
handlers
在關注的資源發生變化時採取一定的操作,會在 playbook 的每一個 task 結束時被觸發,而且即使有多個不同的 task 通知改動的發生, ‘notify’ actions 只會被觸發一次.
- name: template configuration file
template: src=template.j2 dest=/etc/foo.conf
notify:
- restart memcached
- restart apache
handler是task列表,這些task與前述的task並沒有本質上的區別
handlers: - name: restart memcached #名字要和上面notify的 一致 service: name=memcached state=restarted - name: restart apache service: name=apache state=restarted
執行 playbook
ansible-playbook -t tag_name httpd.yml #-t指定標籤名,多個標籤用逗號分隔
ansible-playbook playbookname.yml --list-task #列出該playbook中的任務
--check | -C
:只檢測可能會發生的改變,但不真正執行操作--list-hosts
:列出執行任務的主機--list-tags
:列出playbook檔案中定義的所有tags--list-tasks
:列出playbook檔案中定義的所有任務--limit
:主機列表 只針對主機列表中的某個主機或者某個組執行-f
:指定併發數,預設為5個-t
:指定tags執行,執行某一個或者多個tags。前提是playbook中有定義tags
ansible-playbook命令結果說明:
- ok:已經達到任務要求,無需再次處理
- changed:經過了ansible的處理,再次執行則會發現這些資訊也變成了ok
- PLAY RECAP:一個彙總報告
例項2:安裝Httpd
# ansible install httpd
- hosts: # 這裡是需要安裝的機器列表, 也可以是ansible配置好的組名
- 192.168.199.110
- 192.168.199.180
tasks: # 任務塊
- name: install httpd server # 描述資訊
yum: # ansible 模組
name: httpd,lrzsz # 需要安裝的軟體名稱
state: installed # 執行動作
- name: start httpd server
service:
name: httpd
state: started
enabled: yes
相關命令
#通過-e引數能給將變數傳入進去
ansible-playbook check_variable.yml -e "key=hehe"
#-t指定標籤名,多個標籤用逗號分隔
ansible-playbook -t tag_name httpd.yml
#列出該playbook中的任務
ansible-playbook playbookname.yml --list-task
#語法檢查
ansible-playbook playbook1.yml --syntax-check
#列出所有任務
ansible-playbook playbook1.yml --list-tasks
#指定要使用的並行程序數(預設值 = 5)
ansible-playbook playbook1.yml -f 3
#檢視某一個 Ansible 模組介紹
ansible-doc -l | grep <keywords associated with the module name>
#檢視某一個 Ansible 模組的使用方法
ansible-doc <module>
#按下 “:” 之後再按下 “/” 之後再輸入 <要檢視部分的關鍵字>
變數與引用
在hosts裡定義變數
[root@LeoDevops playb]# grep -vE "(^$|^#)" /etc/ansible/hosts
192.168.93.132 key=132
192.168.93.137 key=137
[nginx]
192.168.93.132
192.168.93.137
[nginx:vars]
ansible_python_interpreter=/usr/bin/python2.6
playbook引用變數
- hosts: all
gather_facts: False
tasks:
- name: Display Host Variable From Hostfile
debug: msg="The {{ inventory_hostname }} Value is {{ key }}"
在playbook定義變數
- hosts: all
gather_facts: False #設定為false,那麼下面的debug模組會生效
vars: # 先申明vars這個關鍵字
key: "Ansible" #這種方式定義,key: value的形式
tasks:
- name: display host variables from hostfile
debug: msg="The {{ inventory_hostname }} value is {{ key }}"
或者在playbook裡面引用有變數的檔案
- hosts: all
gather_facts: False
vars_files:
- var.json
tasks:
- name: display host variables from hostfile
debug: msg="The {{ inventory_hostname }} value is {{ key }}"
[root@LeoDevops playb]# cat var.json
{"key":"json"}
另一種變數引用, 定義全域性變數
在hosts的nginx裡面定義一個變數key, 不在單獨對每個主機定義key
> grep -vE "(^$|^#)" /etc/ansible/hosts
[nginx]
192.168.93.132
192.168.93.137
[nginx:vars]
ansible_python_interpreter=/usr/bin/python2.6
key=nginx
playbook保持不變
通過命令列傳輸
- 通過-e引數能給將變數傳入進去
[root@LeoDevops playb]# ansible-playbook check_variable.yml -e "key=hehe"
- -e指定檔案的方式傳入變數
[root@LeoDevops playb]# cat var.json
{"key":"json"}
[root@LeoDevops playb]# ansible-playbook check_variable.yml -e "@var.json"
register內的變數
ansible playbook內的task之間還可以互相傳遞資料,比如總共有兩個tasks,其中第二個task是否執行是需要判斷第1個task執行後的結果,這個時候就得在task之間傳遞資料,需要把第一個task執行的結果傳遞給第二個task,下面看看簡單的register的方式
- hosts: u12
tasks:
- name: register variable
shell: date
register: info
- name: display variable
debug: msg="the variable is {{ info['stdout'] }}"
使用vars_prompt傳入
ansible 還支援在執行playbook的時候通過互動式的方式給定義好的引數傳入變數值,只需要在playbook中定義vars_prompt 的變數名和互動式提示內容即可。當然ansible還可以對傳入的變數值進行加密處理。加密處理依賴於passlib python庫。請看簡單的 vars_prompt的例子
- hosts: all
gather_facts: False
vars_prompt:
- name: "one"
prompt: "please input your value"
private: no
- name: "two"
prompt: "please input two value"
default: 'good' # 預設顯示一個值
private: yes #置為yes的話,那麼就是看不見自己輸入的什麼了
tasks:
- name: display one value
debug: msg="one value is {{ one }}"
- name: display two value
debug: msg="two value is {{ two }}"
例項
playbook示例
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
notify:
- restart apache
- name: ensure apache is running
service: name=httpd state=started
handlers:
- name: restart apache
service: name=httpd state=restarted
此action可用於在每個play的最後被觸發,這樣可以避免多次有改變發生時每次都執行指定的操作,僅在所有的變化發生完成最後一次性地執行指定操作。在notify中列出的操作稱為handler,也即notify中呼叫handler中定義的操作。
vim hello_world.yml
--- #固定格式
- hosts: 192.168.1.31 #定義需要執行的主機或主機組
remote_user: root #遠端使用者
vars: #定義變數
http_port: 8088 #變數
tasks: #定義一個任務
- name: create new file #定義任務的名稱
file: name=/tmp/playtest.txt state=touch #呼叫模組,具體要做的事情
- name: install package
yum: name=httpd
- name: config httpd
template: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: #觸發器,當條件觸發後需要做的操作,配合handlers使用
- restart apache #需要引用的handlers的名字
- name: copy index.html
copy: src=/var/www/html/index.html dest=/var/www/html/index.html
- name: start httpd
service: name=httpd state=started
handlers: #notify定義的觸發執行相應的處理動作
- name: restart apache #要與notify定義的內容相同
service: name=httpd state=restarted #觸發要執行的動作
hosts:指定遠端主機(多個主機用逗號分隔)或主機組
remote_user:指定執行任務的使用者(也可單獨給每個task定義),通常是root使用者,也可指定非root使用者使用sudo方式執行任務
執行
ansible-playbook hello_world.yml
---
- hosts: 192.168.1.31
remote_user: root #定義全域性使用者
tasks:
- name: run df -h
remote_user: test #單獨為task定義使用者
shell: name=df -h
sudo(可省略):如果設定為yes,那麼sudo_user指定的使用者在執行任務時會獲得root許可權
sudo_user(可省略):指定需要使用sudo執行操作的使用者
tasks:
- name: run df -h
sudo_user: test
sudo: yes
shell: name=df -h
connection(可省略):通過什麼方式連線到遠端主機,預設為SSH
gather_facts(可省略):如果明確不需要通過setup模組來獲取遠端主機facts資訊,可以使用這個選項
---
#安裝mysql
- hosts: db_hosts #主機或主機組
remote_user: root #指定遠端主機的執行使用者
var: dar #變數,引用方式為{{ var }}
http_port: 80
db_port: 3306
tasks: #指定遠端主機將要執行的一系列動作
- name: Install MySQL-server package #不是必須,但建議加上
yum: name=mysql-server state=present #模組
- name: Starting mysqld service
service: name=mysqld state=started
notify:
handlers:
- name: restart apache
service: name=httpd state=restarted
第一個示例
vim /root/first.yml
- hosts: all
remote_user: root
vars: httpd_port=80
tasks:
- name: install httpd
yum: name=httpd state=present
- name: install php
yum: name=php state=present
- name: start httpd
service: name=httpd state=started enabled=true
hosts 定義單個主機或組,vars定義變數,remote_user定義執行命令的遠端使用者,tasks定義執行哪些命令,handlers定義呼叫哪些處理器
vars(變數)
- 變數命名: 字母數字下劃線組成,只能以字母開頭
變數種類:
- facts(內建變數)
由遠端主機發回的主機屬性資訊,這些資訊被儲存在ansible變數當中
例如:ansible 192.168.238.170 -m setup
來獲取遠端主機上的屬性資訊,這些屬性資訊儲存在facts中
通過命令列傳遞:ansible-playbook test.yml --extra-vars “host=www user=tom“
(如果劇本中已有此處定義的變數則會被覆蓋)
-
通過roles傳遞
主機變數 , 在
/etc/ansible/hosts
中定義
[web1]
192.168.1.1 name=haha
組變數
[group_name:vars]
foo=bar
hosts :
/etc/abible/hosts
中指定的遠端主機,並用指定的屬性進行連線
ansible_ssh_port 連線遠端主機使用的埠
ansible_ssh_user 連線遠端主機使用的使用者
ansible_ssh_pass 連線遠端主機使用的密碼
cat /etc/ansible/hosts
[web1]
web1.hostname ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123
web2.hostname
第二個示例
vim /root/second.yml
- hosts: web1
remote_user: root
vars:
username: bob
password: 123
tasks:
- name: add user
user: name={{ username }} state=present
when: ansible_os_family == "Debian"
- name: set password
shell: echo {{ password }} |passwd --stdin {{ username }}
- name: install httpd php
yum: name={{ item }} state=present
with_items:
- httpd
- php
- name: add two users
user: name={{ item }} state=present groups={{ item.groups }}
with_items:
- { name: 'user1', groups: 'group1'}
- { name: 'user2', groups: 'group2'}
- 在playbook中呼叫變數的方式為{{ variable }}
- when語句用來條件測試
- ansible_os_family 是facts中內建的屬性資訊 ansible_os_family的資訊可以使用ansible all -m setup | grep ansible_os_family 檢視
- 在task中呼叫內建的item變數;在某task後面使用with_items語句來定義元素列表
第三個示例
vim /root/third.yml
- hosts: web1
remote_user: root
vars:
httpd_port=80
tasks:
- name: install httpd
yum: name=httpd state=present
- name: install php
yum: name=php state=present
- name: copy config file
copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
- name: start httpd
service: name=httpd state=started enabled=true
handlers:
- name: restart httpd
service: name=httpd state=restarted
上面的意思是copy中複製過去的檔案跟遠端主機上的檔案不同,就通過notify呼叫handlers,即重啟httpd服務。
handler是重啟服務是最通用的用法
第四個示例
vim /etc/ansible/hosts
[web1]
192.168.1.1 http_port=80
vim /root/httpd.conf
……
Listen {{ http_port }}
……
vim /root/fourth.yml
- hosts: web1
remote_user: root
vars:
httpd_port=80
tasks:
- name: install httpd
yum: name=httpd state=present
- name: copy config file
template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
- name: start httpd
service: name=httpd state=started enabled=true
handlers:
- name: restart httpd
service: name=httpd state=restarted
templates:用於生成文字檔案(配置檔案)
模板檔案中可使用jinja2表示式,表示式要定義在{{ }},也可以簡單地僅執行變數替換
第五個示例
roles:roles用於實現“程式碼複用”,roles以特定的層次型格式組織起來的playbook元素(variables, tasks, templates,handlers);可被playbook以role的名字直接進行呼叫
roles的檔案結構:
- files/:此角色中用到的所有檔案均放置於此目錄中
- templates/: Jinja2模板檔案存放位置
- tasks/:任務列表檔案;可以有多個,但至少有一個叫做main.yml的檔案
- handlers/:處理器列表檔案;可以有多個,但至少有一個叫做main.yml的檔案
- vars/:變數字典檔案;可以有多個,但至少有一個叫做main.yml的檔案
- meta/:此角色的特殊設定及依賴關係
mkdir /root/roles
cd /root/roles
mkdir -p web1/{files, templayes, tasks, handlers, vars, meta}
vim web1/vars/main.yml
user: tom
group: tom
http_port: 8080
vim web1/tasks/main.yml
- name: install httpd
yum: name=httpd state=present
- name: copy config file
template: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: restart httpd
tags: conf
- name: start httpd
service: name=httpd state=started enabled=true
#這裡的template指的是相對路徑-->web1/templates
#tags可以在執行時指定標籤任務
vim web1/handlers/main.yml
handlers:
- name: restart httpd
service: name=httpd state=restarted
vim web1/templates/httpd.conf
……
Listen {{ http_port }}
……
定義一個呼叫roles檔案
vim /root/web1.yml
- hosts: web1
remote_user: root
roles:
- web1
- { role:web2, http_port:8080 }
- hosts:web1 指在/etc/ansible/hosts中定義的組,上面有定義
- roles: web1 指的是當前目錄下的web1目錄,也可通過role傳遞變數, 也可呼叫多個role。這樣只需更改hosts的主機就可以實現不同主機的程式碼重用了
執行
ansible-playbook web1.yml
#指定執行任務:
ansible-playbook -t conf web1.yml
ansible任務的非同步執行
ansible方便在於能批量下發,並返回結果和呈現。簡單、高效。
但有的任務執行起來卻不那麼直接,可能會花比較長的時間,甚至可能會比ssh的超時時間還要長。這種情況任務是不是沒法執行了?
ansible考慮到了這種情況,官方文件介紹了這個問題的解決方法,就是讓下發的任務執行的連線變為非同步:任務下發之後,長連線不再保持,而是每隔一段時間輪詢結果,直到任務結束。
他們在playbook的任務中加入兩個引數:async和poll。
async引數值代表了這個任務執行時間的上限值。即任務執行所用時間如果超出這個時間,則認為任務失敗。此引數若未設定,則為同步執行。
poll引數值代表了任務非同步執行時輪詢的時間間隔。 官方給出例子:
hosts: all
remote_user: root
tasks:
- name: simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
command: /bin/sleep 15
async: 45
poll: 5
這時候已經不怕任務超時了。可以執行一個45s的任務,當然也可以根據需要自己設定。另外,如果poll為0,就相當於一個不關心結果的任務。
如果還想要更方便地看輪詢結果,ansible還提供了這個模組async_status。
# Requires ansible 1.8+
- name: 'YUM - fire and forget task'
yum: name=docker-io state=installed
async: 1000
poll: 0
register: yum_sleeper
- name: 'YUM - check on fire and forget task'
async_status: jid={{ yum_sleeper.ansible_job_id }}
register: job_result
until: job_result.finished
retries: 30
第一個job執行非同步任務,並且註冊了一個名字叫yum_sleeper,用於提供給第二個job作為輪詢物件,並且poll設為0,它自己不再輪詢。
第二個job使用async_status模組,進行輪詢並返回輪詢結果。準備檢查30次。結果如下:
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [cloudlab001]
TASK [YUM - fire and forget task] **********************************************
ok: [cloudlab001]
TASK [YUM - check on fire and forget task] *************************************
FAILED - RETRYING: TASK: YUM - check on fire and forget task (29 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (28 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (27 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (26 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (25 retries left).
FAILED - RETRYING: TASK: YUM - check on fire and forget task (24 retries left).
changed: [cloudlab001]
PLAY RECAP *********************************************************************
cloudlab001 : ok=3 changed=1 unreachable=0 failed=0
playbook安裝zabbix
定義hosts
shell > vim /etc/ansible/hosts
[mini]
129.139.153.78:16283
155.139.190.94:12573
定義入口檔案install_zabbix_agent.yml
shell > vim /etc/ansible/install_zabbix_agent.yml
---
- hosts: mini
roles:
- install_zabbix_agent
## 可以看到將要安裝的主機組為 mini 組,角色為 install_zabbix_agent
定義角色 install_zabbix_agent
shell > tree /etc/ansible/roles/install_zabbix_agent/
├── files
│ └── zabbix-2.4.5.tar.gz
├── tasks
│ └── main.yml
├── templates
│ ├── zabbix_agentd
│ └── zabbix_agentd.conf
└── vars
└── main.yml
## 建立 files 目錄,存放編譯安裝過的 zabbix_agent 目錄的壓縮檔案,用於拷貝到遠端主機
## 建立 tasks 目錄,用於編寫將要執行的任務
## 建立 templates 目錄,用於存放可變的模板檔案
## 建立 vars 目錄,用於存放變數資訊
建立tasks主檔案
shell > cat /etc/ansible/roles/install_zabbix_agent/tasks/main.yml
---
- name: Install Software
yum: name={{ item }} state=latest
with_items:
- libcurl-devel
- name: Create Zabbix User
user: name={{ zabbix_user }} state=present createhome=no shell=/sbin/nologin
- name: Copy Zabbix.tar.gz
copy: src=zabbix-{{ zabbix_version }}.tar.gz dest={{ zabbix_dir }}/src/zabbix-{{ zabbix_version }}.tar.gz owner=root group=root
- name: Uncompression Zabbix.tar.gz
shell: tar zxf {{ zabbix_dir }}/src/zabbix-{{ zabbix_version }}.tar.gz -C {{ zabbix_dir }}/
- name: Copy Zabbix Start Script
template: src=zabbix_agentd dest=/etc/init.d/zabbix_agentd owner=root group=root mode=0755
- name: Copy Zabbix Config File
template: src=zabbix_agentd.conf dest={{ zabbix_dir }}/zabbix/etc/zabbix_agentd.conf owner={{ zabbix_user }} group={{ zabbix_user }} mode=0644
- name: Modify Zabbix Dir Permisson
file: path={{ zabbix_dir }}/zabbix owner={{ zabbix_user }} group={{ zabbix_user }} mode=0755 recurse=yes
- name: Start Zabbix Service
shell: /etc/init.d/zabbix_agentd start
- name: Add Boot Start Zabbix Service
shell: chkconfig --level 35 zabbix_agentd on
建立主變數檔案
shell > cat /etc/ansible/roles/install_zabbix_agent/vars/main.yml
zabbix_dir: /usr/local
zabbix_version: 2.4.5
zabbix_user: zabbix
zabbix_port: 10050
zabbix_server_ip: 131.142.101.120
建立模板檔案
shell > cat /etc/ansible/roles/install_zabbix_agent/templates/zabbix_agentd
#!/bin/bash
. /etc/init.d/functions
# Zabbix-Directory
BASEDIR={{ zabbix_dir }}/zabbix
# Binary File
BINARY_NAME=zabbix_agentd
# Full Binary File Call
FULLPATH=$BASEDIR/sbin/$BINARY_NAME
# PID file
PIDFILE=/tmp/$BINARY_NAME.pid
# Establish args
ERROR=0
STOPPING=0
if [ -f $PIDFILE ] && [ -s $PIDFILE ]
then
PID=`cat $PIDFILE`
if [ "x$PID" != "x" ] && kill -0 $PID 2>/dev/null && [ $BINARY_NAME == `ps -e | grep $PID | awk '{print $4}'` ]
then
STATUS="$BINARY_NAME (pid `pidof $APP`) running.."
RUNNING=1
else
rm -f $PIDFILE
STATUS="$BINARY_NAME (pid file existed ($PID) and now removed) not running.."
RUNNING=0
fi
else
if [ `ps -e | grep $BINARY_NAME | head -1 | awk '{ print $1 }'` ]
then
STATUS="$BINARY_NAME (pid `pidof $APP`, but no pid file) running.."
else
STATUS="$BINARY_NAME (no pid file) not running"
fi
RUNNING=0
fi
# functions
start() {
if [ $RUNNING -eq 1 ]
then
echo "$0 $ARG: $BINARY_NAME (pid $PID) already running"
else
action $"Starting $BINARY_NAME: " $FULLPATH
touch /var/lock/subsys/$BINARY_NAME
fi
}
stop() {
echo -n $"Shutting down $BINARY_NAME: "
killproc $BINARY_NAME
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$BINARY_NAME
RUNNING=0
}
# logic
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $BINARY_NAME
;;
restart)
stop
sleep 10
start
;;
help|*)
echo $"Usage: $0 {start|stop|status|restart|help}"
cat <<EOF
start - start $BINARY_NAME
stop - stop $BINARY_NAME
status - show current status of $BINARY_NAME
restart - restart $BINARY_NAME if running by sending a SIGHUP or start if not running
help - this screen
EOF
exit 1
;;
esac
exit 0
shell > cat /etc/ansible/roles/install_zabbix_agent/templates/zabbix_agentd.conf
LogFile=/tmp/zabbix_agentd.log
Server={{ zabbix_server_ip }}
ListenPort={{ zabbix_port }}
Hostname={{ ansible_all_ipv4_addresses[1] }}
Timeout=20
UnsafeUserParameters=1
安裝
shell > ansible-playbook /etc/ansible/install_zabbix_agent.yml
PLAY [mini] *******************************************************************
GATHERING FACTS ***************************************************************
ok: [129.139.153.78]
ok: [155.139.190.94]
TASK: [install_zabbix_agent | Install Software] *******************************
changed: [155.139.190.94] => (item=libcurl-devel)
changed: [129.139.153.78] => (item=libcurl-devel)
TASK: [install_zabbix_agent | Create Zabbix User] *****************************
changed: [129.139.153.78]
changed: [155.139.190.94]
TASK: [install_zabbix_agent | Copy Zabbix.tar.gz] *****************************
changed: [129.139.153.78]
changed: [155.139.190.94]
TASK: [install_zabbix_agent | Uncompression Zabbix.tar.gz] ********************
changed: [129.139.153.78]
changed: [155.139.190.94]
TASK: [install_zabbix_agent | Copy Zabbix Start Script] ***********************
changed: [155.139.190.94]
changed: [129.139.153.78]
TASK: [install_zabbix_agent | Copy Zabbix Config File] ************************
changed: [129.139.153.78]
changed: [155.139.190.94]
TASK: [install_zabbix_agent | Modify Zabbix Dir Permisson] ********************
changed: [155.139.190.94]
changed: [129.139.153.78]
TASK: [install_zabbix_agent | Start Zabbix Service] ***************************
changed: [129.139.153.78]
changed: [155.139.190.94]
TASK: [install_zabbix_agent | Add Boot Start Zabbix Service] ******************
changed: [129.139.153.78]
changed: [155.139.190.94]
PLAY RECAP ********************************************************************
155.139.190.94 : ok=10 changed=9 unreachable=0 failed=0
129.139.153.78 : ok=10 changed=9 unreachable=0 failed=0
## 關注一下,啟動指令碼跟配置檔案中變數的引用。
## 完成安裝,可以去客戶機檢查效果了 !
模組
ping模組
功能:檢測
#測試連線可通性,沒有引數。通的話返回pong
ansible all -m ping
setup模組
功能:獲取主機資訊(綠色,紅色)
--tree :#將所有主機的輸出資訊儲存到/tmp/目錄下,以/etc/ansible/hosts裡的主機名為檔名
filter :#過濾關鍵字
ansible all -m setup -a 'filter=ansible_distribution_version' --tree /tmp/xx
#企業需求
1.根據不同主機'不同IP'建立對應IP的目錄
2.根據不同主機不同'主機名'建立對應主機名的目錄
3.自動化運維平臺需要自動獲取到主機的'IP地址,記憶體資訊,磁碟資訊,主機名'...等
4.如果安裝資料庫,分配記憶體為實體記憶體的80%,此時有3臺不同實體記憶體的機器2G、4G、16G
寫一個playbook的情況下,我需要獲取到對應主機的記憶體並作出計算,寫判斷。
#檢視主機所有詳細資訊(命令列和劇本中獲取的格式不同)
[root@m01 ~]# ansible web01 -m setup
#獲取ip
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_default_ipv4'
#獲取主機名
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_fqdn'
#獲取記憶體資訊
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_memory_mb'
#獲取磁碟資訊
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_devices'
#其他資訊引數
ansible_all_ipv4_addresses:'僅顯示ipv4的資訊'。
ansible_devices:僅顯示磁碟裝置資訊。
ansible_distribution:'顯示是什麼系統',例:centos,suse等。
ansible_distribution_major_version:顯示是系統主版本。
ansible_distribution_version:僅顯示系統版本。
ansible_machine:顯示系統型別,例:32位,還是64位。
ansible_eth0:'僅顯示eth0的資訊'。
ansible_hostname:'僅顯示主機名。
ansible_kernel:僅顯示核心版本。
ansible_lvm:顯示lvm相關資訊。
ansible_memtotal_mb:'顯示系統總記憶體'。
ansible_memfree_mb:顯示可用系統記憶體。
ansible_memory_mb:詳細顯示記憶體情況。
ansible_swaptotal_mb:顯示總的swap記憶體。
ansible_swapfree_mb:顯示swap記憶體的可用記憶體。
ansible_mounts:'顯示系統磁碟掛載情況'。
ansible_processor:'顯示cpu個數(具體顯示每個cpu的型號)''。
ansible_processor_vcpus:顯示cpu個數(只顯示總的個數)
#取ip
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_default_ipv4'|awk -F '["]' '/"address"/{print $4}'
10.0.0.7
[root@m01 ~]# ansible web_group -m setup -a 'filter=ansible_default_ipv4'|awk -F '["]' '/"address"/{print $4}'
10.0.0.7
10.0.0.9
10.0.0.8
#取主機名
[root@m01 ~]# ansible web01 -m setup -a 'filter=ansible_fqdn'|awk -F '["]' '/fqdn/{print $4}'
web01
command模組
功能:遠端執行簡單的命令
#預設模組(可省略不指定)
#作用:執行系統命令(linux windows),不支援變數,"<",">","|",";","&"等符號
[root@m01 ~]# ansible web_group -a 'ls'
[root@m01 ~]# ansible web_group -a 'df -h'
cron模組
功能:新增定時任務
#使用crontab之前最好同步時間(注意單引號和雙引號的作用)(*有時候需要加'')
[root@m01 ~]# ansible '*' -m cron -a "name=同步時間 minute=*/5 job='/usr/sbin/ntpdate time1.aliyun.com &>/dev/null'"
ansible-doc cron
ansible db -m cron -a 'minute="" hour="" day="" month="" weekday="" job="" name="(必須填寫)" state='
# 1、定時設定指定值的寫入即可,沒有設定的要刪除
# 2、name必須寫(建立定時任務或者刪除定時任務的 標誌,不能修改註釋)(這一點和yum倉庫名一樣)
# 3、state有兩個狀態:present(新增(預設值))or absent(移除)
#新增定時任務
ansible db -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job" state="present"'
#檢視定時任務
ansible db -a "crontab -l"
#修改定時任務
ansible db -m cron -a 'minute="*/5" job="/bin/echo hello" name="test cron job" state="present"'
#移除定時任務(根據name來刪除)
ansible db -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job" state="absent"'
ansible all -m cron -a "name=test state=absent"
檢視定時任務
ansible db -a "crontab -l"
# 註釋相應定時任務,使定時任務失效
ansible web_group -m cron -a "name='ansible cron01' minute=0 hour=0 job='/bin/sh /server/scripts/test.sh' disabled=yes"
ansible yml語法(playbook)
注意:yml語法很嚴格,不能多,漏空格,不能使用TAB
在不同的主機上,建立以主機名命名的目錄
[root@m01 ~]# vim 2.yml
- hosts: web_group
tasks:
- name: 233
file:
path: /root/{{ ansible_fqdn }}
state: directory
owner: root
group: root
mode: 0755
[root@m01 ~]# ansible-playbook 2.yml
[root@web01 ~]# ll
total 8
drwxr-xr-x 2 root root 6 Jun 1 00:41 web01
#檢視ansiable-playbook命令
[root@m01 ~]# ll /usr/bin/ansible #TAB
ansible ansible-console-2.7
copy模組
拷貝, 修改檔案或目錄, 修改已經存在的目錄的許可權
使用content可以直接在遠端建立檔案,同時指定檔案內容
使用backup=yes備份配置檔案,可以實現配置檔案的修改或回滾
該模組可以直接拷貝連結
[root@m01 ~]# ansible-doc copy #檢視copy模組用法
src: #原始檔或目錄,要複製到遠端主機的檔案在本地的地址,可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,它將遞迴複製。在這種情況下,如果路徑使用"/"來結尾,則只複製目錄裡的內容,如果沒有使用"/"來結尾,則包含目錄在內的整個內容全部複製,類似於rsync(#)。(src為空目錄是時候是不會拷貝的,一致顯示綠色)
content:用於替代"src",可以在命令列直接設定指定檔案的值
dest: #目標目錄
owner: foo #屬主
group: foo #屬組(不能使用gid指定)
mode: '0644' #許可權,數字(3位|4位),字母,UGO
backup: yes #當出現同名的檔案,直接覆蓋,因為預設是no,指定yes後(檔案內容不同會以當前時間戳備份該檔案)
force:如果目標主機包含該檔案,但內容不同,如果設定為yes,則強制覆蓋,如果為no,則只有當目標主機的目標位置不存在該檔案時,才複製。預設為yes(force=no和state=backup可以二選一)
remote_src:
yes #受控端自己玩(可以做批量回滾)
no #預設
--------------------------------------------------
#遠端批量拷貝,相當於scp,rsync
#目標目錄下檔案存在的話會報錯,被控端主機使用者不存在會報錯(但是它把能做的都做了)
[root@m01 ~]# ansible 'web_group' -m copy -a 'src=/root/hosts dest=/root owner=www group=www mode=0644'
--------------------------------------------
[root@web01 /]# yum install -y httpd
[root@web01 ~]# systemctl start httpd
[root@web01 ~]# echo 233 > /var/www/html/index.html
#瀏覽器訪問
------------------------------------------------------------
#遠端拷貝檔案,並且將原來的同名檔案備份,如果檔名和檔案內容,屬主屬組和許可權都一樣就不做拷貝了(綠),backup=no可以省略,屬主屬組是root的時候可以不寫(目的地檔案1.同名 2.內容不同 才備份),當dest不存在時,原始檔改名
[root@m01 /]# ansible 'web_group' -m copy -a 'src=/root/hosts dest=/root owner=www group=www mode=0644 backup=yes'
----------------------------------------------------------------
#簡單的檔案直接可以直接使用content在命令列copy,不需要copy檔案(記得在末尾加\n)
[root@m01 ~]# ansible 'nfs_group' -m copy -a 'content="/data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)\n" dest=/etc/exports'
--------------------------------------------------------------------------
#遠端的源拷貝到遠端指定的位置
[root@m01 ~]# ansible 'web_group' -m copy -a 'src=/etc/passwd dest=/tmp remote_src=yes'
#配置檔案回滾
[root@m01 ~]# ansible web01 -m copy -a 'src=/root/passwd.1811.2020-06-09@18:16:13~ dest=/root/passwd remote_src=yes'
file模組
功能:建立檔案或目錄,修改已經存在的目錄的許可權,建立軟硬連線
file:
path: /etc/foo.conf #指定建立的目錄或檔案
state:
touch #建立檔案
directory #建立目錄
absent #刪除目錄或檔案
link #做軟連結
owner: foo #屬主
group: foo #屬組
mode: '0644' #許可權
recurse #遞迴
#1 force:需要在兩種情況下強制建立軟連結,一種是原始檔不存在但之後會建立的情況下;另一種是目標軟連結已存在,需要先取消之前的軟鏈,然後建立新的軟鏈,有兩個選項:yes|no
#2 group:定義檔案/目錄的屬組
#3 mode:定義檔案/目錄的許可權( 1.一次建立多個目錄的時候才會遞迴授權, 2.recurse=yes也會遞迴授權)
#4 owner:定義檔案/目錄的屬主
#5 path:必選項,定義檔案/目錄的路徑(不存在的話可以直接建立)#
#6 recurse:'遞迴'的設定檔案的屬性,只對'目錄'有效(指定recurce的話,可以修改已經存在的檔案或者目錄的許可權,預設關閉)(需要配合mode owner group一起使用)
#7 src:要被連結的原始檔的路徑,只應用於state=link的情況
#8 dest:被連結到的路徑,只應用於state=link的情況
#9 state:
directory:如果目錄不存在,建立目錄
file:只能修改檔案或目錄的時間 (配合modification_time access_time)
link:建立軟連結
hard:建立硬連結
touch:如果檔案不存在,則會建立一個新的檔案,如果檔案或目錄已存在,則更新其最後修改時間 (不能在不存在的目錄下建立檔案,這一點和touch命令一樣)
absent:刪除目錄、檔案或者取消連結檔案
#遠端批量建立目錄
不指定屬主屬組,預設是root(當前使用者),不指定mode,那麼許可權為預設
[root@lb01 /code]# ansible 'web_group' -m file -a 'path=/backup state=directory owner=adm group=adm mode=0000'
#建立目錄,同時遞迴授權(不能針對檔案)
[root@m01 ~]# ansible 'web01' -m file -a 'path=/1/2/3 state=directory mode=000 recurse=yes'
#當state=touch mode=000同時指定,建立的都是目錄,只指定touch才會建立檔案 3
[root@m01 ~]# ansible web01 -m file -a 'path=/1/2/3 state=touch mode=000'
#遠端批量建立檔案(上級目錄必須存在)
[root@lb01 /code]# ansible 'web_group' -m file -a 'path=/backup state=touch owner=adm group=adm mode=0000'
--------------------------------------------------------------------
#遠端批量刪除目錄或檔案
[root@lb01 ~]# ansible 'web_group' -m file -a 'path=/backup state=absent'
-----------------------------------------------------------------------
#遠端建立軟連結,(不指定許可權的話,屬主屬組為root,連結檔案許可權是777)
[root@lb01 /code]# ansible 'web_group' -m file -a 'src=/backup/a.txt dest=/b.txt state=link owner=adm group=adm mode=0000'
#遠端建立硬連結(可通過ll -i 檢視inode號,判斷是否為硬連結關係)
[root@lb01 /code]# ansible 'web_group' -m file -a 'src=/backup/a.txt dest=/b.txt state=hard owner=adm group=adm mode=0000'
yum模組
功能:遠端下載
name #包名,用等於號表示(指定要安裝的軟體包的名稱)
file:// #指定本地安裝路徑,=yum localinstall -y
http:// #指定yum倉庫
state #指定動作,用等於號表示
present #安裝軟體包(預設)(=install)
absent #刪除軟體包(=remove)
latest #安裝最新版本的軟體包或,升級
disable_gpg_check #預設值為 no,表示不禁用驗證,設定為 yes 表示禁用驗證,即不驗證包,直接安裝。
enablerepo #臨時啟用源(無論此源是否開啟)
disablerepo #臨時禁用某個源,這樣設定後,在安裝軟體包時則不會從對應的源中選擇安裝包。
download_only=true #只下載不安裝 yum install [d]
-------------------------------------------------------------
#下載安裝,使用被控端的源安裝軟體包
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=vsftpd'
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=vsftpd state=present'
#下載安裝,指定源的rpm包,相當於wget+localinstall,可以指定包名和協議
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-agent-5.0.0-1.el7.x86_64.rpm state=present'
#安裝,前提是客戶端指定目錄下有這個rpm包(相當於yum localinstall)
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=/root/zabbix-agent-5.0.0-1.el7.x86_64.rpm state=present'
--------------------------------------------------------------
#解除安裝
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=zabbix-agent-5.0.0-1.el7.x86_64 state=absent'
[root@m01 ~]# ansible 'web_group' -m yum -a 'name=zabbix state=absent'
-----------------------------------------------------------------------
#擴充套件
[root@localhost ~]# ansible all -m yum -a "name=httpd state=latest disable_gpg_check=yes enablerepo=epel"
#升級所有軟體包,排除httpd
[root@Ansible ~]# ansible all -m yum -a "state=latest name='*' exclude='httpd'"
shell模組
功能:執行復雜的命令
#尤其是用到複雜命令時(如帶管道符等等),但是shell模組不能做mysql的主從複製,但是nginx編譯安裝的時候只能使用shell模組(一般不用shell模組,因為還要指定模組...)
#企業中一般不讓使用shell模組
#使用ansible批量操作叢集的主機
[root@m01 ~]# ansible 'web_group' -m shell -a 'free -m'
[root@m01 ~]# ansible 'web_group' -m conmand -a 'free -m'
[root@m01 ~]# ansible web01 -m shell -a "ps -ef|grep httpd"
#命令的最後也可以加 -f number ,表示使用的併發程序數目,預設是5個
ansible webserver -a 'netstat -ulntp' -f 15
#/usr/bin/ansible 預設使用當前ansible 伺服器登陸的使用者來進行管理,如果你不喜歡這樣,也可以使用 -u username 的方式來指定使用者
[root@docker ~]# ansible webserver -a "ls" -u zhangsan -f 9
script模組
功能:作用:將本地指令碼複製到遠端主機,並執行。(不需要給指令碼新增執行許可權)
#編輯指令碼(只需要放在m01就好)
vim /root/dir.sh
mkdir syy
#執行
absible 'web01' -m script -a '/root/dir.sh'
synchronize模組
功能:基於rsync命令工具同步目錄和檔案
由於synchronize模組會呼叫rsync命令,因此首先要記得提前安裝好rsync軟體包
1 archive: 歸檔,相當於同時開啟recursive(遞迴)、links、perms、times、owner、group、-D選項都為yes ,預設該項為開啟(#保證原始檔和目標檔案屬性一致)
2 checksum: 是否檢測sum值,預設關閉
3 compress:是否開啟壓縮(預設開啟)
4 copy_links:同步的時候是否複製連結,預設為no ,注意後面還有一個links引數
links:同步連結檔案
5 delete: 刪除不存在的檔案,delete=yes 使兩邊的內容一樣(即以推送方為主),預設no
6 dest:目錄路徑(絕對路徑或者相對路徑)
7 dest_port:目標主機上的埠 ,預設是22,走的ssh協議
8 dirs:傳送目錄不進行遞迴,預設為no,即進行目錄遞迴(#一般不用指定)
9 rsync_opts:通過傳遞陣列來指定其他rsync選項。 #
--exclude=*.txt #排除
10 set_remote_user:主要用於ansible預設使用的使用者與rsync使用的'使用者不同的情況
11 mode: push(預設)或pull 模組,push模的話,'一般用於從本機向遠端主機上傳檔案,pull 模式用於從遠端主機上取檔案'
12 src: 要同步到目的地的源主機上的路徑; 路徑可以是絕對的或相對的。如果路徑使用”/”來結尾,則只複製目錄裡的內容,如果沒有使用”/”來結尾,則包含目錄在內的整個內容全部複製
ansible 172.25.70.2 -m synchronize -a ' '
#同步目錄(前提是遠端伺服器上有rsync這個命令)
src=some/relative/path dest=/some/absolute/path rsync_path="sudo rsync"
#排除(#由於這個是rsync命令的引數,所以必須和rsync_opts一起使用)
src=/tmp/helloworld dest=/var/www/helloword rsync_opts=--exclude=.log
mount模組
功能:掛載
mount模組控制/etc/fstab中的活動和配置掛載點
檔案系統的型別:C7(xfs),C6(ext4), C5(ext3)
#1 fstype:必選項,掛載檔案的型別 (nfs檔案共享 fstype=nfs)
#2 name:必選項,'哪個檔案掛載' (可以使用path指定)
#3 opts:傳遞給mount命令的引數(rw,ro)
#4 src:必選項,'掛載到哪的目錄' (nfs)
#5 state:必選項
present:把指定的掛載寫入到fastab中,不會立即掛載,(綠色)
mounted :即寫入檔案,又直接掛載(自動建立掛載點並掛載之)(#推薦)
absent:刪除掛載點 (會清理fastab中的開機掛載)(#推薦)
unmounted:解除安裝(不會清理fastab中的開機掛載)
--------------------------------------------------------------------
1.#服務端和客戶端安裝nfs
[root@m01 ~]# ansible web_group -a 'yum -y install nfs-utils'
[root@m01 ~]# ansible nfs_group -a 'yum -y install nfs-utils'
2.#編輯nfs配置檔案
[root@m01 ~]# ansible 'nfs_group' -m copy -a 'content="/data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)\n" dest=/etc/exports'
3.建立
[root@m01 ~]# ansible nfs_group -a 'mkdir /data'
[root@m01 ~]# ansible nfs_group -m systemd -a 'name=nfs state=started'
4.啟動並設定開機自啟
[root@m01 ~]# ansible web_group -m systemd -a 'name=nfs state=started'
[root@m01 ~]# ansible web_group -m systemd -a 'name=nfs enabled=yes'
[root@m01 ~]# ansible nfs_group -m systemd -a 'name=nfs enabled=yes'
5.掛載
[root@m01 ~]# ansible web01 -m mount -a ''
path=/mnt src=172.16.1.31:/data fstype=nfs state=mounted
name=/mnt/dvd src=/dev/sr0 fstype=iso9660 opts=ro state=present
name=/srv/disk src='LABEL=SOME_LABEL' state=present
name=/home src='UUID=b3e48f45-f933-4c8e-a700-22a159ec9077' opts=noatime state=present
ansible test -a 'dd if=/dev/zero of=/disk.img bs=4k count=1024'
ansible test -a 'losetup /dev/loop0 /disk.img'
ansible test -m filesystem 'fstype=ext4 force=yes opts=-F dev=/dev/loop0'
ansible test -m mount 'name=/mnt src=/dev/loop0 fstype=ext4 state=mounted opts=rw'
6.取消掛載
[root@m01 ~]# ansible web_group -m mount -a 'path=/mnt src=172.16.1.31:/data fstype=nfs state=unmounted'
7.清理/etc/fstab檔案
#UUID就是磁碟的身份證號,不會重複(一般使用UUID的方式掛載)
[root@web ~]# blkid /dev/sda1 檢視UUID(xfs檔案系統)
/dev/sda1: UUID="12722517-ff26-416b-b535-073a95a7a00e" TYPE="xfs"
[root@web ~]# cat /etc/fstab
UUID=5bf16417-9cb6-40eb-80b9-8cc2f715f79f / (根目錄的UUID) xfs defaults 0 0
UUID=12722517-ff26-416b-b535-073a95a7a00e /boot (/bbot目錄的UUID) xfs defaults 0 0
#把本地的磁碟掛載到遠端主機上
[root@Ansible ~]# ansible all -m mount -a "name=/mnt src=/dev/sda3 fstype=xfs state=mounted opts=rw"
#格式化磁碟:
ansible all -m filesystem -a "fstype=ext4 dev=/dev/sdb1"
get_url模組
功能:下載
[root@m01 ~]# ansible-doc get_url
url: http://example.com/path/file.conf #自定下載檔案的URL
dest: /etc/foo.conf #指定下載的目錄
mode: '0440' #指定下載後的許可權
owner
group
force_basic_auth: yes #檔名相同直接覆蓋(預設)
checksum #預設關閉
md5 #md5校驗
sha256 #sha校驗
#遠端連線並下載(序列,速度慢)
[root@m01 ~]# ansible 'web_group' -m get_url -a 'url=http://test.driverzeng.com/Nginx_Code/wordpress-4.9.4-zh_CN.tar.gz dest=/root mode=000'
#校驗MD5並下載(小心等於號,阿里雲不使用md5sum校驗,)
[root@m01 ~]# ansible 'web_group' -m get_url -a 'url=http://test.driverzeng.com/Nginx_Code/wordpress-4.9.4-zh_CN.tar.gz dest=/root mode=000 checksum= md5:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
yum_repository模組
功能:新增,刪除,修改yum源
[root@m01 ~]# ansible-doc yum_repository
yum_repository:
name: epel #不能省略,指定倉庫檔名和倉庫名,自動新增.repo
description: #相當於倉庫內的name註釋
baseurl: https://download.fedoraproject.org/pub/epel/$releasever/$basearch/
file: #指定倉庫檔名(優先順序高),不指定的話倉庫檔名和倉庫名一樣,不能同時在同一個倉庫檔案內新增多個倉庫名不同的倉庫,同時指定的話file=倉庫檔名,name=倉庫名
gpgcheck #是否開啟校驗
yes
no
enabled #是否啟用yum倉庫
yes
no
state
present #建立yum倉庫(預設)
absent #刪除yum倉庫
--------------------------------------------------------
#批量新增yum倉庫,不能一次在某一主機新增多個倉庫檔案和倉庫,功能有限
[root@m01 ~]# ansible 'web_group' -m yum_repository -a 'name=syy_add_epel description=EEE baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=no enabled=yes file=zdy'
#在客戶端已存在的倉庫檔案內新增倉庫(1.指定倉庫檔案。2.指定倉庫名,存在即修改,不存在即新增)
[root@m01 ~]# ansible 'web_group' -m yum_repository -a 'name=syy2_add_epel description=EEE baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=no enabled=yes file=zdy'
--------------------------------------------------------------
#批量刪除yum倉庫,只能一個一個刪除倉庫檔案(也就是說不能只指定name來批量刪除),file優先順序高,可以只指定name,也可以同時指定(視情況而定)
(倉庫檔名和倉庫名要對應,最好都寫上)
[root@m01 ~]# ansible 'web_group' -m yum_repository -a 'name=syy_add_epel file=zdy state=absent'
--------------------------------------------------------------
#修改
不能修改倉庫檔名,也不能修改倉庫名,可以修改URL,gpg,enabled
[root@m01 ~]# ansible 'web_group' -m yum_repository -a 'name=syy_add_epelllll description=EEE baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=no enabled=yes file=1'
也可以修改gpgcheck和enable
[root@m01 ~]# ansible 'web_group' -m yum_repository -a 'name=syy_add_epel description=EEE baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=no enabled=no file=1'
#使用playbook執行yml指令碼,可以實現更精確的操作
ansible服務模組--systemd模組
功能:遠端啟停,過載服務,
[root@m01 ~]# ansible-doc systemd
systemd: #模組
state: started #啟動
name: httpd #指定服務名稱
state: stopped #停止
state: restarted #重啟
state: reloaded #過載配置檔案
enabled=yes #設定開機自啟
daemon_reload # 讀取配置檔案,每次修改了檔案,最好都執行一次,確保應用了(systemd)
masked: #是否將服務設定為masked狀態,被mask的服務是無法啟動的(systemd),(yes|no)預設為no
----------------------------------------------------------------
#遠端停止服務
[root@m01 ~]# ansible 'web_group' -m systemd -a 'name=nginx state=stopped '
#遠端啟動服務(並設定開機自啟動)
[root@m01 ~]# ansible 'web_group' -m systemd -a 'name=nginx state=started enabled=yes '
-------------------------------------------------------------
# 先將服務停止
[root@Ansible ~]# ansible web -m systemd -a "name=httpd state=stopped"
#設定masked
[root@Ansible ~]# ansible web -m systemd -a "name=httpd masked=yes"
# 服務已無法啟動
[root@Ansible ~]# ansible web -m systemd -a "name=httpd state=started"
# 撤銷mask
[root@Ansible ~]# ansible web -m systemd -a "name=httpd masked=no"
# 可以啟動成功
[root@Ansible ~]# ansible web -m systemd -a "name=httpd state=started"
service模組
遠端啟停,過載服務
service模組(可以跨平臺,跨系統) 與systemd模組作用類似,使用命令類似
#1 arguments:給命令列提供一些選項 #
#2 enabled:是否開機啟動 yes|no(預設是no)
#3 name:必選項,服務名稱
#4 pattern:定義一個模式,如果通過status指令來檢視服務的狀態時,沒有響應,就會通過ps指令在程序中根據該模式進行查詢,如果匹配到,則認為該服務依然在執行 #
#5 runlevel:執行級別 #
#6 sleep:如果執行了restarted,在則stop和start之間沉睡幾秒鐘
#7 state:對當前服務執行啟動,停止、重啟、重新載入等操作(started,stopped,restarted,reloaded)
#保持服務啟動並設定為開機自啟
ansible web_group -m service -a 'enabled=yes name=httpd state=started'
ansible使用者組管理模組
功能:建立使用者組
[root@m01 ~]# ansible-doc group
name: somegroup #指定組名
state: present #建立(預設,課省略)
state: absent #刪除
gid #指定建立的組的gid
#遠端建立組
[root@m01 ~]# ansible 'web_group' -m group -a 'name=dd gid=233 state=present'
#遠端刪除組
[root@m01 ~]# ansible 'web_group' -m group -a 'name=dd gid=233 state=absent'
ansible使用者管理模組
功能:管理遠端主機上的使用者,比如建立使用者、修改使用者、刪除使用者、為使用者建立金鑰對等操作
#user模組是請求的是useradd, userdel, usermod三個指令,goup模組請求的是groupadd, groupdel, groupmod 三個指令。
groups: #修改附加組為
append=no #預設,覆蓋(相當於usermod -G)
append=yes #追加(相當於usermod -aG)
uid: #指定用的uid
group: #指定主組
password: #明文密碼進行雜湊後的字串,你可以在 python 的命令提示符下輸入如下命令,生成明文密碼對應的加密字串 "import crypt; crypt.crypt('666666')"
update_password:
always: #只有當密碼不相同時才會生效,即修改密碼(預設) #
on_create: #只為新使用者設定密碼
name: #指定使用者名稱
system: #是否為系統使用者 yes|no(預設是no)
remove: #當state=absent時,remove=yes則表示連同家目錄,郵件目錄一起刪除,等價於userdel -r(預設是no)
state:
absent #刪除使用者
remove=no #預設,刪除使用者時,不會刪除使用者的家目錄等資訊
remove=yes #刪除使用者的同時,會刪除使用者的家目錄,郵件目錄
present #建立使用者(預設)
shell: #指定使用者的shell環境(預設是/bin/bash)
expires: #設定使用者的過期時間,值是一個時間戳(轉化命令:date -d 2018-12-31 +%s,命令列設定 expires=)
comment: #建立使用者的時候新增一段註釋
generate_ssh_key: yes #建立公鑰(預設)
ssh_key_bits: 2048 #指定公鑰長度
ssh_key_file: .ssh/id_rsa #建立私鑰(建立使用者的家目錄下)
create_home=false #是否建立家目錄(預設建立true)
------------------------------------------------------------------------
#建立使用者,修改使用者
ansible 'web_group' -m user -a ' '
name=ll
name=hh comment="zhushi" uid=1040 group=adm #該組必須存在
name=hh shell=/bin/bash groups=adm,lp append=yes
name=hh state=absent remove=yes
name=hh expires=1422403387
name=hh generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa
name="testops" password="$6$0lwTSmqKOkL.ktgl$OnBexXC7haBf0FRHVMIZM2edDeFWBbpKJ2r9cxVwNvY.vh3IIUzwFz8n7jFglc0CrtQSY12ziDonVL6e71Og2."
--------------------------------------------------------------
#生成金鑰時,只會生成公鑰檔案和私鑰檔案,和直接使用ssh-keygen指令效果相同,不會生成authorized_keys檔案。複製id_rsa.pub貼上為authorized_keys檔案即可使用
name=test generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=~/.ssh/id_rsa
-----------------------------------------------------------------------
#指定password引數時,不能使用後面這一串密碼會被直接傳送到被管理主機的/etc/shadow檔案中,所以需要先將密碼字串進行加密處理。然後將得到的字串放到password中即可。
#1.加密
[root@ansible-manager ~]# python
>>> import crypt;crypt.crypt('666666')
'$6$ziT/sb5KRtUaxoq7$ulfHVLqVgXfmfFUYY7FppzqBQMUYd.2GLDyQwmKv4dYAd0zpgtt5JDheoO/OvvTvY53x9UShX.PtHykJEvsmG0'
#2.建立使用者指定密碼 或 修改使用者密碼
------------------------------------------------------------------
#刪除使用者
#注意該使用者下不能有任何程序,否則會報錯(但是能刪除的都刪除了)
ansible 'web_group' -m user -a ' '
name=ll state=absent remove=yes
fetch
[root@m01 ~]# ansible web01 -m fetch -a "src=/root/lol.txt dest=/root"
壓縮解壓unarchive模組
功能:解壓縮
1、解壓ansible管理機上的壓縮檔案到遠端主機:
ansible all -m unarchive -a "src=/tmp/install/zabbix-3.0.4.tar.gz dest=/tmp/ mode=0755 copy=yes"
2、解壓遠端主機上的檔案到目錄:
#ansible all -m unarchive -a "src=/tmp/install/zabbix-3.0.4.tar.gz dest=/tmp/ mode=0755 copy=no"
#copy:預設為yes,當copy=yes,那麼拷貝的檔案是從ansible主機複製到遠端主機上的,如果設定為copy=no,那麼會在遠端主機上尋找src原始檔
#src:源路徑,可以是ansible主機上的路徑,也可以是遠端主機上的路徑,如果是遠端主機上的路徑,則需要設定copy=no
#dest:遠端主機上的目標路徑
selinux
功能:管理selinux
C6想要使用這種方式關閉selinux的話,需要安裝 libselinux-python(改過要重啟生效)
不能使用systemd service模組來管理selinux systemd
state:
enforcing #永久開啟
permissive #臨時開啟(預設)
disabled #禁用
#修改配置檔案關閉selinux(永久關閉),必須重啟
[root@m01 ~]# ansible web_group -m selinux -a 'state=disabled' -i ./hosts
#臨時關閉
[root@m01 ~]# ansible web_group -m shell -a 'setenforce 0' -i ./hosts
#檢視
[root@m01 ~]# ansible web_group -m shell -a 'getenforce' -i ./hosts
# 如果修改了/etc/selinux/config檔案的話,需要重啟,如果你只是臨時修改的話,不需要重啟
# 使用setenforce 可以臨時改變selinux的狀態,不需要重啟系統。但是系統重啟後,配置失效,因為系統重啟後,是根據/var/selinux/config的配置內容進行功能設定的
firewalld
功能:管理firewalld
開啟才能關閉
service #指定開放或關閉的服務名稱(http https)
port #指定開放或關閉的埠(-)
permanent #是否新增永久生效(permanent=no即為臨時生效) #
immediate #臨時生效
state
enabled #永久開啟
disabled #永久關閉
zone #指定配置某個區域
rich_rule #配置輔規則
masquerade #開啟地址偽裝
source #指定來源IP
#service指定服務(需要提前開啟防火牆)
[root@m01 ~]# ansible web_group -m firewalld -a 'service=http permanent=yes state=enabled' -i ./hosts
[root@m01 ~]# ansible web_group -m firewalld -a "service=https permanent=yes state=enabled" -i ./hosts
#service指定埠(某些服務系統自動開啟)
[root@m01 ~]# ansible web_group -m firewalld -a "port=8080-8090/tcp permanent=yes state=enabled" -i ./hosts
lineinfile
功能:lineinfile模組用於確保一個特定的行在一個檔案中,或使用一個正則表示式替換現有的行
如果想要改變檔案中相似的多行,可以使用replace模組。如果想要插入、更新、刪除一個行塊,可以使用blockinfile模組
#(1)文字替換
#將/etc/selinux/config檔案中所有匹配^SELINUX=正則表示式的行中的最後一行使用SELINUX=disabled替換
#如果regexp不匹配檔案中的任何一行,則將line所指定的行插入到檔案的末尾
[root@Ansible ~]# ansible web -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled'"
#(2)刪除行
#將/tmp/test.sh檔案中所有匹配^pwd的行刪除
[root@Ansible ~]# ansible web -m lineinfile -a "path=/tmp/test.sh regexp='^pwd' state=absent"
#(3)替換行並設定檔案許可權
[root@Ansible ~]# ansible web -m lineinfile -a "path=/etc/hosts regexp='^127.0.0.1' line='127.0.0.1 localhost' owner=root group=root mode=0644"
stat模組
功能:stat模組獲取遠端檔案狀態資訊,包括atime、ctime、mtime、md5、uid、gid等
#(1)顯示檔案的所有資訊
[root@Ansible ~]# ansible web -m stat -a "path=/etc/sysctl.conf"
#(2)顯示MD5值
[root@Ansible ~]# ansible web -m stat -a "path=/etc/sysctl.conf get_md5=yes"
mysql_user模組
功能:主控端對被控端mysql伺服器 新增刪除使用者,授權遠端使用者登入,訪問
mysql_user模組引數
login_host=“localhost” 指定本地root使用者登入本機mysql
login_password=“123.com” root使用者的登入密碼 #登入密碼
login_user=“root” 為root使用者或者mysql使用者 #登入使用者
login_port=“3306” 資料庫埠號
name="" 指定grant授權使用者 #建立使用者的名字或是已存在的使用者
password="" grant授權使用者密碼 #給新使用者設定密碼,或者修改密碼
priv="" 庫名.SQL語句許可權,GRANT #資料庫.資料表:許可權1,許可權2(要用")
host="" 授權遠端登入的IP地址,一般為 網段.% 或者直接 %
state=“present” 建立授權使用者
state=“absent” 刪除授權使用者
ahdoc模式寫法建立授權使用者,驗證模組正確時使用
[root@localhost ansible]# ansible mysql -m mysql_user -a "login_host=% login_password=123.com login_user=root login_port=3306 name=ty_user password=1 priv=".:ALL,GRANT" host='%' state=present"
playbook劇本寫法建立授權使用者,執行自動化部署時使用
- hosts: mysql_group
remote_user: root
tasks:
- name: grant mysql user
mysql_user:
login_host: "localhost"
login_user: "root"
login_password: "123.com"
login_port: "3306"
name: "ty"
password: "123.com"
host: "%"
priv: "*.*:ALL,GRANT"
state: "present"
mysql_db模組
功能:用於建立、刪除、匯入和匯出資料庫
#建立資料庫
hosts: mysql_group
tasks:
- name: create a database
mysql_db:
login_host: "127.0.0.1"
login_user: "root"
login_password: "mysql@123"
login_port: "3306"
name: "mezz"
encoding: "utf8"
state: "present"
#刪除資料庫
hosts: mysql_group
tasks:
- name: delete a database
mysql_db:
login_host: "127.0.0.1"
login_user: "root"
login_password: "mysql@123"
login_port: "3306"
name: "mezz"
state: "absent"
#匯出資料庫
hosts: mysql_group
tasks:
- name: dump a database
mysql_db:
login_host: "127.0.0.1"
login_user: "root"
login_password: "mysql@123"
login_port: "3306"
name: "mezz"
target: "/tmp/mezz.gz"
state: "dump"
#匯入資料庫
hosts: mysql_group
tasks:
- name: import a database
mysql_db:
login_host: "127.0.0.1"
login_user: "root"
login_password: "mysql@123"
login_port: "3306"
name: "mezz"
target: "/tmp/mezz.gz"
state: "import"
template模組
template
模組使用了Jinjia2
模版語言,進行文件內變數的替換的模組。
該模組只能在playbook中執行,不能使用命令列
功能:該模組和copy模組作用基本一樣,都是把某個檔案複製到遠端主機上,但是區別在於template模組可以獲取變數的值,而copy則是原封不動的把檔案內容複製過去
改變數的呼叫依賴於facts,關閉fascs的話,該模組作用將於copy模組相同
#問題:由於每臺伺服器cpu數量不一樣,沒辦法來靈活配置Nginx最大程序數
– backup: 如果原目標檔案存在,則先備份目標檔案
– src:在ansible控制器上的Jinja2格式化模板的路徑。 這可以是相對或絕對的路徑。
– dest:將模板渲染到遠端機器上的位置。
force:是否強制覆蓋,預設為yes
– owner:目標檔案屬主
– group:目標檔案屬組
– mode:目標檔案的許可權模式
# Example from Ansible Playbooks
- template:
src: /mytemplates/foo.j2
dest: /etc/file.conf
owner: bin
group: wheel
mode: 0644
pam_limits模組
功能:修改檔案描述符
#為使用者joe新增或修改nofile軟限制
- pam_limits:
domain: joe
limit_type: soft
limit_item: nofile
value: 64000
# 為使用者smith新增或修改硬限制。保持或設定最大值。
- pam_limits:
domain: smith
limit_type: hard
limit_item: fsize
value: 1000000
use_max: yes
#為使用者james新增或修改memlock,包括軟硬限制和註釋。
- pam_limits:
domain: james
limit_type: '-'
limit_item: memlock
value: unlimited
comment: unlimited memory lock for james
參考
http://www.linuxe.cn/post-275.html Ansible教程(3)playbook的基本使用
https://www.fdevops.com/2020/03/08/ansible-quick-tutorial Ansible中Playbook的光速教程
https://juejin.cn/post/6844903631066513421 ansible自動化運維詳細教程及playbook詳解