批量管理服務器的工具,無需部署代理,通過ssh進行管理,是python寫的
ansible 常用模塊 :
(1)shell命令模塊執行命令
(2)copy模塊批量下發文件或文件夾
(3)script模塊批量運行腳本
Python3與ansible的安裝
使用源碼安裝Python3.5
#安裝支持包 yum -y install lrzsz vim net-tools gcc gcc-c++ ncurses ncurses-devel unzip zlib-devel zlib openssl-devel openssl #源碼編譯Python3.5 tar xf Python-3.5.2.tgz -C /usr/src/ cd /usr/src/Python-3.5.2/ ./configure --prefix=/usr/local/python/;make ;make install ln -s /usr/local/python/bin/python3 /usr/bin/python3
python3 -V Python 3.5.2
使用pip3安裝ansible
/usr/local/python/bin/pip3 install ansible ln -s /usr/local/python/bin/ansible /usr/local/bin/ ansible --version ansible 2.6.3 config file = None configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/local/python/lib/python3.5/site-packages/ansible executable location = /usr/local/bin/ansible python version = 3.5.2 (default, Sep 2 2018, 22:56:37) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
使用公私鑰實現SSH無密碼登陸
ansible是無代理的,主要是借用ssh來批量管理服務器.ssh默認登陸是需要密碼的,所以管理起來比較麻煩.SSH無密碼登陸實現以后,使用ansible批量管理服務器就變得簡單了。
ansible |
192.168.50.16 |
主機1 | 192.168.50.168 |
主機2 | 192.168.50.176 |
#生成密鑰對 ssh-keygen -t rsa -f ~/.ssh/id_rsa -P "" #分發密鑰 yum -y install sshpass #安裝sshpass sshpass -p 123456 ssh-copy-id -i ~/.ssh/id_rsa.pub "-o StrictHostKeyChecking=no" 192.168.50.168
免密碼 密碼 上傳公鑰 免交互 去往的主機
#進行免密碼登陸測試 ssh 192.168.50.176 hostname -I 192.168.50.176
ansible的簡單配置和模塊
ansible的配置文件
通過PIP安裝的ansible是沒有配置文件的。我們需要創建一個
mkdir -p /etc/ansible vim /etc/ansible/hosts #ansible主機管理配置文件 [zhujizu] #被管理的主機組名稱 webA ansible_ssh_host=192.168.50.168 ansible_ssh_port=22 ansible_ssh_user=root #第一台主機 webB ansible_ssh_host=192.168.50.176 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass=123456 #第二台主機
主機名 定義主機IP ssh的默認端口號 以什么身份管理 如果沒有上傳公鑰需要指定連接密碼
ansible語法:ansible -i /etc/ansible/hosts 主機或主機組 -m 指定模塊 -a 命令
不用-i指定配置文件默認為在/etc/ansible/hosts
主機組,主機,all代表所有
進行命令測試:
ansible zhujizu -m ping #ping整個組 zhuji2 | SUCCESS => { #連接成功 "changed": false, "ping": "pong" } zhuji1 | SUCCESS => { "changed": false, "ping": "pong" }
ansible zhuji1 -m ping #只ping 主機1 zhuji1 | SUCCESS => { "changed": false, "ping": "pong" }
ansible all -m ping #ping 配置文件的所有 zhuji2 | SUCCESS => { "changed": false, "ping": "pong" } zhuji1 | SUCCESS => { "changed": false, "ping": "pong" }
ansible的三個命令模塊
ansible模塊command(不支持管道,不建議使用) #需要python支持,一般都有python
ansible模塊shell(支持管道,支持重定向,常用) #需要python支持,一般都有python
ansible模塊raw,最原始的方式運行命令(不依賴python,僅通過ssh實現)
ansible all -m shell -a "echo hehe >>/root/wk" #在所有主機執行輸出hehe並重定向到wk文件
zhuji1 | SUCCESS | rc=0 >> zhuji2 | SUCCESS | rc=0 >> cat /root/wk #查看wk文件 hehe
ansible的copy模塊批量下發文件或文件夾
copy模塊概述
copy模塊的參數,ansible 主機組 -m 模塊 -a 命令
- src:指定源文件或目錄
- dest:指定目標服務器的文件或目錄
- backup:是否要備份
- owner:拷貝到目標服務器后,文件或目錄的所屬用戶
- group:拷貝到目標服務器后,文件或目錄的所屬群組
- mode:文件或目錄的權限
所有被管理端節點必須安裝libselinux-python包
yum -y install libselinux-python
copy模塊拷貝文件
ansible all -m copy -a "src=/root/server/txt dest=/root/server/"
# 源文件 目標目錄(如果目標沒有目錄可自動創建)如果目標路徑里有與我拷貝的文件同名文件的話,會直接覆蓋目標路徑下的文件
copy模塊拷貝目錄下所有文件
ansible all -m copy -a "src=/root/server/ dest=/root/server/"
源目錄下所有 目標目錄
copy模塊自動備份
backup=yes ===>意思是,如果目標路徑下,有與我同名但不同內容的文件時,在覆蓋前,對目標文件先進行備份。
ansible all -m copy -a "src=/root/server/ dest=/root/server/ backup=yes"
copy模塊指定用戶和屬主
ansible all -m copy -a "src=/service/scripts/ dest=/service/scripts/ owner=nobody group=nobody mode=0600"
屬主 屬組 權限
ansible的script模塊批量運行腳本
ansible的script模塊能夠實現遠程服務器批量運行本地的shell腳本。
#遠程批量分發並自動部署nginx #所有被管理端都能使用yum pwd /root/server ls |xargs -n1 nginx-1.14.0.tar.gz #nginx源碼包 nginx-anzhuang.sh #自動安裝nginx腳本 vim /root/server/nginx-anzhuang.sh #安裝nginx腳本 #!/bin/sh #nginx install shell scripts test -d /media/cdrom || mkdir -p /media/cdrom mount /dev/sr0 /media/cdrom &>/dev/null yum -y install gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl openssl-devel &>/dev/null test -d /service/scripts || exit 3 cd /service/scripts/ tar xf nginx-1.14.0.tar.gz -C /usr/src/ cd /usr/src/nginx-1.14.0/ ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module &>/dev/null make &>/dev/null make install &>/dev/null exit 0 vim /root/fenfa.sh #批量分發腳本 #!/bin/sh #批量分發腳本 Group=$1 ansible $Group -m copy -a "src=/root/server/ dest=/service/scripts/" ansible $Group -m script -a "/usr/bin/sh /service/scripts/nginx-anzhuang.sh" ~ sh /root/fenfa.sh all #激活腳本
ansible-playbook(劇本)
playbook的使用,playbook可以把ansible的模塊進行組合,然后執行每個模塊
ln -s /usr/local/python/bin/ansible-playbook /usr/local/bin/ #設置playbook的環境變量
playbook的格式 #ansible是python寫的,python很注重格式,因此playbook也很注重格式
vim hehe.yaml #playbook的執行模板 結尾必須以.yaml --- #開頭三個小-開頭 - hosts: zhuji2 tasks: - name: test shell: echo "welcome to yunjisaun" >> /tmp/username - name: test2 shell: echo "welcome to yunjisuan" >> /tmp/username
模板說明: --- #開頭必須有三個小-,頂格寫 - hosts: #正文配置代碼的第一級,必須有兩個空格(-占一個空格位) - host: webB #webB是host參數的值,值和hosts:之間要有一個空格 tasks: #tasks:表示接下來要執行的具體任務 - name: #相對於tasks再多縮進兩個格(-占一個空格位),表示屬於tasks的下一級 - name: test #test只是要執行的具體命令的名字可以隨便寫。name:后還是有一個空格要注意 shell: #表示調用shell模塊執行命令相對於tasks仍舊要多縮進兩個空格 shell: echo "xxx" >> xxx #shell:后邊還是要有個空格,需要注意。
執行playbook配置文件
ansible-playbook hehe.yaml
playbook的簡單copy模塊的使用
vim hehe.yaml --- - hosts: zhuji2 tasks: - name: test copy: src=/etc/passwd dest=/root
--- - hosts: zhuji2 tasks: - name: test shell: echo "quzhongrensan" register: i #把shell的命令結果保存在變量i里 變量可以是任意字符 - debug: var=i #debug輸出變量i debug和var是固定格式
playbook使用register輸出命令運行結果
我們在用playbook進行ansible模塊操作的時候,並沒有命令的執行結果輸出,默認被隱藏了。
我們可以通過register模塊最加輸出命令的執行結果
playbook的自定義變量和內置變量
在Playbook中使用自定義變量
vim hehe.yaml
--- - hosts: zhuji2 vars: #定義變量 - xixi: "xxiixxii" #變量xixi=xxiixxii - hehe: "hheehhee" #變量hehe=hheehhee tasks: - name: xixi shell: echo "{{ xixi }},{{ hehe }}" #調用變量{{ xixi }}固定格式 兩個{{}} 變量名與括號間必須有空格 register: i - debug: var=i
#在使用自定義變量時,我們要特別注意不要和系統的內置保留變量同名,容易引發問題。 定義變量名最好開頭字母用大寫
在playbook中使用ansible內置變量
我們可以使用ansible all -m setup | less查看ansible內置變量
--- - hosts: all gather_facts: True #使用ansible內置變量 tasks: - name: setup var shell: echo "ip {{ ansible_all_ipv4_addresses[0] }} cpu {{ ansible_processor_count }}" register: var_result - debug: var=var_result
Playbook下發可變配置文件
配置文件如果使用copy模塊去下發的話,那配置都是一樣的;
如果下發的配置文件里有可變的配置,需要用到template模塊。
利用template模塊下發可變的配置文件
vim /root/server/txt #編輯將要發送的文件 文件內使用變量 my name is {{ hehe }} #自定義變量 my name is {{ ansible_all_ipv4_addresses[0] }} #系統變量 vim /root/hehe.yaml #編寫發送文件txt的劇本 --- - hosts: zhuji2 gather_facts: True #調用ansible系統變量 vars: #設置自定義變量 - hehe: "hheehhee" tasks: - name: xixi template: src=/root/server/txt dest=/root/txt #使用template下發可變配置文件 cat txt #查看主機2收到的txt文件,里邊已經成功的使用了變量 my name is hheehhee my name is 192.168.50.176
下發配置文件里面使用判斷語法
vim /root/server/txt {% if PORT %} #if PORT存在 ip=0.0.0.0:{{ PORT }} {% else %} #否則 ip=0.0.0.0:80 {% endif %} #結尾 vim /root/hehe.yaml --- - hosts: zhuji2 gather_facts: True vars: - PORT "80" tasks: - name: xixi template: src=/root/server/txt dest=/root/txt
Playbook的notify通知和下發nginx配置
#實戰下發可執行動作的可變的nginx配置文件 head -1 /tmp/nginx.j2 worker_processes {{ ansible_processor_count }}; #可變的參數 cat test_nginxvars.yaml --- - hosts: all gather_facts: True #開啟系統內置變量 tasks: - name: nginx conf template: src=/tmp/nginx.j2 dest=/usr/local/nginx/conf/nginx.conf notify: - reload nginx #下發通知給handlers模塊執行名字叫做reload nginx的動作 handlers: #定義動作 - name: reload nginx #動作的名字 shell: /usr/local/nginx/sbin/nginx -s reload ansible-playbook test_nginxvars.yaml
使用roles標准化Playbook
roles功能可以用來規范playbook的編寫
創建所需要的roles原型目錄結構
tree rolesbzh/ 標准化目錄 rolesbzh/ ├── nginx.retry #文件:/etc//ansible/hosts里的主機名 ├── nginx.yam #文件:觸發器,用來觸發roles內的不同劇本 └── roles #目錄:里面存放不同的劇本目錄 └── nginx #目錄:存放nginx劇本相關模塊 ├── files #目錄:files存放copy模塊和script模塊的參數src默認會從這個文件夾查找 │ ├── test #要上傳的文件 │ └── test.sh #需要在目標主機執行的腳本 ├── handlers #用來存放notify的 │ └── main.yaml ├── tasks #用來存放ansible任務的模塊,ansible會根據里面寫的執行過程進行劇本的執行 │ └── main.yaml ├── templates #template模塊的使用,用來存放可變配置文件j2的 │ └── test.j2 └── vars #用來存放變量的 └── main.yaml
入口觸發配置文件
ansible-playbook執行入口配置文件nginx.yaml后,它會自動在roles目錄下查找nginx目錄並進入后查找tasks任務目錄並執行main.yaml的任務配置文件。
cat /root/rolesbzh/nginx.yaml --- - hosts: all #執行的主機范圍 gather_facts: True #開啟系統內置變量 roles: #啟用roles原型配置 - nginx #執行nginx原型模組,即roles里的nginx劇本
roles中tasks任務編排模組的使用
#在nginx模組添加tasks任務配置文件 vim /root/rolesbzh/roles/nginx/tasks/main.yaml --- - name: ping #任務1的名字 ping (名字可有可無可隨意) ping: #執行ping - name: 執行shell #任務2的名字 執行shell shell: ls / #執行ls查看跟目錄 register: i #將執行的結果帶入一個變量i內 - debug: var=i #將變量i輸出出來 - name: 變量 #任務3的名字 變量 shell: echo my name is {{ my_name }},{{ qq }} #執行命令可調用vars變量 register: I #將執行的結果帶入一個變量I內 - debug: var=I #將變量I輸出出來 - name: copy #任務4的名字 copy copy: src=test dest=/root/ #將files目錄下的test移動到目標主機的root下 - name: script #任務5的名字 script script: test.sh #在目標主機執行files目錄下的test.sh腳本 - name: 可變配置文件 #任務6的名字 可變配置文件 template: src=test.j2 dest=/root/text1 #將templates目錄下的test.j2文件移動到目標主機root目錄下改名為text1 並將變量變為值 notify: reload #如果template發生變化則執行handles里的動作,如果template沒有發生變化則不執行handles里的動作
roles中vars自定義變量模組的使用
#創建自定義變量vars模組的配置文件 vim /root/rolesbzh/roles/nginx/vars/main.yaml --- my_name: wk #變量my_name值wk qq: 224901 #變量qq值224901
使用copy,script模塊的標准化
roles模型里使用copy,script模塊,默認從roles/nginx/files這里面找
vim //root/rolesbzh/roles/nginx/files/test #files存放的文件 生死闊契 vim /root/rolesbzh/roles/nginx/files/test.sh #files存放的腳本 files里的腳本在客戶機執行完后會自行刪除,等於無痕執行了一次腳本
echo "與子成說" > /tmp/test
chmod +x roles/nginx/files/test.sh
roles中template模塊的使用
roles模型里使用template模塊,默認從roles/nginx/template里面找
vim /root/rolesbzh/roles/nginx/templates/test.j2 my name is {{ my_name }},my qq {{ qq }},my ip {{ansible_all_ipv4_addresses[0]}} #引用自定義變量和內置變量
roles中notify模塊的使用
roles使用notify模塊,默認從roles/nginx/handles里面找
vim /root/rolesbzh/roles/nginx/handlers/main.yaml
--- - name: start #定義handlers的動作類型 shell /usr/local/nginx/sbin/nginx - name; stop #定義handlers的動作類型 shell /usr/local/nginx/sbin/nginx -s stop - name; reload #定義handlers的動作類型 shell /usr/local/nginx/sbin/nginx -s reload
notify下發通知只有當之前的任務造成了變化那么才會被執行,如果沒有發生任何改變,則notify不會被執行。