通过Ansible安装MySQL(yum + CentOS Stream 8)

通过Ansible安装MySQL(yum + CentOS Stream 8)

目的:通过Ansible的Playbook实现批量安装MySQL

方法:基于appstream在线安装MySQL 8

安装之前

确认要用哪种方式

通过Playbook安装软件的思路(和命令行一样的思路)

  • 安装配置什么软件,如何获取软件
    • 在线yum(内网or外网)
    • 离线安装包
      • rpm
      • 源码
      • 二进制,解释性程序等,解压即用
  • 需要什么前提
    • 前提软件的安装
      • 在线
      • 离线
    • 前提配置(用户,权限等)
      • 命令修改
      • shell修改
      • 通过Ansible修改
  • 什么配置,配置如何生产,
    • 通过事先写好的配置文件(也可搭配template和变量生成动态的配置文件)
    • 通过shell脚本生产
    • 通过纯Ansible生产
  • Ansible配置
    • 主机列表inventory
    • 变量
      • inventory里
      • 文件里
      • Playbook里
    • Playbook
      • role

Playbook编写步骤

  1. 先在特定的环境下,直接在shell下安装,确认步骤
  2. 用脚本试试(可选)
  3. 编写Playbook&执行

手动安装MySQL

# OS
[root@vm7 ~]# cat /etc/redhat-release
CentOS Stream release 8
[root@vm7 ~]# uname -a
Linux vm7 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Tue Nov 16 14:42:35 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

# 卸载已有的
[root@vm7 ~]# yum -y remove $(rpm -qa | grep -i -e mysql -e maria)
[root@vm7 ~]# rpm -qa | grep -i -e mysql -e maria
[root@vm7 ~]# echo $?
1

[root@vm7 ~]# rm -rf /var/log/mysql

# 获取包(默认源)
[root@vm7 ~]# yum info mysql-server | grep -e Name -e Version -e Repository
Name         : mysql-server
Version      : 8.0.26
Repository   : appstream

# 创建用户

[root@vm7 ~]# groupadd --gid 360 mysql

[root@vm7 ~]# useradd --gid 360 --no-create-home --uid 360 --shell /sbin/nologin mysql

[root@vm7 ~]# tail -1 /etc/passwd
mysql:x:360:1004::/home/mysql:/sbin/nologin

[root@vm7 ~]# id mysql
uid=360(mysql) gid=360(mysql) groups=360(mysql)

# 安装,确认配置文件的路径和内容等

[root@vm7 ~]# yum -y install mysql-server

[root@vm7 ~]# rpm -ql mysql-server
/etc/my.cnf.d/mysql-server.cnf
/usr/bin/mysql_secure_installation

[root@vm7 ~]# systemctl status mysqld

[root@vm7 ~]# egrep '^[^#]' /etc/my.cnf.d/mysql-server.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysql/mysqld.log
pid-file=/run/mysqld/mysqld.pid

[root@vm7 ~]# mysqld --initialize

[root@vm7 ~]# grep password /var/log/mysql/mysqld.log
2022-01-05T11:35:30.464114Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: lzJd#htSi3.g

[root@vm7 ~]# awk '/A temporary password/{print $NF}' /var/log/mysql/mysqld.log
lzJd#htSi3.g

# 确保权限正确
chown -R mysql:mysql /var/lib/mysql
chown -R mysql:mysql /var/log/mysql

# 初期密码
[root@vm7 ~]# pass=`awk '/A temporary password/{print $NF}' /var/log/mysql/mysqld.log`
[root@vm7 ~]# mysqladmin -uroot -p$pass password "MySQL123!"

用shell脚本安装MySQL

编写脚本

[root@vm7 ~]# cat install_mysql8_yum.sh
#!/bin/bash
#####################
# Author: li
# Version:
#     2022-01-05 New
# description: install MySQL via yum at CentOS Stream 8
#####################

# set vars
timestamp=`date +"%F_%H-%M-%S"`
ins_log=/tmp/mysql_install-${timestamp}.log

# get OS info
osrelease=`cat /etc/redhat-release`
systeminfo=`uname -a`
echo -e "This script is suitable for CentOS Stream release 8 to install MySQL8 on line \n current OS is:\n [$osrelease]\n ${systeminfo}\n"

# remove old MySQL / MariaDB
echo "Remove old mysql release if any..."
systemctl stop mysqld &> ${ins_log}
yum -y --quiet remove $(rpm -qa | grep -i -e mysql -e maria) &> ${ins_log}
rm -rf /var/lib/mysql &> ${ins_log}
rm -rf /var/log/mysql/mysqld.log &> ${ins_log}

# install MySQL
echo "Creating group and user(recreate if exists)..."
userdel --remove mysql &> ${ins_log}
groupdel mysql &> ${ins_log}
groupadd --gid 360 mysql &> ${ins_log}
useradd --gid 360 --no-create-home --uid 360 --shell /sbin/nologin mysql &> ${ins_log}

echo "Installing MySQL..."
yum -y install mysql-server &> ${ins_log}

# initialize
echo "Initializing MySQL Database..."
mysqld --initialize &> ${ins_log}
pass=`awk '/A temporary password/{print $NF}' /var/log/mysql/mysqld.log`

# make sure dir privileges are right
chown -R mysql:mysql /var/lib/mysql &> ${ins_log}
chown -R mysql:mysql /var/log/mysql &> ${ins_log}

systemctl start mysqld &> ${ins_log}
if [ $? != 0 ]; then
  echo "Failed to start mysqld service, something maybe wrong, check log: ${ins_log}"
else
  mysqladmin -uroot -p${pass} password "MySQL123!" &> ${ins_log}
  echo "Successful to install and start MySQL, enjog."
fi

timestamp2=`date +"%F %T"`
echo "End installation at ${timestamp2}" &> ${ins_log}


执行脚本


[root@vm7 ~]# bash install_mysql8_yum.sh
This script is suitable for CentOS Stream release 8 to install MySQL8 on line
 current OS is:
 [CentOS Stream release 8]
 Linux vm7 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Tue Nov 16 14:42:35 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Remove old mysql release if any...
Creating group and user(recreate if exists)...
Installing MySQL...
Initializing MySQL Database...
Successful to install and start MySQL, enjog.


[root@vm7 ~]# mysql -uroot -p'MySQL123!'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.26 Source distribution

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


[root@vm7 tmp]# cat mysql_install-2022-01-05_21-31-43.log
End installation at 2022-01-05 21:32:57

通过Ansible安装MySQL

编写Playbook

[root@ansible ansible]# cat install_mysql8_yum.yaml
---
# install MySQL8 via yum at CentOS Stream 8
- hosts: vm7
  gather_facts: no
  vars:
    mypass: MySQL123!
  tasks:
    - name: remove old MySQL or MariaDB(can not assure if any... if can, then use ansible yum module will be better)
      shell: yum -y --quiet remove $(rpm -qa | grep -i -e mysql -e maria)
    - name: remove old datadir
      file: path=/var/lib/mysql state=absent
    - name: remove old log
      file: path=/var/log/mysql/mysqld.log state=absent
    - name: remove mysql user
      user: name=mysql state=absent remove=yes
    - name: remove mysql group
      group: name=mysql state=absent
    - name: add mysql group
      group: name=mysql gid=360
    - name: add mysql user
      user: name=mysql uid=360 group=mysql create_home=no system=yes
    - name: install mysql-server
      yum: name=mysql-server state=present
    - name: initialize databse
      shell: mysqld --initialize --user=mysql
    - name: start mysqld
      service: name=mysqld state=started
    - name: get mysql root initial password
      shell: "awk '/A temporary password/{print $NF}' /var/log/mysql/mysqld.log"
      register: oldpass
    - name: set mysql root password
      shell: mysqladmin -uroot -p{{ oldpass.stdout }} password "{{ mypass }}"
      register: error1
      ignore_errors: yes
    - name: show error1
      debug:
        msg: "{{ error1 }}"


执行Playbook


[root@ansible ansible]# ansible-playbook install_mysql8_yum.yaml

PLAY [vm7] **************************

TASK [remove old MySQL or MariaDB(can not assure if any... if can, then use ansible yum module will be better)] ****************
changed: [vm7]

TASK [remove old datadir] ***********
changed: [vm7]

TASK [remove old log] ***************
changed: [vm7]

TASK [remove mysql user] ************
changed: [vm7]

TASK [remove mysql group] ***********
ok: [vm7]

TASK [add mysql group] **************
changed: [vm7]

TASK [add mysql user] ***************
changed: [vm7]

TASK [install mysql-server] *********
changed: [vm7]

TASK [initialize databse] ***********
changed: [vm7]

TASK [start mysqld] *****************
changed: [vm7]

TASK [get mysql root initial password] *****************************************************************************
changed: [vm7]

TASK [set mysql root password] ******
changed: [vm7]

TASK [show error1] ******************
ok: [vm7] => {
    "msg": {
        "changed": true,
        "cmd": "mysqladmin -uroot -pypxPN0p=q=sk password \"MySQL123!\"",
        "delta": "0:00:00.126392",
        "end": "2022-01-05 22:14:38.814841",
        "failed": false,
        "msg": "",
        "rc": 0,
        "start": "2022-01-05 22:14:38.688449",
        "stderr": "mysqladmin: [Warning] Using a password on the command line interface can be insecure.\nWarning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.",
        "stderr_lines": [
            "mysqladmin: [Warning] Using a password on the command line interface can be insecure.",
            "Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety."
        ],
        "stdout": "",
        "stdout_lines": []
    }
}

PLAY RECAP **************************
vm7                        : ok=13   changed=11   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  


反省

  • Playbook
    • 由于使用了shell来卸载旧的,使得这个Playbook没有幂等性,每次执行都会从卸载开始,如果确定没有安装旧的,可以不要这部分
  • 调试
    • 一次性写完全,可能会出错一些错误,可以尝试写一部task来调试
  • MySQL
    • mysqld执行初始化时如没有指定--user=mysql到导致数据目录的属主为root,进而导致msyqld启动失败
    • 要么指定用户,要么初始化后修改
上一篇:如何使用PHP计算两个日期之间的差异?


下一篇:SQL Server时间算法总结