def tcp(cls, service, params): """ Consul TCP Check This feature is only available when using Consul 0.6 or newer. Containers specifying these extra metadata in labels or environment will be used to register an TCP health check with the service. SERVICE_443_CHECK_TCP=true SERVICE_443_CHECK_INTERVAL=15s SERVICE_443_CHECK_TIMEOUT=3s # optional, Consul default used otherwise """ # https://github.com/cablehead/python-consul/blob/53eb41c4760b983aec878ef73e72c11e0af501bb/consul/base.py#L85 # https://github.com/gliderlabs/registrator/blob/master/docs/user/backends.md#consul-tcp-check tcp = cls._bool_value(params, 'tcp') if tcp: # Attempt to establish a tcp connection to the specified *host* and # *port* at a specified *interval* with optional *timeout* and optional # *deregister* after which a failing service will be automatically # deregistered. host = service.ip port = service.port interval, deregister = cls._common_values(params) timeout = cls._value(params, 'timeout') ret = Check.tcp(host, port, interval, timeout=timeout, deregister=deregister) return cls._post_process(ret, params) return None
def register(self): logger.info( 'Registering %s on Consul as %s with %s:%s', self._service_name, self._service_id, self._advertise_address, self._advertise_port, ) try: ttl_check = Check.ttl(self._ttl_interval) registered = self._client.agent.service.register( self._service_name, service_id=self._service_id, address=self._advertise_address, port=self._advertise_port, check=ttl_check, tags=self._tags, ) if not registered: raise RegistererError( '{} registration on Consul failed'.format( self._service_name)) except (ConnectionError, ConsulException) as e: raise RegistererError(str(e))
def register(self, name, register_type=MicroRegistry.TYPES_KV, value=None, **options): registry_name = register_type + ":" + name try: if registry_name not in self.registries: registry = { 'name': name, 'type': register_type, 'value': value, 'options': options, 'registered': False } self.registries[registry_name] = registry if register_type == MicroRegistry.TYPES_KV: yield from self.kv.put(name, value, **options) if register_type == MicroRegistry.TYPES_SERVICE: service_id = options.pop('service_id', name) check_ttl = options.pop('check_ttl', None) if check_ttl: options['check'] = Check.ttl(check_ttl) ttl = None if 'ttl_ping' in options: ttl = options.pop('ttl_ping') yield from self.agent.service.register(name, service_id=service_id) if ttl: self.health_tasks[service_id] = self._loop.create_task( self._health_ttl_ping(service_id, ttl)) self.registries[registry_name]['registered'] = True return True except Exception: logger.critical('failed to register with consul') self.registries[registry_name]['registered'] = False return False
def main(): c = consul.Consul() check_http = Check.http('http://127.0.0.1:5000/healthcheck', interval='5s', timeout='10s', deregister=True) # registration of checkout service c.agent.service.register('checkout', address=os.getenv("LISTEN_ADDR", "127.0.0.1"), port=5000, check=check_http) app.run(debug=True, host='0.0.0.0', port=5000)
def test_get_failed_cluster_checks(consul_service, consul1, consul2, consul3, consul4): consul_service.register(consul1, "service1") consul_service.register(consul2, "service1") consul_service.register(consul3, "service1", check=Check.ttl("1ms")) # failing consul_service.register(consul4, "service2") consul_service.register(consul3, "service2") consul_service.register(consul3, "service3") consul_service.register(consul2, "service4", check=Check.ttl("1ms")) # failing time.sleep(0.01) assert set(get_failed_cluster_checks(consul1, ["service1", "service2", "service3", "service4"]).keys()) \ == {"service:service1", "service:service4"}
def _create_http_check(options): http_check = Check.http( f'http://{options.consul_check_host}:{options.port}/status', f'{options.consul_http_check_interval_sec}s', timeout=f'{options.consul_http_check_timeout_sec}s' ) return http_check
def initialize_app(self, app) -> Optional[Future]: if not options.consul_enabled: integrations_logger.info('Consul disabled, skipping') return None host = socket.gethostname() self.consul = Consul(host=options.consul_host, port=options.consul_port) self.service_name = options.app self.service_id = f'{self.service_name}-{options.datacenter}-{host}-{options.port}' http_check = Check.http(f'http://{host}:{options.port}/status', options.consul_http_check_interval_sec, timeout=options.consul_http_check_timeout_sec) # not supported by version 1.1.0 meta = {'serviceVersion': version} return asyncio.ensure_future( self.consul.agent.service.register( self.service_name, service_id=self.service_id, address=host, port=options.port, check=http_check, tags=options.consul_tags, ))
def register(self, metrics_server, loop): """ :return: A coroutine callable to deregister or ``None``. """ consul = _Consul(token=self.token, loop=loop) if not (yield from consul.agent.service.register( name=self.name, service_id=self.service_id, address=metrics_server.socket.addr, port=metrics_server.socket.port, tags=self.tags, check=Check.http( metrics_server.url, "10s", ))): # pragma: nocover return None @asyncio.coroutine def deregister(): try: if self.deregister is True: yield from consul.agent.service.deregister(self.service_id) finally: consul.close() return deregister
def register_plugin(): """ Registers this plugin with Consul :return: None """ logger.info("Registering plugin with Consul") consul_host = getenv("CONSUL_HOST", "localhost") consul_port = getenv("CONSUL_PORT", 8500) c = Consul(host=consul_host, port=consul_port) hname = socket.gethostname() ipaddr = socket.gethostbyname(hname) health_check = Check.http(url=f'http://{ipaddr}:{port}/config', interval="20s", deregister=True) service_name = config['serviceName'] service_id = f'{service_name}-{str(uuid.uuid4())}' c.agent.service.register(name=service_name, service_id=service_id, address=ipaddr, port=port, tags=['secure=false'], check=health_check) atexit.register(deregister, c, service_id)
def keep_alive(service): ''' Ping the registry on an interval to show good health. ''' # the default tt is 10 sec ttl = service.ttl if hasattr(service, 'ttl') else 10 # register the service with consul register_service(service) # add a ttl check for the service in case we die consulSession.agent.check.register( name = service.consul_name, check = Check.ttl(str(ttl) + 's'), ) # the keep alive check def run_check(): # continuously run while True: # sleep every 2 seconds time.sleep(2) # tell the agent that we are passing the ttl check consulSession.agent.check.ttl_pass(service.consul_name, 'Agent alive and reachable.') # create a thread that will run the consumer thread = threading.Thread(target=run_check) # start the thread thread.start()
def run(self): all_svc = list(c.agent.services()) st.write(all_svc) if self.register_btn: for v in self.services.split('\n'): arr = v.split('\t') if len(arr) != 2: st.warning("Line not valid: {}".format(v)) name, url = arr if not name or not url: st.warning("Line not valid: {}".format(v)) if name in all_svc and not self.force: st.warning("Ignore: {}".format(name)) continue check = Check.http(url, interval=f'{self.num_interval}s', timeout=f'{self.num_timeout}s') c.agent.service.register(name=name, service_id=name, address=url, check=check) st.success("Registered: {}".format(name))
def keep_alive(service): ''' Ping the registry on an interval to show good health. ''' # the default tt is 10 sec ttl = service.ttl if hasattr(service, 'ttl') else 10 # register the service with consul register_service(service) # add a ttl check for the service in case we die consulSession.agent.check.register( name=service.consul_name, check=Check.ttl(str(ttl) + 's'), ) # the keep alive check def run_check(): # continuously run while True: # sleep every 2 seconds time.sleep(2) # tell the agent that we are passing the ttl check consulSession.agent.check.ttl_pass(service.consul_name, 'Agent alive and reachable.') # create a thread that will run the consumer thread = threading.Thread(target=run_check) # start the thread thread.start()
def register(self, metrics_server, loop): """ :return: A coroutine callable to deregister or ``None``. """ consul = _Consul(token=self.token, loop=loop) if not (yield from consul.agent.service.register( name=self.name, service_id=self.service_id, address=metrics_server.socket.addr, port=metrics_server.socket.port, tags=self.tags, check=Check.http( metrics_server.url, "10s", ) )): # pragma: nocover return None @asyncio.coroutine def deregister(): try: if self.deregister is True: yield from consul.agent.service.deregister(self.service_id) finally: consul.close() return deregister
def docker(cls, service, params): """ Consul Docker Check SERVICE_CHECK_DOCKER=curl --silent --fail example.com """ # https://github.com/cablehead/python-consul/blob/53eb41c4760b983aec878ef73e72c11e0af501bb/consul/base.py#L111 # https://www.consul.io/docs/discovery/checks#docker-interval # # NOTE: consul agent should be able to access docker socket: -v /var/run/docker.sock:/var/run/docker.sock script = cls._value(params, 'docker') if script: # Invoke *script* packaged within a running docker container with # *container_id* at a specified *interval* on the configured # *shell* using the Docker Exec API. Optional *register* after which a # failing service will be automatically deregistered. script = script.replace('$SERVICE_IP', service.ip).replace( '$SERVICE_PORT', str(service.port)) container_id = service.container_id[:12] shell = cls._value(params, 'shell') interval, deregister = cls._common_values(params) ret = Check.docker(container_id, shell, script, interval, deregister=deregister) # FIXME: as 2021/01/24, python-consul2 uses old script instead of args # it was removed in consul 1.1.0 # https://github.com/hashicorp/consul/blob/master/CHANGELOG.md#110-may-11-2018 if cls.consul_version >= (1, 1, 0): ret['args'] = script.split(" ") del ret['script'] return cls._post_process(ret, params) return None
def run(self): if self.register_btn: check = Check.http(self.txt_url, interval=f'{self.num_interval}s', timeout=f'{self.num_timeout}s') c.agent.service.register(name=self.txt_name, service_id=self.txt_name, address=self.txt_url, check=check)
def register(self, host='localhost', port=3000, tags=None): if host is None: host = 'localhost' self.consul.agent.service.register( name=self.service_name, address=host, port=port, tags=tags, check=Check.http(url=f'http://{host}:{port}/check', interval=10))
def register(self, url, timeout: int = TIMEOUT) -> None: self.consul.agent.service.register(self.service_name, tags=self.tags, service_id=self.service_id, address=self.address, port=8156, # timeout=self.timeout, check=Check.http(url=url, interval=self.http_interval))
def register_to_consul(): consul = Consul(host="consul", port=consul_port) agent = consul.agent service = agent.service check = Check.http(f"http://{service_name}:{service_port}/api/ui", interval="10s", timeout="5s", deregister="1s") service.register(service_name, service_id=service_name, port=service_port, check=check)
def script(cls, service, params): """ Consul Script Check This feature is tricky because it lets you specify a script check to run from Consul. If running Consul in a container, you're limited to what you can run from that container. For example, curl must be installed for this to work: SERVICE_CHECK_SCRIPT=curl --silent --fail example.com The default interval for any non-TTL check is 10s, but you can set it with _CHECK_INTERVAL. The check command will be interpolated with the $SERVICE_IP and $SERVICE_PORT placeholders: SERVICE_CHECK_SCRIPT=nc $SERVICE_IP $SERVICE_PORT | grep OK """ # https://github.com/cablehead/python-consul/blob/53eb41c4760b983aec878ef73e72c11e0af501bb/consul/base.py#L53 # https://github.com/gliderlabs/registrator/blob/4322fe00304d6de661865721b073dc5c7e750bd2/consul/consul.go#L115 # https://github.com/gliderlabs/registrator/blob/master/docs/user/backends.md#consul-script-check # https://www.consul.io/docs/agent/options#_enable_script_checks # https://www.hashicorp.com/blog/protecting-consul-from-rce-risk-in-specific-configurations args = cls._value(params, 'script') if args: # Run the script *args* every *interval* (e.g. "10s") to perfom health check args = args.replace('$SERVICE_IP', service.ip).replace('$SERVICE_PORT', str(service.port)) interval = cls._value(params, 'interval') if cls.consul_version >= (1, 1, 0): args = args.split(' ') ret = Check.script(args, interval) return cls._post_process(ret, params) else: # compat # https://github.com/cablehead/python-consul/commit/f405dee1beb6019986307c121702d2e9ad40bcda # https://github.com/cablehead/python-consul/commit/e3493a0e6089d01ae37347f452cf7510813e2eb4 ret = Check.script(args, interval) ret['script'] = args del ret['args'] return cls._post_process(ret, params) return None
def register(self): """ Register service in consul cluster. :return: None """ logger.debug("registering service") with ignore_connection_errors(): self.session.agent.service.register( name=self.service_name, service_id=self.service_id, port=self.port, tags=self.tags, # format the ttl into XXXs format check=Check.ttl("%ss" % self.ttl))
def register_service(self, app_id: str, host: str, port: int): if not app_id: raise ValueError if not host: raise ValueError if not port: raise ValueError self.consul.agent.service.register(name='pe', service_id=app_id, address=host, port=port, tags=['pe', 'python', app_id], check=Check.http( url='http://' + host + ':' + str(port), interval=self._DEFAULT_CONSUL_CONFIG['HEALTHCHECK_INTERVAL'], header={"Accept": ["application/json"]} ))
def test_reboot_fails_with_failing_checks(run_cli, consul_cluster, forward_consul_port, default_config, reboot_task, mock_subprocess_run, mocker): consul_cluster[0].agent.service.register("A", tags=["rebootmgr"]) consul_cluster[1].agent.service.register("A", tags=["rebootmgr"], check=Check.ttl("1ms")) # Failing time.sleep(0.01) mocker.patch("time.sleep") mock_subprocess_run(["shutdown", "-r", "+1"]) result = run_cli(rebootmgr, ["-v"]) assert result.exit_code == 2
def register_to_consul(): consul = Consul(host='consul', port=CONSUL_PORT) agent = consul.agent service = agent.service check = Check.http(f"http://{SERVICE_NAME}:{SERVICE_PORT}/api/social/ui", interval="10s", timeout="5s", deregister="1s") service.register(SERVICE_NAME, service_id=SERVICE_NAME, port=SERVICE_PORT, check=check)
def register(self): """ Register service in consul cluster. :return: None """ logger.debug("registering service") with ignore_connection_errors(): self.session.agent.service.register( name=self.service_name, service_id=self.service_id, address=self.address, port=self.port, tags=self.tags, # format the ttl into XXXs format check=Check.ttl("%ss" % self.ttl) )
def register(): """注册进入consul中""" # 读取配置文件 conf = config.CONF # 生成健康检查配置 check = Check().tcp(host=conf["consul"]["service"]["address"], port=conf["consul"]["service"]["port"], interval=conf["consul"]["service"]["interval"], timeout=conf["consul"]["service"]["timeout"], deregister=conf["consul"]["service"]["deregister"]) # 设置健康检查 _consul.agent.service.register( name=conf["consul"]["service"]["name"], service_id=conf["consul"]["service"]["service_id"], address=conf["consul"]["service"]["address"], port=conf["consul"]["service"]["port"], check=check) logging.info("服务注册进入consul")
def register_consul(self, port): self.consul_service.register( name=ConsulConfig.service_name, service_id=ConsulConfig.service_id, address=ConsulConfig.service_host, port=port, token=ConsulConfig.token, ) self.consul_check.register( name=f"service '{ConsulConfig.service_name}' check", check=Check.ttl("10000000s"), check_id=ConsulConfig.check_id, service_id=ConsulConfig.service_id, token=ConsulConfig.token, ) self.consul_check.ttl_pass(ConsulConfig.check_id)
def ttl(cls, service, params): """ Consul TTL Check You can also register a TTL check with Consul. Keep in mind, this means Consul will expect a regular heartbeat ping to its API to keep the service marked healthy. SERVICE_CHECK_TTL=30s """ # https://github.com/cablehead/python-consul/blob/53eb41c4760b983aec878ef73e72c11e0af501bb/consul/base.py#L103 # https://github.com/gliderlabs/registrator/blob/master/docs/user/backends.md#consul-ttl-check ttl = cls._value(params, 'ttl') if ttl: # Set check to be marked as critical after *ttl* (e.g. "10s") unless the # check ret = Check.ttl(ttl) return cls._post_process(ret, params) return None
def register_to_consul(): consul = Consul(host="consul", port=CONSUL_PORT) agent = consul.agent service = agent.service ip = get_host_name_IP() check = Check.http(f"http://{ip}:{SERVICE_PORT}/api/{SERVICE_NAME}/ui", interval="10s", timeout="5s", deregister="1s") service.register(name=SERVICE_NAME, service_id=SERVICE_NAME, address=ip, port=SERVICE_PORT, check=check)
def register_to_consul(): consul = Consul(host="consul", port=consul_port) agent = consul.agent service = agent.service ip = get_ip() check = Check.http(f"http://{ip}:{service_port}/", interval="10s", timeout="5s", deregister="1s") service.register(service_name, service_id=service_name, address=ip, port=service_port, check=check)
def main(): # consul client create c = consul.Consul() # health check check_http = Check.http('http://127.0.0.1:5001/healthcheck', interval='5s', timeout='10s', deregister=True) # registration of cart service c.agent.service.register('cart', address=os.getenv("LISTEN_ADDR", "127.0.0.1"), port=5001, check=check_http) # discovery services = c.catalog.service('checkout')[1][0] # url for checkout micro-service config[ 'CHECKOUT_URL'] = f"http://{services['ServiceAddress']}:{services['ServicePort']}" app.run(debug=True, host='0.0.0.0', port=5001)
def test_post_reboot_consul_checks_failing(run_cli, consul_cluster, forward_consul_port, default_config, reboot_in_progress, reboot_task, mocker): """ Test if we fail if consul checks are failing after reboot. """ consul_cluster[0].agent.service.register("A", tags=["rebootmgr"]) consul_cluster[1].agent.service.register("A", tags=["rebootmgr"], check=Check.ttl("1ms")) # Failing time.sleep(0.01) mocker.patch("time.sleep") mocked_run = mocker.patch("subprocess.run") result = run_cli(rebootmgr, ["-v"]) mocked_run.assert_not_called() assert result.exit_code == EXIT_CONSUL_CHECKS_FAILED
def test_post_reboot_wait_until_healthy(run_cli, consul_cluster, forward_consul_port, default_config, reboot_in_progress, reboot_task, mocker): """ Test if we wait until consul checks are passing after reboot. """ consul_cluster[0].agent.service.register("A", tags=["rebootmgr"]) consul_cluster[1].agent.service.register("A", tags=["rebootmgr"], check=Check.ttl("1000s")) consul_cluster[1].agent.check.ttl_fail("service:A") sleep_counter = 2 def fake_sleep(seconds): """ While we're waiting for consul checks to start passing, we sleep 120 seconds at a time. Count how often this happens, and after a few times, we will set the failing check to passing. We ignore sleep requests for different amounts of time. """ nonlocal sleep_counter if seconds == WAIT_UNTIL_HEALTHY_SLEEP_TIME: sleep_counter -= 1 if sleep_counter <= 0: consul_cluster[1].agent.check.ttl_pass("service:A") mocker.patch("time.sleep", new=fake_sleep) mocked_run = mocker.patch("subprocess.run") result = run_cli(rebootmgr, ["-v", "--post-reboot-wait-until-healthy"]) mocked_run.assert_not_called() assert sleep_counter == 0 assert result.exit_code == 0
def _register_service(self): logger.info("registering service to consul") client = Consul(host=self.configuration["CONSUL_HOST"], port=self.configuration["CONSUL_PORT"], scheme=self.configuration["CONSUL_SCHEME"], verify=self.configuration["CONSUL_VERIFY_SSL"]) health_address = "http://{host}:{port}/service/health" health_http = Check.http( url=health_address.format(host=self.configuration["HOST"], port=self.configuration["PORT"]), interval=self.configuration["CONSUL_HEALTH_INTERVAL"], timeout=self.configuration["CONSUL_HEALTH_TIMEOUT"]) client.agent.service.register(name=self.configuration["SERVICE_NAME"], service_id=generate_service_id( self.configuration["SERVICE_NAME"], self.configuration["HOST"], self.configuration["PORT"]), address=self.configuration["HOST"], port=self.configuration["PORT"], check=health_http)
def register(self): logger.info('Registering service {} with id {}'.format(self.name, self.id)) self.client.agent.service.register(name=self.name, service_id=self.id, check=Check.ttl('10s')) self.client.agent.check.ttl_pass(check_id=self.check_id) self.session = self.client.session.create(behavior='delete', checks=[self.check_id])
from consul import Consul, Check from lorem.text import TextLorem import time consul_port = 8500 time.sleep(10) models.Base.metadata.create_all(bind=engine) app = FastAPI(docs_url='/docs', openapi_url='/openapi.json') consul = Consul(host='consul', port=8500) agent = consul.agent service = agent.service check = Check.http('http://referral:5050/', interval='10s', timeout='5s', deregister='10s') ip = socket.gethostbyname('referral') service.register('referral', service_id='referral', address=ip, port=5050, check=check) def get_db(): try: db = SessionLocal() yield db finally: db.close()