公司计划在年底做一次大型市场促销活动,全面冲刺下交易额,为明年的上市做准备。公司要求各业务组对年底大促做准备要求所有业务容量进行三倍的扩容,并搭建出多套环境可以共开发和测试人员做测试,运维老大为了在年底有所表现,要求运门同学尽快实现,当你接到这个任务时,有没有更快的解决方案?
Host Inventory(主机清单) ansible怎么知道那些主机是被控制的。
通过ssh协议
getenforce :查看是否开启selinux
asible是基于linux开发的 不支持在windows里面安装ansbile
ansible已经被红帽收购
官方地址
yum -y install ansible
yum -y install python-jinja2 PyYAML python-paramiko python-babel python-cryto
tar xf ansible-1.2.4.tar.gz
cd ansible-1.5.4
python setup.py build
python setup.py install
mkdir -p /etc/ansible
cp -r examples/* /etc/ansible
git clone git://github.com/ansible/ansible.git --recursive
cd ./ansible
source ./hacking/env-setup
yum install python-pip python-devel
yum install gcc glibc-devel zibl-devel rpm-build openssl-devel
pip install --upgrade pip
piup install ansible --upgrade
ansbile --version
yum -y install ansible
yum info ansible #查看ansible的信息
# ansible --version #验证是否安装成功
ansible 2.9.10
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible #对应的模板路径
executable location = /usr/bin/ansible # 对应的二进制模板文件在哪
python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
# file /usr/bin/ansible
/usr/bin/ansible: symbolic link to `/usr/bin/ansible-2.7'
#这是一个软链接 用起来更方便
rpm -ql ansible | less
/etc/ansible/ansible.cfg #主配置文件
/etc/ansible/hosts #主机清单
/etc/ansible/roles #角色的目录
/usr/bin/ansible #主程序 临时命令执行工具
/usr/bin/ansible-doc #查看配置文档,模块功能查看工具
/usr/bin/ansible-galaxy #下载/上传优秀代码或Roles模块的官网平台
/usr/bin/ansible-playbook #定制自动化任务,编排剧本工具/usr/bin/ansible-pull远程执行命令的工具
/usr/bin/ansible-vault #文件加密工具
/usr/bin/ansible-console #基于console界面与用户交互的执行工具
rpm -ql ansible | grep file.py
/usr/lib/python2.7/site-packages/ansible/modules/windows/win_file.py
主机清单
Inventory主机清单
ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名
默认的inventory file为/etc/ansible/hosts
inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成
[root@ansible ~]# ansible --help
usage: ansible [-h] [--version] [-v] [-b] [--become-method BECOME_METHOD]
ansible -m ping
-m 使用模块 ping
[root@ansible ~]# ansible 10.0.0.48 -m ping
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not
match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.48 #提示为空
cat >> /etc/ansible/hosts << EOF
10.0.0.48
10.0.0.49
EOF
#也是提示错误 因为没有key验证
[root@ansible ~]# ansible 10.0.0.48 -m ping #探测以下
The authenticity of host '10.0.0.48 (10.0.0.48)' can't be established.
ECDSA key fingerprint is SHA256:Zp63J/kTvnYc3to3flnLUoagIIVYMYA3hwcDdjoPFdA.
ECDSA key fingerprint is MD5:af:6d:49:41:09:7b:a5:e9:13:e1:51:1f:20:fc:31:17.
Are you sure you want to continue connecting (yes/no)? yes
10.0.0.48 | UNREACHABLE! => { #不可到达
"changed": false,
"msg": "Failed to connect to the host via ssh: Warning: Permanently added '10.0.0.48' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
"unreachable": true
}
[root@ansible ~]# ansible 10.0.0.48 -m ping -k
SSH password: #输入密码
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
# 修改48的密码使48.49 密码不一致
[root@c7-48 ~]# passwd
Changing password for user root.
New password:12345678
BAD PASSWORD: The password fails the dictionary check - it is too simplistic/systematic
Retype new password:12345678
passwd: all authentication tokens updated successfully.
#毫无顺序可言
[root@ansible ~]# ansible 10.0.0.48,10.0.0.49 -m ping -k
SSH password:
10.0.0.49 | FAILED! => {
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ~]# ansible 10.0.0.48,10.0.0.49 -m ping -k
SSH password:
10.0.0.49 | FAILED! => {
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
#查看已知主机目录
[root@ansible ~]# cd .ssh/
[root@ansible .ssh]# ls
known_hosts
[root@ansible .ssh]# cat known_hosts
10.0.0.48 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI/gOEa/2bc0EAi3sG8Wrt94I5j+Ln5/k15je1cQCq97d1aoC2I1lNdq5qelONBCRjbEjsKeVtRUe/foBuK6BII=
[root@ansible .ssh]# ssh 10.0.0.49 #进行登录 加入信任主机
The authenticity of host '10.0.0.49 (10.0.0.49)' can't be established.
ECDSA key fingerprint is SHA256:Zp63J/kTvnYc3to3flnLUoagIIVYMYA3hwcDdjoPFdA.
ECDSA key fingerprint is MD5:af:6d:49:41:09:7b:a5:e9:13:e1:51:1f:20:fc:31:17.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.0.49' (ECDSA) to the list of known hosts.
[email protected]'s password:
Last login: Wed Aug 12 23:31:25 2020 from 10.0.0.1
[root@c7-49 ~]# exit
logout
Connection to 10.0.0.49 closed.
[root@ansible .ssh]# ansible 10.0.0.48,10.0.0.49 -m ping -k #success
SSH password:
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ~]# ansible all -m ping -k #提供用户名指令
SSH password:
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
cat >> /etc/ansible/hosts <<EOF
[webserver]
10.0.0.48
[dbserver]
10.0.0.49
EOF
ntp.magedu.com
[webservers]
www1.magedu.com:2222 #指定端口
www2.magedu.com
[dbservers]
db1.magedu.com
db2.magedu.com
db3.magedu.com
[websrvs]
www[01:100].example.com
[dbsrvs]
db-[a:f].example.com
ansible配置文件 /etc/ansible/ansible.cfg(一般保持默认)
[defaults] #默认值
#inventory = /etc/ansible/hosts #主机列表配置文件
#library = /usr/share/my_modules/ #库文件存放目录
#module_utils = /usr/share/my_module_utils/
#remote_tmp = ~/.ansible/tmp #在被控制上执行 并删除
#local_tmp = ~/.ansible/tmp #两个搭配使用 执行完命令后会自动生成脚本 到远程主机 执行完即删除
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
#forks = 5 #并发执行5次
#poll_interval = 15 #15秒拉取一次数据
#sudo_user = root #普通用户无法在远程主机管理root 所以要使用sudo
#ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码
#ask_pass = True
#transport = smart
#remote_port = 22 #远程主机默认端口号
#module_lang = C
#module_set_locale = False
#host_key_checking = False #检查对应服务器的host_key,建议取消注释 这个如果不取消就会出现 2情况
#log_path=/var/log/ansible.log #日志文件 (取消注释,建议开启)
[root@ansible ~]# cd .ssh/
[root@ansible .ssh]# ls
known_hosts #这是信任文件 我们ssh之后就出产生记录 才能ping 要不然注释下面的默认值
[root@ansible .ssh]# rm -rf known_hosts
[root@ansible .ssh]# ansible all -m ping -k
SSH password:
10.0.0.48 | FAILED! => {
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
}
10.0.0.49 | FAILED! => {
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."
}
所有的主机都要手动ssh连接一遍才行
所以
#host_key_checking = False #检查对应服务器的host_key,建议取消注释
#注释后
[root@ansible .ssh]# ansible all -m ping -k
SSH password:
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ~]# ansible # tab
ansible ansible-console ansible-doc-2.7 ansible-playbook ansible-pull-2.7
ansible-2 ansible-console-2 ansible-galaxy ansible-playbook-2 ansible-test
ansible-2.7 ansible-console-2.7 ansible-galaxy-2 ansible-playbook-2.7 ansible-vault
ansible-config ansible-doc ansible-galaxy-2.7 ansible-pull ansible-vault-2
ansible-connection ansible-doc-2 ansible-inventory ansible-pull-2 ansible-vault-2.7
Ansible系列命令
ansible ansible-doc ansible-playbookansible-vault
ansible-consoleansible-galaxyansible-pull
ansible-doc:显示模块帮助
ansible-doc [options][module...]
显示所有模块的文档
-a
-l,--list列出可用模块
-s, --snippet显示指定模块的playbook片段
示例:
ansible-docl列出所有模块
ansible-doc ping查看指定模块帮助用法
ansible-doc -s ping查看指定模块帮助用法
[root@ansible ~]# ansible doc ping #加上模块名 查看怎么使用
usage: ansible [-h] [--version] [-v] [-b] [--become-method BECOME_METHOD]
[--become-user BECOME_USER] [-K] [-i INVENTORY] [--list-hosts]
[-l SUBSET] [-P POLL_INTERVAL] [-B SECONDS] [-o] [-t TREE] [-k]
[--private-key PRIVATE_KEY_FILE] [-u REMOTE_USER]
[-c CONNECTION] [-T TIMEOUT]
[--ssh-common-args SSH_COMMON_ARGS]
[--sftp-extra-args SFTP_EXTRA_ARGS]
[--scp-extra-args SCP_EXTRA_ARGS]
[--ssh-extra-args SSH_EXTRA_ARGS] [-C] [--syntax-check] [-D]
[-e EXTRA_VARS] [--vault-id VAULT_IDS]
[--ask-vault-pass | --vault-password-file VAULT_PASSWORD_FILES]
[-f FORKS] [-M MODULE_PATH] [--playbook-dir BASEDIR]
[-a MODULE_ARGS] [-m MODULE_NAME]
pattern
ansible: error: unrecognized arguments: ping
#统计ansible模块数量
[root@ansible ~]# ansible-doc -l | wc -l
3387
[root@ansible ~]# ansible-doc -s ping
- name: Try to connect to host, verify a usable python and return `pong' on success
ping:
data: # Data to return for the `ping' return value. If this parameter is set to `crash', the
module will cause an exception.
ansible通过ssh实现配置管理、应用部署、任务执行等功能,建议配置ansible
端能基子密钥认证的方式联系各被管理节点
ansible
-m module指定模块,默认为command
-v详细过程→vv -vv更详细
–list-hosts显示主机列表,可简写—list
[root@ansible ~]# ansible all --list-hosts
hosts (2):
10.0.0.48
10.0.0.49
-k,–ask-pass提示输入ssh连接密码,默认Key验证
-K,–ask-become-pass提示输入sudo时的口令
-C,–check检查,并不执行
-T,–timeout=TIMEOUT 执行命令的超时时间,默认10s
-u,–user=REMOTE_USER执行远程执行的用户
[root@ansible ~]# ansible webserver -m ping -u y -k
SSH password:
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ~]# ansible webserver -u y -k -m command -a'ls /root'
SSH password:
10.0.0.48 | FAILED | rc=2 >>
ls: cannot open directory /root: Permission deniednon-zero return code
#做不了权限以外的事
-b,–become代替l旧版的sudo切换
[root@ansible ansible]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
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:
SHA256:jd0oYIQ0Ms/MYd5V3mV3W3DEr4xfOHbP2dCV3ZIATv0 root@ansible
The key's randomart image is:
+---[RSA 2048]----+
| o.=.. ..+o ++*|
| X.= . + .oo o=|
| * + o .o o=|
| . . + o E.=|
| S + .o =.|
| . . B +|
| o *+|
| ..+|
| |
+----[SHA256]-----+
[root@ansible ansible]# ssh-copy-id 10.0.0.48
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '10.0.0.48'"
and check to make sure that only the key(s) you wanted were added.
[root@ansible ansible]# ssh-copy-id 10.0.0.49
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '10.0.0.49'"
and check to make sure that only the key(s) you wanted were added.
表示所有Inventory中的所有主机
[root@ansible ansible]# ansible all -m ping
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ansible]#
[root@ansible ansible]# ansible webserver -m ping
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ansible]# ansible dbserver -m ping
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ansible]# ansible *server -m ping
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ansible]# ansible "10.0.0.*" -m ping
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ansible]# ansible "*" -m ping
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ansible]# ansible webserver:dbserver -m ping
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
#必须是两个分组里有相同的主机 才可以使用
ansible 'webserver:&dbserver' -m ping
#使用单引号
ansible 'webserver:!dbserver' -m ping
#既在webserver和dbserver里面并且在appserver里面 不在ftpserver里面
ansible 'webserver:dbserver:&appservers:!ftpserver' -m ping
ansible "webserver:&dbserver" -m ping
ansible "~(web|db).*\.magedu\.com" -m ping
~ :表示主机里面是web|db开头的
. 结尾包含的magedu
[root@ansible ansible]# ansible '~(web|db)' -m ping
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@ansible ansible]# ansible '~(web|db)server' -m ping
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
1. 加载自己的配置文件默认/etc/ansible/ansible.cfg
2. 加载自己对应的模块文件,如command
3. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器
的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/xxX.PY文件
4. 给文件+x执行
5. 执行并返回结果
6. 删除临时py文件,sleep o退出
ansible all -m ping -vvv
#以wang用户执行ping存活检测
ansible all -m ping-u wang -k
#以wang sudo至root执行ping存活检测
ansible all -m ping -u wang-b-k
#以wang sudo至mage用户执行ping存活检测
ansible all -m|ping-u wang -b-k --become-user mage
#以wang sudo至root用户执行ls
ansible all -m command -u wang --become-user=root -a 'ls /root' -b -k -K
```bash
ansible srvs -m command -a 'service vsftpd start'
ansible srvs-m command -a 'echo magedu |passwd --stdin wang’不成功
>此命令不支持$VARNAME< > |;&等,用shell模块实现
ansible srv-m shell -a 'echo magedu |passwd -stdin wang'
调用bash执行命令类似cat/tmp/stanley.md | awk -F'I'‘iprint $1,$2y&>
/tmp/example.txt这些复杂命令,即使使用shell也可能会失败,解决办法∶写到脚本
时,copy到远程,执行,再把需要的结果拉回执行命令的机器
-a "/PATH/TO/SCRIPT_FILE“
snsible websrvs -m script -a f1.sh
ansible all -m copy -a "src=/root/f1.sh dest=/tmp/f2.sh owner=wang mode=600 backup=yes"
如果目标存在,默认覆盖,此处指定先备份
ansible all -m copy -a "content='test content\n' dest=/tmp/f1.txt" 利用内容,直接生成目标文件
ansible all -m fetch -a 'src=/root/a.sh dest=/data/scripts'
File: 设置文件属性
ansible all -m file -a "path=/root/a.sh owner=wang mode=755"
ansible web -m file -a 'src=/app/testfile dest=/app/testfile-link state=link'
removes 如果存在 执行
creates 如果不存在 执行
#如果存在/etc/fs 文件 则执行cat
ansible all -a 'removes=/etc/fs cat /etc/fstab'
#如果不存在 所以要执行
ansible all -a 'creates=/etc/fs cat /etc/fstab'
ansible all -a 'chdir=/boot ls'
[root@ansible ansible]# ansible 10.0.0.48 -a 'useradd test1'
10.0.0.48 | CHANGED | rc=0 >>
[root@ansible ansible]# ansible 10.0.0.48 -a 'getent passwd test1'
10.0.0.48 | CHANGED | rc=0 >>
test1:x:1002:1002::/home/test1:/bin/bash
建议用shell模块
[root@ansible ansible]# ansible 10.0.0.48 -a 'echo magedu|passwd --stdin test1'
10.0.0.48 | CHANGED | rc=0 >>
magedu|passwd --stdin test1
[root@ansible ansible]# ansible 10.0.0.48 -a 'getent shadow test1'
10.0.0.48 | CHANGED | rc=0 >>
test1:!!:18488:0:99999:7::: #!! 提示为空
[root@ansible ansible]# ansible 10.0.0.48 -a 'echo $HOSTNAME'
10.0.0.48 | CHANGED | rc=0 >>
$HOSTNAME #直接打印了$HOSTNAME
[root@ansible ansible]# ansible 10.0.0.48 -m shell -a 'echo $HOSTNAME'
10.0.0.48 | CHANGED | rc=0 >>
c7-48 #输出成功
#修改密码 也是成功的
[root@ansible ansible]# ansible 10.0.0.48 -m shell -a "echo magedu|passwd --stdin test1"
10.0.0.48 | CHANGED | rc=0 >>
Changing password for user test1.
passwd: all authentication tokens updated successfully.
[root@ansible ansible]# ansible 10.0.0.48 -m shell -a "getent shadow test1" 10.0.0.48 | CHANGED | rc=0 >>
test1:$6$2zu5Lawc$5UgDQI8CR7cImwOu.AcTzM9pnM4UjW.svTM9mY3h3HI4nX4ECMEnoVzzwY0kWPaYVRRLL1p/FFzQQEsvaD.hU/:18488:0:99999:7:::
## 在本地新建一个脚本
[root@ansible ansible]# vim host.sh
#!/bin/bash
hostname
[root@ansible ansible]# chmod +X host.sh
[root@ansible ansible]# pwd
/etc/ansible
使用script的模块能使远程主机执行本地脚本
[root@ansible ansible]# ansible all -m script -a "/etc/ansible/host.sh"
10.0.0.48 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 10.0.0.48 closed.\r\n",
"stderr_lines": [
"Shared connection to 10.0.0.48 closed."
],
"stdout": "c7-48\r\n",
"stdout_lines": [
"c7-48"
]
}
10.0.0.49 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 10.0.0.49 closed.\r\n",
"stderr_lines": [
"Shared connection to 10.0.0.49 closed."
],
"stdout": "c7-49\r\n", #标准输出
"stdout_lines": [
"c7-49"
]
}
ansible-doc -s copy
ansible all -m copy -a 'src=/root/ansible/selinux dest=/etc/selinux/config backup=yes'
ansible all -a 'cat /etc/selinux/config' #验证
ansible all -a 'ls /etc/selinux' #查看复制文件
ansible all -m shell -a 'rm -f /etc/selinux/config.*' #删除复制的文件
ansible all -m shell -a 'reboot'
#更改为selinux后需要重启生效
ansible all -m shell -a 'getenforce' #验证
#复制完更改权限
ansible all -m copy -a 'src=/etc/shadow dest=/data/ mode=000 owner=wang'
ansible all -a 'ls -l /data/' #查看
#编辑文件发送到目标主机
ansible all -m copy -a 'content="hello\nthanks\n" dest=/data/f2'
ansible all -m ping -a 'cat /data/f2'
#content里面是文件内容
src是本机源文件
dest是目标文件
backup=yes 是在推送是进行复制 保留源文件
mode= 权限可以设置
owner= 所有者也可以设置
ansible all -a ‘cat /etc/selinux/config’
vim /etc/ansible/ansible.cfg
取消注释 使用shell模块
module_name = shell
[root@ansible ~]# ansible-doc -s copy
#content可以新建文件内容 并发送到目标主机
# 执行命令
[root@ansible ~]# ansible all -m copy -a "content='hello\nthanks\n' dest=/root/f2"
#在目标主机查看
[root@c7-48 ~]# cat f2
hello
thanks
[root@ansible ~]# ansible-doc -s fetch
#只能抓取单个文件
[root@ansible ~]# ls /data
[root@ansible ~]# ansible all -m fetch -a 'src=/var/log/messages dest=/data'
[root@ansible ~]# ls /data/
10.0.0.44 10.0.0.48 10.0.0.49
[root@ansible ~]# tree /data/
/data/
├── 10.0.0.44
│ └── var
│ └── log
│ └── messages
├── 10.0.0.48
│ └── var
│ └── log
│ └── messages
└── 10.0.0.49
└── var
└── log
└── messages
[root@ansible data]# ansible 10.0.0.44 -m shell -a 'tar jcf log.tar.xz /var/log/*.log'
[root@c7-44 ~]# ls /root
log.tar.xz f2
[root@ansible data]# ansible 10.0.0.44 -m fetch -a 'src=/root/log.tar.xz dest=/data'
#查看
[root@ansible ~]# tree /data/
/data/
├── 10.0.0.44
│ ├── root
│ │ └── log.tar.xz #在这
│ └── var
│ └── log
│ └── messages
#验证
[root@ansible ~]# cd /data/10.0.0.44/root/
[root@ansible root]# ls
log.tar.xz
[root@ansible root]# tar tvf log.tar.xz #预览
[root@ansible ~]# ansible-doc -s unarchive
[root@ansible ~]# ansible-doc -s archive
[root@ansible ~]# ansible-doc -s file
name | path|src是等价的
ansible all -m file -a 'name=/data/f3 state=touch'
ansible all -m file -a 'path=/data/f3 state=touch'
[root@ansible ~]# ansible all -m file -a 'name=/data/f3 state=absent'
[root@ansible ~]# ansible all -m file -a 'path=/data/f3 state=absent'
[root@ansible ~]# ansible all -m file -a 'path=/data/dir2 state=directory'
[root@ansible ~]# ansible all -m file -a 'name=/data/dir1 state=directory'
[root@ansible ~]# ansible all -m file -a 'name=/data/dir1 state=absent'
[root@ansible ~]# ansible all -m file -a 'path=/data/dir2 state=absent'
[root@ansible ~]# ansible all -m file -a 'src=/etc/fstab dest=/data/fstab.link state=link'
#查看
[root@ansible ~]# ansible all -a 'ls -l /data'
[root@ansible ~]# ansible all -m file -a 'dest=/data/fstab.link state=absent'
#查看
[root@ansible ~]# ansible all -a 'ls -l /data'
[root@ansible ~]# ansible all -m file -a 'dest=/data/ state=absent'
ps:挂在点的目录无法删除
#查看挂载点
[root@c7-48 ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 1500376 0 1500376 0% /dev
tmpfs 1512380 0 1512380 0% /dev/shm
tmpfs 1512380 19616 1492764 2% /run
tmpfs 1512380 0 1512380 0% /sys/fs/cgroup
/dev/mapper/centos-root 28289540 2177492 26112048 8% /
/dev/sda1 1038336 139480 898856 14% /boot
tmpfs 302480 0 302480 0% /run/user/0
挂载点介绍
ansible all -m shell -a "rm -rf /data/*"
[root@ansible ~]# ansible 10.0.0.48 -m hostname -a "name=node1"
已经生效并改名
[root@c7-48 ~]# bash
[root@node1 ~]# ls
anaconda-ks.cfg f1.txt f2
[root@node1 ~]# cat /etc/hostname #centos-7的主机名的配置文件
node1
#centos6的主机名在
/etc/sysconfig/network
缺点:
#没有改 手动更改建议修改
[root@node1 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 ==localhost4.localdomain4==
::1 localhost localhost.localdomain localhost6 ==localhost6.localdomain6==
==之间的部分 ==
支持时间: minute,hour,day,month,weekday
*/1 每1分钟
1-5 范围
1,3,6 隔开
#广播位置
[root@ansible ~]# which wall
/usr/bin/wall
[root@ansible ~]# ansible all -m cron -a 'minute=* weekday=1,7,6 job="/usr/bin/wall FBI warning" name=warningcron'
[root@ansible ~]# ansible all -m cron -a 'job="/usr/bin/wall FBI warning" name=warningcron state=absent'
[root@ansible ~]# ansible all -m cron -a 'disabled=true job="/usr/bin/wall FBI warning" name=warningcron'
[root@ansible ~]# ansible all -m cron -a 'disabled=no job="/usr/bin/wall FBI warning" name=warningcron'
[root@node1 ~]# contab -l
bash: contab: command not found
[root@node1 ~]# crontab -l
*/5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1
#Ansible: warningcron
#* * * * * /usr/bin/wall FBI warning #已注释
[root@ansible ~]# ansible all -m cron -a 'disabled=false job="/usr/bin/wall FBI warning" name=warningcron'
[root@ansible ~]# ansible all -m cron -a 'disabled=yes job="/usr/bin/wall FBI warning" name=warningcron'
[root@node1 ~]# crontab -l
*/5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1
#Ansible: warningcron
* * * * * /usr/bin/wall FBI warning
install (present' or
installed’,`latest’),
remove (absent' or
removed’)
[root@ansible ~]# ansible all -m yum -a 'name=vsftpd'
ansible all -m yum -a 'list=installed'
ansible all -m yum -a 'name=vsftpd state=removed'
#验证
ansible all -m shell -a 'rpm -q vsftpd'
ansible all -m yum -a 'name=vsftpd,memcached state=latest'
ansible all -m yum -a 'name=vsftpd,memcached state=absent'
#先copy到远程主机
[root@ansible data]# ansible 10.0.0.44,10.0.0.48 -m copy -a 'src=/data/jdk-8u131-linux-x64_.rpm dest=/root/'
#然后安装
[root@ansible data]# ansible 10.0.0.44,10.0.0.48 -m yum -a 'name=/root/jdk-8u131-linux-x64_.rpm state=installed'
#禁用gpg检查
[root@ansible data]# ansible 10.0.0.44,10.0.0.48 -m yum -a 'name=/root/jdk-8u131-linux-x64_.rpm state=installed disabled_gpg_check=yes'
#边清楚更新缓存 一边去装包
[root@ansible data]# ansible 10.0.0.44,10.0.0.48 -m yum -a 'name=dstat update_cache=yes'
gpg_check简介
dtsta是一款监控工具
[root@ansible ~]# ansible all -m service -a 'name=nginx state=started enabled=yes'
ansible all-m service -a 'name=httpd state=stopped'
ansible all -m service -a 'name=httpd state=started'
ansible all -m service -a 'name=httpd state=reloaded'
ansible all -m service -a 'name=httpd state=restarted'
#查看nginx账号有没有
getent passwd nginx
id nginx
[root@ansible ~]# ansible all -m user -a 'name=nginx shell=/sbin/nologin system=yes home=/var/system groups=root,bin uid=808 comment="system service"'
#system=yes 表示系统账号
# shell=/sbin/nologin 系统用户的shell类型
#comment 描述
#groups 附加组
[root@ansible ~]# ansible all -m user -a 'name=ylm shell=/sbin/nologin system=yes home=/var/ylm groups=root,bin uid=88 comment="nginx service"'
[root@ansible ~]# ansible all -m shell -a 'getent passwd ylm'
[root@ansible ~]# ansible all -m user -a 'name=ylm state=absent remove=yes'
#removes=yes 是确认删除家目录
[root@ansible ~]# ansible all -m shell -a 'getent passwd ylm'
[root@ansible ~]# ansible all -m group -a 'name=ylm system=yes gid=800'
#验证
[root@ansible ~]# ansible all -a 'getent group ylm'
[root@ansible ~]# ansible all -m group -a 'name=ylm state=absent'
连接https://galaxy.ansible.com下载相应的roles(角色)
ansible-galaxy list
ansible-galaxy install geerlingguy.redis
ansible-galaxy remove geerlingguy.redis
[root@ansible ~]# ansible-galaxy install geerlingguy.nginx
#下载到隐藏目录.asnible目录
[root@ansible ~]# tree .ansible/roles/
.ansible/roles/
└── geerlingguy.nginx
├── defaults
│ └── main.yml
├── handlers
│ └── main.yml
├── LICENSE
├── meta
│ └── main.yml
├── molecule
│ └── default
│ ├── converge.yml
│ └── molecule.yml
├── README.md
├── tasks
│ ├── main.yml
│ ├── setup-Archlinux.yml
│ ├── setup-Debian.yml
│ ├── setup-FreeBSD.yml
│ ├── setup-OpenBSD.yml
│ ├── setup-RedHat.yml
│ ├── setup-Ubuntu.yml
│ └── vhosts.yml
├── templates
│ ├── nginx.conf.j2
│ ├── nginx.repo.j2
│ └── vhost.j2
└── vars
├── Archlinux.yml
├── Debian.yml
├── FreeBSD.yml
├── OpenBSD.yml
└── RedHat.yml
角色就是多个playbook
[root@ansible tasks]# pwd
/root/.ansible/roles/geerlingguy.nginx/tasks
[root@ansible tasks]# cat main.yml
---
# Variable setup.
- name: Include OS-specific variables.
include_vars: "{{ ansible_os_family }}.yml"
- name: Define nginx_user.
set_fact:
nginx_user: "{{ __nginx_user }}"
when: nginx_user is not defined
# Setup/install tasks.
- include_tasks: setup-RedHat.yml
when: ansible_os_family == 'RedHat'
- include_tasks: setup-Ubuntu.yml
when: ansible_distribution == 'Ubuntu'
- include_tasks: setup-Debian.yml
when: ansible_os_family == 'Debian'
- include_tasks: setup-FreeBSD.yml
when: ansible_os_family == 'FreeBSD'
- include_tasks: setup-OpenBSD.yml
when: ansible_os_family == 'OpenBSD'
- include_tasks: setup-Archlinux.yml
when: ansible_os_family == 'Archlinux'
# Vhost configuration.
- import_tasks: vhosts.yml
# Nginx setup.
- name: Copy nginx configuration in place.
template:
src: "{{ nginx_conf_template }}"
dest: "{{ nginx_conf_file_path }}"
owner: root
group: "{{ root_group }}"
mode: 0644
notify:
- reload nginx
- name: Ensure nginx service is running as configured.
service:
name: nginx
state: "{{ nginx_service_state }}"
enabled: "{{ nginx_service_enabled }}"
[root@ansible tasks]# ansible-galaxy list geerlingguy.nginx
# /root/.ansible/roles
- geerlingguy.nginx, 2.8.0
[root@ansible roles]# cp geerlingguy.nginx/ wang.nginx -rp
[root@ansible roles]# ansible-galaxy list
# /root/.ansible/roles
- geerlingguy.nginx, 2.8.0
- wang.nginx, 2.8.0
# /usr/share/ansible/roles
# /etc/ansible/roles
[root@ansible ~]# ansible-galaxy remove geerlingguy.nginx
#验证
#说白了 删除目录就可以
[root@ansible ~]# cd .ansible/roles/
[root@ansible roles]# ls
wang.nginx
推送至远程,效率无线提升,对运维要求较高
useage: ansible-playbook [optinon] playbook.yml [playbook2...]
#可以跟很多playbook
.yaml 后缀
[root@ansible ansible]# cat hello.yaml
--- #表示开头
- hosts: webserver #操作的哪些主机
remote_user: root #默认使用什么用户
tasks: #任务
- name: hello #任务名称
command: hostname #执行操作
== 功能︰管理加密解密yml文件==
ansible-vault[create|decrypt|edit|encrypt|rekey|view]
ansible-vault encrypt hello.yml加密
ansible-vault decrypt hello.yml解密
ansible-vault view hello.yml查看
ansible-vault edit hello.yml编辑加密文件
ansible-vault rekey hello.yml修改口令
ansible-vault create new.yml创建新文件
[root@ansible ansible]# ansible-vault encrypt hello.yaml #加密
New Vault password:
Confirm New Vault password:
Encryption successful
[root@ansible ansible]# cat hello.yaml
$ANSIBLE_VAULT;1.1;AES256
62303934313466613534656430353834353434636532643439633634636434346462366537626365
3037313238336431643961323631333334663035653762650a663738316336333263383465343734
36323363636166316635396433646563383162653831323037646661313336303439303235313766
3433613735313237340a616264666464616334393033343138323539373764303734366538316439
31623730366338636438366363396538313966643539363737386264366639336238396635633130
39643264623730303435666431303232633062643439356238663333323333303766336665363661
38303535306565373131626163626466333439386265343837643034373461666534656364363730
36616665343862326537666333623266313538366262323430333832656465636531343862643738
6632
#加密后playbook不能直接使用
[root@ansible ansible]# ansible-playbook hello.yaml
ERROR! Attempting to decrypt but no vault secrets found
[root@ansible ansible]# ansible-vault decrypt hello.yaml
Vault password:
Decryption successful
[root@ansible ansible]# cat hello.yaml
---
- hosts: webserver
remote_user: root
tasks:
- name: hello
command: hostname
使用口令进行查看加密的yml
[root@ansible ansible]# ansible-vault view hello.yaml
Vault password:
---
- hosts: webserver
remote_user: root
tasks:
- name: hello
command: hostname
[root@ansible ansible]# ansible-vault edit hello.yaml
Vault password:
[root@ansible ansible]# ansible-vault rekey hello.yaml
Vault password:
New Vault password:
Confirm New Vault password:
Rekey successful
[root@ansible ansible]# ansible-vault create hello2.yml
New Vault password:
Confirm New Vault password:
Ansible-console : 2.0+新增,可交互执行命令,支持tab
root@test(2)[f:10]$
执行用户@当前操作的主机组(当前组的主机数量)[f:并发数]$
设置并发数:forks n例如: forks 10
切换组:cd主机组例如: cd web
列出当前组主机列表:list
列出所有的内置命令∶?或help
root@all(2)[f:5]$ list #查看主机
root@all (2)[f:5]$ cd appsrvs #进入主机清单
root@appsrvs (2)[f:5]$ list #查看主机
root@appsrvs (2)[f:5]$ yum name=httpd state=present #执行命令
root@appsrvs (2)[f:5]$ service name=httpd state=started
[root@ansible ~]# ansible-console
Welcome to the ansible console.
Type help or ? to list commands.
root@all (3)[f:5]$
#root 用户
# all 所有人
(3)表示几个主机
[f:5] 并发5执行5个
[root@ansible ~]# ansible-console
Welcome to the ansible console.
Type help or ? to list commands.
root@all (3)[f:5]$ cd webserver
root@webserver (1)[f:5]$ forks 10
root@webserver (1)[f:10]$ ?
root@webserver (1)[f:10]$ command hostname
10.0.0.48 | CHANGED | rc=0 >>
node1.ylm.com
root@webserver (1)[f:10]$ cd 10.0.0.48
[email protected] (1)[f:10]$ hostname name=48
10.0.0.48 | CHANGED => {
"ansible_facts": {
"ansible_domain": "",
"ansible_fqdn": "48",
"ansible_hostname": "48",
"ansible_nodename": "48"
},
"changed": true,
"name": "48"
}
[email protected] (1)[f:1
在playbook里面写好多 play 用户用ansible命令去调用执行的play,每个play里面有自己的任务,任务和任务之间有先后顺序,本质上调底层模块(开发 ,核心,插件),也得看主机清单 ,也通过ssh连接到远程主机上。
YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML.
C语言、Python、Perl以及电子邮件格式RFC2822等。ClarkEvans在2001年在首次发表了这种
语言,另外Ingy dot Net与Oren Ben-Kikit也是这语言的共同设计者
YAML Ain’t Markup Language(不是标记语言),即YAML不是XML。不过,在开发的这种语言时,YAML的意
思其实是:“Yet Another Markup Language”(仍是一种标记语言)
特性
1. YAML的可读性好
2. YAML和脚本语言的交互性好
3. YAML使用实现语言的数据类型
4. YAML有一个一致的信息模型
5. YAML易于实现
6. YAML可以基于流来处理
7. YAML表达能力强,扩展性好
内容及规范参见http://www.yaml.org
在单一挡案中,可用连续三个连字号(——)区分多个档案。另外,还有选择性的连续三个点号
(…)用来表示档案结尾
次行开始正常写Playbook的内容,一般建议写明该Playbook的功能
使用#号注释代码
缩进必须是统一的,不能空格和tab混用
缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结
合换行来实现的
YAML文件内容和Linux系统大小写判断方式保持一致,是区别大小写的,k/v的值均需大小写敏
感
k/v的值可同行写也可换行写。同行使用:分隔
v可是个字符串,也可是另一个列表
一个完整的代码块功能需最少元素需包括name: task
一个name只能包括一个task
YAML文件扩展名通常为yml或yaml
#A list of tasty fruits
-Apple
-orange
-strawberry
-Mango
Dictionary :字典,通常由多个key与value构成(键值对)
#An employee record
name: Example Developer
job: Developer
skill:Elite
也可以将key:value放置于{f}中进行表示,用,分隔多个key:value
--
# An employee record
{name:Example Developer,job: Developer,skill:Elite}
name: John Smith
age;41
gender: Male
spouse:
name: lane Smith
age: 37
gender: Female
children:
- name: Jimmy Smith
age: 17
gender:Malc
- name: Jenny Smith
age 13
gender: Female
ansible中文权威指南
ansible-playbook -t tagsname useradd.yml
Hosts;:
Websrvs:dbsrvs两个组的并集
Websrvs:&dbsrvs两个组的交集
webservers:!phoenix在websrvs组,但不在dbsrvs组
示例: - hosts: websrvs : dbsrvs
remote_user:可用于Host和task中。也可以通过指定其通过sudo的方式在远
程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使
用sudo_user指定sudo时切换的用户
- hosts: websrvs
remote_user: root
tasks:
- name: test connection
ping:
remote_user: magedu
sudo: yes #默认sudo为root
sudo_user:wang #sudo为wang
task列表和actioh
play的主体部分是tasklist。task list中的各任务按次序逐个在hosts中指定的所
有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自
下而下某playbook时,如果中途发生错误,所有已执行任务都将回滚,因此,
在更正playbook后重新执行一次即可
task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模
块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致
每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可
能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出
tasks:任务列表
格式∶(1)action: module arguments
(2) module: arguments # 建议使用
- 注意: shell和command模块后面跟命令,而非key=value
某任务的状态在运行后为changed时,可通过“notify”通知给相应的
handlers
任务可以通过"tags“打标签,而后可在ansible-playbook命令上使用-t指定进
行调用
示例:
tasks:
- name: disable selinux
command: /sbin/setenforce o
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True
[root@ansible ansible]# cat file.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: create new file
file: name=/data/newfile state=touch
- name: create new user
user: name=test2 system=yes shell=/sbin/nologin
- name: install package
yum: name=httpd
- name: copy html
copy: src=/var/www/html/index.html dest=/var/www/html
- name: start service
service: name=httpd state=started enabled=yes
[root@ansible ansible]#
ps:新建用户使用user命令之前 一定要查看 用户是否存在
[root@ansible ~]# ansible webserver -a 'getent passwd'
[root@ansible ansible]# ansible-playbook -C file.yml
ansible-playbook > ... [options]
--check只检测可能会发生的改变,但不真正执行操作
--list-hosts列出运行任务的主机
--limit主机列表只针对主机列表中的主机执行
-v 显示过程 -vv -v 更详细
ansible-playbook file.yml --check只检测
ansible-playbook file.yml
ansible-playbook file.yml --limit websrvs
[root@ansible ansible]# ansible all -a 'getent passwd test2' --limit 10.0.0.48 只看48的
10.0.0.48 | CHANGED | rc=0 >>
test2:x:807:807::/home/test2:/sbin/nologin
[root@ansible ansible]# ansible-playbook file.yml --list-hosts
playbook: file.yml
play #1 (webserver): webserver TAGS: []
pattern: [u'webserver']
hosts (1):
10.0.0.48
[root@ansible ansible]# ansible-playbook file.yml --list-tasks
playbook: file.yml
play #1 (webserver): webserver TAGS: []
tasks:
create new file TAGS: []
create new user TAGS: []
install package TAGS: []
copy html TAGS: []
start service TAGS: []
#!/bin/bash
#安装Apache
yum install --quiet -y httpd
#复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp/tmp/vhosts.conf /etc/httpd/conf.d/
#启动Apache,并设置开机启动
service httpd start
chkconfig httpd on
hosts: all
tasks:
- name:"安装Apache"
yum: name=httpd
- name:"复制配置文件”
copy: src=ftmp/httpd.conf dest=/etc/httpd/conf/
copy: src=/tmp/vhosts.conf dest=fetc/httpd/conf/ #不可用 一个name 使用一个copy
- name:"启动Apache ,并设置开机启动”
service: name=httpd state=started enabled=yes
相对路径☞的是playbook 的目录下
[root@ansible ansible]# cat file.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: create new file
file: name=/data/newfile state=touch
- name: create new user
user: name=test2 system=yes shell=/sbin/nologin
- name: install package
yum: name=httpd
- name: copy html
copy: src=file/index.html dest=/var/www/html/
- name: copy test.html
copy: src=file/test.html dest=/var/www/html/
- name: start service
service: name=httpd state=started enabled=yes
示例:
执行一遍:
[root@ansible ansible]# cat files.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: create new file
file: name=/root/newfile state=touch
- name: create new user
user: name=test2 system=yes shell=/sbin/nologin
- name: install package
yum: name=httpd
- name: copy html
copy: src=files/index.html dest=/var/www/html/
- name: start service
service: name=httpd state=started enabled=yes
[root@ansible ansible]# cat files.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: create new file
file: name=/root/newfile state=touch
- name: create new user
user: name=test2 system=yes shell=/sbin/nologin
- name: install package
yum: name=httpd
- name: copy html
copy: src=files/index.html dest=/var/www/html/
- name: copy test html #增加了这一行 有拷贝了同一个文件
copy: src=files/test.html dest=/var/www/html/index.html
- name: start service
service: name=httpd state=started enabled=yes
我们发现 访问的时候 并没有更新页面 是因为 服务是启动的所以 必须重启 才可以
[root@ansible ansible]# cat files.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: create new file
file: name=/root/newfile state=touch
- name: create new user
user: name=test2 system=yes shell=/sbin/nologin
- name: install package
yum: name=httpd
- name: copy html
copy: src=files/index.html dest=/var/www/html/
- name: copy test html
copy: src=files/test.html dest=/var/www/html/index.html
notify: restart httpd
- name: start service
service: name=httpd state=started enabled=yes
handlers:
- name: restart httpd
service: name=httpd state=restarted enabled=yes
更改80端口为800
[root@ansible ansible]# cat http.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: install package
yum: name=httpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf backup=yes #将配置文件更改后
notify: restart service #重启服务
- name: start service
service: name=httpd state=started enabled=yes
handlers: #触发器可以定义多个
- name: restart service
service: name=httpd state=restarted
[root@ansible ansible]# cat http.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: install package
yum: name=httpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf backup=yes
notify: restart service
- name: start service
service: name=httpd state=started enabled=yes
tags: rshttpd #打上标签
handlers:
- name: restart service
service: name=httpd state=restarted
[root@ansible ansible]# ansible-playbook -t rshttpd http.yml
[root@ansible ansible]# cat http.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: install package
yum: name=httpd
tags: inshttpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf backup=yes
notify: restart service
- name: start service
service: name=httpd state=started enabled=yes
tags: rshttpd
handlers:
- name: restart service
service: name=httpd state=restarted
[root@ansible ansible]#
[root@ansible ansible]# ansible-playbook -t inshttpd,rshttpd http.yml
[root@ansible ansible]# cat http.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: install package
yum: name=httpd
tags: httpd
- name: copy conf file
copy: src=files/httpd.conf dest=/etc/httpd/conf backup=yes
notify: restart service
- name: start service
service: name=httpd state=started enabled=yes
tags: httpd
handlers:
- name: restart service
service: name=httpd state=restarted
[root@ansible ansible]# ansible-playbook -t httpd http.yml
[root@ansible ansible]# ansible-playbook http.yml --list-tags
playbook: http.yml
play #1 (webserver): webserver TAGS: []
TASK TAGS: [httpd]
[root@ansible ansible]# ansible webserver -m setup #查看系统信息
[root@ansible ansible]# ansible webserver -m setup | less
[root@ansible ansible]#
[root@ansible ansible]# ansible 10.0.0.48 -m hostname -a 'name=node1'
10.0.0.48 | CHANGED => {
"ansible_facts": {
"ansible_domain": "",
"ansible_fqdn": "node1",
"ansible_hostname": "node1",
"ansible_nodename": "node1",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"name": "node1"
}
[root@ansible ansible]# ansible webserver -m setup | grep ansible_fqdn
"ansible_fqdn": "c7-49.shared",
"ansible_fqdn": "node1",
[root@ansible ansible]# ansible webserver -m setup | grep ansible_hostname
"ansible_hostname": "c7-49",
"ansible_hostname": "node1",
[root@ansible ansible]# ansible webserver -m setup -a 'filter=ansible_hostname' #使用filter去过滤
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"ansible_hostname": "c7-49",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"ansible_hostname": "node1",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
[root@ansible ansible]# cat app.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: install package
yum: name={{ pkname }}
- name: start service
service: name={{ pkname }} state=started enabled=yes
使用==-e==去执行
[root@ansible ansible]# ansible-playbook -e 'pkname=httpd' app.yml
[root@ansible ansible]# cat app.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: install package
yum: name={{ pkname1 }} #变量名
- name: install package
yum: name={{ pkname2 }} #变量名
[root@ansible ansible]# ansible-playbook -e 'pkname1=vsftpd pkname2=memcached' app.yml
[root@ansible ansible]# ansible webserver -m shell -a 'rpm -q vsftpd memcached' #查看安装的包
[root@ansible ansible]# ansible webserver -m shell -a 'yum -y remove vsftpd memcached' #卸载安装的包
[root@ansible ansible]# cat app.yml
---
- hosts: webserver
remote_user: root
vars:
- pkname1: httpd
- pkname2: vsftpd
tasks:
- name: install package
yum: name={{ pkname1 }}
- name: install package
yum: name={{ pkname2 }}
[root@ansible ansible]# ansible-playbook app.yml
[root@ansible ansible]# ansible webserver -m shell -a 'rpm -q httpd vsftpd'
vim /etc/ansible/hosts
[webserver]
10.0.0.48 http_port=81
10.0.0.49 http_port=82
[root@ansible ansible]# cat hostname.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: set hostaname
hostname: name=www{{http_port}}.node
[root@ansible ansible]# ansible-playbook hostname.yml
10.0.0.49 | CHANGED | rc=0 >>
www82.node
10.0.0.48 | CHANGED | rc=0 >>
www81.node
[webserver]
10.0.0.48 http_port=81
10.0.0.49 http_port=82
[webserver:vars]
nodename=www
domainname=liming.com
[root@ansible ansible]# cat hostname.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: set hostaname
hostname: name={{nodename}}{{http_port}}.{{domainname}}
[root@ansible ansible]# ansible-playbook hostname.yml
[root@ansible ansible]# ansible webserver -m shell -a 'hostname'
10.0.0.48 | CHANGED | rc=0 >>
www81.liming.com
10.0.0.49 | CHANGED | rc=0 >>
www82.liming.com
[root@ansible ansible]# ansible-playbook -e 'nodename=web domainname=example.com' hostname.yml
[root@ansible ansible]# ansible webserver -a 'hostname'
10.0.0.49 | CHANGED | rc=0 >>
web82.example.com
10.0.0.48 | CHANGED | rc=0 >>
web81.example.com
#命令行优先级大于配置文件
变量的优先级 -e > playbook > 主机清单
普通变量比分组里面的公共变量优先级高
[root@ansible ansible]# ansible all -m setup -a 'filter="ansible_fqdn"'
10.0.0.50 | SUCCESS => {
"ansible_facts": {
"ansible_fqdn": "c7-50.shared",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
10.0.0.49 | SUCCESS => {
"ansible_facts": {
"ansible_fqdn": "web82.example.com",
"discovered_interpreter_python": "/usr/bin/python"
},
---
"changed": false
}
10.0.0.48 | SUCCESS => {
"ansible_facts": {
"ansible_fqdn": "web81.example.com",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
[root@ansible ansible]# cat var.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: create log file
file: name=/data/{{ ansible_fqdn }}.log state=touch #直接只是setup的变量
[root@ansible ansible]# ansible-playbook var.yml
[root@ansible ~]# ansible all -a 'ls /data -l'
10.0.0.49 | CHANGED | rc=0 >>
总用量 0
-rw-r--r-- 1 root root 0 8月 20 05:41 web82.example.com.log
10.0.0.48 | CHANGED | rc=0 >>
总用量 0
-rw-r--r-- 1 root root 0 8月 20 05:41 web81.example.com.log
10.0.0.50 | CHANGED | rc=0 >>
总用量 0
[root@ansible ansible]# cat vars.yml
var1: httpd
var2: vsftpd
[root@ansible ansible]# cat testvar.yml
---
- hosts: webserver
remote_user: root
vars_files: #定义变量文件
- vars.yml #文件名
tasks:
- name: install package
yum: name={{ var1 }}
- name: cretate file
file: name=/data/{{ var2 }}.log state=touch
[root@ansible ansible]# ansible-playbook testvar.yml
#验证
[root@ansible ansible]# ansible webserver -m shell -a 'rpm -q httpd'
[WARNING]: Consider using the yum, dnf or zypper module rather than running
'rpm'. If you need to use command because yum, dnf or zypper is insufficient
you can add 'warn: false' to this command task or set 'command_warnings=False'
in ansible.cfg to get rid of this message.
10.0.0.48 | CHANGED | rc=0 >>
httpd-2.4.6-93.el7.centos.x86_64
10.0.0.49 | CHANGED | rc=0 >>
httpd-2.4.6-93.el7.centos.x86_64
[root@ansible ansible]# ansible webserver -m shell -a 'ls /data'
10.0.0.48 | CHANGED | rc=0 >>
vsftpd.log
10.0.0.49 | CHANGED | rc=0 >>
vsftpd.log
[root@ansible ansible]# ansible-doc -s template
- name: Template a file out to a remote server
#拿一个文件当模板传到远程主机上去
[root@ansible ~]# yum -y install nginx
root@ansible ~]# cat /etc/nginx/nginx.conf
worker_processes auto; #根据CPU核数自动生成work进程数
[root@ansible ~]# systemctl start nginx
[root@ansible ~]# ps aux | grep nginx
root 22038 0.0 0.2 120900 2096 ? Ss 21:21 0:00 nginx: master process /usr/sbin/nginx
nginx 22039 0.0 0.3 121296 3052 ? S 21:21 0:00 nginx: worker process #只有一个进程表示一个CPU
root 22041 0.0 0.0 112824 980 pts/2 S+ 21:21 0:00 grep --color=auto nginx
[root@ansible ~]# lscpu #查看CPU 只有一个
CPU(s): 1
ansible_processor_vcpus": 1
[root@ansible templates]# cat nginx.conf.j2
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes {{ansible_processor_vcpus*4}}; #使用变量*4
[root@ansible templates]# cat templat.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: install package
yum: name=nginx
- name: copy template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf #使用template模块 且只能在playbook中使用
notify: restart service
- name: start service
service: name=nginx state=started enabled=yes
handlers:
- name: restart service
service: name=nginx state=restarted
[root@ansible templates]# ansible-playbook templat.yml
#因为是1核所以*4是4个进程
[root@ansible templates]# ansible webserver -m shell -a 'ps aux| grep nginx'
10.0.0.49 | CHANGED | rc=0 >>
root 7061 0.0 0.2 120900 2244 ? Ss 01:10 0:00 nginx: master process /usr/sbin/nginx
nginx 7063 0.0 0.3 121296 3256 ? S 01:10 0:00 nginx: worker process
nginx 7064 0.0 0.3 121296 3256 ? S 01:10 0:00 nginx: worker process
nginx 7065 0.0 0.3 121296 3256 ? S 01:10 0:00 nginx: worker process
nginx 7066 0.0 0.3 121296 3052 ? S 01:10 0:00 nginx: worker process
root 7215 0.0 0.1 113280 1204 pts/1 S+ 01:10 0:00 /bin/sh -c ps aux| grep nginx
root 7217 0.0 0.0 112828 960 pts/1 S+ 01:10 0:00 grep nginx
10.0.0.48 | CHANGED | rc=0 >>
root 7445 0.0 0.2 120900 2244 ? Ss 01:10 0:00 nginx: master process /usr/sbin/nginx
nginx 7447 0.0 0.3 121296 3052 ? S 01:10 0:00 nginx: worker process
nginx 7448 0.0 0.3 121296 3052 ? S 01:10 0:00 nginx: worker process
nginx 7449 0.0 0.3 121296 3052 ? S 01:10 0:00 nginx: worker process
nginx 7450 0.0 0.3 121296 3052 ? S 01:10 0:00 nginx: worker process
root 7580 0.0 0.1 113280 1204 pts/1 S+ 01:10 0:00 /bin/sh -c ps aux| grep nginx
root 7582 0.0 0.0 113280 188 pts/1 R+ 01:10 0:00 /bin/sh -c ps aux| grep nginx
[root@ansible ~]# cat /etc/ansible/hosts
[webserver]
10.0.0.48 http_port=81
10.0.0.49 http_port=82
[root@ansible ansible]# cd templates/
[root@ansible templates]# cat nginx.conf.j2
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes {{ ansible_processor_vcpus*4 }}; #将auto改成变量
server {
listen {{ http_port }} default_server; #将80改成变量
[root@ansible templates]# cat template.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: install package
yum: name=nginx
- name: copy template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf #推送到目标主机
notify: restart service
- name: start service
service: name=nginx state=started enabled=yes
handlers:
- name: restart service
service: name=nginx state=restarted
#更改为4个进程
[root@ansible templates]# ansible webserver -m shell -a 'ps aux| grep nginx'
10.0.0.49 | CHANGED | rc=0 >>
root 9665 0.0 0.2 120900 2244 ? Ss 01:48 0:00 nginx: master process /usr/sbin/nginx
nginx 9667 0.0 0.3 121296 3256 ? S 01:48 0:00 nginx: worker process
nginx 9668 0.0 0.3 121296 3256 ? S 01:48 0:00 nginx: worker process
nginx 9669 0.0 0.3 121296 3256 ? S 01:48 0:00 nginx: worker process
nginx 9670 0.0 0.3 121296 3048 ? S 01:48 0:00 nginx: worker process
root 9800 0.0 0.1 113280 1204 pts/1 S+ 01:48 0:00 /bin/sh -c ps aux| grep nginx
root 9802 0.0 0.0 112824 960 pts/1 R+ 01:48 0:00 grep nginx
10.0.0.48 | CHANGED | rc=0 >>
root 10378 0.0 0.2 120900 2248 ? Ss 01:48 0:00 nginx: master process /usr/sbin/nginx
nginx 10380 0.0 0.3 121296 3260 ? S 01:48 0:00 nginx: worker process
nginx 10381 0.0 0.3 121296 3260 ? S 01:48 0:00 nginx: worker process
nginx 10382 0.0 0.3 121296 3260 ? S 01:48 0:00 nginx: worker process
nginx 10383 0.0 0.3 121296 3056 ? S 01:48 0:00 nginx: worker process
root 10513 0.0 0.1 113280 1204 pts/1 S+ 01:48 0:00 /bin/sh -c ps aux| grep nginx
root 10515 0.0 0.0 112824 960 pts/1 S+ 01:48 0:00 grep nginx
[root@ansible templates]# ansible webserver -m shell -a 'ss -ntlp | grep nginx'
10.0.0.49 | CHANGED | rc=0 >>
LISTEN 0 128 *:82#已更改 *:* users:(("nginx",pid=9670,fd=6),("nginx",pid=9669,fd=6),("nginx",pid=9668,fd=6),("nginx",pid=9667,fd=6),("nginx",pid=9665,fd=6))
LISTEN 0 128 [::]:80 [::]:* users:(("nginx",pid=9670,fd=7),("nginx",pid=9669,fd=7),("nginx",pid=9668,fd=7),("nginx",pid=9667,fd=7),("nginx",pid=9665,fd=7))
10.0.0.48 | CHANGED | rc=0 >>
LISTEN 0 128 *:81 #已更改 *:* users:(("nginx",pid=10383,fd=6),("nginx",pid=10382,fd=6),("nginx",pid=10381,fd=6),("nginx",pid=10380,fd=6),("nginx",pid=10378,fd=6))
LISTEN 0 128 [::]:80 [::]:* users:(("nginx",pid=10383,fd=7),("nginx",pid=10382,fd=7),("nginx",pid=10381,fd=7),("nginx",pid=10380,fd=7),("nginx",pid=10378,fd=7))
[root@ansible templates]#
迭代:当有需要重复执行的任务时,可以使用迭代机制
- 对迭代项的引用,固定变量名为 “itrem”
- 要在task中使用with_itrems给定要迭代的元素列表
- 列表格式:
字符串
字典
YAML文件在线测试
[webserver]
10.0.0.48 http_port=81
10.0.0.49 http_port=82
[webserver:vars]
nodename=www
domainname=liming.com
[logserver]
10.0.0.49
10.0.0.54 #新建的虚拟机6已经搭好了
[root@ansible ansible]# ansible all -m setup | grep version
"ansible_bios_version": "15.1.4 (47270)",
"ansible_distribution_major_version": "6",
"ansible_distribution_version": "6.9",
"ansible_kernel_version": "#1 SMP Tue Mar 21 19:29:05 UTC 2017",
"ansible_product_version": "None",
"version": {
"version_info": [
"ansible_python_version": "2.6.6",
"ansible_bios_version": "15.1.4 (47270)",
"ansible_distribution_major_version": "7",
"ansible_distribution_version": "7.7",
"ansible_kernel_version": "#1 SMP Wed Aug 7 18:08:02 UTC 2019",
"ansible_product_version": "None",
"version": {
"version_info": [
"ansible_python_version": "2.7.5",
"ansible_bios_version": "15.1.4 (47270)",
"ansible_distribution_major_version": "7",
"ansible_distribution_version": "7.7",
"ansible_kernel_version": "#1 SMP Wed Aug 7 18:08:02 UTC 2019",
"ansible_product_version": "None",
"version": {
"version_info": [
"ansible_python_version": "2.7.5",
[root@ansible ansible]# cat testiterm.yml
---
- hosts: all
remote_user: root
tasks:
- name: create some file
file: name=/data/{{ item }} state=touch
when: ansible_distribution_major_version == "7"
with_items:
- file1
- file2
- file3
- name: install some packages
yum: name={{ item }}
with_items:
- htop
- sl
- hping3
#因为有条件判断 所以54 是6的机器 没有创建文件
[root@ansible ansible]# ansible all -m shell -a 'ls /data'
10.0.0.54 | FAILED | rc=2 >> #已经跳过54 没有文件
ls: 无法访问/data: 没有那个文件或目录non-zero return code
10.0.0.49 | CHANGED | rc=0 >>
file1 #安装了三个文件
file2
file3
vsftpd.log
web82.example.com.log
10.0.0.48 | CHANGED | rc=0 >>
file1
file2
file3
vsftpd.log
web81.example.com.log
#没有条件判断所以都安装上了
[root@ansible ansible]# ansible all -m shell -a "rpm -q htop sl hping3"
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'. If you need to use command
because yum, dnf or zypper is insufficient you can add 'warn: false' to this command task or set
'command_warnings=False' in ansible.cfg to get rid of this message.
10.0.0.54 | CHANGED | rc=0 >>
htop-1.0.3-1.el6.x86_64
sl-5.02-1.el6.x86_64
hping3-0.0.20051105-16.el6.x86_64
10.0.0.49 | CHANGED | rc=0 >>
htop-2.2.0-3.el7.x86_64
sl-5.02-1.el7.x86_64
hping3-0.0.20051105-24.el7.x86_64
10.0.0.48 | CHANGED | rc=0 >>
htop-2.2.0-3.el7.x86_64
sl-5.02-1.el7.x86_64
hping3-0.0.20051105-24.el7.x86_64
[root@ansible ansible]# cat testiterm2.yml
---
- hosts: all
remote_user: root
tasks:
- name: create some groups
group: name={{ item }}
when: ansible_distribution_major_version == "7"
with_items:
- g1
- g2
- g3
ansible all -m shell -a 'getent group'
[root@ansible ansible]# cat testiterm3.yml
---
- hosts: webserver
remote_user: root
tasks:
- name: create some groups
group: name={{ item }}
when: ansible_distribution_major_version == "7"
with_items:
- g1
- g2
- g3
- name: create some users
user: name={{item.name}} group={{item.group}}
with_items:
- { name: 'user1', group: 'g1'}
- { name: 'user2', group: 'g2'}
- { name: 'user3', group: 'g3'}
[root@ansible ansible]# cat testiterm4.yml
---
- hosts: webserver
remote_user: root
vars:
ports:
- 81
- 82
- 83
tasks:
- name: cp conf
template: src=for1.conf.j2 dest=/data/for1.conf
[root@ansible ansible]# cat templates/for1.conf.j2
{% for port in ports %}
server{
listen {{ port }} #port从yaml文件中来
}
{% endfor %}
[root@ansible ansible]# ansible webserver -m shell -a 'ls /data'
10.0.0.48 | CHANGED | rc=0 >>
file1
file2
file3
for1.conf
vsftpd.log
web81.example.com.log
10.0.0.49 | CHANGED | rc=0 >>
file1
file2
file3
for1.conf
vsftpd.log
web82.example.com.log
[root@ansible ansible]# ansible webserver -m shell -a 'cat /data/for1.conf'
10.0.0.48 | CHANGED | rc=0 >>
server{
listen 81
}
server{
listen 82
}
server{
listen 83
}
10.0.0.49 | CHANGED | rc=0 >>
server{
listen 81
}
server{
listen 82
}
server{
listen 83
}
[root@ansible ansible]# cat for2.yml
---
- hosts: webserver
remote_user: root
vars:
ports:
- listen_port: 81
- listen_port: 82
- listen_port: 83
tasks:
- name: cp conf
template: src=for2.conf.j2 dest=/data/for2.conf
[root@ansible ansible]# cat templates/for2.conf.j2
{% for port in ports %}
server{
listen {{ port.listen_port }}
}
{% endfor %}
[root@ansible ansible]# ansible webserver -m shell -a 'ls /data'
10.0.0.48 | CHANGED | rc=0 >>
file1
file2
file3
for1.conf
for2.conf
vsftpd.log
web81.example.com.log
10.0.0.49 | CHANGED | rc=0 >>
file1
file2
file3
for1.conf
for2.conf
vsftpd.log
web82.example.com.log
[root@ansible ansible]# ansible webserver -m shell -a 'cat /data/for2.conf'
10.0.0.49 | CHANGED | rc=0 >>
server{
listen 81
}
server{
listen 82
}
server{
listen 83
}
10.0.0.48 | CHANGED | rc=0 >>
server{
listen 81
}
server{
listen 82
}
server{
listen 83
}
[root@ansible ansible]# cat for3.yml
---
- hosts: webserver
remote_user: root
vars:
ports:
- web1:
port: 81
name: web1.node.com
rootdir: /data/website1
- web2:
port: 82
name: web2.node.com
rootdir: /data/website2
- web3:
port: 83
name: web3.node.com
rootdir: /data/website3
tasks:
- name: cp conf
template: src=for3.conf.j2 dest=/data/for3.conf
[root@ansible ansible]# cat templates/for3.conf.j2
{% for p in ports %}
server{
listen {{ p.port }}
servername {{ p.name }}
documentroot {{ p.rootdir }}
}
{% endfor %}
[root@ansible ansible]# ansible webserver -m shell -a 'ls /data'
10.0.0.49 | CHANGED | rc=0 >>
file1
file2
file3
for1.conf
for2.conf
for3.conf
vsftpd.log
web82.example.com.log
10.0.0.48 | CHANGED | rc=0 >>
file1
file2
file3
for1.conf
for2.conf
for3.conf
vsftpd.log
web81.example.com.log
[root@ansible ansible]# ansible webserver -m shell -a 'cat /data/for3.conf'
10.0.0.49 | CHANGED | rc=0 >>
server{
listen 81
servername web1.node.com
documentroot /data/website1
}
server{
listen 82
servername web2.node.com
documentroot /data/website2
}
server{
listen 83
servername web3.node.com
documentroot /data/website3
}
10.0.0.48 | CHANGED | rc=0 >>
server{
listen 81
servername web1.node.com
documentroot /data/website1
}
server{
listen 82
servername web2.node.com
documentroot /data/website2
}
server{
listen 83
servername web3.node.com
documentroot /data/website3
}
[root@ansible ansible]# cat for4.yml
---
- hosts: webserver
remote_user: root
vars:
ports:
- web1:
port: 81
#name: web1.node.com
rootdir: /data/website1
- web2:
port: 82
name: web2.node.com
rootdir: /data/website2
- web3:
port: 83
#name: web3.node.com
rootdir: /data/website3
tasks:
- name: cp conf
template: src=for4.conf.j2 dest=/data/for4.conf
[root@ansible ansible]# cat templates/for4.conf.j2
{% for p in ports %}
server{
listen {{ p.port }}
{% if p.name is defined %}
servername {{ p.name }}
{% endif %}
documentroot {{ p.rootdir }}
}
{% endfor %}
[root@ansible ansible]# ansible webserver -m shell -a 'ls /data'
10.0.0.48 | CHANGED | rc=0 >>
file1
file2
file3
for1.conf
for2.conf
for3.conf
for4.conf
vsftpd.log
web81.example.com.log
10.0.0.49 | CHANGED | rc=0 >>
file1
file2
file3
for1.conf
for2.conf
for3.conf
for4.conf
vsftpd.log
web82.example.com.log
[root@ansible ansible]# ansible webserver -m shell -a 'cat /data/for4.conf'
10.0.0.48 | CHANGED | rc=0 >>
server{
listen 81
documentroot /data/website1
}
server{
listen 82
servername web2.node.com
documentroot /data/website2
}
server{
listen 83
documentroot /data/website3
}
10.0.0.49 | CHANGED | rc=0 >>
server{
listen 81
documentroot /data/website1
}
server{
listen 82
servername web2.node.com
documentroot /data/website2
}
server{
listen 83
documentroot /data/website3
}
[root@ansible ansible]#
[root@ansible ansible]# cd /etc/ansible/ #官方推荐路径
[root@ansible ansible]# ls
ansible.cfg hosts roles #this
[root@ansible ansible]# ansible all -m shell -a 'getent group nginx'
[root@ansible ansible]# ansible all -m shell -a 'getent passwd nginx'
[root@ansible ansible]# ansible all -m shell -a 'userdel -r nginx' #删除
[root@ansible ansible]# pwd
/root/ansible
[root@ansible ansible]# tree
.
├── nginx_roles.yml #ansible执行的文件 要和角色目录平行
└── roles #角色目录
├── httpd
├── memcache
├── mysql
└── nginx #新建nginx角色
├── tasks #包含任务目录
│ ├── group.yml
│ ├── main.yml
│ ├── restart.yml
│ ├── start.yml
│ ├── template.yml
│ ├── user.yml
│ └── yum.yml
└── templates 包含模板目录
└── nginx.conf.j2
[root@ansible tasks]# ls
group.yml main.yml restart.yml start.yml template.yml user.yml yum.yml
[root@ansible tasks]# cat main.yml #设置启动顺序的目录
- include: group.yml
- include: user.yml
- include: yum.yml
- include: template.yml
- include: start.yml
[root@ansible tasks]# cat group.yml
- name: create group
group: name=nginx gid=80
[root@ansible tasks]# cat user.yml
- name: creat user
user: name=nginx uid=80 group=nginx system=yes shell=/sbin/nologin
[root@ansible tasks]# cat yum.yml
- name: install package
yum: name=nginx
[root@ansible tasks]# cat template.yml
- name: copy conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
[root@ansible tasks]# cat start.yml
- name: start service
service: name=nginx state=started enabled=yes
[root@ansible tasks]# cat restart.yml
- name: start service
service: name=nginx state=restarted enabled=yes
[root@ansible templates]# ls
nginx.conf.j2
[root@c7-47 ~]# ansible all -m shell -a 'getent passwd apache'
[root@c7-47 ~]# ansible all -m shell -a 'yum -y remove httpd'
[root@c7-47 ~]# ansible all -m user -a 'name=apache state=absent'
[root@c7-47 ansible]# pwd
/root/ansible
[root@c7-47 ansible]# ls
httpd_role.yml roles #playbook剧本应该和roles目录平行
[root@c7-47 ansible]# tree
.
├── httpd_role.yml #playbook文件
└── roles #角色目录
├── httpd #httpd的角色目录 playbook调用它
│ ├── files
│ │ └── httpd.conf
│ └── tasks
│ ├── copy.yml
│ ├── main.yml
│ └── user.yml
[root@c7-47 ansible]# cat roles/httpd/tasks/main.yml #定义任务使用的顺序
- include: user.yml
- include: copy.yml
[root@c7-47 ansible]# cat roles/httpd/tasks/copy.yml
- name: copy files
copy: src=httpd.conf dest=/data/ owner=apache
[root@c7-47 ansible]# cat roles/httpd/tasks/user.yml
- name: create user
user: name=apache system=yes shell=/sbin/nologin
[root@c7-47 ansible]# ansible-playbook -C httpd_role.yml
[root@c7-47 ansible]# ansible-playbook httpd_role.yml
[root@c7-47 httpd]# ansible all -m shell -a 'ls /data'
[root@c7-47 httpd]# ansible all -m shell -a 'getent passwd apache'
[root@c7-47 ansible]# tree .
.
├── httpd_role.yml
├── nginx_roles.yml
├── roles
│ ├── httpd
│ │ ├── files
│ │ │ └── httpd.conf
│ │ └── tasks
│ │ ├── copy.yml
│ │ ├── main.yml
│ │ └── user.yml
│ ├── memcache
│ ├── mysql
│ └── nginx
│ ├── tasks
│ │ ├── group.yml
│ │ ├── main.yml
│ │ ├── restart.yml
│ │ ├── start.yml
│ │ ├── template.yml
│ │ ├── user.yml
│ │ └── yum.yml
│ └── templates
│ └── nginx.conf.j2
└── some_roles.yml
[root@c7-47 ansible]# cat some_roles.yml
- hosts: webserver
remote_user: root
roles:
- role: httpd #调用两个模块
- role: nginx
[root@c7-47 ansible]# ansible-playbook some_roles.yml
[root@c7-47 ansible]# cat roles/nginx/tasks/main.yml
- include: group.yml
- include: user.yml
- include: yum.yml
- include: template.yml
- include: start.yml
- include: roles/httpd/tasks/copy.yml #使用其它任务角色时 要加路径
#调用的相对应模块也要写绝对路径
[root@c7-47 ansible]# cat roles/httpd/tasks/copy.yml
- name: copy files
copy: src=/etc/httpd/conf/httpd.conf dest=/data/ owner=apache
[root@c7-47 ansible]# cat some_roles.yml
- hosts: webserver
remote_user: root
roles:
- { role: httpd,tags: ['web','httpd']}
- { role: nginx,tags: ['web','nginx']}
- { role: app,tags: 'app' }
[root@c7-47 ansible]# ansible-playbook -t web some_roles.yml
#-t 选择相对应的标签
[root@c7-47 ansible]# cat some_role.yml
- hosts: all
remote_user: root
roles:
- { role: httpd, tags: ['web','httpd'] }
- { role: nginx, tags: ['web','nginx'],when: ansible_distribution_major_version == "7" }
- { role: app, tags: "app" }
[root@c7-47 ansible]# tree
.
├── app_role.yml
├── roles
│ ├── app
│ │ ├── files
│ │ │ └── vhosts.conf
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── copy.yml
│ │ │ ├── group.yml
│ │ │ ├── main.yml
│ │ │ ├── start.yml
│ │ │ ├── template.yml
│ │ │ ├── user.yml
│ │ │ └── yum.yml
│ │ ├── templates
│ │ │ └── httpd.conf.j2
│ │ └── vars
│ │ └── main.yml
[root@c7-47 ansible]# cat app_role.yml
- hosts: webserver
remote_user: root
roles:
- app
[root@c7-47 ansible]# cat roles/app/handlers/main.yml
- name: restart service
service: name=httpd state=restarted
[root@c7-47 ansible]# cat roles/app/tasks/copy.yml
- name: copy config
copy: src=vhosts.conf dest=/etc/httpd/conf.d/ owner=app
[root@c7-47 ansible]# cat roles/app/tasks/group.yml
- name: create group
group: name=app system=yes gid=123
[root@c7-47 ansible]# cat roles/app/tasks/main.yml
- include: group.yml
- include: user.yml
- include: yum.yml
- include: template.yml
- include: copy.yml
- include: start.yml
[root@c7-47 ansible]# cat roles/app/tasks/start.yml
- name: start service
service: name=httpd state=started enabled=yes
[root@c7-47 ansible]# cat roles/app/tasks/template.yml
- name: copy conf
template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify: restart service
[root@c7-47 ansible]# cat roles/app/tasks/user.yml
- name: create user
user: name=app group=app system=yes shell=/sbin/nologin uid=123
[root@c7-47 ansible]# cat roles/app/tasks/yum.yml
- name: install packages
yum: name=httpd
[root@c7-47 ansible]# cat roles/app/vars/main.yml
username: app
groupname: app
[root@c7-47 ansible]# ansible webserver -m shell -a 'ss -ntlp'
[root@c7-47 ansible]# ansible webserver -m shell -a 'getent passwd app'
[root@c7-47 ansible]# ansible webserver -m shell -a 'ps aux | grep app'
[root@c7-47 ansible]# ansible webserver -m shell -a 'ls /etc/httpd/conf.d'
[root@c7-47 ansible]# pwd
/root/ansible
[root@c7-47 ansible]# tree
.
├── memcache_role.yml
├── roles
│ ├── memcached
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── main.yml
│ │ │ ├── start.yml
│ │ │ ├── template.yml
│ │ │ └── yum.yml
│ │ └── templates
│ │ └── memcached.j2
[root@c7-47 ansible]# cat memcache_role.yml
- hosts: webserver
remote_user: root
roles:
- memcached
[root@c7-47 ansible]# cat roles/memcached/handlers/main.yml
- name: restart service
service: name=memcached state=restarted
[root@c7-47 ansible]# cat roles/memcached/tasks/main.yml
- include: yum.yml
- include: template.yml
- include: start.yml
[root@c7-47 ansible]# cat roles/memcached/tasks/start.yml
- name: start service
service: name=memcached state=started enabled=yes
[root@c7-47 ansible]# cat roles/memcached/tasks/template.yml
- name: copy conf
template: src=memcached.j2 dest=/etc/sysconfig/memcached
notify: restart service
[root@c7-47 ansible]# cat roles/memcached/tasks/yum.yml
- name: install packages
yum: name=memcached
[root@c7-47 ansible]# cat roles/memcached/templates/memcached.j2
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="{{ ansible_memtotal_mb//4 }}"
OPTIONS=""
验证
[root@c7-47 ansible]# ansible webserver -m shell -a 'ss -ntlp' #判断服务是否启动
[root@c7-47 ansible]# ansible webserver -m shell -a 'cat /etc/sysconfig/memcached' #查看文件 是否生效