consul

2019-08-11  本文已影响0人  Robin92

Using consul, this doc is from https://learn.hashicorp.com/consul/getting-started/agent

Get Started

Installing

> sudo mv consul /usr/local/bin/
> consul
Usage: consul [--version] [--help] <command> [<args>]

Available commands are:
    acl            Interact with Consul's ACLs
    agent          Runs a Consul agent
    catalog        Interact with the catalog
    ...

Run the Consul Agent

Starting the Agent

> consul agent -dev  // never use -dev on production

show members

> consul members
Node                            Address         Status  Type    Build  Protocol  DC   Segment
xxx-HP-Pavilion-14-Notebook-PC  127.0.0.1:8301  alive   server  1.5.3  2         dc1  <all>

The output displays your agent, its IP address, its health state, its role in the datacenter, and some version information. You can discover additional metadata by providing the -detailed flag.

check

> curl localhost:8500/v1/catalog/nodes #  Failed by curl command, succeed by postman
> dig @127.0.0.1 -p 8600 xxx-HP-Pavilion-14-Notebook-PC.node.consul
... # 暂时理解不了输出

(我这里 curl 不成功是因为配置了命令行的代理,去掉 http_proxy 这样的设置,就可以成功了)

Stop agent

> consul leave
Graceful leave complete

总结

本节学习了如何启动 consul 的 agent 模式,并了解到它提供了一些 http api 和 dns 接口供使用查询相关信息,最后优雅地关闭 consul。


Registering A Service And A Health Check

service discovery

Consul provides a DNS interface that downstream services can use to find the IP addresses of their upstream dependancies. (Consul 提供了一个 DNS 接口,让下游服务获取到上游依赖服务的 IP 地址。)

You will register a service and health check manually by providing Consul with a configuration file, and use Consul discover its location using the DNS interface and HTTP API.

你将学到:

Defining a Service

We use the first method to try:

> mkdir ./consul.d
{
  "service": {
    "name": "web",
    "tags": ["rails"], // optional, used to find the service later on
    "port": 80 
  }
}
> consul agent -dev -enable-script-checks -config-dir=./consul.d
    # ...
    2019/08/11 12:11:06 [DEBUG] agent: Service "web" in sync
    2019/08/11 12:11:06 [DEBUG] agent: Node info in sync
    # ...

Note: We never started a web service in this example. Consul can register services that aren't running yet. It correlates each running service with its registration based on the service's port
注意:在这个例子中我们并没有启动一个 web 服务,即在 80 端口上并没有提供服务,但 consul 还是注册上了它。...

Query services

DNS Interface

NAME.service.consul

Consul runs by default on port 8600

> dig @127.0.0.1 -p 8600 web.service.consul
# ...
web.service.consul. 0   IN  A   127.0.0.1
web.service.consul. 0   IN  TXT "consul-network-segment="
# ...

You can also get the entire address/port pair as a SRV record

> dig @127.0.0.1 -p 8600 web.service.consul SRV
# ...
web.service.consul. 0   IN  SRV 1 1 80 robincai-HP-Pavilion-14-Notebook-PC.node.dc1.consul.
xxx-HP-Pavilion-14-Notebook-PC.node.dc1.consul. 0 IN A 127.0.0.1
xxx-HP-Pavilion-14-Notebook-PC.node.dc1.consul. 0 IN TXT "consul-network-segment="
# ...

The SRV record says that the web service is running on port 80 and exists on the node xxx-HP-Pavilion-14-Notebook-PC.node.dc1.consul..

Finally, you can also use the DNS interface to filter services by tags. TAG.NAME.service.consul

> dig @127.0.0.1 -p 8600 rails.web.service.consul
# ...
;; ANSWER SECTION:
rails.web.service.consul. 0 IN  A   127.0.0.1

;; ADDITIONAL SECTION:
rails.web.service.consul. 0 IN  TXT "consul-network-segment="

HTTP API

> curl http://localhost:8500/v1/catalog/service/web 
> curl 'http://localhost:8500/v1/health/service/web?passing'

Updating Services

Next you'll update the web service by registering a health check for it. Because you never started a service on port 80 where you registered web, the health check you register will fail.

{
    "service": {
        "name": "web",
        "tags": ["rails"],
        "port": 80,
        "check": { // scripts: every 10s call curl localhost to check 
            "args": ["curl", "localhost"],
            "interval": "10s"
        }
    }
}
> consul reload

If the command exits with an exit code >= 2, the check will fail, and 1 will be considered as warning state.
DNS server only return healthy service, so now query by DNS will return no host.

总结

这一节学了如何注册一个服务,对它进行 health 检查(check 字段),并通过 api 去获取信息,主要是通过配置文件来实现。


Connect Service - Service Mesh

In addition to providing IP addresses directly to services with the DNS interface or HTTP API, Consul can connect services to each other via sidecar proxies that you deploy locally with each service instance. This type of deployment (local proxies that control network traffic between service instances) is a service mesh. Consul's service mesh feature is called Consul Connect.
除了通过 DNS 接口和 HTTP API 提供 IP 地址给服务, Consul 也能连接 services 通过边车代理,你可以在本地通过每一个服务实例部署这个边车代理。这种类型的部署就是服务网格。

In this guide you will:

Start a Service

socat 是一个小工具,可以创建一个 Connect-unaware 的服务

> socat -v tcp-l:8181,fork exec:"/bin/cat"
> nc 127.0.0.1 8181

Register the Service and Proxy with Consul

// ./consul.d/socat.json
{
    "service": {
        "name": "socat",
        "port": 8181,
        "connect": { 
            "sidecar_service": {}
        }
    }
}
> consul reload

Take a look at the "connect" stanza in the registration you just added. This empty configuration notifies Consul to register a sidecar proxy for this process on a dynamically allocated port. It also creates reasonable defaults that Consul will use to configure the proxy once you start it via the CLI. Consul does not automatically start the proxy process for you. This is because Consul Connect allows you to chose the proxy you'd like to use.

看上面的 connect 字段,它指定了一个空的 sidecar_service ,意思是通知 consul 为 这个进程 动态 注册一个 边车代理。但这个代理默认是不自动启动的,需要你通过 cli 来启动,这么做是因为 Consul Connect 允许你自己选择你想用的代理。虽然这个代理没有任何配置,但在你启动时,它会自动给一些合理的默认值进去。

You'll use the L4 proxy in this guide, because it comes with Consul and doesn't require any extra installation.

Run with consul connect proxy, and specify service instance and proxy registration it corresponds to

> consul connect proxy -sidecar-for socat
After this, you can see: image.png

Register a Dependent Service and Proxy

下面我们来注册一个下游服务 web 带有 connectsidecar, 并且指定 socat 为上游依赖,监听端口和代理。
更改 ./consul.d/web.json

{
    "service": {
        "name": "web",
        "port": 8080,
        "connect": {
            "sidecar_service": {
                "proxy": {
                    "upstreams": [
                        {
                            "destination_name": "socat",
                            "local_bind_port": 9191
                        }
                    ]
                }
            }
        }
    }
}

This registers a sidecar proxy for the service "web", and will listen on port 9191 to establish mTLS connections to "socat".

> consul reload

如果我们起一个真实的服务去访问代理,代理将加密数据并通过网络发送给 socat 的 sidecar proxy,socat 的 sidecar proxy 会解密并发送线 socat 服务(8181端口)。 Because there is no web service running, you will pretend to be the web service by talking to its proxy on the port that we specified (9191).

所以现在是这样(通过 UI 查看的):

此时,命令行中 run nc 127.0.0.1 9191 是连接不上的。执行下面的语句

> consul connect proxy -sidecar-for web

然后再执行 nc 127.0.0.1 9191 即可以连接上了。证明,配置文件生效了。

Control Communication with Intentions

intention 命令定义了哪些 services 之间允许交流,上面默认是用了 allow all。它用的是 service name 进行操作,而不是 IP 和 端口。如:

> consul intention create -deny web socat
Created: web => socat (deny)

这个命令明确禁止了 web 与 socat 服务的访问关系。执行了后,再次尝试 nc 127.0.0.1 9191 进行访问将会失败

> consul intention delete web socat

此时再执行 nc 127.0.0.1 9191 又可以访问成功

总结

这里我们学习了如何配置一个服务的自动发现。
知道了 connect.sidecar_service 字段是设置边车服务,这个对象设置为空会使用默认值;里面再加上字段 proxy.upstreams 可以设置它的上游服务(会调用的,依赖的服务)指定了端口和服务名。(没理解这个 9191 是什么意思)
另外地,也学到了一些工具,如 socat 工具和 nc 工具。

参考: https://www.consul.io/docs/connect/registration/sidecar-service.html 其中,解释了 sidecar-service 的模式与等效配置,即相当于配了一个 "name": "web-sidecar-proxy", "kind": "connect-proxy" 的服务。

参考:https://www.consul.io/docs/connect/registration/service-registration.html#upstream-configuration-reference 中解释了 “ local_bind_port (int: <required>) - Specifies the port to bind a local listener to for the application to make outbound connections to this upstream.” 即, 这个字段为上游服务(在 8181)指定了一个新端口 (9191),因为现在是都在本地,所以 两者都是暴露的,之后用容器的话, 8181 应该是要隐藏在容器中的


这里只做了简单的入门操作,以便更能理解一些技术文章中的操作,可以再参考其他文章以加深理解:

上一篇 下一篇

猜你喜欢

热点阅读