使用ansible快速部署一套集群

使用ansible快速部署一套集群

axing
2023-07-19 / 0 评论 / 14 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年09月29日,已超过115天没有更新,若内容或图片失效,请留言反馈。

1.Roles基本概述
通过使用 roles,你可以将复杂的设置和操作流程封装在一个统一的文件夹下,进而实现代码的复用和模块化例如你要部署负载均衡、web服务器、nfs、数据库,那你可以创建四个role每个role都组织管理了好了各白需要的所有元素(包括任务、变量、handler、文件等)的目录结构。

2.创建单独一个Role
一个完整的Role里包含的目录和文件可能较多,手动去创建所有这些目录和文件是一件比较烦人的事,好在可以使用ansible-galaxy init ROLE NAME命令来快速创建一个符合Role文件组织规范的框架。

[root@lb workspace]# ansible-galaxy init first_role
 
[root@lb workspace]# tree first_role/
first_role/       # 角色名称,或者叫项目名
├── README.md
├── defaults      # 默认的变量(优先级很低)
│   └── main.yml
├── files         # 存放文件,使用copy模块时自动获取
├── handlers      # 存放触发器的配置
│   └── main.yml
├── meta          # 依赖的服务,执行该项目时先执行其他的项目
│   └── main.yml
├── tasks         # 默认执行的playbook
│   └── main.yml
├── templates     # 存放jinja2模板,使用template模块时自动获取
├── tests
│   ├── inventory
│   └── test.yml
└── vars          # 存放变量
    └── main.yml

3.一些关键介绍
Ansible Roles的依赖关系说明

`roles`允许你再使用roles时自动引入其他的roles。role依赖关系存储在roles目录中meta/main.yml文件中。
 
例如:推送wordpress并解压,前提条件,必须要安装nginx和php,把服务跑起来,才能运行wordpress的页面,此时我们就可以在wordpress的roles中定义依赖nginx和php的roles
[root@m01 roles]# vim /etc/ansible/roles/wordpress/meta/main.yml
dependencies:
  - { role: nginx }
  - { role: php }
 
如果编写了meta目录下的main.yml文件,那么Ansible会自动先执行meta目录中main.yml文件中的dependencies文件,如上所示,就会先执行nginx和php的安装。

Role中有两个地方可以定义变量:

  1. roles/xxx/defaults/main.yml:用于定义Role的默认变量
  2. roles/xxx/vars/main.yml:用于定义其它变量

两个文件之间的区别在于,defaults/main.yml中定义的变量优先级低于vars/main.yml中定义的变量。事实上,defaults/main.yml中的变量优先级几乎是最低的,基本上其它任何地方定义的变量都可以覆盖它

4.基于roles机制重构playbook

主机IP身份
m01192.168.110.110控制端
web01192.168.110.97受控端
db01192.168.110.163受控端
nfs192.168.110.51受控端
web02192.168.110.191受控端
lb01192.168.110.138受控端
  1. 配置主机清单
[root@manager ~]# cat /etc/ansible/hosts
[lb]
lb01 ansible_ssh_pass='1'
 
[nfs_server]
nfs ansible_ssh_pass='1'
 
[web_group]
web01 ansible_ssh_pass='1'
web02 ansible_ssh_pass='1'
 
[db_server]
db01 ansible_ssh_pass='1'
 
[www:children]
lb
nfs_server
web_group
db_server
  1. 配置hosts
[root@manager ~]# cat /etc/hosts # 添加如下内容
 
192.168.110.138 lb01
192.168.110.51  nfs
192.168.110.91  web01
192.168.110.191 web02
192.168.110.163 db01
  1. 创建项目及各个role
# 1、创建项目目录,项目名就叫roles吧,好理解
mkdir /project
mkdir /project/roles
 
# 2、在roles目录下创建一系列的role
cd /project/roles          # 切换到工作目录下
ansible-galaxy init base   # 基础优化role
ansible-galaxy init nfs    # 部署nfs服务的role
ansible-galaxy init web    # 部署web服务的role
ansible-galaxy init mysql  # 部署mysql服务的role
ansible-galaxy init lb     # 部署lb负载均衡服务的role
ansible-galaxy init wordpress     # 部署wordpress项目的role
  1. base role
[root@m01 tasks]# cat /project/roles/base/tasks/main.yml 
# tasks file for base
- name: Stop Selinux
  selinux:
    state: disabled

- name: Create www Group
  group:
    name: www
    gid: 1666
    state: present

- name: Create www User
  user: 
    name: www
    uid: 1666
    group: www
    shell: /sbin/nologin
    create_home: false
    state: present
  1. nfs role
    准备文件
[root@m01 tasks]# cat /project/roles/nfs/files/exports.txt 
/data 192.168.110.0/24(rw,sync,all_squash)
编写tasks
[root@m01 tasks]# cat /project/roles/nfs/tasks/main.yml 
# tasks file for nfs
- name: Install nfs-util
  yum: 
    name: nfs*
    state: present

- name: mkidr /data
  file: 
    path: "/data"
    state: directory

- name: Config nfs
  copy:
    src: "exports.txt"
    dest: /etc/exports

- name: Start nfs-server
  systemd:
    name: nfs-server
    state: restarted
    enabled: true
  1. web role
    部署两台web上的Nginx+php环境,并且挂载好nfs共享存储
    (1)准备好包和配置文件
    nginx的安装源文件
    cd /project/roles/web/files
cat > nginx.repo << "EOF"
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
 
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

nginx转发php-fpm的配置

cat > myweb.conf << "EOF"
server {
    listen       8181;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index index.php index.html;
    }
    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
        fastcgi_param HTTPS on;
        include        fastcgi_params;
    }
}
EOF

准备好php-fpm的配置文件

cat > www.conf << "EOF"
[www]
user = www
group = www
listen = 127.0.0.1:9000
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/opt/remi/php74/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/opt/remi/php74/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[soap.wsdl_cache_dir]  = /var/opt/remi/php74/lib/php/wsdlcache
EOF

(2)编写部署php-fpm+nginx的剧本

  vi /project/roles/web/tasks/mian.yml
# 1、安装php
- name: Gather OS version
  command: cat /etc/redhat-release
  register: os_version
 
- name: Extract major version from OS version
  set_fact:
    os_major_version: "{{ os_version.stdout.split()[3] | regex_replace('\\..*$', '') }}"
- name: Extract minor version from OS version
  set_fact:
    os_minor_version: "{{ os_version.stdout.split()[3] | regex_replace('^[^.]*\\.', '') }}"
 
- name: Install rpm package for CentOS 7.9
  yum:
    name: http://rpms.remirepo.net/enterprise/remi-release-7.rpm
    state: latest
  when: os_major_version == '7' and os_minor_version == '9.2009'
 
- name: Install rpm package for CentOS 9.3
  yum:
    name: http://rpms.remirepo.net/enterprise/remi-release-9.3.rpm
    state: latest
  when: os_major_version == '9' and os_minor_version == '3'
 
- name: Install php-fpm
  yum:
    name: 
      - 'php74-php-pdo'
      - 'php74-php-mbstring'
      - 'php74-php-cli'
      - 'php74-php-fpm'
      - 'php74-php-mysqlnd'
    state: latest
 
- name: Config php-fpm
  copy:
    src: www.conf
    dest: /etc/opt/remi/php74/php-fpm.d/www.conf
  notify: restart_php
 
- name: Start php-fpm
  systemd:
    name: php74-php-fpm
    state: restarted
    enabled: true
 
#2、安装nginx,配置nginx代理php-fpm
- name: copy nginx.repo
  copy:
    src: nginx.repo
    dest: /etc/yum.repos.d/nginx.repo
 
- name: Install nginx
  yum:
    name: nginx
    state: latest
 
- name: Config nginx
  copy:
    src: myweb.conf
    dest: /etc/nginx/conf.d/myweb.conf
  notify: restart_nginx
 
- name: Start nginx server
  systemd:
    name: nginx
    state: restarted
    enabled: true
 
#3、配置所有web服务挂载nfs
- name: 安装nfs
  yum:
    name: nfs-utils
    state: latest
 
- name: 挂载
  mount:
    path: /usr/share/nginx/html
    src: "{{ nfs_share_dir }}"
    fstype: nfs
    opts: defaults
    state: mounted

配置触发器handler

[root@m01 base]# cat /project/roles/web/handlers/main.yml 
# handlers file for web
- name: restart_php
  systemd:
    name: php74-php-fpm
    state: restarted
 
- name: restart_nginx
  systemd:
    name: nginx
    state: restarted
创建变量
[root@m01 roles]# cat web/vars/main.yml
nfs_share_dir: "192.168.110.51:/data"
  1. mysql role
    安装mysql_db模块
ansible-galaxy collection install community.mysql
编写剧本
[root@m01 base]# cat /project/roles/web/handlers/main.yml 
# handlers file for web
- name: restart_php
  systemd:
    name: php74-php-fpm
    state: restarted
 
- name: restart_nginx
  systemd:
    name: nginx
    state: restarted
[root@m01 base]# cat /project/roles/mysql/tasks/main.yml 
# tasks file for mysql
- name: Download PyMySQL tar.gz
  get_url:
    url: https://files.pythonhosted.org/packages/44/39/6bcb83cae0095a31b6be4511707fdf2009d3e29903a55a0494d3a9a2fac0/PyMySQL-0.8.1.tar.gz
    dest: /tmp/PyMySQL-0.8.1.tar.gz
 
- name: Extract PyMySQL tar.gz
  unarchive:
    src: /tmp/PyMySQL-0.8.1.tar.gz
    dest: /tmp/
    remote_src: yes
 
- name: Install PyMySQL
  command:
    cmd: "python setup.py install"
    chdir: "/tmp/PyMySQL-0.8.1"
  
 
 
- name: clear mysql
  shell: "yum remove mysql* -y"
  ignore_errors: True
 
- name: Install mariadb
  yum:
    name: mariadb*
    state: latest
 
- name: init maridb
  shell: "rm -rf /var/lib/mysql/*"
 
- name: Start mariadb
  systemd:
    name: mariadb
    state: restarted
    enabled: true
 
 
- name: create database
  mysql_db:
    # root登录localhost不允许,需要用套接字登录
    login_unix_socket: /var/lib/mysql/mysql.sock
    # 引用变量名必须加引号,否则报错
    name: "{{ my_db.name }}"
    state: present
    encoding: "{{ my_db.encoding }}"
 
- name: grant all on *.* to 'bob'@'192.168.110.%' identified by '12345';
  mysql_user:
    login_unix_socket: /var/lib/mysql/mysql.sock
    # 引用变量名必须加引号,否则报错
    name: "{{ my_user.name }}"
    host: "{{ my_user.host }}"
    password: "{{ my_user.password }}"
    priv: "{{ my_user.priv }}"
    state: present
创建变量文件
[root@m01 base]# cat /project/roles/mysql/vars/main.yml 
# vars file for mysql
my_db:
  name: wordpress
  encoding: utf8mb4
 
my_user:
  name: bob
  host: 192.168.110.%
  password: 12345
  priv: '*.*:ALL'
  1. lb role
    准备nginx.repo cd /project/roles/lb/files
cat > lb/files/nginx.repo << "EOF"
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
 
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
准备证书
openssl genrsa -out server.key 2048 
openssl req -new -x509 -days 3650 -key server.key -out server.crt -subj "/C=CH/ST=mykey/L=mykey/O=mykey/OU=mykey/CN=domain1/CN=www.egon.com/CN=domain3"
放置证书到lb/files目录下
[root@m01 roles]# mv server.*  /project/roles/lb/files/
准备配置文件
[root@m01 base]# cat /project/roles/lb/files/nginx.conf 
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
http {
    upstream webserver {
      server 192.168.110.97:8181;
      server 192.168.110.191:8181;
    }
    server {
        listen 443 ssl;
        server_name www.egon.com 192.168.110.138;
        ssl_certificate /etc/nginx/ssl_key/server.crt;
        ssl_certificate_key /etc/nginx/ssl_key/server.key;
 
        location / {
            proxy_pass  http://webserver;
           # 把真实的访问者ip发给后端web,后端web会据此来拼接静态文件的url地址以便让访问者浏览器发起二次请求
           # 如果没有下面的这段内容,后端web会将静态资源的url地址拼成http://webserver/static/img/1.jpg的形式,导致访问者浏览器二次访问失败
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header Host $http_host;
           proxy_next_upstream error timeout http_500 http_502 http_503 http_504 http_403 http_404;
        }
    }
    server {
        listen 80;
        server_name 192.168.110.138 www.egon.com;
 
        rewrite (.*) https://$server_name$1;
    }
}

编写剧本

[root@m01 base]# cat /project/roles/lb/tasks/main.yml 
# tasks file for lb
- name: clear nginx
  shell: >
    yum remove nginx* -y ; rm -rf /etc/nginx /usr/share/nginx
 
- name: copy nginx.repo
  copy:
    src: nginx.repo
    dest: /etc/yum.repos.d/nginx.repo
 
- name: Install nginx
  yum:
    name: nginx
    state: latest
 
- name: Create dir
  file:
    path: /etc/nginx/ssl_key
    state: directory
 
- name: copy multiple files
  copy:
    src: "{{ item.src }}"
    dest: "{{ item.dest }}"
  with_items:
    - { src: 'nginx.conf', dest: '/etc/nginx/nginx.conf'}
    - { src: 'server.crt', dest: '/etc/nginx/ssl_key/server.crt'}
    - { src: 'server.key', dest: '/etc/nginx/ssl_key/server.key'}
  notify: restart_nginx
 
- name: Start nginx server
  systemd:
    name: nginx
    state: restarted
    enabled: true

配置触发器

[root@m01 base]# cat /project/roles/lb/handlers/main.yml 
# handlers file for lb
- name: restart_nginx
  systemd:
    name: nginx
    state: restarted
  1. wordpress role
    安装包
cd /project/roles/wordpress/files
wget https://wordpress.org/latest.zip

准备好配置文件(配置上数据库相关信息)

[root@m01 base]# cat /project/roles/wordpress/files/wp-config.php 
<?php
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'bob' );
define( 'DB_PASSWORD', '12345' );
define( 'DB_HOST', '192.168.110.138' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
 
define( 'AUTH_KEY',         'put your unique phrase here' );
define( 'SECURE_AUTH_KEY',  'put your unique phrase here' );
define( 'LOGGED_IN_KEY',    'put your unique phrase here' );
define( 'NONCE_KEY',        'put your unique phrase here' );
define( 'AUTH_SALT',        'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT',   'put your unique phrase here' );
define( 'NONCE_SALT',       'put your unique phrase here' );
 
$table_prefix = 'wp_';
define( 'WP_DEBUG', false );
 
if ( ! defined( 'ABSPATH' ) ) {
    define( 'ABSPATH', __DIR__ . '/' );
}
 
require_once ABSPATH . 'wp-settings.php';
 
EOF

编写剧本(解压到nfs共享目录里就发布给了所有的web服务)

[root@m01 base]# cat /project/roles/lb/handlers/main.yml 
# handlers file for lb
- name: restart_nginx
  systemd:
    name: nginx
    state: restarted
[root@m01 base]# cat /project/roles/wordpress/tasks/main.yml 
---
# tasks file for wordpress
- name: mkdir /data
  copy:
    src: "latest.zip"
    dest: "/data"
 
- name: install unzip
  yum:
    name: unzip
    state: present
 
- name: 发布
  shell: unzip /data/latest.zip -d /data
 
- name: 传送配置
  copy:
    src: "wp-config.php"
    dest: "/data/wordpress/wp-config.php"
  1. 整合为一个playbook

编写一个playbook剧本,剧本里面一如各个子role,运行的时候运行这一个playbook即可

[root@m01 base]# cat /project/roles/run.yml 
- name: 优化部分
  hosts: all
  roles:
    - base
 
- name: 安装nfs
  hosts: nfs_server
  roles:
    - nfs
 
- name: 安装web
  hosts: web_group
  roles: # 其实你可以将安装web进一步细分为nginx role与php role,留给你作业了
    - web
 
- name: 安装数据库
  hosts: db_server
  roles:
    - mysql
 
- name: 配置负载均衡和高可用
  hosts: lb_server
  roles:
    - lb
    #- keepalived  # 高可用role留给你来实现
 
- name: 发布wordpress项目
  hosts: nfs_server
  roles:
    - wordpress

补充:各个子role里的hosts其实不用指定,run.yml已经指定了

ansible-playbook /project/roles/run.yml

访问负载均衡:https://192.168.110.138/wordpress/
lysfewy1.png

0

评论 (0)

取消