🔜什么是Ansible?🔚

Ansible 是一款 IT 自动化工具。主要应用场景有配置系统、软件部署、持续发布及不停服平滑滚动更新的高级任务编排。

Ansible 提供开源自动化,可降低复杂性并在任何地方运行。使用 Ansible 可以自动执行几乎任何任务。

架构

Ansible:Ansible核心程序。
HostInventory:记录由Ansible管理的主机信息,包括端口、密码、ip等。
Playbooks:“剧本”YAML格式文件,多个任务定义在一个文件中,定义主机需要调用哪些模块来完成的功能。
CoreModules核心模块,主要操作是通过调用核心模块来完成管理任务。
CustomModules:自定义模块,完成核心模块无法完成的功能,支持多种语言。
ConnectionPlugins:连接插件,Ansible和Host通信使用

Ansible重要概念

控制节点

控制节点是运行 Ansible Ansible CLI 工具 的机器。它负责与受控节点(被管理节点)进行通信,发出命令并执行任务。

受控节点(被管理节点)

也称为“主机”,这些是用 Ansible 管理的目标设备。Ansible控制节点会在这些机器上执行任务。受控节点不需要安装任何代理。

库存 (Inventory)

包含要管理的目标主机或节点的清单。它是 Ansible 用来定义目标主机信息的配置文件,支持静态或动态的主机清单。它还用于分配组,这既允许在剧集中选择节点,也允许批量分配变量。

剧本(Playbook)

Playbook 是 Ansible 配置管理的核心部分,是一组用于自动化执行任务的 YAML 文件。Playbook 可以执行多个步骤(例如安装软件、启动服务等),并定义执行顺序、任务等。

模块 (Modules)

模块是 Ansible 中执行实际任务的单元。它们是高度可复用的代码块,负责执行特定的操作(如安装软件包、配置文件等)。

角色 (Roles)

角色是 Playbook 的一种组织方式,用于把多个任务、文件、模板、变量等组织成一个完整的功能模块。角色帮助将复杂的配置拆分成可复用的组件。可在剧集内部使用的可重用 Ansible 内容。

任务 (Tasks)

任务是 Playbook 中定义的具体操作。每个任务通常会调用一个 Ansible 模块来执行特定的操作。是ad-hoc 更适合临时执行命令的执行场景。

插件

扩展 Ansible 核心功能的代码片段。插件可以控制您如何连接到被管理节点(连接插件)、操作数据(过滤器插件),甚至控制在控制台中显示的内容(回调插件)。

集合

Ansible 内容的分发格式,可以包含剧本、角色、模块和插件。

Ansible任务执行模式

Ansible 系统由控制主机对被管节点的操作方式可分为两类,即ad-hocplaybook

  • ad-hoc模式(点对点模式)
      使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。
  • playbook模式(剧本模式)
      是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件。

Ansible安装(centos 7)

修改系统镜像源为阿里云镜像源

1
2
3
cd /etc/yum.repos.d
mv CentOS-Base.repo CentOS-Base.repo.bak
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

方式一:使用yum安装

安装epel-release包与Ansible

1
2
3
4
yum install epel-release -y
yum install ansible -y
#查看版本
ansible --version

方式二:使用pip安装

1
2
3
4
yum install python3 python3-devel python3-pip -y
python3 -m pip install ansible
#查看版本
ansible --version

Ansible 配置文件

配置文件读取的优先级顺序如下:

  1. 检查环境变量ANSIBLE_CONFIG指向的路径文件(export ANSIBLE_CONFIG=xxxx);
  2. 检查当前项目目录下的ansible.cfg配置文件;
  3. ~/.ansible.cfg,检查当前目录下的ansible.cfg配置文件;
  4. /etc/ansible/ansible.cfg检查etc目录的配置文件。

Ansible免密登录

root用户

控制节点设置ssh免密登录,并将密钥传至受控节点上。

1
2
ssh-keygen -t dsa -f ~/.ssh/id_dsa -P ""
ssh-copy-id -i ~/.ssh/id_dsa.pub root@受控主机ip

普通用户

控制节点和被控节点都要有普通用户,此处以test用户为例。

1
2
3
#添加test用户,并设置密码
useradd test
passwd test

在控制节点设置ssh免密登录,并将密钥传至受控节点。

1
2
ssh-keygen -t dsa -f ~/.ssh/id_dsa -P ""
ssh-copy-id -i ~/.ssh/id_dsa.pub test@受控主机ip

修改所有主机的test用户的sudo权限。

1
2
visudo
test ALL=(ALL) NOPASSWD: ALL

修改控制节点的配置文件/etc/ansible/ansible.cfg,设置普通用户权限提升。

1
2
3
4
5
6
7
vi /etc/ansible/ansible.cfg
#将以下内容注释取消
[privilege_escalation]
become=True #启用权限提升
become_method=sudo #通过 sudo 提升到 root 用户的权限
become_user=root #作为 root 用户执行任务
become_ask_pass=False #禁用密码提示

Ansible Ad-Hoc与常用模块

Ad-Hoc

ad-hoc即为命令行模式,执行完即结束。

命令语法结构:

ansible 'groups' -m command -a 'df -h',其含义如下图:

执行过程:

  1. 加载配置文件,默认/etc/ansible/ansible.cfg;
  2. 查找对应的主机配置文件,找到要执行的主机或者组:
  3. 加载对应的模块文件,如command;
  4. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器对应执行用户$HOME/.ansible/tmp/ansible-tmp-number/XXX.PY;
  5. 远程主机执行该文件;
  6. 执行并返回结果;
  7. 删除临时py文件,sleep 0退出;

执行状态:

使用ad-hoc执行一次远程命令,注意观察返回结果的颜色:

  • 绿色:代表受控节点没有被修改
  • 黄色:代表受控节点发现变更
  • 红色:代表出现了故障,注意查看提示

常用模块

command模块

基本格式和常用参数

1
ansible '组/IP' -m command -a '[参数] 命令'
参数 选项 含义
chdir chdir /opt 执行ansible时,切换到指定目录
creates creates /data/file 如果文件存在,则跳过执行
removes removes /data/file 如果文件存在,则执行

[root@121 ~]# ansible webservers -m command -a ‘ls /root’

192.168.1.122 | CHANGED | rc=0 >>
anaconda-ks.cfg
test.txt
192.168.1.121 | CHANGED | rc=0 >>
anaconda-ks.cfg
test

[root@121 ~]# ansible webservers -m command -a ‘creates=/root/test.txt hostname’
192.168.1.122 | SUCCESS | rc=0 >>
skipped, since /root/test.txt exists
192.168.1.121 | CHANGED | rc=0 >>
121
[root@121 ~]# ansible webservers -m command -a ‘removes=/root/test.txt hostname’
192.168.1.122 | CHANGED | rc=0 >>
122
192.168.1.121 | SUCCESS | rc=0 >>
skipped, since /root/test.txt does not exist
[root@121 ~]#

shell模块支持管道符,command模块不支持

shell模块

基本格式和常用参数

1
ansible '组/IP/all' -m shell -a '[参数] 命令'

ansible webservers -m shell -a ‘ps aux | grep sshd’

yum/apt 模块

常用参数 功能
name 需要安装的服务名
state=present(缺省值)/absent 状态,abasent表示卸载服务

安装服务

ansible webservers -m yum -a ‘name=httpd’

卸载服务

ansible webservers -m yum -a ‘name=httpd state=absent’

copy模块

基本格式和常用参数

1
ansible < > -m copy -a 'src=   dest=   [owner= ] [mode=]   '
常用参数 功能 注意事项
src 指定源文件的路径(支持目录或文件) 若源为目录,目标也需为目录
dest 指定目标文件的位置(必须为绝对路径) 1. 若源为目录,目标需为目录2. 目标文件已存在时会覆盖原内容
mode 设置目标文件的权限
owner 设置目标文件的属主
group 设置目标文件的属组
content 直接指定目标文件的内容 不可与 src 参数同时使用

ansible dbservers -m copy -a ‘src=/etc/fstab dest=/opt/fstab.bak owner=root mode=640’
ansible dbservers -a ‘ls -l /opt’
ansible dbservers -a ‘cat /opt/fstab.bak’

systemd 模块

常用参数 功能
name 指定需要控制的服务名称
state 指定服务状态,可选值:stoppedstartedreloadedrestartedstatus
enabled 设置服务是否开机启动,yes 为启动,no 为不启动
daemon_reload 设为 yes 时重启 systemd 服务,使 unit 文件生效

ansible webservers -m systemd -a ‘name=firewalld state=started enabled=yes’

file模块

基本格式和常用参数

1
ansible < > -m file -a ''
常用参数 功能 备注
path 指定远程服务器的路径 也可写成 destname
state 定义操作类型:- directory:创建目录- touch:创建文件- link:创建软链接- hard:创建硬链接- absent:删除目录/文件/链接
mode 设置文件/目录权限 默认值:- 文件 644- 目录 755
owner 设置属主 默认 root
group 设置属组 默认 root
recurse 递归修改 yes或no
src 目标主机上的源文件(与 copy 模块不同)

创建/data目录,授权test属组

ansible webservers -m file -a ‘owner=test group=test mode=644 path=/data state=directory recurse=yes ‘

group模块

基本格式和常用参数

1
ansible <组/IP/all> -m group -a ' '
参数 功能 可选值/说明
name 指定用户名(必选参数)
state 控制账号的创建或删除 present:创建账号absent:删除账号
system 指定是否为系统账号 yes:系统账号no:普通账号
gid 指定组ID(修改用户所属组) 数值格式(如 1001

ansible webservers -m group -a ‘name=www gid=666 state=present ‘

user模块

基本格式和常用参数

1
ansible <组/IP/all> -m user -a ' '
参数 功能 可选值/说明
name 指定用户名(必选)
state 控制账号的创建或删除 present:创建absent:删除
system 指定是否为系统账号 yes:系统账号(如 mysqlno:普通账号
uid 指定用户UID 数值(如 1001),需唯一
group 指定用户基本组 组名或GID(需提前存在)
groups 指定用户所属附加组 组名列表(如 groups=wheel,admin
shell 设置用户默认shell 路径(如 /bin/bash
create_home 是否创建家目录 yes:自动创建no:不创建(默认行为可能依赖系统)
password 设置用户密码 建议使用加密后的字符串(如 password="$6$加密字符串"
remove 删除用户时是否同时删除家目录(需state=absent yes:删除家目录no:保留

1、 创建www用户,指定uid666,基本组www

1
ansible webservers -m user -a 'name=www uid=666 group=www shell=/sbin/nologin create home=no'

2、 创建db用户,基本组是root,附加组,adm,sys

1
ansible webservers -m user -a 'name=db group=root groups=adm,sys append=yes shell=/bin/bash create_home=yes'

3、 创建一个ddd用户,密码123,需要正常登录系统

(1)密码加密

1
ansible localhost -m debug -a "msg={{ '123' | password_hash('sha512', 'salt123') }}"
参数 作用 注意事项
sha512 指定哈希算法(推荐) 支持 sha256/md5 等,但 sha512 更安全 2
salt123 自定义盐值 盐值需为字母/数字,含 -_ 会导致哈希失败(返回 *0) 5
password_hash 过滤器 将明文密码转为加密字符串 需通过 {{ }} 调用且与变量用 `

localhost | SUCCESS => {
“msg”: “$6$salt123$c806NQq6Oqk29MjZdmHxTw7sK3BB1K498o7sZC47UiwQmjx5NJyi5ZhWWGngXf3UfyELHQ1wRJ//oW/Y94azv0
}

(2)撰写创建命令,完成创建

1
ansible webservers -m user -a "name=ddd password=第一步获取的加密密码 shell=/bin/bash create_home=yes"

4、 创建一个dev用户,并为其生成对应的秘钥

1
ansible webservers -m user -a 'name=dev generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa'

mount 模块

常用参数 功能
src 指定要挂载的设备或分区路径。
path 指定要挂载到的目标路径。
fstype 指定要挂载的文件系统类型。
state 指定挂载状态,可选值为 mounted、(临时挂载)present(永久挂载)、unmounted (临时卸载)或 absent(卸载)。
opts 指定挂载选项,例如挂载选项或参数。

将192.168.1.121上的/nfs目录挂载到192.168.1.122的/nfs目录

ansible 192.168.1.122 -m mount -a ‘src=192.168.1.121:/nfs path=/nfs fstype=nfs opts=defaults state=present ‘

cron模块

基本格式和常用参数

1
ansible <组/IP/all> -m cron -a ' '
常用参数 功能
minute/hour/day/month/weekday 分/时/日/月/周
job 任务计划要执行的命令
name 任务计划的名称
user 指定计划任务属于哪个用户,默认是root用户
state present表示添加(可以省略),absent表示移除。

添加一个每天19点执行/data/test.sh脚本的定时任务,任务名为script-test。

ansible webservers -m cron -a ‘name=”script-test” hour=19 minute=00 job=”/bin/bash /data/test.sh” ‘

注释该定时任务

ansible webservers -m cron -a ‘name=”script-test” hour=19 minute=00 job=”/bin/bash /data/test.sh” disabled=yes ‘

删除该定时任务

ansible webservers -m cron -a ‘name=”script-test” hour=19 minute=00 job=”/bin/bash /data/test.sh” state=absent ‘

archive 模块

常用参数 功能
path 指定要打包的源目录或文件的路径。
dest 指定打包文件的输出路径。
format 指定打包文件的格式,可以是 zip、tar、gz 或 bzip2。默认为 tar 格式。
remove 指定是否在打包文件之后,删除源目录或文件。可选值为 yes 或 no。默认为 no,即不删除源目录或文件。

unarchive 模块

常用参数 功能
copy 指定是否将打包文件复制到远程节点以进行解压缩。
remote_src (已弃用) 改用 copy 参数。
src 指定要解压缩的打包文件路径,可以是本地路径或远程路径。
dest 指定要将文件解压缩到的目标目录。
creates 指定一个文件路径,如果该文件已经存在,则不进行解压缩操作。
remote_tmp 用于指定远程节点上的临时目录。默认为 /tmp

1、 将控制端的压缩包,解压到被控端:

ansible webservers -m unarchive -a ‘src=./test.tar.gz dest=/mnt’
2、 将被控端的压缩包解压到被控端:

ansible webservers -m unarchive -a ‘src=/tmp/config_vpn_new.zip dest=/mnt remote_src=yes’

lineinfile模块

含义:替换|追加|删除

参数 选项 含义
path 指定要操作的目标文件路径
regexp 使用正则表达式匹配文件中的行
line 指定要修改或插入的新文本内容
insertafter 将文本插入到「正则匹配行」之后
insertbefore 将文本插入到「正则匹配行」之前
state absent / present (默认) absent删除匹配行,present确保文本存在
backrefs yes / no yes启用正则后向引用,no未匹配时不操作文件
backup 修改前是否创建备份文件(布尔值)
create 当目标文件不存在时是否创建新文件(布尔值)

1、替换httpd.conf文件中,Listen为Listen8080;

ansible webservers -m lineinfile -a ‘path=/etc/httpd/conf/httpd.conf regexp=”^Listen” line=”Listen 8080”‘

2、 给主机增加一个网关:

ansible webservers -m lineinfile -a ‘path=/etc/sysconfig/network-scripts/ifcfg-eth1 line=”GATEWAY=172.16.1.200”‘
3、 删除主机的网关:

ansible webservers -m lineinfile -a ‘path=/etc/sysconfig/network-scripts/ifcfg-ethl regexp=”^GATEWAY” state=absent’

Ansible Playbook

playbook是一个由yml语法编写的文本文件,它由playtask两部分组成。
play:主要定义要操作主机或者主机组。

task:主要定义对主机或主机组具体执行的任务,可以是一个任务,也可以是多个任务(模块)。

playbook是由一个或多个play组成,一个play可以包含多个task任务。

可以理解为:使用多个不同的模块来共同完成一件事情。

Playbook书写格式

playbook是由yml语法书写,结构清晰,可读性强。

语法 描述
缩进 YAML 使用固定的缩进风格表示层级结构,每个缩进由两个空格组成,不能使用 tabs
冒号 以冒号结尾的除外,其他所有冒号后面必须有空格
短横线 表示列表项,使用一个短横杠加一个空格。多个项使用同样的缩进级别作为同一列表

Playbook应用实例:

安装nignx

(1)撰写playbook文件

1
2
3
4
5
6
7
8
9
10
11
12
13
vi nginx.yml

- hosts: webservers
tasks:
- name: 安装nignx
yum:
name: nginx
state: present
- name: 启动nignx
systemd:
name: nginx
state: started
enabled: yes

(2)检查文件是否有语法错误

1
2
3
ansible-playbook --syntax nginx.yml

ansible-playbook --syntax-check nginx.yml

[root@121 data]# ansible-playbook —syntax nginx.yml

playbook: nginx.yml

(3)进行模拟执行

1
ansible-playbook -C nginx.yml

[root@121 data]# ansible-playbook -C nginx.yml

PLAY [webservers] **

TASK [Gathering Facts] *
ok: [192.168.1.122]
ok: [192.168.1.121]

TASK [安装nignx] *
changed: [192.168.1.122]
changed: [192.168.1.121]

TASK [启动nignx] *
changed: [192.168.1.121]
changed: [192.168.1.122]

PLAY RECAP *
192.168.1.121 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.1.122 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

(4)实际执行

1
ansible-playbook nginx.yml

[root@121 data]# ansible-playbook nginx.yml

PLAY [webservers] **

TASK [Gathering Facts] *
ok: [192.168.1.122]
ok: [192.168.1.121]

TASK [安装nignx] * **
changed: [192.168.1.121]
changed: [192.168.1.122]

TASK [启动nignx] *
changed: [192.168.1.122]
changed: [192.168.1.121]

PLAY RECAP *
192.168.1.121 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.1.122 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

安装NFS服务

任务顺序:

  • 下载nfs程序
  • 挂载nfs配置文件(设置触发器,修改配置文件后,使配置重启生效)
  • 初始化设置nfs(设置用户、组、授权)
  • 启动nfs

设置的触发器是handles,在第二步中添加notify信息,当配置文件修改时,handles获取notify中的信息,重启nfs服务,使得配置重新生效

文件准备:

1
2
3
4
5
6
7
#创建目录存放该项目
mkdir nfs
#创建nfs配置文件,将以下内容写入
vi exports.j2

/ansible_test 192.168.1.0/24(rw,all_squash,anonuid=7777,anongid=7777)

将ansible的配置文件ansible.cfghosts,提前放置在该项目目录下

创建nfs剧本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
vi nfs.yml

- hosts: webservers
tasks:
- name: download nfs
yum:
name: nfs-utils
state: present
- name: configure nfs
copy:
src: ./exports.j2
dest: /etc/exports
notify: restart nfs #触发信息
- name: init group
group:
name: bbb
gid: 7777
- name: init user
user:
name: bbb
uid: 7777
group: bbb
shell: /sbin/nologin
create_home: no
- name: init directory
file:
path: /ansible_test
state: directory
owner: bbb
group: bbb
mode: "0755"
- name: start nfs
systemd:
name: nfs
state: started
enabled: yes
handlers: #触发器
- name: restart nfs
systemd:
name: nfs
state: restarted

执行并验证

1
2
3
4
5
6
7
8
9
10
11
ansible-playbook --syntax-check nfs.yml
ansible-playbook -C nfs.yml
ansible-playbook nfs.yml

#查看nfs服务
showmount -e 192.168.1.121
showmount -e 192.168.1.122

#挂载测试
mount -t nfs 192.168.1.121:/ansible_test /data/test
mount -t nfs 192.168.1.122:/ansible_test /data/test1

[root@121 ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 898M 0 898M 0% /dev
tmpfs 910M 0 910M 0% /dev/shm
tmpfs 910M 9.7M 901M 2% /run
tmpfs 910M 0 910M 0% /sys/fs/cgroup
/dev/mapper/centos-root 17G 1.7G 16G 10% /
/dev/sda1 1014M 153M 862M 16% /boot
tmpfs 182M 0 182M 0% /run/user/0
192.168.1.121:/ansible_test 17G 1.7G 16G 10% /data/test
192.168.1.122:/ansible_test 17G 2.2G 15G 13% /data/test1

安装rsync服务

rsync服务端:

任务顺序:

  • 下载rsync程序
  • 挂载rsync配置文件(设置触发器,修改配置文件后,使配置重启生效)
  • 初始化设置rsync(设置用户、组、授权)
  • 创建虚拟用户和密码
  • 启动rsync

设置的触发器是handles,当配置文件或虚拟用户密码修改时,handles获取notify中的信息,重启rsync服务,使得配置重新生效

文件准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#创建目录存放该项目
mkdir rsync
#复制rsync配置文件rsyncd.conf并修改(可先手动下载rsync,拷贝配置文件后再卸载,也可直接使用以下内容)

uid = ansible_www
gid = ansible_www
port = 873
fake super = yes
use chroot = yes
max connections = 4
timeout = 900
read only = false
list = false
auth users = rsync_backup
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log
[backup]
path = /backup

将ansible的配置文件ansible.cfghosts,提前放置在该项目目录下

创建rsync剧本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
vi rsync.yml

- hosts: webservers
tasks:
- name: download rsync
yum:
name: rsync
state: present
- name: configure rsync
copy:
src: ./rsyncd.conf
dest: /etc/rsyncd.conf
owner: root
group: root
mode: "0644"
notify: restart rsync
- name: init group
group:
name: ansible_www
gid: 8888
- name: init user
user:
name: ansible_www
uid: 8888
group: ansible_www
shell: /sbin/nologin
create_home: no
- name: init directory
file:
path: /backup
state: directory
owner: ansible_www
group: ansible_www
mode: "0755"
recurse: yes
- name: init rsync user passwd
copy:
content: "rsync_backup:123456"
dest: /etc/rsync.passwd
owner: root
group: root
mode: 0600
notify: restart rsync
- name: start rsync
systemd:
name: rsyncd
state: started
enabled: yes
handlers:
- name: restart rsync
systemd:
name: rsyncd
state: restarted

执行并验证

1
2
3
4
5
6
ansible-playbook --syntax-check rsync.yml 
ansible-playbook -C rsync.yml
ansible-playbook rsync.yml

#验证
rsync -avz host_group rsync_backup@192.168.1.122::backup
rsync客户端:

任务顺序:

  • 将脚本推送至被控端指定路径下
  • 配置定时任务

创建rsync-client剧本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
vi rsync-client.yml

- hosts: localhost
tasks:
- name: create scripts path
file:
path: /scripts
owner: root
group: root
state: directory
mode: 0755
- name: push scripts
copy:
src: test.sh
dest: /scripts/test.sh
owner: root
group: root
mode: 0755
- name: contable job
cron:
name: "push backup data"
minute: "*/1"
job: "/bin/bash /scripts/test.sh &>/dev/null"

创建test.sh以供测试

1
2
#!/bin/bash
RSYNC_PASSWORD="123456" rsync -avz /backup/ rsync_backup@192.168.1.122::backup

查看是否有定时任务

1
crontab -l

Ansible: push backup data

/1 * /bin/bash /scripts/test.sh &>/dev/null

使用Ansible部署多节点phpmyadmin

项目需求
  • 使用LNMP部署phpmyadmin
  • nginx(Haproxy)作为负载均衡
  • Redis实现会话保持
主机规划
主机名 ip 用途
121 192.168.1.121 Ansible控制节点、nignx+PHP
122 192.168.1.122 Ansible受控节点、nignx+PHP
123 192.168.1.123 Ansible受控节点、nignx(Haproxy)
124 192.168.1.124 Ansible受控节点、nignx(Haproxy)
125 192.168.1.125 Ansible受控节点、Redis
部署步骤
环境准备

121节点上要准备好Ansible,并设置以上5台机器免密登录,具体参照上方的配置过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#创建存放项目文件目录
mkdir /data/phpmyadmin
#将ansible的配置文件`ansible.cfg`和`hosts`,复制到该phpmyadmin目录下,并修改配置
cp /etc/ansible/ansible.cfg /data/phpmyadmin/ansible.cfg
#修改配置文件中的路径,并取消注释
inventory = /data/phpmyadmin/host_group

cp /etc/ansible/hosts /data/phpmyadmin/host_group
#修改主机组
[webservers]
192.168.1.121
192.168.1.122

[dbservers]
192.168.1.125

[lbservers]
192.168.1.123
192.168.1.124

确认配置文件的读取路径是否为当前项目下的/data/phpmyadmin/ansible.cfg

[root@121 phpmyadmin]# ansible —version
ansible 2.9.27
config file = /data/phpmyadmin/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, Jun 28 2022, 15:30:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]

验证主机是否都可ping通

[root@121 phpmyadmin]# ansible all -m ping
192.168.1.122 | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
},
“changed”: false,
“ping”: “pong”
}
192.168.1.124 | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
},
“changed”: false,
“ping”: “pong”
}
192.168.1.123 | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
},
“changed”: false,
“ping”: “pong”
}
192.168.1.125 | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
},
“changed”: false,
“ping”: “pong”
}
192.168.1.121 | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
},
“changed”: false,
“ping”: “pong”
}

安装Redis

任务顺序:

  • 下载redis程序
  • 挂载redis配置文件(设置触发器,修改配置文件后,使配置重启生效)
  • 启动redis

设置触发器handles,重启redis服务

(1)将redis的配置文件redis.conf,拷贝至/data/phpmyadmin/files目录下

1
2
3
4
5
mkdir /data/phpmyadmin/files
# 若无redis.conf文件可先在控制节点上使用命令yum -y install redis下载后再拷贝
cp /etc/redis.conf /data/phpmyadmin/files
#修改配置文件,将要安装redis的主机ip加入
bind 127.0.0.1 192.168.1.125

(2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
vi redis.yml

- hosts: dbservers
tasks:
- name: download redis
yum:
name: redis
state: present
- name: configure redis
copy:
src: ./files/redis.conf
dest: /etc/redis.conf
owner: redis
group: root
mode: 0640
notify: restart redis
- name: start redis
systemd:
name: redis
state: started
enabled: yes
handlers:
- name: restart redis
systemd:
name: redis
state: restarted

(3)安装并测试

1
2
3
4
5
6
ansible-playbook --syntax-check redis.yml
ansible-playbook -C redis.yml
ansible-playbook redis.yml
#测试,之前控制节点121安装了redis,可直接在121上测试
#注意防火墙端口
redis-cli -h 192.168.1.125

[root@121 phpmyadmin]# redis-cli -h 192.168.1.125
192.168.1.125:6379>

安装Mariadb

在192.168.1.125上安装Mariadb

1
2
3
4
5
6
7
8
9
10
11
yum -y install mariadb-server
systemctl start mariadb
systemctl enable mariadb
#设置root用户密码
mysqladmin -uroot password '123456'
#登录创建用户
mysql -uroot -p123456
#创建数据库
create database php_db;
#创建数据库用户
grant all on php_db.* to php_user@'%' identified by '123456';
安装nginx、PHP

任务顺序:

  • 下载nginx、PHP程序
  • 挂载nginx、PHP配置文件(设置触发器,修改配置文件后,使配置重启生效)
  • 初始化设置nginx(设置用户、组、授权)
  • 启动nginx、PHP

设置触发器handles,重启nginx、PHP服务

(1)设置php7下载源,在121,122上执行

1
2
rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm

(2)将nginx、php的配置文件,拷贝至/data/phpmyadmin/files目录下,并修改配置

1
2
3
4
5
#nginx配置文件
cp /etc/nginx/nginx.conf /data/phpmyadmin/files
#php配置文件
cp /etc/php.ini /data/phpmyadmin/files
cp /etc/php-fpm.d/www.conf /data/phpmyadmin/files

修改nginx配置文件,将用户修改为www

1
2
vi nginx.conf
user www;

/data/phpmyadmin/files目录下,新增phpmyadmin的nginx代理文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
vi phpmyadmin.conf

server {
listen 80;
server_name ansible.phpmyadmin.local;

# 确保此路径与phpMyAdmin实际路径完全一致
root /code/phpmyadmin;
index index.php;

location / {
try_files $uri $uri/ /index.php$is_args$args;
}

location ~ \.php$ {
# 绝对路径必须完整正确
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;

# 添加关键参数
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_intercept_errors on;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}

修改php配置文件php.ini,设置redis连接。

1
2
3
4
5
vi php.ini
[Session]

session.save_handler = redis
session.save_path = "tcp://192.168.1.125:6379?weight=1&timeout=2.5"

修改php配置文件www.conf,设置用户和组,并注释部分设置。

1
2
3
4
5
6
7
8
9
vi www.conf

[www]
user = www
group = www

;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session

(3)下载phpmyadmin

1
2
3
4
5
6
7
8
9
#phpmyadmin程序下载到/data/phpmyadmin/files目录下
curl -O https://files.phpmyadmin.net/phpMyAdmin/5.2.2/phpMyAdmin-5.2.2-all-languages.zip

#解压程序
unzip phpMyAdmin-5.2.2-all-languages.zip
#复制并修改配置文件,连接mariadb数据库
cp phpMyAdmin-5.2.2-all-languages/config.sample.inc.php config.inc.php
#修改localhost为192.168.1.125
$cfg['Servers'][$i]['host'] = '192.168.1.125';

(4)创建nignx-php剧本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
vi nginx-php.yml

- hosts: webservers
tasks:
- name: download nginx
yum:
name: nginx
state: present
- name: download php
yum:
name: "{{ packages }}"
vars:
packages:
- php72w
- php72w-cli
- php72w-common
- php72w-devel
- php72w-embedded
- php72w-fpm
- php72w-gd
- php72w-mbstring
- php72w-mysqlnd
- php72w-opcache
- php72w-pdo
- php72w-xml
- php72w-ldap
- php72w-pecl-redis

- name: configure nginx
copy:
src: ./files/nginx.conf
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: 0644
notify: restart nginx
- name: init group www
group:
name: www
gid: 666
- name: init user www
user:
name: www
uid: 666
group: www
shell: /sbin/nologin
create_home: no
- name: start nginx
systemd:
name: nginx
state: started
enabled: yes

- name: configure php.ini
copy:
src: ./files/php.ini
dest: /etc/php.ini
owner: root
group: root
mode: 0644
notify: restart php
- name: configure www.conf
copy:
src: ./files/www.conf
dest: /etc/php-fpm.d/www.conf
owner: root
group: root
mode: 0644
notify: restart php
- name: start php
systemd:
name: php-fpm
state: started
enabled: yes

- name: copy nginx conf
copy:
src: ./files/phpmyadmin.conf
dest: /etc/nginx/conf.d/phpmyadmin.conf
notify: restart nginx
- name: create code directory
file:
path: /code
state: directory
owner: www
group: www
mode: "0755"
recurse: yes
- name: unarchive phpmyadmin #解压phpmyadmin
unarchive:
src: ./files/phpMyAdmin-5.2.2-all-languages.zip
dest: /code/
owner: www
group: www
creates: /code/phpMyAdmin-5.2.2-all-languages/config.inc.php
- name: create link #创建软连接
file:
src: /code/phpMyAdmin-5.2.2-all-languages/
dest: /code/phpmyadmin
state: link
- name: change phpmyadmin configure
copy:
src: ./files/config.inc.php
dest: /code/phpMyAdmin-5.2.2-all-languages/config.inc.php


handlers:
- name: restart nginx
systemd:
name: nginx
state: restarted
- name: restart php
systemd:
name: php-fpm
state: restarted

(5)安装并测试

1
2
3
ansible-playbook --syntax-check nginx-php.yml
ansible-playbook -C nginx-php.yml
ansible-playbook nginx-php.yml

(6)在本机电脑C:\Windows\System32\drivers\etc\hosts配置hosts

1
2
3
#分别配置121,122的hosts进行访问测试
192.168.1.121 ansible.phpmyadmin.local
192.168.1.122 ansible.phpmyadmin.local

(7)浏览器访问ansible.phpmyadmin.local,用户密码是安装Mariadb数据库时,创建的用户php_user及其密码123456

负载均衡方式一:nginx

(1)复制nginx的配置文件nginx.conf,至/data/phpmyadmin/files目录下并命名为nginx.conf.lb

1
cp /etc/nginx.conf /data/phpmyadmin/files/nginx.conf.lb

(2)在/data/phpmyadmin/files目录下创建配置文件proxy.conf,用作负载均衡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vi proxy.conf

upstream ansible {
server 192.168.1.121;
server 192.168.1.122;
}
server {
listen 80;
server_name ansible.phpmyadmin.local;
location / {
proxy_pass http://ansible;
proxy_set_header Host $http_host;
}

}

(3)创建lb-nginx剧本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
vi lb-nginx.yml

- hosts: lbservers
tasks:
- name: download nginx
yum:
name: nginx
state: present
- name: configure nginx
copy:
src: ./files/nginx.conf.lb
dest: /etc/nginx/nginx.conf
notify: restart nginx
- name: copy nginx conf
copy:
src: ./files/proxy.conf
dest: /etc/nginx/conf.d/proxy.conf
notify: restart nginx
- name: start nginx
systemd:
name: nginx
state: started
enabled: yes
handlers:
- name: restart nginx
systemd:
name: nginx
state: restarted

(4)安装并测试

1
2
3
ansible-playbook --syntax-check lb-nginx.yml
ansible-playbook -C lb-nginx.yml
ansible-playbook lb-nginx.yml

(5)在本机电脑C:\Windows\System32\drivers\etc\hosts配置hosts

1
2
192.168.1.123 ansible.phpmyadmin.local
192.168.1.124 ansible.phpmyadmin.local

(6)浏览器访问ansible.phpmyadmin.local,并观察数据库服务器-用户,刷新查看用户是否为121与122切换显示。

负载均衡方式二:haproxy

(1)设置haproxy下载源

1
rpm -Uvh https://repo.ius.io/ius-release-el7.rpm

(2)将/etc/haproxy/haproxy.cfg,至/data/phpmyadmin/files目录下

1
cp /etc/haproxy/haproxy.cfg /data/phpmyadmin/files

可先在任意一台服务器安装haproxy,获取/etc/haproxy/haproxy.cfg文件

(3)修改haproxy.cfg配置文件,新增以下内容。

1
2
3
4
5
6
7
8
9
10
11
frontend web
bind *:8080
mode http
acl ansible_domain hdr_reg(host) -i ansible.phpmyadmin.local
use_backend ansible_cluster if ansible_domain
backend ansible_cluster
balance roundrobin
option httpchk HEAD / HTTP/1.1\r\nHost:\ ansible.phpmyadmin.local
server server1 192.168.1.121:80 check port 80 inter 3s rise 2 fall 3
server server2 192.168.1.122:80 check port 80 inter 3s rise 2 fall 3

(4)创建lb-haproxy剧本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
vi lb-haproxy.yml

- hosts: lbservers
tasks:
- name: download haproxy
yum:
name: haproxy22
state: present
- name: configure haproxy
copy:
src: ./files/haproxy.cfg
dest: /etc/haproxy/haproxy.cfg
owner: root
group: root
mode: 0644
notify: restart haproxy
- name: start haproxy
systemd:
name: haproxy
state: started
enabled: yes
handlers:
- name: restart haproxy
systemd:
name: haproxy
state: restarted

(5)安装并测试

1
2
3
ansible-playbook --syntax-check lb-haproxy.yml
ansible-playbook -C lb-haproxy.yml
ansible-playbook lb-haproxy.yml

(5)在本机电脑C:\Windows\System32\drivers\etc\hosts配置hosts

1
2
192.168.1.123 ansible.phpmyadmin.local
192.168.1.124 ansible.phpmyadmin.local

(6)浏览器访问ansible.phpmyadmin.local:8080,并观察数据库服务器-用户,刷新查看用户是否为121与122切换显示。

本篇知识来源于B站视频BV11JZcYwEDd