Ansible

首先咱們安裝一個ansible。python

在7版本,直接用yum安裝就能夠linux

yum -y install ansible

而後清空ansible的配置文件,在裏面寫入本身須要管理的服務器的ip和相應的登錄密碼nginx

[root@localhost ~]# cat /etc/ansi
[root@localhost ~]# cat /etc/ansible/hosts 
[test]
web1 ansible_ssh_host=192.168.200.131 ansible_ssh_pass=mima 
web2 ansible_ssh_host=192.168.200.133 ansible_ssh_pass=mima
[root@localhost ~]# 

ansible的批量運行的腳本c++

 

[root@localhost scripts]# pwd
/server/scripts
[root@localhost scripts]# vim auto_nginx.shweb


#!/bin/bash dir=/media/cdrom anzhuang=/server/scripts [ -d $dir ] || mkdir -p $dir umount /dev/sr0 mount /dev/sr0 $dir &>/dev/null yum -y install gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl openssl-devel &>/dev/null [ -d $anzhuang ] || mkdir -p $anzhuang cd /server/scripts/ tar xf nginx-1.10.2.tar.gz -C /usr/src/ cd /usr/src/nginx-1.10.2/ ./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
 

寫分發腳本shell

 
[root@localhost scripts]# vim fenfa.sh

#!/bin/bash
Group=$1
dir=/server/scripts/vim

ansible $Group -m shell -a "mkdir -p $dir"
ansible $Group -m copy -a "src=$dir dest=$dir"
ansible $Group -m script -a "/server/scripts/auto_nginx.sh"bash

而後激活腳本服務器

[root@localhost scripts]# sh fenfa.sh all less

 

若是copy報錯一下的語句

  "msg": "Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"

 

須要在備分發的服務器上安裝支持包

[root@www ~]# mount /dev/sr0 /media/cdrom/
mount: block device /dev/sr0 is write-protected, mounting read-only
[root@www ~]# yum -y install libselinux-python

ansible的劇本playbook

 
[root@ansible scripts]# cat test_shell.yaml  #playbook的執行模板
---         #開頭三個小-開頭
- hosts: webB   
  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:後邊仍是要有個空格,須要注意。
 

執行劇本

 
[root@ansible scripts]# ansible-playbook test_shell.yaml #執行playbook配置文件
PLAY [webB] ********************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
ok: [webB]
TASK [test] ********************************************************************************************************
changed: [webB]
TASK [test2] *******************************************************************************************************
changed: [webB]
PLAY RECAP *********************************************************************************************************
webB                       : ok=3    changed=2    unreachable=0    failed=0 
 

簡單的copy劇本

 
[root@ansible scripts]# echo "welcom to yunjisuan" >> /tmp/test_copy
[root@ansible scripts]# cat test_copy.yaml 
---
- hosts: all
  tasks:
  - name: test copy
    copy: src=/tmp/copy_test dest=/tmp/
[root@ansible scripts]# ansible-playbook /service/scripts/test_copy.yaml 
PLAY [all] *********************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
ok: [webA]
ok: [webB]
TASK [test copy] ***************************************************************************************************
changed: [webA]
changed: [webB]
PLAY RECAP *********************************************************************************************************
webA                       : ok=2    changed=1    unreachable=0    failed=0   
webB                       : ok=2    changed=1    unreachable=0    failed=0   
 

劇本的查看輸出的過程

咱們在用playbook進行ansible模塊操做的時候,並無命令的執行結果輸出,默認被隱藏了。 
咱們能夠經過register模塊最加輸出命令的執行結果

 
[root@ansible scripts]# cat test_register.yaml 
---
- hosts: all
  tasks:
  - name: test register
    shell: echo "welcome to yunjisuan"
    register: print_result          #將以前命令的輸出結果保存在變量print_result裏
  - debug: var=print_result         #將變量的值做爲debug輸出出來。
[root@ansible scripts]# ansible-playbook test_register.yaml 
PLAY [all] *********************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
ok: [webA]
ok: [webB]
TASK [test register] ***********************************************************************************************
changed: [webA]
changed: [webB]
TASK [debug] *******************************************************************************************************
ok: [webA] => {                                             #命令的執行結果有輸出了
    "print_result": {
        "changed": true,
        "cmd": "echo \"welcome to yunjisuan\"",
        "delta": "0:00:00.002269",
        "end": "2018-06-15 10:28:14.693883",
        "failed": false,
        "rc": 0,
        "start": "2018-06-15 10:28:14.691614",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "welcome to yunjisuan",
        "stdout_lines": [
            "welcome to yunjisuan"
        ]
    }
}
ok: [webB] => {
    "print_result": {
        "changed": true,
        "cmd": "echo \"welcome to yunjisuan\"",
        "delta": "0:00:00.002633",
        "end": "2018-06-15 10:28:14.710242",
        "failed": false,
        "rc": 0,
        "start": "2018-06-15 10:28:14.707609",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "welcome to yunjisuan",
        "stdout_lines": [
            "welcome to yunjisuan"
        ]
    }
}
PLAY RECAP *********************************************************************************************************
webA                       : ok=3    changed=1    unreachable=0    failed=0   
webB                       : ok=3    changed=1    unreachable=0    failed=0   
 

配置文件下發的簡單劇本

 
[root@ansible scripts]# cat test_nginx_conf.yaml 
---
- hosts: all
  tasks:
  - name: copy nginx.conf
    copy: src=/tmp/nginx.conf dest=/usr/local/nginx/conf/ backup=yes
  - name:
    shell: /usr/local/nginx/sbin/nginx -t
    register: nginx_result
  - debug: var=nginx_result
 

在劇本中使用自定義變量

 
[root@localhost scripts]# cat test_vars.yaml 
---
- hosts: all
  vars:         #定義變量
  - name: "yunjisuan"   #第一個name變量
    age: "3"            #第二個age變量
  tasks:
  - name: "{{ name }}"      #{{}}兩對大括號引用變量,變量名兩頭空格
    shell: echo "myname {{ name }},myage {{ age }}"
    register: var_result
  - debug: var=var_result
特別提示:
引用變量須要在雙引號中引用。
[root@localhost scripts]# ansible-playbook /service/scripts/test_vars.yaml 
 [WARNING]: Found variable using reserved name: name        #這裏提示,name是一個保留的內置變量,咱們在自定義時不能用
PLAY [all] *********************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
ok: [webA]
ok: [webB]
TASK [yunjisuan] ***************************************************************************************************
changed: [webA]
changed: [webB]
TASK [debug] *******************************************************************************************************
ok: [webA] => {
    "var_result": {
        "changed": true,
        "cmd": "echo \"myname yunjisuan,myage 3\"",
        "delta": "0:00:00.002320",
        "end": "2018-06-19 10:45:16.175728",
        "failed": false,
        "rc": 0,
        "start": "2018-06-19 10:45:16.173408",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "myname yunjisuan,myage 3",
        "stdout_lines": [
            "myname yunjisuan,myage 3"
        ]
    }
}
ok: [webB] => {
    "var_result": {
        "changed": true,
        "cmd": "echo \"myname yunjisuan,myage 3\"",
        "delta": "0:00:00.002518",
        "end": "2018-06-19 10:45:10.552331",
        "failed": false,
        "rc": 0,
        "start": "2018-06-19 10:45:10.549813",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "myname yunjisuan,myage 3",
        "stdout_lines": [
            "myname yunjisuan,myage 3"
        ]
    }
}
PLAY RECAP *********************************************************************************************************
webA                       : ok=3    changed=1    unreachable=0    failed=0   
webB                       : ok=3    changed=1    unreachable=0    failed=0   
#咱們修改一下name這個變量再發送,就不會出警告了
[root@localhost scripts]# cat test_vars.yaml 
---
- hosts: all
  vars:
  - names: "yunjisuan"
    age: "3"
  tasks:
  - name: "{{ names }}"
    shell: echo "myname {{ names }},myage {{ age }}"
    register: var_result
  - debug: var=var_result
在使用自定義變量時,要特別注意不要和系統的內置保留變量同名,容易引起問題。
 

使用內置的變量

咱們可使用ansible all -m setup | less查看ansible內置變量
 
[root@localhost scripts]# cat test_setupvars.yaml 
---
- 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
[root@localhost scripts]# 
[root@localhost scripts]# ansible-playbook test_setupvars.yaml 
PLAY [all] *********************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************
ok: [webA]
ok: [webB]
TASK [setup var] ***************************************************************************************************
changed: [webA]
changed: [webB]
TASK [debug] *******************************************************************************************************
ok: [webA] => {
    "var_result": {
        "changed": true,
        "cmd": "echo \"ip 192.168.200.132 cpu 1\"",
        "delta": "0:00:00.002408",
        "end": "2018-06-19 11:32:44.540658",
        "failed": false,
        "rc": 0,
        "start": "2018-06-19 11:32:44.538250",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "ip 192.168.200.132 cpu 1",
        "stdout_lines": [
            "ip 192.168.200.132 cpu 1"
        ]
    }
}
ok: [webB] => {
    "var_result": {
        "changed": true,
        "cmd": "echo \"ip 192.168.200.138 cpu 1\"",
        "delta": "0:00:00.002102",
        "end": "2018-06-19 11:32:44.526875",
        "failed": false,
        "rc": 0,
        "start": "2018-06-19 11:32:44.524773",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "ip 192.168.200.138 cpu 1",
        "stdout_lines": [
            "ip 192.168.200.138 cpu 1"
        ]
    }
}
PLAY RECAP *********************************************************************************************************
webA                       : ok=3    changed=1    unreachable=0    failed=0   
webB                       : ok=3    changed=1    unreachable=0    failed=0   
 

去內置變量的操做

 
[root@localhost scripts]# cat test_setupvars.yaml
---
- hosts: all
  gather_facts: True
  tasks:
  - name: setup var
    shell: echo "ip {{ ansible_all_ipv4_addresses[0] }} cpu {{ ansible_processor_count }}" >> /tmp/test
  - name: setup var2
    shell: echo "time {{ ansible_date_time["date"] }}" >> /tmp/test
    register: var_result
  - debug: var=var_result
 

利用template模塊下發可變的變量配置

 
[root@localhost scripts]# cat /tmp/test 
my name is {{ myname }} #自定義變量
my name is {{ ansible_all_ipv4_addresses[0] }}  #系統變量
[root@localhost scripts]# cat test_filevars.yaml 
---
- hosts: all
  gather_facts: True    #開啓系統變量
  vars:
  - myname: "yunjisuan" #自定義變量
  tasks:
  - name: template test
    template: src=/tmp/test dest=/root/test #使用template下發可變配置文件
[root@localhost scripts]# ansible-playbook test_filevars.yaml
 

下發的變量的判斷的語法

 
[root@localhost scripts]# cat /tmp/if.j2 
{% if PORT %}       #if PORT存在
ip=0.0.0.0:{{ PORT }}
{% else %}          #不然的話
ip=0.0.0.0:80
{% endif %}         #結尾
[root@localhost scripts]# cat test_ifvars.yaml 
---
- hosts: all
  gather_facts: True    #開啓系統內置變量
  vars:
  - PORT: 90        #自定義變量
  tasks:
  - name: jinja2 if test
    template: src=/tmp/if.j2 dest=/root/test
[root@localhost scripts]# ansible-playbook test_ifvars.yaml 
 

若是咱們把PROT的值置空就會是假

 
[root@localhost scripts]# cat test_ifvars.yaml 
---
- hosts: all
  gather_facts: True
  vars:
  - PORT:       #置空
  tasks:
  - name: jinja2 if test
    template: src=/tmp/if.j2 dest=/root/test
[root@localhost scripts]# ansible-playbook test_ifvars.yaml
 

劇本的通知和下發機制

 
#下發可執行動做的可變的nginx配置文件
[root@localhost scripts]# head -1 /tmp/nginx.j2 
worker_processes  {{ ansible_processor_count }};    #可變的參數
[root@localhost scripts]# 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
[root@localhost scripts]# ansible-playbook test_nginxvars.yaml 
 

用roles來模板換劇本,能夠本身組合模板

 
#建立roles基本原型的目錄結構
[root@ansible myroles]# tree /myroles/
/myroles/
├── nginx.yaml  #入口觸發配置文件
└── roles       #playbook的原型配置目錄
    └── nginx   #nginx相關模組配置目錄
        ├── files   #copy模塊和script模塊的參數src默認會從這個文件夾查找
        ├── handlers    #用來存放notify的
        ├── tasks       #用來存放ansible模塊任務的
        ├── templates   #用來存放j2的
        └── vars        #用來存放變量的
7 directories, 1 file
#入口觸發配置文件
[root@ansible myroles]# cat /myroles/nginx.yaml 
---
- hosts: all    #執行的主機範圍
  gather_facts: True    #開啓系統內置變量
  roles:                #啓用roles原型配置
  - nginx           #執行nginx原型模組
 

tasks的任務編排模塊

 
#在nginx模組添加tasks任務配置文件
[root@ansible myroles]# cat roles/nginx/tasks/main.yaml 
---
- name: check alived    #任務1的名字
  ping:                 #執行ping模塊
- name:                 #任務2的名字
  shell: ls /           #執行shell模塊
  register: ls_result   #將執行結果保存給變量
- debug: var=ls_result  #變量的值賦值給debug進行輸出
#完成後的目錄結構以下所示
[root@ansible myroles]# tree /myroles/
/myroles/
├── nginx.yaml  #nginx模組入口配置文件
└── roles
    └── nginx   #nginx原型模組目錄
        ├── files
        ├── handlers
        ├── tasks
        │   └── main.yaml   #nginx模組的tasks任務配置文件
        ├── templates
        └── vars
7 directories, 2 files
 

執行監督的模塊

 
[root@ansible myroles]# ansible-playbook nginx.yaml 
PLAY [all] ****************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************
ok: [webA]
ok: [webB]
TASK [nginx : check alived] ***********************************************************************************
ok: [webA]
ok: [webB]
TASK [nginx : shell] ******************************************************************************************
changed: [webA]
changed: [webB]
TASK [nginx : debug] ******************************************************************************************
ok: [webA] => {
    "ls_result": {
        "changed": true,
        "cmd": "ls /",
        "delta": "0:00:00.002805",
        "end": "2018-06-21 11:52:29.343592",
        "failed": false,
        "rc": 0,
        "start": "2018-06-21 11:52:29.340787",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "bin\nboot\ndev\netc\nhome\nlib\nlib64\nmedia\nmnt\nopt\nproc\nroo\nroot\nrun\nsbin\nservice\nsrv\nsys\ntmp\nusr\nvar",
        "stdout_lines": [
            "bin",
            "boot",
            "dev",
            "etc",
            "home",
            "lib",
            "lib64",
            "media",
            "mnt",
            "opt",
            "proc",
            "roo",
            "root",
            "run",
            "sbin",
            "service",
            "srv",
            "sys",
            "tmp",
            "usr",
            "var"
        ]
    }
}
ok: [webB] => {
    "ls_result": {
        "changed": true,
        "cmd": "ls /",
        "delta": "0:00:00.002708",
        "end": "2018-06-21 11:52:29.359754",
        "failed": false,
        "rc": 0,
        "start": "2018-06-21 11:52:29.357046",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "bin\nboot\ndev\netc\nhome\nlib\nlib64\nmedia\nmnt\nopt\nproc\nroo\nroot\nrun\nsbin\nservice\nsrv\nsys\ntmp\nusr\nvar",
        "stdout_lines": [
            "bin",
            "boot",
            "dev",
            "etc",
            "home",
            "lib",
            "lib64",
            "media",
            "mnt",
            "opt",
            "proc",
            "roo",
            "root",
            "run",
            "sbin",
            "service",
            "srv",
            "sys",
            "tmp",
            "usr",
            "var"
        ]
    }
}
PLAY RECAP ****************************************************************************************************
webA                       : ok=4    changed=1    unreachable=0    failed=0   
webB                       : ok=4    changed=1    unreachable=0    failed=0   
 
ansible-playbook執行入口配置文件nginx.yaml後,它會自動在roles目錄下查找nginx目錄並進入後查找tasks任務目錄並執行main.yaml的任務配置文件。
其實,這個roles的操做等效於如下配置
 
#本配置和以前的roles配置等效
[root@ansible myroles]# cat /service/scripts/test.yaml
---
- hosts: all
  gather_facts: True
  tasks:                #其實roles的本質就是將tasks任務單獨寫了。
  - name: check alived  #並在入口文件裏追加了roles去查找tasks配置文件路徑
    ping:
  - name:
    shell: ls /
    register: ls_result
  - debug: var=ls_result
 

roles下的自定義變量模塊

 
#建立自定義變量vars模組的配置文件
[root@ansible myroles]# cat roles/nginx/vars/main.yaml 
---
my_name: yunjisuan
phone: 1800000000
[root@ansible myroles]# cat roles/nginx/tasks/main.yaml 
---
- name: check alived
  ping:
- name:
  shell: ls /
  register: ls_result
- debug: var=ls_result
- name:         #添加對變量引用的任務編排
  shell: echo my phone is {{ phone }}
  register: echo_result
- debug: var=echo_result
[root@ansible myroles]# ansible-playbook nginx.yaml     #執行入口配置文件
 

roles使用copy,和scripts模塊

 
[root@ansible myroles]# cat roles/nginx/files/test
welcome to yunjisuan
[root@ansible myroles]# cat roles/nginx/files/test.sh
echo "aaa" >> /tmp/test
[root@ansible myroles]# chmod +x roles/nginx/files/test.sh
[root@ansible myroles]# cat roles/nginx/tasks/main.yaml 
---
- name: check alived
  ping:
- name:
  shell: ls /
  register: ls_result
- debug: var=ls_result
- name:
  shell: echo my phone is {{ phone }}
  register: echo_result
- debug: var=echo_result
- name:         #添加copy模塊
  copy: src=test dest=/root/
- name:         #添加script模塊(自動在目標IP機器上執行腳本)
  script: test.sh
[root@ansible myroles]# ansible-playbook nginx.yaml 
 

roles中的template模塊

 
[root@ansible myroles]# cat roles/nginx/templates/test.j2 
myname is {{ my_name }},my phone is {{ phone }} #引用自定義變量
my ipaddress is {{ansible_all_ipv4_addresses[0]}}   #引用內置變量
[root@ansible myroles]# cat roles/nginx/tasks/main.yaml 
---
- name: check alived
  ping:
- name:
  shell: ls /
  register: ls_result
- debug: var=ls_result
- name:
  shell: echo my phone is {{ phone }}
  register: echo_result
- debug: var=echo_result
- name:
  copy: src=test dest=/root/
- name:
  script: test.sh
- name:
  template: src=test.j2 dest=/root/test2    #下發可變配置文件
[root@ansible myroles]# ansible-playbook nginx.yaml 
 

roles的notify變更通知執行模塊

 
[root@ansible myroles]# cat roles/nginx/handlers/main.yaml 
---
- name: start_nginx     #定義handlers的動做類型
  shell: /usr/local/nginx/sbin/nginx    
- name: stop_nginx  #定義handlers的動做類型
  shell: /usr/local/nginx/sbin/nginx -s stop   
- name: reload_nginx    #定義handlers的動做類型
  shell: /usr/local/nginx/sbin/nginx -s reload  
[root@ansible myroles]# cat roles/nginx/tasks/main.yaml 
---
- name: check alived
  ping:
- name:
  shell: ls /
  register: ls_result
- debug: var=ls_result
- name:
  shell: echo my phone is {{ phone }}
  register: echo_result
- debug: var=echo_result
- name:
  copy: src=test dest=/root/
- name:
  script: test.sh
- name:
  template: src=test.j2 dest=/root/test2
  notify: start_nginx   #執行template任務後下發通知給handlers執行start_nginx
[root@ansible myroles]# ansible-playbook nginx.yaml 
 

特別提示: 
notify下發通知只有當以前的任務形成了變化那麼纔會被執行,若是沒有發生任何改變,則notify不會被執行。例如:

 
#tasks任務形成改變,觸發notify
[root@ansible myroles]# cat /tmp/test.yaml 
---
- hosts: webA
  gather_facts: True
  tasks:
  - name:
    copy: src=/tmp/test dest=/root/ #這步形成目標改變才能出發notify
    notify: start_nginx
  handlers:
  - name: start_nginx
    shell: /usr/local/nginx/sbin/nginx
[root@ansible myroles]# ansible-playbook /tmp/test.yaml 
PLAY [webA] ***************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************
ok: [webA]
TASK [copy] ***************************************************************************************************
changed: [webA] #發生了改變
RUNNING HANDLER [start_nginx]   #觸發notify *********************************************************************************
changed: [webA]
PLAY RECAP ****************************************************************************************************
webA                       : ok=3    changed=2    unreachable=0    failed=0   
#咱們再次執行/tmp/test.yaml
[root@ansible myroles]# ansible-playbook /tmp/test.yaml 
PLAY [webA] ***************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************
ok: [webA]
TASK [copy] ***************************************************************************************************
ok: [webA]      #沒有形成任務改變,未觸發notify通知
PLAY RECAP ****************************************************************************************************
webA                       : ok=2    changed=0    unreachable=0    failed=0
相關文章
相關標籤/搜索