Linux运维7.2——ansible
Linux运维7.2
ansible
概念
Ansible 是什么
Ansible 是一款开源、无代理(agentless) 的自动化运维工具,使用 Python 开发;
可以实现:批量远程执行命令、配置管理、应用部署、持续交付、编排任务。
核心特点:不需要在被管理机器安装客户端,依托 SSH 通信。
核心架构组成
1. 控制节点(Control Node)
运行 ansible 的服务器,只需要一台;
所有任务从控制节点发起,依赖:Python、OpenSSH。
2. 被管理节点(Managed Node / 被控主机)
被批量操作的服务器;
只需满足:开启 SSH、自带 Python(绝大多数 Linux 默认具备)。
3. Inventory 主机清单
定义所有被控主机列表,Ansible 知道要操作哪些机器。
默认文件:/etc/ansible/hosts
支持分组、变量、主机别名、动态清单。
示例:
[web]
192.168.1.10
192.168.1.11
[db]
192.168.1.20
4. Module 模块
Ansible 的最小执行单元,相当于一条条封装好的功能函数。
-
执行单条命令:
ansible 主机 -m 模块名常见模块:
command/shell/copy/file/yum/apt/service/user
command:不支持管道;shell:支持管道、特殊符号
5. Ad-hoc 临时命令
一次性执行的简短命令,适合简单批量操作,不保存任务。
示例:
ansible web -m shell -a "df -h"
6. Playbook 剧本
使用 YAML 语言编写的任务文件,批量编排多步骤任务,可以持久保存、重复执行。
- Play:定义对哪一组主机执行任务
- Task:一个个要执行的动作(调用模块)
简易结构:
- name: 部署nginx
hosts: web
tasks:
- name: 安装nginx
yum: name=nginx state=present
- name: 启动服务
service: name=nginx state=started enabled=yes
7. Role 角色
Playbook 的规范化封装,用于复用、模块化大型项目。
固定目录结构,把变量、任务、模板、文件分离;多套环境直接调用 role,企业主流用法。
8. Facts 资产信息
Ansible 连接主机后自动采集的主机信息:CPU、内存、IP、系统版本等;
可以直接在 playbook 中作为变量引用。
9. Handler 处理器
只有当 changed 状态触发 才执行的任务,多用于服务重启。
例如:配置文件修改后,才执行重启 nginx。
10. Template 模板
基于 Jinja2 模板语法的配置文件,可以写入变量,推送至远端主机。后缀一般 .j2。
核心通信原理
控制节点 → SSH → 被控节点
- 控制节点生成临时 Python 脚本
- 通过 SSH 传输到远端
- 远端执行脚本并返回结果
- 执行完毕自动删除临时脚本
三种返回状态
ok:成功,没有发生变更changed:成功,主机资源发生修改(安装软件、修改文件)failed:执行失败
简单区分概念
- Ad-hoc:临时单行命令(一次性)
- Playbook:yaml 脚本,多任务流程
- Role:标准化打包的 playbook,方便复用
- Inventory:管理主机名单
- Module:实际干活的功能单元
安装配置
yum 安装
- 配置EPEL网络yum源
[root@ansible ~]# yum install -y epel-release
- 安装ansible
[root@ansible ~]# yum install ansible -y
pip 安装
[root@ansible ~]# yum install python-pip
[root@ansible ~]# pip install ansible
激活配置文件
[root@server1 ~]# cat /etc/ansible/ansible.cfg

[root@server1 ~]# ansible-config init --disabled > ansible.cfg
配置文件生成
[root@server1 ansible]# vim /etc/ansible/ansible.cfg

Inventory 主机清单配置文件
[root@server1 ansible]# vim /etc/ansible/hosts

查看主机配置信息
[root@server1 ansible]# ansible-inventory --graph

Ansible 命令
主机连通
[root@server ~]# ansible web -m ping
注意需要免密配置或者主机之间至少远程连接过一次

command模块
示例——获取主机名


file模块
增加文件
ansible rocky9 -a 'touch /tmp/test.txt'

删除文件
ansible rocky9 -a 'rm -f /tmp/test.txt'

创建目录
[root@server ~]# ansible web -m file -a 'path=/data/app state=directory'
创建链接文件
path=链接文件
src=源文件
[root@server ~]# ansible web -m file -a 'path=/data/bbb.jpg src=aaa.jpg state=link'
copy模块
src #被复制到远程主机的本地文件。可以是绝对路径,也可以是相对路径。如果路径是一个目录,则会递 归复
制,用法类似于"rsync"
content #用于替换"src",可以直接指定文件的内容
dest #必选项,将源文件复制到的远程主机的**绝对路径**
backup #当文件内容发生改变后,在覆盖之前把源文件备份,备份文件包含时间信息
directory_mode #递归设定目录的权限,默认为系统默认权限
force #当目标主机包含该文件,但内容不同时,设为"yes",表示强制覆盖;设为"no",表示目标主机的 目标
位置不存在该文件才复制。默认为"yes"
others #所有的 file 模块中的选项可以在这里使用
复制文件
[root@server ~]# ansible web -m copy -a 'src=~/hello dest=/data/hello'
给定内容生成文件,并制定权限
[root@server ~]# ansible web -m copy -a 'content="I am keer\n" dest=/data/name mode=666'
覆盖
[root@server ~]# ansible web -m copy -a 'content="I am keerya\n" backup=yes dest=/data/name mode=666'
fetch模块
该模块用于从远程某主机获取(复制)文件到本地。
dest #用来存放文件的目录
src #在远程拉取的文件,并且必须是一个file,不能是目录
cron模块
用于管理cron计划任务的。
day # 日应该运行的工作( 1-31, *, */2, )
hour # 小时 ( 0-23, *, */2, )
minute # 分钟( 0-59, *, */2, )
month # 月( 1-12, * , */2, )
weekday # 周 ( 0-6 for Sunday-Saturday,, )
job # 指明运行的命令是什么
name # 定时任务描述
reboot # 任务在重启时运行,不建议使用,建议使用special_time
special_time # 特殊的时间范围,参数:reboot(重启时),annually(每年),monthly(每月),weekly (每周),
daily(每天),hourly(每小时)
state # 指定状态,present表示添加定时任务,也是默认设置,absent表示删除定时任务
user # 以哪个用户的身份执行
yum模块
name #所安装的包的名称
state #present--->安装, latest--->安装最新的, absent---> 卸载软件。
update_cache #强制更新yum的缓存
conf_file #指定远程yum安装时所依赖的配置文件(安装本地已有的包)。
disable_pgp_check #是否禁止GPG checking,只用于`present`or `latest`。
disablerepo #临时禁止使用yum库。 只用于安装或更新时。
enablerepo #临时使用的yum库。只用于安装或更新时。
service模块
arguments #命令行提供额外的参数
enabled #设置开机启动。 =yes/true 开机自启 ; =no/flase 开机关闭
name #服务名称
runlevel #开机启动的级别,一般不用指定。
sleep #在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。(定义在剧本中。)
state #有四种状态,分别为:#started--->启动服务
#stopped--->停止服务
#restarted--->重启服务
#reloaded--->重载配置
user模块
comment # 用户的描述信息
createhome # 是否创建家目录
force # 在使用state=absent时, 行为与userdel –force一致.
group # 指定基本组
groups # 指定附加组,如果指定为(groups=)表示删除所有组
home # 指定用户家目录
move_home # 如果设置为home=时, 试图将用户主目录移动到指定的目录
name # 指定用户名
non_unique # 该选项允许改变非唯一的用户ID值
password # 指定用户密码
remove # 在使用state=absent时, 行为是与userdel –remove一致; remove=yes //删除干净
shell # 指定默认shell
system # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
uid # 指定用户的uid
group模块
gid #设置组的GID号
name #指定组的名称
state #指定组的状态,默认为创建,设置值为absent为删除
system #设置值为yes,表示创建为系统组
script模块
该模块用于将本机的脚本在被管理端的机器上运行。
[root@server ~]# vim /tmp/df.sh
#!/bin/bash
date >> /tmp/disk_total.log
df -lh >> /tmp/disk_total.log
[root@server ~]# chmod +x /tmp/df.sh
setup模块
该模块主要用于收集信息,是通过调用facts组件来实现的。
facts组件是Ansible用于采集被管机器设备信息的一个功能,我们可以使用setup模块查机器的所有facts信息,可以使用filter来查看指定信 息。整个facts信息被包装在一个JSON格式的数据结构中,ansible_facts是最上层的值。
facts就是变量,内建变量 ,每个主机的各种信息,cpu颗数、内存大小等。会存在facts中的某个变量中。调用后返回很多对应主机的信 息,在后面的操作中可以根据不同的信息来做不同的操作。如redhat系列用yum安装,而debian系列用apt来安装软件。
lineinfile
功能:修改或删除文件内容,与系统中的 sed 命令类似;
主要参数如下:
path #指定要操作的文件
regexp #使用正则表达式匹配对应的行
line #修改为新的内容
insertafter #将文本插入到“指定的行”之后
insertbefore #将文本插入到“指定的行”之前
state #删除对应的文本时,需要state=absent
backrefs #1.支持后向引用、2.当未匹配到内容则不操作文件
backup #是否在修改文件之前对文件进行备份
create #当要操作的文件并不存在时,是否创建对应的文件
Ansible Playbook
示例——httpd
---
- hosts: web
become: yes
tasks:
- name: Install the Apache
ansible.builtin.yum:
name: httpd
state: present
- name: Start service httpd, if not started
ansible.builtin.service:
name: httpd
state: started
enable: yes
- name: creat index.html
ansible.builtin.copy:
content: "www.westos.org\n"
dest: /var/www/html/index.html

测试运行
[devops@server1 ansible]$ ansible-playbook apache.yml

[devops@server1 ~]$ curl server2

示例——返回httpd网页内容
---
- hosts: lamp
become: yes
tasks:
- name: Install the Apache
ansible.builtin.yum:
name: httpd
state: present
- name: Start service httpd, if not started
ansible.builtin.service:
name: httpd
state: started
enabled: yes
- name: creat index.html
ansible.builtin.copy:
content: "{{ ansible_hostname }}\n"
dest: /var/www/html/index.html
- name: Ensure the default Apaceh port is 80
ansible.builtin.lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: '^Listen'
insertafter: '^#Listen'
line: Listen 80
notify: restart service httpd
handlers:
- name: restart service httpd
ansible.builtin.service:
name: httpd
state: restarted
- hosts: localhost
gather_facts: false
become: false
tasks:
- name: Check that you can connect (GET) to a page and it returns a status 200
ansible.builtin.uri:
url: http://192.168.234.162 return_content: true
register: result
- name: Print return information from the previous task
ansible.builtin.debug:
var: result

示例——keepalived
[devops@server1 root]$ cd /home/devops/ansible/
[devops@server1 ansible]$ sudo vim /etc/ansible/hosts
[hacluster]
192.168.234.161 state=MASTER pri=100
192.168.234.162 state=BACKUP pri=80[hacluster:vars]
interface=eth0
router_id=61
vip=192.168.234.200

[devops@server1 ansible]$ vim keepalived.yml
---
- hosts: hacluster
#become: yes
tasks:
- name: Install the keepalived
ansible.builtin.yum:
name: keepalived
state: present
- name: configure the keepalived
ansible.builtin.template:
src: keepalived.conf.j2
dest: /etc/keepalived/keepalived.conf
notify: restart service keepalived
- name: Start service kepalived
ansible.builtin.service:
name: keepalived
state: started
enabled: yes
handlers:
- name: restart service keepalived
ansible.builtin.service:
name: keepalived
state: restarted

[devops@server1 ansible]$ yum install -y keepalived.x86_64
[devops@server1 ansible]$ cd
[devops@server1 ~]$ cd /etc/keepalived/
[devops@server1 keepalived]$ ls
keepalived.conf
[devops@server1 keepalived]$ cp keepalived.conf /home/devops/ansible/
[devops@server1 keepalived]$ cd /home/devops/ansible/
[devops@server1 ansible]$ ls
apache.yml keepalived.conf keepalived.yml
[devops@server1 ansible]$ mv keepalived.conf keepalived.conf.j2
[devops@server1 ansible]$ vim keepalived.conf.j2
[devops@server1 ansible]$sudo ansible-playbook keepalived.yml
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}vrrp_instance VI_1 {
state {{ state }}
interface {{ interface }}
virtual_router_id {{ router_id }}
priority {{ pri }}
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
{{ vip }}
}
}

运行
[devops@server1 ansible]$ ansible-playbook keepalived.yml

测试
[devops@server1 ansible]$ ip a

示例——批量创建用户
[devops@server1 ansible]$ vim user.yml
---
- hosts: db
tasks:
- name: Add the user
ansible.builtin.user:
name: "{{ item.user }}"
password: "{{ item.pass | password_hash('sha512') }}"
state: present
loop:
- {user: user1, pass: pass1}
- {user: user2, pass: pass2}

运行
[devops@server1 ansible]$ ansible-playbook user.yml

[root@node1 ~]# cat /etc/shadow

示例——结合haproxy
[devops@server1 ansible]$ vim hosts

[devops@server1 ansible]$ vim haproxy.yml
---
- hosts: haproxy,webservers
become: yes
tasks:
- name: deploy haproxy
block:
- name: Install the haproxy
ansible.builtin.yum:
name: haproxy
state: present
- name: configure the haproxy
ansible.builtin.template:
src: haproxy.cfg.j2
dest: /etc/haproxy/haproxy.cfg
notify: restart service haproxy
- name: Start service haproxy
ansible.builtin.service:
name: haproxy
state: started
enabled: yes
when: ansible_hostname == 'server1'
- name: deploy apache
block:
- name: Install the Apache
ansible.builtin.yum:
name: httpd
state: present
- name: Start service httpd
ansible.builtin.service:
name: httpd
state: started
enabled: yes
- name: creat index.html
ansible.builtin.copy:
content: "{{ ansible_hostname }}\n"
dest: /var/www/html/index.html
- name: Ensure the default Apaceh port is {{ http_port }}
ansible.builtin.template:
src: httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
notify: restart service httpd
when: ansible_hostname in groups['webservers']
handlers:
- name: restart service haproxy
ansible.builtin.service:
name: haproxy
state: restarted
- name: restart service httpd
ansible.builtin.service:
name: httpd
state: restarted

运行测试
[devops@server1 ansible]$ ansible-playbook haproxy.yml



更多推荐
所有评论(0)