自動化運維工具Ansible

1、簡介html

當下有許多的運維自動化工具( 配置管理 ),例如:Ansible、SaltStack、Puppet、Fabric 等。node

Ansible 一種集成 IT 系統的配置管理、應用部署、執行特定任務的開源平臺,是 AnsibleWorks 公司名下的項目,該公司由 Cobbler 及 Func 的做者於 2012 年建立成立。python

Ansible 基於 Python 語言實現,由 Paramiko 和 PyYAML 兩個關鍵模塊構建。mysql

2、特性linux

部署簡單,只需在主控端部署 Ansible 環境,被控端無需作任何操做。ios

支持Linux/UNIX及windows環境nginx

默認使用 SSH(Secure Shell)協議對設備進行管理,用它來配置思科路由也很是方便。git

主從集中化管理。
配置簡單、功能強大、擴展性強。
支持 API 及自定義模塊,可經過 Python 輕鬆擴展。
經過 Playbooks 來定製強大的配置、狀態管理。
對雲計算平臺、大數據都有很好的支持。
提供一個功能強大、操做性強的 Web 管理界面和 REST API 接口 ---- AWX 平臺。github

3、整體架構web

 

4、執行過程

5、Ansible 與 SaltStack對比

>> 最大的區別是 Ansible 無需在被監控主機部署任何客戶端代理,默認經過 SSH 通道進行遠程命令執行或下發配置。
>> 相同點是都具有功能強大、靈活的系統管理、狀態配置,都使用 YAML 格式來描述配置,二者都提供豐富的模板及 API,對雲計算平臺、大數據都有很好的支持。

Ansible在github上地址:https://github.com/ansible

 

Ansible安裝部署與配置

       角色              主機名                  IP                                組名             

       控制端           hd01                     192.168.1.11                 ——             

       被控端           hd02                     192.168.1.12                 webservers   

       被控端           hd03                     192.168.1.13                 webservers   

 

Ansible安裝

安裝可以使用源碼編譯安裝,也能夠更新yum源後使用yum安裝

 

yum 安裝:

配置源(centos6)

yum install http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm -y

換163的源

wget http://mirrors.163.com/.help/CentOS6-Base-163.repo      

 mv CentOS6-Base-163.repo /etc/yum.repos.d/

 yum clean all

 

CentOS6-Base-163.repo主要是爲了安裝:PyYAML

配置源(centos7)
rpm -iUvh http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel//7/x86_64/e/epel-release-7-7.noarch.rpm
下載配置文件(centos7)
wget http://mirrors.163.com/.help/CentOS7-Base-163.repo          CentOS7-Base-163.repo主要是爲了安裝:PyYAML
mv CentOS7-Base-163.repo /etc/yum.repos.d/

yum clean all

 

安裝ansible

yum -y install ansible


查看ansible 版本

[root@hd01 ~]# ansible --version

ansible 2.5.3

  config file = /etc/ansible/ansible.cfg

  configured module search path = [u'/usr/share/my_modules']

  ansible python module location = /usr/lib/python2.6/site-packages/ansible

  executable location = /usr/bin/ansible

  python version = 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)]

注:yum裝ansible      隨着時間的推移,ansible版本會是最新版的。

Ansible經過定義好的主機與組規則(Inventory)對匹配的目標主機進行遠程操做,配置文件默認是/etc/ansible/hosts

定義Host Inventory

添加組名及容許執行命令的主機

webservers 是組名,下面的是IP也可使用域名、別名標識。

各主機SSH互信

[root@hd01 ~]# ssh-keygen -t rsa   #建立公鑰與私鑰

 

一直回車就OK

將公鑰傳給webservers組中的主機

ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.12

ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.13

 

 

測試主機免密 連通性:

[root@hd01 ~]# ansible webservers -m ping

#-m 使用ping模塊  -vvv 能夠查看詳細的執行過程

 

OK

提示:

使用Linux普通用戶帳戶進行鏈接並使用sudo命令實現root權限,格式爲:

ansible webservers -m ping -u ansible -sudo

當沒有作免密碼訪問時用 ansible webservers -m ping -k

而後輸入密碼 操做

 

關於定義主機與組

在/etc/ansible/hosts中主機能夠用域名、IP、別名進行標識。

/etc/ansible/hosts  中組成員主機名稱支持正則描述   組成員主機IP支持正則描述

舉例說明 格式:

[webservers]                #組名

alpha.example.org    #域名對應192.168.1.100     

beta.example.org     #域名對應192.168.1.110     

192.168.1.100               #IP

192.168.1.110               #IP

 

mail.example.com

192.168.1.90:2135         #定義一個SSH服務端口爲:2135的主機  

 

組成員主機名稱支持正則描述,舉例:

[webservers]

www.[01:50].example.com

[databases]

db-[a:f].example.com

 

定義主機變量

主機能夠指定變量,以便後面供Playbook配置使用,好比定義主機host1及host2上apache參數http_port及maxRequestsPerChild,目的是讓兩臺主機產生Apache配置文件httpd.conf差別化,格式:

[atlanta]

host1 http_port=80 maxRequestsPerChild=808

host2 http_port=303 maxRequestsPerChild=909

定義組變量

組變量的做用域是覆蓋全部成員,經過定義一個新塊,塊名由組名+」:vars」組成

格式:

[atlanta]

host1

host2

[atlanta:vars]

ntp_server=ntp. atlanta.example.com

proxy=proxy.atlanta.example.com

 

 

匹配目標

格式:ansible <目標主機或組> -m <模塊名字> -a <模塊參數>

重啓webservers組全部Apache服務

[root@hd01 ~]# ansible webservers -m service -a "name=httpd state=restarted"

 

匹配目標主機規則表

192.168.1.12或者hd02               匹配目標IP地址或主機名,多個IP或主機名使用」:」號分隔

webservers                                匹配目標組爲webservers多個組使用」:」號分隔

all或者'*'                                   匹配全部主機

hd.*或者192.168.1.*                   支持正則匹配主機或者IP地址

webservers:!192.168.1.11            匹配webservers組且排除192.168.1.11主機IP

agent:&webservers                    匹配agent和webservers兩個組的交集

webservers:!{{excluded}}:&{{required}}       支持變量匹配方式

 

Ansible經常使用模塊及API

Ansible提供了很是豐富的功能模塊,包括cloud(雲計算)、Commands(命令行)、Database(數據庫)、Files(文件管理)、Internal(內置功能)、Monitoring(監控管理)等等。

獲取webservers組中主機uptime信息

[root@hd01 ~]# ansible webservers -m command -a "uptime"     

 

 

-m command是默認模塊  可省略

[root@hd01 ~]# ansible-doc ping

可得到模塊的幫助信息

EXAMPLES:

# Test we can logon to 'webservers' and execute python with json lib.

# ansible webservers -m ping

 

# Example from an Ansible Playbook

- ping:

 

# Induce an exception to see what happens

- ping:

    data: crash

 

RETURN VALUES:

ping:

    description: value provided with the data parameter

    returned: success

    type: string

    sample: pong

在playbook中運行遠程命令格式:

- name: reboot the service

  command: /sbin/reboot -t now

 

Ansible 經常使用模塊學習

shell > ansible-doc -l    # 列出 Ansible 支持的模塊

ansible-doc <模塊名>查看模塊幫助信息

 

>>遠程命令模塊( command / script / shell )

command 做爲 Ansible 的默認模塊,能夠運行遠程權限範圍全部的 shell 命令,不支持管道符。

例:

ansible webservers -m command -a "free -m"               # 查看 webservers 分組主機內存使用狀況

[root@hd01 ~]# ansible webservers -m command -a "free -m"

shell 的功能是執行遠程主機上的 shell 腳本文件,支持管道符。

例:

[root@hd01 ~]# ansible webservers -m shell -a "/root/test.sh"          # 執行遠程腳本

 

 

ansible的command和shell模塊的區別:

好比我要批量刪除一些文件, 

[root@hd01 ~]# ansible webservers -m command -a "rm -f /root/test*.sh"

由於你的命令行中包含了通配符*號,通配符必需要有在shell環境中才能被識別出,否則,它只能刪除test*.sh這一個文件。

 

雖顯示成功,但目標文件未被刪除

 

因此你須要執行如下命令才能成功

[root@hd01 ~]# ansible webservers -m shell -a "rm -f /root/test*.sh"

執行以後    

關於command模塊運行的命令中沒法使用管道符的說明。

 

script 的功能是在遠程主機執行主控端存儲的 shell 腳本文件,至關於 scp + shell 組合。

例:

[root@hd01 ~]# ansible webservers -m script -a "/root/test.sh"      # 遠程執行本地腳本

192.168.1.12 | SUCCESS => {

    "changed": true,

    "rc": 0,

    "stderr": "Shared connection to 192.168.1.12 closed.\r\n",

    "stdout": "123\r\n",

    "stdout_lines": [

        "123"

    ]

}

192.168.1.13 | SUCCESS => {

    "changed": true,

    "rc": 0,

    "stderr": "Shared connection to 192.168.1.13 closed.\r\n",

    "stdout": "123\r\n",

    "stdout_lines": [

        "123"

    ]

 

>>copy 模塊(實現主控端向目標主機拷貝文件,相似於 scp 功能)

例:

[root@hd01 ~]# ansible webservers -m copy -a "src=/root/test.sh dest=/tmp/ owner=root group=root mode=0755 backup=yes"

# 向 webservers 組中主機拷貝 test.sh 到 /tmp 下,owner:指定屬主爲 root,group:指定屬組爲:root ,mode:權限爲 0755 , backup:在覆蓋以前將原文件備份,備份文件包含時間信息。有兩個選項:yes|no

 

 

>>stat 模塊(獲取遠程文件狀態信息,atime/ctime/mtime/md5/uid/gid 等信息)

例:

[root@hd01 ~]# ansible webservers -m stat -a "path=/etc/passwd"    #path指定具體路徑

 

>>get_url 模塊(實如今遠程主機下載指定 URL 到本地,支持 sha256sum 文件校驗)

例:

[root@hd01 ~]# ansible webservers -m get_url -a "url=http://www.baidu.com dest=/tmp/index.html mode=0440 force=yes"  

 

#下載百度首頁index.html文件

# force:

        yes:默認項,若是目標主機包含該文件,但內容不一樣,則強制覆蓋

        no:則只有當目標主機的目標位置不存在該文件時,才複製

 

>>yum 模塊(軟件包管理)

#name:要進行操做的軟件包的名字,也能夠傳遞一個url或者一個本地的rpm包的路徑 

#state:目標狀態(present,absent,latest)

  1. present是指安裝套件,而 latest 則是指安裝最新的套件,也就是會使用 yum mirror 上最新的版本。
  2. absent   卸載

 

例:yum 裝httpd

[root@hd01 ~]#ansible webservers -m yum -a "name=httpd state=latest"

安裝

卸載

[root@hd01 ~]#ansible webservers -m yum -a "name=httpd state=absent" 

>>cron 模塊(遠程主機 crontab 配置)

例: 

[root@hd01 ~]# ansible webservers -m cron -a "name='check passwd md5value' hour='8' job='md5sum /etc/passwd>/tep/p.txt'"

任務名字叫check passwd md5value   hour=’8’ 天天的8時執行任務

效果:

[root@hd02 ~]# crontab -l

#Ansible: check passwd md5value

* 8 * * * md5sum /etc/passwd>/tep/p.txt

[root@hd02 ~]#

 

>>mount 模塊(遠程主機分區掛載)

例:

[root@hd01 ~]# ansible webservers -m mount -a 'name=/test src=/dev/sdb1 fstype=ext3 opts=ro state=present' 

# fstype  指定文件系統類型爲ext4  

# opts     設定掛載的參數選項信息;-o ro == opts=ro 

# src       要被掛載的目錄設備信息 src=/dev/sdb1

 

 

>>service 模塊(遠程主機系統服務管理)

例:

                                                          #state的4種目標狀態

[root@hd01 ~]# ansible webservers -m service -a "name=httpd state=started"  #啓動httpd

[root@hd01 ~]# ansible webservers -m service -a "name=httpd state=stopped" #關閉httpd

 

[root@hd01 ~]# ansible webservers -m service -a "name=httpd state=restarted" #重啓httpd

 

[root@hd01 ~]# ansible webservers -m service -a "name=httpd state=reloaded" #從新加載httpd

 

>>sysctl 包管理模塊

功能

遠程Linux主機sysctl配置。

實例

sysctl: name=kernel.panic value=3 sysctl_file=/etc/sysctl.conf checks=before reload=yessalt '*' pkg.upgrade

 

>>user 服務模塊(遠程主機用戶管理)

例:

[root@hd01 ~]# ansible webservers -m user -a "name=wang comment='user wang'"

[root@hd01 ~]# ansible webservers -m user -a "name=wang state=absent remove=yes"    #state 目標狀態  刪除

 

實現一些監控功能

查看所有主機在線狀況

[root@ansible ~]# ansible all -m ping //內建的ping模塊  #all表示/etc/ansible/hosts中所有主機

 

[root@hd01 ~]# ansible webservers -a "/bin/df -h" #輸出掛載信息

 

[root@hd01 ~]# ansible webservers -a "/sbin/ip addr show dev eth0"  #查看webservers組中主機網卡信息

 

YAML語言

yaml語言是一種基於Unicode容易閱讀,容易和腳本語言交互的,用來表達數據序列的編程語言Ansible與Saltstack環境中配置文件都以YAML格式存在,YAML文件擴展名一般爲.yaml或者.yml

重要組成結構:list和directory

如下經過描述YAML與Python的對應關係,瞭解YAML的層次及結構

塊序列描述

塊序列就是將描述的元素序列到python的列表中

Python:

import yaml

obj = yaml.load(

"""

- apple

- banana

- orange

"""

)

print(obj)

結果:

['apple', 'banana', 'orange']

 

YAML與Python塊概念相似,例如:

-

 - apple

 - banana

 - orange

-

 - chuanzhi

 - oldboy

 - mage

對應Python結果:

[['apple', 'banana', 'orange'],[ 'chuanzhi', 'oldboy', 'mage']]

塊映射描述:

塊映射就是將描述的元素序列到字典的中,格式爲」key: value」,如下爲YAML例子:

hero:

  hp: 34

  sp: 8

  level: 4

orc:

  hp: 12

  sp: 0

  level: 2

對應python結果爲:

{'hero': '{'hp': 34, 'sp': 8, 'level': 4}, 'orc': {'hp': 12, 'sp': 0, 'level': 2}}

YAML塊序列與塊映射是能夠自由組合在一塊兒的,他們之間能夠相互嵌套,經過靈活的組合實現複雜的對象屬性。例如:

- hero:

   hp: 34

   sp: 8

   level: 4

- orc:

   hp:

    - 12

    - 30

   sp: 0

   level: 2

對應Python結果爲:

[{'hero': '{'hp': 34, 'sp': 8, 'level': 4}, {'orc': {'hp': [12,30] ,'sp': 0, 'level': 2}}]

 

 

Ansible-playbook介紹

# 使用 Ansible-playbook 能夠完成一組複雜的動做,例如部署環境、搭建服務、修改配置等。playbook能夠定製配置,能夠按指定的操做步驟有序執行,支持同步及異步方式。官方提供不少例子,可在https://github.com/ansible/ansible-examples 找到。playbook經過YAML格式來進行描述定義,能夠實現多臺主機應用部署。

先建立一個存放playbook劇本的目錄

[root@hd01 ~]# mkdir -p /root/ansible/playbooks

在webservers組中簡單部署nginx,ntp服務,利用其批量部署過程介紹playbook。

playbook案例一  yum安裝nginx,ntp

建立nginx的目錄

[root@hd01 ~]# cd /root/ansible/

[root@hd01 ansible]# mkdir nginx

 

【/root/ansible/playbooks/nginx.yml】

---

- hosts: webservers

  vars:

    worker_processes: 4

    num_cpus: 4

    max_open_file: 65506

    root: /application

  remote_user: root

  tasks:

  - name: ensure nginx is at the latest version

    yum: name=nginx state=latest

  - name: write the nginx config file

    template: src=/root/ansible/nginx/nginx2.conf dest=/etc/nginx/nginx.conf

    notify:

    - restart nginx

  - name: ensure nginx is running

    service: name=nginx state=started

  handlers:

    - name: restart nginx

      service: name=nginx state=restarted

 

以上playbook定製了一個簡單的Nginx軟件包管理,內容包括安裝、配置模板、狀態管理等。下文將上面代碼拆分進行說明。

一、定義主機與用戶

- hosts: webservers

  vars:

    worker_processes: 4

    num_cpus: 4

    max_open_file: 65506

    root: /application

  remote_user: root

#hosts  定義操做的對象是webservers組,對象能夠是主機或組

#vars  定義了4個變量(配置模板用到)

#remote_user  指定遠程操做主機爲root,支持sudo方式運行,經過添加sudo:yes便可。

二、任務列表

tasks:                                                             #任務集

- name: ensure nginx is at the latest version   #確保nginx是最新的版本

  yum: name=nginx state=latest             # state=latest  目標狀態=最新版     

- name: ensure nginx is running   #name標籤加強可讀性,對下面的service模塊(動做)描述

  service: name=nginx state=started      #serivce模塊使nginx處於啓動狀態

         #軟件名字   #狀態    參數使用key=value格式

功能是檢測Nginx服務是否爲啓動狀態,如沒有則啓動。

 

 

在playbook可經過template模塊對本地配置模板文件進行渲染並同步到目標主機。

- name: write the nginx config file

    template: src=/root/ansible/nginx/nginx2.conf dest=/etc/nginx/nginx.conf

    notify:

    - restart nginx

#src指定文件源地址  dest指定文件的目標地址

 

 

    notify:                                #通知handlers重啓nginx

    - restart nginx

  - name: ensure nginx is running             #確保nginx在運行中

    service: name=nginx state=started

  handlers:                                  # handlers(處理程序)作通知的動做

    - name: restart nginx

      service: name=nginx state=restarted

執行playbook

執行playbook,能夠經過ansible-playbook命令實現,格式:

ansible-playbook playbookfile(.yml或.yaml) [參數],如啓用10個並行進程執行playbook:

[root@hd01 ~]# ansible-playbook /root/ansible/playbooks/nginx.yml -f 10

其餘經常使用參數說明:

-u remote_user: 本身指定遠程指定執行playbook的系統用戶

--syntax-check: 檢查playbook語法

--list-hosts playbooks: 匹配到的主機列表

-T timeout:定義執行playbook的超時時間

--step: 以單任務分步驟運行,方便作每一步的確認工做

playbook角色與包含聲明

當咱們寫一個很是大的playbook時,想要複用些功能顯得有些吃力,還好ansible支持寫playbook時拆分紅多個文件,經過包含(include)的形式進行引用,咱們能夠根據多重維度進行「封裝」,好比定義變量、任務、處理程序等等。

角色創建在包含文件之上,抽象以後更清晰,可複用,

ansible官方在https://github.com/ansible/ansible-examples/上提供大量資料供參考

包含文件,鼓勵複用

當多個playbook涉及服用的任務列表時,能夠將複用的內容剝離出,寫到獨立的文件當中,最後在須要的地方include進來便可,示例以下:

 

將處理程序(handlers)放到包含文件中是一個好的辦法,好比重啓apache的任務:

【handlers/handlers.yml】

---

#this might be in a file like handlers/handlers.yml        #註釋說明在處理這類文件

- name: restart apache                                                   

  service: name=apache state=restarted

須要用時以下引用:

handlers:

  - include: handlers/handlers.yml       #注意路徑

角色

角色能夠更好地進行組織或抽象,讓劇本複用性更強、功能更具模塊化。

角色是Ansible定製的一種標準規範,以不一樣級別目錄層次及文件對角色、變量、任務、處理程序等進行拆分,爲後續功能擴展、可維護性打下基礎。一個典型角色目錄結構的示例以下:

site.yml                   

webservers.yml

roles/

   common/     #公共類角色

     files/                    ## files目錄:用於存放將要拷貝到遠程主機的安裝包等

     templates/

tasks/    #tasks目錄: 將要執行的全部任務,若是比較複雜,能夠單獨定義不一樣任務,

     handlers/ 

     vars/

     defaults/

     meta/       

   webservers/

     files/

     templates/

     tasks/

     handlers/

     vars/

     defaults/

     meta/

在playbook是這樣引用的:

【site.yml】

---

- hosts: webservers

  roles:

    - common

- webservers

角色定製如下規範,其中x爲角色名。

-如roles/x/tasks/main.yml文件存在,其中列出的任務將被添加到執行隊列;

-如roles/x/handlers/main.yml文件存在,其中所列的處理程序將被添加到執行隊列

-如roles/x/vars/main.yml 文件存在,其中所列出的變量將被添加到執行隊列

-如roles/x/meta/main.yml 文件存在,所列任何變量的依賴關係將被添加到角色的列表

-任何副本任務能夠引用roles/x/files/  無需寫路徑,默認相對或絕對引用

-任何腳本任務能夠引用roles/x/files/  無需寫路徑,默認相對或絕對引用

-任何模板任務能夠引用文件中的roles/x/templates/  無需寫路徑,默認相對或絕對引用

 

對上面nginx軟件包管理的playbook(獨立文件)修改爲角色的形式,添加一個公共類角色common,從角色全局做用域中抽取出公共的部分,通常爲系統的基礎服務,好比ntp、iptables、selinux、sysctl等。本實例針對ntp服務管理。

  1. playbook目錄結構

playbook目錄包括變量定義目錄group_vars、主機組定義文件hosts、全局配置文件site.yml、角色功能目錄。

【/root/ansible/playbooks/nginx/】

[root@hd01 ~]# cd /root/ansible/playbooks/

[root@hd01 playbooks]# mkdir nginx

 

playbook目錄樹結構

[root@hd01 playbooks]# tree nginx/

nginx/

├── group_vars

│   ├── all

│   └── webservers

├── hosts

├── roles

│   ├── common

│   │   ├── handlers

│   │   │   └── main.yml

│   │   ├── tasks

│   │   │   └── main.yml

│   │   ├── templates

│   │   │   └── ntp.conf.j2

│   │   └── vars

│   │       └── main.yml

│   └── web

│       ├── handlers

│       │   └── main.yml

│       ├── tasks

│       │   └── main.yml

│       └── templates

│           └── nginx2.conf

└── site.yml

 

 

 

  1. 定義主機組

定義一個業務組webservers,成員爲兩臺主機。

【nginx/hosts】

[root@hd01 nginx]# cat hosts

[webservers]

192.168.1.12

192.168.1.13

 

非必選配置,默認引用/etc/ansible/hosts的參數,角色中定義組與主機的文件將經過」-i file」參數調用,格式:

[root@hd01 nginx]# ansible-playbook -i hosts 劇本文件

 

  1. 定義主機或組變量

group_vars爲定義組變量目錄,目錄當中的文件名要與組名保持一致,組變量文件定義的變量做爲域只受限於該組,all表明全部主機。

[root@hd01 group_vars]# cat all

---

# Variables listed here sre applicable to all host groups

ntpserver: ntp.sjtu.edu.cn

[root@hd01 group_vars]# cat webservers

---

worker_processes: 4

num_cpus: 4

max_open_file: 65506

root: /application

 

  1. 全局配置文件site.yml

site.yml引用了兩個角色塊,角色的應用範圍及實現功能都不太同樣

【nginx/site.yml】

[root@hd01 nginx]# cat site.yml

---

- name: apply common configuration to all nodes

  hosts: all

  roles:

    - common

- name: configure add deploy the webservers and application code

  hosts: webservers

  roles:

    - web

 

site.yml引用了兩個角色,一個爲公共類的common,另外一個爲web類,分別對應nginx/roles/common、nginx/roles/web目錄。以此類推,能夠引用更多的角色如db、hadoop等等,前提是得先定義,一般一個角色對應着一個服務。經過hosts參數來綁定角色對應的主機或組。

  1. 角色common的定義

角色common定義了handlers、tasks、templates、vars 4個功能類,分別存放處理程序、任務集、模板、變量的配置文件main.yml,須要注意的是,vars/main.yml中定義的變量優先級高於/nginx/group_vars/all,可從ansible-playbook的執行結果中獲得驗證。各功能塊定義文件以下:

 

[root@hd01 roles]# pwd

/root/ansible/playbooks/nginx/roles

[root@hd01 roles]# mkdir common

[root@hd01 roles]# cd common/

[root@hd01 common]# mkdir {handlers,tasks,templates,vars}

 

【handlers/main.yml】

[root@hd01 handlers]# cat main.yml

- name: restart ntp

  service: name=ntpd state=restarted

 

【tasks/main.yml】

[root@hd01 tasks]# cat main.yml

- name: install ntp

  yum: name=ntp state=present

- name: configure ntp file

  template: src=ntp.conf.j2 dest=/etc/ntp.conf  #src引用模板是無需寫路徑,默認在上級的

  notify: restart ntp                                             templates目錄查找

- name start the ntp service

  service: name=ntpd state=started

- name: test to see if selinux is running

  command: getenforce

  register: sestatus

  changed_when:false

 

【templates/ ntp.conf.j2】

[root@hd01 templates]# cat ntp.conf.j2

driftfile /var/lib/ntp/drift

restrict 127.0.0.1

restrict -6 ::1

 

server {{ ntpserver }}        #{{ ntpserver }}將引用vars/main.yml定義的ntpserver變量

 

includefile /etc/ntp/crypto/pw

keys /etc/ntp/keys

 

 

【vars/main.yml】

[root@hd01 vars]# cat main.yml

---

# Variables listed here are applicable to all groups

ntpserver: 210.72.145.44

 

  1. 角色web的定義

角色web定義了handlers、tasks、templates三個功能類,基本上是前面nginx管理playbook對應定義功能段打散了以後的內容。

[root@hd01 roles]# mkdir web

[root@hd01 roles]# cd web/

[root@hd01 web]# mkdir {handlers,tasks,templates}

【handlers/main.yml】

[root@hd01 handlers]# cat main.yml

- name: restart nginx

  service: name=nginx state=restarted

 

【tasks/main.yml】

[root@hd01 tasks]# cat main.yml

- name: ensure nginx is at latest version

  yum: pkg=nginx state=latest     

- name: write the nginx config file

  template: src=nginx2.conf dest=/etc/nginx/nginx.conf   

  notify:

  - restart nginx

- name: ensure nginx is running

  service: name=nginx state=started

 

 

須要去替換的nginx配置文件

【templates/nginx2.conf】

 

[root@hd01 templates]# cat nginx2.conf

#The configuration file has been modified

 

# For more information on configuration, see:

#   * Official English Documentation: http://nginx.org/en/docs/

#   * Official Russian Documentation: http://nginx.org/ru/docs/

 

user nginx;

worker_processes auto;

error_log /var/log/nginx/error.log;

pid /var/run/nginx.pid;

 

# Load dynamic modules. See /usr/share/nginx/README.dynamic.

include /usr/share/nginx/modules/*.conf;

 

events {

    worker_connections  1024;

}

 

 

http {

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

 

    access_log  /var/log/nginx/access.log  main;

 

    sendfile            on;

    tcp_nopush          on;

    tcp_nodelay         on;

    keepalive_timeout   65;

    types_hash_max_size 2048;

 

    include             /etc/nginx/mime.types;

    default_type        application/octet-stream;

 

    # Load modular configuration files from the /etc/nginx/conf.d directory.

    # See http://nginx.org/en/docs/ngx_core_module.html#include

    # for more information.

    include /etc/nginx/conf.d/*.conf;

}

 

 

 

  1. 運行角色

先在webservers組上換163的源  安裝擴展源

wget http://mirrors.163.com/.help/CentOS6-Base-163.repo

cp /root/CentOS6-Base-163.repo /etc/yum.repos.d/CentOS-Base.repo

yum clean all

yum -y install epel-release

yum clean all

 

 

運行以前先介紹下ntp

在Linux系統中,爲了不主機時間由於在長時間運行下所致使的時間誤差,進行時間同步(synchronize)的工做是很是必要的。Linux系統下,通常使用ntp服務來同步不一樣機器的時間。NTP 是網絡時間協議(Network Time Protocol)的簡稱,幹嗎用的呢?就是經過網絡協議使計算機之間的時間同步化。

ntpd與ntpdate在更新時間時有什麼區別。ntpd不只僅是時間同步服務器,它還能夠作客戶端與標準時間服務器進行同步時間,並且是平滑同步,並不是ntpdate當即同步,在生產環境中慎用ntpdate,也正如此二者不可同時運行。

 

 

 

 

 

 

 

 

[root@hd01 playbooks]# tree nginx/

nginx/

├── group_vars

│   ├── all

│   └── webservers

├── hosts

├── roles

│   ├── common

│   │   ├── handlers

│   │   │   └── main.yml

│   │   ├── tasks

│   │   │   └── main.yml

│   │   ├── templates

│   │   │   └── ntp.conf.j2

│   │   └── vars

│   │       └── main.yml

│   └── web

│       ├── handlers

│       │   └── main.yml

│       ├── tasks

│       │   └── main.yml

│       └── templates

│           └── nginx2.conf

└── site.yml

 

 

[root@hd01 nginx]# pwd

/root/ansible/playbooks/nginx

[root@hd01 nginx]# ansible-playbook -i hosts site.yml

 

驗證:

[root@hd02 ~]# rpm -qa|grep nginx

nginx-mod-http-image-filter-1.10.2-1.el6.x86_64

nginx-mod-http-geoip-1.10.2-1.el6.x86_64

nginx-filesystem-1.10.2-1.el6.noarch

nginx-mod-stream-1.10.2-1.el6.x86_64

nginx-1.10.2-1.el6.x86_64

nginx-mod-http-perl-1.10.2-1.el6.x86_64

nginx-mod-mail-1.10.2-1.el6.x86_64

nginx-all-modules-1.10.2-1.el6.noarch

nginx-mod-http-xslt-filter-1.10.2-1.el6.x86_64

[root@hd02 ~]# rpm -qa | grep ntp   

fontpackages-filesystem-1.41-1.1.el6.noarch

ntpdate-4.2.6p5-12.el6.centos.2.x86_64

ntp-4.2.6p5-12.el6.centos.2.x86_64

 

 

 

 OK

 

 

 

獲取遠程主機系統信息: Facts

Facts是一個很是有用的組件,相似於Saltstack的Grains功能,實現獲取遠程主機的系統信息,包括主機名、IP地址、操做系統、分區信息、硬件信息等,能夠配合playbook實現更多功能需求。好比在httpd.conf模板中引用Facts的主機名信息做爲ServerName參數的值。運行ansible 192.168.1.12 -m setup,返回192.168.1.12的Facts信息:

192.168.1.12 | SUCCESS => {

    "ansible_facts": {

        "ansible_all_ipv4_addresses": [

            "192.168.1.12"

        ],

        "ansible_all_ipv6_addresses": [

            "fe80::20c:29ff:fe59:9cc4"

        ],

        "ansible_apparmor": {

            "status": "disabled"

        },

        "ansible_architecture": "x86_64",

        "ansible_bios_date": "07/02/2015",

        "ansible_bios_version": "6.00",

        "ansible_cmdline": {

            "KEYBOARDTYPE": "pc",

            "KEYTABLE": "us",

            "LANG": "zh_CN.UTF-8",

            "quiet": true,

            "rd_NO_DM": true,

            "rd_NO_LUKS": true,

            "rd_NO_LVM": true,

            "rd_NO_MD": true,

            "rhgb": true,

"ro": true,

            "root": "UUID=17ff3012-e425-439a-9cd4-0f8da54aa4ae"

        },

 

 

 

系統  版本  dns地址等等

        "ansible_distribution": "CentOS",

        "ansible_distribution_file_parsed": true,

        "ansible_distribution_file_path": "/etc/redhat-release",

        "ansible_distribution_file_variety": "RedHat",

        "ansible_distribution_major_version": "6",

        "ansible_distribution_release": "Final",

        "ansible_distribution_version": "6.6",

        "ansible_dns": {

            "nameservers": [

                "114.114.114.114"

            ]

        },

主機名  CPU  VMware虛擬平臺  等等

        "ansible_nodename": "hd02",

        "ansible_os_family": "RedHat",

        "ansible_pkg_mgr": "yum",

        "ansible_processor": [

            "0",

            "GenuineIntel",

            "Intel(R) Core(TM) i7-5500U CPU @ 2.40GHz"

        ],

        "ansible_processor_cores": 1,

        "ansible_processor_count": 1,

        "ansible_processor_threads_per_core": 1,

        "ansible_processor_vcpus": 1,

        "ansible_product_name": "VMware Virtual Platform",

        "ansible_product_serial": "VMware-56 4d d9 aa 53 2d 1d 9c-c8 1d ac 6d 1c 59 9c c4",

        "ansible_product_uuid": "564DD9AA-532D-1D9C-C81D-AC6D1C599CC4",

        "ansible_product_version": "None",

……

在模板文件中這樣引用Facts信息

{{ ansible_devices.sda.model }}

{{ ansible_hostname }}

變量

在實際應用環境中,機器之間可能存在不一樣差別,好比CPU核心數等等,在ansible中定義變量可處理這些差別。

變量定義規則:由字母、數字、下劃線組成,必須以字母開頭。

關於前文Nginx軟件包管理的劇本的變量的解釋

  vars:

    worker_processes: 4             #4個工做進程

    num_cpus: 4                                     #CPU數量爲4

max_open_file: 65506                        #最大打開文件數

root: /application                            #Nginx根目錄

Jinja2過濾器

Jinja2是Python下一個普遍應用的模板引擎,它的設計思想相似於Django的模板引擎,並擴展了其語法和一系列強大的功能,官網地址: http://jinja.pocoo.org/

下面介紹Ansible使用Jinja2強大的過濾器(Filters)功能。

使用格式:{{ 變量名|過濾方法 }}

實現獲取一個文件路徑變量過濾出文件名的一個示例:

{{ path | basename }}

獲取文件所處的目錄名:

{{ path | dirname }}

下面爲一個完整的示例,實現從」 /etc/profile」中過濾出文件名」profile」並輸出重定向到

/tmp/testshell文件中

 

[root@hd01 ~]# cat 1.yml

---

- hosts: 192.168.1.12

  vars:

    filename: /etc/profile

  tasks:

    - name: "shelll"

      shell: echo {{ filename | basename }}>tmp/testshell

[root@hd02 ~]# cat /tmp/testshell

profile

更多過濾方法參考:

http://jinja.pocoo.org/docs/2.10/templates/#builtin-filters   

本地Facts

經過Facts能夠來獲取目標主機的系統信息,當這些信息還不能知足功能需求時,可經過編寫自定義的Facts模板來實現。還有一個更簡單的實現辦法,就是經過本地Facts實現。只需在目標設備/etc/ansible/facts.d 目錄定義JSON、INI或可執行文件的JSON(數據)輸出,文件擴展名要求使用 「.fact」,這些文件均可以做爲Ansible本地的Facts,例如,在目標設備192.168.1.12定義三個變量,供之後playbook進行引用。

【/etc/ansible/facts.d/preferences.fact】

 

[root@hd02 ~]# cat /etc/ansible/facts.d/preferences.fact

[general]      #常規

max_memory_size=32

max_user_processes=3730

open_files=65535

[root@hd01 ~]# ansible 192.168.1.12 -m setup -a "filter=ansible_local"

192.168.1.12 | SUCCESS => {

    "ansible_facts": {

        "ansible_local": {

            "preferences": {

                "general": {

                    "max_memory_size": "32",

                    "max_user_processes": "3730",

                    "open_files": "65535"

                }

            }

        }

    },

    "changed": false

}

注意返回JSON(數據)的層次結構,perferences(facts文件名前綴)→general(INI的節名)→key:value(INI的鍵與值),最後就能夠在咱們的模板或playbook中經過如下方式調用:

{{ ansible_local.preferences.general.openfiles }}

 

 

註冊變量

變量的另外一個用途是將一條命令的運行結果保存到變量中去,供後面的playbook使用。

示例:

- hosts: webservers

  tasks:

    - shell: /usr/bin/foo            

      register: foo_result   #註冊foo_result變量 變量值爲shell: /usr/bin/foo的運行結果;

      ignore_errors: True                 #忽略錯誤

    - shell: /usr/bin/bar                   

      when: foo_result.rc == 5  

#當條件語句when: foo_result.rc == 5成立時,shell: /usr/bin/bar命令纔會執行  

其中foo_result.rc爲返回/usr/bin/foo 的resultcode(返回碼)。

 

 

條件語句

有時候一個playbook的結果取決於一個變量,或者取決於上一個任務(task)的執行結果,某些狀況下,一個變量的值能夠依賴於其餘變量的值,固然也會影響Ansible的執行過程。

有時候咱們想跳過某些主機的執行步驟,好比符合特定版本的操做系統將不安裝某個軟件,或者磁盤爆滿了將進行清理的步驟。在Ansible中很容易作到這一點,經過When子句實現,其中引用Jinja2表達式。

簡單示例1:

[root@hd01 ~]# cat 1.yml

- hosts: webservers

  remote_user: root

  tasks:

    - name: "shutdown Debian flavored systems"   

      command: /sbin/shutdown -t now      #下面when語句執行結果爲True時  關機

      when: ansible_os_family == "Debian"    #Jinja2表達式    

#經過定義任務的Facts本地變量ansible_os_family(操做系統版本名稱)是否爲Debian,

結果返回BOOL(布爾型)類型,爲True是將執行上一條語句,爲False是該條語句不觸發

 

 

skipping跳過

綠色  沒執行shutdown命令

示例2:

經過判斷一條命令執行結果作不一樣分支的二級處理

[root@hd01 ~]# cat 1.yml

……

    - command: /bin/false

      register: result      #註冊變量

      ignore_errors: True   #忽略錯誤

    - command: /bin/something        

      when: result|failed   #當變量result執行結果爲失敗狀態時執行/bin/something

    - command: /bin/something_else

      when: result|success  #當變量result執行結果爲成功狀態時執行/bin/something_else

    - command: /bin/still/something_else

      when: result|skipped  #當變量result執行結果跳過期執行/bin/something_else

……

循環

一般一個任務會作不少事情,如建立大量用戶、安裝不少包、重複輪詢特定的步驟,直到某種結果條件爲止,Ansible提供良好支持。

例如在被控端添加 2 個用戶  

方式1通常作法  

- name: add user testuser1  

user: name=testuser1 state=present groups=wheel

- name: add user testuser2  

user: name=testuser2 state=present groups=wheel

 

解釋:

user: name=testuser1 state=present groups=wheel #用戶名testuser1 目標狀態爲安裝 加入wheel組

 

在重複執行執行任務量大的時候  推薦使用 迭代機制 方式2

方式2使用迭代方式  

- name: add several users  

user: name={{ item }} state=present groups=wheel   #{{ item }}  在引用下面的變量

with_items:   #經過with_items語句來指明迭代的元素列表

- testuser1  

- testuser2  

with_items會自動循環執行上面的語句」 user: name={{ item }} state=present groups=wheel」  次數爲with_items的元素個數。

還支持字典、列表形式在這裏只敘述簡單 經常使用的

 

批量用yum安裝軟件包

……

- name: yum many install package

  yum: name={{ item }} state=installed

  with_items:

  - httpd

  - nginx

……

 

playbook案例二  源碼安裝nginx,定製服務,針對自定製的nginx服務

需求:假如說業務須要擴容,我須要部署新的環境,新增長了機器,我須要把我原來標準的環境搬過去,那麼就可使用ansible的playbook,把你已經存在的模板,已經編譯好的nginx,包括配置文件 包括啓動腳本。

思路:先在一臺機器上編譯安裝好nginx、打包,而後再用ansible去下發。

 

過程:

目錄樹結構

[root@hd01 playbooks]# pwd

/root/ansible/playbooks

[root@hd01 playbooks]# tree nginx_install/

nginx_install/

├── install.yml

└── roles

    ├── common

    │   ├── files

    │   ├── handlers

    │   ├── meta

    │   ├── tasks

    │   │   └── main.yml

    │   ├── templates

    │   └── vars

    └── install

        ├── files

        │   └── nginx.tar.gz

        ├── handlers

        ├── meta

        ├── tasks

        │   ├── copy.yml

        │   ├── install.yml

        │   └── main.yml

        ├── templates

        │   ├── nginx

        │   └── nginx.conf

        └── vars

            └── main.yml

 

 

 

[root@hd01 playbooks]# mkdir nginx_install

[root@hd01 ~]# mkdir -p roles/{common,install}/{handlers,files,meta,tasks,templates,vars}

 

說明:roles目錄下有兩個角色,common爲一些準備操做,install爲安裝nginx的操做。每一個角色下面又有幾個目錄,handlers下面是當發生改變時要執行的操做,一般用在配置文件發生改變,重啓服務。Files爲安裝時用到的一些文件,meta爲說明信息,說明角色依賴等信息,tasks裏面是核心的配置文件,templates一般存一些配置文件,啓動腳本等模板文件,vars下爲定義的變量。

 

須要事先準備好安裝用到的文件,具體以下:

- 在一臺機器上事先編譯安裝好nginx,配置好啓動腳本,配置好配置文件

-安裝好後咱們須要把nginx目錄打包,並放到/root/ansible/playbooks/nginx_install/roles/install/files下面,名字爲nginx.tar.gz

- 啓動腳本、配置文件都要放到/root/ansible/playbooks/nginx_install/roles/install/templates下面

- cd /root/ansible/playbooks/nginx_install/roles

- 定義common的tasks,nginx是須要一些依賴包的,以下:

[root@hd01 tasks]# pwd

/root/ansible/playbooks/nginx_install/roles/common/tasks

[root@hd01 tasks]# cat main.yml

- name: Install initializtion require software

  yum: name={{ item }} state=installed

  with_items:

    - pcre

    - zlib-devel

    - pcre-devel

 

 

先看下準備好的nginx  

[root@hd01 ~]# ls /usr/local/nginx/

client_body_temp  conf  fastcgi_temp  html  logs  proxy_temp  sbin  scgi_temp  uwsgi_temp

[root@hd01 ~]# ls /etc/init.d/nginx

/etc/init.d/nginx

[root@hd01 ~]# ls /usr/local/nginx/conf/nginx.conf

/usr/local/nginx/conf/nginx.conf

[root@hd01 ~]#

[root@hd01 sbin]# ./nginx -V

nginx version: nginx/1.12.1

built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC)

configure arguments:

 

 

啓動腳本內容:

若是想添加腳本用service啓動,加入開機啓動,必需要腳本里麪包含標紅的這2行

[root@hd01 ~]# cat /etc/init.d/nginx

#! /bin/bash

#chkconfig: 2345 59 26

# description: nginx is a World Wide Web server. It is used to serve

. /etc/rc.d/init.d/functions

pidfile="/usr/local/nginx/logs/nginx.pid"

start(){

         if [ -f $pidfile ]

         then

                echo "nginx is running..." 

         else

                /usr/local/nginx/sbin/nginx

                sleep 1

                if [ -f $pidfile ]

                then

                        action "nginx start"  /bin/true

                else

                        action "nginx start" /bin/false

                fi

         fi

}

stop(){

         if [ -f $pidfile ]

         then

             kill  `cat $pidfile`

             #rm -rf $pidfile

             action "nginx stop"  /bin/true

         else

             action "nginx have been stopped"    /bin/false

         fi

}

status(){

         if [ -f $pidfile ]

         then

            action "nginx is running"  /bin/true

         else

            action "nginx  have been stopped"         /bin/true

         fi

}

restart(){

        stop

        start

}

case "$1" in

start)

      start

      ;;

stop)

      stop

      ;;

restart)

      restart

      ;;

status)

      status

      ;;

*)

   echo "USAGE:{start|stop|restart|status}"

   exit 1

      ;;

esac

exit 0

 

 

打包nginx以前  控制端hd01關閉nginx,被控端確保環境中不存在nginx以及啓動腳本。

把啓動腳本,配置文件複製到對應的templates/下。

[root@hd01 ~]# cd /usr/local/

[root@hd01 local]# tar zcvf nginx.tar.gz --exclude "nginx.conf" --exclude "vhost" nginx/

[root@hd01 local]# mv nginx.tar.gz /root/ansible/playbooks/nginx_install/roles/install/files/

[root@hd01 local]#

cp nginx/conf/nginx.conf /root/ansible/playbooks/nginx_install/roles/install/templates/

[root@hd01 local]#

cp /etc/init.d/nginx /root/ansible/playbooks/nginx_install/roles/install/templates/

 

查看公共類角色

[root@hd01 common]# pwd

/root/ansible/playbooks/nginx_install/roles/common

[root@hd01 common]# ls

files  handlers  meta  tasks  templates  vars

[root@hd01 common]# cat tasks/main.yml

- name: Install initializtion require software

  yum: name={{ item }} state=installed

  with_items:

    - pcre

    - zlib-devel

    - pcre-devel

 

 

定義變量

[root@hd01 vars]# pwd

/root/ansible/playbooks/nginx_install/roles/install/vars

[root@hd01 vars]# cat main.yml

nginx_user: www

nginx_port: 80

nginx_basedir: /usr/local/nginx

 

能夠根據這個去修改 被控端的一些參數

把全部須要的文件拷貝到目標機器

[root@hd01 tasks]# pwd

/root/ansible/playbooks/nginx_install/roles/install/tasks

[root@hd01 tasks]# cat copy.yml

- name: copy nginx software

  copy: src=nginx.tar.gz dest=/tmp/nginx.tar.gz owner=root group=root

- name: uncompression nginx software

  shell: tar zxf /tmp/nginx.tar.gz -C /usr/local/

- name: copy nginx start script

  template: src=nginx dest=/etc/init.d/nginx owner=root group=root mode=0755

- name: copy nginx config

  template: src=nginx.conf dest={{ nginx_basedir }}/conf/ owner=root group=root mode=0644

 

 

爲何上面的src後沒跟絕對路徑呢,由於他默認就去上一級files、templates裏面找了。

 

接下來創建用戶,啓動服務,刪除壓縮包。

[root@hd01 tasks]# pwd

/root/ansible/playbooks/nginx_install/roles/install/tasks

[root@hd01 tasks]# cat install.yml

- name: creat nginx user

  user: name={{ nginx_user }} state=present createhome=no shell=/sbin/nologin

- name: To solve the error

  shell: ln -s /lib64/libpcre.so.0.0.1 /lib64/libpcre.so.1

- name: start nginx service

  shell: /etc/init.d/nginx start

- name: add boot start nginx service

  shell: chkconfig --level 345 nginx on

- name: delete nginx compreeion files

  shell: rm -rf /tmp/nginx.tar.gz

 

 

上述標紅的兩行  根據被控端 實際狀況考慮

 

再建立一個新的文件main.yml去調用copy.yml 和install.yml

[root@hd01 tasks]# pwd

/root/ansible/playbooks/nginx_install/roles/install/tasks

[root@hd01 tasks]# cat main.yml

- include: copy.yml

- include: install.yml

 

到此兩個roles: common和install就定義完成了,接下來定義一個入口配置文件

[root@hd01 nginx_install]# pwd

/root/ansible/playbooks/nginx_install

[root@hd01 nginx_install]# cat install.yml

---

- hosts: webservers

  remote_user: root

  gather_facts: True

  roles:

    - common

    - install

 

 

 

 

 

[root@hd01 nginx_install]# pwd

/root/ansible/playbooks/nginx_install

[root@hd01 nginx_install]# ansible-playbook install.yml

 

控制端

webservers端

 

 

 

 

 

環境不一樣 或一些小細節問題,或者機器有bug

ansible-playbook極可能會報錯,須要耐心調試。

 

playbook案例3:

在agent組上yum安裝並啓動mysql而後檢查啓動狀況返回結果   

[root@hd01 ~]# cat install_mysql.yaml  

---

- hosts: agent

  remote_user: root

  tasks:

  - name: install mysql-server

    yum: name=mysql-server state=present

  - name: start mysql-server

    service: name=mysqld state=started

  - name: check mysql service

shell: ps -ef |grep mysqld

 

            

選項解析:

hosts:agent         #指定要執行指定任務的主機,其能夠是一個或多個由冒號分隔主機組

remote_user:root         #用於指定遠程主機上的執行任務的用戶

tasks:                       #  任務集

-name:mysql-server installing # 給這個任務起的名字 yum:name= mysql-server #利用yum模塊,安裝軟件的包名爲mysql-server service: name=mysqld state=started #啓動mysql state=present #狀態爲安裝 state=absent #狀態爲卸載 檢查agent是否已經安裝mysql-server

執行命令

[root@hd01 ~]# ansible-playbook install_mysql.yaml

 

對比兩張圖

當返回信息爲綠色時,表示ansible沒有進行任何操做。

當返回信息爲黃色時,表示ansible執行了操做,「當前狀態」已經變成了「目標狀態」。

playbook案例4:

  建立crontab計劃

創建cron.yaml,讓agent組 天天1點來運行/root/backup.sh腳本 作重要資料的備份

[root@hd01 ~]# cat crond.yaml

---

- hosts: agent

  remote_user: root

  tasks:

  - name: cron

     cron: name='test job' hour='1' job="/root/backup.sh"

 

 

 

 

看到結果,ok=2    changed=1 說明客戶機上的crontab計劃建立成功了!

 

 


 

 

 

上述基本操做案例熟悉後開始優化ansible運行

讓你的ansible飛起來

1、SSH Multiplexing    #SSH 多路複用

說明:

注意:OpenSSH須要5.6以上版本,低版本須要升級才能使用。 
Centos7系統上安裝的OpenSSH版本是較新的,能夠直接支持;對於Centos6的系統,自帶的OpenSSH版本較低,能夠用下面這個yum源進行升級yum update openssh-clients:

加入新yum源

cat  /etc/yum.repos.d/openssh.repo

[CentALT]

name=CentALT Packages for Enterprise Linux 6

baseurl=http://mirror.neu.edu.cn/CentALT/6/$basearch/

enabled=1

gpgcheck=0

 

輸入  yum update openssh-clients  升級OpenSSH 版本到5.6以上

1.配置

[root@hd01 ~]# tail -3 /etc/ssh/ssh_config   #最後三行添加

        ControlMaster   yes     

        ControlPath     /tmp/%r@%h:%p   

        ControlPersist  10m

 

解釋:

ControlMaster yes                       #Session Multiplexing 開關

ControlPath   ~/.ssh/master-%r@%h:%p    #供 Session Multiplexing 使用的 Control Socket (Unix Socket) 路徑

ControlPersist yes                      #是否開啓後臺 Control master 模式保持

成功開啓後,不管從該客戶端節點用同一用戶向同一 SSH Server 節點發起多少次鏈接,都有且僅有一條TCP鏈接被創建,負責該節點到該 Server 之間的全部 SSH 包文。

 

[root@hd01 ~]# ssh -O check 192.168.1.12

[root@hd01 ~]# ssh -O check 192.168.1.13

成功開啓後以下所示

 

 

 

測試:

 

1 開啓SSH長鏈接

ansible是經過使用ssh和遠程主機進行通訊,因此對ssh有這很強的依賴。在OpenSSH 5.6之後支持Multiplexing這個特性,能夠經過在ansible配置中設置以支持該特性。

以下是配置參數,設置長鏈接保持時間爲5天;control_path指定socket文件所保存的位置。

 

ssh_args = -C -o ControlMaster=auto -o ControlPersist=5d

control_path = /etc/ansible/ssh-socket/%%h-%%p-%%r

 

經過上面配置後,ansible中控機上執行一次與遠程主機的鏈接以後,這個鏈接會持久保持設定時間之久。能夠經過netstat命令查看到ESTABLISHED狀態的鏈接信息。

注意:control_path指定的目錄不存在,或執行ansible命令的用戶沒有寫權限的話是會報錯的。

2 開啓pipelining

默認狀況下,ansible的執行流程是把生成好的本地python腳本PUT到遠程服務器而後運行。若是開啓了pipelining,整個流程少了一個PUT腳本到遠程服務器的步驟,直接在SSH的會話中進行,能夠提升整個執行效率。

# 在ansible.cfg配置文件中設置pipelining爲True

pipelining = True  

須要注意的是:若是開啓pipelining,須要被控的遠程服務器將/etc/sudoers中的」Defaults requiretty」註釋掉,不然會出現相似如:you must have a tty to run sudo 的報錯。

 

 

用sed作替換

[root@hd01 ~]# ansible agent -m shell -a"sed -i 's/Defaults    requiretty/#Defaults    requiretty/' /etc/sudoers"

以下警告解決辦法

 

 

在/etc/ansible/ansible.cfg的[defaults]

添加一行

command_warnings = False

便可解決

 

 

 

 

Ansible  先介紹這麼多實際上它的用法挺深奧的,須要你不斷的去實踐,纔可以掌握,你入門以後再去深刻研究包括他的理論也好  具體實踐也好就會很容易了。

 

 

參考書籍 《python自動化運維》

 

 

 

 

 

 

 

 

出處:http://www.javashuo.com/article/p-ekvapbvm-bn.html 

 

注:本文版權歸做者和博客園共有,轉載請註明出處!

相關文章
相關標籤/搜索