ansible简单使用

安装

ansible的安装算简单的了,不要配置数据库,不用在远程操作的节点安装任何东西。只需要本机安装ansible即可。

但是还是依赖一些基本python库。

ansible
|– jinja2
|– PyYAML
|– paramiko
|– pycrypto>=2.6
|– setuptools
|– MarkupSafe
|– cryptography>=1.1
|– pyasn1>=0.1.7
|– idna>=2.1
|– asn1crypto>=0.21.0
|– packaging
|– six>=1.4.1
|– enum34
|– ipaddress
|– cffi>=1.4.1
|– pyparsing
|– pycparser

hello world

# echo "127.0.0.1" > ~/ansible_hosts
# export ANSIBLE_HOSTS=~/ansible_hosts
# ansible all -m ping --ask-pass
[root@promote ~]# cat ~/ansible_hosts
127.0.0.1
[root@promote ~]# export ANSIBLE_HOSTS=~/ansible_hosts
[root@promote ~]# ansible all -m ping --ask-pass
SSH password: 
127.0.0.1 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

安装最新版

# git clone git://github.com/ansible/ansible.git
# cd ./ansible
# make rpm
# sudo rpm -Uvh ~/rpmbuild/ansible-*.noarch.rpm

模块

ping模块

[root@localhost ~]# ansible 127.0.0.1 -m ping
127.0.0.1 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

wait_for模块

检查端口是否占用

[root@promote ~]# ansible 127.0.0.1 -m wait_for -a "port=22 delay=0 timeout=2"
127.0.0.1 | SUCCESS => {
    "changed": false, 
    "elapsed": 0, 
    "path": null, 
    "port": 22, 
    "search_regex": null, 
    "state": "started"
}
[root@promote ~]# ansible 127.0.0.1 -m wait_for -a "port=81 delay=0 timeout=2"
127.0.0.1 | FAILED! => {
    "changed": false, 
    "elapsed": 2, 
    "failed": true, 
    "msg": "Timeout when waiting for 127.0.0.1:81"
}

检查文件是否存在,如配置文件,lock文件

[root@promote ~]# ansible 127.0.0.1 -m wait_for -a "path=~/a delay=0 timeout=2"
127.0.0.1 | SUCCESS => {
    "changed": false, 
    "elapsed": 0, 
    "gid": 1001, 
    "group": "1001", 
    "mode": "0600", 
    "owner": "1001", 
    "path": "/root/a", 
    "port": null, 
    "search_regex": null, 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 75, 
    "state": "file", 
    "uid": 1001
}
[root@promote ~]# ansible 127.0.0.1 -m wait_for -a "path=~/a1934 delay=0 timeout=2"
127.0.0.1 | FAILED! => {
    "changed": false, 
    "elapsed": 2, 
    "failed": true, 
    "msg": "Timeout when waiting for file /root/a1934"
}

raw模块

[root@localhost ~]# ansible 127.0.0.1 -m raw -a 'hostname|tee fgh'
127.0.0.1 | SUCCESS | rc=0 >>
localhost.localdomain
Shared connection to 127.0.0.1 closed.


[root@localhost ~]# cat fgh
localhost.localdomain

get_url模块

目的:将http://10.1.1.116/favicon.ico文件下载到指定节点10.1.1.113的/tmp目录下
命令:ansible 10.1.1.113 -m get_url -a ‘url=http://10.1.1.116/favicon.ico dest=/tmp’

synchronize模块

目的:将主控方/root/a目录推送到指定节点的/tmp目录下
命令:ansible 10.1.1.113 -m synchronize -a ‘src=/root/a dest=/tmp/ compress=yes’

delete=yes   使两边的内容一样(即以推送方为主)
compress=yes  开启压缩,默认为开启
--exclude=.git  忽略同步.git结尾的文件

由于模块,默认都是推送push。因此,如果你在使用拉取pull功能的时候,可以参考如下来实现
mode=pull 更改推送模式为拉取模式
目的:将10.1.1.113节点的/tmp/a目录拉取到主控节点的/root目录下
命令:ansible 10.1.1.113 -m synchronize -a ‘mode=pull src=/tmp/a dest=/root/‘
执行效果:
由于模块默认启用了archive参数,该参数默认开启了recursive, links, perms, times, owner,group和-D参数。如果你将该参数设置为no,那么你将停止很多参数,比如会导致如下目的递归失败,导致无法拉取

其它相关的参数解释:

dest_port=22    # 指定目的主机的ssh端口,ansible配置文件中的 ansible_ssh_port 变量优先级高于该 dest_port 变量
rsync_path      # 指定 rsync 命令来在远程服务器上运行。这个参考rsync命令的--rsync-path参数,--rsync-path=PATH     # 指定远程服务器上的rsync命令所在路径信息
rsync_timeout   # 指定 rsync 操作的 IP 超时时间,和rsync命令的 --timeout 参数效果一样

service模块

[root@promote ~]# ansible 127.0.0.1 -m service -a "name=firewalld state=stop" --ask-pass
SSH password: 
127.0.0.1 | FAILED! => {
    "changed": false, 
    "failed": true, 
    "msg": "value of state must be one of: started,stopped,restarted,reloaded, got: stop"
}
[root@promote ~]# ansible 127.0.0.1 -m service -a "name=firewalld state=stopped" --ask-pass
SSH password: 
127.0.0.1 | SUCCESS => {
    "changed": true, 
    "name": "firewalld", 
    "state": "stopped", 
    "status": {
        "ActiveEnterTimestamp": "Tue 2017-05-02 18:24:48 CST", 
        "ActiveEnterTimestampMonotonic": "271551053930", 
        "ActiveExitTimestamp": "Tue 2017-05-02 18:24:45 CST", 
        "ActiveExitTimestampMonotonic": "271547664754", 
        "ActiveState": "active", 
        "After": "system.slice polkit.service dbus.service basic.target", 
        "AllowIsolate": "no", 
        "AssertResult": "yes", 
        "AssertTimestamp": "Tue 2017-05-02 18:24:46 CST", 
        "AssertTimestampMonotonic": "271549335937", 
        "Before": "libvirtd.service shutdown.target network.target NetworkManager.service", 
        "BlockIOAccounting": "no", 
        "BlockIOWeight": "18446744073709551615", 
        "BusName": "org.fedoraproject.FirewallD1", 
        "CPUAccounting": "no", 
        "CPUQuotaPerSecUSec": "infinity", 
        "CPUSchedulingPolicy": "0", 
        "CPUSchedulingPriority": "0", 
        "CPUSchedulingResetOnFork": "no", 
        "CPUShares": "18446744073709551615", 
        "CanIsolate": "no", 
        "CanReload": "yes", 
        "CanStart": "yes", 
        "CanStop": "yes", 
        "CapabilityBoundingSet": "18446744073709551615", 
        "ConditionResult": "yes", 
        "ConditionTimestamp": "Tue 2017-05-02 18:24:46 CST", 
        "ConditionTimestampMonotonic": "271549335937", 
        "Conflicts": "ip6tables.service shutdown.target ipset.service ebtables.service iptables.service", 
        "ControlGroup": "/system.slice/firewalld.service", 
        "ControlPID": "0", 
        "DefaultDependencies": "yes", 
        "Delegate": "no", 
        "Description": "firewalld - dynamic firewall daemon", 
        "DevicePolicy": "auto", 
        "Documentation": "man:firewalld(1)", 
        "EnvironmentFile": "/etc/sysconfig/firewalld (ignore_errors=yes)", 
        "ExecMainCode": "0", 
        "ExecMainExitTimestampMonotonic": "0", 
        "ExecMainPID": "28770", 
        "ExecMainStartTimestamp": "Tue 2017-05-02 18:24:46 CST", 
        "ExecMainStartTimestampMonotonic": "271549353698", 
        "ExecMainStatus": "0", 
        "ExecReload": "{ path=/bin/kill ; argv[]=/bin/kill -HUP $MAINPID ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "ExecStart": "{ path=/usr/sbin/firewalld ; argv[]=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "FailureAction": "none", 
        "FileDescriptorStoreMax": "0", 
        "FragmentPath": "/usr/lib/systemd/system/firewalld.service", 
        "GuessMainPID": "yes", 
        "IOScheduling": "0", 
        "Id": "firewalld.service", 
        "IgnoreOnIsolate": "no", 
        "IgnoreOnSnapshot": "no", 
        "IgnoreSIGPIPE": "yes", 
        "InactiveEnterTimestamp": "Tue 2017-05-02 18:24:46 CST", 
        "InactiveEnterTimestampMonotonic": "271549332916", 
        "InactiveExitTimestamp": "Tue 2017-05-02 18:24:46 CST", 
        "InactiveExitTimestampMonotonic": "271549353774", 
        "JobTimeoutAction": "none", 
        "JobTimeoutUSec": "0", 
        "KillMode": "control-group", 
        "KillSignal": "15", 
        "LimitAS": "18446744073709551615", 
        "LimitCORE": "18446744073709551615", 
        "LimitCPU": "18446744073709551615", 
        "LimitDATA": "18446744073709551615", 
        "LimitFSIZE": "18446744073709551615", 
        "LimitLOCKS": "18446744073709551615", 
        "LimitMEMLOCK": "65536", 
        "LimitMSGQUEUE": "819200", 
        "LimitNICE": "0", 
        "LimitNOFILE": "4096", 
        "LimitNPROC": "7027", 
        "LimitRSS": "18446744073709551615", 
        "LimitRTPRIO": "0", 
        "LimitRTTIME": "18446744073709551615", 
        "LimitSIGPENDING": "7027", 
        "LimitSTACK": "18446744073709551615", 
        "LoadState": "loaded", 
        "MainPID": "28770", 
        "MemoryAccounting": "no", 
        "MemoryCurrent": "18446744073709551615", 
        "MemoryLimit": "18446744073709551615", 
        "MountFlags": "0", 
        "Names": "firewalld.service", 
        "NeedDaemonReload": "no", 
        "Nice": "0", 
        "NoNewPrivileges": "no", 
        "NonBlocking": "no", 
        "NotifyAccess": "none", 
        "OOMScoreAdjust": "0", 
        "OnFailureJobMode": "replace", 
        "PermissionsStartOnly": "no", 
        "PrivateDevices": "no", 
        "PrivateNetwork": "no", 
        "PrivateTmp": "no", 
        "ProtectHome": "no", 
        "ProtectSystem": "no", 
        "RefuseManualStart": "no", 
        "RefuseManualStop": "no", 
        "RemainAfterExit": "no", 
        "Requires": "basic.target", 
        "Restart": "no", 
        "RestartUSec": "100ms", 
        "Result": "success", 
        "RootDirectoryStartOnly": "no", 
        "RuntimeDirectoryMode": "0755", 
        "SameProcessGroup": "no", 
        "SecureBits": "0", 
        "SendSIGHUP": "no", 
        "SendSIGKILL": "yes", 
        "Slice": "system.slice", 
        "StandardError": "null", 
        "StandardInput": "null", 
        "StandardOutput": "null", 
        "StartLimitAction": "none", 
        "StartLimitBurst": "5", 
        "StartLimitInterval": "10000000", 
        "StartupBlockIOWeight": "18446744073709551615", 
        "StartupCPUShares": "18446744073709551615", 
        "StatusErrno": "0", 
        "StopWhenUnneeded": "no", 
        "SubState": "running", 
        "SyslogLevelPrefix": "yes", 
        "SyslogPriority": "30", 
        "SystemCallErrorNumber": "0", 
        "TTYReset": "no", 
        "TTYVHangup": "no", 
        "TTYVTDisallocate": "no", 
        "TimeoutStartUSec": "1min 30s", 
        "TimeoutStopUSec": "1min 30s", 
        "TimerSlackNSec": "50000", 
        "Transient": "no", 
        "Type": "dbus", 
        "UMask": "0022", 
        "UnitFilePreset": "enabled", 
        "UnitFileState": "enabled", 
        "WantedBy": "basic.target", 
        "Wants": "system.slice", 
        "WatchdogTimestamp": "Tue 2017-05-02 18:24:48 CST", 
        "WatchdogTimestampMonotonic": "271551053862", 
        "WatchdogUSec": "0"
    }
}

shell模块

[root@promote ~]# ansible targets -m shell -a 'df -h'
127.0.0.1 | SUCCESS | rc=0 >>
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   50G  6.1G   44G  13% /
devtmpfs                 879M     0  879M   0% /dev
tmpfs                    889M  144K  889M   1% /dev/shm
tmpfs                    889M   20M  869M   3% /run
tmpfs                    889M     0  889M   0% /sys/fs/cgroup
/dev/mapper/centos-home   46G  569M   45G   2% /home
/dev/sda1                497M  155M  343M  32% /boot
tmpfs                    178M     0  178M   0% /run/user/0

120.16.220.26 | SUCCESS | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       40G  5.9G   32G  16% /
devtmpfs        489M     0  489M   0% /dev
tmpfs           497M     0  497M   0% /dev/shm
tmpfs           497M   50M  447M  11% /run
tmpfs           497M     0  497M   0% /sys/fs/cgroup

copy模块

[root@promote ~]# ansible 120.16.220.26 -m copy  -a "src=/root/a dest=/root/a"
120.26.200.226 | SUCCESS => {
    "changed": true, 
    "checksum": "43e57bee936f6e0f6e8d7b32bdbc0270a02734de", 
    "dest": "/root/a", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "d931cf1b23ae3441357fdf7a937b8acb", 
    "mode": "0644", 
    "owner": "root", 
    "size": 15306, 
    "src": "/root/.ansible/tmp/ansible-tmp-1493741518.08-148843208427673/source", 
    "state": "file", 
    "uid": 0
}

file模块

[root@promote ~]# ll a
-rw-r--r--. 1 root root 15306 May  2 23:08 a
[root@promote ~]# ansible 127.0.0.1 -m file -a "dest=/root/a mode=600"
127.0.0.1 | SUCCESS => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0600", 
    "owner": "root", 
    "path": "/root/a", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 15306, 
    "state": "file", 
    "uid": 0
}
[root@promote ~]# ls a
a
[root@promote ~]# ll a
-rw-------. 1 root root 15306 May  2 23:08 a

[root@promote ~]# ll a
-rw-------. 1 root root 15306 May  2 23:08 a
[root@promote ~]# ansible 127.0.0.1 -m file -a "dest=/root/a mode=600 owner=docker group=docker"
127.0.0.1 | SUCCESS => {
    "changed": true, 
    "gid": 1001, 
    "group": "docker", 
    "mode": "0600", 
    "owner": "docker", 
    "path": "/root/a", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": 15306, 
    "state": "file", 
    "uid": 1001
}
[root@promote ~]# ll a
-rw-------. 1 docker docker 15306 May  2 23:08 a

使用 file 模块也可以创建目录,与执行 mkdir -p 效果类似:

$ ansible webservers -m file -a "dest=/path/to/c mode=755 owner=mdehaan group=mdehaan state=directory"

删除目录(递归的删除)和删除文件:

$ ansible webservers -m file -a "dest=/path/to/c state=absent"

yum模块

[root@localhost ~]# ansible 127.0.0.1 -m yum -a "name=vim state=present"
127.0.0.1 | SUCCESS => {
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * epel: mirrors.tuna.tsinghua.edu.cn\nResolving Dependencies\n--> Running transaction check\n---> Package vim-enhanced.x86_64 2:7.4.160-1.el7_3.1 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package            Arch         Version                    Repository     Size\n================================================================================\nInstalling:\n vim-enhanced       x86_64       2:7.4.160-1.el7_3.1        updates       1.0 M\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 1.0 M\nInstalled size: 2.2 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : 2:vim-enhanced-7.4.160-1.el7_3.1.x86_64                      1/1 \n  Verifying  : 2:vim-enhanced-7.4.160-1.el7_3.1.x86_64                      1/1 \n\nInstalled:\n  vim-enhanced.x86_64 2:7.4.160-1.el7_3.1                                       \n\nComplete!\n"
    ]
}
[root@localhost ~]# ansible 127.0.0.1 -m yum -a "name=vim state=present"
127.0.0.1 | SUCCESS => {
    "changed": false, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "vim-enhanced-2:7.4.160-1.el7_3.1.x86_64 providing vim is already installed"
    ]
}

user模块

[root@localhost ~]# ansible 127.0.0.1 -m user  -a "name=docker state=absent"
127.0.0.1 | SUCCESS => {
    "changed": false, 
    "name": "docker", 
    "state": "absent"
}
[root@localhost ~]# useradd docker
useradd: warning: the home directory already exists.
Not copying any file from skel directory into it.
Creating mailbox file: File exists
[root@localhost ~]# ansible 127.0.0.1 -m user  -a "name=docker state=absent"
127.0.0.1 | SUCCESS => {
    "changed": true, 
    "force": false, 
    "name": "docker", 
    "remove": false, 
    "state": "absent"
}

group模块

目的:在所有节点上创建一个组名为nolinux,gid为2014的组
命令:ansible all -m group -a ‘gid=2014 name=nolinux’

script模块

[root@localhost ~]# cat a.sh
echo hello from a.sh
[root@localhost ~]# ansible 127.0.0.1 -m script -a '/root/a.sh'
127.0.0.1 | SUCCESS => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 127.0.0.1 closed.\r\n", 
    "stdout": "hello from a.sh\r\n", 
    "stdout_lines": [
        "hello from a.sh"
    ]
}

cron模块

[root@localhost ~]# ansible 127.0.0.1 -m cron -a 'name="custom job" minute=*/3 hour=* day=* month=* weekday=* job="/usr/sbin/ntpdate 172.16.254.139"'
127.0.0.1 | SUCCESS => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "custom job"
    ]
}

# crontab -e
#Ansible: custom job
*/3 * * * * /usr/sbin/ntpdate 172.16.254.139

后台执行

# ansible all -B 3600 -P 0 -a "/usr/bin/long_running_operation --do-stuff"
# ansible all -B 1800 -P 60 -a "/usr/bin/long_running_operation --do-stuff"
其中 -B 1800 表示最多运行30分钟, -P 60 表示每隔60秒获取一次状态信息.

转载请注明来源,欢迎指出任何有错误或不够清晰的表达。可以邮件至 backendcloud@gmail.com