Ansible自动化运维
一、Ansible安装
1. Ansible离线安装
A. RPM包下载:yumdownloader --resolve --destdir=/rhxy/ansible ansible;

B. RPM包安装:rpm -Uvh /rhxy/ansible/*.rpm --nodeps --force;
C. 版本查看:ansible --version ;

二、Ansible介绍
1. 相关文件
A. /etc/ansible/ansible.cfg:主配置文件,配置ansible工作特性;
transport:paramiko | ssh,指数据传输方式和协议,若ansible安装成功但执行报错,可以尝试使用ssh方式。
B. /etc/ansible/hosts:类似Inventory文件,列出主机清单,包含主机名和IP地址及组名等信息,后缀是.ini格式;

C. /etc/ansible/roles:存放角色的目录,每个角色是一组变量文件、任务文件、模板文件等的集合,用于定义如何在主机上执行特定的配置任务;
D. /etc/ansible/group_vars:用于定义全局变量的yml文件。
2. 相关命令
A. ansible:
B. ansible-doc:查看配置文档,模块功能查看工具;
C. ansible-playbook:执行编写好playbook任务,如:ansible-playbook -i ./hosts.ini ./rhxy.yml;
D. ansible-inventory:读取host文件内容,如获取IP: ansible-inventory --host "nginx" | grep -o '"ansible_host": "[^"]*"' | cut -d'"' -f4;
E. ansible-vault:用于加解密yml文件。
3. Playbook:提供了一个可重复、可重用、简单的配置管理和多机部署系统,非常适合部署复杂的应用程序
A. 核心元素:hosts、remote_user、tasks和action等;
4. Roles角色
A. tasks/main.yml:角色执行的主要任务列表;
B. vars/mysql.yml:角色的其他变量;
C. files/mysql.tar.gz:角色部署的文件;
D. templates/my.cnf.j2:角色部署的模板;
5. 内置变量
A. hostvars:获取某台指定的主机相关变量,如:{{ hostvars['nacos']['ansible_host'] }}
三、Ansible常用的模块
1. Stat模块:用户获取文件或目录的状态信息;
# stat模块返回的结果是一个字典,如下:
# exists:如果文件或目录存在,则为true;
# md5:获取文件的MD5值;
- name: 检查文件或目录是否存在
stat:
path: "/usr/local/nginx/nginx.conf" # 必须,要获取状态信息的文件或目录的路径
get_md5: yes # 计算文件的MD5校验和
register: installed
2. Register模块:用于捕获任务的输出,并将其存储在一个变量中,供后续的任务或条件使用;
- name: 检查文件或目录是否存在
stat:
path: "/usr/local/nginx/nginx.conf"
get_md5: yes
register: installed
# changed:任务是否改变了目标注解的状态;
# stderr:命令的标准错误输出;
- name: 打印状态
debug:
msg: {{installed.stdout}} # stdout:命令的标准输出;
when: installed.stat.exists
3. When模块:根据特定的条件来决定是否执行某个task,条件为真才会执行,在when语句中变量不需要使用{{ }};
比较运算符:> == < !=等;
逻辑运算符:and-所有条件同时满足、or-任意条件满足、not-条件取反;
正则表达式:用于匹配字符串模式。
4. File模块:创建、删除、修改文件及更改权限等;
- name: 创建安装及数据目录
file:
path: "{{ item }}" # 指定要操作的文件或目录的路径
state: directory # 指定要执行的操作,如file-文件、directory-目录、absent-删除
mode: "0755" # 设置文件或目录的权限
with_items:
- "{{ mysql_dir }}/mysql{{ mysql_version }}"
- "{{ mysql_main_dir }}/data"
- "{{ mysql_main_dir }}/log"
when: not installed.stat.exists
5. Copy模块:文件或目录的复制;
- name: 复制包及SQL文件到临时目录
copy:
src: "{{ item.src }}" # 源文件路径
dest: "{{ item.dest }}" # 目标路径
mode: 0644 # 文件权限
with_items:
- { src: "files/{{ mysql_pkg }}", dest: "/tmp/{{ mysql_pkg }}"}
- { src: "files/rhxy.sql", dest: "/tmp/rhxy.sql"}
- { src: "files/nacos.sql", dest: "/tmp/nacos.sql"}
when: not installed.stat.exists
6. Unarchive模块:将包解压缩和提取文件,支持多种压缩格式:.tar、.tar.gz、.zip等;
- name: 解压安装包
unarchive:
src: "/tmp/{{ elasticsearch_pkg }}" # 必须,将要解压缩的文件路径
dest: "{{ elasticsearch_dir }}" # 解压缩文件的目标路径,默认值是当前工作目录
remote_src: "{{ hostvars['localhost']['ansible_host'] != hostvars['mysql']['ansible_host'] }}" # src参数指定的文件是否是远程文件,yes or no
creates: "{{ elasticsearch_dir }}/packages/config" # 如果指定路径存在,则不执行解压操作,主要用于防止重复解压
extra_opts: # 额外的解压缩选项,作为字符串传递
- --transform
- 's/elasticsearch-{{ elasticsearch_version }}/packages/'
7. Template模块:用于部署模版化的文件,模板文件可以设置变量,替换时自动获取;
- name: 替换配置文件
template:
src: "{{ item.src }}" # 指定模板文件的路径,一般以.j2为后缀
dest: "{{ item.dest }}" # 指定模板文件复制到目标路径
mode: u+x # 设置目标文件的权限路径
with_items:
- { src: "my.cnf.j2", dest: "/etc/my.cnf"}
when: not installed.stat.exists
8. Shell模块:用于执行shell命令;
# args:chdir: 在执行命令前更改为指定的目录
- name: 导入SQL脚本 shell: | chmod 775 {{ mysql_dir }}/mysql{{ mysql_version }}/rhxy.sql && chmod 775 {{ mysql_dir }}/mysql{{ mysql_version }}/nacos.sql && mysql -uroot -p{{ mysql_root_password }} -e "source {{ mysql_dir }}/mysql{{ mysql_version }}/rhxy.sql; source {{ mysql_dir }}/mysql{{ mysql_version }}/nacos.sql;" when: not installed.stat.exists
9. Systemd模块:管理和控制基于systemd的系统服务,替代常用的service关键字;
# daemon_reload:是否在执行其他操作之前重新加载系统管理器配置
- name: 启动服务 systemd: name: mysqld # 必须,要管理的systemd服务单元的名称 state: started # 服务的目标状态,有started、stoped、restarted、reloaded enabled: yes # 是否启用服务开机自启 when: not installed.stat.exists
10. Wait_for模块:在继续执行之前等待一个条件成立;
- name: 服务启动成功
wait_for:
host: 0.0.0.0 # 等待可解析的主机名或IP地址
port: "{{ mysql_port }}" # 轮询的端口号
delay: 1 # 开始轮询之前等待的秒数
sleep: 3 # 在两次检查之间休眠的秒数
timeout: 120 # 等待的最大秒数
when: not installed.stat.exists
11. Lineinfile模块:确保一个特定的行在一个文件中,或者使用一个正则表达式替换一个现有的行;
- name: 设置环境变量
lineinfile:
dest: /etc/profile # 要修改的文件,关键字可以是path、dest、name等
insertafter: "{{ item.position }}" # 不匹配任何值时就将新行插入到最后一行的后面,EOF代表文件的末尾
line: "{{ item.value }}" # 要插入或者替换的行
state: present # 设置新增或替换一行、还是删除行,如present、absent-删除
with_items:
- { position: EOF, value: "export JAVA_HOME={{ jdk_dir }}/jdk{{ jdk_version }}" }
- { position: EOF, value: "export PATH=$JAVA_HOME/bin:$PATH" }
when: not installed.stat.exists
12. Loop模块:循环执行,可以避免模代码块重复臃肿,替代with_items关键字(低版本使用),对迭代项的引用变量固定为"item"。
- name: 删除临时文件
file:
path: "{{ item }}"
state: absent
loop:
- "/tmp/{{ elasticsearch_pkg }}"
- "/tmp/run.sh"
when: not installed.stat.exists
13. User模块:用于管理用户,可以创建、删除和修改用户属性;
- name: 创建用户
user:
name: elasticsearch # 要管理用户的名称
create_home: no # 不用创建用户的家目录
state: present # 用户的目标状态,present-新建用户、absent-删除用户
when: not installed.stat.exists
14. Sysctl模块:设置内核参数;
- name: 修改sysctl参数
sysctl:
name: vm.max_map_count # 变量名
value: 262144 # 值
state: present # present-设置、absent-删除
reload: yes # 执行sysctl -p生效配置
when: not installed.stat.exists
15. Firewalld模块:管理系统上防火墙服务;
- name: 检查firewalld状态
systemd:
name: firewalld
register: service
- name: 开放端口
firewalld:
port: "{{ mysql_port }}/tcp" # 要管理的端口及协议,如:3306/tcp
permanent: yes # 指定规则是否永久生效
state: enabled # 指规则的状态,enabled-启用规则、disabled-禁用规则
immediate: yes # 是否自动重载防火墙来生效配置
when: service.status.ActiveState == "active" # 当防火墙开启时才需要添加规则
四、常见错误
1. 拷贝模板时报错:AnsibleError: template error while templating string: Missing end of comment tag.
原因:Shell脚本中的{#和jinja中的语法comment tag相同,而且只有一半,导致无法渲染导致;
解决办法:在有语法冲突的地方使用组合标签{% raw %} 、{% endraw %}包裹起来,例如:

2. 服务进程无法启动,但是手动执行可以
解决办法:后台启动,加上nohup sh ./start.sh &

浙公网安备 33010602011771号