ansible的基礎使用(一)

ansible基礎使用(一)


  • ansible的主要功能
    • A:爲何是ansible
    • B:ansible的安裝
    • C:ansible的相關文件
    • D:ansible的基本使用
  • ansible的簡單操做
    • A:ansible的經常使用模塊
  • ansible的進階操做
    • A:ansible-galaxy命令
    • B:ansible-pull命令
    • C:ansible-vault:管理加解密yml文件
    • D:ansible-console:控制檯
    • E:ansible-playbook的進階操做
    • F:templates模板
  • ansible的企業級運用
    • A:roles角色的運用

♣一:ansible的主要功能html

A:爲何是ansible

咱們如今的企業環境都是串聯起來提供服務能力,運行在一系列分佈式的計算資 源上並用各類不一樣的網絡協議進行通訊,當服務平臺隨着業務量增長鬚要橫向擴容的狀況下,不得不面臨一個問題就是N臺服務器的高效率服務部署和集中化的配置管理。基於此類狀況ansible就能很好解決。node

在實際的運維中咱們劃分爲6個場景:python

  • 1:配置管理(Ansible,Puppet,Salt)
  • 2:服務即時開通 (Docker,LXC)
  • 3:應用部署(滾動式部署,金絲雀部署)
  • 4:流程編排(Ansible,Mcollective,Salt,Serf,Chef)
  • 5:監控警告(Graphite,Sensu,Riemann ,zabbix)
  • 6:日誌記錄(ELK, SumoLogic)

在上面6個場景中,ansible能很好勝任前面4個場景。mysql

在經常使用相似的自動化運維工具中ansible是有絕對優點的。linux

ansible首先基於python開發,模塊衆多,能支持二次開發,並且最重要的不須要代理服務,直接在主控端安裝便可,被控端都是基於openssh遠程來控制操做,另外支持冪等性(一個任務執行1遍和n遍效果是同樣的,不會由於執行屢次致使的意外狀況),api接口支持任何語言來寫模塊,ansible不是以傳統的服務方式運行的,不須要常駐內存等資源,只用使用ansible命令的時候纔會用到。nginx

saltstack,也是基於python開發,可是要使用必須在被操做的機器上也裝上saltstack服務,並且嚴格分主控端和被控端。git

puppet,功能強大,配置複雜,適合超大型的環境,基於的開發語言是ruby,想作二次開發難度大。github

B:ansible的安裝:

ansible的rpm安裝,EPEL源。web

yum install ansible正則表達式

編譯安裝:

yum -y install python-jinja2 PyYAML python-paramiko python-bable python-crypto

tar -zxvf ansible1.5.4.tar.gz

cd ansible

python setup.py build

python setup.py install

mkdir /etc/ansible

cp -r examples/* /etc/ansible

git方式安裝:

git clone git://github.com/ansible/ansible.git/ansible.git --recursive(此方法安裝的版本都是最新的版本,特定版本的不建議此安裝方式)

cd ./ansible

source ./hacking/env-setup

pip安裝:

yun -y install python-pip python-devel

yum -y install gcc glibc-devel zibl-devel rpm-bulid openssl-devel

pip install --upgrade pip

pip install ansible --upgrade

安裝以後執行ansible --version能看到版本就爲成功。

(注:只須要安裝主控端,被控端不須要安裝,可是被控端要安裝openssh遠程服務)

[root@ansible ypc.soft]# ansible --version
ansible 2.6.8  #看到版本是2.6.8
  config file = /etc/ansible/ansible.cfg  #配置文件所在路徑
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.6/site-packages/ansible
  executable location = /usr/bin/ansible #依賴的python版本
  python version = 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) [GCC 4.4.7 20120313 (Red Hat 4.4.7-17)]
ansible --version

C:ansible的相關文件:

配置文件:

/etc/ansible/ansible.cfg (主配置文件,配置ansible的工做特性)

#inventory      = /etc/ansible/hosts 主機列表清單配置文件位置
#library        = /usr/share/my_modules/  庫文件存放位置
#remote_tmp     = ~/.ansible/tmp 臨時py命令存放遠程主機的目錄
ansible的工做原理是當用戶執行命令,那麼ansible會產生一個py的腳本,這個腳本里面記錄的是用戶的執行命令,而後經過ssh遠程放到被控端家目錄.ansible/tmp/下,執行完成以後.ansible/tmp就會自動刪除。
#forks          = 5 默認併發數,ansible在執行一個任務的時候不是一臺機器一臺機器去執行的,是同一時間執行5臺機器,固然機器配置好的時候能夠調整至更大的指,通常默認便可
#sudo_user      = root 默認sudo用戶。
#ask_sudo_pass = True 每次執行ansible命令是否詢問ssh密碼
#remote_port    = 22 默認ssh遠程端口是22
log_path = /var/log/ansible.log 日誌文件,ansible默認是沒有開啓日誌記錄的,這個要取消註釋
host_key_checking = False 檢查服務的host_key,建議取消註釋
ansible.conf配置文件

/etc/ansible/hosts       (主機清單)

例如我主控端是(192.168.219.135)
我須要在主控端增長主機的ip地址
host配置以下:
192.168.219.136
192.168.219.137
在文件末尾增長兩臺被控端機器的ip,可是這種方式咱們每次執行都須要在命令行輸入兩臺機器的ip地址,十分不方便。
這個時候咱們就能夠寫成組的方式:
host配置以下
[web]
192.168.219.136
192.168.219.137
在ip前面加上一個組名用中括號定義便可
主機清單

/etc/ansible/roles       (存放角色的目錄)

程序

/usr/bin/ansible         (主程序,臨時命令執行工具)

/usr/bin/ansible-doc     (查看配置文檔,模塊功能查看工具)

/usr/bin/ansible-galaxy   (下載/上傳優秀代碼或roles模塊的官網平臺)

/usr/bin/ansible-playbook  (定製自動化任務,編排劇本工具)

/usr/bin/ansible-vault     (文件加密工具)

/usr/bin/ansible-console   (基於console界面與用戶交互的執行工具)

/usr/bin/ansible-pull       (遠程執行命令工具)

ansible相關命令:

ansible-doc(至關於men幫助,主要查看模塊的詳細使用方法)

ansible-doc ping  (查看指定模塊的使用方法和參數)
> PING    (/usr/lib/python2.6/site-packages/ansible/modules/system/ping.py)


[root@ansible .ssh]# ansible-doc -l  (列出全部模塊)
a10_server                                           Manage A10 Networks AX...
a10_server_axapi3                                    Manage A10 Networks AX...

[root@ansible .ssh]# ansible-doc -s ping (查看指定模塊的用法,簡易模式顯示)
- name: Try to connect to host, verify a usable python and return `pong' on suc
  ping:
ansible-doc示例  

ansible-playbook

ansible-vault

ansible-console

ansible-galaxy

ansible-pull

ansible的參數:

--version(顯示版本號),-v(詳細過程)-vv,-vvv(最詳細),-k輸入ssh鏈接密碼,默認key驗證,--list(顯示主機列表),-K(輸入sudo的密碼),-C(檢查並不執行),-T(執行命令超時的時間,默認10s),-u(指定用戶鏈接),-b(代替舊版本的sudo)

D:ansible的基本使用:

基本語法:

ansible (主機清單組名) -m (模塊名) -a (執行參數或命令)

ansible的主機模式:

[root@ansible .ssh]# ansible "w*" -m ping
192.168.219.137 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.219.136 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[root@ansible .ssh]#

[root@ansible .ssh]# ansible 192.168.219.* -m ping
192.168.219.136 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.219.137 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[root@ansible .ssh]#
*:通配符
或關係
[root@ansible .ssh]# ansible "web:&dbserver" -m ping
192.168.219.136 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.219.137 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[root@ansible .ssh]#
邏輯與
ansible "web:!dbserver" -m ping
邏輯非

固然也支持正則表達式,不過極少用。

ping模塊

[root@ansible ansible]# ansible web -m ping -k
SSH password:
192.168.219.137 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.219.136 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[root@ansible ansible]#

web是咱們以前配置的組名
-m後面更上模塊名
-k是指定輸入ssh用戶名的密碼,固然若是是基於key驗證的ssh就不須要-k參數
能夠看到結果列出了主機名,ping以後對端迴應pong就表明執行成功了

使用ssh-keygen命令產生公鑰,使用ssh-copy-id 192.168.219.136和ssh-copy-id 192.168.219.137把公鑰傳輸到被控端便可完成基於key驗證。
[root@ansible ansible]# ansible web -m ping
192.168.219.137 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
192.168.219.136 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
[root@ansible ansible]#
-k參數就不須要加了,也不須要輸入密碼了
ping模塊使用

 上面咱們說ansible是基於openssh來進行遠程操做的,若是新環境的ip第一次鏈接的話,會有提示不可鏈接的錯誤,這個是由於主控端並無和被控端進行過鏈接,在正常的狀況下若是你使用ssh遠程登陸對端機器都須要輸入下yes才能鏈接,ansible走的是ssh的遠程,因此也須要經過ssh的yes驗證以後才能不會出錯,固然這個問題的前提是沒有基於key驗證的狀況下,也就是加了-k參數的狀況下會出現,那麼咱們實際環境中確定會存在新環境接入的時候出現首次驗證的問題,咱們還能夠經過ansible的配置文件取消首次驗證基於key的驗證問題。

# uncomment this to disable SSH key host checking
host_key_checking = False
將host_key_checking = False這行取消註釋
取消基於key

 非root用戶的使用ansible操做

[root@ansible .ssh]# ansible web -m command -a 'ls /root' -u mysql
192.168.219.137 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).\r\n",
    "unreachable": true
}
192.168.219.136 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).\r\n",
    "unreachable": true
}

能夠看到沒有進行sudo受權的狀況下,是會報錯的,提示須要輸入sudo用戶密碼

[root@ansible .ssh]# ansible web -m command -a 'ls /root' -u mysql -k -b -K
SSH password:
SUDO password[defaults to SSH password]: #加上-K輸入sudo密碼
192.168.219.137 | FAILED | rc=2 >>
ls: cannot open directory /root: Permission deniednon-zero return code

192.168.219.136 | FAILED | rc=2 >>
ls: cannot open directory /root: Permission deniednon-zero return code

如今又會出現另一個問題就是mysql用戶沒有在控制端sudo受權過
到控制端執行visudo
## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL
把wheel這行註釋取消掉
而後在命令行執行命令,將mysql用戶加到組裏面去
[root@web1 ~]# usermod -aG wheel mysql
同時SUDO password[defaults to SSH password]:這個sudo的密碼我不想輸入,也能夠在visudo裏面取消註釋:
## Same thing without a password
%wheel  ALL=(ALL)       NOPASSWD: ALL
[root@ansible .ssh]# ansible web -m command -a 'ls /root' -u mysql -k -b
SSH password:
192.168.219.137 | SUCCESS | rc=0 >>
anaconda-ks.cfg
Desktop
Documents
Downloads
install.log
install.log.syslog
Music
Pictures
Public
Templates
Videos

192.168.219.136 | SUCCESS | rc=0 >>
anaconda-ks.cfg
Desktop
Documents
Downloads
install.log
install.log.syslog
Music
Pictures
Public
Templates
Videos
#能夠看到非root用戶登陸須要那些操做
非root用戶

♣二:ansible的簡單操做

A:ansible的經常使用模塊

ansible默認模塊是command,若是是簡單的操做不須要在-m後面指定command模塊,直接-m便可。

上面咱們已經使用過了ping模塊,因ansible模塊已經有接近2千個模塊了,並且還在增加,咱們只學一些經常使用的模塊,後續有須要用到其餘模塊直接查看幫助也能完成。

shell模塊和command類似,用於執行shell命令。 

[root@ansible ~]# ansible-doc -s shell
- name: Execute commands in nodes.
  shell:
      chdir:                 # cd into this directory before running the command
      creates:               # a filename, when it already exists, this step will *not* be run.
      executable:            # change the shell used to execute the command. Should be an absolute path to the executable.
      free_form:             # (required) The shell module takes a free form command to run, as a string.  There's not an actual option named "free
                               form".  See the examples!
      removes:               # a filename, when it does not exist, this step will *not* be run.
      stdin:                 # Set the stdin of the command directly to the specified value.
      warn:                  # if command warnings are on in ansible.cfg, do not warn about this particular line if set to no/false.
[root@ansible ~]#
shell模塊幫助

因shell模塊不是默認模塊,-m後面就必須指定模塊名稱了。

ansible all -m shell -a 'echo $HOSTNAME'

ansible all -m shell -a 'mkdir -r /root/ansible'

shell模塊能完成command不能完成的操做,好比特殊符號等,並且command能完成的shell模塊也能完成。

script模塊:

[root@ansible ~]# ansible-doc -s script
- name: Runs a local script on a remote node after transferring it
  script:
      chdir:                 # cd into this directory on the remote node before running the script
      creates:               # a filename, when it already exists, this step will *not* be run.
      decrypt:               # This option controls the autodecryption of source files using vault.
      executable:            # Name or path of a executable to invoke the script with
      free_form:             # (required) Path to the local script file followed by optional arguments. There is no parameter actually named 'free form';
                               see the examples!
      removes:               # a filename, when it does not exist, this step will *not* be run.
[root@ansible ~]#
script模塊幫助

 在傳統的模式下,咱們要在被控機執行本機(主控端)上一個寫好的腳本,及時有ansible也須要把腳本傳輸到被控機上,而後執行ansible的shell模塊來執行腳本,那麼前面的傳輸的操做就會變得有點麻煩。並且不還不能肯定全部機器傳輸的時候都能給到執行權限,這樣的狀況下,你還得給這些被控端機器上腳本執行權限。

script模塊直接在本機雲信,無需傳輸。

[root@ansible ansible.test]# pwd
/home/ansible.test
[root@ansible ansible.test]# cat test.sh
#!/bin/bash
hostname
[root@ansible ansible.test]# ansible all -m script -a '/home/ansible.test/test.sh'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 192.168.219.137 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 192.168.219.137 closed."
    ],
    "stdout": "web2\r\n",
    "stdout_lines": [
        "web2"
    ]
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 192.168.219.136 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 192.168.219.136 closed."
    ],
    "stdout": "web1\r\n",
    "stdout_lines": [
        "web1"
    ]
}
[root@ansible ansible.test]#
script案例

copy模塊:

copy模塊用來批量傳輸文件,例如服務的配置文件等。

ansible db -m copy -a 'src=源路徑下文件 dest=目標路徑(路徑必須存在)'

[root@ansible ansible.test]# ansible-doc -s copy
- name: Copies files to remote locations
  copy:
      attributes:            # Attributes the file or directory should have. To get supported flags look at the man page for `chattr' on the target
                               system. This string should contain the attributes in the same order as the one displayed by
                               `lsattr'.
      backup:                # Create a backup file including the timestamp information so you can get the original file back if you somehow clobbered it
                               incorrectly.
      checksum:              # SHA1 checksum of the file being transferred. Used to validate that the copy of the file was successful. If this is not
                               provided, ansible will use the local calculated checksum of the src file.
      content:               # When used instead of `src', sets the contents of a file directly to the specified value. For anything advanced or with
                               formatting also look at the template module.
      decrypt:               # This option controls the autodecryption of source files using vault.
      dest:                  # (required) Remote absolute path where the file should be copied to. If `src' is a directory, this must be a directory too.
                               If `dest' is a nonexistent path and if either `dest' ends with "/" or `src' is a directory,
                               `dest' is created. If `src' and `dest' are files, the parent directory of `dest' isn't
                               created: the task fails if it doesn't already exist.
      directory_mode:        # When doing a recursive copy set the mode for the directories. If this is not set we will use the system defaults. The mode
                               is only set on directories which are newly created, and will not affect those that already
                               existed.
      follow:                # This flag indicates that filesystem links in the destination, if they exist, should be followed.
      force:                 # the default is `yes', which will replace the remote file when contents are different than the source. If `no', the file
                               will only be transferred if the destination does not exist.
      group:                 # Name of the group that should own the file/directory, as would be fed to `chown'.
      local_follow:          # This flag indicates that filesystem links in the source tree, if they exist, should be followed.
      mode:                  # Mode the file or directory should be. For those used to `/usr/bin/chmod' remember that modes are actually octal numbers.
                               You must either specify the leading zero so that Ansible's YAML parser knows it is an octal
                               number (like `0644' or `01777') or quote it (like `'644'' or `'0644'' so Ansible receives a
                               string and can do its own conversion from string into number.  Giving Ansible a number
                               without following one of these rules will end up with a decimal number which will have
                               unexpected results.  As of version 1.8, the mode may be specified as a symbolic mode (for
                               example, `u+rwx' or `u=rw,g=r,o=r').  As of version 2.3, the mode may also be the special
                               string `preserve'.  `preserve' means that the file will be given the same permissions as
                               the source file.
      owner:                 # Name of the user that should own the file/directory, as would be fed to `chown'.
      remote_src:            # If `no', it will search for `src' at originating/master machine. If `yes' it will go to the remote/target machine for the
                               `src'. Default is `no'. Currently `remote_src' does not support recursive copying.
                               `remote_src' only works with `mode=preserve' as of version 2.6.
      selevel:               # Level part of the SELinux file context. This is the MLS/MCS attribute, sometimes known as the `range'. `_default' feature
                               works as for `seuser'.
      serole:                # Role part of SELinux file context, `_default' feature works as for `seuser'.
      setype:                # Type part of SELinux file context, `_default' feature works as for `seuser'.
      seuser:                # User part of SELinux file context. Will default to system policy, if applicable. If set to `_default', it will use the
                               `user' portion of the policy if available.
      src:                   # Local path to a file to copy to the remote server; can be absolute or relative. If path is a directory, it is copied
                               recursively. In this case, if path ends with "/", only inside contents of that directory
                               are copied to destination. Otherwise, if it does not end with "/", the directory itself
                               with all contents is copied. This behavior is similar to Rsync.
      unsafe_writes:         # Normally this module uses atomic operations to prevent data corruption or inconsistent reads from the target files,
                               sometimes systems are configured or just broken in ways that prevent this. One example are
                               docker mounted files, they cannot be updated atomically and can only be done in an unsafe
                               manner. This boolean option allows ansible to fall back to unsafe methods of updating files
                               for those cases in which you do not have any other choice. Be aware that this is subject to
                               race conditions and can lead to data corruption.
      validate:              # The validation command to run before copying into place. The path to the file to validate is passed in via '%s' which must
                               be present as in the example below. The command is passed securely so shell features like
                               expansion and pipes won't work.
(END)
copy模塊幫助
1 backup:在覆蓋以前將原文件備份,備份文件包含時間信息。有兩個選項:yes|no 
2 content:用於替代"src",能夠直接設定指定文件的值 
3 dest:必選項。要將源文件複製到的遠程主機的絕對路徑,若是源文件是一個目錄,那麼該路徑也必須是個目錄 
4 directory_mode:遞歸的設定目錄的權限,默認爲系統默認權限
5 force:若是目標主機包含該文件,但內容不一樣,若是設置爲yes,則強制覆蓋,若是爲no,則只有當目標主機的目標位置不存在該文件時,才複製。默認爲yes
6 others:全部的file模塊裏的選項均可以在這裏使用
7 src:要複製到遠程主機的文件在本地的地址,能夠是絕對路徑,也能夠是相對路徑。若是路徑是一個目錄,它將遞歸複製。在這種狀況下,若是路徑使用"/"來結尾,則只複製目錄裏的內容,若是沒有使用"/"來結尾,則包含目錄在內的整個內容所有複製,相似於rsync。 
8 validate :The validation command to run before copying into place. The path to the file to validate is passed in via '%s' which must be present as in the visudo example below.
經常使用選項
[root@ansible ansible.test]# ansible all -m copy -a 'src=/home/ansible.test/copy_test.conf dest=/home/copy_test.conf'
192.168.219.136 | SUCCESS => {
    "changed": true,
    "checksum": "5ffd53c0987ac64d0a82a8c97978afe8f02d7b5a",
    "dest": "/home/copy_test.conf",
    "gid": 0,
    "group": "root",
    "md5sum": "40488fea7fe48f99ea02e86166a0bc9d",
    "mode": "0644",
    "owner": "root",
    "size": 28,
    "src": "/root/.ansible/tmp/ansible-tmp-1550554363.16-165811746367830/source",
    "state": "file",
    "uid": 0
}
192.168.219.137 | SUCCESS => {
    "changed": true,
    "checksum": "5ffd53c0987ac64d0a82a8c97978afe8f02d7b5a",
    "dest": "/home/copy_test.conf",
    "gid": 0,
    "group": "root",
    "md5sum": "40488fea7fe48f99ea02e86166a0bc9d",
    "mode": "0644",
    "owner": "root",
    "size": 28,
    "src": "/root/.ansible/tmp/ansible-tmp-1550554363.16-162669317189243/source",
    "state": "file",
    "uid": 0
}
[root@ansible ansible.test]# ansible all -a 'ls /home'
192.168.219.136 | SUCCESS | rc=0 >>
centos12
copy_test.conf
mysql
ypc.soft

192.168.219.137 | SUCCESS | rc=0 >>
centos13
copy_test.conf
mysql

[root@ansible ansible.test]#
copy模塊案例

fetch模塊:

既然咱們能將主控端的文件拷貝到被控端機器上,ansible固然也提供了能夠將被控端機器上文件抓取到主控端的功能,例如咱們須要把被控端的日誌等文件抓取到主控端統一進行分析。

注:fetch模塊只能一次抓取一個文件且不能是目錄。固然不是沒有辦法,能夠經過shell模塊把被控端目錄或者多個文件進行打包在抓取過來。

[root@ansible ansible.test]# ansible-doc -s fetch
- name: Fetches a file from remote nodes
  fetch:
      dest:                  # (required) A directory to save the file into. For example, if the `dest' directory is `/backup' a `src' file named
                               `/etc/profile' on host `host.example.com', would be saved into
                               `/backup/host.example.com/etc/profile'
      fail_on_missing:       # When set to 'yes', the task will fail if the remote file cannot be read for any reason.  Prior to Ansible-2.5, setting
                               this would only fail if the source file was missing. The default was changed to "yes" in
                               Ansible-2.5.
      flat:                  # Allows you to override the default behavior of appending hostname/path/to/file to the destination.  If dest ends with '/',
                               it will use the basename of the source file, similar to the copy module. Obviously this is
                               only handy if the filenames are unique.
      src:                   # (required) The file on the remote system to fetch. This `must' be a file, not a directory. Recursive fetching may be
                               supported in a later release.
      validate_checksum:     # Verify that the source and destination checksums match after the files are fetched.
[root@ansible ansible.test]#
fetch模塊幫助
[root@ansible ansible.test]# ansible all -m fetch -a 'src=/etc/passwd dest=/home/ansible.test/test'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "checksum": "edf3216846dae3f593314cf07b8d8f328e58f067",
    "dest": "/home/ansible.test/test/192.168.219.137/etc/passwd",
    "md5sum": "86e07804c44a27941e1fc798a5779756",
    "remote_checksum": "edf3216846dae3f593314cf07b8d8f328e58f067",
    "remote_md5sum": null
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "checksum": "65a433c99ff5ce054264be87594828c83989aa0e",
    "dest": "/home/ansible.test/test/192.168.219.136/etc/passwd",
    "md5sum": "891484511715765f25fd7c4fa67f8288",
    "remote_checksum": "65a433c99ff5ce054264be87594828c83989aa0e",
    "remote_md5sum": null
}
[root@ansible ansible.test]# tree test
test
├── 192.168.219.136
│   └── etc
│       └── passwd
└── 192.168.219.137
    └── etc
        └── passwd

4 directories, 2 files

[root@ansible ansible.test]# cd test
[root@ansible test]# ls
192.168.219.136  192.168.219.137
[root@ansible test]# cd 192.168.219.136
[root@ansible 192.168.219.136]# ls
etc
[root@ansible 192.168.219.136]# cd etc/
[root@ansible etc]# ls
passwd
[root@ansible etc]#
#能夠看到在test下各自建立了一個屬於被控端機器ip的目錄,抓取的文件都放在這個目錄下面,方便區分
fetch案例
[root@ansible etc]# ansible all -m shell -a 'tar Jcf log.tar.xz /var/log/*.log'
 [WARNING]: Consider using the unarchive module rather than running tar.  If you
need to use command because unarchive is insufficient you can add warn=False to
this command task or set command_warnings=False in ansible.cfg to get rid of this
message.

192.168.219.137 | SUCCESS | rc=0 >>
tar: Removing leading `/' from member names

192.168.219.136 | SUCCESS | rc=0 >>
tar: Removing leading `/' from member names

[root@ansible etc]# ansible all -m shell -a 'ls -h'
192.168.219.136 | SUCCESS | rc=0 >>
anaconda-ks.cfg
Desktop
Documents
Downloads
install.log
install.log.syslog
log.tar.xz
Music
Pictures
Public
Templates
Videos

192.168.219.137 | SUCCESS | rc=0 >>
anaconda-ks.cfg
Desktop
Documents
Downloads
install.log
install.log.syslog
log.tar.xz
Music
Pictures
Public
Templates
Videos

[root@ansible etc]# ansible all -m shell -a 'pwd'
192.168.219.137 | SUCCESS | rc=0 >>
/root

192.168.219.136 | SUCCESS | rc=0 >>
/root

[root@ansible etc]# ansible all -m fetch -a 'src=/root/log.tar.xz dest=/home/ansible.test/test/'
192.168.219.136 | SUCCESS => {
    "changed": true,
    "checksum": "893ff89ed3394cf7a94e6b4d2aca694a7b8f4f9e",
    "dest": "/home/ansible.test/test/192.168.219.136/root/log.tar.xz",
    "md5sum": "bc8e9ac43907b51c4e1e31b786e1e1ef",
    "remote_checksum": "893ff89ed3394cf7a94e6b4d2aca694a7b8f4f9e",
    "remote_md5sum": null
}
192.168.219.137 | SUCCESS => {
    "changed": true,
    "checksum": "9662827bc0da5854fe108a9847e1df4986388cfd",
    "dest": "/home/ansible.test/test/192.168.219.137/root/log.tar.xz",
    "md5sum": "9216f8c9dd0e41058d6ef3ca77f1919e",
    "remote_checksum": "9662827bc0da5854fe108a9847e1df4986388cfd",
    "remote_md5sum": null
}
[root@ansible ansible.test]# tree test
test
├── 192.168.219.136
│   ├── etc
│   │   └── passwd
│   └── root
│       └── log.tar.xz
└── 192.168.219.137
    ├── etc
    │   └── passwd
    └── root
        └── log.tar.xz

6 directories, 4 files
[root@ansible ansible.test]#
能夠看到多個文件已經被抓取過來了
打包抓取多個文件

cron模塊:計劃任務模塊

cron模塊格式:

ansible 主機清單名 -m cron -a 'minute="分鐘" hour="時" day="日" month="月" weekday="周" job="計劃任務內容" name="計劃任務名稱(必填)" state="添加(present默認)和absent(移除)"'

[root@ansible ~]# ansible-doc -s cron
- name: Manage cron.d and crontab entries
  cron:
      backup:                # If set, create a backup of the crontab before it is modified. The location of the backup is returned in the `backup_file'
                               variable by this module.
      cron_file:             # If specified, uses this file instead of an individual user's crontab. If this is a relative path, it is interpreted with
                               respect to /etc/cron.d. (If it is absolute, it will typically be /etc/crontab). Many linux
                               distros expect (and some require) the filename portion to consist solely of upper- and
                               lower-case letters, digits, underscores, and hyphens. To use the `cron_file' parameter you
                               must specify the `user' as well.
      day:                   # Day of the month the job should run ( 1-31, *, */2, etc )
      disabled:              # If the job should be disabled (commented out) in the crontab. Only has effect if `state=present'.
      env:                   # If set, manages a crontab's environment variable. New variables are added on top of crontab. "name" and "value" parameters
                               are the name and the value of environment variable.
      hour:                  # Hour when the job should run ( 0-23, *, */2, etc )
      insertafter:           # Used with `state=present' and `env'. If specified, the environment variable will be inserted after the declaration of
                               specified environment variable.
      insertbefore:          # Used with `state=present' and `env'. If specified, the environment variable will be inserted before the declaration of
                               specified environment variable.
      job:                   # The command to execute or, if env is set, the value of environment variable. The command should not contain line breaks.
                               Required if state=present.
      minute:                # Minute when the job should run ( 0-59, *, */2, etc )
      month:                 # Month of the year the job should run ( 1-12, *, */2, etc )
      name:                  # Description of a crontab entry or, if env is set, the name of environment variable. Required if state=absent. Note that if
                               name is not set and state=present, then a new crontab entry will always be created,
                               regardless of existing ones.
      reboot:                # If the job should be run at reboot. This option is deprecated. Users should use special_time.
      special_time:          # Special time specification nickname.
      state:                 # Whether to ensure the job or environment variable is present or absent.
      user:                  # The specific user whose crontab should be modified.
      weekday:               # Day of the week that the job should run ( 0-6 for Sunday-Saturday, *, etc )
[root@ansible ~]# 

 1 backup:對遠程主機上的原任務計劃內容修改以前作備份 
 2 cron_file:若是指定該選項,則用該文件替換遠程主機上的cron.d目錄下的用戶的任務計劃 
 3 day:日(1-31,*,*/2,……) 
 4 hour:小時(0-23,*,*/2,……)  
 5 minute:分鐘(0-59,*,*/2,……) 
 6 month:月(1-12,*,*/2,……) 
 7 weekday:周(0-7,*,……)
 8 job:要執行的任務,依賴於state=present 
 9 name:該任務的描述 
10 special_time:指定何時執行,參數:reboot,yearly,annually,monthly,weekly,daily,hourly 
11 state:確認該任務計劃是建立仍是刪除 
12 user:以哪一個用戶的身份執行
幫助信息
[root@ansible ~]# ansible all -m cron -a 'minute="*/1" job="/bin/echo hello ansible" name="test cron job" state="present"'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": [
        "kk",
        "test cron job"
    ]
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": [
        "kk",
        "test cron job"
    ]
}
[root@ansible ~]#

136:
[root@web1 ~]# crontab -l
#Ansible: test cron job
*/1 * * * * /bin/echo hello ansible
[root@web1 ~]#

137#Ansible: test cron job
*/1 * * * * /bin/echo hello ansible
You have new mail in /var/spool/mail/root
[root@web2 ~]#
corn案例present添加
[root@ansible ~]# ansible all -m cron -a 'minute="*/1" job="/bin/echo hello ansible" name="test cron job" state="absent"'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": []
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": []
}
[root@ansible ~]#

136:
[root@web1 ~]# crontab -l
You have new mail in /var/spool/mail/root
[root@web1 ~]#

[root@web2 ~]# crontab -l
You have new mail in /var/spool/mail/root
[root@web2 ~]#
corn案例absent移除
[root@ansible ~]# ansible all -m cron -a 'disabled=yes job="/usr/bin/wall FBI warning" name=kk'
192.168.219.136 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": [
        "test cron job",
        "kk"
    ]
}
192.168.219.137 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": [
        "test cron job",
        "kk"
    ]
}
[root@ansible ~]# ansible all -m shell -a 'crontab -l'
192.168.219.136 | SUCCESS | rc=0 >>
#Ansible: test cron job
*/1 * * * * /bin/echo hello ansible
#Ansible: kk
#* * * * * /usr/bin/wall FBI warning

192.168.219.137 | SUCCESS | rc=0 >>
#Ansible: test cron job
*/1 * * * * /bin/echo hello ansible
#Ansible: kk
#* * * * * /usr/bin/wall FBI warning
發現新加的計劃任務就是註釋的
ansible案例註釋計劃任務
[root@ansible ~]# ansible all -m cron -a 'disabled=no job="/usr/bin/wall FBI warning" name=kk'
192.168.219.136 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": [
        "test cron job",
        "kk"
    ]
}
192.168.219.137 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": [
        "test cron job",
        "kk"
    ]
}
[root@ansible ~]# ansible all -m shell -a 'crontab -l'
192.168.219.136 | SUCCESS | rc=0 >>
#Ansible: test cron job
*/1 * * * * /bin/echo hello ansible
#Ansible: kk
* * * * * /usr/bin/wall FBI warning

192.168.219.137 | SUCCESS | rc=0 >>
#Ansible: test cron job
*/1 * * * * /bin/echo hello ansible
#Ansible: kk
* * * * * /usr/bin/wall FBI warning
能夠看到計劃任務註釋取消掉了,disable後面能夠接yes/no,還能夠是ture和flase
ansible案例取消註釋計劃任務

yum模塊:

批量經過yum安裝服務便可使用yum模塊。

[root@ansible ~]# ansible-doc -s yum
- name: Manages packages with the `yum' package manager
  yum:
      allow_downgrade:       # Specify if the named package and version is allowed to downgrade a maybe already installed higher version of that package.
                               Note that setting allow_downgrade=True can make this module behave in a non-idempotent way.
                               The task could end up with a set of packages that does not match the complete list of
                               specified packages to install (because dependencies between the downgraded package and
                               others can cause changes to the packages which were in the earlier transaction).
      bugfix:                # If set to `yes', and `state=latest' then only installs updates that have been marked bugfix related.
      conf_file:             # The remote yum configuration file to use for the transaction.
      disable_gpg_check:     # Whether to disable the GPG checking of signatures of packages being installed. Has an effect only if state is `present' or
                               `latest'.
      disable_plugin:        # `Plugin' name to disable for the install/update operation. The disabled plugins will not persist beyond the transaction.
      disablerepo:           # `Repoid' of repositories to disable for the install/update operation. These repos will not persist beyond the transaction.
                               When specifying multiple repos, separate them with a ",".
      enable_plugin:         # `Plugin' name to enable for the install/update operation. The enabled plugin will not persist beyond the transaction.
      enablerepo:            # `Repoid' of repositories to enable for the install/update operation. These repos will not persist beyond the transaction.
                               When specifying multiple repos, separate them with a ",".
      exclude:               # Package name(s) to exclude when state=present, or latest
      installroot:           # Specifies an alternative installroot, relative to which all packages will be installed.
      list:                  # Package name to run the equivalent of yum list <package> against. In addition to listing packages, use can also list the
                               following: `installed', `updates', `available' and `repos'.
      name:                  # A package name or package specifier with version, like `name-1.0'. If a previous version is specified, the task also needs
                               to turn `allow_downgrade' on. See the `allow_downgrade' documentation for caveats with
                               downgrading packages. When using state=latest, this can be '*' which means run `yum -y
                               update'. You can also pass a url or a local path to a rpm file (using state=present). To
                               operate on several packages this can accept a comma separated list of packages or (as of
                               2.0) a list of packages.
      security:              # If set to `yes', and `state=latest' then only installs updates that have been marked security related.
      skip_broken:           # Resolve depsolve problems by removing packages that are causing problems from the trans‐ action.
      state:                 # Whether to install (`present' or `installed', `latest'), or remove (`absent' or `removed') a package. `present' and
                               `installed' will simply ensure that a desired package is installed. `latest' will update
                               the specified package if it's not of the latest available version. `absent' and `removed'
                               will remove the specified package.
      update_cache:          # Force yum to check if cache is out of date and redownload if needed. Has an effect only if state is `present' or `latest'.
      update_only:           # When using latest, only update installed packages. Do not install packages. Has an effect only if state is `latest'
      validate_certs:        # This only applies if using a https url as the source of the rpm. e.g. for localinstall. If set to `no', the SSL
                               certificates will not be validated. This should only set to `no' used on personally
                               controlled sites using self-signed certificates as it avoids verifying the source site.
                               Prior to 2.1 the code worked as if this was set to `yes'.
(END)
yum模塊幫助
name參數:必須參數,用於指定要操做的惟一的倉庫ID,也就是」.repo」配置文件中每一個倉庫對應的」中括號」內的倉庫ID。

baseurl參數:此參數用於設置 yum 倉庫的 baseurl。

description參數:此參數用於設置倉庫的註釋信息,也就是」.repo」配置文件中每一個倉庫對應的」name字段」對應的內容。

file參數:此參數用於設置倉庫的配置文件名稱,即設置」.repo」配置文件的文件名前綴,在不使用此參數的狀況下,默認以 name 參數的倉庫ID做爲」.repo」配置文件的文件名前綴,同一個」.repo」 配置文件中能夠存在多個 yum 源。

enabled參數:此參數用於設置是否激活對應的 yum 源,此參數默認值爲 yes,表示啓用對應的 yum 源,設置爲 no 表示不啓用對應的 yum 源。

gpgcheck參數:此參數用於設置是否開啓 rpm 包驗證功能,默認值爲 no,表示不啓用包驗證,設置爲 yes 表示開啓包驗證功能。

gpgcakey參數:當 gpgcheck 參數設置爲 yes 時,須要使用此參數指定驗證包所需的公鑰。

state參數:默認值爲 present,當值設置爲 absent 時,表示刪除對應的 yum 源。
參數詳解
卸載httpd服務
[root@ansible ~]# ansible all -m yum -a 'state=removed name=httpd'
192.168.219.136 | SUCCESS => {
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror, refresh-packagekit, security\nSetting up Remove Process\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.2.15-69.el6.centos will be erased\n--> Processing Dependency: httpd >= 2.2.0 for package: gnome-user-share-2.28.2-3.el6.x86_64\n--> Running transaction check\n---> Package gnome-user-share.x86_64 0:2.28.2-3.el6 will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package  Arch   Version         Repository                                Size\n================================================================================\nRemoving:\n httpd    x86_64 2.2.15-69.el6.centos\n                                 @base                                    3.0 M\nRemoving for dependencies:\n gnome-user-share\n          x86_64 2.28.2-3.el6    @anaconda-CentOS-201508042137.x86_64/6.7 1.1 M\n\nTransaction Summary\n================================================================================\nRemove        2 Package(s)\n\nInstalled size: 4.1 M\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r  Erasing    : gnome-user-share-2.28.2-3.el6.x86_64                         1/2 \n\r  Erasing    : httpd-2.2.15-69.el6.centos.x86_64                            2/2 \n\r  Verifying  : gnome-user-share-2.28.2-3.el6.x86_64                         1/2 \n\r  Verifying  : httpd-2.2.15-69.el6.centos.x86_64                            2/2 \n\nRemoved:\n  httpd.x86_64 0:2.2.15-69.el6.centos                                           \n\nDependency Removed:\n  gnome-user-share.x86_64 0:2.28.2-3.el6                                        \n\nComplete!\n"
    ]
}
192.168.219.137 | SUCCESS => {
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror, refresh-packagekit, security\nSetting up Remove Process\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.2.15-69.el6.centos will be erased\n--> Processing Dependency: httpd >= 2.2.0 for package: gnome-user-share-2.28.2-3.el6.x86_64\n--> Running transaction check\n---> Package gnome-user-share.x86_64 0:2.28.2-3.el6 will be erased\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package  Arch   Version         Repository                                Size\n================================================================================\nRemoving:\n httpd    x86_64 2.2.15-69.el6.centos\n                                 @base                                    3.0 M\nRemoving for dependencies:\n gnome-user-share\n          x86_64 2.28.2-3.el6    @anaconda-CentOS-201508042137.x86_64/6.7 1.1 M\n\nTransaction Summary\n================================================================================\nRemove        2 Package(s)\n\nInstalled size: 4.1 M\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r  Erasing    : gnome-user-share-2.28.2-3.el6.x86_64                         1/2 \n\r  Erasing    : httpd-2.2.15-69.el6.centos.x86_64                            2/2 \n\r  Verifying  : gnome-user-share-2.28.2-3.el6.x86_64                         1/2 \n\r  Verifying  : httpd-2.2.15-69.el6.centos.x86_64                            2/2 \n\nRemoved:\n  httpd.x86_64 0:2.2.15-69.el6.centos                                           \n\nDependency Removed:\n  gnome-user-share.x86_64 0:2.28.2-3.el6                                        \n\nComplete!\n"
    ]
}
[root@ansible ~]# ansible all -m shell -a 'httpd -v'
192.168.219.137 | FAILED | rc=127 >>
/bin/sh: httpd: command not foundnon-zero return code

192.168.219.136 | FAILED | rc=127 >>
/bin/sh: httpd: command not foundnon-zero return code

安裝httpd服務
[root@ansible ~]# ansible all -m yum -a 'state=present name=httpd'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror, refresh-packagekit, security\nSetting up Install Process\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * epel: mirrors.huaweicloud.com\n * extras: mirrors.cn99.com\n * updates: mirror.bit.edu.cn\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.2.15-69.el6.centos will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package       Arch           Version                        Repository    Size\n================================================================================\nInstalling:\n httpd         x86_64         2.2.15-69.el6.centos           base         836 k\n\nTransaction Summary\n================================================================================\nInstall       1 Package(s)\n\nTotal download size: 836 k\nInstalled size: 3.0 M\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r  Installing : httpd-2.2.15-69.el6.centos.x86_64                            1/1 \n\r  Verifying  : httpd-2.2.15-69.el6.centos.x86_64                            1/1 \n\nInstalled:\n  httpd.x86_64 0:2.2.15-69.el6.centos                                           \n\nComplete!\n"
    ]
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror, refresh-packagekit, security\nSetting up Install Process\nLoading mirror speeds from cached hostfile\n * base: mirrors.cqu.edu.cn\n * epel: mirrors.yun-idc.com\n * extras: mirrors.cqu.edu.cn\n * updates: mirrors.cqu.edu.cn\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.2.15-69.el6.centos will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package       Arch           Version                        Repository    Size\n================================================================================\nInstalling:\n httpd         x86_64         2.2.15-69.el6.centos           base         836 k\n\nTransaction Summary\n================================================================================\nInstall       1 Package(s)\n\nTotal download size: 836 k\nInstalled size: 3.0 M\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r  Installing : httpd-2.2.15-69.el6.centos.x86_64                            1/1 \n\r  Verifying  : httpd-2.2.15-69.el6.centos.x86_64                            1/1 \n\nInstalled:\n  httpd.x86_64 0:2.2.15-69.el6.centos                                           \n\nComplete!\n"
    ]
}
[root@ansible ~]# ansible all -m shell -a 'httpd -v'
192.168.219.137 | SUCCESS | rc=0 >>
Server version: Apache/2.2.15 (Unix)
Server built:   Jun 19 2018 15:45:13

192.168.219.136 | SUCCESS | rc=0 >>
Server version: Apache/2.2.15 (Unix)
Server built:   Jun 19 2018 15:45:13
卸載和安裝
[root@ansible ansible.test]# ansible all -m file -a 'name=/home/soft state=directory'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/home/soft",
    "size": 4096,
    "state": "directory",
    "uid": 0
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/home/soft",
    "size": 4096,
    "state": "directory",
    "uid": 0
}
[root@ansible ansible.test]# ansible all -m copy -a 'src=/home/ansible.test/htop-1.0.3-1.el6.rf.x86_64.rpm dest=/home/soft'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "checksum": "2deed7a9030c2963c677cce6ecaccb4750106052",
    "dest": "/home/soft/htop-1.0.3-1.el6.rf.x86_64.rpm",
    "gid": 0,
    "group": "root",
    "md5sum": "683cc37192a76556c0847aaf93459abf",
    "mode": "0644",
    "owner": "root",
    "size": 88608,
    "src": "/root/.ansible/tmp/ansible-tmp-1550738545.61-57323277206137/source",
    "state": "file",
    "uid": 0
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "checksum": "2deed7a9030c2963c677cce6ecaccb4750106052",
    "dest": "/home/soft/htop-1.0.3-1.el6.rf.x86_64.rpm",
    "gid": 0,
    "group": "root",
    "md5sum": "683cc37192a76556c0847aaf93459abf",
    "mode": "0644",
    "owner": "root",
    "size": 88608,
    "src": "/root/.ansible/tmp/ansible-tmp-1550738545.6-127862535278548/source",
    "state": "file",
    "uid": 0
}
[root@ansible ansible.test]# ansible all -m shell -a 'ls -h /home/soft'
192.168.219.136 | SUCCESS | rc=0 >>
htop-1.0.3-1.el6.rf.x86_64.rpm

192.168.219.137 | SUCCESS | rc=0 >>
htop-1.0.3-1.el6.rf.x86_64.rpm

[root@ansible ansible.test]# ansible all -m yum -a 'name=/home/soft/htop-1.0.3-1.el6.rf.x86_64.rpm'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror, refresh-packagekit, security\nSetting up Install Process\nExamining /home/soft/htop-1.0.3-1.el6.rf.x86_64.rpm: htop-1.0.3-1.el6.rf.x86_64\nMarking /home/soft/htop-1.0.3-1.el6.rf.x86_64.rpm to be installed\nLoading mirror speeds from cached hostfile\n * base: mirrors.aliyun.com\n * epel: mirrors.aliyun.com\n * extras: mirrors.163.com\n * updates: ftp.sjtu.edu.cn\nResolving Dependencies\n--> Running transaction check\n---> Package htop.x86_64 0:1.0.3-1.el6.rf will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package  Arch       Version              Repository                       Size\n================================================================================\nInstalling:\n htop     x86_64     1.0.3-1.el6.rf       /htop-1.0.3-1.el6.rf.x86_64     209 k\n\nTransaction Summary\n================================================================================\nInstall       1 Package(s)\n\nTotal size: 209 k\nInstalled size: 209 k\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r  Installing : htop-1.0.3-1.el6.rf.x86_64                                   1/1 \n\r  Verifying  : htop-1.0.3-1.el6.rf.x86_64                                   1/1 \n\nInstalled:\n  htop.x86_64 0:1.0.3-1.el6.rf                                                  \n\nComplete!\n"
    ]
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
        "Loaded plugins: fastestmirror, refresh-packagekit, security\nSetting up Install Process\nExamining /home/soft/htop-1.0.3-1.el6.rf.x86_64.rpm: htop-1.0.3-1.el6.rf.x86_64\nMarking /home/soft/htop-1.0.3-1.el6.rf.x86_64.rpm to be installed\nLoading mirror speeds from cached hostfile\n * base: centos.ustc.edu.cn\n * epel: mirror.premi.st\n * extras: mirrors.163.com\n * updates: mirrors.tuna.tsinghua.edu.cn\nResolving Dependencies\n--> Running transaction check\n---> Package htop.x86_64 0:1.0.3-1.el6.rf will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package  Arch       Version              Repository                       Size\n================================================================================\nInstalling:\n htop     x86_64     1.0.3-1.el6.rf       /htop-1.0.3-1.el6.rf.x86_64     209 k\n\nTransaction Summary\n================================================================================\nInstall       1 Package(s)\n\nTotal size: 209 k\nInstalled size: 209 k\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r  Installing : htop-1.0.3-1.el6.rf.x86_64                                   1/1 \n\r  Verifying  : htop-1.0.3-1.el6.rf.x86_64                                   1/1 \n\nInstalled:\n  htop.x86_64 0:1.0.3-1.el6.rf                                                  \n\nComplete!\n"
    ]
}
[root@ansible ansible.test]# ansible all -m shell -a 'htop -v'
192.168.219.136 | SUCCESS | rc=0 >>
htop 1.0.3 - (C) 2004-2012 Hisham Muhammad
Released under the GNU GPL.

192.168.219.137 | SUCCESS | rc=0 >>
htop 1.0.3 - (C) 2004-2012 Hisham Muhammad
Released under the GNU GPL.

[root@ansible ansible.test]#
能夠看到服務都已經安裝成功了
經過yum安裝單個包

 service模塊:

當咱們要批量啓動或關閉n臺機器上的服務的時候,ansible也能經過很簡單的操做就能夠完成。

[root@ansible ~]# ansible-doc -s service
- name: Manage services
  service:
      arguments:             # Additional arguments provided on the command line
      enabled:               # Whether the service should start on boot. *At least one of state and enabled are required.*
      name:                  # (required) Name of the service.
      pattern:               # If the service does not respond to the status command, name a substring to look for as would be found in the output of the
                               `ps' command as a stand-in for a status result.  If the string is found, the service will
                               be assumed to be running.
      runlevel:              # For OpenRC init scripts (ex: Gentoo) only.  The runlevel that this service belongs to.
      sleep:                 # If the service is being `restarted' then sleep this many seconds between the stop and start command. This helps to
                               workaround badly behaving init scripts that exit immediately after signaling a process to
                               stop.
      state:                 # `started'/`stopped' are idempotent actions that will not run commands unless necessary.  `restarted' will always bounce
                               the service.  `reloaded' will always reload. *At least one of state and enabled are
                               required.* Note that reloaded will start the service if it is not already started, even if
                               your chosen init system wouldn't normally.
      use:                   # The service module actually uses system specific modules, normally through auto detection, this setting can force a
                               specific module. Normally it uses the value of the 'ansible_service_mgr' fact and falls
                               back to the old 'service' module when none matching is found.
[root@ansible ~]#
service模塊幫助
[root@ansible ~]# ansible all -m shell -a 'httpd -v'
192.168.219.137 | SUCCESS | rc=0 >>
Server version: Apache/2.2.15 (Unix)
Server built:   Jun 19 2018 15:45:13

192.168.219.136 | SUCCESS | rc=0 >>
Server version: Apache/2.2.15 (Unix)
Server built:   Jun 19 2018 15:45:13

[root@ansible ~]# ansible all -m service -a 'name=httpd state=restarted enabled=yes'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "enabled": true,
    "name": "httpd",
    "state": "started"
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "enabled": true,
    "name": "httpd",
    "state": "started"
}
[root@ansible ~]# ansible all -m shell -a 'ps -aux | grep http'
192.168.219.137 | SUCCESS | rc=0 >>
root       3342  0.0  0.3 183896  3816 ?        Ss   13:16   0:00 /usr/sbin/httpd
apache     3345  0.0  0.2 184028  2500 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3346  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3347  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3348  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3349  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3350  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3351  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3352  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
root       3389  0.0  0.1 106096  1120 pts/1    S+   13:17   0:00 /bin/sh -c ps -aux | grep http
root       3391  0.0  0.0 103312   860 pts/1    S+   13:17   0:00 grep httpWarning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ

192.168.219.136 | SUCCESS | rc=0 >>
root       3323  0.0  0.3 183896  3824 ?        Ss   13:16   0:00 /usr/sbin/httpd
apache     3326  0.0  0.2 184028  2500 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3327  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3328  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3329  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3330  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3331  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3332  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
apache     3333  0.0  0.2 184028  2476 ?        S    13:16   0:00 /usr/sbin/httpd
root       3370  0.0  0.1 106096  1128 pts/1    S+   13:17   0:00 /bin/sh -c ps -aux | grep http
root       3372  0.0  0.0 103312   856 pts/1    S+   13:17   0:00 grep httpWarning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ

[root@ansible ~]# ansible all -m shell -a 'netstat -anptu | grep 80'
192.168.219.137 | SUCCESS | rc=0 >>
tcp        0      0 :::80                       :::*                        LISTEN      3342/httpd

192.168.219.136 | SUCCESS | rc=0 >>
tcp        0      0 :::80                       :::*                        LISTEN      3323/httpd

[root@ansible ~]# ansible all -m shell -a 'chkconfig httpd --list'
192.168.219.137 | SUCCESS | rc=0 >>
httpd           0:off   1:off   2:on    3:on    4:on    5:on    6:off

192.168.219.136 | SUCCESS | rc=0 >>
httpd           0:off   1:off   2:on    3:on    4:on    5:on    6:off

[root@ansible ~]#
啓動http服務並加入開機自啓

file模塊:

設置文件的屬性,所屬組等,軟鏈接,建立空目錄,遞歸刪除等。

[root@ansible ansible.test]# ansible all -m file -a 'name=/root/date state=touch'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "dest": "/root/date",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "state": "file",
    "uid": 0
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "dest": "/root/date",
    "gid": 0,
    "group": "root",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "state": "file",
    "uid": 0
}
[root@ansible ansible.test]# ansible all -m shell -a 'ls -h date'
192.168.219.137 | SUCCESS | rc=0 >>
date

192.168.219.136 | SUCCESS | rc=0 >>
date

[root@ansible ansible.test]#
flie模塊案例(建立一個空目錄)
[root@ansible ansible.test]# ansible all -m shell -a 'ls -l date'
192.168.219.137 | SUCCESS | rc=0 >>
-rw-r--r-- 1 root root 0 Feb 20 13:17 date

192.168.219.136 | SUCCESS | rc=0 >>
-rw-r--r-- 1 root root 0 Feb 20 13:17 date

[root@ansible ansible.test]# ansible all -m file -a 'name=/root/date state=absent'
192.168.219.136 | SUCCESS => {
    "changed": true,
    "path": "/root/date",
    "state": "absent"
}
192.168.219.137 | SUCCESS => {
    "changed": true,
    "path": "/root/date",
    "state": "absent"
}
[root@ansible ansible.test]# ansible all -m shell -a 'ls'
192.168.219.137 | SUCCESS | rc=0 >>
anaconda-ks.cfg
Desktop
Documents
Downloads
install.log
install.log.syslog
log.tar.xz
Music
Pictures
Public
Templates
Videos

192.168.219.136 | SUCCESS | rc=0 >>
anaconda-ks.cfg
Desktop
Documents
Downloads
install.log
install.log.syslog
log.tar.xz
Music
Pictures
Public
Templates
Videos

[root@ansible ansible.test]#
能夠看到date目錄已經刪除了
file刪除案例
[root@ansible ansible.test]# ansible all -m file -a 'name=/root/file123/file321 state=directory'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/root/file123/file321",
    "size": 4096,
    "state": "directory",
    "uid": 0
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/root/file123/file321",
    "size": 4096,
    "state": "directory",
    "uid": 0
}
[root@ansible ansible.test]# ansible all -m shell -a 'ls -l file123'
192.168.219.137 | SUCCESS | rc=0 >>
total 4
drwxr-xr-x 2 root root 4096 Feb 20 13:27 file321

192.168.219.136 | SUCCESS | rc=0 >>
total 4
drwxr-xr-x 2 root root 4096 Feb 20 13:27 file321

[root@ansible ansible.test]#
能夠看到遞歸建立成功了
file遞歸建立文件夾
[root@ansible ansible.test]# ansible all -m file -a 'src=/etc/passwd name=/root/file123/passwd.link state=link'
192.168.219.137 | SUCCESS => {
    "changed": true,
    "dest": "/root/file123/passwd.link",
    "gid": 0,
    "group": "root",
    "mode": "0777",
    "owner": "root",
    "size": 11,
    "src": "/etc/passwd",
    "state": "link",
    "uid": 0
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "dest": "/root/file123/passwd.link",
    "gid": 0,
    "group": "root",
    "mode": "0777",
    "owner": "root",
    "size": 11,
    "src": "/etc/passwd",
    "state": "link",
    "uid": 0
}
[root@ansible ansible.test]# ansible all -m shell -a 'ls -l /root/file123/passwd.link'
192.168.219.136 | SUCCESS | rc=0 >>
lrwxrwxrwx 1 root root 11 Feb 20 13:33 /root/file123/passwd.link -> /etc/passwd

192.168.219.137 | SUCCESS | rc=0 >>
lrwxrwxrwx 1 root root 11 Feb 20 13:33 /root/file123/passwd.link -> /etc/passwd

[root@ansible ansible.test]#
軟鏈接建立成功

刪除軟鏈接
[root@ansible ansible.test]# ansible all -m file -a 'name=/root/file123/passwd.link state=absent'
 [WARNING]: The src option requires state to be 'link' or 'hard'.  This will become
an error in Ansible 2.10

192.168.219.137 | SUCCESS => {
    "changed": true,
    "path": "/root/file123/passwd.link",
    "state": "absent"
}
192.168.219.136 | SUCCESS => {
    "changed": true,
    "path": "/root/file123/passwd.link",
    "state": "absent"
}
[root@ansible ansible.test]# ansible all -m shell -a 'ls -l /root/file123/passwd.link'
file建立文件的軟鏈接和刪除軟鏈接

因模塊不少,本篇不作過多的介紹,須要查找能夠經過ansible的官方手冊:https://docs.ansible.com/ansible/latest/modules/modules_by_category.html來進行查找。

♣三:ansible的進階操做

A:ansible-galaxy命令

ansible-galaxy是連接https://galaxy.ansible.com/下載相應的roles(角色),以前咱們是歇學的單條ansible的命令,可是要把不少單條的命令組合起來就須要playbook(劇本),那麼把playbook組合起來的就是roles(角色),把衆多的playbook組合起來造成一個完整的文件夾,就是角色,你也能夠經過提供的網站去網上下載一些人編寫的一些實用的角色,能夠下載下來使用。

保證服務器能訪問互聯網的狀況下
ansible-galaxy install geerlingguy.nginx
直接使用ansible-galaxy命令安裝網站的角色名就能夠
ansible-galaxy的案例

B:ansible-pull命令

把主控端的命令推送到被控端去執行,能提高執行的效率,在實際生產中用到不多。

ansible-playbook命令的簡單實用:

playbook只是把衆多的模塊寫成了一個腳本的形式在執行,寫成腳本無非是能重複使用,提升工做效率,固然playbook也是有本身的語法和格式的,playbook是使用yml語法寫的,因此playbook的文件也是yml爲後綴的。

[root@ansible playbook]# cat playbook.test.yml
---  #三橫槓是表明劇本編寫的開始,不用寫也沒有關係,語法上也是沒有錯誤的。
- hosts: web  #- hosts指定主機清單,就是組名,必須有空格
  remote_user: root #remote_user表明我接下的劇本是以什麼身份運行的

  tasks:  #接下來就爲劇本的命令內容
   - name: test  #給我接下來的命令取一個名字
     shell: 'hostname' #指定模塊,後面接操做的命令便可,-a就不須要了


這就是一個簡單的playbook的語法和基本格式。
一個簡單的playbook
[root@ansible playbook]# ansible-playbook playbook.test.yml

PLAY [web] ***********************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [192.168.219.137]
ok: [192.168.219.136]

TASK [test] **********************************************************************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

PLAY RECAP ***********************************************************************************************************************************************
192.168.219.136            : ok=2    changed=1    unreachable=0    failed=0
192.168.219.137            : ok=2    changed=1    unreachable=0    failed=0

[root@ansible playbook]#
能夠看到劇本在被控端確實執行成功了,可是沒有獲得咱們想要的結果。
playbook的執行案例

第一個劇本編寫成功了,可是執行以後沒有獲得咱們想要的結果,咱們接着看下playbook的其它命令,不斷的去解決這個問題。

C:ansible-vault:管理加解密yml文件

爲何要對playbook進行加密是由於playbook裏面可能存在一些敏感信息,好比密碼等,那就須要對playbook進行加密。

ansible-vault【create,decrypt,edit,encrypt,rekey,view】

ansible-vault encrypt 後面是playbook的腳本   【加密】

[root@ansible playbook]# ansible-vault encrypt playbook.test.yml
New Vault password:
Confirm New Vault password:
Encryption successful
[root@ansible playbook]# cat playbook.test.yml
$ANSIBLE_VAULT;1.1;AES256
30666539373365363535623538663639366633303138333730656264333935636531626537623665
3032393434646461613334393739636362653035376131610a333463343461353538373038303765
30323861353330666135313038353966366635386338643434376232643062373165343361316432
3231316430643036660a353730623063353031626634663538333565633130613637353232313361
36383762653337303133303932333631633538666430313465653934636432643732613835643663
35626535623631613937616266343366353730663662343961353164343330666538346162663138
39333432303631643465396265386430653834363233626137356632383739383935393430343935
34326666323132343461643765616537376337376533653933663764306435663233393833366361
34366232346663666362316565363264373261353063643965313863333330393365373233623032
39623163623936343762666537613439376439313564616438383930313233623931653331396663
66613436646661306531363362663539316532326561363633646437376134396337363139316361
32663038653733343739306233643636653237333364313833386330666434623331636363393965
63623338373730346431613065666561303338393538646133346636306531306566363639333331
32646435613565613861396135313862313331653432323339636636323237323865313335326164
33613432396539636637356263656466633036616232616238393462363030616336343037373566
61353738343435623138336432376534393061393232356438396130643738633233633862626565
65393764323234353238623934343635326364333565643132363963323865633265343533313764
62336438313637623833643735623933353639643064356631323963316265303566333437383736
35323565613532616363303937623539376535396162643864396337393366366463323535346538
33393062653338303234346165633434616132333961613463393136633161353765313838646338
61353566666430353161323136383230303361396336653064653638656134396265613636636639
33633066623165333337363233646232366663613939613066386338636665646333353039386439
61336633626531333961663861303064663065353732353139363934333361396236613330306632
36363564373264616233626530373062656133633130633835626632393232613639353263643633
62653565313361386538386162356565383762666138643139323265613734373565643363373661
62383037356664343063393434633766333734343261306563333365653737323533323238383538
39646338613536313831303266653239663933366531363863353136323135363466303636636531
34393931333930383035
[root@ansible playbook]#
能夠看到加密以後的劇本咱們就不能經過正常的方式查看了,並且使用的是AES的加密算法。

[root@ansible playbook]# ansible-playbook playbook.test.yml
ERROR! Attempting to decrypt but no vault secrets found
[root@ansible playbook]#
加密狀態下劇本是沒法執行的
encrypt案例

ansible-vault decrypt 後面是playbook的腳本   【解密】

[root@ansible playbook]# ansible-vault decrypt playbook.test.yml
Vault password:
Decryption successful
解密是須要輸入加密以後的口令的。
[root@ansible playbook]# cat playbook.test.yml
---  #三橫槓是表明劇本編寫的開始,不用寫也沒有關係,語法上也是沒有錯誤的。
- hosts: web  #- hosts指定主機清單,就是組名,必須有空格
  remote_user: root #remote_user表明我接下的劇本是以什麼身份運行的

  tasks:  #接下來就爲劇本的命令內容
   - name: test  #給我接下來的命令取一個名字
     shell: 'init 0' #指定模塊,後面接操做的命令便可,-a就不須要了
[root@ansible playbook]# ansible-playbook playbook.test.yml

PLAY [web] ******************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [192.168.219.136]
ok: [192.168.219.137]

TASK [test] *****************************************************************************************************************
changed: [192.168.219.136]
changed: [192.168.219.137]

PLAY RECAP ******************************************************************************************************************
192.168.219.136            : ok=2    changed=1    unreachable=0    failed=0
192.168.219.137            : ok=2    changed=1    unreachable=0    failed=0

[root@ansible playbook]#
加密文件要執行必須解密才能繼續使用
decrypt案例

ansible-vault view 後面是playbook的腳本   【查看】

[root@ansible playbook]# ansible-vault encrypt playbook.test.yml
New Vault password:
Confirm New Vault password:
Encryption successful
[root@ansible playbook]# ansible-vault view playbook.test.yml
Vault password:
---  #三橫槓是表明劇本編寫的開始,不用寫也沒有關係,語法上也是沒有錯誤的。
- hosts: web  #- hosts指定主機清單,就是組名,必須有空格
  remote_user: root #remote_user表明我接下的劇本是以什麼身份運行的

  tasks:  #接下來就爲劇本的命令內容
   - name: test  #給我接下來的命令取一個名字
     shell: 'init 0' #指定模塊,後面接操做的命令便可,-a就不須要了
[root@ansible playbook]#
若是我只是想看看playbook腳本,也可使用view參數去查看,仍是須要輸入口令。
View案例

ansible-vault edit 後面是playbook的腳本   【編輯加密文件】

[root@ansible playbook]# ansible-vault edit playbook.test.yml
Vault password:
[root@ansible playbook]#
若是不想解密就把文件內容直接調整了,就可使用edit參數。輸入口令就能調整了
edit 

ansible-vault rekey 後面是playbook的腳本   【修改口令】 

[root@ansible playbook]# ansible-vault rekey playbook.test.yml
Vault password:     輸入老密碼以後
New Vault password:   提示輸入新密碼
Confirm New Vault password:
Rekey successful
[root@ansible playbook]#
直接修改老的密碼,
rekey案例

ansible-vault create 後面是新playbook的腳本   【建立新文件】

[root@ansible playbook]# ansible-vault create playbook.test011.yml
New Vault password:
Confirm New Vault password:




[root@ansible playbook]# ls
playbook.test011.yml  playbook.test.retry  playbook.test.yml
[root@ansible playbook]#
若是想在編寫playbook的時候就把文件加密了,就可使用create參數,進去劇本直接編寫。
create 

D:ansible-console:控制檯

直接提供一個控制檯,用戶在控制檯進行操做,能支持tab補全

[root@ansible playbook]# ansible-console
Welcome to the ansible console.
Type help or ? to list commands.

root@all (2)[f:5]$
root表明操做用戶,all表明主機清單裏面的全部機器,2表明主機清單的數量,f:5表明併發請求的數量是5

可是一下操做全部主機確定不是經常使用的,經常使用的狀況下仍是按照咱們的分組來控制,執行相關的命令
root@all (2)[f:5]$ cd web
root@web (2)[f:5]$
直接執行cd (主機清單組的名字),就能切換控制對象

併發數過小,咱們調大一點

root@web (2)[f:5]$ forks 10
root@web (2)[f:10]$
執行forks 數量就能快速調整併發數

前面已經把主機清單和執行的用戶定義好了,咱們執行就只須要接模塊和須要執行的命令便可,並且模塊名記不住沒關係,支持tab補全。
root@web (2)[f:10]$ shell hostname   -a和引號都不須要
192.168.219.136 | SUCCESS | rc=0 >>
web1

192.168.219.137 | SUCCESS | rc=0 >>
web2

root@web (2)[f:10]$ shell df -h
192.168.219.136 | SUCCESS | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        18G  2.7G   14G  16% /
tmpfs           491M   72K  491M   1% /dev/shm
/dev/sda1       283M   37M  232M  14% /boot

192.168.219.137 | SUCCESS | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        18G  2.6G   14G  16% /
tmpfs           491M   72K  491M   1% /dev/shm
/dev/sda1       283M   36M  232M  14% /boot

root@web (2)[f:10]$

在ansible-console控制檯下,須要注意的是一些帶有風險的操做是對全部被控機器執行仍是單臺機器執行,避免形成不可逆的操做,控制檯的形式也能讓咱們臨時去進行測試。

E:ansible-playbook的進階操做

使用playbook須要記住兩點,1:playbook實用yaml語言編寫,文件後綴必須是yml,2:playbook的編寫格式有必定要求。

劇本在舞臺上使用的時候,能夠想到是由多個演員按照預先規劃好的時間軸依次出廠和退場,共同的來完成一場演出,那麼playbook也是如此,例如我是否是須要驗證機器服務有沒有裝,有沒有啓動,有沒有開機自啓,其次是否是要裝包,下發配置文件,起服務,加入開機自啓,最後是否是要驗證啓動狀況,端口監聽是否正常等。都是須要按照時間排列好的形式來編寫playbook,這個就很像編劇的職務。

playbook的核心元素:

hosts  主機列表

tasks     任務集

varbiables  內置變量或自定義變量在playbook中的調用

tempates   模板,看替換模板文件中的變量並實現一些簡單邏輯的文件

handlers  和notity結合使用,由特定條件觸發,知足則執行,不然不執行

tags  標籤

[root@ansible playbook]# ansible-playbook -C playbook.test.yml
在執行腳本的時候加上-C就能查看腳本是否有錯誤

PLAY [web] ******************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [192.168.219.137]
ok: [192.168.219.136]

TASK [test] *****************************************************************************************************************
skipping: [192.168.219.136]
skipping: [192.168.219.137]

PLAY RECAP ******************************************************************************************************************
192.168.219.136            : ok=1    changed=0    unreachable=0    failed=0
192.168.219.137            : ok=1    changed=0    unreachable=0    failed=0

[root@ansible playbook]#
playbook檢查語法是否錯誤

在ansible裏面咱們一般要控制幾十上百臺機器,不少狀況下咱們不能保證每臺機器的目錄是否存在,命令執行錯誤等狀況,這種狀況下,playbook就可能由於錯誤不執行結束了,那不少狀況下咱們都但願無論錯誤繼續執行剩下的操做,這個時候就須要在操做後面加上一個||/bin/true

還有狀況下,例如我就想在單臺機器上把我剛纔寫的playbook先跑下,不想一下把全部的機器都跑了,也能夠經過--limit  後面跟上ip地址便可。

[root@ansible playbook]# ansible-playbook playbook.test.yml --list-hosts

playbook: playbook.test.yml

  play #1 (web): web    TAGS: []
    pattern: [u'web']
    hosts (2):
      192.168.219.136
      192.168.219.137
[root@ansible playbook]# ansible-playbook playbook.test.yml --limit 192.168.219.136

PLAY [web] ******************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [192.168.219.136]

TASK [test] *****************************************************************************************************************
changed: [192.168.219.136]

PLAY RECAP ******************************************************************************************************************
192.168.219.136            : ok=2    changed=1    unreachable=0    failed=0

[root@ansible playbook]#
limit的參數使用

腳本寫好了,跑的過程我想知道也能夠在執行的時候末尾加上-v -vv -vvv來看不一樣詳細的運行過程信息。

task重複執行的問題:

若是我一個模塊裏面執行了兩條操做,這個時候playbook不會報錯,可是隻會執行命令裏面的最後一個操做。

[root@ansible playbook]# cat playbook.test.yml
---
-hosts: all
 remote_user: root

 tasks:
  -name: copy file
   copy: src=/home/ansible.test/playbook/11.sh dest=/home/ansible/
   copy: src=/home/ansible.test/playbook/22.sh dest=/home/ansible/
[root@ansible playbook]#
能夠看到copy的操做有兩個
[root@ansible playbook]# ansible-playbook playbook.test.yml
 [WARNING]: While constructing a mapping from /home/ansible.test/playbook/playbook.test.yml, line 6, column 6, found a
duplicate dict key (copy). Using last defined value only.


PLAY [all] ******************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [192.168.219.136]
ok: [192.168.219.137]

TASK [copy file] ************************************************************************************************************
changed: [192.168.219.136]
changed: [192.168.219.137]

PLAY RECAP ******************************************************************************************************************
192.168.219.136            : ok=2    changed=1    unreachable=0    failed=0
192.168.219.137            : ok=2    changed=1    unreachable=0    failed=0

[root@ansible playbook]# ansible all -m shell -a 'ls /home/ansible'
192.168.219.136 | SUCCESS | rc=0 >>
22.sh

192.168.219.137 | SUCCESS | rc=0 >>
22.sh

[root@ansible playbook]#
能夠看到就拷貝了22.sh,這個就說明在tasks裏面一個模塊只能對應一個name,一個name也只能對應一個操做。
tasks的重複執行

上面咱們執行的時候都是按照流程去操做的,不存在判斷的過程,這個我要判斷機器的httpd服務是否裝了,裝了就沒必要要從新裝,不然就安裝。

handlers和notify配合使用:

這個時候就須要handlers(觸發器),handlers能夠監控tasks裏面的每個操做,當一個操做執行了,那麼就會觸發handlers後面定義的一些命令,那麼handlers是怎麼被觸發的了,配合handlers作觸發的是notity,當操做執行以後notity就會通知handlers來執行相應的命令。

[root@ansible playbook]# cat playbook.test.yml
---
- hosts: all
  remote_user: root

  tasks:
   - name: install httpd service
     yum: name=httpd
   - name: start service
     service: name=httpd state=started enabled=yes

[root@ansible playbook]# ansible-playbook playbook.test.yml

PLAY [all] ******************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [192.168.219.137]
ok: [192.168.219.136]

TASK [install httpd service] ************************************************************************************************
ok: [192.168.219.136]
ok: [192.168.219.137]

TASK [start service] ********************************************************************************************************
changed: [192.168.219.136]
changed: [192.168.219.137]

PLAY RECAP ******************************************************************************************************************
192.168.219.136            : ok=3    changed=1    unreachable=0    failed=0
192.168.219.137            : ok=3    changed=1    unreachable=0    failed=0

[root@ansible playbook]# ansible all -m shell -a 'netstat -anptu | grep 80'
192.168.219.137 | SUCCESS | rc=0 >>
tcp        0      0 :::80                       :::*                        LISTEN      5631/httpd

192.168.219.136 | SUCCESS | rc=0 >>
tcp        0      0 :::80                       :::*                        LISTEN      4599/httpd
能夠看到httpd服務已經裝好了,可是這個時候我要把默認的80端口改爲8088的話,那麼更新我本地的配置文件同步到備機,配置文件變更過,服務就須要重啓才能生效。
咱們在本地將修改httpd的配置文件
[root@ansible playbook]# cat playbook.test.yml
---
- hosts: all
  remote_user: root

  tasks:
   - name: install httpd service
     yum: name=httpd
   - name: start service
     service: name=httpd state=started enabled=yes
   - name: copy conf file
     copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/ backup=yes
     notify: restart service  #這個notify就要寫handiers後面定義的名字

  handlers:
   - name: restart service
     service: name=httpd state=restarted  #當監控有變更以後handlers須要作什麼操做

[root@ansible playbook]# ansible-playbook playbook.test.yml

PLAY [all] ******************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [192.168.219.137]
ok: [192.168.219.136]

TASK [install httpd service] ************************************************************************************************
ok: [192.168.219.136]
ok: [192.168.219.137]

TASK [start service] ********************************************************************************************************
ok: [192.168.219.137]
ok: [192.168.219.136]

TASK [copy conf file] *******************************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

RUNNING HANDLER [restart service] *******************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

PLAY RECAP ******************************************************************************************************************
192.168.219.136            : ok=5    changed=2    unreachable=0    failed=0
192.168.219.137            : ok=5    changed=2    unreachable=0    failed=0

[root@ansible playbook]# ansible all -m shell -a 'netstat -anptu | grep 8088'
192.168.219.137 | SUCCESS | rc=0 >>
tcp        0      0 :::8088                     :::*                        LISTEN      6045/httpd

192.168.219.136 | SUCCESS | rc=0 >>
tcp        0      0 :::8088                     :::*                        LISTEN      5016/httpd

[root@ansible playbook]#
執行以後就能夠看到服務重啓成功了,並且8088端口修改也生效了
handiers案例

notify能夠通知多個handlers的操做:

notify:

- 空格以後接第一個handlers的名字

- 空格以後接第二個handlers的名字
notify重複觸發

tags:標籤

加標籤的目的是,後面咱們能夠調用標籤裏面的內容,如上面重啓httpd的案例同樣,我不須要每次都把這個playbook都完完整整的執行一遍,我只須要在httpd重啓的地方打上一個標籤,後面咱們在執行的時候就選擇這個標籤來執行便可。

[root@ansible playbook]# cat playbook.test.yml
---
- hosts: all
  remote_user: root

  tasks:
   - name: install httpd service
     yum: name=httpd
   - name: start service
     service: name=httpd state=started enabled=yes
     tags: rehttpd   #在此位置加一個tags的標籤,後面寫上標籤名,標籤名要有意義且簡單,最好加上註釋。
   - name: copy conf file
     copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/ backup=yes
     notify: restart service

  handlers:
   - name: restart service
     service: name=httpd state=restarted

[root@ansible playbook]# ansible all -m shell -a 'ps -aux | grep httpd'
192.168.219.136 | SUCCESS | rc=0 >>
root       5969  0.0  0.1 106096  1128 pts/1    S+   06:12   0:00 /bin/sh -c ps -aux | grep httpd
root       5971  0.0  0.0 103308   852 pts/1    S+   06:12   0:00 grep httpdWarning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ

192.168.219.137 | SUCCESS | rc=0 >>
root       6998  0.0  0.1 106096  1120 pts/1    S+   06:12   0:00 /bin/sh -c ps -aux | grep httpd
root       7000  0.0  0.0 103308   848 pts/1    S+   06:12   0:00 grep httpdWarning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
能夠看到httpd服務是沒有啓動的
[root@ansible playbook]# ansible-playbook -t rehttpd playbook.test.yml
-t 指定標籤名執行playbook 
PLAY [all] ******************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [192.168.219.137]
ok: [192.168.219.136]

TASK [start service] ********************************************************************************************************
changed: [192.168.219.136]
changed: [192.168.219.137]

PLAY RECAP ******************************************************************************************************************
192.168.219.136            : ok=2    changed=1    unreachable=0    failed=0
192.168.219.137            : ok=2    changed=1    unreachable=0    failed=0

[root@ansible playbook]# ansible all -m shell -a 'ps -aux | grep httpd'
192.168.219.136 | SUCCESS | rc=0 >>
root       6101  0.0  0.3 183896  3832 ?        Ss   06:12   0:00 /usr/sbin/httpd
apache     6104  0.0  0.2 184028  2508 ?        S    06:12   0:00 /usr/sbin/httpd
apache     6105  0.0  0.2 184028  2484 ?        S    06:12   0:00 /usr/sbin/httpd
apache     6106  0.0  0.2 184028  2484 ?        S    06:12   0:00 /usr/sbin/httpd
apache     6107  0.0  0.2 184028  2484 ?        S    06:12   0:00 /usr/sbin/httpd
apache     6108  0.0  0.2 184028  2484 ?        S    06:12   0:00 /usr/sbin/httpd
apache     6109  0.0  0.2 184028  2484 ?        S    06:12   0:00 /usr/sbin/httpd
apache     6110  0.0  0.2 184028  2484 ?        S    06:12   0:00 /usr/sbin/httpd
apache     6111  0.0  0.2 184028  2484 ?        S    06:12   0:00 /usr/sbin/httpd
root       6143  0.0  0.1 106096  1128 pts/1    S+   06:12   0:00 /bin/sh -c ps -aux | grep httpd
root       6145  0.0  0.0 103312   860 pts/1    S+   06:12   0:00 grep httpdWarning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ

192.168.219.137 | SUCCESS | rc=0 >>
root       7130  0.0  0.3 183896  3824 ?        Ss   06:12   0:00 /usr/sbin/httpd
apache     7133  0.0  0.2 184028  2476 ?        S    06:12   0:00 /usr/sbin/httpd
apache     7134  0.0  0.2 184028  2500 ?        S    06:12   0:00 /usr/sbin/httpd
apache     7135  0.0  0.2 184028  2476 ?        S    06:12   0:00 /usr/sbin/httpd
apache     7136  0.0  0.2 184028  2476 ?        S    06:12   0:00 /usr/sbin/httpd
apache     7137  0.0  0.2 184028  2476 ?        S    06:12   0:00 /usr/sbin/httpd
apache     7138  0.0  0.2 184028  2476 ?        S    06:12   0:00 /usr/sbin/httpd
apache     7139  0.0  0.2 184028  2476 ?        S    06:12   0:00 /usr/sbin/httpd
apache     7140  0.0  0.2 184028  2476 ?        S    06:12   0:00 /usr/sbin/httpd
root       7172  0.0  0.1 106096  1124 pts/1    S+   06:12   0:00 /bin/sh -c ps -aux | grep httpd
root       7174  0.0  0.0 103312   856 pts/1    S+   06:12   0:00 grep httpdWarning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ

[root@ansible playbook]#
能夠看到httpd服務就啓動了
tags標籤案例
[root@ansible conf]# ansible all -m shell -a 'netstat -anptu | grep 8088'
192.168.219.137 | SUCCESS | rc=0 >>
tcp        0      0 :::8088                     :::*                        LISTEN      7130/httpd

192.168.219.136 | SUCCESS | rc=0 >>
tcp        0      0 :::8088                     :::*                        LISTEN      6101/httpd
能夠看到服務端口是8088
咱們把配置文件改9099,並執行在copy位置加的標籤
[root@ansible playbook]# cat playbook.test.yml
---
- hosts: all
  remote_user: root

  tasks:
   - name: install httpd service
     yum: name=httpd
   - name: start service
     service: name=httpd state=started enabled=yes
     tags: rehttpd
   - name: copy conf file
     copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/ backup=yes
     notify: restart service
     tags: cohttpd  #在此處加了標籤

  handlers:
   - name: restart service
     service: name=httpd state=restarted

[root@ansible playbook]# ansible-playbook -t cohttpd playbook.test.yml

PLAY [all] ******************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [192.168.219.136]
ok: [192.168.219.137]

TASK [copy conf file] *******************************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

RUNNING HANDLER [restart service] *******************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

PLAY RECAP ******************************************************************************************************************
192.168.219.136            : ok=3    changed=2    unreachable=0    failed=0
192.168.219.137            : ok=3    changed=2    unreachable=0    failed=0

[root@ansible playbook]# ansible all -m shell -a 'netstat -anptu | grep 9099'
192.168.219.137 | SUCCESS | rc=0 >>
tcp        0      0 :::9099                     :::*                        LISTEN      7464/httpd

192.168.219.136 | SUCCESS | rc=0 >>
tcp        0      0 :::9099                     :::*                        LISTEN      6435/httpd

[root@ansible playbook]# 
能夠看到端口是9099,咱們執行了copy的配置文件下發同時也觸發了重啓任務的操做。
tags標籤案例1
[root@ansible playbook]# ansible all -m shell -a 'httpd -v'
192.168.219.136 | FAILED | rc=127 >>
/bin/sh: httpd: command not foundnon-zero return code

192.168.219.137 | FAILED | rc=127 >>
/bin/sh: httpd: command not foundnon-zero return code

[root@ansible playbook]# cat playbook.test.yml
---
- hosts: all
  remote_user: root

  tasks:
   - name: install httpd service
     yum: name=httpd
     tags: inhttpd   #在此處我加了一個安裝httpd服務的標籤
   - name: start service
     service: name=httpd state=started enabled=yes
   - name: copy conf file
     copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/ backup=yes
     notify: restart service
     tags: cohttpd  #增長了該端口配置的標籤

  handlers:
   - name: restart service
     service: name=httpd state=restarted

[root@ansible playbook]# ansible-playbook -t inhttpd,cohttpd playbook.test.yml
在-t指定標籤執行的時候我能夠選擇多個標籤進行執行,中間逗號區分便可
PLAY [all] ***********************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [192.168.219.136]
ok: [192.168.219.137]

TASK [install httpd service] *****************************************************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

TASK [copy conf file] ************************************************************************************************************************************
changed: [192.168.219.136]
changed: [192.168.219.137]

RUNNING HANDLER [restart service] ************************************************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

PLAY RECAP ***********************************************************************************************************************************************
192.168.219.136            : ok=4    changed=3    unreachable=0    failed=0
192.168.219.137            : ok=4    changed=3    unreachable=0    failed=0

[root@ansible playbook]# ansible all -m shell -a 'netstat -anptu | grep 1234'
192.168.219.136 | SUCCESS | rc=0 >>
tcp        0      0 :::1234                     :::*                        LISTEN      7152/httpd

192.168.219.137 | SUCCESS | rc=0 >>
tcp        0      0 :::1234                     :::*                        LISTEN      8120/httpd

[root@ansible playbook]#
tags標籤案例2

tags還支持多個操做共用一個標籤

playbook使用變量:

playbook的變量和大多數變量定義規則同樣,字母下劃線和數字組成且只能以字母開頭

setup模塊:

setup自帶了系統中的變量

ansible 機器ip -m setup 能獲取被控端機器的全部信息,磁盤大小,主機名,內核版本等等信息,有時候咱們想經過命令獲取機器的信息的時候須要重複執行不少命令,這個時候setup就頗有用,直接查詢出來進行過濾便可。

[root@ansible playbook]# ansible 192.168.219.136 -m setup | grep 'ansible_kernel'
        "ansible_kernel": "2.6.32-573.el6.x86_64",
[root@ansible playbook]# ansible 192.168.219.136 -m setup -a 'filter=ansible_kernel'
192.168.219.136 | SUCCESS => {
    "ansible_facts": {
        "ansible_kernel": "2.6.32-573.el6.x86_64"
    },
    "changed": false
}
[root@ansible playbook]#
兩種方式均可以,可是你要寫到playbook裏面的grep命令可能會出問題,仍是使用推薦的命令,這個setup過濾出來的數值咱們到時候就能夠進行調用,以知足其餘的需求。
setup案例

playbook腳本使用變量案例:

[root@ansible playbook]# cat playbook.test.yml
---
- hosts: all
  remote_user: root

  tasks:
   - name: install soft 
     yum: name={{ deploy }}  #在安裝的名字的位置使用變量名,格式就是兩組花括號,先後留有空格不是強制要求,只是爲了更加簡潔易讀
   - name: start service
     service: name={{ deploy }} state=started enabled=yes
 #一樣在只要使用到包名的位置都要替換成變量

[root@ansible playbook]# ansible-playbook -e 'deploy=vsftpd' playbook.test.yml
#在執行的時候跟上-e參數,後面的變量直接指定實際要安裝的程序名便可

PLAY [all] ***********************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [192.168.219.136]
ok: [192.168.219.137]

TASK [install soft] *****************************************************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

TASK [start service] *************************************************************************************************************************************
changed: [192.168.219.136]
changed: [192.168.219.137]

PLAY RECAP ***********************************************************************************************************************************************
192.168.219.136            : ok=3    changed=2    unreachable=0    failed=0
192.168.219.137            : ok=3    changed=2    unreachable=0    failed=0
能夠看到ftp程序安裝成,咱們進行檢查,看下服務是否啓動
[root@ansible playbook]# ansible all -m shell -a 'netstat -anptu | grep 21'
192.168.219.137 | SUCCESS | rc=0 >>
tcp        0      0 0.0.0.0:21                  0.0.0.0:*                   LISTEN      2906/vsftpd
tcp        0      0 192.168.219.137:22          192.168.219.135:38357       ESTABLISHED 2928/sshd
tcp        0      0 192.168.219.137:22          192.168.219.1:50993         ESTABLISHED 2679/sshd
tcp        0      0 192.168.219.137:22          192.168.219.1:50994         ESTABLISHED 2681/sshd

192.168.219.136 | SUCCESS | rc=0 >>
tcp        0      0 0.0.0.0:21                  0.0.0.0:*                   LISTEN      2936/vsftpd
tcp        0      0 192.168.219.136:22          192.168.219.1:50861         ESTABLISHED 2640/sshd
tcp        0      0 192.168.219.136:22          192.168.219.135:34572       ESTABLISHED 2954/sshd
tcp        0      0 192.168.219.136:22          192.168.219.1:50865         ESTABLISHED 2642/sshd

[root@ansible playbook]#
能夠看到21端口啓用了,ftp程序安裝並啓動成功。
變量案例1

在腳本里面使用變量可使得腳本更加靈活,固然playbook也是支持多個變量的,指須要在-e後面分別賦值便可,例如ansible-playbook -e 'deploy=vsftpd deploy1=httpd' 腳本名

[root@ansible playbook]# cat playbook.test.yml
---
- hosts: all
  remote_user: root
  vars:
   - deploy1: redis    #在腳本里面就把變量進行賦值
   - deploy2: subversion
  tasks:
   - name: install soft
     yum: name={{ deploy1 }}
   - name: install soft
     yum: name={{ deploy2 }}

[root@ansible playbook]# ansible-playbook playbook.test.yml
#執行的時候就不須要在給變量傳參
PLAY [all] ***********************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [192.168.219.136]
ok: [192.168.219.137]

TASK [install soft] **************************************************************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

TASK [install soft] **************************************************************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

PLAY RECAP ***********************************************************************************************************************************************
192.168.219.136            : ok=3    changed=2    unreachable=0    failed=0
192.168.219.137            : ok=3    changed=2    unreachable=0    failed=0


[root@ansible playbook]# ansible all -m shell -a 'rpm -qa redis'
 [WARNING]: Consider using the yum, dnf or zypper module rather than running rpm.  If you need to use command because yum, dnf or zypper is insufficient
you can add warn=False to this command task or set command_warnings=False in ansible.cfg to get rid of this message.

192.168.219.136 | SUCCESS | rc=0 >>
redis-3.2.12-2.el6.x86_64

192.168.219.137 | SUCCESS | rc=0 >>
redis-3.2.12-2.el6.x86_64

[root@ansible playbook]# ansible all -m shell -a 'rpm -qa subversion'
 [WARNING]: Consider using the yum, dnf or zypper module rather than running rpm.  If you need to use command because yum, dnf or zypper is insufficient
you can add warn=False to this command task or set command_warnings=False in ansible.cfg to get rid of this message.

192.168.219.137 | SUCCESS | rc=0 >>
subversion-1.6.11-15.el6_7.x86_64

192.168.219.136 | SUCCESS | rc=0 >>
subversion-1.6.11-15.el6_7.x86_64
能夠看到都安裝成功
變量案例2

也能夠在腳本里面把變量進行賦值,在執行的時候就直接執行,無需在執行的時候給參數。

在/etc/ansible/hosts裏面使用變量,例如我被控端機器太多,我就算用組名來區分仍是不夠細緻,若是我有幾十臺http的服務器,可是裏面機器的端口不同,這個時候變量就能很好的解決此問題。

## db-[99:101]-node.example.com
[web]
192.168.219.136   httpd_server=8080
192.168.219.137   httpd_server=9090   
在組所屬的ip後面在加以區分,至關於標記,不竟能在第一時間查看到機器服務還能看到端口

[root@ansible playbook]# cat playbook.test.yml
---
- hosts: web
  remote_user: root

  tasks:
   - name: mod hostname
     hostname: name=www.{{http_server}}.http.com  
     #在腳本里面調用變量進行主機名批量修改



[root@ansible playbook]# cat playbook.test.yml
---
- hosts: web
  remote_user: root

  tasks:
   - name: set server
     hostname: name=www{{http_server}}.http.com


[root@ansible playbook]# vim playbook.test.yml
[root@ansible playbook]# ansible-playbook -C playbook.test.yml

PLAY [web] ***********************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [192.168.219.137]
ok: [192.168.219.136]

TASK [set server] ****************************************************************************************************************************************
changed: [192.168.219.136]
changed: [192.168.219.137]

PLAY RECAP ***********************************************************************************************************************************************
192.168.219.136            : ok=2    changed=1    unreachable=0    failed=0
192.168.219.137            : ok=2    changed=1    unreachable=0    failed=0

[root@ansible playbook]# cat playbook.test.yml
---
- hosts: web
  remote_user: root

  tasks:
   - name: set server
     hostname: name=www{{httpd_server}}.http.com


[root@ansible playbook]# ansible-playbook playbook.test.yml

PLAY [web] ***********************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [192.168.219.137]
ok: [192.168.219.136]

TASK [set server] ****************************************************************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

PLAY RECAP ***********************************************************************************************************************************************
192.168.219.136            : ok=2    changed=1    unreachable=0    failed=0
192.168.219.137            : ok=2    changed=1    unreachable=0    failed=0

[root@ansible playbook]# ansible web -a 'hostname'
192.168.219.137 | SUCCESS | rc=0 >>
www9090.http.com

192.168.219.136 | SUCCESS | rc=0 >>
www8080.http.com

[root@ansible playbook]#
能夠看到主機名修改爲hosts裏面事先定義好了的端口
hosts文件使用變量1
[web:vars]  #也能夠在組裏面使用變量,指須要在組名後面添加vars便可
name1=www
name2=httpd.com

在  hostname: name={{name1}}{{httpd_server}}.{{name2}}位置使用變量,也能夠
hosts文件使用變量2

在變量使用中,普通變量(單條命令)比公共組(hosts)裏面的優先級要高。

在指定的路徑下編寫yml文件,將變量定義成共用的變量,方便不一樣的運維上來無需在進行變量的聲明和定義,直接調用已經編寫好的yml文件裏面的變量進行操做,這樣的好處就是避免每人運維上來都要對playbook進行變量的聲明,若是是沒有提早規劃,這些變量名將變得雜亂無章。

[root@ansible playbook]# cat vars.yml
db_backup: dbbackup
time: date +%Y%m%d
[root@ansible playbook]#
建立一個vars.yml的文件,把須要定義的變量和指實現寫好
[root@ansible playbook]# cat backup.yml
---
- hosts: web
  remote_user: root
  vars_files:
      - vars.yml

  tasks:
      - name: create flie
        file: name=/root/{{ db_backup }} state=touch
[root@ansible playbook]#
在playbook裏面指定變量使用vars文件來定義,下面要使用變量的部分直接使用vars裏面的變量便可
[root@ansible playbook]# ansible web -m shell -a 'ls -h /root'
192.168.219.137 | SUCCESS | rc=0 >>
anaconda-ks.cfg
dbbackup
Desktop
Documents
Downloads
file123
install.log
install.log.syslog
log.tar.xz
Music
Pictures
Public
Templates
Videos

192.168.219.136 | SUCCESS | rc=0 >>
anaconda-ks.cfg
dbbackup
Desktop
Documents
Downloads
file123
install.log
install.log.syslog
log.tar.xz
Music
Pictures
Public
Templates
Videos
能夠看到建立成功
vars.yml文件定義變量

注:playbook腳本在哪一個路徑下,vars.yml文件就要在相應的路徑下

F:templates模板:

實際生產中,咱們會遇到不少須要下發配置文件的操做,可是配置文件不可能每套環境都是使用的同樣的,這個時候有差別咱們若是還使用前面的ansible操做就會不適用,因此咱們須要藉助ansible的templates模板來完成和機器相匹配的配置文件下發。

 templates使用的jinja2語言,能支持整數,浮點數,列表,元祖,字典,布爾值,算數運算符,邏輯表達式,流表達式(for if when)這個是比較特殊的表達式,它的含義是當什麼知足條件的時候才執行相應的操做。

template自己就是一個模塊,並且這個模塊比較特殊,他只能用於playbook。

咱們將服務的配置文件拷貝一份放到創建好的路徑下,並修改爲.j2結尾的文件
[root@ansible templates]# pwd
/home/ansible.test/templates
[root@ansible templates]# ls
httpd.conf.j2  templates.retry  templates.yml
修改hosts文件以下:
## db-[99:101]-node.example.com
[web]
192.168.219.136 httpd_server=1010   在hosts文件夾定義好變量
192.168.219.137 httpd_server=2020

在httpd.conf裏面使用該變量
#Listen 12.34.56.78:80
Listen {{httpd_server}}

[root@ansible templates]# cat templates.yml
---
- hosts: web
  remote_user: root

  tasks:
    - name: copy httpd
      template: src=/home/ansible.test/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
      notify: service restart

  handlers:
     - name: service restart
       service: name=httpd state=restarted

[root@ansible templates]# ansible-playbook templates.yml

PLAY [web] ***********************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************
ok: [192.168.219.136]
ok: [192.168.219.137]

TASK [copy httpd] ****************************************************************************************************************************************
changed: [192.168.219.136]
changed: [192.168.219.137]

RUNNING HANDLER [service restart] ************************************************************************************************************************
changed: [192.168.219.137]
changed: [192.168.219.136]

PLAY RECAP ***********************************************************************************************************************************************
192.168.219.136            : ok=3    changed=2    unreachable=0    failed=0
192.168.219.137            : ok=3    changed=2    unreachable=0    failed=0

[root@ansible templates]# ansible all -m shell -a 'netstat -anptu | grep httpd'
192.168.219.137 | SUCCESS | rc=0 >>
tcp        0      0 :::2020                     :::*                        LISTEN      5710/httpd
udp        0      0 192.168.219.137:53613       192.168.219.2:53            ESTABLISHED 5710/httpd

192.168.219.136 | SUCCESS | rc=0 >>
tcp        0      0 :::1010                     :::*                        LISTEN      5704/httpd
udp        0      0 192.168.219.136:37088       192.168.219.2:53            ESTABLISHED 5704/httpd

[root@ansible templates]#
能夠看到兩臺機器的ip都按照設定的下發了不一樣端口的配置文件並重啓生效了
template模板案例

template的還能完成根據機器的資源配置下發與機器相關匹配的配置文件。

變量的優先級是命令行裏面的-e參數指定的變量,其實playbook裏面定義的變量,最後是主機清單裏面的變量。

template裏面when的用法

[root@ansible templates]# cat templates.yml
---
- hosts: web
  remote_user: root

  tasks:
    - name: copy httpd
      service: name=httpd state=statred
      notify: service restart
      when: httpd_server == "1010"

  handlers:
     - name: service restart
       service: name=httpd state=stoped

[root@ansible templates]#
例如我判斷端口等於1010的纔會關閉httpd服務
when的用法

迭代:with_items:

當咱們須要重複執行某一個操做的時候,就須要迭代運行的機制。在ansible裏面迭代的引用固定變量名爲「item」,在task中使用with_items給須要迭代的定義元素列表,支持字符串和字典。

[root@ansible playbook]# cat item.yml
---
- hosts: web
  remote_user: root

  tasks:
    - name: create file
      file: name=/root/{{ item }} state=touch
      #這個item在此處比較特殊,它表明了下面with_items裏面的每個元素

      with_items:  #在with_items裏面定義沒一個元素,讓上面的item變量來迭代使用
         - file1
         - file2
         - file3

[root@ansible playbook]# ansible-playbook item.yml

PLAY [web] ****************************************************************************

TASK [Gathering Facts] ****************************************************************
ok: [192.168.219.136]
ok: [192.168.219.137]

TASK [create file] ********************************************************************
changed: [192.168.219.136] => (item=file1)
changed: [192.168.219.137] => (item=file1)
changed: [192.168.219.136] => (item=file2)
changed: [192.168.219.137] => (item=file2)
changed: [192.168.219.136] => (item=file3)
changed: [192.168.219.137] => (item=file3)

PLAY RECAP ****************************************************************************
192.168.219.136            : ok=2    changed=1    unreachable=0    failed=0
192.168.219.137            : ok=2    changed=1    unreachable=0    failed=0
[root@ansible playbook]# ansible all -m shell -a 'ls /root/ -l'
192.168.219.137 | SUCCESS | rc=0 >>
total 156
-rw-------. 1 root root  3341 Feb 14 01:57 anaconda-ks.cfg
-rw-r--r--  1 root root     0 Feb 25 06:09 dbbackup
drwxr-xr-x. 2 root root  4096 Feb 14 02:02 Desktop
drwxr-xr-x. 2 root root  4096 Feb 14 02:02 Documents
drwxr-xr-x. 2 root root  4096 Feb 14 02:02 Downloads
-rw-r--r--  1 root root     0 Feb 27 01:48 file1
drwxr-xr-x  3 root root  4096 Feb 20 13:35 file123
-rw-r--r--  1 root root     0 Feb 27 01:48 file2
-rw-r--r--  1 root root     0 Feb 27 01:48 file3
-rw-r--r--. 1 root root 41800 Feb 14 01:57 install.log
-rw-r--r--. 1 root root  9154 Feb 14 01:54 install.log.syslog
-rw-r--r--  1 root root 55144 Feb 20 13:05 log.tar.xz
drwxr-xr-x. 2 root root  4096 Feb 14 02:02 Music
drwxr-xr-x. 2 root root  4096 Feb 14 02:02 Pictures
drwxr-xr-x. 2 root root  4096 Feb 14 02:02 Public
drwxr-xr-x. 2 root root  4096 Feb 14 02:02 Templates
drwxr-xr-x. 2 root root  4096 Feb 14 02:02 Videos

192.168.219.136 | SUCCESS | rc=0 >>
total 156
-rw-------. 1 root root  3341 Feb 14 01:56 anaconda-ks.cfg
-rw-r--r--  1 root root     0 Feb 25 06:09 dbbackup
drwxr-xr-x. 2 root root  4096 Feb 14 02:01 Desktop
drwxr-xr-x. 2 root root  4096 Feb 14 02:01 Documents
drwxr-xr-x. 2 root root  4096 Feb 14 02:01 Downloads
-rw-r--r--  1 root root     0 Feb 27 01:48 file1
drwxr-xr-x  3 root root  4096 Feb 20 13:35 file123
-rw-r--r--  1 root root     0 Feb 27 01:48 file2
-rw-r--r--  1 root root     0 Feb 27 01:48 file3
-rw-r--r--. 1 root root 41800 Feb 14 01:56 install.log
-rw-r--r--. 1 root root  9154 Feb 14 01:53 install.log.syslog
-rw-r--r--  1 root root 55452 Feb 20 13:05 log.tar.xz
drwxr-xr-x. 2 root root  4096 Feb 14 02:01 Music
drwxr-xr-x. 2 root root  4096 Feb 14 02:01 Pictures
drwxr-xr-x. 2 root root  4096 Feb 14 02:01 Public
drwxr-xr-x. 2 root root  4096 Feb 14 02:01 Templates
drwxr-xr-x. 2 root root  4096 Feb 14 02:01 Videos

[root@ansible playbook]#
能夠看到迭代幫忙建立的空的目錄
item使用案例

迭代嵌套子變量:

若是想重複完成多件事情,單純的嵌套寫起來會比較麻煩。

[root@ansible playbook]# cat item2.yml
---
- hosts: all
  remote_user: root

  tasks:
    - name: create groups
      group: name={{ item }} state=present
在建立組的時候使用變量的格式
      with_items:
        - group1
        - group2
        - group3
    - name: add users
      user: name={{ item.name }} group={{ item.group }} state=present
#在建立用戶的時候把屬組參數調用上面定義好的變量
      with_items:
        - { name: 'user1',group: 'group1' }  #在with_items下面以字典的格式記錄數據
        - { name: 'user2',group: 'group2' }
        - { name: 'user3',group: 'group3' }
[root@ansible playbook]# ansible all -m shell -a 'getent passwd'
192.168.219.137 | SUCCESS | rc=0 >>
。。。。。。。
user1:x:502:502::/home/user1:/bin/bash
user2:x:503:503::/home/user2:/bin/bash
user3:x:504:504::/home/user3:/bin/bash

[root@ansible playbook]# ansible all -m shell -a 'getent group'
192.168.219.137 | SUCCESS | rc=0 >>
。。。。。
group1:x:502:
group2:x:503:
group3:x:504:
能夠看到建立的用戶和所屬組的關係是咱們上面定義好的形式
迭代嵌套子變量案例

playbook中template的for if:

for和endfor造成一對兒。

{% for pote in nginx_pote %}
server{

}

{% if server_name is defined %}
server name {{}}
{% endif %}
......
for if示例

迭代是咱們定義好的參數,可是若是是想要產出的數字有規律且不少的狀況下迭代很顯然就不適合了,就須要使用循環來處理。

[root@ansible playbook]# cat for.yml
---
- hosts: all
  remote_user: root
  vars:
    ports:  #在此處定義一個元素列表
      - 81
      - 82
      - 83

  tasks:
     - name: copy conf
       template: src=/home/ansible.test/playbook/for.conf.j2 dest=/root/file123/for.conf
#在拷貝的時候運用模板功能拷貝相應的文件
[root@ansible playbook]# cat for.conf.j2  #建立模板文件。
{% for port in ports %}  #此處須要注意的就是ports,這個ports是playbook裏面定義好的元素列表名
server{
     listen {{ port }} #用for後面的port去拿ports裏面的數據,不斷賦值給此處的變量port,直到ports裏面的數據取完爲止
}
{% endfor %}
[root@ansible playbook]#
運行playbook腳本
[root@ansible playbook]# ansible all -m shell -a 'cat /root/file123/for.conf'
192.168.219.137 | SUCCESS | rc=0 >>
server{
     listen 81
}
server{
     listen 82
}
server{
     listen 83
}

192.168.219.136 | SUCCESS | rc=0 >>
server{
     listen 81
}
server{
     listen 82
}
server{
     listen 83
}

能夠看到for.conf文件取到的指就是ports被模板循環賦值的結果。
template裏面的for運用案例
[root@ansible playbook]# cat for.yml
---
- hosts: all
  remote_user: root
  vars:
    ports:  #咱們把ports裏面的數據定義成字典的形式
      - licent: 85
      - licent: 86
      - licent: 87

  tasks:
     - name: copy conf
       template: src=/home/ansible.test/playbook/for.conf.j2 dest=/root/file123/for.conf

[root@ansible playbook]# cat for.conf.j2
{% for port in ports %}
server{
     listen {{ port.licent }} #變量的位置就須要用到字典的鍵名
}
{% endfor %}
[root@ansible playbook]# ansible all -m shell -a 'cat /root/file123/for.conf'
192.168.219.137 | SUCCESS | rc=0 >>
server{
     listen 85
}
server{
     listen 86
}
server{
     listen 87
}

192.168.219.136 | SUCCESS | rc=0 >>
server{
     listen 85
}
server{
     listen 86
}
server{
     listen 87
}

[root@ansible playbook]#
template裏面的for字典案例

字典的好處就是我能在playbook裏面定義多個鍵值對,這樣我在模板裏面直接取變量名便可。

[root@ansible playbook]# cat for.yml
---
- hosts: all
  remote_user: root
  vars:
    ports:  #ports裏面我定義多個鍵值對
      - licent: 88 
        name: www.88.com
      - licent: 89
        name: www.89.com
      - licent: 90
        name: www.90.com

  tasks:
     - name: copy conf
       template: src=/home/ansible.test/playbook/for.conf.j2 dest=/root/file123/for.conf

[root@ansible playbook]# cat for.conf.j2
{% for port in ports %}
server{
     listen {{ port.licent }}
     server {{ port.name }}  #在模板裏面我只須要調用playbook裏面定義好的變量便可
}
{% endfor %}
[root@ansible playbook]# ansible all -m shell -a 'cat /root/file123/for.conf'
192.168.219.136 | SUCCESS | rc=0 >>
server{
     listen 88
     server www.88.com
}
server{
     listen 89
     server www.89.com
}
server{
     listen 90
     server www.90.com
}

192.168.219.137 | SUCCESS | rc=0 >>
server{
     listen 88
     server www.88.com
}
server{
     listen 89
     server www.89.com
}
server{
     listen 90
     server www.90.com
}

[root@ansible playbook]#
template裏面for字典的案例2

template增長if判斷條件:

[root@ansible playbook]# cat for.conf.j2
{% for port in ports %}  
server{
     listen {{ port.licent }}
{% if port.name is defined %}  #增長判斷,判斷下name是否有指,有指我才執行下面的語句
     server {{ port.name }}
{% endif %}
}
{% endfor %}
[root@ansible playbook]# cat for.yml
---
- hosts: all
  remote_user: root
  vars:
    ports:
      - licent: 91
       # name: www.91.com  #將91的name註釋掉,讓其檢查的時候判斷爲沒有指
      - licent: 92
        name: www.92.com
      - licent: 93
        name: www.93.com

  tasks:
     - name: copy conf
       template: src=/home/ansible.test/playbook/for.conf.j2 dest=/root/file123/for.conf

[root@ansible playbook]# ansible all -m shell -a 'cat /root/file123/for.conf'
192.168.219.137 | SUCCESS | rc=0 >>
server{
     listen 91
}
server{
     listen 92
     server www.92.com
}
server{
     listen 93
     server www.93.com
}

192.168.219.136 | SUCCESS | rc=0 >>
server{
     listen 91
}
server{
     listen 92
     server www.92.com
}
server{
     listen 93
     server www.93.com
}

能夠看到所屬的91是沒有建立name的
增長if案例

♣三:ansible的企業級運用

A:roles角色的運用

在實際工做中,咱們須要管理N臺服務器,這個時候由於機器部署的環境,機器的配置,是不是雲主機等致使ansible在使用的時候簡單的playbook已經不能知足所要處理的任務了,咱們須要層次型結構自動裝載變量文件,task以及handlers等,這樣咱們只須要在playbook裏面使用include指令便可。

roles能完成更加靈活的場景,代碼的複用度也大大增長,能夠經過簡單的include靈活調取所要執行的任務。

咱們在安裝ansible的時候在/etc/ansibe下已經給咱們建立好了roles目錄,咱們只須要在這個目下建立層級結構目錄和文件便可,固然還可使用自定義的目錄。

                                                    

 

咱們經過上圖相似的層級結構,這樣我每一個文件的功能雖然單一,可是文件的功能性更加全面,能夠很好的保證代碼的複用度。

建立roles目錄和相應的工程目錄

mkdir -p roles/{nginx,mysql,httpd}
[root@ansible playbook]# tree roles/
roles/
├── httpd
├── mysql
└── nginx

3 directories, 0 files

調用roles角色的劇本須要放在roles相同層級的目錄下

roles層級下目錄和各目錄的做用;

files:存放由shell或者yum等模塊調用的文件;

templates:模塊須要查找所需的模板文件;

tasks:定義tasks,role的基本元素,至少包含一個名爲main.yml的文件;

handlers:至少包含一個main.yml文件;

vars:定義變量,至少包含一個main.yml文件;

meta:定義當前角色的特殊設定及依賴關係,至少包含一個main.yml文件;

default:設定默認變量時使用此目錄中的main.yml文件。

[root@ansible playbook]# tree roles/
roles/
├── httpd
│   ├── tasks  #分別在tasks目錄下建立相應的操做劇本
│   │   ├── copy.yml     #這每個劇本只作一件事情,例如copy就作配置文件的拷貝
│   │   ├── group.yml   #建立組
│   │   ├── main.yml     #這個劇本的名字是固定的,用來規定這全部劇本的執行順序
│   │   ├── restart.yml  #重啓
│   │   ├── start.yml     #啓動
│   │   ├── user.yml      #建立用戶
│   │   └── yum.yml      #安裝包
│   └── templates
│       └── httpd.conf.j2
├── mysql
└── nginx
directories, 8 files
[root@ansible tasks]# cat copy.yml
- name: copy httpd.conf
 template:src=/home/ansible.test/playbook/roles/httpd/templates/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
[root@ansible tasks]# cat group.yml
- name: create group   #因是roles形式就不須要在單個劇本定義hosts了,在總運行的劇本里面定義便可
  group: name=httpd
[root@ansible tasks]# cat restart.yml
- name: restart server
  service: name=hhtpd state=restarted
[root@ansible tasks]# cat start.yml
- name: start server
  service: name=httpd state=started enabled=yes
[root@ansible tasks]# cat user.yml
- name: create user
  user: name=httpd group=httpd system=yes shell=/sbin/nologin
[root@ansible tasks]# cat yum.yml
- name: install
  yum: name=httpd
用main.yml來規定這些劇本的執行順序
[root@ansible tasks]# cat main.yml
- include: group.yml   
- include: user.yml
- include: yum.yml
- include: copy.yml
- include: start.yml
#include是固定詞
[root@ansible tasks]#
[root@ansible templates]# cat httpd.conf.j2 | grep httpd_server
Listen {{ httpd_server }}
[root@ansible templates]#
定義模板,端口在hosts裏面提早定義
[root@ansible playbook]# cat httpd.yml
---
- hosts: web
  remote_user: root
  roles:  #用關鍵字來調用roles角色下面的httpd,一層層的執行劇本。
    - role: httpd
在roles平級的目錄下寫一個總調用的劇本
[root@ansible playbook]# ansible-playbook httpd.yml

PLAY [web] ******************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************
ok: [192.168.219.137]
ok: [192.168.219.136]

TASK [httpd : copy httpd.conf] **********************************************************************************************
changed: [192.168.219.136]
changed: [192.168.219.137]

TASK [httpd : start server] *************************************************************************************************
changed: [192.168.219.136]
changed: [192.168.219.137]

PLAY RECAP ******************************************************************************************************************
192.168.219.136            : ok=3    changed=2    unreachable=0    failed=0
192.168.219.137            : ok=3    changed=2    unreachable=0    failed=0
[root@ansible playbook]# ansible all -m shell -a 'netstat -anptu | grep httpd'
192.168.219.137 | SUCCESS | rc=0 >>
tcp        0      0 :::9090                     :::*                        LISTEN      3560/httpd

192.168.219.136 | SUCCESS | rc=0 >>
tcp        0      0 :::8080                     :::*                        LISTEN      3382/httpd

[root@ansible playbook]#
這樣咱們經過roles把流程規劃的很清晰,不會再出現單一playbook出現的問題而難以調整或者複用的問題
roles案例
[root@ansible ansible.test]# tree roles
roles
├── keepalived
│   ├── handlers
│   │   └── restart.yml
│   ├── tasks
│   │   ├── copy.yml
│   │   ├── main.yml
│   │   ├── start.yml
│   │   └── yum.yml
│   ├── templates
│   │   └── keepalived.conf.j2
│   └── vars
│       └── main.yml
├── nginx
│   ├── handlers
│   ├── tasks
│   │   ├── copy.yml
│   │   ├── main.yml
│   │   ├── start.yml
│   │   └── yum.yml
│   ├── templates
│   │   └── nginx.conf.j2
│   └── vars
└── redis
    ├── handlers
    ├── tasks
    ├── templates
    └── vars

15 directories, 12 files
[root@ansible ansible.test]# cat roles/keepalived/vars/main.yml
ip_addr: 192.168.219.130/24   把keep須要的虛擬ip經過變量存在vars裏面
[root@ansible ansible.test]# cat roles/keepalived/templates/keepalived.conf.j2

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority {{ vrrp }}
    advert_int 210
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        {{ ip_addr }}
    }
}
[root@ansible ansible.test]# cat setup.yml
---
- hosts: all
  remote_user: root
  roles:
    - { role: keepalived,tags: ['keepalived','web'],when:ansible_nodename == "www8080.http.com"}
    - { role: nginx,tags: ['nginx','web']}
[root@ansible ansible.test]#
在總控制的劇本里面加入tags標籤,並加入判斷,當主機名等於指定的名稱以後才裝keep。
ansible-playbook --tags="keepalived" setup.yml  在執行的時候加上標籤來執行
[root@ansible ansible.test]# ansible all -m shell -a 'ps -aux | grep keepalived'
192.168.219.137 | SUCCESS | rc=0 >>
root       8382  0.0  0.1 106096  1128 pts/1    S+   08:24   0:00 /bin/sh -c ps -aux | grep keepalived
root       8384  0.0  0.0 103308   852 pts/1    S+   08:24   0:00 grep keepalivedWarning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ

192.168.219.136 | SUCCESS | rc=0 >>
root      10398  0.0  0.1 110276  1088 ?        Ss   08:23   0:00 /usr/sbin/keepalived -D
root      10400  0.0  0.2 114584  2944 ?        S    08:23   0:00 /usr/sbin/keepalived -D
root      10401  0.0  0.2 114452  2024 ?        S    08:23   0:00 /usr/sbin/keepalived -D
root      10440  0.0  0.1 106096  1128 pts/1    S+   08:24   0:00 /bin/sh -c ps -aux | grep keepalived
root      10442  0.0  0.0 103308   856 pts/1    S+   08:24   0:00 grep keepalivedWarning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ

[root@ansible ansible.test]# ansible all -m shell -a 'hostname'
192.168.219.137 | SUCCESS | rc=0 >>
www9090.http.com

192.168.219.136 | SUCCESS | rc=0 >>
www8080.http.com
能夠看到總程序能自動判斷並安裝相應的程序
roles案例2,tags的使用
相關文章
相關標籤/搜索