欢迎光临散文网 会员登陆 & 注册

Shell脚本实战:Consul 服务注册和注销的最佳实践

2023-04-24 04:03 作者:小毛驴的烂笔头  | 我要投稿

业务爸爸需求: 写一个脚本用于向 Consul 注册或注销服务。

Consul API 实现服务的注册和注销功能

拿到这个需求,我第一时间想到是用 curl 调用 Consul API 实现服务的注册和注销功能。 如下:

#!/bin/bash

CONSUL_TOKEN="<your_token_here>"
CONSUL_URL="http://localhost:8500"

function register_service {
  curl \
    --request PUT \
    --header "Content-Type: application/json" \
    --header "X-Consul-Token: ${CONSUL_TOKEN}" \
    --data "@- ${CONSUL_URL}/v1/agent/service/register" <<EOF
{
  "ID": "${1}",
  "Name": "${2}",
  "Address": "${3}",
  "Port": ${4}
}
EOF
}

function deregister_service {
  curl \
    --request PUT \
    --header "X-Consul-Token: ${CONSUL_TOKEN}" \
    "${CONSUL_URL}/v1/agent/service/deregister/${1}"
}

# example usage
register_service "my-service" "My Service" "localhost" 8080
deregister_service "my-service"

在这个实现中,我们将认证token存储在CONSUL_TOKEN变量中,并在curl请求中使用--header "X-Consul-Token: ${CONSUL_TOKEN}"来添加它。

这个是可以实现业务爸爸的需求, 但是,这种实现有以下几个问题:

1. 不能批量添加相同的类型的指标。

2. 唯一ID需要手动维护。

3. 没有配置文件留底,虽然三节点的consul集群很小概率同时出问题, 但是有留底还是一个很好习惯。

基于这个几个点, 写入下面实现脚本。

register 和 deregister实现

#!/bin/bash
# author 小毛驴


SHELL_DIR=$(cd $(dirname $0);pwd)
BACKUP_DIR=${SHELL_DIR}"/consulbackup"
SOURCEFILE=${SHELL_DIR}"/origin.json"
LOGFILE=${SHELL_DIR}"/add.log"
BASESVCRIR=/data/consul/config/
TOKENFILE=/data/consul/consul_token.yaml 

OPTION=${OPTION:="1"}
ENV=${ENV:="prod"}
PROJECT=${PROJECT:="fb"}
MODULE=${MODULE:="api"}
SERVICENAME=${SERVICENAME:="node-exporter"}
NAME=${NAME:="core"}
TAG=${TAG:="node-exporter"}
IPADDRS=""
IPADDR=""
PORT=${PORT:="9520"}

LEGAL_IP="^([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$"



if [ ! -"${BACKUP_DIR}" ];then
    mkdir -p ${BACKUP_DIR}
fi

function usage(){
        echo -"\nUsage: $0 <option> <value>"
        echo -"\n option:"
        echo -"\n -o,--option    option name, default 1:add , 2:delete"
        echo -"\n -e,--env       env name, default prod"
        echo -"\n -p,--project   project name, default fb"
        echo -"\n -m,--module    module name, default api"
        echo -"\n -n,--name      api name, default core"
        echo -"\n -s,--svcname   serviceName name, default node-exporter"
        echo -"\n -t,--tag       tag name, default node-exporter"
        echo -"\n -a,--address   ip address, eg 1.1.1.1|2.2.2.2 default '' [Require]"
        echo -"\n -i,--interface interface num default 9520"
        echo -"\n -h,--help      help"
}

function checkIp()
{
    #正则表达式检验 ip 地址
    [[  $1 =~ $LEGAL_IP ]]
    if [ $? -gt 0 ]; then
        echo "$1 is an error ip fromat"
        exit 10
    fi
}

function svcDeregister() {
    if [ ! -"$1" ];then
        echo "$1 not exit, please check!"
    else
        /bin/consul services deregister  -token-file=${TOKENFILE}  $1
    fi
}

function svcRegister() {
    if [ ! -"$1" ];then
        echo "$1 not exit, please check!"
    else
        /bin/consul services register  -token-file=${TOKENFILE} $1
    fi
}


function genJson() {

cat > "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}.json" <<EOF
{
  "service": {
    "id": "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}",
    "name": "${SERVICENAME}",
    "tags": [
       "${TAG}"
    ],
    "address": "${IPADDR}",
    "port": ${PORT},
    "meta": {
      "name": "${NAME}-${IPADDR}",
      "module": "${MODULE}",
      "project": "${PROJECT}",
      "env": "${ENV}"
    },
    "check": {
      "http": "http://${IPADDR}:${PORT}/metrics",
      "interval": "10s"
    },
    "weights": {
      "passing": 10,
      "warning": 1
    }
  }
}
EOF

}

function removeJson() {
    mv "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}.json"  ${BACKUP_DIR}
}


function main() {

    if (($# == 0));then
        usage
        exit
    fi

    cd ${SHELL_DIR}

    while [ -"$1" ];do
        case $1 in 
        -o|--option )
            OPTION=$2
            shift
            ;;
        -e|--env )
            ENV=$2
            shift
            ;;
        -p|--project )
            PROJECT=$2
            shift
            ;;
        -m|--module  )
            MODULE=$2
            shift
            ;;
        -n|--name )
            NAME=$2
            shift
            ;;
        -s|--svcname )
            SERVICENAME=$2
            shift
            ;;
        -t|--tag )
            TAG=$2
            shift
            ;;
        -a|--address )
            IPADDRS=$2
            shift
            ;;
        -i|--interface )
            PORT=$2
            shift
            ;;
        -h|--help )
            usage
            exit
            ;;
        *)
            echo -"\n$1 unknow an option"
            usage
            exit
        esac
        shift
     done

    if [ "${IPADDRS}"== ""];then
        echo -"\n-a|--address option is Require"
        usage
        exit
    fi

    SVCRIR="${BASESVCRIR}/${SERVICENAME}"
    if [ ! -"${SVCRIR}" ];then
        mkdir -p ${SVCRIR}
    fi
    cd ${SVCRIR}

    hosts=($(echo ${IPADDRS} | sed 's/|/ /g'))
    for(( i=0;i<${#hosts[@]};i++)) 
    do
        echo ${hosts[$i]}
        checkIp ${hosts[$i]}
        IPADDR="${hosts[$i]}"
        if [[ "${OPTION}"== "1"x  ]]; then
            genJson
            #statements
            svcRegister "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}.json" 
        fi
        if [[ "${OPTION}"== "2"x  ]]; then
            #statements
            svcDeregister "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}.json" 
            removeJson
        fi
    done 
}

main $@

这个脚本首先定义了BACKUP_DIR,BASESVCRIR 和TOKENFILE 等路径。

用法

./register-service.sh [OPTIONS]参数
-h, --help: 显示帮助信息并退出。
-o, -option: 1 register ; 2 deregister
-e,--env       环境标识, default prod
-p,--project  项目名字, default fb
-m,--module   业务模块名, default api
-n,--name      模块下面的应用名, default core
-s,--svcname   service 名字, default node-exporter
-t,--tag       tag 名字, default node-exporter
-a,--address   需要注册到该服务的地址,多个以“|”分开,, eg 1.1.1.1|2.2.2.2 default '' [Require],必须提供
-i,--interface  需要注册的端口 9520

./register-service.sh -o 1 -e prod -p fb -m ops -n consul-ops -s consul_exporter-t consul_exporter -a "10.2.0.6|10.2.0.10|10.2.0.41" -i 9107


Shell脚本实战:Consul 服务注册和注销的最佳实践的评论 (共 条)

分享到微博请遵守国家法律