Ansible浅谈

ansible特性:

        模块化,调用特定的模块,完成特定的任务;

        基于Python语言实现,由Paramiko、PyYAML和Jinja2三个关键模块;

        部署简单,agentless;

        主从模式

        支持自定义模块

        支持Playbook

        幂等性:


安装:

        epel,ansible

            配置文件:/etc/ansible/ansible.cfg

                  主机清单:/etc/ansible/hosts

       主程序:

           ansible

           ansible-playbook

           ansible-doc

       ansible的简单使用格式:

          ansible HOST-PATTERN -m MOD_NAME -a MOD_ARGS


ansible常用模块:

     获取模块列表:

          ansible-doc -l

     command模块:在远程主机运行命令;

     shell模块:在远程主机在shell进程下运行命令,支持shell特性,如管道等;

     copy模块:Copies files to remote locations

            用法:

                  (1)src= dest=

                  (2)content= dest=

                  owner,group,mode

      cron模块:Manage cron.d and crontab entries.

             minute=

             day=

             month=

             weekday=

             hour=

             job=

             *name=

             state=

             present:创建

             absent:删除

      fetch模块:Fetches a file from remote nodes

      file模块:Sets attributes of files

              用法

                    (1)创建链接文件:*path= src= state=link

                    (2)修改属性:path= owner= mode= group=

                    (3)创建目录:path= state=directory

      hostname模块:Manager Hostname

             name=

      pip模块:Manages Python library dependencies.

      yum模块:Manages packages with the `yum' package manager

            name=:程序包名称,可以带版本号;

            state=

                    present,latest

                    absent

      service模块:管理服务

            *name=

            state=

                    started

                    stopped

                    restarted

            enabled=

            runlevel=

       user模块:管理用户账号

            *name=

            state=

            system=

            uid=

            shell=

            group=

            groups=

            comment=

            home=

      setup模块:用来获取facts


本次Ansible测试的环境:

Ansible主机:192.168.150.137

两台Centos7:192.168.150.138/192.168.150.139

一台Centos6:192.168.150.133

测试前准备:

网络均能ping通

root@localhost yum.repos.d]# ping 192.168.150.138

PING 192.168.150.138 (192.168.150.138) 56(84) bytes of data.

64 bytes from 192.168.150.138: icmp_seq=1 ttl=64 time=0.650 ms

^C

— 192.168.150.138 ping statistics —

1 packets transmitted, 1 received, 0% packet loss, time 0ms

rtt min/avg/max/mdev = 0.650/0.650/0.650/0.000 ms

[root@localhost yum.repos.d]# ping 192.168.150.139

PING 192.168.150.139 (192.168.150.139) 56(84) bytes of data.

64 bytes from 192.168.150.139: icmp_seq=1 ttl=64 time=1.01 ms

^C

— 192.168.150.139 ping statistics —

1 packets transmitted, 1 received, 0% packet loss, time 0ms

rtt min/avg/max/mdev = 1.010/1.010/1.010/0.000 ms

[root@localhost yum.repos.d]# ping 192.168.150.133

PING 192.168.150.133 (192.168.150.133) 56(84) bytes of data.

64 bytes from 192.168.150.133: icmp_seq=1 ttl=64 time=0.716 ms

^C

— 192.168.150.133 ping statistics —

1 packets transmitted, 1 received, 0% packet loss, time 0ms

rtt min/avg/max/mdev = 0.716/0.716/0.716/0.000 ms

ansible主机安装:yum -y install ansible     配置好epel源

编辑ansible中的hosts文件进行分组

~]# cd /etc/ansible/

ansible]# ls

ansible.cfg  hosts  roles

ansible]# cp hosts{,.bak}

ansible]# vim hosts

ansible]# cat hosts

# This is the default ansible 'hosts' file.

#

# It should live in /etc/ansible/hosts

#

#   – Comments begin with the '#' character

#   – Blank lines are ignored

#   – Groups of hosts are delimited by [header] elements

#   – You can enter hostnames or ip addresses

#   – A hostname/ip can be a member of multiple groups

[websrvs]

192.168.150.138

192.168.150.139

[dbsrvs]

192.168.150.138

192.168.150.133

由于ansible是通过ssh进行管理,对被管理的三台主机进行ssh公钥认证

~]# ssh-keygen -t rsa -P ''

Generating public/private rsa key pair.

Enter file in which to save the key (/root/.ssh/id_rsa):

Created directory '/root/.ssh'.

Your identification has been saved in /root/.ssh/id_rsa.

Your public key has been saved in /root/.ssh/id_rsa.pub.

The key fingerprint is:

9c:fb:5b:bb:06:d9:d5:71:62:12:dc:65:55:7d:90:1f root@localhost.localdomain

The key's randomart image is:

+–[ RSA 2048]—-+

|           ..o.+O|

|            o =E+|

|             o +=|

|       . .    . o|

|        S  o .   |

|         .o .    |

|        .  ..    |

|         . …   |

|          ooo.   |

+—————–+

~]# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.150.138

The authenticity of host '192.168.150.138 (192.168.150.138)' can't be established.

ECDSA key fingerprint is 2a:e3:03:52:8c:84:02:59:a2:26:a3:b2:f6:74:6c:3c.

Are you sure you want to continue connecting (yes/no)? yes

ady installed

ll the new keys

root@192.168.150.138's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.150.138'"

and check to make sure that only the key(s) you wanted were added.

~]# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.150.139

The authenticity of host '192.168.150.139 (192.168.150.139)' can't be established.

ECDSA key fingerprint is 2a:e3:03:52:8c:84:02:59:a2:26:a3:b2:f6:74:6c:3c.

Are you sure you want to continue connecting (yes/no)? yes

ady installed

ll the new keys

root@192.168.150.139's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.150.139'"

and check to make sure that only the key(s) you wanted were added.

~]# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.150.133

The authenticity of host '192.168.150.133 (192.168.150.133)' can't be established.

RSA key fingerprint is d7:5f:1a:ba:53:c3:c7:0e:68:32:bf:76:92:64:ca:a0.

Are you sure you want to continue connecting (yes/no)? yes

ady installed

ll the new keys

root@192.168.150.133's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.150.133'"

and check to make sure that only the key(s) you wanted were added.

Ansible常用模块测试:

ping模块


~]# ansible all -m ping

192.168.150.139 | SUCCESS => {

    "changed": false,

    "ping": "pong"

}

192.168.150.138 | SUCCESS => {

    "changed": false,

    "ping": "pong"

}

192.168.150.133 | SUCCESS => {

    "changed": false,

    "ping": "pong"

}

显示说明文档的简要信息

ansible]# ansible-doc -s ping

– name: Try to connect to host, verify a usable python and return `pong' on success.

  action: ping

yum模块


ansible]# ansible-doc -s yum

– name: Manages packages with the `yum' package manager

  action: yum

      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'.

      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 ",".

      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

      list                   # Various (non-idempotent) commands for usage with `/usr/bin/ansible'

                               and `not' playbooks. See examples.

      name=                  # Package name, or package specifier with version, like `name-1.0'. 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.

      state                  # Whether to install (`present' or `installed', `latest'), or remove

                               (`absent' or `removed') a package.

      update_cache           # Force updating the cache. Has an effect only if state is `present' or

                               `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'.

~]# ansible all -m yum -a "name=httpd state=absent"

192.168.150.133 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

httpd.x86_64 0:2.2.15-55.el6.centos.2                                         \n\nComplete!\n"

    ]

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

od_ssl.x86_64 1:2.4.6-40.el7.centos.4     php.x86_64 0:5.4.16-36.3.el7_2    \n\n完毕!\n"

    ]

}

192.168.150.138 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

sl.x86_64 1:2.4.6-40.el7.centos.4                                        \n\n完毕!\n"

    ]

}

~]# ansible all -m yum -a "name=httpd state=latest"

192.168.150.133 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

5-55.el6.centos.2                                         \n\nComplete!\n"

    ]

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

                                      \n\n完毕!\n"

    ]

}

192.168.150.138 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

                                \n\n完毕!\n"

    ]

}

command模块


ansible]# ansible-doc -s command     此模块是默认选项,在ansible不见任何模块是默认即使用comman模块

– name: Executes a command on a remote node

  action: command

      chdir                  # cd into this directory before running the command

      creates                # a filename or (since 2.0) glob pattern, 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=             # the command module takes a free form command to run.  There is no

                               parameter actually named 'free form'.

                               See the examples!

      removes                # a filename or (since 2.0) glob pattern, when it does not exist, this

                               step will *not* be run.

      warn                   # if command warnings are on in ansible.cfg, do not warn about this

                               particular line if set to no/false.

ansible]# ansible websrvs -m command -a 'ls /var'

192.168.150.139 | SUCCESS | rc=0 >>

adm

cache

crash

db

empty

games

gopher

kerberos

lib

local

lock

log

mail

nis

opt

preserve

run

spool

tmp

www

yp

192.168.150.138 | SUCCESS | rc=0 >>

adm

cache

crash

db

empty

games

gopher

kerberos

lib

local

lock

log

mail

nis

opt

preserve

run

spool

tmp

www

yp

[root@localhost ansible]# ansible websrvs -a 'ls /var'

192.168.150.138 | SUCCESS | rc=0 >>

adm

cache

crash

db

empty

games

gopher

kerberos

lib

local

lock

log

mail

nis

opt

preserve

run

spool

tmp

www

yp

192.168.150.139 | SUCCESS | rc=0 >>

adm

cache

crash

db

empty

games

gopher

kerberos

lib

local

lock

log

mail

nis

opt

preserve

run

spool

tmp

www

yp

ansible]# ansible websrvs -a 'useradd user1'

192.168.150.138 | SUCCESS | rc=0 >>

192.168.150.139 | SUCCESS | rc=0 >>

ansible]# ansible websrvs -a 'echo void | passwd –stdin user1'     command的参数不支持管道,需通过shell模块来支持

192.168.150.139 | SUCCESS | rc=0 >>

void | passwd –stdin user1

192.168.150.138 | SUCCESS | rc=0 >>

void | passwd –stdin user1

shell模块


ansible]# ansible-doc -s shell

– name: Execute commands in nodes.

  action: 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=             # 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.

      warn                   # if command warnings are on in ansible.cfg, do not warn about this

                               particular line if set to no/false.

ansible]# ansible websrvs -m shell -a 'echo void | passwd –stdin user1'

192.168.150.138 | SUCCESS | rc=0 >>

更改用户 user1 的密码 。

passwd:所有的身份验证令牌已经成功更新。

192.168.150.139 | SUCCESS | rc=0 >>

更改用户 user1 的密码 。

passwd:所有的身份验证令牌已经成功更新。


copy模块

ansible]# ansible-doc -s copy

– name: Copies files to remote locations.

  action: copy

      backup                 # Create a backup file including the timestamp information so you can

                               get the original file back if you

                               somehow clobbered it incorrectly.

      content                # When used instead of 'src', sets the contents of a file directly to

                               the specified value. This is for simple

                               values, for anything complex or with

                               formatting please switch to the

                               template module.

      dest=                  # Remote absolute path where the file should be copied to. If src is a

                               directory, this must be a directory

                               too.

      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, 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'

      mode                   # mode the file or directory should be. For those used to

                               `/usr/bin/chmod' remember that modes

                               are actually octal numbers (like 0644).

                               Leaving off the leading zero will

                               likely 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').

      owner                  # name of the user that should own the file/directory, as would be fed

                               to `chown'

      remote_src             # If False, it will search for src at originating/master machine, if

                               True it will go to the remote/target

                               machine for the src. Default is False.

                               Currently remote_src does not support

                               recursive copying.

      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.

a、将文件拷贝至各被管理主机

ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab"      

192.168.150.139 | SUCCESS => {

    "changed": true,

    "checksum": "efcce184759db569346abcbb55686bbd3a7a387b",

    "dest": "/tmp/fstab",

    "gid": 0,

    "group": "root",

    "md5sum": "b5b57afea153639c2f0082a3ea764192",

    "mode": "0644",

    "owner": "root",

    "size": 465,

    "src": "/root/.ansible/tmp/ansible-tmp-1478674427.63-215984605850567/source",

    "state": "file",

    "uid": 0

}

192.168.150.138 | SUCCESS => {

    "changed": true,

    "checksum": "efcce184759db569346abcbb55686bbd3a7a387b",

    "dest": "/tmp/fstab",

    "gid": 0,

    "group": "root",

    "md5sum": "b5b57afea153639c2f0082a3ea764192",

    "mode": "0644",

    "owner": "root",

    "size": 465,

    "src": "/root/.ansible/tmp/ansible-tmp-1478674427.6-49164059723033/source",

    "state": "file",

    "uid": 0

}

192.168.150.133 | SUCCESS => {

    "changed": true,

    "checksum": "efcce184759db569346abcbb55686bbd3a7a387b",

    "dest": "/tmp/fstab",

    "gid": 0,

    "group": "root",

    "md5sum": "b5b57afea153639c2f0082a3ea764192",

    "mode": "0644",

    "owner": "root",

    "size": 465,

    "src": "/root/.ansible/tmp/ansible-tmp-1478674427.6-185161529910096/source",

    "state": "file",

    "uid": 0

}

被管理主机状态

~]# ls /tmp/

fstab  httpd.crt  systemd-private-b03b2a0b72a54248954ee1d2328a6818-httpd.service-CbpdoM

b、将内容传递至被管理主机文件中

~]# ansible all -m copy -a "content='hello ansible' dest=/tmp/testfile"

192.168.150.133 | SUCCESS => {

    "changed": true,

    "checksum": "7b320b1dc0c867516cf00728df488daa3532bc1f",

    "dest": "/tmp/testfile",

    "gid": 0,

    "group": "root",

    "md5sum": "37bc018071eae9a0e879c31b2f9aa554",

    "mode": "0644",

    "owner": "root",

    "size": 13,

    "src": "/root/.ansible/tmp/ansible-tmp-1478674619.82-143184915917329/source",

    "state": "file",

    "uid": 0

}

192.168.150.138 | SUCCESS => {

    "changed": true,

    "checksum": "7b320b1dc0c867516cf00728df488daa3532bc1f",

    "dest": "/tmp/testfile",

    "gid": 0,

    "group": "root",

    "md5sum": "37bc018071eae9a0e879c31b2f9aa554",

    "mode": "0644",

    "owner": "root",

    "size": 13,

    "src": "/root/.ansible/tmp/ansible-tmp-1478674619.81-251006283956641/source",

    "state": "file",

    "uid": 0

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "checksum": "7b320b1dc0c867516cf00728df488daa3532bc1f",

    "dest": "/tmp/testfile",

    "gid": 0,

    "group": "root",

    "md5sum": "37bc018071eae9a0e879c31b2f9aa554",

    "mode": "0644",

    "owner": "root",

    "size": 13,

    "src": "/root/.ansible/tmp/ansible-tmp-1478674619.86-136685496450394/source",

    "state": "file",

    "uid": 0

}

被管理主机状态

~]# cd /tmp/

tmp]# ls

fstab  httpd.crt  systemd-private-b03b2a0b72a54248954ee1d2328a6818-httpd.service-CbpdoM  testfile

tmp]# cat testfile

hello ansible[root@localhost tmp]#

c、拷贝是带权限指定

 ~]# ansible all -m copy -a "content='hello ansible\n' mode=600 dest=/tmp/testfile"

192.168.150.138 | SUCCESS => {

    "changed": true,

    "checksum": "df800445bb74b4abb144b3f9bf03f90aa9618f4c",

    "dest": "/tmp/testfile",

    "gid": 0,

    "group": "root",

    "md5sum": "f61d358bbdd6a9bd2e93322023a4e29d",

    "mode": "0600",

    "owner": "root",

    "size": 14,

    "src": "/root/.ansible/tmp/ansible-tmp-1478674782.24-143392146139391/source",

    "state": "file",

    "uid": 0

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "checksum": "df800445bb74b4abb144b3f9bf03f90aa9618f4c",

    "dest": "/tmp/testfile",

    "gid": 0,

    "group": "root",

    "md5sum": "f61d358bbdd6a9bd2e93322023a4e29d",

    "mode": "0600",

    "owner": "root",

    "size": 14,

    "src": "/root/.ansible/tmp/ansible-tmp-1478674782.24-68939485219113/source",

    "state": "file",

    "uid": 0

}

192.168.150.133 | SUCCESS => {

    "changed": true,

    "checksum": "df800445bb74b4abb144b3f9bf03f90aa9618f4c",

    "dest": "/tmp/testfile",

    "gid": 0,

    "group": "root",

    "md5sum": "f61d358bbdd6a9bd2e93322023a4e29d",

    "mode": "0600",

    "owner": "root",

    "size": 14,

    "src": "/root/.ansible/tmp/ansible-tmp-1478674782.23-6367200716688/source",

    "state": "file",

    "uid": 0

}

被管理主机状态

tmp]# ll

总用量 8

-rw-r–r– 1 root root 465 12月  8 19:29 fstab

-rw-r–r– 1 root root   0 12月  1 01:45 httpd.crt

ce-CbpdoM

-rw——- 1 root root  14 12月  8 19:35 testfile

cron模块:


~]# ansible-doc -s cron

– name: Manage cron.d and crontab entries.

  action: 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). 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. 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 )

a、给三台被管理主机统一添加对时脚本cron

~]# ansible all -m cron -a "minute=*/5 job='/sbin/ntpdate 10.53.1.9 &>/dev/null' name=Synctime"

192.168.150.133 | SUCCESS => {

    "changed": true,

    "envs": [],

    "jobs": [

        "Synctime"

    ]

}

192.168.150.138 | SUCCESS => {

    "changed": true,

    "envs": [],

    "jobs": [

        "Synctime"

    ]

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "envs": [],

    "jobs": [

        "Synctime"

    ]

}

执行后被管理主机状态

~]# crontab -l

#Ansible: Synctime

*/5 * * * * /sbin/ntpdate 10.53.1.9 &>/dev/null

b、删除cron

~]# ansible all -m cron -a "state=absent name=Synctime"

192.168.150.138 | SUCCESS => {

    "changed": true,

    "envs": [],

    "jobs": []

}

192.168.150.133 | SUCCESS => {

    "changed": true,

    "envs": [],

    "jobs": []

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "envs": [],

    "jobs": []

}

被管理主机状态,已被删除

]# crontab -l

file模块


~]# ansible-doc -s file

– name: Sets attributes of files

  action: file

      follow                 # This flag indicates that filesystem links, if they exist, should be

                               followed.

      force                  # force the creation of the symlinks in two cases: the source file does

                               not exist (but will appear later); the

                               destination exists and is a file (so, we

                               need to unlink the "path" file and create

                               symlink to the "src" file in place of

                               it).

      group                  # name of the group that should own the file/directory, as would be fed to

                               `chown'

      mode                   # mode the file or directory should be. For those used to `/usr/bin/chmod'

                               remember that modes are actually octal

                               numbers (like 0644). Leaving off the

                               leading zero will likely 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').

      owner                  # name of the user that should own the file/directory, as would be fed to

                               `chown'

      path=                  # path to the file being managed.  Aliases: `dest', `name'

      recurse                # recursively set the specified file attributes (applies only to

                               state=directory)

      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                    # path of the file to link to (applies only to `state=link'). Will accept

                               absolute, relative and nonexisting paths.

                               Relative paths are not expanded.

      state                  # If `directory', all immediate subdirectories will be created if they do

                               not exist, since 1.7 they will be created

                               with the supplied permissions. If `file',

                               the file will NOT be created if it does

                               not exist, see the [copy] or [template]

                               module if you want that behavior.  If

                               `link', the symbolic link will be created

                               or changed. Use `hard' for hardlinks. If

                               `absent', directories will be recursively

                               deleted, and files or symlinks will be

                               unlinked. Note that [file] will not fail

                               if the `path' does not exist as the state

                               did not change. If `touch' (new in 1.4),

                               an empty file will be created if the

                               `path' does not exist, while an existing

                               file or directory will receive updated

                               file access and modification times

                               (similar to the way `touch` works from

                               the command line).

      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.

a、创建连接件文件

~]# ansible all -m file -a "src=/tmp/fstab path=/tmp/fstab.link state=link"

192.168.150.133 | SUCCESS => {

    "changed": true,

    "dest": "/tmp/fstab.link",

    "gid": 0,

    "group": "root",

    "mode": "0777",

    "owner": "root",

    "size": 10,

    "src": "/tmp/fstab",

    "state": "link",

    "uid": 0

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "dest": "/tmp/fstab.link",

    "gid": 0,

    "group": "root",

    "mode": "0777",

    "owner": "root",

    "size": 10,

    "src": "/tmp/fstab",

    "state": "link",

    "uid": 0

}

192.168.150.138 | SUCCESS => {

    "changed": true,

    "dest": "/tmp/fstab.link",

    "gid": 0,

    "group": "root",

    "mode": "0777",

    "owner": "root",

    "size": 10,

    "src": "/tmp/fstab",

    "state": "link",

    "uid": 0

}

被管理主机状态

tmp]# ll

总用量 8

-rw-r–r– 1 root root 465 12月  8 19:29 fstab

lrwxrwxrwx 1 root root  10 12月  8 19:48 fstab.link -> /tmp/fstab

-rw-r–r– 1 root root   0 12月  1 01:45 httpd.crt

-CbpdoM

-rw——- 1 root root  14 12月  8 19:35 testfile

b、创建目录

~]# ansible all -m file -a "path=/tmp/tmpdir state=directory"

192.168.150.133 | SUCCESS => {

    "changed": true,

    "gid": 0,

    "group": "root",

    "mode": "0755",

    "owner": "root",

    "path": "/tmp/tmpdir",

    "size": 4096,

    "state": "directory",

    "uid": 0

}

192.168.150.138 | SUCCESS => {

    "changed": true,

    "gid": 0,

    "group": "root",

    "mode": "0755",

    "owner": "root",

    "path": "/tmp/tmpdir",

    "size": 6,

    "state": "directory",

    "uid": 0

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "gid": 0,

    "group": "root",

    "mode": "0755",

    "owner": "root",

    "path": "/tmp/tmpdir",

    "size": 6,

    "state": "directory",

    "uid": 0

}

被管理主机状态

tmp]# ll

总用量 8

-rw-r–r– 1 root root 465 12月  8 19:29 fstab

lrwxrwxrwx 1 root root  10 12月  8 19:48 fstab.link -> /tmp/fstab

-rw-r–r– 1 root root   0 12月  1 01:45 httpd.crt

-CbpdoM

-rw——- 1 root root  14 12月  8 19:35 testfile

drwxr-xr-x 2 root root   6 12月  8 19:50 tmpdir

hostname模块


 ~]# ansible-doc -s hostname

– name: Manage hostname

  action: hostname

      name=                  # Name of the host

service模块


~]# ansible-doc -s service

– name: Manage services.

  action: 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=                  # 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'

开启被管理主机httpd服务

 ~]# ansible all -m shell -a "ss -tnl | grep :80"

192.168.150.139 | FAILED | rc=1 >>

192.168.150.138 | FAILED | rc=1 >>

192.168.150.133 | FAILED | rc=1 >>

~]# ansible all -m service -a "name=httpd state=started"

192.168.150.138 | SUCCESS => {

    "changed": true,

    "name": "httpd",

    "state": "started",

    "status": {

        "ActiveEnterTimestampMonotonic": "0",

        "ActiveExitTimestampMonotonic": "0",

        "ActiveState": "inactive",

ystemd-journald.socket",

        "AllowIsolate": "no",

        "AssertResult": "no",

        "AssertTimestampMonotonic": "0",

        "Before": "shutdown.target",

        "BlockIOAccounting": "no",

        "BlockIOWeight": "18446744073709551615",

        "CPUAccounting": "no",

        "CPUQuotaPerSecUSec": "infinity",

        "CPUSchedulingPolicy": "0",

        "CPUSchedulingPriority": "0",

        "CPUSchedulingResetOnFork": "no",

        "CPUShares": "18446744073709551615",

        "CanIsolate": "no",

        "CanReload": "yes",

        "CanStart": "yes",

        "CanStop": "yes",

        "CapabilityBoundingSet": "18446744073709551615",

        "ConditionResult": "no",

        "ConditionTimestampMonotonic": "0",

        "Conflicts": "shutdown.target",

        "ControlPID": "0",

        "DefaultDependencies": "yes",

        "Delegate": "no",

        "Description": "The Apache HTTP Server",

        "DevicePolicy": "auto",

        "Documentation": "man:httpd(8) man:apachectl(8)",

        "EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)",

        "ExecMainCode": "0",

        "ExecMainExitTimestampMonotonic": "0",

        "ExecMainPID": "0",

        "ExecMainStartTimestampMonotonic": "0",

        "ExecMainStatus": "0",

rors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",

rors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",

ime=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",

        "FailureAction": "none",

        "FileDescriptorStoreMax": "0",

        "FragmentPath": "/usr/lib/systemd/system/httpd.service",

        "GuessMainPID": "yes",

        "IOScheduling": "0",

        "Id": "httpd.service",

        "IgnoreOnIsolate": "no",

        "IgnoreOnSnapshot": "no",

        "IgnoreSIGPIPE": "yes",

        "InactiveEnterTimestampMonotonic": "0",

        "InactiveExitTimestampMonotonic": "0",

        "JobTimeoutAction": "none",

        "JobTimeoutUSec": "0",

        "KillMode": "control-group",

        "KillSignal": "18",

        "LimitAS": "18446744073709551615",

        "LimitCORE": "18446744073709551615",

        "LimitCPU": "18446744073709551615",

        "LimitDATA": "18446744073709551615",

        "LimitFSIZE": "18446744073709551615",

        "LimitLOCKS": "18446744073709551615",

        "LimitMEMLOCK": "65536",

        "LimitMSGQUEUE": "819200",

        "LimitNICE": "0",

        "LimitNOFILE": "4096",

        "LimitNPROC": "3829",

        "LimitRSS": "18446744073709551615",

        "LimitRTPRIO": "0",

        "LimitRTTIME": "18446744073709551615",

        "LimitSIGPENDING": "3829",

        "LimitSTACK": "18446744073709551615",

        "LoadState": "loaded",

        "MainPID": "0",

        "MemoryAccounting": "no",

        "MemoryCurrent": "18446744073709551615",

        "MemoryLimit": "18446744073709551615",

        "MountFlags": "0",

        "Names": "httpd.service",

        "NeedDaemonReload": "no",

        "Nice": "0",

        "NoNewPrivileges": "no",

        "NonBlocking": "no",

        "NotifyAccess": "main",

        "OOMScoreAdjust": "0",

        "OnFailureJobMode": "replace",

        "PermissionsStartOnly": "no",

        "PrivateDevices": "no",

        "PrivateNetwork": "no",

        "PrivateTmp": "yes",

        "ProtectHome": "no",

        "ProtectSystem": "no",

        "RefuseManualStart": "no",

        "RefuseManualStop": "no",

        "RemainAfterExit": "no",

        "Requires": "basic.target -.mount",

        "RequiresMountsFor": "/tmp /var/tmp",

        "Restart": "no",

        "RestartUSec": "100ms",

        "Result": "success",

        "RootDirectoryStartOnly": "no",

        "RuntimeDirectoryMode": "0755",

        "SameProcessGroup": "no",

        "SecureBits": "0",

        "SendSIGHUP": "no",

        "SendSIGKILL": "yes",

        "Slice": "system.slice",

        "StandardError": "inherit",

        "StandardInput": "null",

        "StandardOutput": "journal",

        "StartLimitAction": "none",

        "StartLimitBurst": "5",

        "StartLimitInterval": "10000000",

        "StartupBlockIOWeight": "18446744073709551615",

        "StartupCPUShares": "18446744073709551615",

        "StatusErrno": "0",

        "StopWhenUnneeded": "no",

        "SubState": "dead",

        "SyslogLevelPrefix": "yes",

        "SyslogPriority": "30",

        "SystemCallErrorNumber": "0",

        "TTYReset": "no",

        "TTYVHangup": "no",

        "TTYVTDisallocate": "no",

        "TimeoutStartUSec": "1min 30s",

        "TimeoutStopUSec": "1min 30s",

        "TimerSlackNSec": "50000",

        "Transient": "no",

        "Type": "notify",

        "UMask": "0022",

        "UnitFilePreset": "disabled",

        "UnitFileState": "disabled",

        "Wants": "system.slice",

        "WatchdogTimestampMonotonic": "0",

        "WatchdogUSec": "0"

    }

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "name": "httpd",

    "state": "started",

    "status": {

        "ActiveEnterTimestampMonotonic": "0",

        "ActiveExitTimestampMonotonic": "0",

        "ActiveState": "inactive",

arget remote-fs.target",

        "AllowIsolate": "no",

        "AssertResult": "no",

        "AssertTimestampMonotonic": "0",

        "Before": "shutdown.target",

        "BlockIOAccounting": "no",

        "BlockIOWeight": "18446744073709551615",

        "CPUAccounting": "no",

        "CPUQuotaPerSecUSec": "infinity",

        "CPUSchedulingPolicy": "0",

        "CPUSchedulingPriority": "0",

        "CPUSchedulingResetOnFork": "no",

        "CPUShares": "18446744073709551615",

        "CanIsolate": "no",

        "CanReload": "yes",

        "CanStart": "yes",

        "CanStop": "yes",

        "CapabilityBoundingSet": "18446744073709551615",

        "ConditionResult": "no",

        "ConditionTimestampMonotonic": "0",

        "Conflicts": "shutdown.target",

        "ControlPID": "0",

        "DefaultDependencies": "yes",

        "Delegate": "no",

        "Description": "The Apache HTTP Server",

        "DevicePolicy": "auto",

        "Documentation": "man:httpd(8) man:apachectl(8)",

        "EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)",

        "ExecMainCode": "0",

        "ExecMainExitTimestampMonotonic": "0",

        "ExecMainPID": "0",

        "ExecMainStartTimestampMonotonic": "0",

        "ExecMainStatus": "0",

rors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",

rors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",

ime=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",

        "FailureAction": "none",

        "FileDescriptorStoreMax": "0",

        "FragmentPath": "/usr/lib/systemd/system/httpd.service",

        "GuessMainPID": "yes",

        "IOScheduling": "0",

        "Id": "httpd.service",

        "IgnoreOnIsolate": "no",

        "IgnoreOnSnapshot": "no",

        "IgnoreSIGPIPE": "yes",

        "InactiveEnterTimestampMonotonic": "0",

        "InactiveExitTimestampMonotonic": "0",

        "JobTimeoutAction": "none",

        "JobTimeoutUSec": "0",

        "KillMode": "control-group",

        "KillSignal": "18",

        "LimitAS": "18446744073709551615",

        "LimitCORE": "18446744073709551615",

        "LimitCPU": "18446744073709551615",

        "LimitDATA": "18446744073709551615",

        "LimitFSIZE": "18446744073709551615",

        "LimitLOCKS": "18446744073709551615",

        "LimitMEMLOCK": "65536",

        "LimitMSGQUEUE": "819200",

        "LimitNICE": "0",

        "LimitNOFILE": "4096",

        "LimitNPROC": "3829",

        "LimitRSS": "18446744073709551615",

        "LimitRTPRIO": "0",

        "LimitRTTIME": "18446744073709551615",

        "LimitSIGPENDING": "3829",

        "LimitSTACK": "18446744073709551615",

        "LoadState": "loaded",

        "MainPID": "0",

        "MemoryAccounting": "no",

        "MemoryCurrent": "18446744073709551615",

        "MemoryLimit": "18446744073709551615",

        "MountFlags": "0",

        "Names": "httpd.service",

        "NeedDaemonReload": "no",

        "Nice": "0",

        "NoNewPrivileges": "no",

        "NonBlocking": "no",

        "NotifyAccess": "main",

        "OOMScoreAdjust": "0",

        "OnFailureJobMode": "replace",

        "PermissionsStartOnly": "no",

        "PrivateDevices": "no",

        "PrivateNetwork": "no",

        "PrivateTmp": "yes",

        "ProtectHome": "no",

        "ProtectSystem": "no",

        "RefuseManualStart": "no",

        "RefuseManualStop": "no",

        "RemainAfterExit": "no",

        "Requires": "-.mount basic.target",

        "RequiresMountsFor": "/tmp /var/tmp",

        "Restart": "no",

        "RestartUSec": "100ms",

        "Result": "success",

        "RootDirectoryStartOnly": "no",

        "RuntimeDirectoryMode": "0755",

        "SameProcessGroup": "no",

        "SecureBits": "0",

        "SendSIGHUP": "no",

        "SendSIGKILL": "yes",

        "Slice": "system.slice",

        "StandardError": "inherit",

        "StandardInput": "null",

        "StandardOutput": "journal",

        "StartLimitAction": "none",

        "StartLimitBurst": "5",

        "StartLimitInterval": "10000000",

        "StartupBlockIOWeight": "18446744073709551615",

        "StartupCPUShares": "18446744073709551615",

        "StatusErrno": "0",

        "StopWhenUnneeded": "no",

        "SubState": "dead",

        "SyslogLevelPrefix": "yes",

        "SyslogPriority": "30",

        "SystemCallErrorNumber": "0",

        "TTYReset": "no",

        "TTYVHangup": "no",

        "TTYVTDisallocate": "no",

        "TimeoutStartUSec": "1min 30s",

        "TimeoutStopUSec": "1min 30s",

        "TimerSlackNSec": "50000",

        "Transient": "no",

        "Type": "notify",

        "UMask": "0022",

        "UnitFilePreset": "disabled",

        "UnitFileState": "disabled",

        "Wants": "system.slice",

        "WatchdogTimestampMonotonic": "0",

        "WatchdogUSec": "0"

    }

}

192.168.150.133 | SUCCESS => {

    "changed": true,

    "name": "httpd",

    "state": "started"

}

~]# ansible all -m shell -a "ss -tnl | grep :80"

192.168.150.133 | SUCCESS | rc=0 >>

LISTEN     0      128                      :::80                      :::*     

192.168.150.138 | SUCCESS | rc=0 >>

LISTEN     0      128         :::80                      :::*                 

192.168.150.139 | SUCCESS | rc=0 >>

LISTEN     0      128         :::80                      :::*      

user模块


~]# ansible-doc -s user

– name: Manage user accounts

  action: user

      append                 # If `yes', will only add groups, not set them to just the list in

                               `groups'.

      comment                # Optionally sets the description (aka `GECOS') of user account.

      createhome             # Unless set to `no', a home directory will be made for the user when the

                               account is created or if the home

                               directory does not exist.

      expires                # An expiry time for the user in epoch, it will be ignored on platforms

                               that do not support this. Currently

                               supported on Linux and FreeBSD.

      force                  # When used with `state=absent', behavior is as with `userdel –force'.

      generate_ssh_key       # Whether to generate a SSH key for the user in question. This will *not*

                               overwrite an existing SSH key.

      group                  # Optionally sets the user's primary group (takes a group name).

      groups                 # Puts the user in this comma-delimited list of groups. When set to the

                               empty string ('groups='), the user is

                               removed from all groups except the

                               primary group.

      home                   # Optionally set the user's home directory.

      login_class            # Optionally sets the user's login class for FreeBSD, OpenBSD and NetBSD

                               systems.

创建一系统账号

~]# ansible all -m user -a "name=user2 system=yes state=present uid=306"

192.168.150.133 | SUCCESS => {

    "append": false,

    "changed": true,

    "comment": "",

    "group": 510,

    "home": "/home/user2",

    "move_home": false,

    "name": "user2",

    "shell": "/bin/bash",

    "state": "present",

    "uid": 306

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "comment": "",

    "createhome": true,

    "group": 306,

    "home": "/home/user2",

    "name": "user2",

    "shell": "/bin/bash",

    "state": "present",

    "system": true,

    "uid": 306

}

192.168.150.138 | SUCCESS => {

    "changed": true,

    "comment": "",

    "createhome": true,

    "group": 306,

    "home": "/home/user2",

    "name": "user2",

    "shell": "/bin/bash",

    "state": "present",

    "system": true,

    "uid": 306

}

setup模块

~]# ansible-doc -s setup

– name: Gathers facts about remote hosts

  action: setup

      fact_path              # path used for local ansible facts (*.fact) – files in this dir will be

                               run (if executable) and their results be

                               added to ansible_local facts if a file is

                               not executable it is read. Check notes

                               for Windows options. (from 2.1 on)

                               File/results format can be json or ini-

                               format

      filter                 # if supplied, only return facts that match this shell-style (fnmatch)

                               wildcard.

      gather_subset          # if supplied, restrict the additional facts collected to the given

                               subset. Possible values: all, hardware,

                               network, virtual, ohai, and facter Can

                               specify a list of values to specify a

                               larger subset. Values can also be used

                               with an initial `!' to specify that that

                               specific subset should not be collected.

                               For instance: !hardware, !network,

                               !virtual, !ohai, !facter.  Note that a

                               few facts are always collected.  Use the

                               filter parameter if you do not want to

                               display those.

      gather_timeout         # Set the default timeout in seconds for individual fact gathering

~]# ansible 192.168.150.138 -m setup     setup模块可以提供templates中的变量



playbook

YAML:playbook语法格式

     packages:

          -httpd

          -php

          -php-mysql

     version:0.1

[1,2,3,4]

{1:mon,2:[red,blue,yellow]}


playbook的核心元素:

Hosts:

tasks: 任务

variables: 变量

templates: 模板,包含了模板语法的文本文件;

handlers: 处理器,由特定条件触发的任务;


       roles: 角色


playbook的基础组件:

    Hosts:运行指定任务的目标主机;

    remote_user:在远程主机上执行任务的用户;

        sudo_user:

    tasks:任务列表   

        模块,模块参数;

        格式:

            (1)action:module arguments

            (2)module:arguments


            注意:shell和command模块后面直接跟命令,而非key=value类的参数列表;


        (1)某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers;

        (2)任务可以通过"tags"打标签,而后可在ansible-playbook命令上使用-t指定进行调用;


运行playbook的方式:

    (1)测试

        ansible-playbook –check

            只检测可能会发生的改变,但不真正执行操作;

        ansible-playbook –list-hosts

            列出运行任务的主机;

    (2)运行


handlers:

    任务,在特定条件下触发;

    接收到其他任务的通知时被触发;


variables:

    (1)facts:可直接调用;

    (2)ansible-playbook命令的命令行中的自定义变量:

        -e VARS,–extra-vars=VARS

    (3)通过role传递变量;

    (4)Host Inventory

        (a)向不同的主机传递不同变量;

            IP/HOSTNAME variable=value var2=values2

        (b)向组中的主机传递相同的变量

            [groupname:vars]

            variable=value


        注意:inventory参数:

            用于定义ansible远程连接目标主机时使用的参数,而非传递给playbook的变量;

                ansible_ssh_host

                ansible_ssh_port

                ansible_ssh_user

                ansible_ssh_pass

                ansible_sudo_pass

            …            


实验:

创建一个yaml文件小试牛刀


~]# vim first.yaml

– hosts: all

  remote_user: root

  tasks:

  – name: create a user user3

    user: name=user3 system=true uid=307

  – name: create a user user4

    user: name=user4 system=true uid=308

~]# ansible-playbook –check first.yaml

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

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

ok: [192.168.150.133]

TASK [create a user user3] *****************************************************

changed: [192.168.150.133]

changed: [192.168.150.138]

changed: [192.168.150.139]

TASK [create a user user4] *****************************************************

changed: [192.168.150.133]

changed: [192.168.150.138]

changed: [192.168.150.139]

PLAY RECAP *********************************************************************

192.168.150.133            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0   

~]# ansible-playbook –list-hosts first.yaml 查看host清单

playbook: first.yaml

  play #1 (all): all    TAGS: []

    pattern: [u'all']

    hosts (3):

      192.168.150.138

      192.168.150.139

      192.168.150.133

playbook之httpd的测试:

yum安装httpd;修改配置文件,监听端口为8080;开启httpd服务;重启httpd服务


创建一个playbook的工作目录

~]# mkdir working    

[root@localhost ~]# cd working/

working]# ls

working]# mkdir files

本地安装httpd,主要用于使用httpd的配置文件

working]# rpm -q httpd      

未安装软件包 httpd

working]# yum -y install httpd

working]# cp /etc/httpd/conf/httpd.conf files/

working]# vim files/httpd.conf     修改httpd的监听端口为8080

创建web.yaml文件

working]# ls

files

working]# vim web.yaml

– hosts: websrvs

  remote_user: root

  tasks:

  – name: install httpd package     安装httpd的包

    yum: name=httpd state=present

  – name: install configure file     将本地配置文件拷贝至被管理主机

    copy: src=files/httpd.conf dest=/etc/httpd/conf/

  – name: start httpd service     开启httpd服务

    service: name=httpd state=started

yaml文件的检测

working]# ansible-playbook –check web.yaml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************     

ok: [192.168.150.138]

ok: [192.168.150.139]

由于被管理主机已经安装了httpd,所有此处的状态为OK

TASK [install httpd package] ***************************************************          

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [install configure file] **************************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

TASK [start httpd service] *****************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=4    changed=1    unreachable=0    failed=0   

192.168.150.139            : ok=4    changed=1    unreachable=0    failed=0   

为了实验效果,此处使用yum模块删除httpd,不然会影响后面的start和配置文件修改等步骤

working]# ansible all -m yum -a "name=httpd state=absent"

192.168.150.133 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

nComplete!\n"

    ]

}

192.168.150.139 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

\n删除:\n  httpd.x86_64 0:2.4.6-40.el7.centos.4                                          \n\n完毕!\n"

    ]

}

192.168.150.138 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

\n删除:\n  httpd.x86_64 0:2.4.6-40.el7.centos.4                                          \n\n完毕!\n"

    ]

}

删除完成后install任务和配置文件的任务均是change状态

working]# ansible-playbook –check web.yaml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [install httpd package] ***************************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

TASK [install configure file] **************************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

TASK [start httpd service] *****************************************************

ested service \"'httpd'\": "}

ested service \"'httpd'\": "}

    to retry, use: –limit @/root/working/web.retry

PLAY RECAP *********************************************************************

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=1   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=1   

执行web.yaml的playbook

orking]# ansible-playbook web.yaml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [install httpd package] ***************************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

TASK [install configure file] **************************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

TASK [start httpd service] *****************************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=4    changed=3    unreachable=0    failed=0   

192.168.150.139            : ok=4    changed=3    unreachable=0    failed=0   

查看状态,被管理主机均被安装了httpd,开启后以8080端口监听

working]# ansible websrvs -m shell -a "ss -tnl | grep :8080"

192.168.150.138 | SUCCESS | rc=0 >>

LISTEN     0      128         :::8080                    :::*                 

192.168.150.139 | SUCCESS | rc=0 >>

LISTEN     0      128         :::8080                    :::*                 

yaml文件中使用shell模块,执行后并不会显示出执行结果

working]# cat web.yaml

– hosts: websrvs

  remote_user: root

  tasks:

  – name: install httpd package

    yum: name=httpd state=present

  – name: install configure file

    copy: src=files/httpd.conf dest=/etc/httpd/conf/

  – name: start httpd service

    service: name=httpd state=started

  – name: execute ss command

    shell: ss -tnl | grep :80

[root@localhost working]# ansible-playbook –check web.yaml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [install httpd package] ***************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [install configure file] **************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [start httpd service] *****************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [execute ss command] ******************************************************

skipping: [192.168.150.139]

skipping: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=4    changed=0    unreachable=0    failed=0   

192.168.150.139            : ok=4    changed=0    unreachable=0    failed=0   

[root@localhost working]# ansible-playbook web.yaml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [install httpd package] ***************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [install configure file] **************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [start httpd service] *****************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [execute ss command] ******************************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=5    changed=1    unreachable=0    failed=0   

192.168.150.139            : ok=5    changed=1    unreachable=0    failed=0   

web2-yaml进行优化,添加了handler模块

working]# cat web-2.yaml

– hosts: websrvs

  remote_user: root

  tasks:

  – name: install httpd package

    yum: name=httpd state=present

  – name: install configure file

    copy: src=files/httpd.conf dest=/etc/httpd/conf/

    notify: restart httpd     添加了触发,如果配置文档有改变的话,会去触发name为restart httpd的handlers

  – name: start httpd service

    service: name=httpd state=started

  handlers:

  – name: restart httpd

    service: name=httpd state=restarted

working]# ansible-playbook –check web-2.yaml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [install httpd package] ***************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [install configure file] **************************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

TASK [start httpd service] *****************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

RUNNING HANDLER [restart httpd] ************************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=5    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=5    changed=2    unreachable=0    failed=0   

working]# vim files/httpd.conf     此时我编辑下本地的配置文件,将8080修改至808

working]# ansible-playbook –check web-2.yaml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [install httpd package] ***************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [install configure file] **************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [start httpd service] *****************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=4    changed=0    unreachable=0    failed=0   

192.168.150.139            : ok=4    changed=0    unreachable=0    failed=0   

working]# ansible websrvs -m shell -a "ss -tnl | grep :8080"

192.168.150.138 | FAILED | rc=1 >>

192.168.150.139 | FAILED | rc=1 >>

working]# ansible websrvs -m shell -a "ss -tnl | grep :80"

192.168.150.139 | SUCCESS | rc=0 >>

LISTEN     0      128         :::808                     :::*                 

192.168.150.138 | SUCCESS | rc=0 >>

LISTEN     0      128         :::808                     :::*                 

web3-yaml版本更新

添加了tags模块,在使用ansible-playbook时使用-t 选项指定所运行的tag

working]# cat web-3.yaml

– hosts: websrvs

  remote_user: root

  tasks:

  – name: install httpd package

    yum: name=httpd state=present

    tags: insthttpd     添加安装httpd的tag

  – name: install configure file

    copy: src=files/httpd.conf dest=/etc/httpd/conf/

    tags: instconf     添加了修改配置文件的tag

    notify: restart httpd

  – name: start httpd service

    service: name=httpd state=started

    tags: starthttpd     添加了开启httpd的tag

  handlers:

  – name: restart httpd

    service: name=httpd state=restarted

working]# ansible-playbook -t insthttpd –check web-3.yaml     此处只运行了install httpd package的task

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [install httpd package] ***************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=2    changed=0    unreachable=0    failed=0   

192.168.150.139            : ok=2    changed=0    unreachable=0    failed=0   

修改下配置文件,测试下instconf的tag下的task

working]# vim files/httpd.conf     将端口修改为80

working]# ansible-playbook -t instconf web-3.yaml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [install configure file] **************************************************     只是运行了此task

changed: [192.168.150.139]

changed: [192.168.150.138]

RUNNING HANDLER [restart httpd] ************************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0   

=working]# ansible websrvs -m shell -a "ss -tnl | grep :80"

192.168.150.139 | SUCCESS | rc=0 >>

LISTEN     0      128         :::80                      :::*                 

192.168.150.138 | SUCCESS | rc=0 >>

LISTEN     0      128         :::80                      :::*         

playbook之variables

变量:

            ansible facts

            ansible-playbook -e "var=value"

            host variable:host iventory

            group variable

                [groupname:vars]

                var=value

            roles


            调用:{{ variable }}


            在playbook中定义变量的方式:

            vars:

            – var1: value1

            – var2: value2

a、ansible-playbook -e "var=value"

working]# cat forth.yaml

– hosts: websrvs

  remote_user: root

  tasks:

  – name: install {{ pkname }}

    yum: name={{ pkname }} state=present

working]# ansible-playbook -e pkname=memcached forth.yaml 在执行时通过-e进行变量赋值

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [install memcached] *******************************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=2    changed=1    unreachable=0    failed=0   

192.168.150.139            : ok=2    changed=1    unreachable=0    failed=0

b、host variable:host iventory

使用hostname模块进行测试,通过hosts中的变量指定进行hostname更改

nsible]# ansible-doc -s hostname

– name: Manage hostname

  action: hostname

      name=                  # Name of the host

在hosts文件中添加变量指定及赋值

working]# cd /etc/ansible/

ansible]# vim hosts

ansible]# cat hosts

# This is the default ansible 'hosts' file.

#

# It should live in /etc/ansible/hosts

#

#   – Comments begin with the '#' character

#   – Blank lines are ignored

#   – Groups of hosts are delimited by [header] elements

#   – You can enter hostnames or ip addresses

#   – A hostname/ip can be a member of multiple groups

[websrvs]

192.168.150.138 hanme=www1    hname变量指定及赋值

192.168.150.139 hname=www2

[dbsrvs]

192.168.150.138

192.168.150.133

yaml编写

ansible]# vim hostname.yaml

– hosts: websrvs

  remote_user: root

  tasks:

  – name: set hostname

    hostname: name={{ hname }}     此处调用了hname变量 

ansible]# ansible-playbook –check hostname.yaml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [set hostname] ************************************************************

skipping: [192.168.150.138]

skipping: [192.168.150.139]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=1    changed=0    unreachable=0    failed=0   

192.168.150.139            : ok=1    changed=0    unreachable=0    failed=0   

ansible]# ansible-playbook hostname.yaml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [set hostname] ************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=2    changed=0    unreachable=0    failed=0   

192.168.150.139            : ok=2    changed=0    unreachable=0    failed=0   

ansible]# vim hosts

# This is the default ansible 'hosts' file.

#

# It should live in /etc/ansible/hosts

#

#   – Comments begin with the '#' character

#   – Blank lines are ignored

#   – Groups of hosts are delimited by [header] elements

#   – You can enter hostnames or ip addresses

#   – A hostname/ip can be a member of multiple groups

[websrvs]

192.168.150.138 hname=www1

192.168.150.139 hname=www2

[websrvs:vars]     在hosts中给http_port指定变量及赋值,可供调用

http_port=8080

[dbsrvs]

192.168.150.138

192.168.150.133

当使用-e执行ansible-playbook时,会使用-e指定的变量值来取代yml中定义的变量

~]# cd working/

working]# ls

1      forth.yaml  nginx.retry  users.yaml  web-3.yaml  web.yaml

files  iter.yaml   nginx.yaml   web-2.yaml  web.retry

working]# vim myuser.yml

working]# cat myuser.yml

– hosts: all

  remote_user: root

  vars:

  – username: testuser1

  – groupname: testgroup1

  tasks:

  – name: create group

    group: name={{ groupname }} state=present

  – name: create user

    user: name={{ username }} state=present

working]# ansible-playbook –check myuser.yml

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

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

ok: [192.168.150.133]

TASK [create group] ************************************************************

changed: [192.168.150.139]

changed: [192.168.150.133]

changed: [192.168.150.138]

TASK [create user] *************************************************************

changed: [192.168.150.139]

changed: [192.168.150.133]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.133            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0   

working]# ansible-playbook -e "groupname=mygrp1" -e "username=myuser1" myuser.yml     此时会使用-e选项指定的变量值

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

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

ok: [192.168.150.133]

TASK [create group] ************************************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

changed: [192.168.150.133]

TASK [create user] *************************************************************

changed: [192.168.150.139]

changed: [192.168.150.133]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.133            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0   

nginx]# tail /etc/group

user4:x:308:

memcached:x:305:

nginx:x:304:

group11:x:1002:

group12:x:1003:

group13:x:1004:

testgroup1:x:1005:

testuser1:x:1006:

mygrp1:x:1007:

myuser1:x:1008:

playbook之nginx的测试:

nginx安装、配置

模板:templates

            文本文件,嵌套有脚本(使用模板编程语言编写)

                jinja2:

                    字面量:

                        字符串:使用单引号或双引号;

                        数字:整数,浮点数;

                        列表:[item1,item2,…]

                        元组:(item1,item2,…)

                        字典:{key1:value1,key2:value2,…}

                        布尔型:true/false


                    算数运算:

                        +,-,*,/,//,%,**


                    比较操作:

                        ==,!=,>,>=,<,<=


                    逻辑运算符:

                        and,or,not



yum源的统一部署方法:

本地编辑epel的yum源

working]# vim files/epel.repo  

[epel]

name=Fedora EPEL

baseurl=http://mirrors.aliyun.com/epel/$releasever/$basearch     此处使用变量进行指定本机的版本号及架构

enabled=1

gpgcheck=0

将仓库通过ansible的copy模块,拷贝至被管理主机

working]# ansible all -m copy -a "src=files/epel.repo dest=/etc/yum.repos.d"

192.168.150.139 | SUCCESS => {

    "changed": false,

    "checksum": "d23380d4e6429df809ec9990951d68c430fed96f",

    "dest": "/etc/yum.repos.d/epel.repo",

    "gid": 0,

    "group": "root",

    "mode": "0644",

    "owner": "root",

    "path": "/etc/yum.repos.d/epel.repo",

    "size": 106,

    "state": "file",

    "uid": 0

}

192.168.150.138 | SUCCESS => {

    "changed": false,

    "checksum": "d23380d4e6429df809ec9990951d68c430fed96f",

    "dest": "/etc/yum.repos.d/epel.repo",

    "gid": 0,

    "group": "root",

    "mode": "0644",

    "owner": "root",

    "path": "/etc/yum.repos.d/epel.repo",

    "size": 106,

    "state": "file",

    "uid": 0

}

192.168.150.133 | SUCCESS => {

    "changed": true,

    "checksum": "d23380d4e6429df809ec9990951d68c430fed96f",

    "dest": "/etc/yum.repos.d/epel.repo",

    "gid": 0,

    "group": "root",

    "md5sum": "494d30aa39c457eda24955cf4dc58963",

    "mode": "0644",

    "owner": "root",

    "size": 106,

    "src": "/root/.ansible/tmp/ansible-tmp-1478688854.86-29806914220334/source",

    "state": "file",

    "uid": 0

}

nginx的统一安装

working]# ansible all -m yum -a "name=nginx state=present"

192.168.150.138 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

                             \n\nComplete!\n"

    ]

}

192.168.150.133 | SUCCESS => {

    "changed": true,

    "msg": "",

    "rc": 0,

    "results": [

ete!\n"

    ]

}

192.168.150.139 | SUCCESS => {

    "changed": true,

r mirror.\n",

    "rc": 0,

    "results": [

x86_64 1:1.10.2-1.el7                                        \n\nComplete!\n"

    ]

}

nginx配置选项的设置

拷贝配置文件至工作目录

working]# ls /etc/nginx/

conf.d                fastcgi_params          mime.types          scgi_params           win-utf

default.d             fastcgi_params.default  mime.types.default  scgi_params.default

fastcgi.conf          koi-utf                 nginx.conf          uwsgi_params

fastcgi.conf.default  koi-win                 nginx.conf.default  uwsgi_params.default

working]# cp /etc/nginx/nginx.conf files/

working]# mv files/nginx.conf files/nginx.conf.j2     一般模板文件的后缀已j2结尾

working]# vim files/nginx.conf.j2      修改启动进程数进行试验worker_processes {{ ansible_processor_vcpus+1 }}     listen {{ http_port }};调用hosts中定义的http_port

此处的变量引用了ansible facts,通过ansible的setup模块可以查看facts(ansible all -m setup)

同时修改hosts文件,同步调用hosts中的变量

working]# vim /etc/ansible/hosts

# This is the default ansible 'hosts' file.

#

# It should live in /etc/ansible/hosts

#

#   – Comments begin with the '#' character

#   – Blank lines are ignored

#   – Groups of hosts are delimited by [header] elements

#   – You can enter hostnames or ip addresses

#   – A hostname/ip can be a member of multiple groups

[websrvs]

192.168.150.138 http_port=8080

192.168.150.139 http_port=8080

[dbsrvs]

192.168.150.138

192.168.150.133

编辑nginx.yaml

– hosts: websrvs

  remote_user: root

  tasks:

  – name: install nginx

    yum: name=nginx state=present

  – name: install conf file

    template: src=files/nginx.conf.j2 dest=/etc/nginx/nginx.conf     此处的配置文件使用的是template模板组件

    notify: restart nginx

    tags: instconf

  – name: start nginx service

    service: name=nginx state=started

  handlers:

  – name: restart nginx

    service: name=nginx state=restarted


playbook之条件测试when:

条件测试:

            when语句:在task中使用,jinja2的语法格式

                task:

                – name: install conf file to centos7

                  template: src=file/nginx.conf.c7.j2

                  when: ansible_distribution_major_version == "7"

                – name: install conf file to cento6

                  template:src=file/nginx.conf.c6.j2

                  when: ansible_distribution_major_version == "6"


将centos6主机的配置文件拷贝至ansible主机,通过模板话后,进行条件判断部署

working]# scp root@192.168.150.133:/etc/nginx/nginx.conf files/nginx.conf.c6.j2

nginx.conf                                                           100% 1137     1.1KB/s   00:00

working]# vim nginx.yaml

– hosts: all

  remote_user: root

  tasks:

  – name: install nginx

    yum: name=nginx state=present

  – name: install conf file to centos7

    template: src=files/nginx.conf.j2 dest=/etc/nginx/nginx.conf

    when: ansible_distribution_major_version == "7"

    notify: restart nginx

    tags: instconf

  – name: install conf file to centos6

    template: src=files/nginx.conf.c6.j2 dest=/etc/nginx/nginx.conf

    when: ansible_distribution_major_version == "6"     进行when的条件判断,变量使用facts中选项,判定操作系统是centos6还是centos7

    notify: restart nginx

    tags: instconf

  – name: start nginx service

    service: name=nginx state=started

  handlers:

  – name: restart nginx

    service: name=nginx state=restarted

working]# ansible-playbook –check nginx.yaml

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

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

ok: [192.168.150.133]

TASK [install nginx] ***********************************************************

ok: [192.168.150.139]

ok: [192.168.150.133]

ok: [192.168.150.138]

TASK [install conf file to centos7] ********************************************

skipping: [192.168.150.133]

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [install conf file to centos6] ********************************************

skipping: [192.168.150.138]

skipping: [192.168.150.139]

changed: [192.168.150.133]

TASK [start nginx service] *****************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

changed: [192.168.150.133]

RUNNING HANDLER [restart nginx] ************************************************

changed: [192.168.150.133]

PLAY RECAP *********************************************************************

192.168.150.133            : ok=5    changed=3    unreachable=0    failed=0   

192.168.150.138            : ok=4    changed=0    unreachable=0    failed=0   

192.168.150.139            : ok=4    changed=0    unreachable=0    failed=0   

working]# ansible-playbook  nginx.yaml

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

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

ok: [192.168.150.133]

TASK [install nginx] ***********************************************************

ok: [192.168.150.139]

ok: [192.168.150.133]

ok: [192.168.150.138]

TASK [install conf file to centos7] ********************************************

skipping: [192.168.150.133]

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [install conf file to centos6] ********************************************

skipping: [192.168.150.138]

skipping: [192.168.150.139]

ok: [192.168.150.133]

TASK [start nginx service] *****************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

changed: [192.168.150.133]

PLAY RECAP *********************************************************************

192.168.150.133            : ok=4    changed=1    unreachable=0    failed=0   

192.168.150.138            : ok=4    changed=0    unreachable=0    failed=0   

192.168.150.139            : ok=4    changed=0    unreachable=0    failed=0   


playbook之循环:

循环:迭代,需要重复执行的任务;

            对迭代项的引用,固定变量名为"item"

            而后,要在task中使用with_items给定要迭代的元素列表;

                列表方法:

                    字符串

                    字典



            – name: install some packages

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

              with_items:

              – nginx

              – memcached

              – php-fpm


            – name: add some groups

              group: name={{ item }} state=present

              with_items:

              – group11

              – group12

              – group13

            – name: add some users

              user: name={{ item.name }} group={{ item.group }} state=present

              with_items:

              – { name: 'user11',group: 'group11'}

              – { name: 'user12',group: 'group12'}

              – { name: 'user13',group: 'group13'}

通过循环迭代的方式进行多个安装包的安装

working]# vim iter.yaml

– hosts: all

  remote_user: root

  tasks:

  – name: install some packages

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

    with_items:

    – nginx

    – memcached

    – php-fpm

working]# ansible-playbook –check iter.yaml

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

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

ok: [192.168.150.133]

TASK [install some packages] ***************************************************

changed: [192.168.150.138] => (item=[u'nginx', u'memcached', u'php-fpm'])

changed: [192.168.150.139] => (item=[u'nginx', u'memcached', u'php-fpm'])

changed: [192.168.150.133] => (item=[u'nginx', u'memcached', u'php-fpm'])

PLAY RECAP *********************************************************************

192.168.150.133            : ok=2    changed=1    unreachable=0    failed=0

192.168.150.138            : ok=2    changed=1    unreachable=0    failed=0

192.168.150.139            : ok=2    changed=1    unreachable=0    failed=0

working]# ansible-playbook iter.yaml

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

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

ok: [192.168.150.133]

TASK [install some packages] ***************************************************

changed: [192.168.150.139] => (item=[u'nginx', u'memcached', u'php-fpm'])

changed: [192.168.150.133] => (item=[u'nginx', u'memcached', u'php-fpm'])

changed: [192.168.150.138] => (item=[u'nginx', u'memcached', u'php-fpm'])

PLAY RECAP *********************************************************************

192.168.150.133            : ok=2    changed=1    unreachable=0    failed=0

192.168.150.138            : ok=2    changed=1    unreachable=0    failed=0

192.168.150.139            : ok=2    changed=1    unreachable=0    failed=0

通过迭代方式进行用户和组的添加

working]# cat users.yaml

– hosts: all

  remote_user: root

  tasks:

    – name: add some groups     此处是循环

      group: name={{ item }} state=present

      with_items:

      – group11

      – group12

      – group13

    – name: add some users     此处使用的是迭代

      user: name={{ item.name }} group={{ item.group }} state=present

      with_items:

      – { name: 'user11',group: 'group11' }

      – { name: 'user12',group: 'group12' }

      – { name: 'user13',group: 'group13' }

working]# ansible-playbook –check users.yaml

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

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

ok: [192.168.150.133]

TASK [add some groups] *********************************************************

changed: [192.168.150.133] => (item=group11)

changed: [192.168.150.139] => (item=group11)

changed: [192.168.150.138] => (item=group11)

changed: [192.168.150.133] => (item=group12)

changed: [192.168.150.138] => (item=group12)

changed: [192.168.150.139] => (item=group12)

changed: [192.168.150.133] => (item=group13)

changed: [192.168.150.139] => (item=group13)

changed: [192.168.150.138] => (item=group13)

TASK [add some users] **********************************************************

changed: [192.168.150.139] => (item={u'group': u'group11', u'name': u'user11'})

changed: [192.168.150.138] => (item={u'group': u'group11', u'name': u'user11'})

changed: [192.168.150.133] => (item={u'group': u'group11', u'name': u'user11'})

changed: [192.168.150.139] => (item={u'group': u'group12', u'name': u'user12'})

changed: [192.168.150.133] => (item={u'group': u'group12', u'name': u'user12'})

changed: [192.168.150.138] => (item={u'group': u'group12', u'name': u'user12'})

changed: [192.168.150.133] => (item={u'group': u'group13', u'name': u'user13'})

changed: [192.168.150.139] => (item={u'group': u'group13', u'name': u'user13'})

changed: [192.168.150.138] => (item={u'group': u'group13', u'name': u'user13'})

PLAY RECAP *********************************************************************

192.168.150.133            : ok=3    changed=2    unreachable=0    failed=0

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0

working]# ansible-playbook  users.yaml

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

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

ok: [192.168.150.133]

TASK [add some groups] *********************************************************

changed: [192.168.150.139] => (item=group11)

changed: [192.168.150.138] => (item=group11)

changed: [192.168.150.133] => (item=group11)

changed: [192.168.150.139] => (item=group12)

changed: [192.168.150.138] => (item=group12)

changed: [192.168.150.133] => (item=group12)

changed: [192.168.150.139] => (item=group13)

changed: [192.168.150.138] => (item=group13)

changed: [192.168.150.133] => (item=group13)

TASK [add some users] **********************************************************

changed: [192.168.150.139] => (item={u'group': u'group11', u'name': u'user11'})

changed: [192.168.150.138] => (item={u'group': u'group11', u'name': u'user11'})

changed: [192.168.150.133] => (item={u'group': u'group11', u'name': u'user11'})

changed: [192.168.150.139] => (item={u'group': u'group12', u'name': u'user12'})

changed: [192.168.150.138] => (item={u'group': u'group12', u'name': u'user12'})

changed: [192.168.150.133] => (item={u'group': u'group12', u'name': u'user12'})

changed: [192.168.150.139] => (item={u'group': u'group13', u'name': u'user13'})

changed: [192.168.150.138] => (item={u'group': u'group13', u'name': u'user13'})

changed: [192.168.150.133] => (item={u'group': u'group13', u'name': u'user13'})

PLAY RECAP *********************************************************************

192.168.150.133            : ok=3    changed=2    unreachable=0    failed=0

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0

角色(roles)

角色集合:

    roles/

        mysql/

        httpd/

        nginx/

        memcached/


每个角色,以特定的层级目录结构进行组织;

    mysql/

        files/ :存放由copy或script模块等调用的文件;

        templates/:template模块查找所需要模板文件的目录;

        tasks/:至少应该包含一个名为main.yml的文件;其他的文件需要在此文件中通过include进行包含;

        handlers/:至少应该包含一个名为main.yml的文件;其他的文件需要在此文件中通过include进行包含;

        vars/:至少应该包含一个名为main.yml的文件;其他的文件需要在此文件中通过include进行包含;

        meta/:至少应该包含一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;其他的文件需要在此文件中通过include进行包含;

        default/:设定默认变量时使用此目录中的main.yml文件;


在playbook调用角色方法1:

    – hosts: websrvs

      remote_user: root

      roles:

      – mysql

      – memcached

      – nginx


在playbook调用角色方法2:传递变量给角色

    – hosts:

      remote_user:

      roles:

      – { role: nginx,username: nginx}


创建一个角色并创建特定的层级目录结构

~]# ls /etc/ansible/

1  ansible.cfg  hostname.retry  hostname.yaml  hosts  hosts.bak  roles

~]# mkdir /etc/ansible/roles/nginx/{files,tasks,templates,handlers,vars,default,meta} -pv

mkdir: 已创建目录 "/etc/ansible/roles/nginx"

mkdir: 已创建目录 "/etc/ansible/roles/nginx/files"

mkdir: 已创建目录 "/etc/ansible/roles/nginx/tasks"

mkdir: 已创建目录 "/etc/ansible/roles/nginx/templates"

mkdir: 已创建目录 "/etc/ansible/roles/nginx/handlers"

mkdir: 已创建目录 "/etc/ansible/roles/nginx/vars"

mkdir: 已创建目录 "/etc/ansible/roles/nginx/default"

mkdir: 已创建目录 "/etc/ansible/roles/nginx/meta"

~]# tree /etc/ansible/roles/nginx/

/etc/ansible/roles/nginx/

├── default

├── files

├── handlers

├── meta

├── tasks

├── templates

└── vars

7 directories, 0 files

创建task

 ~]# cd /etc/ansible/roles/nginx/

nginx]# vim tasks/main.yml

– name: install nginx package

  yum: name=nginx state=present

– name: install conf file

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

– name: start nginx

  service: name=nginx state=started enabled=true

创建template

nginx]# cp /root/working/files/nginx.conf.j2 templates/

创建工作目录,通过playbook调用roles

nginx]# cd

 ~]# mkdir ansible

 ~]# cd ansible/

ansible]# vim nginx.yml

– hosts: websrvs

  remote_user: root

  roles:     此处为playbook调用roles

  – nginx

check和执行

ansible]# ansible-playbook –check nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [nginx : install nginx package] *******************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

TASK [nginx : start nginx] *****************************************************

ested service \"'nginx'\": "}

ested service \"'nginx'\": "}

    to retry, use: –limit @/root/ansible/nginx.retry

PLAY RECAP *********************************************************************

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=1   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=1   

ansible]# ansible-playbook  nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [nginx : install nginx package] *******************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

TASK [nginx : start nginx] *****************************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=4    changed=3    unreachable=0    failed=0   

192.168.150.139            : ok=4    changed=3    unreachable=0    failed=0   

编辑task,添加handler

nginx]# vim tasks/main.yml

– name: install nginx package

  yum: name=nginx state=present

– name: install conf file

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

  notify: restart nginx

– name: start nginx

  service: name=nginx state=started enabled=true

nginx]# vim handlers/main.yml

– name: restart nginx

  service: name=nginx state=restarted

ansible]# ansible-playbook –check nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [nginx : install nginx package] *******************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

TASK [nginx : start nginx] *****************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

RUNNING HANDLER [nginx : restart nginx] ****************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=5    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=5    changed=2    unreachable=0    failed=0   

加tag

ansible]# vim /etc/ansible/roles/nginx/tasks/main.yml

– name: install nginx package

  yum: name=nginx state=present

– name: install conf file

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

  notify: restart nginx

  tags: instconf

– name: start nginx

  service: name=nginx state=started enabled=true

ansible]# ansible-playbook -t instconf –check nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

RUNNING HANDLER [nginx : restart nginx] ****************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0   

ansible]# ansible-playbook -t instconf  nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

RUNNING HANDLER [nginx : restart nginx] ****************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0   

变量使用

变量声明

ansible]# vim /etc/ansible/roles/nginx/vars/main.yml

username: daemon

template中调用此变量

working]# vim /etc/ansible/roles/nginx/templates/nginx.conf.j2     修改nginx使用哪个用户开启服务 指定变量user {{ username }};

check并执行

ansible]# ansible-playbook –check nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

TASK [nginx : install nginx package] *******************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

TASK [nginx : start nginx] *****************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

RUNNING HANDLER [nginx : restart nginx] ****************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=5    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=5    changed=2    unreachable=0    failed=0   

ansible]# ansible-playbook  nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [nginx : install nginx package] *******************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

TASK [nginx : start nginx] *****************************************************

ok: [192.168.150.138]

ok: [192.168.150.139]

RUNNING HANDLER [nginx : restart nginx] ****************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=5    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=5    changed=2    unreachable=0    failed=0   

被管理端状态

nginx]# ps aux

USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

……

daemon     8134  0.0  0.3 122652  3072 ?        S    17:50   0:00 nginx: worker process

daemon     8135  0.0  0.3 122652  3280 ?        S    17:50   0:00 nginx: worker process

daemon     8136  0.0  0.3 122652  3280 ?        S    17:50   0:00 nginx: worker process

root       8139  0.0  0.1 139492  1648 pts/0    R+   17:50   0:00 ps aux

此时在执行时通过-e选项来进行变量指定,会直接调用此选项

ansible]# ansible-playbook -t instconf -e "username=adm" –check  nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

RUNNING HANDLER [nginx : restart nginx] ****************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0   

ansible]# ansible-playbook -t instconf -e "username=adm"  nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

RUNNING HANDLER [nginx : restart nginx] ****************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0   

后端状态

nginx]# ps aux

USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

……

adm        8604  0.0  0.3 122652  3276 ?        S    17:52   0:00 nginx: worker process

adm        8605  0.0  0.3 122652  3276 ?        S    17:52   0:00 nginx: worker process

adm        8606  0.0  0.3 122652  3072 ?        S    17:52   0:00 nginx: worker process

在roles通过k/v方式进行传递变量给角色

ansible]# vim nginx.yml

– hosts: websrvs

  remote_user: root

  roles:

  – { role: nginx, username: nginx }

ansible]# ansible-playbook -t instconf –check  nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.138]

changed: [192.168.150.139]

RUNNING HANDLER [nginx : restart nginx] ****************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0   

ansible]# ansible-playbook -t instconf   nginx.yml

PLAY [websrvs] *****************************************************************

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.138]

TASK [nginx : install conf file] ***********************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

RUNNING HANDLER [nginx : restart nginx] ****************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.138            : ok=3    changed=2    unreachable=0    failed=0   

192.168.150.139            : ok=3    changed=2    unreachable=0    failed=0

后端状态 

nginx]# ps aux

USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

……

nginx      8894  0.0  0.3 122652  3276 ?        S    17:59   0:00 nginx: worker process

nginx      8895  0.0  0.3 122652  3276 ?        S    17:59   0:00 nginx: worker process

nginx      8896  0.0  0.3 122652  3276 ?        S    17:59   0:00 nginx: worker process

还可以基于条件测试实现角色调用

ansible]# vim nginx.yml

– hosts: all

  remote_user: root

  roles:

  – { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }     当版本为centos7时调用此角色

ansible]# cat lnm.yml

– hosts: all

  remote_user: root

  roles:

  – { role: nginx, when: ansible_distribution_major_version == '7' }     版本为7时调用nginx角色,当主机名称为memcached时调用memcached角色

  – { role: memcached,when: ansible_hostname == 'memcached' }

创建memcached的角色

ansible]# mkdir -pv /etc/ansible/roles/memcached/tasks

mkdir: 已创建目录 "/etc/ansible/roles/memcached"

mkdir: 已创建目录 "/etc/ansible/roles/memcached/tasks"

ansible]# vim /etc/ansible/roles/memcached/tasks/main.yml

ansible]# cat /etc/ansible/roles/memcached/tasks/main.yml

– name: install package

  yum: name=memcached state=present

– name: start memcached

  service: name=memcached state=started enabled=true

ansible]# ansible-playbook   lnm.yml

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

TASK [setup] *******************************************************************

ok: [192.168.150.139]

ok: [192.168.150.133]

ok: [192.168.150.138]

TASK [nginx : install nginx package] *******************************************

skipping: [192.168.150.133]

changed: [192.168.150.138]

changed: [192.168.150.139]

TASK [nginx : install conf file] ***********************************************

skipping: [192.168.150.133]

changed: [192.168.150.139]

changed: [192.168.150.138]

TASK [nginx : start nginx] *****************************************************

skipping: [192.168.150.133]

changed: [192.168.150.138]

changed: [192.168.150.139]

TASK [memcached : install package] *********************************************

skipping: [192.168.150.133]

skipping: [192.168.150.139]

ok: [192.168.150.138]

TASK [memcached : start memcached] *********************************************

skipping: [192.168.150.133]

skipping: [192.168.150.139]

changed: [192.168.150.138]

RUNNING HANDLER [nginx : restart nginx] ****************************************

changed: [192.168.150.139]

changed: [192.168.150.138]

PLAY RECAP *********************************************************************

192.168.150.133            : ok=1    changed=0    unreachable=0    failed=0   

192.168.150.138            : ok=7    changed=5    unreachable=0    failed=0   

192.168.150.139            : ok=5    changed=4    unreachable=0    failed=0   

原创文章,作者:N23-苏州-void,如若转载,请注明出处:http://www.178linux.com/63811

(0)
上一篇 2016-12-14 20:18
下一篇 2016-12-15 19:04

相关推荐

  • Puppet基于Master/Agent模式实现LNMP平台部署

    前言 随着IT行业的迅猛发展,传统的运维方式靠大量人力比较吃力,运维人员面对日益增长的服务器和运维工作,不得不把很多重复的、繁琐的工作利用自动化处理。前期我们介绍了运维自动化工具ansible的简单应用,本期带来的是运维自动化神器puppet基于Master/Agent模式实现LNMP平台部署。 Puppet 简介 Puppet是基于ruby语言开发的一种L…

    Linux干货 2015-07-13
  • OpenSSL

    三个组件: openssl: 多用途的命令行工具; libcrypto: 加密解密库; libssl:ssl协议的实现; PKI:Public Key Infrastructure CA RA CRL 证书存取库  建立私有CA: OpenCA openssl  证书申请及签署步骤: 1、生成申请请求; 2、RA核验; 3、CA签署; 4…

    Linux干货 2015-03-21
  • 马哥教育网络班21期+第6周课程练习

    请详细总结vim编辑器的使用并完成以下练习题1、复制/etc/rc.d/rc.sysinit文件至/tmp目录,将/tmp/rc.sysinit文件中的以至少一个空白字符开头的行的行首加#; %s/^([[:space:]]{1,}.*)/#\1/s 2、复制/boot/grub/grub.conf至/tmp目录中,删除/tmp/grub.conf文件中的行…

    Linux干货 2016-08-15
  • Linux高级磁盘管理-RAID管理

    在冯诺依曼体系机构中,输入输出要存储的外部磁盘I/O能力实在太低,尤其是企业面对高并发的访问量,在系统内部需要大量调度磁盘的上的网页文件资源,这些都会产生大量的I/O,一个磁盘的I/O能力不管如何提升毕竟是有线的,尤其是机械硬盘;同时为了保障业务的连续性,磁盘故障时必须提供冗余能力,面对这样的实际需求环境,RAID技术产生了,通过组织磁盘阵列方式提供I/O,…

    Linux干货 2016-09-06
  • bash的特性和目录管理命令

    bash的特性和目录管理命令 bash特性     1. 命令补全机制: 所谓的命令补全,就是当输入命令的前几个字符的时候,按下tab,此时,bash根据输入的字符串,到path路径下进行寻找,把找到的且能唯一根据这个字符串标识的命令,予以补全。 如果根据这个字符串能在一个目录下面找到多个相同的命令,则再按一下tab就能列出所有…

    Linux干货 2016-10-29
  • 2

    2

    Linux干货 2018-03-26

评论列表(1条)

  • 马哥教育
    马哥教育 2017-03-13 23:41

    赞,很详细的描述了ansible的用法~继续加油~