[과제] My SQL, Redis 설치 자동화 셸 스크립트

강세준·2023년 1월 16일
0

nhn

목록 보기
5/7

환경


사용 언어 : bash shell script
환경 : NHN Cloud CentOS 7.9


기능


Binary auto install

1) MySQL

  1. 버전을 입력받는다. (NHN Cloud 자동설치 같은 경우 최신 버전 링크 자동 등록)
  2. 다운받을 수 있는 올바른 링크인지 확인한다.
  3. 바이너리 설치 된 MySQL을 검사하여 삭제한다.
  4. MySQL을 다운받고 압축을 해제한다.
  5. my.cnf 파일 기록 및 data,log파일을 생성한다.(skip-grant-tables 옵션을 통해 초기 비밀번호 없이 로그인 한다.)
  6. .bashrc에 환경변수를 검사하여 등록하고 MySQL을 실행한다.

2) Redis

  1. 버전을 입력받는다. (NHN Cloud 자동설치 같은 경우 최신 버전 링크 자동 등록)
  2. 다운받을 수 있는 올바른 링크인지 확인한다.
  3. 바이너리 설치 된 Redis을 검사하여 삭제한다.
  4. Redis을 다운받고 압축을 해제한다.
  5. .bashrc에 환경변수를 검사하여 등록한다.
  6. Redis를 처음 실행할 때 나타나는 warning과 관련된 파라미터들을 조정한다.

Yum auto install

3) MySQL(최신 버전 다운로드)

  1. yum으로 설치된 mysql를 검사하고 제거한다.
  2. yum으로 최신 버전의 Mysql을 설치한다.
  3. mysqld 데몬을 중지하고 systemctl set-environment MYSQLD_OPTS="skip-grant-tables"을 통해 초기 비밀번호 없이 로그인 한다.
  4. mysqld 데몬을 실행시킨다.

4) Redis(최신 버전 다운로드)

  1. yum으로 설치된 redis를 검사하고 제거한다.
  2. remi repo를 설치하고 등록한다.
  3. yum으로 최신 버전의 Redis를 설치한다.
  4. Redis를 처음 실행할 때 나타나는 warning과 관련된 파라미터들을 조정한다.

환경


사용 언어 : bash shell script
환경 : NHN Cloud CentOS 7.9

구현


binary_mysql_install.sh

#!/usr/bin/env bash

#if [ -z $1 ]; then
#	echo 버전 정보를 입력하지 않으면 실행되지 않습니다.
#	exit 1
#fi

user_path="/home/centos"
mysql_folderName="mysql-${1}-el7-x86_64"

# mysql 링크 확인 로직
#if [ ${1} != "8.0.32" ]; then
#	mysql_connection=`wget --timeout=1 --tries=1 --spider https://downloads.mysql.com/archives/get/p/23/file/${mysql_folderName}.tar.gz 2>&1 | grep 'broken link' | wc -l`
#	if [ ${mysql_connection} -ge 1 ]; then
#		echo "잘못된 링크입니다. 프로그램을 종료합니다."
#		exit 2
#	fi
#fi

# mysql 바이너리 설치 확인 및 삭제 로직
mysql_count=`find ${user_path}/mysql* | wc -l`
if [ ${mysql_count} -gt 0 ]; then
	echo "mysql binary install 이 발견되어 삭제합니다."
	echo `rm -rf ${user_path}/mysql*`
fi

# 인자를 줘야만 실행되는 로직
#mysql_folderName="mysql-${1}-el7-x86_64"

#if [ ${1} == "8.0.32" ]; then
 # mysql 바이너리 최신버전 설치 로직
#	echo `wget https://dev.mysql.com/get/Downloads/MySQL-8.0/${mysql_folderName}.tar.gz`
#else
 # mysql 바이너리 구 버전 설치 로직 (아카이브에서 가져옴)
#	echo `wget https://downloads.mysql.com/archives/get/p/23/file/${mysql_folderName}.tar.gz`
#fi

# NHN Cloud 환경 실험용 자동 실행 로직
mysql_folderName="mysql-8.0.32-el7-x86_64"
echo `wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.32-el7-x86_64.tar.gz`


# mysql 압축해제 및 권한 변경
echo `mv ${mysql_folderName}.tar.gz ${user_path}`
echo `tar -xvf ${user_path}/${mysql_folderName}.tar.gz -C ${user_path}`
echo `sudo yum install -y libaio`
echo `ln -s ${user_path}/${mysql_folderName} ${user_path}/mysql`

# my.cnf parameter 설정
mycnf_parameter=$(cat << EOF
[client]
port=3306
socket=${user_path}/mysql/mysql.sock
[mysqld]
user=centos
socket=${user_path}/mysql/mysql.sock
basedir=${user_path}/mysql
datadir=${user_path}/mysql/data
pid-file=${user_path}/mysql/mysqld.pid
log-error=${user_path}/mysql/mysql-logs/mysqld.log
skip-grant-tables
EOF
)

echo `echo "${mycnf_parameter}" >> ${user_path}/mysql/my.cnf`
echo `mkdir ${user_path}/mysql/data`
echo `mkdir ${user_path}/mysql/mysql-logs`
echo `touch ${user_path}/mysql/mysql-logs/mysqld.log`
echo `ln -s ${user_path}/mysql/mysql.sock /tmp/mysql.sock`

#권한 변경
echo `sudo chown -R centos:centos ${user_path}/${mysql_folderName}`
echo `sudo chown -h centos:centos ${user_path}/mysql`

mysql_env_count=`cat ${user_path}/.bashrc | grep 'mysql' | wc -l`

if [ ${mysql_env_count} -gt 0 ]; then
        echo "이미 bashrc 환경변수가 지정되었습니다."
else
        echo `echo "export PATH="\\$"PATH:"${user_path}"/mysql/bin/" >> ${user_path}/.bashrc`
fi

echo `${user_path}/mysql/bin/mysqld --defaults-file=${user_path}/mysql/my.cnf --initialize`
echo `${user_path}/mysql/bin/mysqld --defaults-file=${user_path}/mysql/my.cnf &`

binary_redis_install.sh

#!/usr/bin/env bash

# if [ -z $1 ]; then
#	echo 버전 정보를 입력하지 않으면 실행되지 않습니다.
#	exit 1
#fi

user_path="/home/centos"
#redis_folderName="redis-${1}"

# redis 링크 확인 로직
#redis_connection=`wget --timeout=1 --tries=1 --spider http://download.redis.io/releases/${redis_folderName}.tar.gz | grep 'broken link' | wc -l`
# if [ redis_connection -ge 1 ]; then
#	echo "잘못된 링크입니다. 프로그램을 종료합니다."
#	exit 2
#fi


# redis binary 설치 확인 및 삭제 로직
redis_count=`find ${user_path}/redis* | wc -l`
if [ ${redis_count} -gt 0 ]; then
	echo "redis 설치가 확인되어 삭제합니다."
	echo `rm -rf ${user_path}/redis*`
fi


# 인자를 주어야 실행되는 로직
# redis 설치
# echo `wget http://download.redis.io/releases/${redis_folderName}.tar.gz`

# NHN Cloud 환경 실험용 자동 실행 로직
redis_folderName="redis-7.0.8"
echo `wget http://download.redis.io/releases/${redis_folderName}.tar.gz`

# 필수 라이브러리 설치
echo `sudo yum install -y python3`
echo `sudo yum install -y gcc`


# redis 압축해제
echo `mv ${redis_folderName}.tar.gz ${user_path}`
echo `tar -xvf ${user_path}/${redis_folderName}.tar.gz -C ${user_path}`
echo `ln -s ${user_path}/${redis_folderName} ${user_path}/redis`

# 권한 변경
echo `sudo chown -R centos:centos ${user_path}/${redis_folderName}`
echo `sudo chown -h centos:centos ${user_path}/redis`

# 파일 이동

# make 소스파일 컴파일
echo `cd ${user_path}/redis/deps && sudo make hdr_histogram hiredis jemalloc linenoise lua`
echo `cd ${user_path}/redis && sudo make install `

# 컴파일 내용 권한 변경
echo `sudo chown -R centos:centos ${user_path}/${redis_folderName}`

# redis 커맨드 환경변수로 등록
redis_env_count=`cat ${user_path}/.bashrc | grep 'redis' | wc -l`

if [ ${redis_env_count} -gt 0 ]; then
	echo "이미 redis의  bashrc 환경변수가 지정되었습니다."
else
	echo `echo "export PATH="\\$"PATH:"${user_path}"/redis/src/" >> ${user_path}/.bashrc`
fi

# 환경변수는 바로 등록이 안되므로 alias 사용
echo `alias redis-cli="${user_path}"/redis/src/redis-cli`
echo `alias redis-server="${user_path}"/redis/src/redis-server`
echo `alias redis.conf="${user_path}"/redis/redis.conf`

# redis.conf alias 영구 등록
redis_conf_count=`cat ${user_path}/.bashrc | grep 'redis.conf' | wc -l`

if [ ${redis_conf_count} -ge 1 ]; then
	echo "이미 redis.conf의 alias가 지정되었습니다."
else
	echo `echo "alias redis.conf="${user_path}"/redis/redis.conf" >> ${user_path}/.bashrc`
fi

# redis 설정 에러 해결
# maxclients

# echo `ulimit -n 50000`

# 영구적 등록 (루트 권한이 아닐 경우에는 ulimit 명령어도 실행되지 않음)
maxclients_count=`grep centos /etc/security/limits.conf | wc -l`
if [ ${maxclients_count} -gt 0 ]; then
	echo "이미 centos계정의 maxclients값이 설정되어 있습니다."
else
	echo `echo "centos	 soft	nofile		50000" >> /etc/security/limits.conf`
	echo `echo "centos	 hard	nofile		50000" >> /etc/security/limits.conf`
fi

# TCP backlog
echo `sudo sysctl -w net.core.somaxconn=1024`

# 영구적 등록
somaxconn_count=`grep somaxconn /etc/sysctl.conf | wc -l`
if [ ${somaxconn_count} -gt 0 ]; then
	echo "이미 somaxconn값이 설정되어 있습니다."
else
	echo `echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf`
fi

# Memory overcommit
echo `sudo sysctl -w vm.overcommit_memory=1`

# 영구적 등록
overcommit_count=`grep overcommit /etc/sysctl.conf | wc -l`
if [ ${overcommit_count} -gt 0 ]; then
	echo "이미 overcommit값이 설정되어 있습니다."
else
	echo `echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf`
fi

yum_mysql_install.sh

#!/usr/bin/env bash

# yum으로 설치된 mysql 제거
yum_install_count=`yum list installed | grep mysql | wc -l`
rpm_install_count=`rpm -qa | grep mysql | wc -l`
# rpmfile_install_count=`sudo find / -name 'mysql*rpm' | wc -l`

if [ ${yum_install_count} -ge 1 ]; then
	echo "mysql package install find"
	echo `sudo yum remove -y mysql-community-*`
	echo `sudo rm -rf /var/lib/mysql`
fi

if [ ${rpm_install_count} -ge 1 ]; then
	echo "mysql rpm install find"
	rpm_install_name=`rpm -qa | grep mysql`
	echo `sudo rpm -e ${rpm_install_name}`
fi

# yum mysql 설치(최신 버전)
echo `sudo yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm`
echo `sudo yum install -y mysql-community-server`

# skip-grant-tables옵션 추가
echo `sudo systemctl stop mysqld`
echo `sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables"`
echo `sudo systemctl start mysqld`

echo "mysql yum 설치 완료"

yum_redis_install.sh

#!/usr/bin/env bash

# yum으로 설치된 Redis 제거
echo `sudo yum remove -y redis`

# redis 설치 로직 (최신 버전 고정)
echo `sudo yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm`
echo `sudo yum-config-manager --enable remi`
echo `sudo yum install -y redis`

# redis 설정 에러 해결
# maxclients

# echo `ulimit -n 50000`

# 영구적 등록 (루트 권한이 아닐 경우에는 ulimit 명령어도 실행되지 않음)
maxclients_count=`grep centos /etc/security/limits.conf | wc -l`
if [ ${maxclients_count} -gt 0 ]; then
        echo "이미 centos계정의 maxclients값이 설정되어 있습니다."
else
        echo `echo "centos       soft   nofile          50000" >> /etc/security/limits.conf`
        echo `echo "centos       hard   nofile          50000" >> /etc/security/limits.conf`
fi

# TCP backlog
echo `sudo sysctl -w net.core.somaxconn=1024`

# 영구적 등록
somaxconn_count=`grep somaxconn /etc/sysctl.conf | wc -l`
if [ ${somaxconn_count} -gt 0 ]; then
        echo "이미 somaxconn값이 설정되어 있습니다."
else
        echo `echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf`
fi

# Memory overcommit
echo `sudo sysctl -w vm.overcommit_memory=1`

# 영구적 등록
overcommit_count=`grep overcommit /etc/sysctl.conf | wc -l`
if [ ${overcommit_count} -gt 0 ]; then
        echo "이미 overcommit값이 설정되어 있습니다."
else
        echo `echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf`
fi

echo "redis yum 설치 완료"

결과


binary_mysql_install.sh

binary_redis_install.sh

yum_mysql_install.sh

yum_redis_install.sh

기타 사항


  1. Expect 명령어

    • CLI 상호작용 프로그램으로 프로그램 입력 자동화를 수행하거나 출력을 기다릴 수 있다.

    • (구) 버전의 MySQL 자동 설치 스크립트 구현시 Expect 명령어를 사용하여
      초기비밀번호를 입력해 루트계정으로 접속하여 사용자가 입력한 비밀번호로 바꿔주는 셸을 구현하였다.

    • Example

      function change_init_password() {
          local init_password=`sudo grep 'temporary password' /var/log/mysqld.log | cut -d ':' -f4 | sed 's/^ *//' | tail -1`
      
          expect -c "
          set timeout 3
          spawn mysql -u root -p
          expect \"Enter password :\"
          send \"$init_password\r\"
          expect \"mysql\"
          send \"alter user 'root'@'localhost' identified by '$1';\r\"
          expect \"mysql\"
          send \"exit\r\"
          expect eof"
          echo "새로운 루트 계정의 패스워드는 : $1 입니다."}
          
  2. wget option

    • wget --timeout=1 --tries=1 --spider을 통해 해당 링크가 유효하는지 검사하는 로직을 구현하였다.
      • spider : wget이 다운받지 않고 파일이 존재하거나 접근가능 한지만 확인한다.
      • timeout : wget이 응답을 기다리는 시간(seconds)
      • tries : wget이 파일을 검사하는 횟수(default : 20)
  3. skip-grant-tables vs initialize-insecure

MySQL 공식문서에서는 skip-grant-tables를 이용해 설치하는 방식을 지양 하므로(보안문제)
initialize-insecure방식으로 수정할 필요가 있다.

profile
데이터를 탐구하는 개발자

0개의 댓글