天天看點

consul API,使用API來管理 consul

本次測試了下面幾個 api

consul_ip="10.0.26.104"

service_name="base-gateway"

檢視consul叢集所有 node :

curl "http://${consul_ip}:8500/v1/catalog/nodes" | jq
           
consul API,使用API來管理 consul

檢視consul叢集所有 service:

curl "http://${consul_ip}:8500/v1/internal/ui/services?dc=dc1" | jq
           

檢視consul叢集内某個service下的服務詳情(服務下的ID可以從這裡檢視):

curl "http://${consul_ip}:8500/v1/health/service/${service_name}?dc=dc1" | jq
           

删除consul叢集内某個ID:

curl -XPUT "http://${consul_ip}:8500/v1/agent/service/deregister/${service_id}"
           

檢視consul叢集内所有 critical (失效)狀态的

ID: "http://${consul_ip}:8500/v1/health/state/critical" | jq
           

檢視consul叢集内所有 passing (有效)狀态的

ID: "http://${consul_ip}:8500/v1/health/state/critical" | jq
           

=============================================

現在可以通過這些API拿到這些資訊,那麼接下來撸一段兒代碼,來利用起來。目前碰到了這種情況,某些地方的 consul 管理頁面不在一個内網,且對面沒有windows,不給代理。于是就突發奇想,研究一個linux端的管理工具。

使用python寫的,為了直接可以放在 centos 上執行,不安裝任何依賴包,于是下面代碼使用了 python2 ,子產品用了已經接近淘汰的 urllib和 urllib2 , 代碼如下:

vim manage_consul.py

# -*- coding: utf-8 -*-
import sys
import json
import urllib,urllib2


class ManageConsulServiceNode(object):
    """使用 consul 接口管理服務注冊情況"""
    def __init__(self, consul_ip):
        """基本資料"""
        self.consul_ip = consul_ip
        self.get_consul_nodes_url = "http://{consul_ip}:8500/v1/catalog/nodes"
        self.get_consul_service_url = "http://{consul_ip}:8500/v1/internal/ui/services?dc=dc1"
        self.get_consul_service_name_url = "http://{consul_ip}:8500/v1/health/service/{service_name}?dc=dc1"
        self.put_consul_service_id_url = "http://{consul_ip}:8500/v1/agent/service/deregister/{service_id}"
        self.query_consul_critical_url = "http://{consul_ip}:8500/v1/health/state/critical"

    def consul_ip_list(self):
        """擷取consul叢集節點ip"""
        ip_list = []
        get_consul_nodes_url = self.get_consul_nodes_url.format(consul_ip=self.consul_ip)
        request = urllib2.Request(get_consul_nodes_url)
        response = urllib2.urlopen(request)
        json_data = json.loads(response.read())
        for data_dict in json_data:
            consul_ip = data_dict["Address"]
            ip_list.append(consul_ip)
        return ip_list

    def get_consul_service_status(self):
        """擷取consul内所有服務"""
        service_list = []
        service_dict = {}
        get_consul_service_url = self.get_consul_service_url.format(consul_ip=self.consul_ip)
        request = urllib2.Request(get_consul_service_url)
        response = urllib2.urlopen(request)
        json_data = json.loads(response.read())
        for service_dict in json_data:
            service_dict["service_name"] = service_dict["Name"]
            service_dict["service_critical"] = service_dict["ChecksCritical"]
            service_dict["service_passing"] = service_dict["ChecksPassing"]/2
            service_list.append(service_dict)
        return service_list

    def get_consul_service_info(self):
        """擷取各服務内節點狀态,并列印"""
        print("")
        print("--- consul 叢集中目前服務如下: ---")
        print("\t目前 consul 叢集節點: {0}\n".format(self.consul_ip_list()))
        for service_name_dict in self.get_consul_service_status():
            service_name = service_name_dict["service_name"]
            if "consul" in service_name:
                continue
            head_mess = "\t\033[1;32m服務名: {0:^20} -存活的節點數: {1}, -失效的節點數: {2}\033[0m".format(
                                                                                           service_name_dict["service_name"],
                                                                                           service_name_dict["service_critical"],
                                                                                           service_name_dict["service_passing"],
                                                                                           chr(250)
                                                                                           )
            print(head_mess)
            get_consul_service_url = self.get_consul_service_name_url.format(consul_ip=self.consul_ip,service_name=service_name)
            request = urllib2.Request(get_consul_service_url)
            response = urllib2.urlopen(request)
            json_data = json.loads(response.read())
            for service_info in json_data:
                service_id = service_info["Service"]["ID"]
                service_ipaddr = service_info["Service"]["Address"]
                service_port = service_info["Service"]["Port"]
                service_status = service_info["Checks"][1]["Status"]
                boday_mess = "\t\t服務ID: {0:^60} 服務位址: {1}:{2} 狀态: {3}".format(
                                                                                  service_id,
                                                                                  service_ipaddr,
                                                                                  service_port,
                                                                                  service_status,
                                                                                  chr(250)
                                                                                  )
                print boday_mess
            print("")

    def deregister_consul_service_id(self, service_id):
        """發送 PUT 請求登出 consul 中服務 id"""
        for consul_ip in self.consul_ip_list():
            print("--- 清理{0}節點的: {1}".format(consul_ip, service_id))
            put_consul_service_id_url = self.put_consul_service_id_url.format(consul_ip=consul_ip,service_id=service_id)
            request = urllib2.Request(put_consul_service_id_url)
            request.get_method = lambda: 'PUT'
            ret = urllib2.urlopen(request).read()
            print(ret)

    def deregister_consul_all_critical_id(self, deregister_service=None):
        """登出 consul 内所有 critical 狀态的服務 ID"""
        query_consul_critical_url = self.query_consul_critical_url.format(consul_ip=self.consul_ip)
        request = urllib2.Request(query_consul_critical_url)
        response = urllib2.urlopen(request)
        json_data = json.loads(response.read())
        for critical_id_dict in json_data:
            if deregister_service is None:
                critical_id = critical_id_dict["ServiceID"]
                self.deregister_consul_service_id(critical_id)
            else:
                critical_service_name = critical_id_dict["ServiceName"]
                if deregister_service == critical_service_name:
                    critical_id = critical_id_dict["ServiceID"]
                    self.deregister_consul_service_id(critical_id)


if __name__ == "__main__":
    """按參數做相應處理"""
    parameter_sum = len(sys.argv)
    self_name = sys.argv[0]
    if parameter_sum < 2 or parameter_sum == 1:
        query_mess = "列出consul内所有服務和節點: {0} {1}".format(self_name, "[consul ip]")
        deregister_mess = "登出某個服務ID: {0} {1} {2}".format(self_name, "[consul ip]", "[service id]")
        deregister_critical_all_mess = "登出所有服務下的失效ID: {0} {1} {2}".format(self_name, "[consul ip]", "[critical]")
        deregister_critical_service_mess = "登出某個服務下的失效ID: {0} {1} {2} {3}".format(self_name, "[consul ip]", "[critical]", "[service name]")
        print(query_mess)
        print(deregister_mess)
        print(deregister_critical_all_mess)
        print(deregister_critical_service_mess)
        sys.exit(deregister_mess)

    ### 調用 consul api
    ip_parameter = sys.argv[1]
    manage_consul_service = ManageConsulServiceNode(ip_parameter)
    # 帶一個參數,直接列出所有服務的節點
    if parameter_sum == 2:
        manage_consul_service.get_consul_service_info()
    # 帶兩個參數時,第二個參數為 critical 時清理所有失效ID,第二個參數為服務 ID 時隻登出目前 ID
    if parameter_sum == 3:
        service_id = sys.argv[2]
        if service_id == "critical":
            manage_consul_service.deregister_consul_all_critical_id()
        else:
            manage_consul_service.deregister_consul_service_id(service_id)
    # 帶三個參數時,第二個參數為 critical, 第三個參數為對應的 service 名稱,即可登出對應 service 下的所有失效節點
    if parameter_sum == 4:
        service_name = sys.argv[3]
        manage_consul_service.deregister_consul_all_critical_id(service_name)
           

執行效果如下圖

空的執行腳本,列印使用方式

consul API,使用API來管理 consul

 列出所有服務和下面的 ID

consul API,使用API來管理 consul

 清理所有已經失效的ID

consul API,使用API來管理 consul

 清理某個沒有節點(沒有失效的節點也可被清理):

consul API,使用API來管理 consul

 清理某個服務下的失效節點:

consul API,使用API來管理 consul

繼續閱讀