写点什么

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

  • 2023-04-24
    广东
  • 本文字数:3275 字

    阅读完需:约 11 分钟

业务爸爸需求: 写一个脚本用于向 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 usageregister_service "my-service" "My Service" "localhost" 8080deregister_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 [ ! -e "${BACKUP_DIR}" ];then mkdir -p ${BACKUP_DIR}fi
function usage(){ echo -e "\nUsage: $0 <option> <value>" echo -e "\n option:" echo -e "\n -o,--option option name, default 1:add , 2:delete" echo -e "\n -e,--env env name, default prod" echo -e "\n -p,--project project name, default fb" echo -e "\n -m,--module module name, default api" echo -e "\n -n,--name api name, default core" echo -e "\n -s,--svcname serviceName name, default node-exporter" echo -e "\n -t,--tag tag name, default node-exporter" echo -e "\n -a,--address ip address, eg 1.1.1.1|2.2.2.2 default '' [Require]" echo -e "\n -i,--interface interface num default 9520" echo -e "\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 [ ! -e "$1" ];then echo "$1 not exit, please check!" else /bin/consul services deregister -token-file=${TOKENFILE} $1 fi}
function svcRegister() { if [ ! -e "$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 [ -n "$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 -e "\n$1 unknow an option" usage exit esac shift done
if [ "${IPADDRS}"x == ""x ];then echo -e "\n-a|--address option is Require" usage exit fi
SVCRIR="${BASESVCRIR}/${SERVICENAME}" if [ ! -e "${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}"x == "1"x ]]; then genJson #statements svcRegister "${SERVICENAME}-${ENV}-${PROJECT}-${MODULE}-${NAME}-${IPADDR}.json" fi if [[ "${OPTION}"x == "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

发布于: 刚刚阅读数: 4
用户头像

还未添加个人签名 2018-12-12 加入

还未添加个人简介

评论

发布
暂无评论
Shell脚本实战:Consul 服务注册和注销的最佳实践_Linux_小毛驴的烂笔头_InfoQ写作社区