萧瑟风雨中 发表于 2023-1-10 11:09:05

Ansible介绍以及基于角色搭建LNMP和zabbix

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主控端能基于密钥认证的方式联系各个被管理节点
1.1 ansible-doc

此工具用来显示模块帮助,相当于man
格式
ansible-doc
-l, --list #列出可用模块
-s, --snippet #显示指定模块的playbook片段范例:
#列出所有模块
ansible-doc -l
#查看指定模块帮助用法
ansible-doc ping
#查看指定模块帮助用法
ansible-doc -s ping范例: 查看指定的插件
$ ansible-doc -t connection -l
$ ansible-doc -t lookup -l1.2 ansible

1.2.1 Ansible Ad-Hoc 介绍

Ansible Ad-Hoc 的执行方式的主要工具就是 ansible
特点: 一次性的执行,不会保存执行命令信息,只适合临时性或测试性的任务
1.2.2 ansible 命令用法

格式:
ansible <host-pattern> [-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的run as用户,默认为root
-K, --ask-become-pass                   #提示输入sudo时的口令
-f FORKS, --forks FORKS               #指定并发同时执行ansible任务的主机数
-i INVENTORY, --inventory INVENTORY   #指定主机清单文件范例:
#先打通基于key验证
#以yanlinux用户执行ping存活检测
$ ansible all -m ping -u yanlinux
10.0.0.18 | SUCCESS => {
    "ansible_facts": {
      "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.102 | SUCCESS => {
    "ansible_facts": {
      "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.7 | SUCCESS => {
    "ansible_facts": {
      "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

#以yanlinux sudo至root执行命令
##没有添加sudo授权之前
$ ansible all -a 'ls /root'
10.0.0.18 | FAILED | rc=2 >>
ls: cannot open directory '/root': Permission deniednon-zero return code
10.0.0.102 | FAILED | rc=2 >>
ls: cannot open directory '/root': Permission deniednon-zero return code
10.0.0.7 | FAILED | rc=2 >>
ls: cannot open directory /root: Permission deniednon-zero return code
##在所有被控制主机上都加上suod授权
$ echo "yanlinux    ALL=(ALL)   NOPASSWD: ALL" >> /etc/sudoers
$ ansible all -a 'ls /root' -b
10.0.0.102 | CHANGED | rc=0 >>
init_os.sh
snap
10.0.0.7 | CHANGED | rc=0 >>
anaconda-ks.cfg
init_os.sh
10.0.0.18 | CHANGED | rc=0 >>
anaconda-ks.cfg
init_os.sh
##所有被管理主机上创建用户magedu
$ ansible all -a 'useradd magedu' -b
10.0.0.102 | CHANGED | rc=0 >>

10.0.0.18 | CHANGED | rc=0 >>

10.0.0.7 | CHANGED | rc=0 >>

$ ansible all -a 'getent passwd magedu' -b
10.0.0.7 | CHANGED | rc=0 >>
magedu:x:1002:1002::/home/magedu:/bin/bash
10.0.0.102 | CHANGED | rc=0 >>
magedu:x:1001:1001::/home/magedu:/bin/sh
10.0.0.18 | CHANGED | rc=0 >>
magedu:x:1001:1001::/home/magedu:/bin/bash范例: 并发执行控制
#并发是1一个主机一个主机的执行,一条条返回结果
$ ansible all -a 'sleep 5' -f1
#并发是10,同时10个主机执行命令,返回结果
$ ansible all -a 'sleep 5' -f10范例: 使用普通用户连接远程主机执行代替另一个用户身份执行操作
#在被管理主机上创建用户并sudo授权
$ useradd magedu
$ echo magedu:centos1 |chpasswd

#以yanlinux的用户连接用户并利用sudo代表magedu执行whoami命令
$ ansible all -a 'whoami' -b --become-user=magedu
10.0.0.18 | CHANGED | rc=0 >>
magedu
10.0.0.7 | CHANGED | rc=0 >>
magedu1.3 ansible-console

此工具可交互执行命令,支持tab,ansible 2.0+新增
提示符格式:
执行用户@当前操作的主机组 (当前组的主机数量)$常用子命令:

[*]设置并发数: forks n 例如: forks 10
[*]切换组: cd 主机组 例如: cd web
[*]列出当前组主机列表: list
[*]列出所有的内置命令: ?或help
范例
$ ansible-console
Welcome to the ansible console. Type help or ? to list commands.

root@all (3)$ ping
10.0.0.18 | SUCCESS => {
    "ansible_facts": {
      "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.102 | SUCCESS => {
    "ansible_facts": {
      "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.7 | SUCCESS => {
    "ansible_facts": {
      "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
root@all (3)$ list
10.0.0.18
10.0.0.7
10.0.0.102
root@all (3)$ cd websrvs
root@websrvs (2)$ list
10.0.0.18
10.0.0.7
root@websrvs (2)$ forks 10
root@websrvs (2)$ cd appsrvs
root@appsrvs (2)$ list
10.0.0.102
10.0.0.181.4 ansible-playbook

此工具用于执行编写好的 playbook 任务
范例:
$ vi hello.yml
---
#hello world yml file
- hosts: websrvs
remote_user: root
gather_facts: no

tasks:
    - name: hello world
      command: /usr/bin/wall hello world
$ ansible-playbook hello.yml

PLAY ****************************************************************************************

TASK ************************************************************************************
changed:
changed:

PLAY RECAP ********************************************************************************************
10.0.0.18                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.7                   : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

1.5 ansible-vault

此工具可以用于加密解密yml文件
格式:
ansible-vault 范例:
#1 加密
$ ansible-vault encrypt hello.yml
New Vault password:
Confirm New Vault password:
Encryption successful
##查看文件内容
$ cat hello.yml
$ANSIBLE_VAULT;1.1;AES256
65323766623831636563636132623333623932633461396563383764333037396563633766363231
3335646336346136626231353133623566626166626336380a306630643338353031353739353538
62373930306636633430653537363534376231323839643131376335653366656634616365663063
6236663364343461610a383365643534646564316261326166316233393039386134363436313138
63323939663537666462646233613262646637306130626336336239323737623833393735666364
36336334316666326265356166326163373039616533353564353964396266376637363037353338
37623639656262303966363766356630376466666463363338353535623635633137616335383333
65333263643762353264326563326362393663316538666530616664643438666435373162616164
30313761323030343165666330326537653430333764363834326566333666316133386465663334
63353035616266396366366662643839353431653736353465626261623433343735663534663831
32636632653730323465366531353531633761623930303138643337613162613062333237633566
39663562393535343165

#2 解密
$ ansible-vault decrypt hello.yml
Vault password:
Decryption successful
$ 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
      
#3 查看加密后的yml文件内容
$ ansible-vault view hello.yml
Vault password:
---
#hello world yml file
- hosts: websrvs
remote_user: root
gather_facts: no

tasks:
    - name: hello world
      command: /usr/bin/wall hello world

#4 编辑加密文件
$ ansible-vault edit hello.yml
Vault password:             #输入密码后进入vim编辑器进行编辑

#5 修改口令
$ ansible-vault rekey hello.yml
Vault password:    #先前的口令
New Vault password:#修改为的口令
Confirm New Vault password:#再确认一遍
Rekey successful

#6 创建加密新文件
$ ansible-vault create new.yml
New Vault password:
Confirm New Vault password:

#7 交互式输入密码来执行加密文件
$ ansible-playbook --ask-vault-pass hello.yml
Vault password:

PLAY ****************************************************************************************

TASK ************************************************************************************
changed:
changed:

PLAY RECAP ********************************************************************************************
10.0.0.18                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.7                   : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

#8 从文件中读取密码
$ ansible-playbook --vault-password-file pass.txt hello.yml

PLAY ****************************************************************************************

TASK ************************************************************************************
changed:
changed:

PLAY RECAP ********************************************************************************************
10.0.0.18                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.7                   : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

#9 从配置文件中添加密码文件
$ vi /etc/ansible/ansible.cfg
#添加以下一行信息
ault-password-file=pass.txt
$ ansible-playbook hello.yml

PLAY ****************************************************************************************

TASK ************************************************************************************
changed:
changed:

PLAY RECAP ********************************************************************************************
10.0.0.18                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.7                   : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=01.6 ansible-galaxy

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

Found 100 roles matching your search:

Name                                    Description
----                                    -----------
abhiarun_94.apache_lamp                   your role description
adelaidearnauld.galaxy-lamp               your description
adelaidearnauld.lamp_compose            your description
ajish_antony.ansible_lamp               your role description
AlexanderAllen.Liara                      The sexiest toolkit for LAMP hackers.
alphinaugustine.ansible_role            your description
amtega.horde                              Setup horde
......


#2 列出所有已安装的galaxy
$ ansible-galaxy list
# /usr/share/ansible/roles
# /etc/ansible/roles


#3 安装galaxy,默认下载到~/.ansible/roles
$ ansible-galaxy install 想要安装的galaxy

#删除
ansible-galaxy remove 2 总结ansible role目录结构及文件用途。

roles目录结构:
├── playbook1.yml
├── playbook2.yml
├── roles/
│   ├── project1/
│   │        ├── tasks/
│   │        ├── files/
│   │        ├── vars/
│   │        ├── templates/
│   │        ├── handlers/
│   │        ├── default/
│   │        └── meta/
│   ├── project2/
│   │        ├── tasks/
│   │        ├── files/
│   │        ├── vars/
│   │        ├── templates/
│   │        ├── handlers/
│   │        ├── default/
│   │        └── meta/Roles各目录作用
roles/project/ :项目名称,有以下子目录

[*]files/ :存放由copy或script模块等调用的文件
[*]templates/:template模块查找所需要模板文件的目录
[*]tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
[*]handlers/:至少应该包含一个名为main.yml的文件;此目录下的其它的文件需要在此文件中通过include进行包含
[*]vars/:定义变量,至少应该包含一个名为main.yml的文件;此目录下的其它的变量文件需要在此文件中通过include进行包含,也可以通过项目目录中的group_vars/all定义变量,从而实现角色通用代码和项目数据的分离
[*]meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
[*]default/:设定默认变量时使用此目录中的main.yml文件,比vars的优先级低
3 使用ansible playbook实现一个mysql角色。

#mysql角色目录
$ tree
.
├── ansible.cfg
├── hosts
├── mysql_role.yml
└── roles
   └── mysql
     ├── files
     │   └── mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz
     ├── tasks
     │   └── main.yml
     └── templates
       └── my.cnf.j2
       
#定义主机及变量
$ tail -n9 hosts

db_group=mysql
db_gid=306
db_user=mysql
db_uid=306
db_version=8.0.31
db_file="mysql-{{db_version}}-linux-glibc2.12-x86_64.tar.xz"
db_data_dir="/data/mysql"
db_root_passwd="lgq123456**"

#下载准备mysql源文件包
$ ls roles/mysql/files/
mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz

#创建task文件
$ cat roles/mysql/tasks/main.yml
- name: install dependent package
yum:
    name: "{{ item }}"
loop:
    - libaio
    - numactl-libs

- name: create mysql group
group: name={{db_group}} gid={{db_gid}}

- name: create mysql user
user: name={{db_user}} uid={{db_uid}} system=yes shell="/sbin/nologin" create_home=no group={{db_group}}

- name: copy tar to remote host and file mode
unarchive:
    src: "{{ db_file }}"
    dest: "/usr/local/"
    owner: root
    group: root

- name: create lingfile /usr/local/mysql
file:
    src: "/usr/local/mysql-{{ db_version }}-linux-glibc2.12-x86_64"
    dest: "/usr/local/mysql"
    state: link

- name: path file
copy:
    content: "PATH=/usr/local/mysql/bin:$PATH"
    dest: "/etc/profile.d/mysql.sh"

- name: config file
template:
    src: my.cnf.j2
    dest: "/etc/my.cnf"

- name: create directory
file:
    name: "/data"
    state: directory

- name: init mysql data
shell:
    cmd: "/usr/local/mysql/bin/mysqld --initialize-insecure --user={{ db_user }} --datadir={{ db_data_dir }}"
tags:
    - init

- name: service script
copy:
    src: "/usr/local/mysql/support-files/mysql.server"
    dest: "/etc/init.d/mysqld"
    remote_src: yes
    mode: '+x'

- name: start service
shell:
    cmd: chkconfig --add mysqld;chkconfig mysqld on;service mysqld start

- name: change root password
shell:
    cmd: "/usr/local/mysql/bin/mysqladmin -uroot password {{ db_root_passwd }}"
   
   
#准备MySQL 配置文件模板
$ cat roles/mysql/templates/my.cnf.j2

server-id=1
log-bin
datadir={{ db_data_dir }}
socket={{ db_data_dir }}/mysql.sock
log-error={{ db_data_dir }}/mysql.log
pid-file={{ db_data_dir }}/mysql.pid


socket={{ db_data_dir }}/mysql.sock

#准备MySQL角色playbook文件
$ cat mysql_role.yml
- hosts: dbsrvs
remote_user: root
gather_facts: no

roles:
    - mysql
   
#部署MySQL
$ ansible-playbook -i hosts mysql_role.yml
PLAY *****************************************************************************************

TASK **************************************************************
ok: => (item=libaio)
ok: => (item=numactl-libs)

TASK *********************************************************************
changed:

TASK **********************************************************************
changed:

TASK **************************************************
changed:

TASK *******************************************************
changed:

TASK ******************************************************************************
changed:

TASK ****************************************************************************
changed:

TASK ***********************************************************************
ok:

TASK ************************************************************************
changed:

TASK *************************************************************************
changed:

TASK **************************************************************************
changed:

TASK *******************************************************************
changed:

PLAY RECAP ********************************************************************************************
10.0.0.38                  : ok=12   changed=10   unreachable=0    failed=0    skipped=0    rescued=0    ignored=04 基于角色完成部署LNMP架构,并支持一键发布,回滚应用。同时基于zabbix角色批量部署zabbix。

4.1 部署LNMP架构

4.1.1 目录结构

$ tree /opt/
/opt/
├── ansible.cfg
├── hosts
├── lnmp_role.yml
├── mysql_role.yml
├── nginx_role.yml
├── php-fpm_role.yml
├── roles
│   ├── mysql
│   │   ├── files
│   │   │   └── mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │     └── my.cnf.j2
│   ├── nginx
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │     ├── nginx.conf.j2
│   │     └── nginx.service.j2
│   ├── php-fpm
│   │   ├── files
│   │   │   ├── test.php
│   │   │   └── www.conf
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │     ├── php-fpm.conf.j2
│   │     └── php.ini.j2
│   └── wordpress
│     ├── files
│     │   └── wordpress-6.1.1-zh_CN.zip
│     └── tasks
│           └── main.yml
└── wordpress_role.yml

17 directories, 22 files4.1.2 LNMP架构所需主机清单以及变量设置

$ cat hosts

10.0.0.18
10.0.0.28


version="1.20.2"
url="http://nginx.org/download/nginx-{{ version }}.tar.gz"
install_dir="/apps/nginx"
fqdn="www.yanlinux.org"
root_path="/data/wordpress"
app="wordpress-6.1.1-zh_CN"


10.0.0.38


db_group=mysql
db_gid=306
db_user=mysql
db_uid=306
db_version=8.0.31
db_file="mysql-{{db_version}}-linux-glibc2.12-x86_64.tar.xz"
db_data_dir="/data/mysql"
db_root_passwd="lgq123456**"4.1.2 实现编译安装nginx角色

#task文件
$ cat nginx/tasks/main.yml
- name: add group nginx
group: name=nginx system=yes gid=80

- name: add user nginx
user: name=nginx group=nginx uid=80 system=yes shell="/sbin/nologin" create_home=no

- name: install dependent package
yum: name={{item}} state=latest
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: config file
template:
    src: nginx.conf.j2
    dest: "{{install_dir}}/conf/nginx.conf"
    owner: nginx
    group: nginx
notify: restart service
tags:
    - config

- name: create directory
file:
    path: "{{install_dir}}/conf/conf.d"
    state: directory
    owner: nginx
    group: nginx

- name: change install directory owner
file:
    path: "{{install_dir}}"
    owner: nginx
    group: nginx
    recurse: yes

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

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

- name: start service
systemd:
    daemon_reload: yes
    name: nginx.service
    state: started
    enabled: yes
      
#创建handler文件
$ cat nginx/handlers/main.yml
- name: restart service
service:
    name: nginx
    state: restarted

#准备两个template文件
$ cat nginx/templates/nginx.conf.j2

#usernobody;
user nginx;
worker_processes{{ ansible_processor_vcpus*2 }};
events {
    worker_connections1024;
}
http {
    include       mime.types;
    default_typeapplication/octet-stream;
    log_formataccess_json '{"@timestamp":"$time_iso8601",'
      '"host":"$server_addr",'
      '"clientip":"$remote_addr",'
      '"size":$body_bytes_sent,'
      '"responsetime":$request_time,'
      '"upstreamtime":"$upstream_response_time",'
      '"upstreamhost":"$upstream_addr",'
      '"http_host":"$host",'
      '"uri":"$uri",'
      '"xff":"$http_x_forwarded_for",'
      '"referer":"$http_referer",'
      '"tcp_xff":"$proxy_protocol_addr",'
      '"http_user_agent":"$http_user_agent",'
      '"status":"$status"}';
    # logging                                                                                          
    access_log {{install_dir}}/logs/access-json.log access_json;
    error_log {{install_dir}}/logs/error.log warn;

    keepalive_timeout65;
    include {{install_dir}}/conf/conf.d/*.conf;
}
$ cat nginx/templates/nginx.service.j2

Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target


Type=forking
PIDFile={{install_dir}}/logs/nginx.pid
ExecStartPre=/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=process
PrivateTmp=true                                                                                       
LimitNOFILE=100000


WantedBy=multi-user.target

#总入口playbook文件
$ cat /opt/nginx_role.yml
- hosts: websrvs
remote_user: root

roles:
    - nginx4.1.4 实现php-fpm角色

#首先准备php.ini.j2和www.conf文件
#修改php上传限制配置
$ vi /opt/roles/php-fpm/templates/php.ini.j2
post_max_size = 100M #将次行从8M修改为100M
upload_max_filesize = 100M #将此行从2M改为100M

#修改配置文件
$ vi /opt/roles/php-fpm/files/www.conf
user = nginx #修改为nginx
group = nginx #修改为nginx
;listen = /run/php-fpm/www.sock #注释此行
listen = 127.0.0.1:9000 #添加此行,监控本机的9000端口

#准备网页配置文件
$ cat /opt/roles/php-fpm/templates/php-fpm.conf.j2
server {
    listen 80;
    server_name {{ fqdn }};
    location / {
      root         {{ root_path}};
      fastcgi_pass   127.0.0.1:9000;
      fastcgi_indexindex.php;
      fastcgi_paramSCRIPT_FILENAME $document_root$fastcgi_script_name;
      include      fastcgi_params;
    }
}

#准备tasks文件
$ cat /opt/roles/php-fpm/tasks/main.yml
- name: install package
yum:
    name: "{{ item }}"
loop:
    - php-fpm
    - php-mysqlnd
    - php-json
    - php-xml
    - php-gd
    - php-pecl-zip

- name: php path permissions
file:
    path: /var/lib/php/
    owner: nginx
    group: nginx
    recurse: yes

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

- name: config www.conf
copy:
    src: www.conf
    dest: /etc/php-fpm.d/www.conf

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

- name: start service
service:
    name: php-fpm
    state: started
    enabled: yes
   
#准备handler文件
$ cat /opt/roles/php-fpm/handlers/main.yml
- name: restart nginx
service:
    name: nginx
    state: restarted
   
#准备总入口playbook文件
$ cat /opt/php-fpm_role.yml
- hosts: websrvs
remote_user: root

roles:
    - php-fpm4.1.5 实现MySQL角色

注意:ansible playbook调用mysql系列模块需要依赖python3-mysql包和利用pip安装pymysql
#下载准备mysql源文件包
$ ls roles/mysql/files/
mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz

#创建task文件
$ cat roles/mysql/tasks/main.yml
- name: install dependent package
yum:
    name: "{{ item }}"
loop:
    - libaio
    - numactl-libs
    - python39
    - python3-mysql

- name: install pymysql
pip:
    name: pymysql
    state: present
   
- name: create mysql group
group: name={{db_group}} gid={{db_gid}}

- name: create mysql user
user: name={{db_user}} uid={{db_uid}} system=yes shell="/sbin/nologin" create_home=no group={{db_group}}

- name: copy tar to remote host and file mode
unarchive:
    src: "{{ db_file }}"
    dest: "/usr/local/"
    owner: root
    group: root

- name: create lingfile /usr/local/mysql
file:
    src: "/usr/local/mysql-{{ db_version }}-linux-glibc2.12-x86_64"
    dest: "/usr/local/mysql"
    state: link

- name: path file
copy:
    content: "PATH=/usr/local/mysql/bin:$PATH"
    dest: "/etc/profile.d/mysql.sh"

- name: config file
template:
    src: my.cnf.j2
    dest: "/etc/my.cnf"

- name: create directory
file:
    name: "/data"
    state: directory

- name: init mysql data
shell:
    cmd: "/usr/local/mysql/bin/mysqld --initialize-insecure --user={{ db_user }} --datadir={{ db_data_dir }}"
tags:
    - init

- name: service script
copy:
    src: "/usr/local/mysql/support-files/mysql.server"
    dest: "/etc/init.d/mysqld"
    remote_src: yes
    mode: '+x'

- name: start service
shell:
    cmd: chkconfig --add mysqld;chkconfig mysqld on;service mysqld start

- name: change root password
shell:
    cmd: "/usr/local/mysql/bin/mysqladmin -uroot password {{ db_root_passwd }}"
   
- name: create {{ wp_db_name }} database
mysql_db:
    login_host: "localhost"
    login_user: "root"
    login_password: "{{ db_root_passwd }}"
    login_port: 3306
    login_unix_socket: "{{ db_data_dir }}/mysql.sock"
    name: "{{ wp_db_name }}"
    state: present
when: "{{ wp_db_name }} is defined"

- name: create {{ wp_db_user }}
mysql_user:
    login_host: "localhost"
    login_user: "root"
    login_password: "{{ db_root_passwd }}"
    login_port: 3306
    login_unix_socket: "{{ db_data_dir }}/mysql.sock"
    name: "{{ wp_db_user}}"
    password: "{{ wp_db_passwd }}"
    priv: "{{ wp_db_name }}.*:ALL"
    host: "10.0.0.%"
    state: present
when: "{{ wp_db_user }} is defined"
   
   
#准备MySQL 配置文件模板
$ cat roles/mysql/templates/my.cnf.j2

server-id=1
log-bin
datadir={{ db_data_dir }}
socket={{ db_data_dir }}/mysql.sock
log-error={{ db_data_dir }}/mysql.log
pid-file={{ db_data_dir }}/mysql.pid


socket={{ db_data_dir }}/mysql.sock

#准备总入口playbook文件
$ cat mysql_role.yml
- hosts: dbsrvs
remote_user: root
gather_facts: no

roles:
    - mysql4.2 基于zabbix角色批量部署zabbix

依赖上面搭建好的LNMP架构实现
4.2.1 部署zabbix-server

#总体目录结构
$ tree
.
├── ansible.cfg
├── hosts
├── hosts_zabbix
├── roles
│   ├── mysql
│   │   ├── files
│   │   │   ├── create.sql.gz
│   │   │   └── mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │     └── my.cnf.j2
│   ├── nginx
│   │   ├── files
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │     ├── nginx.conf.j2
│   │     └── nginx.service.j2
│   ├── php-fpm
│   │   ├── files
│   │   │   ├── test.php
│   │   │   └── www.conf
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │     ├── php-fpm.conf.j2
│   │     └── php.ini.j2
│   └── zabbix_server
│     ├── handlers
│     │   └── main.yml
│     ├── tasks
│     │   └── main.yml
│     └── templates
│           ├── zabbix.conf.j2
│           ├── zabbix_server.conf.j2
│           └── zabbix-server-ngx.conf.j2
└── zabbix_server.yml

29 directories, 26 files

#主入口playbook
$ cat zabbix_server.yml
- hosts: websrvs
remote_user: root
roles:
    - nginx
    - php-fpm

- hosts: dbsrvs
remote_user: root
roles:
    - mysql

- hosts: websrvs
remote_user: root
roles:
    - zabbix_server


#tasks文件
$ cat /opt/roles/zabbix_server/tasks/main.yml
- name: config zabbix yum repo
yum_repository:
    name: "ansible_zabbix"
    description: "zabbix repo"
    baseurl: "https://mirrors.aliyun.com/zabbix/zabbix/{{ zabbix_version }}/rhel/{{ ansible_distribution_major_version }}/{{ ansible_architecture }}/"
    gpgcheck: yes
    gpgkey: "https://mirrors.aliyun.com/zabbix/zabbix-official-repo.key"

- name: install zabbix-server
yum:
    name: "{{ item }}"
loop:
    - zabbix-server-mysql
    - zabbix-agent2
    - zabbix-get
    - zabbix-web-mysql

- name: copy zabbix_server.conf
template:
    src: zabbix_server.conf.j2
    dest: /etc/zabbix/zabbix_server.conf
    mode: 0600
notify:
    - restart zabbix-server
tags: restart zabbix-server

- name: chownzabbix-web
file:
    path:/etc/zabbix/web   
    state: directory
    owner: nginx
    group: nginx
    recurse: yes

- name: copy zabbix-server web conf
template:
    src: zabbix-server-ngx.conf.j2
    dest: "{{ install_dir }}/conf/conf.d/zabbix_server_ngx.conf"
    owner: nginx
    group: nginx
notify:
    - restart nginx

- name: copy zabbix.conf into php-fpm.d
template:
    src: zabbix.conf.j2
    dest: "/etc/php-fpm.d/zabbix.conf"
notify:
    - restart php-fpm

- name: start zabbix-server
service:
    name: zabbix-server
    state: restarted
    enabled: yes
   
#查看handler
$ cat /opt/roles/zabbix_server/handlers/main.yml
- name: restart zabbix-server
service:
    name: zabbix-server
    state: restarted

- name: restart nginx
service:
    name: nginx
    state: restarted

- name: restart php-fpm
service:
    name: php-fpm
    state: restarted
   
#查看template文件
$ cat /opt/roles/zabbix_server/templates/zabbix.conf.j2

user = nginx
group = nginx

listen = /run/php-fpm/zabbix.sock
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
pm.max_requests = 200

php_value = files
php_value    = /var/lib/php/session

php_value = 300
php_value = 128M
php_value = 80M
php_value = 80M
php_value = 300
php_value = 10000
php_value = Asia/Shanghai

$ grep -Ev '^$|#' /opt/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
DBHost=10.0.0.58
DBName=zabbix
DBUser=zabbix
DBPassword=lgq123456
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
##zabbix网页配置文件
$ cat /opt/roles/zabbix_server/templates/zabbix-server-ngx.conf.j2
server {
    listen 80;
    server_name {{ zabbix_fqdn }};
    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;
    }

}
4.2.2 部署zabbix-agent

#目录结构
$ tree
.
├── files
│   └── zabbix_agnet2.d
│     ├── login.conf
│     ├── mem.conf
│     ├── mysql.conf
│     ├── mysql_repl_status.sh
│     ├── mysql.sh
│     ├── nginx_status.conf
│     ├── nginx_status.sh
│     └── tcp_state.conf
├── handlers
│   └── main.yml
├── tasks
│   └── main.yml
└── templates
    └── zabbix_agent2.conf.j2

5 directories, 11 files

#task文件
$ cat /opt/roles/zabbix_agent2/tasks/main.yml
- name: install repo
yum_repository:
    name: "ansible_zabbix"
    description: "zabbix repo"
    baseurl: "https://mirrors.aliyun.com/zabbix/zabbix/{{ zabbix_version }}/rhel/{{ ansible_distribution_major_version }}/{{ ansible_architecture }}/"
    gpgcheck: yes
    gpgkey: "https://mirrors.aliyun.com/zabbix/zabbix-official-repo.key"

- name: install agent2 for centos or rocky
yum:
    name: zabbix-agent2
when:
    - ansible_distribution == "Rocky" or ansible_distribution == "Centos"

- name: install agent2 for centos or ubuntu
apt:
    name: zabbix-agent2
    update_cache: yes
when:
    - ansible_distribution == "Ubuntu"

- name: config file
template:
    src: zabbix_agent2.conf.j2
    dest: "/etc/zabbix/zabbix_agent2.conf"
    mode: 0644
notify:
    - restart zabbix-agent2

- name: copy zabbix-agent2.d content
copy:
    src: zabbix_agent2.d
    dest: "/etc/zabbix"
notify:
    - restart zabbix-agent2
tags: zabbix_agent2.d

- name: start zabbix-agent2
service:
    name: zabbix-agent2
    state: started
    enabled: yes
   
#handler文件
$ cat /opt/roles/zabbix_agent2/handlers/main.yml
- name: restart zabbix_agent2
service:
    name: zabbix-agent2
    state: restarted
   
#template文件
$ cat /opt/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.sock4.2.3 测试

$ zabbix_get -s 10.0.0.18 -k mem_use_percent
20.1886
$ zabbix_get -s 10.0.0.18 -k tcp_state
32
$ zabbix_get -s 10.0.0.28 -k tcp_state
28
$ zabbix_get -s 10.0.0.58 -k tcp_state
55
来源:https://www.cnblogs.com/yan-linux/p/17039200.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: Ansible介绍以及基于角色搭建LNMP和zabbix