본문 바로가기
Linux

원격 서버 서비스 정지/가동 스크립트

by 도경다경 2023. 10. 19.
반응형

리눅스 서버 대상

원래는 각 서버에 직접 들어가서 스크립트를 통해 서비스 정지/가동을 했었으나
대상도 많아지고 각 서버 로그인하는게 너무 불편해서 
오픈소스 ansible 적용을 하려고 했으나 막상 해보니 구축하기도, 사용하기도 불편하고 그래서 그냥 간단한 프로그램을 만들었다.

 

1. 관리서버 1대에서 다른 서버에 ssh로 접속하여 서비스 정지 가동
2. 서비스 정지/가동/확인 명령어는 사전에 정의
3. 호스트를 지정하면 서비스 상태를 확인하고 가동중인 서비스 선택 시 종료, 종료 중인 서비스 선택 시 가동

 

■ 서비스 정지/가동/확인 사전 정의
$homedir/conf/hostname
호스트명:서비스명:서비스실행계정:서비스실행명령어:서비스종료명령어:서비스확인(프로세스 갯수 확인)명령어:프로세스 갯수

서비스가 여러개면 여러줄 입력

■ 서비스 실행 스크립트
service.sh -> service 호출

1) service.sh

########################################################################

#!/bin/bash

datetime=`date +"%Y%m%d_%H%M"`

home_dir=/sysadmin/master
bin_dir=$home_dir/bin
conf_dir=$home_dir/conf
log_dir=$home_dir/log

logfile=$log_dir/service_$datetime.log
config_file=$1

$bin_dir/service $conf_dir/$config_file | tee -a $logfile

########################################################################

※ 사용법 service.sh [hostname]

2) service 실행파일
########################################################################

#!/bin/bash

### root 접근 제한으로 입력한 계정명으로 접속 후 sudo 하여 명령어 수행
### 해당 계정은 사전에 sudo 권한이 부여되어 있어야 함
### 모든 서버 패스워드가 동일하다는 전제 하에 구성이며, ssh-key 배포로 해도 무관함(스크립트는 수정해야함)
### 실행하기 전에 대상 서버에 SSH 한번씩 접속해서 known_hosts에 추가가 되어야 한다.
SSH_USERNAME=[SSH접속 계정명] 
SSH_PASSWORD=[패스워드]

# Function to escape quotes in a command
# 명령어에 특수기호 있으면 전달이 안되므로 특수기호가 정상적으로 포함되도록 명령어에 특수기호 추가하는 함수
# 이 함수는 간단하지만 여기저기 많이 쓰인다.
escape_quotes() {
    echo "$1"  | sed "s/' /'\\\\' '/g"
}

 

run_command_as_service_account() {
    local hostname="$1"
    local service_user="$2"
    local command="$3"

    local escape_command
    escaped_command=$(escape_quotes "$command")

    ## USERNAME으로 접속, root 계정으로 switch user, 다시 서비스 실행계정으로 switch user 하여 실행
    sshpass -p "$SSH_PASSWORD" ssh "$SSH_USERNAME"@"$hostname" "sudo su -c 'su - $service_user -c \"$escaped_command\"'"
}

 

check_process_count() {
    local hostname="$1"
    local service_user="$2"
    local process_count_command="$3"
    local target_process_count="$4"

    local current_process_count
    current_process_count=$(run_command_as_service_account "$hostname" "$service_user" "$process_count_command")

    if (( $(echo "$current_process_count >= $target_process_count" | bc -l) )); then
        echo "running"
    else
        echo "stopped"
    fi
}

 

display_menu() {
    local index=1

    IFS=$'\n'

    /dev/null > /tmp/menu.tmp

    for line in $(awk NF "$SERVICE_INFO_FILE"); do
        IFS=":" read -r hostname service_name service_user start_command stop_command process_count_command target_process_count <<< "$line"
        local service_status=$(check_process_count "$hostname" "$service_user" "$process_count_command" "$target_process_count")
        echo "$index. $hostname $service_user@$service_name Status: $service_status" >> /tmp/menu.tmp
        ((index++))
    done

    clear

    echo "Service Management Menu :"
    echo "======================================================="

    cat /tmp/menu.tmp
    echo "======================================================="
}

 

### main

if [ "$#" -eq 0 ]; then
    echo "Usage: $0 <service_info_file>"
    exit 1
fi

SERVICE_INFO_FILE="$1"
max_line=`cat $SERVICE_INFO_FILE | wc -l`

while true; do
    display_menu
    choice=0
    echo "Enter then number of the service to manage (q to quit): "
    read choice

    if [ "$choice" == "q" ]; then
        break
    fi

    if [[ ! "$choice" =~ ^[0-9]+$ ]]; then
        echo "Invalid input. Please enter a valid number."
        continue
    fi

    if (( $choice >=1 && $choice <= $max_line )); then
        IFS=":" read -r hostname service_name service_user start_command stop_command process_count_command target_process_count <<< "$(sed -n "${choice}p" "$SERVICE_INFO_FILE")"
        echo "$choice"
        echo "Selected: $hostname $service_user@$service_name"

        service_status=$(check_process_count "$hostname" "$service_user" "$process_count_command" "$target_process_count")

        if [ "$service_status" == "running" ]; then
            echo "Stopping the service..."
            run_command_as_service_account "$hostname" "$service_user" "$stop_command"
            echo $stop_command
        else
            echo "Starting the service..."
            run_command_as_service_account "$hostname" "$service_user" "$start_command"
            echo $start_command
    else
        echo "Invalid choice. Please enter a valid number."
    fi
done

########################################################################

 

 

반응형

댓글