一,ansible概述
- Ansible基本概述
Ansible是一个IT自动化的配置管理工具(python开发,基于ssh远程服务批量管理主机),自动化主要体现在Ansible集成了丰富模块,丰富的功能组件, 可以通过一个命令行完成一系列的操作。进而能减少我们重复性的工作和维护成本,以提高工作的效率。
2.Ansible的功能
1)批量执行远程命令,可以对N多台主机同时进行命令的执行 2)批量配置软件服务,可以进行自动化的方式配置和管理服务。3)实现软件开发功能,jumpserver底层使用ansble来实现的自动化管理 4)编排高级的IT任务,Ansible的playbook是一门编程语言,可以用来描绘一套IT架构。
3.Ansible的特点
1.容易学习,无代理模式,不像saltstack既要学服务端又要学习客户端,还要学习服务端与客户端之间的通讯协议 2.操作灵活,体现在Ansible有较多的模块,提供了丰富的功能,playbook则提供了类似于编程语言的复杂功能 3.简单易用,体现在Ansible —个命令可以完成很多事情 4.安全可靠,因为Ansible使用了SSH协议进行通汛,既稳定又安全 5.可移植性高,可以将写好的playbook拷贝至任意机器进行执行
介绍Ansible原理?
ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块
ansible只提供一种框架。ansible这个框架主要包含以下功能:
(1)连接插件connection plugins:负责和被监控端事先通信; (2)host inventory:操作主机清单; (3)核心引擎:ansible (4)借助与插件完成记录日志邮件等功能; (5)Playbook:剧本执行多个任务时,非必须可以让节点一次性运行多个任务。
4.任务执行模式
- ad-hoc:这个模式支持执行单个模块,支持批量执行单条命令。
- playbook:可以把多个你想要执行的任务放到一个playbook当中,通过这多个任务可以完成一个总体的目标
PS :Ansible优势…
Redhat企业版—> Centos 开源 红帽企业版->CentOS开源saltstack 并行 (CS结构) ansible 串行
准备工作
安装ansible
yum install ansible -y
创建项目目录
mkdir /ansble_adhoc/ && cd ``/ansble_adhoc/
创建配置文件及主机清单文件:
/ansble_adhoc/
├── ansible.cfg #配置
└── hosts (ini,yml多种格式编写) #主机清单配置
./ansible.cfg | ./hosts(ini格式) |
---|---|
[defaults] inventory = ./hosts |
[webservers] web1 ansible_ssh_host=172.16.1.7 web2 ansible_ssh_host=172.16.1.8 [client] |
ssh-keygen -C 123@mail
生成秘钥对 ssh-copy-id user@ip
#被控端检查 cat ~/.ssh/authorized_keys
检验对端公钥信息
ansible webservers -m ping
执行ansible ad-hoc 测试 是否能与该清单定义的节点通讯
cat /server/scripts/distribute_pub_key.sh
#!/bin/bash
for ip in 5 6 7 8 9 31 41 51 52 61 62 71
do
sshpass -p123456 ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.$ip -o StrictHostKeyChecking=no &>/dev/null
if [ $? -eq 0 ]
then
echo "host 172.16.1.$ip distribute_pub_key ok."
else
echo "host 172.16.1.$ip distribute_pub_key failed."
fi
done
----------------------
#!/bin/bash
#检查脚本
vim /server/scripts/check_pub_key.sh
#!/bin/bash
for ip in 7 31 41
do
ssh root@172.16.1.$ip hostname
done
*配置文件优先级
$ANSIBLE_CONFIG--->> 查看当前环境变量 然后指向这个环境所在的ansible.cfg
优先一 ./ansible.cfg
优先二 ~/.ansible.cfg
优先三 /etc/ansible/ansible.cfg (最后匹配)
-i 目标主机列表可以指定任意位置的hosts,建议使用目录下的创建配置
二,Ansible Inventory 主机清单定义连接形式
1.如何定义主清单
1.基于密码的方式 #多个主机都需要密码方式连接
情况一: 密码 端口 用户 不统一---手敲
[webservers]
172.16.1.31 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='123456' #尽量不使用明文
情况二: 密码 端口 用户 都是统一
[web]
web01 ansible_host=172.16.1.7
web02 ansible_host=172.16.1.8
[web:vars] #固定格式: 配置了一些内置变量参数
ansible_port=52113 #可以指定远程服务端口信息
ansible_password=123456 #可以指定连接主机地址
ansible_user=root #可以指定以什么用户身份远程管理 了解
ansible_password: #可以指定密码信息
--------------------------------------
2.基于秘钥的方式(默认)
[webservers]
172.16.1.31
[webservers]
172.16.1.31 hostname=nfs
172.16.1.7 hostname=web01
172.16.1.8 hostname=web02
[webservers] (较多:生产环境中IP地址难记,配置hosts解析又时闲麻烦)
web01 ansible_ssh_host=172.16.1.7
web02 ansible_ssh_host=172.16.1.8
web01 ansible_host=172.16.1.9
--------------------------------------
3.其他类写法
采用匹配方式进行配置
[webservers]
www[01:50].example.com
[web]
172.16.1.[10:20]
[databases]
db-[a:f].example.com
--------------------------------------
2.配置主机子组方式
[webstatic]
web01
web02
[webdynamic] ansible
web03
web04
[websum:children] #固定写法,老板管马仔。马仔管小弟
web-static
web-dynamic
...
Ps** 远程管理问题:**
1) 确认远程管理的主机名称是否做了解析 OK
2) 远程管理主机是否实现秘钥连接 OK
补充:** 远程连接主机设置密文密码 -yaml格式的主机清单** (ansible-vault参考资料)
第一个里程:需要生成密文信息
ansible-vault encrypt_string 123456
第二个里程:编写yaml格式主机清单
# cat hosts.yml
all:
hosts:
backup:
vars:
ansible_host: "172.16.1.41"
ansible_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
64366339306666353263336565656663343731653038623639303166306664376534333263373764
3331633962373066363231316337313831633634356362380a376339316263626237316132373966
31623430623535396661316563383630343033666534336435653063383937333363626664356466
3763633739653235370a613034313631363661656665313135326461393439356261313832306365
6561
第三个里程:测试yaml主机清单功能作用
ansible backup -m ping -i /etc/ansible/hosts.yml --ask-vault-pass ---交互进行管理, 需要输入保险库密码
echo oldboy123 >pwdfile.txt
ansible backup -m ping -i /etc/ansible/hosts.yml --vault-id pwdfile.txt ---免交互进行管理, 无需输入保险库密码
ansible all -i localhost, -m debug -a “msg={{ ‘123456’ | password_hash(‘sha512’, ‘diy-word’) }}”
练习:
1.创建一个项目目录
2.在该项目下创建ansible.cfg、hosts
3.ansible —version 查看加载的是哪个配置文件
4.最后在该目录下执行ansible webservers -m ping -i /etc/ansible/hosts 检测
Ansible-必会命令
#ansible命令使用说明
/usr/bin/ansible #命令行加载模块功能 命令执行实现批量管理
-i INVENTORY --- 加载指定hosts.资产清单文件
-m MODULE_NAME --- 加载指定模块信息
-a MODULE_ARGS --- 加载指定模块参数信息
/usr/bin/ansible-playbook #剧本中加载模块功能 脚本执行实现批量管理
-e EXTRA_VARS --- 用于指定剧本变量信息
-C, --check --- 模拟执行剧本功能
--syntax-check --- 测试剧本语法规范
--skip-tags SKIP_TAGS --- 跳过指定标记功能
-t TAGS --- 关注指定标记信息
/usr/bin/ansible-doc #ansible程序帮助命令 #/EX 可以看详细示例
-l --- 列表显示ansible所有模块信息3380多个模块
-s --- 显示模块详细参数信息 #可以看示例
三,Ansible Ad-Hoc [playbook基础]
临时命令,执行完即结束,并不会保存。 场景: 比如查看多个机器的某个进程是否启动,将某个文件拷贝到多个机器中。
ansible webserbers -m 模块 -a ‘动作’ [root@manager ansible_adhoc]# ansible webservers -m command -a ‘df -h’
提示: 绿色:正常 黄色:被控端发生了更改 红色:报错
1. ad-hoc模块:[官方手册]
*1.1 建议使用ansible-doc module /EX —-> 查看使用说明
常用模块
命令 | command(不支持管道) shell(常用于单条ansible命令) |
---|---|
安装 | yum |
配置 | copy |
启动 | systemd |
挂载 | mount |
定时 | cron |
用户 | user |
防火墙 | selinux |
yum模块
- name: yum module example
yum:
name: #要安装软件的包名称
state: #安装最新版本的软件包
state:
latest
absent 移除软件包
present 安装软件包
exclude 排除某些软件包( 更新大量的软件包,而某些软件不需要更新的时候)
enablerepo 指定使用某个仓库获取软件
disablerepo 不从哪个仓库获取软件
- name: xxx xxx play中相当于模块的注释信息
示例一、安装当前最新的Apache软件,如果存在则不安装ansible webservers -m yum -a "name=httpd state=present"
示例二、安装当前最新的Apache软件,通过epel仓库安装ansible webservers -m yum -a "name=httpd state=present enablerepo=epel"
示例三、通过公网URL安装rpm软件ansible webservers -m yum -a "name=https://mirror.tuna.tsinghua.edu.cn/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-agent-5.0.0-1.el7.x86_64.rpm state=present"
示例四、安装最新版本的Apache软件,如果存在则更新Apacheansible webservers -m yum -a "name=httpd state=latest"
示例五、更新所有的软件包,但排除和kernel相关的ansible webservers -m yum -a "name=* state=latest exclude=kernel"
示例六、删除Apache软件ansible webservers -m yum -a "name=httpd state=absent"
group模块
- name: ugroup module example
group: #创建用户组
name: somegroup
state: present #present、absent
示例一:[root@manager ansible_adhoc]# ansible webservers -m group -a "name=www gid=666 state=present"
user模块
(创建一个用户,先使用group模块)
- name: user module example
user:
name: #用户名称
uid: #uid
group:#指定组
groups:#指定附加组 append = yes
shell: #指定登陆shell
create_home: #创建用户家目录
state: present #创建 absent #删除 remove: #移除用户相关的文件
[root@manager ansible_adhoc]# ansible webservers -m user -a "name=www uid=666 create_home=no shell=/no/login group=www state=present"
copy模块
(管理配置模块)
- name: copy module example
copy:
src: # 控制端所在的文件路径
dest: # 拷贝到被控端的哪个目录下
owner: # 属主
group: # 属组
mode: # 权限
backup # 备份
content # 填充一个内容
emote_src: yes将远程主机进行copy
[root@manager ansible_adhoc]# ansible webservers -m copy -a "src=./exports.j2 dest=/etc/exports owner=root group=root mode=644"
[root@manager ansible_adhoc]# ansible webservers -m copy -a "src=./exports.j2 dest=/etc/exports owner=root group=root mode=644 backup=yes"
[root@manager ansible_adhoc]# ansible webservers -m copy -a "content="http-test" dest=/tmp/1.txt"
nfs的配置 文件: [root@manager ansible_adhoc]# vim ./exports.j2 /data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666) [root@manager ansible_adhoc]# ansible webservers -m copy -a “src=./exports.j2 dest=/etc/exports owner=www group=www mode=644 backup=yes”
示例一、创建test用户、uid为555
[root@manager ansible_adhoc]# ansible webservers -m user -a "name=test uid=555"
示例二、移除test用户,同时移除家目录
[root@manager ansible_adhoc]# ansible webservers -m user -a "name=test uid=555 state=absent remove=yes"
示例三、创建jsm用户,为其添加123作为登录密码,并且创建家目录
ansible localhost -m debug -a "msg={{ '123' | password_hash('sha512', 'salt') }}"
ansible webservers -m user -a 'name=jsm password="$6$salt$jkHSO0tOjmLW0S1NFlw5veSIDRAVsiQQMTrkOKy4xdCCLPNIsHhZkIRlzfzIvKyXeGdOfCBoW1wJZPLyQ9Qx/1" create_home=yes'
file模块
( 创建文件或、目录、授权 )
- name: file module example
file:
src: #源文件(如果做软链接就是远程机器上的文件)
dest: #目标文件(如果做软链接就是远程机器上的链接文件)
path: #路径/文件
owner: #文件或目录的属主
group: #文件或目录的属组
mode: #文件或目录的权限
state:
link #软链接
touch #创建文件
directory #创建目录
absent #删除
recurse: #递归操作
如何支持删除目录下的所有内容,但不删除目录本身: https://www.jb51.net/article/163748.htm
unarchive模块
(解压包到被控端…)
- name: unarchive module example
unarchive:
dest: 远程绝对路径,档案应该被解压缩
exec: 列出需要排除的目录和文件
src: 指定源
creates: 一个文件名,当它已经存在时,这个步骤将不会被运行。
mode 设置解压后数据权限
remote_src: yes 将远程主机压缩文件进行解压 | no 默认将本地主机压缩文件进行解压 将解压后数据传输到指定路基下
creates:一个文件名,当它已经存在时,这个步骤将不会被运行
mode:设置解压缩后的文件权限
exec:列出需要排除的目录和文件
owner:解压后文件或目录的属主
group:解压后的目录或文件的属组
systemd | service模块
- name: systemctl module example
systemd:
name: #启动的服务名称
state: #状态 |started# 启动 |stopped #停止 |restarted #重启 |reloaded #重载|
enabled # 开机自启 yes |no 关闭开机自启|
案例一:
启动nfs服务,并加入开机自启动
[root@manager ansible_adhoc]# ansible webservers -m systemd -a "name=nfs state=started enabled=yes"
案例二: 停止nfs服务
[root@manager ansible_adhoc]# ansible webservers -m systemd -a "name=nfs-utils state=stopped enabled=yes"
mount模块
- name: mount module example
mount:
src: #设备| nfs|磁盘| 光盘 /dev/sda1
path: #被控端要挂载的目录 /data
fstype: nfs,xfs
opts: ro,noauto defaults
state: mounted: 挂载设备,并加入开机自启动* |
absent: 卸载设备,会清除/etc/fstab* |
present: 写入fstab,不立即生效 |
unmounted: 卸载,不会清除/etc/fstab |
remounted: 重新在挂载一次
showmount -e 172.16.1.xx
172.16.1.7 /data | 挂载到 172.16.1.31 /opt |
---|---|
172.16.1.8 /data | 挂载到 172.16.1.31 /mnt |
[root@manager ansible_adhoc]# ansible client -m mount -a "src=172.16.1.7:/data path=/opt fstype=nfs opts=defaults state=mounted"
[root@manager ansible_adhoc]# ansible client -m mount -a "src=172.16.1.8:/data path=/mnt fstype=nfs opts=defaults state=mounted"
get_url 模块
(联网下载)
- name: Download modules example
get_url:
url: http://example.com/path/file.conf #连接地址
dest: /etc/foo.conf #存放目标目录
mode: '0644' #权限
如何持久化
- 写入脚本
- 写入剧本
nfs_server_client.sh
ansible webservers -m yum -a "name=nfs-utils state=present"
ansible webservers -m copy -a "src=./exports.j2 dest=/etc/exports owner=root group=root mode=644"
ansible webservers -m group -a "name=www gid=666 state=present"
ansible webservers -m user -a "name=www uid=666 create_home=no shell=/no/login group=www state=present"
ansible webservers -m file -a "path=/data state=directory owner=www group=www mode=755 recurse=yes"
ansible webservers -m systemd -a "name=nfs-utils state=started enabled=yes"
挂载
ansible client -m mount -a "src=172.16.1.7:/data path=/opt fstype=nfs opts=defaults state=mounted"
ansible client -m mount -a "src=172.16.1.8:/data path=/mnt fstype=nfs opts=defaults state=mounted"
四,出现的问题:
无法通讯
公钥没有推送到对应的节点
目录没有权限
无法远程挂载:
systemctl status nfs
● nfs-server.service - NFS server and services
Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; disabled; vendor preset: disabled)
Active: inactive (dead)
①单个节点:systemctl start nfs ansible: ansible webservers -m systemd -a “name=nfs state=started enabled=yes”)
在查看nfs状态 systemctl status nfs
②exports配置错误导致的重启失败
其他正常挂载是夯主:systemctl status firewalld 防火墙没关