- 模块化:调用特定的模块,完成特定任务
- 基于:
Paramiko
,PyYAML
,Jinja2
- 支持自定义模块
- 基于
Python
语言实现 - 部署简单,基于
python
和SSH(默认已安装),agentless
- 安全,基于
OpenSSH
- 支持
playbook
编排任务 - 幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况
- 无需代理不依赖
PKI
(无需ssl) - 可使用任何编程语言写模块,比如:
java
、Golang
… YAML
格式,编排任务,支持丰富的数据结构- 较强大的多层解决方案
1.0 基础配置操作
1.0.1 主机清单inventory
/etc/ansible/hosts
# 当没有加入主机清单的时候,可以采用-k选项输入用户密码进行登录.
ansible 10.1.6.87 -m ping -k
代码语言:javascript复制[webserver]
192.168.1.10[1:103] 或者 192.168.1.10[1:3] # 代表的是192.168.101~103的主机
192.168.1.101:2222 # 如果对方的默认SSH端口不是22,需要制指定默认端口
1.0.2 加速SSH访问
- 编辑
/etc/ssh/sshd_config
# 将下面的配置选项修改为no即可
UseDNS no
GSSAPIAuthentication no
GSSAPICleanupCredentials no
1.0.3 主配置文件详解
/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 # 监控
#sudo_user = root # 默认执行用户
#ask_sudo_pass = True
#ask_pass = True
#transport = smart
#remote_port = 22
#module_lang = C
#host_key_checking = False # 检查服务器对应的host_key 建议取消注释
#module_set_locale = False
log_path = /var/log/ansible.log # 开启ansible操作日志记录
2.0 Ansible命令使用
2.0.1 ansible-doc
- 显示模块帮助
ansible-doc: 显示模块帮助
ansible-doc [options] [module...]
-a 显示所有模块的文档
-l, --list 列出可用模块
-s, --snippet 显示指定模块的playbook片段(简化版,便于查找语法)
示例:
ansible-doc -l 列出所有模块
ansible-doc ping 查看指定模块帮助用法
ansible-doc -s ping 查看指定模块帮助用法
2.0.2 ansible
ansible
<host-pattern>
[-m module_name]
[-a args]
ansible <host-pattern> [-m module_name] [-a args]
ansible 被管理的主机(ALL) 模块 参数
--version 显示版本
-m module 指定模块,默认为command
-v 详细过程 –vv -vvv更详细
--list-hosts 显示主机列表,可简写 --list
-k, --ask-pass 提示输入ssh连接密码,默认Key验证
-C, --check 检查,并不执行
-T, --timeout=TIMEOUT 执行命令的超时时间,默认10s
-u, --user=REMOTE_USER 执行远程执行的用户
-b, --become 代替旧版的sudo切换
--become-user=USERNAME 指定sudo的runas用户,默认为root
-K, --ask-become-pass 提示输入sudo时的口令
2.0.3 ansible的Host-pattern
代码语言:javascript复制匹配主机的列表
All :表示所有Inventory中的所有主机
ansible all –m ping
* :通配符
ansible "*" -m ping (*表示所有主机)
ansible 192.168.1.* -m ping # 表示192.168.1.*的所有主机
ansible "*srvs" -m ping
或关系 ":"
ansible "websrvs:appsrvs" -m ping # 表示执行websrvs或appsrvs的主机清单
ansible “192.168.1.10:192.168.1.20” -m ping #
逻辑与 ":&"
ansible "websrvs:&dbsrvs" –m ping # 表示在websrvs组并且在dbsrvs组的主机才会执行
在websrvs组并且在dbsrvs组中的主机
逻辑非 ":!"
ansible 'websrvs:!dbsrvs' –m ping # 在websrvs组,但不在dbsrvs组中的主机
在websrvs组,但不在dbsrvs组中的主机
注意:此处为单引号
综合逻辑
ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' –m ping
正则表达式
ansible "websrvs:&dbsrvs" –m ping
ansible "~(web|db).*.magedu.com" –m ping
2.0.4 ansible执行过程
- 加载自己的配置文件 默认
/etc/ansible/ansible.cfg
- 加载自己对应的模块文件,如command
- 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
- 给文件 x执行
- 执行并返回结果
- 删除临时py文件,sleep 0退出
2.0.5 ansible-galaxy
代码语言:javascript复制通过连接https://galaxy.ansible.com 下载相应的roles
ansible-galaxy list # 列出已经安装的galaxy
ansible-galaxy install geerlingguy.nginx # 安装一个geerlingguy.nginx角色
ansible-galaxy remove geerlingguy.nginx # 删除
2.0.6 ansible-pull
- 推送命令至远程,效率无限提升,对运维要求相对较高
2.0.7 加密剧本
- 通过
ansible-vault encrypt
进行对剧本的加密
ansible-vault encrypt [剧本文件]
ansible-vault encrypt hello.yaml
New Vault password:
Confirm New Vault password:xxxxxxxxxx anansible-vault encrypt hello.yaml New Vault password: Confirm New Vault password:
加密的剧本不可直接运行
2.0.8 解密剧本
- 通过
ansible-vault decrypt
解密
ansible-vault decrypt hello.yaml
2.0.9 ansible-console
2.0
新加的,可以交互式执行命令- root@all (1)[f:5]$
root
:表示操作的用户all
: 表示当前要对那些主机进行操作(1)
: 表示包括几个主机[f:5]
: 并发请求数量
cd test # 进入test主机列表
forks 100 # 修改并发数
command ls /etc # 执行远程命令
hostname name=ansible2 # 用法跟命令行一样
3.0 Ansible常用模块详解
3.0.1 Command 模块
- 在远程主机执行命令,默认模块,可忽略-m选项
ansible srvs -m command -a 'service vsftpd start'
ansible srvs -m command -a 'echo adong |passwd --stdin 123456'
此命令不支持 $VARNAME < > | ; & 等,用shell模块实现 chdir: 进入到被管理主机目录 creates: 如果有一个目录是存在的,步骤将不会运行Command命令 removes: 如果一个目录不存在,则不会运行命令
3.0.2 Shell模块
Shell
:和command
相似,用shell执行命令
ansible all -m shell -a 'getenforce' # 查看SELINUX状态
ansible all -m shell -a "sed -i 's/SELINUX=.*/SELINUX=disabled' /etc/selinux/config"
ansible all -m shell -a 'echo magedu |passwd –stdin wang'
调用bash执行命令 类似 cat /tmp/stanley.md | awk -F'|' '{print 1,2}' &> /tmp/example.txt
3.0.3 Script模块
- 在远程主机上运行ansible服务器上的脚本
ansible all -m script -a /data/test.sh
3.0.4 COPY模块
- 从主控端复制文件到远程主机
src
: 源文件 指定拷贝文件的本地路径 (如果有/ 则拷贝目录内容,比拷贝目录本身)dest
: 指定目标路径mode
: 设置权限backup
: 备份源文件content
: 代替src 指定本机文件内容,生成目标主机文件owner
: 应该拥有文件系统对象的用户的名称
# 如果目标存在,默认覆盖,此处指定先备份
ansible all -m copy -a "src=/root/test1.sh dest=/tmp/test2.showner=wang mode=600 backup=yes"
# 指定内容,直接生成目标文件
ansible all -m copy -a "content='test contentnxxx' dest=/tmp/test.txt"
注意:如果两个文件的内容一样,则backup=yes不会进行备份.
3.0.5 Fetch模块
- 从客户端获取文件到服务端
- 目前不支持目录,可以先打包,再提取文件
ansible all -m fetch -a 'src=/root/test.sh dest=/data/scripts'
3.0.6 File模块
path
: 要管理的文件路径 (强制添加)recurse
: 递归,文件夹要用递归src
: 创建硬链接,软链接时,指定源目标,配合’state=link' ‘state=hard’ 设置软链接,硬链接state
: 状态absent
: 删除文件touch
: 创建一个空文件direcory
: 建立一个文件夹link
: 建立软连接
# 创建新文件
ansible all -m file -a 'path=/root/java.log state=touch'
# 创建一个目录,并且设置属主、属组、以及目录权限
ansible test -m file -a "path=/data/ state=directory owner=root group=root mode=644"
# 递归方法 recurse=yes
ansible test -m file -a "path=/data/ state=directory owner=root group=root mode=644 recurse=yes"
# 删除
ansible all -m file -a 'path=/root/java.log state=absent'
3.0.7 Hostname模块
- 管理主机名
ansible all -m hostname -a "name=app.adong.com" 更改一组的主机名
ansible 192.168.38.103 -m hostname -a "name=app2.adong.com" 更改单个主机名
3.0.8 Cron模块
- 支持时间:
minute
,hour
,day
,month
,weekday
代码语言:javascript复制注意:
name
和job
是必须添加的
# 每五分钟自动同步一次ntp时间服务器
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null' name=Synctime"
# 删除任务
ansible websrvs -m cron -a 'state=absent name=Synctime'
# 禁用任务,任务不生效
ansible websrvs -m cron -a 'minute=*/10 job='/usr/sbin/ntpdate 172.30.0.100" name=synctime disabled=yes'
3.0.9 Yum模块
- 包管理工具
- state
present
: 安装包absent
: 卸载包latest
: 如果包不是最新版本,则会进行更新
-
update_cache
: 检查是否需要更新缓存 -
validate_certs
: 是否检查SSL认证 -
disable_gpg_check
: 是否禁用gpg检查
ansible all -m yum -a 'list=httpd' # 查看程序列表
ansible all -m yum -a 'name=httpd state=present' # 安装
ansible all -m yum -a 'name=httpd state=absent' # 删除
3.1.0 Service 模块
- 用于管理服务的
state
stopped
:停止服务started
: 启动服务reloaded
: 重新加载服务restarted
: 重启服务
ansible all -m service -a 'name=httpd state=stopped' # 停止服务
ansible all -m service -a 'name=httpd state=started enabled=yes' # 启动服务,并设为开机自启
ansible all -m service -a 'name=httpd state=reloaded' # 重新加载
ansible all -m service -a 'name=httpd state=restarted' # 重启服务
3.1.1 User模块
- 用于管理用户
home
指定家目录路径system
指定系统账号group
指定组remove
清除账户shell
指定shell类型
ansible all -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'
ansible all -m user -a 'name=sysuser1 system=yes home=/app/sysuser1'
ansible all -m user -a 'name=user1 state=absent remove=yes' # 清空用户所有数据
ansible all -m user -a 'name=app uid=88 system=yes home=/app groups=root shell=/sbin/nologin password="$1$zfVojmPy$ZILcvxnXljvTI2PhP2Iqv1"' # 创建用户
ansible websrvs -m user -a 'name=app state=absent' # 不会删除家目录
3.1.2 Group模块
- 管理组模块
ansible srv -m group -a "name=testgroup system=yes" # 创建组
ansible srv -m group -a "name=testgroup state=absent" # 删除组
3.1.3 Setup模块
- 查找当前主机的变量
ansible test -m setup -a 'filter=*hostname*'
[root@bogon ~]# ansible test -m setup -a 'filter=*ipv4*'
10.1.6.171 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"10.1.6.171"
],
"ansible_default_ipv4": {
"address": "10.1.6.171",
"alias": "ens192",
"broadcast": "10.1.6.255",
"gateway": "10.1.6.254",
"interface": "ens192",
"macaddress": "00:0c:29:ee:66:b2",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "10.1.6.0",
"type": "ether"
},
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
3.1.4 get_url模块
- 通过
get_url
模块进行下载内容
[root@bogon ~]# ansible test -m get_url -a "url=http://nginx.org/download/nginx-1.23.1.tar.gz dest=/usr/nginx-1.23.1.tar.gz"
10.1.6.205 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum_dest": null,
"checksum_src": "17015c7a73ba4ec8c64c7d3a09d0c71892740a8d",
"dest": "/usr/nginx-1.23.1.tar.gz",
"elapsed": 1,
"gid": 0,
"group": "root",
"md5sum": "5cc3eeb0f866fbd2e3f4a9611837c62b",
"mode": "0644",
"msg": "OK (1104352 bytes)",
"owner": "root",
"secontext": "system_u:object_r:usr_t:s0",
"size": 1104352,
"src": "/root/.ansible/tmp/ansible-tmp-1660634222.63-2295-136850669667126/tmptku8eyyk",
"state": "file",
"status_code": 200,
"uid": 0,
"url": "http://nginx.org/download/nginx-1.23.1.tar.gz"
}
- 下载文件并且进行MD5校验: 通过
checksum:md5:xxxxx
进行md5校验
ansible test -m get_url -a "url=http://nginx.org/download/nginx-1.23.1.tar.gz dest=/usr/nginx-1.23.1.tar.gz checksum=md5:5cc3eeb0f866fbd2e3f4a9611837c62b"