Linux自动化运维工具之Ansible综合使用案例

1、 管理机部署

1.1 创建项目、安装相关命令

[root@m1 ~]# mkdir project  # 创建项目目录
[root@m1 ~]# yum install wget -y  # 安装wget命令
[root@m1 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo  # 配置epel源
[root@m1 ~]# yum install ansible -y  # 安装ansible
[root@m1 ~]# ansible -m ping  # 监测ansible是否安装成功

1.2 修改主机清单调试所有机器

[root@m1 ~]# vim /etc/ansible/hosts  # 修改主机文件
[web01]
192.168.15.7 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1' 
[web02]
192.168.15.8 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1' 
[web03]
192.168.15.9 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1' 
[web:children]
web01
web02
web03
[lb01]
192.168.15.5 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1' 
[lb02]
192.168.15.6 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1' 
[lb:children]
lb01
lb02
[nfs]
192.168.15.31 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1' 
[db]
192.168.15.61 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
[prometheus]
192.168.15.71 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'

[root@m1 project]# vim /etc/ansible/ansible.cfg  # 	修改ansible配置文件
	host_key_checking = False                 #跳过检查主机指纹
	
[root@m1 ~]# ansible all -m ping  # 测试主机文件配置正常

1.3 安装插件准备代码包

[root@m1 ~]# yum install python3 python3-devel  # 安装python
[root@m1 ~]# pip3 install django  # 安装Django
[root@m1 ~]# cd /opt/  # 切换目录
[root@m1 opt]# django-admin startproject linux20  # 创建目录
[root@m1 ~]# cd linux20  # 切换目录
[root@m1 linux20]# django-admin startapp application  # 创建目录
[root@m1 linux20]# vim linux20/settings.py  # 修改配置文件的以下内容
	ALLOWED_HOSTS = ['*']  # 加入一个※号表示通用
	DATABASES = {}  # 把原来的内容清空
	
[root@m1 linux20]# python3 manage.py runserver 0.0.0.0:8000  # 指定端口启动服务
[root@m1 linux20]# pip3 install uwsgi  # 安装
[root@m1 linux20]# vim myweb.ini  # 编辑配置文件
    [uwsgi]
    # 端口号
    socket            = :8000
    # 指定项目的目录
    chdir           = /opt/linux20
    # wsgi文件路径
    wsgi-file       = linux20/wsgi.py
    # 模块wsgi路径
    module          = linux20.wsgi
    # 是否开启master进程
    master          = true
    # 工作进程的最大数目
    processes       = 4
    # 结束后是否清理文件
    vacuum          = true
    
[root@m1 linux20]# uwsgi --ini myweb.ini  # 启动uwsgi
[root@m1 linux20]# cd ..  # 切换到上层目录/opt
[root@m1 opt]# tar -czvf linux20.tar.gz linux20  # 打包代码

image-20220224175511998

2、 部署公共roles

2.1 初始化公共角色

[root@m01 project]# ansible-galaxy init common  # 创建公共角色目录

2.2 编辑任务文件

[root@m01 project]# vim common/tasks/main.yml  # 编辑公共任务配置文件
- name: 关闭防火墙
  service:
    name: firewalld
    state: stopped
    enabled: no
- name: 关闭Selinux
  selinux:
    state: disabled
- name: 安装NFS
  yum:
    name: nfs-utils
    state: present
  when: 
    - ansible_distribution == "CentOS"
- name: 创建全局用户组
  group:
    name: www
    state: present
    gid: 666
- name: 创建全局用户
  user:
    name: www
    comment: 全局应用程序用户
    uid: 666
    group: www
    shell: /sbin/nologin
    state: present
    create_home: false

image-20220223174602091

3、安装部署NFS

3.1 初始化角色

[root@m01 project]# ansible-galaxy init nfs  # 初始化角色

3.2 编辑任务文件

[root@m01 project]# vim nfs/tasks/main.yml  # 编辑nfs任务配置文件
- name: 安装RpcBind
  yum:
    name: rpcbind
    state: present
  when:
  	- ansible_distribution == "CentOS"
- name: 创建挂载点
  file:
    path: /backup
    owner: www
    group: www
    mode: 777
    state: directory
- name: 创建NFS配置文件
  template:
    src: ./nfs.j2
    dest: /etc/exports
- name: 启动NFS和rpcbind
  service:
    name: "{{ item }}"
    state: restarted
  with_items:
    - nfs-server
    - rpcbind

3.3 编辑配置文件

[root@m01 project]# vim nfs/templates/nfs.j2  # 编辑nfs的j2配置文件
/backup 192.168.15.0/24(rw,sync,all_squash,anonuid=666,anongid=666)

image-20220223181036091

4、 部署数据库db

4.1 初始化角色

[root@m01 project]# ansible-galaxy init db  # 初始化角色

4.2 编辑任务文件

[root@m01 project]# vim db/tasks/main.yml  # 编辑数据库任务配置文件
- name: 安装MariaDB和mariadb-server
  yum:
    name: "{{ item }}"
    state: present
  with_items:
    - mariadb
    - mariadb-server
- name: 启动Mariadb和rpcbind
  service:
    name: mariadb
    state: restarted
- name: 创建远程连接用户和数据库
  shell: /usr/bin/mysql -uroot -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'test@666' WITH GRANT OPTION;FLUSH PRIVILEGES;CREATE DATABASE django;"

image-20220223181158224

5、部署WEB

5.1 初始化角色

[root@m01 project]# ansible-galaxy init web  # 初始化角色

5.2 编辑任务文件

[root@m01 project]# vim web/tasks/main.yml  # 编辑web任务配置文件
- name: 卸载nginx、httpd残留
  yum:
    name: "{{ item }}"
    state: absent
  with_items:
    - nginx
    - httpd
- name: 安装Nginx、python3、python3-devel
  yum:
    name: "{{ item }}"
    state: present
  with_items:
    - nginx
    - python3
    - python3-devel
- name: 安装Django
  shell: pip3 install django -i https://pypi.doubanio.com/simple/ --trusted-host pypi.doubanio.com
  
- name: 安装uwsgi
  shell: pip3 install uwsgi -i https://pypi.doubanio.com/simple/ --trusted-host pypi.doubanio.com
- name: 上传代码
  unarchive:
    src: ./linux20.tar.gz
    dest: /opt/
    remote_src: no
- name: 上传Nginx配置文件
  template:
    src: ./nginx.conf.j2	
    dest: /etc/nginx/nginx.conf
- name: 上传Nginx主机配置文件
  template:
    src: ./django.conf.j2
    dest: /etc/nginx/conf.d/default.conf
- name: 启动UWSGI
  shell: cd /opt/linux20 && /usr/local/bin/uwsgi -d --ini myweb.ini
- name: 启动Nginx
  service:
    name: nginx
    state: restarted

5.3 编辑配置文件

[root@m01 project]# vim web/templates/django.conf.j2  
server {
    listen 80;
    server_name www.django.com;
    location / {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:8000;
        uwsgi_read_timeout 2;
        uwsgi_param UWSGI_SCRIPT linux20.wsgi;
        uwsgi_param UWSGI_CHDIR /opt/linux20;
        index  index.html index.htm;
        client_max_body_size 35m;
    }
}

[root@m1 project]# vim web/templates/nginx.conf.j2
user  www;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/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  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
}

image-20220223193553895

5.4 上传代码包

[root@m1 ~]# cp /opt/linux20.tar.gz /root/project/web/files/

6、部署负载均衡lb

6.1 初始化角色

[root@m01 project]# ansible-galaxy init lb  # 初始化角色

6.2 编辑任务文件

[root@m01 project]# vim lb/tasks/main.yml  # 编辑lb任务配置文件
---
- name: 安装高可用软件和nginx
  yum:
    name: "{{ item }}"
    state: present
  with_items:
    - nginx
    - keepalived
- name: 配置Nginx
  template:
    src: ./nginx.conf.j2
    dest: /etc/nginx/nginx.conf
- name: 配置Upstream
  template:
    src: ./upstream.conf.j2
    dest: /etc/nginx/upstream.conf
- name: 配置lb
  template:
    src: ./lb.conf.j2
    dest: /etc/nginx/conf.d/default.conf
- name: 配置keepalived
  template:
    src: ./keepalived.conf.j2
    dest: /etc/keepalived/keepalived.conf
- name: 启动Nginx和Keepalived
  service:
    name: "{{ item }}"
    state: restarted
  with_items:
    - nginx
    - keepalived

6.3 编辑配置文件

[root@m01 project]# vim lb/templates/nginx.conf.j2
user  www;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/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  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*.conf;
}

[root@m01 project]# vim lb/templates/lb.conf.j2
upstream web {
    server 192.168.15.7;
    server 192.168.15.8;
    server 192.168.15.9;
}

server {
    listen 80;
    server_name www.django.com;
    location / {
        proxy_pass http://web;
        include upstream.conf;
    }
}

[root@m01 project]# vim lb/templates/keepalived.conf.j2
! Configuration File for keepalived
# 全局配置
global_defs {
   # 当前keepalived唯一标识
   router_id {{ ansible_fqdn }}
}

# 配置VRRP协议
vrrp_instance VI_1 {

{% if ansible_fqdn == "lb01" %}
    # 状态,MASTER和BACKUP
    state MASTER
    # 优先级
    priority 100
{% else %}
    # 状态,MASTER和BACKUP
    state BACKUP
    # 优先级
    priority 90
{% endif %}
    # 绑定网卡
    interface eth0
    # 虚拟路由标示,可以理解为分组
    virtual_router_id 50
    # 监测心跳间隔时间
    advert_int 1
    # 配置认证
    authentication {
        # 认证类型
        auth_type PASS
        # 认证的密码
        auth_pass 1111
    }
    # 设置VIP
    virtual_ipaddress {
        # 虚拟的VIP地址
        192.168.15.3
    }
}

[root@m01 project]# vim lb/files/upstream.conf.j2

proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;

#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

#以下是一些反向代理的配置,可选。
proxy_set_header Host $host;

#允许客户端请求的最大单文件字节数
client_max_body_size 10m;

#缓冲区代理缓冲用户端请求的最大字节数,
#如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。
#无论使用firefox4.0还是IE8.0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误
client_body_buffer_size 128k;

#表示使nginx阻止HTTP应答代码为400或者更高的应答。
proxy_intercept_errors on;

#后端服务器连接的超时时间_发起握手等候响应超时时间
#nginx跟后端服务器连接超时时间(代理连接超时)
proxy_connect_timeout 90;

#后端服务器数据回传时间(代理发送超时)
#后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据
proxy_send_timeout 90;

#连接成功后,后端服务器响应时间(代理接收超时)
#连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)
proxy_read_timeout 90;

#设置代理服务器(nginx)保存用户头信息的缓冲区大小
#设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头,默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小
proxy_buffer_size 4k;

#proxy_buffers缓冲区,网页平均在32k以下的设置
#设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k
proxy_buffers 4 32k;

#高负荷下缓冲大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;

#设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长
#设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_temp_file_write_size 64k;

image-20220223195857842

7、 部署监控prometheus

prometheus监控的架构:
grafana(显示图表:只在监控上安装) --> server(存储和处理监控数据:只在监控上安装)--> agent(获取监控数据:所有机器安装)      

7.1 初始化角色

[root@m01 project]# ansible-galaxy init prometheus  # 初始化角色

7.2 下载监控相关的插件包

[root@m1 files]# wget https://mirrors.tuna.tsinghua.edu.cn/grafana/yum/rpm/grafana-8.4.1-1.x86_64.rpm  # 下载grafana软件包
[root@m1 files]# wgt https://github.com/prometheus/prometheus/releases/download/v2.33.4/prometheus-2.33.4.linux-amd64.tar.gz  # 下载prometheus软件包
[root@m1 files]# wget https://github.com/prometheus/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64.tar.gz  # 下载node-Exporter软件包
[root@m1 files]# wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.13.0/mysqld_exporter-0.13.0.windows-amd64.zip  # 下载数据库插件包

7.3 编辑任务文件

[root@m01 project]# vim prometheus/tasks/main.yml  # 编辑监控的任务配置文件
# 机器系统数据收集:需要注册服务
- name: 安装部署NodeExporter
  unarchive:
    src: ./node_exporter-1.3.1.linux-amd64.tar.gz
    dest: /usr/local/
- name: 注册NodeExpoeter systemd服务
  copy:
    src: node-exporter.service
    dest: /usr/lib/systemd/system/
- name: 启动NodeExporter服务
  systemd:
    name: node-exporter
    daemon_reload: yes
    state: restarted

# 数据库监控:需要注册服务并且需要连接数据库的账户密码
- name: 安装部署MysqldExporter
  unarchive:
    src: ./mysqld_exporter-0.13.0.linux-amd64.tar.gz 
    dest: /usr/local/
  when: ansible_fqdn == "db01"
- name: 注册MysqldExporter systemd服务
  copy:
    src: mysqld-exporter.service
    dest: /usr/lib/systemd/system/
  when: ansible_fqdn == "db01"
- name: 上传密码文件
  copy:
    src: ./.my.cnf
    dest: /usr/local/mysqld_exporter-0.13.0.linux-amd64/
  when: ansible_fqdn == "db01"
- name: 启动MysqldExporter服务
  systemd:
    name: mysqld-exporter
    daemon_reload: yes
    state: restarted
  when: ansible_fqdn == "db01"

# 监控服务:需要注册服务,需要修改配置文件
- name: 部署Prometheus
  unarchive:
    src: ./prometheus-2.33.4.linux-amd64.tar.gz
    dest: /usr/local/
  when: ansible_fqdn == "prometheus"
- name: 注册Prometheus systemd服务
  copy:
    src: prometheus.service
    dest: /usr/lib/systemd/system/
  when: ansible_fqdn == "prometheus"
- name: 修改Prometheus的配置文件
  template:
    src: ./prometheus.yml
    dest: /usr/local/prometheus-2.33.4.linux-amd64/
  when: ansible_fqdn == "prometheus"
- name: 启动Prometheus服务
  systemd:
    name: prometheus
    daemon_reload: yes
    state: restarted
  when: ansible_fqdn == "prometheus"
# grafana服务:可以做数据监控和数据统计展示为图表,不需要注册服务,直接yum安装插件就可以用了
- name: 上传Grafana安装包
  copy:
    src: ./grafana-8.4.1-1.x86_64.rpm
    dest: /opt/
  when: ansible_fqdn == "prometheus"
- name: 安装Grafana
  shell: "cd /opt/ && yum install grafana-8.4.1-1.x86_64.rpm -y"
  when: ansible_fqdn == "prometheus"
- name: 启动Grafana服务
  systemd:
    name: grafana-server
    daemon_reload: yes
    state: restarted
  when: ansible_fqdn == "prometheus"

7.4 编辑注册文件

[root@m1 files]# vim mysqld-exporter.service  # 编辑mysql注册文件
[Unit]
Description=Prometheus

[Service]
ExecStart=/usr/local/mysqld_exporter-0.1.0.linux-amd64/mysqld_exporter --config.my-cnf=/usr/local/mysqld_exporter-0.1.0.linux-amd64/.my.cnf --web.listen-address=:9104
Restart=on-failure

[Install]
WantedBy=multi-user.target

[root@m1 files]# vim node-exporter.service  # 编辑node服务注册文件
[Unit]
Description=This is prometheus node exporter
After=node_exporter.service

[Service]
Type=simple
ExecStart=/usr/local/node_exporter-1.3.1.linux-amd64/node_exporter
ExecReload=/bin/kill -HUP 
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target

[root@m1 files]# vim prometheus.service  # 编辑prometheus服务注册文件
[Unit]
Description=Prometheus

[Service]
ExecStart=/usr/local/prometheus-2.33.4.linux-amd64/prometheus --config.file=/usr/local/prometheus-2.33.4.linux-amd64/prometheus.yml --web.enable-lifecycle  
Restart=on-failure

[Install]
WantedBy=multi-user.target
[root@m1 files]# cat prometheus.service
[Unit]
Description=Prometheus

[Service]
ExecStart=/usr/local/prometheus-2.33.4.linux-amd64/prometheus --config.file=/usr/local/prometheus-2.33.4.linux-amd64/prometheus.yml --web.enable-lifecycle  
Restart=on-failure

[Install]
WantedBy=multi-user.target

7.5 编辑配置文件

  [root@m1 templates]# vim prometheus.yml   # 编辑prometheus的配置文件
# my global config
global:
  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ["localhost:9090"]
  - job_name: "Linux主机监控"
    static_configs:
      - targets:
          - "192.168.15.7:9100"
          - "192.168.15.8:9100"
          - "192.168.15.9:9100"
          - "192.168.15.31:9100"
          - "192.168.15.61:9100"
          - "192.168.15.71:9100"
          - "192.168.15.81:9100"
          - "192.168.15.5:9100"
          - "192.168.15.6:9100"
  - job_name: "MySQL监控"
    static_configs:
      - targets:
          - "192.168.15.61:9104"

7.6 编辑密码文件

[root@m1 files]# vim .my.cnf
[client]
host=192.168.15.61
user=root
password=test@666

8、编写并执行剧本

8.1 编写剧本

[root@m1 ~]# cd /root  # 切换到project的上一层目录再编辑执行剧本
[root@m1 ~]# vim test.yaml  # 编写剧本
- hosts: all
  name: 全局初始化
  roles:
    - common

- hosts: nfs
  name: NFS相关操作
  roles:
    - nfs

- hosts: db01
  name: 数据库相关操作
  roles:
    - db

- hosts: web
  name: WEB相关操作
  roles:
    - web

- hosts: lb
  name: 负载均衡相关操作
  roles:
    - lb
- hosts: all
  name: 安装部署监控
  roles:
    - prometheus

8.2 执行剧本

root@m1 ~]# ansible-playbook -C role.yaml  # -C参数用于测试剧本能不能正常执行
[root@m1 ~]# ansible-playbook role.yaml

9、实现监控

1.浏览器访问ip:http://192.168.15.71:9090/进入prometheus监控页面
2.statue选择targets
3.浏览器访问ip:http://192.168.15.71:3000/进入grafana图表页面,输入账号密码
4.点设置图标,点Data sources,选prometheus
5.修改url:192.168.15.71:9090,拉到页面底部save & test
6.回到grafana官网:https://grafana.com/products/cloud/
7.页面顶端菜单栏选择Products,点Dashboards
8.左边菜单栏Data sources 选择prometheus
9.选择Node Exporter Full,复制仪表板ID  1860
10.回到3000的grafana监控页面,点+号下面的import,输入1860点load,选prometheus然后点import即可查看图表。

image-20220224214618660

image-20220224220240151

image-20220224220349223

image-20220224220542148

image-20220224220738050

image-20220224220749805

image-20220224221018750

image-20220224221328128

image-20220224221515904

image-20220224221702739

image-20220224221856216

image-20220224222030387

image-20220224222212987

posted @ 2022-02-24 21:41  90啊  阅读(992)  评论(0编辑  收藏  举报