马哥SRE第11周课程作业

1. ansible 常用指令总结,并附有相关示例。

1.1 Ansible相关工具

  • /usr/bin/ansible 主程序,临时命令执行工具
  • /usr/bin/ansible-doc 查看配置文档,模块功能查看工具,相当于man
  • /usr/bin/ansible-playbook 定制自动化任务,编排剧本工具,相当于脚本
  • /usr/bin/ansible-pull 远程执行命令的工具
  • /usr/bin/ansible-vault 文件加密工具
  • /usr/bin/ansible-console 基于Console界面与用户交互的执行工具
  • /usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台

利用ansible实现管理的主要方式:

  • Ansible Ad-Hoc 即利用ansible命令,主要用于临时命令使用场景
  • Ansible playbook 主要用于长期规划好的,大型项目的场景,需要有前期的规划过程
    ansible 使用前准备
    ansible 相关工具大多数是通过ssh协议,实现对远程主机的配置管理、应用部署、任务执行等功能
    建议:使用此工具前,先配置ansible主控端能基于密钥认证的方式联系各个被管理节点
    范例:利用sshpass批量实现基于key验证脚本1
vim /etc/ssh/ssh_config
#修改下面一行
StrictHostKeyChecking no
[root@centos8 ~]#cat hosts.list
10.0.0.18
10.0.0.28
[root@centos8 ~]#cat push_ssh_key.sh
#!/bin/bash
rpm -q sshpass &> /dev/null || yum -y install sshpass  
[ -f /root/.ssh/id_rsa ] || ssh-keygen -f /root/.ssh/id_rsa  -P ''
export SSHPASS=magedu
while read IP;do
   sshpass -e ssh-copy-id  -o StrictHostKeyChecking=no $IP
done < hosts.list

1.1.1 ansible-doc

此工具用来显示模块帮助,相当于man
格式

ansible-doc [options] [module…]
-l, --list #列出可用模块
-s, --snippet #显示指定模块的playbook片段

范例:

#列出所有模块
ansible-doc -l  
#查看指定模块帮助用法
ansible-doc ping  
#查看指定模块帮助用法
ansible-doc -s  ping

范例: 查看指定的插件

[root@ansible ~]#ansible-doc -t connection -l
[root@ansible ~]#ansible-doc -t lookup -l

1.1.2 ansible 命令用法

格式:

ansible [-m module_name] [-a args]

选项说明:

--version #显示版本
-m module   #指定模块,默认为command
-v #详细过程 -vv -vvv更详细
--list-hosts #显示主机列表,可简写 --list
-C, --check   #检查,并不执行
-T, --timeout=TIMEOUT #执行命令的超时时间,默认10s
-k, --ask-pass     #提示输入ssh连接密码,默认Key验证 
-u, --user=REMOTE_USER #执行远程执行的用户,默认root
-b, --become    #代替旧版的sudo实现通过sudo机制实现提升权限
--become-user=USERNAME  #指定sudo的runas用户,默认为root
-K, --ask-become-pass  #提示输入sudo时的口令
-f FORKS, --forks FORKS #指定并发同时执行ansible任务的主机数
-i INVENTORY, --inventory INVENTORY  #指定主机清单文件

范例:

#以wang用户执行ping存活检测
ansible all -m ping -u wang  -k
#以wang sudo至root执行ping存活检测
ansible all -m ping -u wang -k -b
#以wang sudo至mage用户执行ping存活检测
ansible all -m ping -u wang -k -b --become-user=mage
#以wang sudo至root用户执行ls 
ansible all -m command  -u wang -a 'ls /root' -b --become-user=root -k -K

范例: 并发执行控制

#分别执行下面两条命令观察结果
[root@ansible ~]#ansible all -a 'sleep 5' -f1
[root@ansible ~]#ansible all -a 'sleep 5' -f10

范例: 使用普能用户进行远程管理

#在所有控制端和被控制端创建用户和密码
[root@rocky8 ~]#useradd wang
[root@rocky8 ~]#echo wang:123456 | chpasswd
#在所有被控制端对用户sudo授权
[root@rocky8 ~]#visudo 
wang    ALL=(ALL)   NOPASSWD: ALL
[root@rocky8 ~]#visudo -c
/etc/sudoers: parsed OK
#实现从控制端到被控制端的基于key验证
[root@ansible ~]#su - wang
wang@ansible:~$ssh-keygen -f ~/.ssh/id_rsa  -P ''
wang@ansible:~$$ssh-copy-id wang@'10.0.0.8'
#使用普通用户测试连接,默认连接权限不足失败
wang@ansible:~$ ansible 10.0.0.8 -m shell -a 'ls /root'
10.0.0.8 | FAILED | rc=2 >>
ls: cannot open directory '/root': Permission deniednon-zero return code
#使用普通用户通过-b选项连接实现sudo提权后连接成功
wang@ansible:~$ ansible 10.0.0.8 -m shell -a 'ls /root' -b --become-user root
10.0.0.8 | CHANGED | rc=0 >>
anaconda-ks.cfg
#修改配置文件指定sudo机制
[root@ansible ~]#vim /etc/ansible/ansible.cfg
#取消下面行前面的注释
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
#再次测试
[root@ansible ~]#su - wang
wang@ansible:~$ ansible 10.0.0.8 -m shell -a 'ls /root'
10.0.0.8 | CHANGED | rc=0 >>
anaconda-ks.cfg

范例: 使用普通用户连接远程主机执行代替另一个用户身份执行操作

[root@centos8 ~]#useradd wang
[root@centos8 ~]#echo wang:123456 | chpasswd
#先在被控制端能过sudo对普通用户授权
[root@centos8 ~]#grep wang /etc/sudoers
wang    ALL=(ALL) NOPASSWD: ALL
#以wang的用户连接用户,并利用sudo代表mage执行whoami命令
[root@ansible ~]#ansible 10.0.0.8 -m shell -a 'whoami' -u wang -k -b --becomeuser=mage
SSH password: #输入远程主机wang用户ssh连接密码
10.0.0.8 | CHANGED | rc=0 >>
mage

ansible的Host-pattern
用于匹配被控制的主机的列表
All :表示所有Inventory中的所有主机
范例

ansible all -m ping

*:通配符

ansible "*" -m ping 
ansible 192.168.1.* -m ping
ansible "srvs" -m ping
ansible "10.0.0.6 10.0.0.7" -m ping

或关系

ansible "websrvs:appsrvs" -m ping 
ansible "192.168.1.10:192.168.1.20" -m ping

逻辑与

#在websrvs组并且在dbsrvs组中的主机
ansible "websrvs:&dbsrvs" -m ping

逻辑非

#在所有主机,但不在websrvs组和dbsrvs组中的主机
#注意:此处为单引号
ansible 'all:!dbsrvs:!websrvs' -m ping

综合逻辑

ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' -m ping

正则表达式

ansible "websrvs:dbsrvs" -m ping
ansible "~(web|db).*\.magedu\.com" -m ping

范例:

[root@kube-master1 ~]#ansible 'kube*:etcd:!10.0.0.101' -a reboot && reboot

范例:

[root@centos8 ~]#ansible all --list-hosts  
 hosts (3):
    10.0.0.6
    10.0.0.7
    10.0.0.8
[root@centos8 ~]#ansible websrvs --list-hosts  
 hosts (3):
    10.0.0.6
    10.0.0.7
    10.0.0.8
[root@centos8 ~]#ansible appsrvs --list-hosts  
 hosts (2):
    10.0.0.7
    10.0.0.8
[root@centos8 ~]#ansible "appsrvs:dbsrvs" --list-hosts  
 hosts (3):
    10.0.0.7
    10.0.0.8
    10.0.0.6
[root@centos8 ~]#ansible "dbsrvs" --list-hosts  
 hosts (2):
    10.0.0.6
    10.0.0.7
[root@centos8 ~]#ansible appsrvs --list-hosts  
 hosts (2):
    10.0.0.7
    10.0.0.8
[root@centos8 ~]#ansible "appsrvs:dbsrvs" --list-hosts  
 hosts (3):
    10.0.0.7
    10.0.0.8
    10.0.0.6
[root@centos8 ~]#ansible "appsrvs:&dbsrvs" --list-hosts  
 hosts (1):
    10.0.0.7
    
#引用!号时,不要用双引号,而使用单引号
[root@centos8 ~]#ansible "appsrvs:!dbsrvs" --list-hosts  
-bash: !dbsrvs: event not found
[root@centos8 ~]#ansible 'appsrvs:!dbsrvs' --list-hosts  
 hosts (1):
    10.0.0.8

ansible 命令的执行过程

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

ansible 命令的执行状态

[root@centos8 ~]#grep -A 14 '\[colors\]' /etc/ansible/ansible.cfg 
[colors]
#highlight = white
#verbose = blue
#warn = bright purple
#error = red
#debug = dark gray
#deprecate = purple
#skip = cyan
#unreachable = red
#ok = green
#changed = yellow
#diff_add = green
#diff_remove = red
#diff_lines = cyan
  • 绿色:执行成功并且对目标主机不需要做改变的操作
  • 黄色:执行成功并且对目标主机做变更
  • 红色:执行失败

1.1.3 ansible-console

此工具可交互执行命令,支持tab,ansible 2.0+新增
提示符格式:

执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$

常用子命令:

  • 设置并发数: forks n 例如: forks 10
  • 切换组: cd 主机组 例如: cd web
  • 列出当前组主机列表: list
  • 列出所有的内置命令: ?或help
    范例
[root@ansible ~]#ansible-console
Welcome to the ansible console.
Type help or ? to list commands.
root@all (3)[f:5]$ ping
10.0.0.7 | SUCCESS => {
    
    
    "ansible_facts": {
    
    
        "discovered_interpreter_python": "/usr/bin/python"
   },
       "changed": false,
    "ping": "pong"
}
10.0.0.6 | SUCCESS => {
    
    
    "ansible_facts": {
    
    
        "discovered_interpreter_python": "/usr/bin/python"
   },
    "changed": false,
    "ping": "pong"
}
10.0.0.8 | SUCCESS => {
    
    
    "ansible_facts": {
    
    
        "discovered_interpreter_python": "/usr/libexec/platform-python"
   },
    "changed": false,
    "ping": "pong"
}
root@all (3)[f:5]$ list
10.0.0.8
10.0.0.7
10.0.0.6
root@all (3)[f:5]$ cd websrvs
root@websrvs (2)[f:5]$ list
10.0.0.7
10.0.0.8
root@websrvs (2)[f:5]$ forks 10
root@websrvs (2)[f:10]$ cd appsrvs
root@appsrvs (2)[f:5]$ yum name=httpd state=present
root@appsrvs (2)[f:5]$ service name=httpd state=started

1.1.4 ansible-playbook

此工具用于执行编写好的 playbook 任务
范例:

ansible-playbook hello.yml
cat hello.yml
---
#hello world yml file
- hosts: websrvs
 remote_user: root
 gather_facts: no
  
 tasks:
    - name: hello world
     command: /usr/bin/wall hello world

1.1.5 ansible-vault

此工具可以用于加密解密yml文件
格式:

ansible-vault [create|decrypt|edit|encrypt|rekey|view]

范例:

ansible-vault encrypt hello.yml #加密
ansible-vault decrypt hello.yml #解密
ansible-vault view hello.yml #查看
ansible-vault edit hello.yml #编辑加密文件
ansible-vault rekey hello.yml #修改口令
ansible-vault create new.yml #创建新文件
#执行加密的playbook,交互式输入密码
chmod 600 hello.yml
ansible-playbook  --ask-vault-pass hello.yml
#从pass.txt文件中读取密码
ansible-playbook --vault-password-file pass.txt hello.yml
#从配置文件中取得密码
#vi /etc/ansible/ansible.cfg
[defaults]
ault-password-file=pass.txt
#可以直接执行加密文件
ansible-playbook   hello.yml

1.1.5 ansible-galaxy

Galaxy 是一个免费网站, 类似于github网站, 网站上发布了很多的共享的roles角色。
Ansible 提供了ansible-galaxy命令行工具连接 https://galaxy.ansible.com 网站下载相应的roles, 进行
init(初始化、search( 查拘、install(安装、 remove(移除)等操作。

范例:

#搜索项目
[root@ansible ~]#ansible-galaxy search lamp
#列出所有已安装的galaxy
ansible-galaxy list
#安装galaxy,默认下载到~/.ansible/roles下
ansible-galaxy install geerlingguy.mysql
ansible-galaxy install geerlingguy.redis
#删除galaxy
ansible-galaxy remove geerlingguy.redis

2. 总结ansible playbook目录结构及文件用途。

在这里插入图片描述

  • 一个 playbook(剧本)文件是一个YAML语言编写的文本文件
  • 通常一个playbook只包括一个play
  • 一个 play的主要包括两部分: 主机和tasks. 即实现在指定一组主机上执行一个tasks定义好的任务列表。
  • 一个tasks中可以有一个或多个task任务
  • 每一个Task本质上就是调用ansible的一个module
  • 在复杂场景中,一个playbook中也可以包括多个play,实现对多组不同的主机执行不同的任务

2.1 Playbook 核心组件

官方文档

https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html#playbook-keywords

一个playbook 中由多个组件组成,其中所用到的常见组件类型如下:

  • Hosts 执行的远程主机列表
  • Tasks 任务集,由多个task的元素组成的列表实现,每个task是一个字典,一个完整的代码块功能需最
    少元素需包括 name 和 task,一个name只能包括一个task
  • Variables 内置变量或自定义变量在playbook中调用
  • Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
  • Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
  • tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此
    会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地
    长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断

2.1.1 hosts 组件

Hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts
用于指定要执行指定任务的主机,须事先定义在主机清单中

one.example.com
one.example.com:two.example.com
192.168.1.50
192.168.1.*
Websrvs:dbsrvs     #或者,两个组的并集
Websrvs:&dbsrvs   #与,两个组的交集
webservers:!dbsrvs  #在websrvs组,但不在dbsrvs组

案例:

- hosts: websrvs:appsrvs

2.1.2 remote_user 组件

remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可
用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户

- hosts: websrvs
 remote_user: root
  
 tasks:
   - name: test connection
     ping:
     remote_user: magedu
     sudo: yes #默认sudo为root
     sudo_user:wang    #sudo为wang

2.1.3 task列表和action组件

play的主体部分是task list,task list中有一个或多个task,各个task 按次序逐个在hosts中指定的所有主
机上执行,即在所有主机上完成第一个task后,再开始第二个task
task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着
多次执行是安全的,因为其结果均一致
每个task都应该有其name,用于playbook的执行结果输出,建议其内容能清晰地描述任务执行步骤。
如果未提供name,则action的结果将用于输出
task两种格式:

action: module arguments  #示例: action: shell wall hello 
module: arguments   #建议使用 #示例: shell: wall hello

注意:shell和command模块后面跟命令,而非key=value
范例:

[root@ansible ansible]#cat hello.yml 
---
#first yaml文件
#
- hosts: websrvs
 remote_user: root
 gather_facts: no
 tasks:
    - name: task1
     debug: msg="task1 running"
    - name: task2
     debug: msg="task2 running"
- hosts: appsrvs
 remote_user: root
 gather_facts: no
 tasks:
    - name: task3
     debug: msg="task3 running"
    - name: task4
     debug: msg="task4 running"

范例:

[root@ansible ansible]#cat hello.yaml
---
# first yaml file 
- hosts: websrvs
 remote_user: root
 gather_facts: no   #不收集系统信息,提高执行效率
 tasks:
    - name: test network connection
      ping:
    - name: excute command
     command: wall "hello world!"

范例:

---
- hosts: websrvs
 remote_user: root
 gather_facts: no
  
 tasks:
   - name: install httpd
     yum: name=httpd 
   - name: start httpd
     service: name=httpd state=started enabled=yes

2.1.4 其它组件说明

某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers任务
还可以通过"tags"给task 打标签,可在ansible-playbook命令上使用-t指定进行调用

2.1.5 ShellScripts VS Playbook 案例

#SHELL脚本实现
#!/bin/bash
# 安装Apache
yum install --quiet -y httpd 
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp/tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache,并设置开机启动
systemctl enable --now httpd 
#Playbook实现
---
- hosts: websrvs
 remote_user: root
 gather_facts: no
  
 tasks:
   - name: "安装Apache"
     yum: name=httpd
   - name: "复制配置文件"
     copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
   - name: "复制配置文件"
     copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
   - name: "启动Apache,并设置开机启动"
     service: name=httpd state=started enabled=yes

3. 使用ansible playbook实现一个mysql角色。

3.1 目录结构

tree  roles/mysql/
roles/mysql/
├── files
│   └── mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz
├── handlers
│   └── main.yml
├── tasks
│   ├── main.yml
│   ├── main.yml_changed_when
│   └── main.yml_when
└── templates
    ├── my.cnf.j2
    └── mysql_auth_sql.j2

3.1.1 host

host 跟role.yml总入口在一级在role目录的上级

 cat hosts_mysql
[dbservers]
10.1.10.113
10.1.10.114

[dbservers:vars]
uid=306
user=mysql
gid=306
group=mysql
basedir="/usr/local"
datadir="/data/mysql"
mysql_version="8.0.20"
mysql_file="mysql-{
    
    {mysql_version}}-linux-glibc2.12-x86_64.tar.xz"
mysql_root_password=123456


cat mysql_role.yml
- hosts: dbservers
  remote_user: root

  roles:
    - mysql

3.1.3 task

mysql创建用户授权相关操作我用的shell模块导入sql文件,后期改成pymysql的mysql_db、mysql_user相关模块操作了

- name: create {
    
    {
    
     group }}
  group:
    name: "{
    
    { group }}"
    gid: "{
    
    { gid }}"
- name: create {
    
    {
    
     user }}
  user:
    name: "{
    
    { user }}"
    uid: "{
    
    { uid }}"
    group: "{
    
    { group }}"
    system: yes
    shell: /sbin/nologin
    create_home: yes
    home: "{
    
    { datadir }}"
- name: install packages
  yum:
    name: "{
    
    { item }}"
  loop:
    - ncurses-compat-libs
- name: copy tar to remote host and file mode
  unarchive:
    src: "{
    
    { mysql_file }}"
    dest: "{
    
    { basedir }}"
    group: "{
    
    { group }}"
    owner: "{
    
    { user }}"
    creates: "{
    
    { basedir }}/mysql-{
    
    { mysql_version }}-linux-glibc2.12-x86_64"
- name: create linkfile {
    
    {
    
     basedir }}/mysql
  file:
    src: "{
    
    { basedir }}/mysql-{
    
    { mysql_version }}-linux-glibc2.12-x86_64"
    dest: "{
    
    { basedir }}/mysql"
    state: link
- name: data dir
  shell:
    cmd: "{
    
    { basedir }}/mysql/bin/mysqld --initialize-insecure --user={
    
    { user }} --datadir={
    
    { datadir }}"
    creates: "{
    
    { datadir }}/mysql"
  tags: data
- name: config my.cnf
  template:
    src: my.cnf.j2
    dest: /etc/my.cnf
  notify:
    - restart mysqld
- name: config mysql_auth_sql
  template:
    src: mysql_auth_sql.j2
    dest: "{
    
    { basedir }}/mysql/mysql_auth_sql"
- name: service script
  copy:
    src: "{
    
    { basedir }}/mysql/support-files/mysql.server"
    dest: /etc/init.d/mysqld
    remote_src: yes
    mode: preserve
- name: PATH variable
  copy:
    content: 'PATH={
    
    { basedir }}/mysql/bin:$PATH'
    dest: /etc/profile.d/mysql.sh
- name: start mysql
  shell:
    cmd: chkconfig --add mysqld;/etc/init.d/mysqld start
  tags: service
- name: check whether mysql has remote access enabled
  shell:
    cmd: "{
    
    { basedir }}/mysql/bin/mysql -uroot  -e 'select user,host from mysql.user where user=\"root\" and host=\"localhost\";'"
  ignore_errors: yes
  register: check_mysql_remote
- name: debug var
  debug:
    var=check_mysql_remote
- name: mysql set remote
  shell:
    cmd: "{
    
    { basedir }}/mysql/bin/mysql < {
    
    { basedir }}/mysql/mysql_auth_sql"
  when: check_mysql_remote.rc ==0

3.1.4 handlers

cat main.yml
- name: restart mysqld
  service:
    name: mysqld
    state: restarted

3.1.5 template

cat my.cnf.j2
[mysqld]
server-id=1
log-bin
datadir={
    
    {
    
     datadir }}
socket={
    
    {
    
     datadir }}/mysql.sock
log-error={
    
    {
    
     datadir }}/mysql.log
pid-file={
    
    {
    
     datadir }}/mysql.pid
max_connections=1500
skip_name_resolve=on

[client]
socket={
    
    {
    
     datadir }}/mysql.sock


cat mysql_auth_sql.j2
ALTER USER "root"@"localhost" IDENTIFIED BY "{
    
    { mysql_root_password }}";
use mysql;
update user set host = "%" where user = "root";
flush privileges;
 ll files/
总用量 479420
-rw-r--r-- 1 root root 490922012 1031 05:43 mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz

4. 基于角色完成部署LNMP架构,并支持一键发布,回滚应用。同时基于zabbix角色批量部署zabbix。

4.1 基于角色完成部署LNMP架构

4.1.1 目录结构

 ll
总用量 52
-rw-r--r--  1 root root 19973 1029 21:23 ansible.cfg
-rw-r--r--  1 root root  1234 1031 05:44 hosts_mysql
-rw-r--r--  1 root root  1217 1115 23:41 hosts_redis
-rw-r--r--  1 root root  1327 1029 21:28 hosts_shopxo
-rw-r--r--  1 root root  1305 1029 21:24 hosts_wordpress
-rw-r--r--  1 root root    63 1031 06:37 mysql_role.yml
-rw-r--r--  1 root root    58 1115 17:17 redis_role.yml
drwxr-xr-x 11 root root   137 1029 21:23 roles
-rw-r--r--  1 root root    64 1029 21:23 shopxo_role.yml
-rw-r--r--  1 root root     0 1029 21:23 tomcat_role.yml
-rw-r--r--  1 root root    67 1029 21:23 wordpress_role.yml

4.1.2 hosts信息

mysql

[dbservers]
10.1.10.113
10.1.10.114

[dbservers:vars]
uid=306
user=mysql
gid=306
group=mysql
basedir="/usr/local"
datadir="/data/mysql"
mysql_version="8.0.20"
mysql_file="mysql-{
    
    {mysql_version}}-linux-glibc2.12-x86_64.tar.xz"
mysql_root_password=123456

redis

[redis]
10.1.10.113
10.1.10.114


[redis:vars]
uid=6379
user=redis
gid=6379
group=redis
redis_version="6.0.15"
redis_file="redis-{
    
    {redis_version}}.tar.gz"
redis_data_dir="/data/redis"
redis_base_dir="/usr/local"
redis_password=123456

nginx

hosts_wordpress

[webservers]
10.1.10.113
10.1.10.114

[webservers:vars]
[webservers]
10.1.10.113
10.1.10.114

[webservers:vars]
uid=88
user=www
gid=88
group=www
version="1.20.2"
url="http://nginx.org/download/nginx-{
    
    { version }}.tar.gz"
install_dir="/apps/nginx"
root_path=/data/wordpress
fqdn=www.wang.org
app=wordpress-6.0-zh_CN


shopxo

[webservers]
10.1.10.113
10.1.10.114

[webservers:vars]
uid=88
user=www
gid=88
group=www
version="1.20.2"
url="http://nginx.org/download/nginx-{
    
    { version }}.tar.gz"
install_dir="/apps/nginx"
root_path=/data/shopxo
fqdn=eshop.wang.org
app_version=2.2.3
app=shopxo-v{
    
    {
    
     app_version }}

4.1.3 总入口yml文件信息

mysql

cat mysql_role.yml
- hosts: dbservers
  remote_user: root

  roles:
    - mysql

redis

cat redis_role.yml
- hosts: redis
  remote_user: root

  roles:
    - redis

nginx

cat wordpress_role.yml
- hosts: webservers
  remote_user: root

  roles:
    - wordpress

cat shopxo_role.yml
- hosts: webservers
  remote_user: root

  roles:
    - shopxo

4.1.4 task代码

以下代码都是可复用,tags替换配置文件、重启服务
mysql (开启远程)
其目录结构

 tree roles/mysql/
roles/mysql/
├── files
│   └── mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz
├── handlers
│   └── main.yml
├── tasks
│   ├── main.yml
│   ├── main.yml_changed_when
│   └── main.yml_when
└── templates
    ├── my.cnf.j2
    └── mysql_auth_sql.j2

4 directories, 7 files

cat roles/mysql/tasks/main.yml
- name: create {
    
    {
    
     group }}
  group:
    name: "{
    
    { group }}"
    gid: "{
    
    { gid }}"
- name: create {
    
    {
    
     user }}
  user:
    name: "{
    
    { user }}"
    uid: "{
    
    { uid }}"
    group: "{
    
    { group }}"
    system: yes
    shell: /sbin/nologin
    create_home: yes
    home: "{
    
    { datadir }}"
- name: install packages
  yum:
    name: "{
    
    { item }}"
  loop:
    - ncurses-compat-libs
- name: copy tar to remote host and file mode
  unarchive:
    src: "{
    
    { mysql_file }}"
    dest: "{
    
    { basedir }}"
    group: "{
    
    { group }}"
    owner: "{
    
    { user }}"
    creates: "{
    
    { basedir }}/mysql-{
    
    { mysql_version }}-linux-glibc2.12-x86_64"
- name: create linkfile {
    
    {
    
     basedir }}/mysql
  file:
    src: "{
    
    { basedir }}/mysql-{
    
    { mysql_version }}-linux-glibc2.12-x86_64"
    dest: "{
    
    { basedir }}/mysql"
    state: link
- name: data dir
  shell:
    cmd: "{
    
    { basedir }}/mysql/bin/mysqld --initialize-insecure --user={
    
    { user }} --datadir={
    
    { datadir }}"
    creates: "{
    
    { datadir }}/mysql"
  tags: data
- name: config my.cnf
  template:
    src: my.cnf.j2
    dest: /etc/my.cnf
  notify:
    - restart mysqld
- name: config mysql_auth_sql
  template:
    src: mysql_auth_sql.j2
    dest: "{
    
    { basedir }}/mysql/mysql_auth_sql"
- name: service script
  copy:
    src: "{
    
    { basedir }}/mysql/support-files/mysql.server"
    dest: /etc/init.d/mysqld
    remote_src: yes
    mode: preserve
- name: PATH variable
  copy:
    content: 'PATH={
    
    { basedir }}/mysql/bin:$PATH'
    dest: /etc/profile.d/mysql.sh
- name: start mysql
  shell:
    cmd: chkconfig --add mysqld;/etc/init.d/mysqld start
  tags: service
- name: check whether mysql has remote access enabled
  shell:
    cmd: "{
    
    { basedir }}/mysql/bin/mysql -uroot  -e 'select user,host from mysql.user where user=\"root\" and host=\"localhost\";'"
  ignore_errors: yes
  register: check_mysql_remote
- name: debug var
  debug:
    var=check_mysql_remote
- name: mysql set remote
  shell:
    cmd: "{
    
    { basedir }}/mysql/bin/mysql < {
    
    { basedir }}/mysql/mysql_auth_sql"
  when: check_mysql_remote.rc ==0

redis

cat  roles/redis/tasks/main.yml
- name: yum install packages
  yum:
    name: "{
    
    { item }}"
  loop:
    - gcc
    - make
    - jemalloc-devel
    - systemd-devel

- name: create group {
    
    {
    
     group }}
  group:
    name: "{
    
    { group }}"
    gid: "{
    
    { gid }}"
- name: create user {
    
    {
    
     user }}
  user:
    name: "{
    
    { user }}"
    uid: "{
    
    { uid }}"
    group: "{
    
    { group }}"
    system: yes
    shell: /sbin/nologin
    create_home: yes
    home: "{
    
    { redis_data_dir }}"
- name: create redis rdb_data log  directory
  file:
    path: "{
    
    { redis_data_dir }}/{
    
    { item }}"
    state: directory
    group: "{
    
    { group }}"
    owner: "{
    
    { user }}"
    mode: '0755'
  loop:
    - "data"
    - "log"
- name:
  unarchive:
    src: "{
    
    { redis_file }}"
    dest: "{
    
    { redis_base_dir }}/src"
    creates: "{
    
    { redis_base_dir }}/src/redis-{
    
    { redis_version }}"
- name: install redis-{
    
    {
    
     redis_version }}
  shell:
    chdir: "{
    
    { redis_base_dir }}/src/redis-{
    
    { redis_version }}"
    cmd: "make -j 2 USE_SYSTEMD=yes PREFIX={
    
    { redis_base_dir }}/redis install"
    creates: "{
    
    { redis_base_dir }}/redis"
- name: Create an etc directory for storing redis.conf
  file:
    path: "{
    
    { redis_base_dir }}/redis/etc"
    state: directory
    mode: '0755'
- name: Copy the compiled redis.conf file to etc
  template:
    src: redis.conf.j2
    dest: "{
    
    { redis_base_dir }}/redis/etc/redis.conf"
  tags: redis_conf
  notify:
    - restart redis
- name: chown {
    
    {
    
     user }} {
    
    {
    
     redis_base_dir}}/redis
  shell:
    cmd: "chown -R {
    
    { redis_base_dir}}/redis;chmod 755 -R {
    
    { redis_data_dir }}"
- name: copy redis.service
  template:
    src: redis.service.j2
    dest: /lib/systemd/system/redis.service
  notify:
    - daemon-reload
- name: redis PATH variable
  copy:
    content: 'PATH={
    
    { redis_base_dir }}/redis/bin:$PATH'
    dest: /etc/profile.d/redis.sh
- name: Chanage net.core.somaxconn
  sysctl:
    name: net.core.somaxconn
    value: '1024'
    sysctl_set: yes
    state: present
- name: vm.overcommit_memory
  sysctl:
    name: vm.overcommit_memory
    value: '1'
    sysctl_set: yes
    state: present
- name: set transparent_hugepage
  shell:
    cmd: "echo never > /sys/kernel/mm/transparent_hugepage/enabled"
- name: start redis
  service:
    name: redis
    state: started
    enabled: yes

nginx

cat  roles/nginx/tasks/main.yml
- name: install packages
  yum:
    name: "{
    
    { item }}"
  loop:
    - gcc
    - make
    - pcre-devel
    - openssl-devel
    - zlib-devel
    - perl-ExtUtils-Embed

- name: get nginx source
  unarchive:
    src: "{
    
    { url }}"
    dest: "/usr/local/src"
    remote_src: yes

- name: compile and install
  shell:
    cmd: "./configure --prefix={
    
    { install_dir }} --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module &&  make && make install"
    chdir: "/usr/local/src/nginx-{
    
    { version }}"
    creates: "{
    
    {install_dir}}/sbin/nginx"

- name: create  {
    
    {
    
     group }}
  group:
    name: "{
    
    { group }}"
    gid: "{
    
    { gid}}"

- name: create {
    
    {
    
     user }}
  user:
    name: "{
    
    { user }}"
    uid: "{
    
    { uid }}"
    group: "{
    
    { group }}"
    system: yes

- name: copy config
  template:
    src: nginx.conf.j2
    dest: "{
    
    {install_dir}}/conf/nginx.conf"
  notify:
    - restart nginx

- name: config dir
  file:
    path: "{
    
    {install_dir}}/conf.d"
    state: directory

- name: config file mode
  file:
    path: "{
    
    {install_dir}}"
    owner: "{
    
    { user }}"
    group: "{
    
    { group }}"
    recurse: yes

- name: check nginx config
  shell:
    cmd: "{
    
    {install_dir}}/sbin/nginx -t"
  register: check_nginx_config
  changed_when:
    - check_nginx_config.stdout.find('successful')
    - false

- name: service file
  template:
    src: nginx.service.j2
    dest: /lib/systemd/system/nginx.service

- name: start nginx
  service:
    name: nginx
    state: started
    enabled: yes

php-fpm

cat roles/php-fpm/tasks/main.yml
- name: install packages
  yum:
    name: "{
    
    { item }}"
  loop:
    - php-fpm
    - php-mysqlnd
    - php-json
    - php-xml
    - php-gd
    - php-pecl-zip

- name: php path
  file:
    path: /var/lib/php/
    owner: "{
    
    { user }}"
    group: "{
    
    { group }}"
    recurse: yes

- name: config php.ini
  template:
    src: php.ini.j2
    dest: /etc/php.ini
  notify: restart php-fpm

- name: config www.conf
  template:
    src: w.conf.j2
    dest: /etc/php-fpm.d/www.conf
  notify: restart php-fpm

- name: config nginx
  template:
    src: php-fpm.conf.j2
    dest: "{
    
    { install_dir }}/conf.d/php-fpm.conf"
  notify: restart nginx


- name: start php-fpm
  service:
    name: php-fpm
    state: started
    enabled: yes

WordPress

 cat  roles/wordpress/tasks/main.yml
- name: mkdir wordpress directory
  file:
    path: /data/
    state: directory
    owner: "{
    
    { user }}"
    group: "{
    
    { group }}"
- name: down wordpress
  unarchive:
    src: "{
    
    {app}}.tar.gz"
    dest: /data/
    owner: "{
    
    { user }}"
    group: "{
    
    { group }}"

shopxo

- name: down {
    
    {
    
     app }}
  unarchive:
    src: "{
    
    {app}}.tar.gz"
    dest: /data/
    owner: "{
    
    { user }}"
    group: "{
    
    { group }}"


- name: link dir
  file:
    src: "/data/shopxo-{
    
    { app_version }}"
    path: "{
    
    { root_path }}"
    state: link

4.1.5 template文件内容

mysql

cat roles/mysql/templates/my.cnf.j2
[mysqld]
server-id=1
log-bin
datadir={
    
    {
    
     datadir }}
socket={
    
    {
    
     datadir }}/mysql.sock
log-error={
    
    {
    
     datadir }}/mysql.log
pid-file={
    
    {
    
     datadir }}/mysql.pid
max_connections=1500

[client]
socket={
    
    {
    
     datadir }}/mysql.sock`

cat roles/mysql/templates/mysql_auth_sql.j2
ALTER USER "root"@"localhost" IDENTIFIED BY "{
    
    { mysql_root_password }}";
use mysql;
update user set host = "%" where user = "root";
flush privileges;

redis

cat roles/redis/templates/redis.conf.j2
bind 0.0.0.0
requirepass  {
    
    {
    
     redis_password }}
masterauth   {
    
    {
    
     redis_password }}
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile {
    
    {
    
     redis_base_dir }}/bin/redis.pid
loglevel notice
logfile "{
    
    { redis_data_dir }}/log/redis.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir {
    
    {
    
     redis_data_dir }}/data
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

cat roles/redis/templates/redis.service.j2
[Unit]
Description=Redis persistent key-value database
After=network.target
[Service]
ExecStart={
    
    {
    
    redis_base_dir}}/redis/bin/redis-server {
    
    {
    
    redis_base_dir}}/redis/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
LimitNOFILE=1000000
[Install]
WantedBy=multi-user.target

nginx

cat roles/nginx/templates/nginx.conf.j2
user {
    
    {
    
     user }};
worker_processes  auto;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    
    
    worker_connections  1024;
}


http {
    
    
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;
    keepalive_timeout  65;
    include {
    
    {
    
    install_dir}}/conf.d/*.conf;
}


cat roles/nginx/templates/nginx.service.j2
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile={
    
    {
    
     install_dir }}/logs/nginx.pid
ExecStartPre=/usr/bin/rm -f {
    
    {
    
     install_dir }}/logs/nginx.pid
ExecStartPre={
    
    {
    
     install_dir }}/sbin/nginx -t
ExecStart={
    
    {
    
     install_dir }}/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=mixed
PrivateTmp=true

[Install]
WantedBy=multi-user.target

php-fpm

cat roles/php-fpm/templates/php-fpm.conf.j2
##
server {
    
    
    listen 80;
    server_name {
    
    {
    
     fqdn }};
    root {
    
    {
    
     root_path }};
    index index.php;
    location ~ \.php$ {
    
    
        root  {
    
    {
    
     root_path }}  ;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;

    }
}


grep -vE "^;|^$" roles/php-fpm/templates/php.ini.j2
[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = -1
disable_functions =
disable_classes =
zend.enable_gc = On
expose_php = On
max_execution_time = 360
max_input_time = 600
memory_limit = 128M
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
html_errors = On
variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 80M
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
default_charset = "UTF-8"
doc_root =
user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 80M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
[CLI Server]
cli_server.color = On
[Date]
date.timezone = Asia/Shanghai
[filter]
[iconv]
[intl]
[sqlite3]
[Pcre]
pcre.jit=0
[Pdo]
[Pdo_mysql]
pdo_mysql.cache_size = 2000
pdo_mysql.default_socket=
[Phar]
[mail function]
sendmail_path = /usr/sbin/sendmail -t -i
mail.add_x_header = On
[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1
[Interbase]
ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M:%S"
[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off
[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = Off
[PostgreSQL]
pgsql.allow_persistent = On
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice = 0
[bcmath]
bcmath.scale = 0
[browscap]
[Session]
session.save_handler = files
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.sid_length = 26
session.trans_sid_tags = "a=href,area=href,frame=src,form="
session.sid_bits_per_character = 5
[Assertion]
zend.assertions = -1
[mbstring]
[gd]
[exif]
[Tidy]
tidy.clean_output = Off
[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5
[sysvshm]
[ldap]
ldap.max_links = -1
[dba]
[curl]
[openssl]

grep -vE "^;|^$" roles/php-fpm/templates/www.conf.j2
[www]
user = {
    
    {
    
     user }}
group = {
    
    {
    
     group }}
listen = 127.0.0.1:9000
listen.acl_users = apache,nginx
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35



slowlog = /var/log/php-fpm/www-slow.log






php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache

4.1.6 handlers文件内容

handlers文件内容基本一致就不展开编写了

cat roles/mysql/handlers/main.yml
- name: restart mysqld
  service:
    name: mysqld
    state: restarted

4.1.7 meta文件内容

WordPress shopxo 需要依赖mysql、redis、nginx、php-fpm
files目录下文件在hosts文件里的变量有说明就不展开说明了

cat roles/wordpress/meta/main.yml
dependencies:
  - role: mysql
    vars:
      uid: 306
      user: mysql
      gid: 306
      group: mysql
      basedir: "/usr/local"
      datadir: "/data/mysql"
      mysql_version: "8.0.20"
      mysql_file: "mysql-{
    
    {mysql_version}}-linux-glibc2.12-x86_64.tar.xz"
      mysql_root_password: 123456

  - role: redis
    vars:
      uid: 6379
      user: redis
      gid: 6379
      group: redis
      redis_version: "6.0.15"
      redis_file: "redis-{
    
    {redis_version}}.tar.gz"
      redis_data_dir: "/data/redis"
      redis_base_dir: "/usr/local"
      redis_password: 123456

  - role: nginx
    vars:
      user: www
      group: www
      uid: 88
      gid: 88

  - role: php-fpm

4.1.8 开始展示安装WordPress

这里我手动把2台被控端服务都停了,部署的文件也保留
在这里插入图片描述

ansible-playbook -i hosts_wordpress wordpress_role.yml

PLAY [webservers] ******************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [mysql : create www] **********************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [mysql : create www] **********************************************************************************************************************
changed: [10.1.10.113]
changed: [10.1.10.114]

TASK [mysql : install packages] ****************************************************************************************************************
ok: [10.1.10.113] => (item=ncurses-compat-libs)
ok: [10.1.10.114] => (item=ncurses-compat-libs)

TASK [mysql : copy tar to remote host and file mode] *******************************************************************************************
skipping: [10.1.10.113]
skipping: [10.1.10.114]

TASK [mysql : create linkfile /usr/local/mysql] ************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [mysql : data dir] ************************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [mysql : config my.cnf] *******************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [mysql : config mysql_auth_sql] ***********************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [mysql : service script] ******************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [mysql : PATH variable] *******************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [mysql : start mysql] *********************************************************************************************************************
changed: [10.1.10.114]
changed: [10.1.10.113]

TASK [mysql : check whether mysql has remote access enabled] ***********************************************************************************
fatal: [10.1.10.113]: FAILED! => {
    
    "changed": true, "cmd": "/usr/local/mysql/bin/mysql -uroot  -e 'select user,host from mysql.user where user=\"root\" and host=\"localhost\";'", "delta": "0:00:00.357809", "end": "2022-12-02 23:39:25.215392", "msg": "non-zero return code", "rc": 1, "start": "2022-12-02 23:39:24.857583", "stderr": "ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)", "stderr_lines": ["ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)"], "stdout": "", "stdout_lines": []}
...ignoring
fatal: [10.1.10.114]: FAILED! => {
    
    "changed": true, "cmd": "/usr/local/mysql/bin/mysql -uroot  -e 'select user,host from mysql.user where user=\"root\" and host=\"localhost\";'", "delta": "0:00:00.352758", "end": "2022-12-02 23:39:25.285422", "msg": "non-zero return code", "rc": 1, "start": "2022-12-02 23:39:24.932664", "stderr": "ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)", "stderr_lines": ["ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [mysql : debug var] ***********************************************************************************************************************
ok: [10.1.10.113] => {
    
    
    "check_mysql_remote": {
    
    
        "changed": true,
        "cmd": "/usr/local/mysql/bin/mysql -uroot  -e 'select user,host from mysql.user where user=\"root\" and host=\"localhost\";'",
        "delta": "0:00:00.357809",
        "end": "2022-12-02 23:39:25.215392",
        "failed": true,
        "msg": "non-zero return code",
        "rc": 1,
        "start": "2022-12-02 23:39:24.857583",
        "stderr": "ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)",
        "stderr_lines": [
            "ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)"
        ],
        "stdout": "",
        "stdout_lines": []
    }
}
ok: [10.1.10.114] => {
    
    
    "check_mysql_remote": {
    
    
        "changed": true,
        "cmd": "/usr/local/mysql/bin/mysql -uroot  -e 'select user,host from mysql.user where user=\"root\" and host=\"localhost\";'",
        "delta": "0:00:00.352758",
        "end": "2022-12-02 23:39:25.285422",
        "failed": true,
        "msg": "non-zero return code",
        "rc": 1,
        "start": "2022-12-02 23:39:24.932664",
        "stderr": "ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)",
        "stderr_lines": [
            "ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)"
        ],
        "stdout": "",
        "stdout_lines": []
    }
}

TASK [mysql : mysql set remote] ****************************************************************************************************************
skipping: [10.1.10.113]
skipping: [10.1.10.114]

TASK [redis : yum install packages] ************************************************************************************************************
ok: [10.1.10.113] => (item=gcc)
ok: [10.1.10.114] => (item=gcc)
ok: [10.1.10.113] => (item=make)
ok: [10.1.10.114] => (item=make)
ok: [10.1.10.114] => (item=jemalloc-devel)
ok: [10.1.10.113] => (item=jemalloc-devel)
ok: [10.1.10.113] => (item=systemd-devel)
ok: [10.1.10.114] => (item=systemd-devel)

TASK [redis : create group www] ****************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [redis : create user www] *****************************************************************************************************************
changed: [10.1.10.114]
changed: [10.1.10.113]

TASK [redis : create redis rdb_data log  directory] ********************************************************************************************
changed: [10.1.10.113] => (item=data)
changed: [10.1.10.114] => (item=data)
changed: [10.1.10.113] => (item=log)
changed: [10.1.10.114] => (item=log)

TASK [redis : unarchive] ***********************************************************************************************************************
skipping: [10.1.10.113]
skipping: [10.1.10.114]

TASK [redis : install redis-6.0.15] ************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [redis : Create an etc directory for storing redis.conf] **********************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [redis : Copy the compiled redis.conf file to etc] ****************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [redis : chown www /usr/local/redis] ******************************************************************************************************
changed: [10.1.10.113]
changed: [10.1.10.114]

TASK [redis : copy redis.service] **************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [redis : redis PATH variable] *************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [redis : Chanage net.core.somaxconn] ******************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [redis : vm.overcommit_memory] ************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [redis : set transparent_hugepage] ********************************************************************************************************
changed: [10.1.10.113]
changed: [10.1.10.114]

TASK [redis : start redis] *********************************************************************************************************************
changed: [10.1.10.114]
changed: [10.1.10.113]

TASK [nginx : install packages] ****************************************************************************************************************
ok: [10.1.10.113] => (item=gcc)
ok: [10.1.10.114] => (item=gcc)
ok: [10.1.10.114] => (item=make)
ok: [10.1.10.113] => (item=make)
ok: [10.1.10.113] => (item=pcre-devel)
ok: [10.1.10.114] => (item=pcre-devel)
ok: [10.1.10.113] => (item=openssl-devel)
ok: [10.1.10.114] => (item=openssl-devel)
ok: [10.1.10.113] => (item=zlib-devel)
ok: [10.1.10.114] => (item=zlib-devel)
ok: [10.1.10.114] => (item=perl-ExtUtils-Embed)
ok: [10.1.10.113] => (item=perl-ExtUtils-Embed)

TASK [nginx : get nginx source] ****************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [nginx : compile and install] *************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [nginx : create  www] *********************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [nginx : create www] **********************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [nginx : copy config] *********************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [nginx : config dir] **********************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [nginx : config file mode] ****************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [nginx : check nginx config] **************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [nginx : service file] ********************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [nginx : start nginx] *********************************************************************************************************************
changed: [10.1.10.114]
changed: [10.1.10.113]

TASK [php-fpm : install packages] **************************************************************************************************************
ok: [10.1.10.113] => (item=php-fpm)
ok: [10.1.10.114] => (item=php-fpm)
ok: [10.1.10.114] => (item=php-mysqlnd)
ok: [10.1.10.113] => (item=php-mysqlnd)
ok: [10.1.10.113] => (item=php-json)
ok: [10.1.10.114] => (item=php-json)
ok: [10.1.10.113] => (item=php-xml)
ok: [10.1.10.114] => (item=php-xml)
ok: [10.1.10.113] => (item=php-gd)
ok: [10.1.10.114] => (item=php-gd)
ok: [10.1.10.113] => (item=php-pecl-zip)
ok: [10.1.10.114] => (item=php-pecl-zip)

TASK [php-fpm : php path] **********************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [php-fpm : config php.ini] ****************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [php-fpm : config www.conf] ***************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

TASK [php-fpm : config nginx] ******************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [php-fpm : start php-fpm] *****************************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [wordpress : mkdir wordpress directory] ***************************************************************************************************
ok: [10.1.10.113]
ok: [10.1.10.114]

TASK [wordpress : down wordpress] **************************************************************************************************************
ok: [10.1.10.114]
ok: [10.1.10.113]

PLAY RECAP *************************************************************************************************************************************
10.1.10.113                : ok=46   changed=9    unreachable=0    failed=0    skipped=3    rescued=0    ignored=1
10.1.10.114                : ok=46   changed=9    unreachable=0    failed=0    skipped=3    rescued=0    ignored=1

在这里插入图片描述
在这里插入图片描述

回滚的话是根据templates下配置文件手动进行替换然后调度handlers重启服务

4.2 基于zabbix角色批量部署zabbix(依赖于原先部署好的LNMP)

4.2.1 zabbix_server、zabbix_agent2增加角色

tree roles/zabbix_*
roles/zabbix_agent2
├── defaults
│   └── main.yml
├── files
│   └── zabbix_agent2.d
│       ├── mem.conf
│       ├── nginx_state.conf
│       ├── not_allow_ip.conf
│       ├── script
│       │   └── not_allow_ip_count.sh
│       ├── tcp.state.conf
│       └── user_login_count.conf
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
│   └── zabbix_agent2.conf.j2
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml
roles/zabbix_server
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
│   ├── zabbix.conf.j2
│   ├── zabbix_ngx.conf.j2
│   └── zabbix_server.conf.j2
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

18 directories, 26 files

 pwd
/data/ansible
# #ansible-galaxy init roles/zabbix_server/
# #ansible-galaxy init roles/zabbix_agent2/

4.2.2 host、role文件展示

cat zabbix_role.yml
- hosts: zabbix_server
  remote_user: root
  roles:
    - zabbix_server

- hosts: zabbix_agent2
  remote_user: root
  roles:
    - zabbix_agent2
[root@shudun ansible]# cat hosts_zabbix
[zabbix_server]
10.1.10.115

[zabbix_server:vars]
ansible_python_interpreter="/usr/bin/python3"
zabbix_server_domain="www.zabbixtest_v2.com"



[zabbix_agent2]
#10.1.10.65
#10.1.10.71
10.1.10.113
10.1.10.114
10.1.10.115

[zabbix_agent2:vars]
zabbix_server_ip="10.1.10.115"
zabbix_ver="5.0"

4.2.3 task代码展示

!注意:mysql_db使用了pymysql的模块需要在两端安装对应模块,而且运行过程中可能出现已经创建库了再执行报错情况,可以ignore_errors

zabbix-server

cat roles/zabbix_server/tasks/main.yml
- name: install zabbix-server
  dnf:
    name: " {
    
    { item }}"
  loop:
    - zabbix-server-mysql
    - zabbix-web-mysql
    - zabbix-get
- name: create zabbix-server database
  mysql_db:
    login_host: "localhost"
    login_user: "root"
    login_password: "{
    
    { mysql_root_password }}"
    login_port: "3306"
    name: "zabbix"
    encoding: "utf8"
    state: "present"
  tags: test_pymysql #适配mysql模块

- name: create zabbix-server user
  mysql_user:
    login_host: "localhost"
    login_user: "root"
    login_password: "{
    
    { mysql_root_password }}"
    name: zabbix             ##用户名
    host: "%"
    password: "{
    
    { mysql_root_password }}" #用户密码,这里设立变量不给明文更安全
    priv: 'zabbix.*:ALL'  #将zabbix数据库的权限给出
    state: present

- name: init zabbix-server db
  mysql_db:
    login_host: "localhost"
    login_user: "root"
    login_password: "{
    
    { mysql_root_password }}"
    name: zabbix
    state: import
    target: /usr/share/doc/zabbix-server-mysql/create.sql.gz
  ignore_errors: yes
  tags: import_db

- name: copy zabbix_server.conf template
  template:
    src: zabbix_server.conf.j2
    dest: /etc/zabbix/zabbix_server.conf
    mode: 0600
    owner: "{
    
    { user }}"
    group: "{
    
    { group }}"
  notify:
    - restart zabbix-server
  tags: restart_zabbix-server

- name: chown {
    
    {
    
     user }} zabbix-web
  file:
    path:  /etc/zabbix/web
    state: directory
    owner: "{
    
    { user }}"
    group: "{
    
    { group }}"
    recurse: yes


- name: copy zabbix-ngx.conf template
  template:
    src: zabbix_ngx.conf.j2
    dest: "{
    
    { install_dir }}/conf.d/zabbix_ngx.conf"
    owner: "{
    
    { user }}"
    group: "{
    
    { group }}"

  notify:
    - restart nginx

- name: copy zabbix.conf template substitute yum install
  template:
    src: zabbix.conf.j2
    dest: "/etc/php-fpm.d/zabbix.conf"

  notify:
    - restart php-fpm
- name: start zabbix server service
  service:
    name: zabbix-server
    state: restarted
    enabled: yes

依赖meta(!注意的是引用别的角色作为依赖的时候需要把相关vars写进去)

cat roles/zabbix_server/meta/main.yml
dependencies:
  - role: mysql
    vars:
      uid: 306
      user: mysql
      gid: 306
      group: mysql
      basedir: "/usr/local"
      datadir: "/data/mysql"
      mysql_version: "8.0.20"
      mysql_file: "mysql-{
    
    {mysql_version}}-linux-glibc2.12-x86_64.tar.xz"
      mysql_root_password: 123456

  - role: nginx
    vars:
      user: www
      group: www
      uid: 88
      gid: 88
      version: "1.20.2"
      url: "http://nginx.org/download/nginx-{
    
    { version }}.tar.gz"
      install_dir: "/apps/nginx"


  - role: php-fpm
    root_path: /data/wordpress
    fqdn: www.wang.org
    app: wordpress-6.0-zh_CN

zabbix-agent2

cat roles/zabbix_agent2/tasks/main.yml
- name: install repo package for CentOS 7
  yum:
    name: "https://repo.zabbix.com/zabbix/{
    
    { zabbix_ver }}/rhel/{
    
    { ansible_distribution_major_version }}/x86_64/zabbix-release-{
    
    { zabbix_ver }}-1.el{
    
    { ansible_distribution_major_version }}.noarch.rpm"
  when:
    - ansible_facts['distribution'] == "CentOS"
    - ansible_facts['distribution_major_version'] == "7"
- name: install repo package for CentOS 8
  dnf:
    name: "https://repo.zabbix.com/zabbix/{
    
    { zabbix_ver }}/rhel/{
    
    { ansible_distribution_major_version }}/x86_64/zabbix-release-{
    
    { zabbix_ver }}-1.el{
    
    { ansible_distribution_major_version }}.noarch.rpm"
    disable_gpg_check: yes
  #shell:
  #  cmd: "yum -y install https://repo.zabbix.com/zabbix/{
    
    { zabbix_ver }}/rhel/{
    
    { ansible_distribution_major_version }}/x86_64/zabbix-release-{
    
    { zabbix_ver }}-1.el{
    
    { ansible_distribution_major_version }}.noarch.rpm"
    #  register: check_zabbix_agent2_url
    #- name: debug zabbix_agent2_url
    #  debug:
    #    meg: "{
    
    { check_zabbix_agent2_url }}"
  when:
    - ansible_facts['distribution'] == "CentOS"
    - ansible_facts['distribution_major_version'] == "8"

- name: download repo package for Ubuntu 18.04
  get_url:
    url: "https://repo.zabbix.com/zabbix/{
    
    { zabbix_ver }}/ubuntu/pool/main/z/zabbix-release/zabbix-release_{
    
    { zabbix_ver }}-1+{
    
    { ansible_distribution_release }}_all.deb"
    dest: /opt/
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_major_version'] == "18"

- name: install repo package for ubuntu 18.04
  shell: "dpkg -i /opt/zabbix-release_{
    
    { zabbix_ver }}-1+{
    
    { ansible_distribution_release }}_all.deb"
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_major_version'] == "18"

- name: aliyun repo for CentOS
  replace:
    path: /etc/yum.repos.d/zabbix.repo
    regexp: 'repo.zabbix.com'
    replace: 'mirrors.aliyun.com/zabbix'
  when: ansible_facts['distribution'] == "CentOS"

- name: aliyun repo for Ubuntu 18.04
  replace:
    path: /etc/apt/sources.list.d/zabbix.list
    regexp: 'repo.zabbix.com'
    replace: 'mirrors.aliyun.com/zabbix'
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_major_version'] == "18"

- name: install zabbix agent packages for CentOS 7
  yum:
    name: zabbix-agent2
  when:
    - ansible_facts['distribution'] == "CentOS"
    - ansible_facts['distribution_major_version'] == "7"
- name: install zabbix agent packages for CentOS 8
  dnf:
    name: zabbix-agent2
  when:
    - ansible_facts['distribution'] == "CentOS"
    - ansible_facts['distribution_major_version'] == "8"
- name: install zabbix agent packages for ubuntu 18.04
  apt:
    name: zabbix-agent2
    update_cache: yes
  when:
    - ansible_facts['distribution'] == "Ubuntu"
    - ansible_facts['distribution_major_version'] == "18"

- name: zabbix agent config file
  template:
    src: zabbix_agent2.conf.j2
    dest: /etc/zabbix/zabbix_agent2.conf
    mode: 0644

  notify:
    - restart zabbix-agent2

- name: copy zabbix-agten2.d dir
  copy:
    src: zabbix_agent2.d
    dest: /etc/zabbix
    preserver: yes
  notify:
    - restart zabbix-agent2
  tags: agent2.d

- name: start zabbix agent2 service
  service:
    name: zabbix-agent2
    state: restarted
    enabled: yes

4.2.4 最后template、handlers展示

zabbix-server template

cat roles/zabbix_server/templates/zabbix_ngx.conf.j2
server {
    
    
    listen 80;
    server_name {
    
    {
    
     zabbix_server_domain }};
    root /usr/share/zabbix;
    index index.php;
    location = /favicon.ico {
    
    
                log_not_found   off;
        }

        location / {
    
    
                try_files       $uri $uri/ =404;
        }

        location /assets {
    
    
                access_log      off;
                expires         10d;
        }

        location ~ /\.ht {
    
    
                deny            all;
        }

        location ~ /(api\/|conf[^\.]|include|locale|vendor) {
    
    
                deny            all;
                return          404;
        }
    location ~ [^/]\.php(/|$) {
    
    
                fastcgi_pass   127.0.0.1:9000;
                #fastcgi_pass    unix:/run/php-fpm/zabbix.sock;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_index   index.php;

                fastcgi_param   DOCUMENT_ROOT   /usr/share/zabbix;
                fastcgi_param   SCRIPT_FILENAME /usr/share/zabbix$fastcgi_script_name;
                fastcgi_param   PATH_TRANSLATED /usr/share/zabbix$fastcgi_script_name;

                include fastcgi_params;
                fastcgi_param   QUERY_STRING    $query_string;
                fastcgi_param   REQUEST_METHOD  $request_method;
                fastcgi_param   CONTENT_TYPE    $content_type;
                fastcgi_param   CONTENT_LENGTH  $content_length;

                fastcgi_intercept_errors        on;
                fastcgi_ignore_client_abort     off;
                fastcgi_connect_timeout         60;
                fastcgi_send_timeout            180;
                fastcgi_read_timeout            180;
                fastcgi_buffer_size             128k;
                fastcgi_buffers                 4 256k;
                fastcgi_busy_buffers_size       256k;
                fastcgi_temp_file_write_size    256k;
        }

}

cat roles/zabbix_server/templates/zabbix_
zabbix_ngx.conf.j2     zabbix_server.conf.j2
[root@shudun ansible]# cat roles/zabbix_server/templates/zabbix_server.conf.j2
LogFile=/var/log/zabbix/zabbix_server.log
LogFileSize=0
PidFile=/var/run/zabbix/zabbix_server.pid
SocketDir=/var/run/zabbix
DBName=zabbix
DBUser=zabbix
DBHost={
    
    {
    
     ansible_default_ipv4.address }}
#DBSocket={
    
    { datadir }}/mysql.sock
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
Timeout=4
AlertScriptsPath=/usr/lib/zabbix/alertscripts
ExternalScripts=/usr/lib/zabbix/externalscripts
LogSlowQueries=3000
StatsAllowedIP=127.0.0.1
DBPassword={
    
    {
    
     mysql_root_password }}

zabbix-server handlers

cat roles/zabbix_server/handlers/main.yml
- name: restart zabbix-server
  service:
    name: zabbix-server
    state: restarted

- name: restart nginx
  service:
    name: nginx
    state: reloaded

- name: restart php-fpm
  service:
    name: php-fpm
    state: restarted

zabbix-agent2 template

cat roles/zabbix_agent2/templates/zabbix_agent2.conf.j2
##
PidFile=/var/run/zabbix/zabbix_agent2.pid
LogFile=/var/log/zabbix/zabbix_agent2.log
LogFileSize=0
Server={
    
    {
    
     zabbix_server_ip }}
ServerActive={
    
    {
    
     zabbix_server_ip }}
Hostname={
    
    {
    
     ansible_default_ipv4.address }}
Include=/etc/zabbix/zabbix_agent2.d/*.conf
ControlSocket=/tmp/agent.sock

zabbix-agent2 handlers

cat roles/zabbix_agent2/handlers/main.yml
- name: restart zabbix-agent2
  service:
    name: zabbix-agent2
    state: restarted

4.2.5 执行展示

在这里插入图片描述

4.2.6 测试

pwd
/etc/zabbix
[root@shudun zabbix]# cat zabbix_agent2.d/mem.conf
UserParameter=mem_use_percent,free | awk 'NR==2{print $3/$2*100}'
UserParameter=mem_unuse_percent,free | awk 'NR==2{print 100-($3/$2*100)}'
[root@shudun zabbix]# zabbix_get -s 10.1.10.113 -k mem_use_percent
9.77897
[root@shudun zabbix]# zabbix_get -s 10.1.10.114 -k mem_use_percent
9.10477
[root@shudun zabbix]# zabbix_get -s 10.1.10.115 -k mem_use_percent
11.1653
[root@shudun zabbix]# cat zabbix_agent2.d/tcp.state.conf
UserParameter=tcp_state[*], netstat -nat | grep -c $1
zabbix_get -s 10.1.10.115 -k tcp_state[ESTABLISHED]
56

我会将代码传到Gitee,有兴趣的小伙伴可以自行down下来
gitee地址

猜你喜欢

转载自blog.csdn.net/qq_46229380/article/details/128417901