Learning to Build Consul Service Discovery and Service Mesh - With Rich Examples and Images

2020年11月21日 4点热度 0人点赞 0条评论
内容目录

Part One: Consul Basics

1. Introduction to Consul

The official documentation describes: Consul is a network tool that provides a full-featured service mesh and service discovery.

What can it do? It automates network configuration, discovers services, and enables secure connections across any cloud or runtime.

So, our understanding of Consul is that it features service mesh and service discovery. What exactly do these two characteristics mean? Across what clouds?

In the following, we will gradually understand Consul through practical operations, building a real Consul service to experience.

2. Installing Consul

Consul needs to be installed on both servers, and the detailed steps can be referred to in the following instructions.

For Ubuntu/Debian Systems

# Add GPG key

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -

# Add repository
# If you get the message "apt-add-repository: command not found"
# You may need to install: apt-get install software-properties-common

sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"

# Update the source and install consul

sudo apt-get update && sudo apt-get install consul

For CentOS/RHEL Systems

# Use yum-config-manager to manage repositories
sudo yum install -y yum-utils

# Connect to the repository
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

# Install
sudo yum -y install consul

Checking Installation

You can enter consul to check if it is installed successfully; if there is output, it means the installation was successful.

root@50skbjiynxyxkcfh:~# 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
    config         Interact with Consul's Centralized Configurations
    connect        Interact with Consul Connect
    debug          Records a debugging archive for operators
    event          Fire a new event
    exec           Executes a command on Consul nodes
... ...

3. Running Consul Agent

Articles usually refer to a Consul service or an instance of Consul, which is called an Agent in the official documentation; remember this. To avoid confusion, this article will specify that a proxy refers to a proxy, while agent refers to the Consul instance.

An agent can run in server mode or client mode, and multiple agents form a Consul datacenter, where at least one agent in each Consul datacenter is in server mode.

It is not recommended to deploy a single server.

Starting the Agent

As mentioned earlier, an agent refers to an instance of Consul.

Since we are in the exploratory practice phase, and to avoid various encryption and security issues, we need to start with the -dev parameter, which indicates the development mode.

# $> consul agent
# Runs a Consul agent

consul agent -dev

After executing this command, Consul will start and occupy the terminal.

Consul started successfully

Pay attention to the information during startup. If it fails, you will need to resolve the issue based on the prompts, such as port conflicts:

Consul failed to start

Discovering Datacenter Members

You can discover datacenter members by executing the consul members command.

root@50skbjiynxyxkcfh:~# consul members
Node              Address          Status  Type    Build  Protocol  DC   Segment
50skbjiynxyxkcfh  172.31.0.6:8301  alive   client  0.5.2  2         dc1  <default>

This means checking the members of the current Consul service; currently, it is a single server, so there is only one member.

You don't need to pay attention to its utility; just remember this command, as we will use it to check information later.

Viewing the UI

If the server IP is 172.31.0.6, you can access the Consul UI service (HTTP APIs) through http://172.31.0.6:8500.

4. Registering Services in Consul Service Discovery

This section will introduce some networking knowledge in Consul, explaining ports and DNS;

Then, through examples, we will explain how to define services and register them in Consul -- Consul service discovery.

Ports

First, let’s explain some Consul ports.

The official documentation states: Before running Consul, you should ensure the following bind ports are accessible.

| Use | Default Ports |
| :----------------------------------------------------------- | :--------------- |
| DNS: The DNS server (TCP and UDP) | 8600 |
| HTTP: The HTTP API (TCP Only) | 8500 |
| HTTPS: The HTTPS API | disabled (8501)* |
| gRPC: The gRPC API | disabled (8502)* |
| LAN Serf: The Serf LAN port (TCP and UDP) | 8301 |
| Wan Serf: The Serf WAN port (TCP and UDP) | 8302 |
| server: Server RPC address (TCP Only) | 8300 |
| Sidecar Proxy Min: Inclusive min port number to use for automatically assigned sidecar service registrations. | 21000 |
| Sidecar Proxy Max: Inclusive max port number to use for automatically assigned sidecar service registrations. | 21255 |

*For HTTPS and gRPC, the ports specified in the table are recommendations.

  • The three interfaces, 8500 (HTTP), 8501 (HTTPS), and 8502 (gRPC), can be used to make remote requests for related services or accessed directly.

  • Since ports 8501 and 8502 are disabled, we can first look at the role of port 8500. We will gradually explain the others later.

​ Open your browser and visit http://{your IP}:8500, and you will be redirected to a UI interface.

  • To check which process occupies a port, you can use lsof -i:8081, where 8081 is the port you're checking.

Defining Services

This section explains how to define services and register them to Consul through configuration files and command form.

Open or create (if it does not exist) the /etc/consul.d directory, which we will use as the storage location for Consul configuration files.

In this directory, create a web.json file to define the service.

touch web.json

Edit the file to change its contents to:

{
  "service": {
    "name": "web",
    "tags": [
      "rails"
    ],
    "port": 8080
  }
}

The port can be set freely; here we define a service named web with port 8080.

Starting Services with Configuration

After defining the configuration directory and configuration file, we can restart the node using the configuration file:

consul agent -dev -enable-script-checks -config-dir=/etc/consul.d

-enable-script-checks enables configuration file checks to enhance security since configuration files can enable scripts that may introduce remote execution vulnerabilities. Of course, the practical steps in this article will not make use of this feature yet; we will preheat it.

If there are no issues, the following information will be prompted:

2020/11/21 10:09:25 [INFO] agent: Synced service "web"
2020/11/21 10:09:25 [DEBUG] agent: Node info in sync
2020/11/21 10:09:25 [DEBUG] agent: Service "web" in sync
2020/11/21 10:09:25 [DEBUG] agent: Node info in sync

Reloading Configuration Files

If you modify the configuration file, you can trigger Consul to reload the configuration file without restarting.

$ consul reload
Configuration reload triggered

5. Querying Services

After adding services to Consul, we can query them using either the DNS interface or the HTTP API. Other applications can query what services are provided by Consul over the network interface; this is service discovery (I hope my understanding is correct).

Via HTTP API

Through the Consul HttpAPI service, we can query the service list using the URL /v1/catalog/service/web.

Query using the command:

curl http://localhost:8500/v1/catalog/service/web

You can also access this through your browser.

The returned JSON lists all service nodes and information about each service instance's status. By analyzing this JSON, you can discover the service.

Once you find the service, you can retrieve the service's IP and port from the JSON information, allowing you to formally connect to this service.

Querying through the UI

Visit http://{your IP}:8500, and you will find that a service named web has been registered in the UI.

Registered web service

6. DNS Knowledge and Queries

Basics

In Linux, the dig command is used to query a domain's DNS information, example usage:

dig baidu.com
... ...
baidu.com.		375	IN	A	220.181.38.148
baidu.com.		375	IN	A	39.156.69.79
... ...

The standard port for DNS queries is 53, which can be used to query more domain information from a DNS server.

DNS has A records (resolving to IP), CNAME (aliases, resolving to domains), etc. If interested, look up more information on your own.

For dig command reference, visit here.

One format for dig queries is:

dig [@server] [-p {port}] [name]

dig @127.0.0.1 -p 8600 specifies port 8600 as the DNS service query port; name indicates the resource name being queried.

Keep this query format in mind.

Querying Consul Service Information via DNS

Having registered the web service earlier, how do we query its information via Consul's DNS interface (port 8600)?

You can execute on the default host:

dig @127.0.0.1 -p 8600 web.service.consul

As previously explained regarding the dig command, web.service.consul refers to the [name] portion. Consul appends .service.consul to the registered service name as a convention.

So, what is the use of querying this DNS? Just remember it for now; we will continue to explore later.

Summary

So far, we have learned how to use commands to register a service. However, since we have only "configured" a web service (on port 8080), there is no actual service running. In the following sections, we will deploy a real web service and register it in Consul.

7. Storing Data in Consul KV

Open your Consul UI, as shown:

KVUI

You can create key-value data via the UI or perform CURD operations on key-value data through the command line. Example commands are as follows:

Add or modify:

consul kv put {key} {value}

Get value:

consul kv get {key}

Delete key:

consul kv delete {key}

Example:

consul kv put name "Example Name"

Part Two: In-Depth Consul

This chapter introduces how to use Consul Service Mesh to connect services and proxy services; establish data centers and deploy multiple instances.

8. Consul Service Mesh

Understanding Consul Service Mesh

Consul Service Mesh creates a consistent platform for modern application networking and security through identity-based authorization, L7 traffic management, and service-to-service encryption.

What is its use?

For instance, it allows for federation between multiple clusters and environments, creating a global service mesh. Policies and security can be applied consistently across platforms. As shown in the diagram below:

Note: envoy is a third-party open-source edge and service proxy, not a feature of Consul; Consul comes with Consul Connect.

ConsulServiceMesh

Use case scenarios for Consul Service Mesh can be referenced here.

Consul Service Mesh can link services across multiple servers through proxies, allowing them to access each other over a dedicated network.

gateway

For details, please click https://www.consul.io/docs/connect/gateways/mesh-gateway

Deploy Real Services

In the official Consul documentation, socat is used to demonstrate a service and register it with Consul. The author finds this too complicated. To better learn Consul, the author has written a lightweight web service in Rust, which is 4MB in size for Windows and 8MB for Linux, with no dependencies required.

Readers are encouraged to use this web demo written by the author as a real service deployment. This demo is open source, and the download address is:

https://github.com/whuanles/consulweb/releases

After the download is complete, upload it to an empty directory on the server.

To customize the binding web service address, create a new option.txt file with the following content:

0.0.0.0:8081

Quickly create the file command:

echo "0.0.0.0:8081" > option.txt

The web service supports the deployment of static files. You can create static web page files such as index.html and place them in the program directory, then access them through the bound IP and port.

Remember to grant permissions to the web service:

chmod +x web

Execute ./web to start the web service, run nohup ./web & to run the web service in the background.

Now we have a real web service, and everyone can access it for testing using a browser.

Real Service Registration

After using the author's or a custom-written service, you need to register this service with Consul.

In the /etc/consul.d directory, create a realweb.json file.

{
  "service": {
    "name": "realweb",
    "port": 8081,
    "connect": {
      "sidecar_service": {}
    }
  }
}

Then execute consul reload to reload the configuration file.

Register Proxy

Why do we need to register a proxy?

Through practice, we have learned how to register services and service discovery. When introducing Consul earlier, we also saw that "Consul provides a powerful service mesh" and "secure connections." By following the steps here (proxy), we can appreciate this feature of Consul.

Having already registered the realweb service, we now start the proxy by executing in a new terminal window:

consul connect proxy -sidecar-for realweb

Registering Proxy

We can see that Consul uses port 21000 to proxy the realweb service.

This proxy function is called Consul Connect.

However, this port is not accessible. Its basic structure is as follows:

        Source                     Proxy After
------------------        ------------------
|8081 <----> 21000| <----> |21001 <----> 9191|
------------------        ------------------

Both 8081 (source) and 9191 (proxy port) are accessible; 21000 and 21001 are bridge ports and cannot be accessed.

Proxy Service

After registering the realweb proxy service (8081 <---> 21000), we start proxying it (21001 <---> 9191).

The proxy here connects services using a Sidecar proxy via Consul Service Mesh, and this feature is called the service mesh.

        Source                                            Proxy After
--------------------------                --------------------------
|8081 <-----------< 21000|   <--------->   |21001 <-----------< 9191|
|     Consul Connect     |     Sidecar    |      Consul Connect    |
--------------------------                --------------------------

To implement the proxy, a new configuration file needs to be created to register the service.

In a new terminal window, create a file named proxyweb.json in the /etc/consul.d/ directory.

Its contents are as follows:

{
  "service": {
    "name": "proxyweb",
    "connect": {
      "sidecar_service": {
        "proxy": {
          "upstreams": [
            {
              "destination_name": "realweb",
              "local_bind_port": 9191
            }
          ]
        }
      }
    }
  }
}  

Each upstream configured for Connect proxy can be routed through the mesh gateway. local_bind_port indicates which port to use as the proxy port after service proxying.

Possible binding proxy ports are as follows (directly referenced from the documentation):

  • local - In this mode, the Connect proxy establishes outbound connections to a gateway running in the same datacenter. The gateway is then responsible for ensuring that the data is forwarded to the gateway in the target datacenter.

  • remote - In this mode, the Connect proxy establishes outbound connections to a gateway running in the target datacenter. That gateway then forwards the data to the final target service.

  • none - In this mode, no gateways are used, and the Connect proxy connects its outbound connections directly to the target service.

Once the configuration is complete (service registered), execute consul reload to reload the configuration file.

Next, execute the command to start the proxy service.

consul connect proxy -sidecar-for proxyweb

Verify Proxy

After creating the proxy, we check if it is functioning properly.

In a new terminal window, execute the access directory:

curl http://127.0.0.1:9191
root@50skbjiynxyxkcfh:~# curl http://127.0.0.1:9191
<h3>Congratulations, you have successfully deployed the Consul service!</h3><br><br><br><br>Remember to give the author a thumbs up~~~

The realweb service originally exposed port 8081, and then a proxy named proxyweb was created, which changed the port to 9191. We can now use 9191 to access the realweb service.

The following image is from the official website, which you can understand according to the picture.

proxy

If a microservice is set up where one host has a service like Redis on port 9003, would you expose Redis to the public internet? Definitely not! Therefore, through the proxy feature, the Redis service is proxied to another web server, changing the port to 5000. The web application can access the Redis service, but it cannot be accessed from the outside world.

Then the web provides port 9002 for users, allowing users to access the web service.

UI Interface View

Open the Consul interface to see the proxy service.

ServiceProxyUI1

ServiceProxyUI2

9. Consul Cluster/Data Center

This chapter will introduce how to link the agents of two servers together to establish a datacenter.

Start Preparation

Two servers are required here. Of course, the official documentation provides a method to deploy another system using virtual machines, but it is not advocated here. It’s better to work with two physical servers; otherwise, what would you learn about clustering and microservices...

Quickly deploy a virtual machine on Linux: https://learn.hashicorp.com/tutorials/consul/get-started-create-datacenter?in=consul/getting-started

Switch to the secondary server/virtual machine and install Consul according to the installation tutorial from the previous section.

On the main server, stop Consul and close other terminal windows, leaving only one terminal window open.

root@50skbjiynxyxkcfh:~# top | grep consul
32318 root      20   0  785168  66096  49008 S  1.3  3.2  13:52.93 consul                                                                                  
root@50skbjiynxyxkcfh:~# kill 32318

Start Consul Center

On the main server, execute the following command to start the Consul instance.

# -bind fill in subnet IP or public IP that the other server can access
consul agent \
  -dev \
  -server \
  -bootstrap-expect=1 \
  -node=agent-one \
  -bind=172.31.0.6 \
  -data-dir=/tmp/consul \
  -config-dir=/etc/consul.d
  • server - This flag indicates that you want the agent to start in server mode.

  • -bootstrap-expect - This tells Consul how many servers it expects to have in the datacenter.

  • -node - Each node in the datacenter must have a unique name.

  • -bind - This is the address that the agent will listen on to communicate with other Consul members. Fill in the subnet IP or public IP.

  • data-dir - This flag tells Consul agents where they should store state, which may include sensitive data such as ACL tokens for both servers and clients.

  • config-dir - This flag tells Consul where to find its configuration.

After successfully starting, the following prompt will appear:

    2020-11-21T07:46:59.903+0800 [INFO]  agent.server: federation state anti-entropy synced
    2020-11-21T07:46:59.903+0800 [INFO]  agent: Synced node info
    2020-11-21T07:46:59.911+0800 [INFO]  agent: Synced service: service=web
    2020-11-21T07:46:59.923+0800 [INFO]  agent: Synced service: service=proxyweb
    2020-11-21T07:46:59.939+0800 [INFO]  agent: Synced service: service=proxyweb-sidecar-proxy
    2020-11-21T07:46:59.961+0800 [INFO]  agent: Synced service: service=realweb
    2020-11-21T07:46:59.971+0800 [INFO]  agent: Synced service: service=realweb-sidecar-proxy
  • If there are error messages regarding realweb or proxy agents, they can be ignored.

Start Client

On the secondary server, execute the following command to start a new agent.

consul agent \
  -node=agent-two \
  -bind=172.31.0.7 \
  -enable-script-checks=true \
  -data-dir=/tmp/consul \
  -config-dir=/etc/consul.d

Check Member Information

So far, we have two servers, each running a Consul instance, but they are still independent and have not been linked together.

We can execute the following command on each server to check their member information:

consul members
# consul server 1
Node       Address          Status  Type    Build  Protocol  DC   Segment
agent-one  172.31.0.6:8301  alive   server  1.8.6  2         dc1  <all>

# consul server 2
Node       Address          Status  Type    Build  Protocol  DC   Segment
agent-two  172.31.0.7:8301  alive   client  1.8.6  2         dc1  <default>

Associate Servers

Now, let’s add the secondary server (172.31.0.7) to the main server (172.31.0.6).

On the secondary server, execute the following command:

consul join 172.31.0.6

Re-execute the consul members command on each server to check their member information:

# consul server 1
Node       Address          Status  Type    Build  Protocol  DC   Segment
agent-one  172.31.0.6:8301  alive   server  1.8.6  2         dc1  <all>
agent-two  172.31.0.7:8301  alive   client  1.8.6  2         dc1  <default>


# consul server 2
Node       Address          Status  Type    Build  Protocol  DC   Segment
agent-one  172.31.0.6:8301  alive   server  1.8.6  2         dc1  <all>
agent-two  172.31.0.7:8301  alive   client  1.8.6  2         dc1  <default>

Open UI to View Service Node Information

Open the Consul UI interface (on port 8500), click on Nodes, and you will see all server nodes of Consul.

Nodes

10. Cluster Proxy Service

This chapter describes how to use the proxy feature to access a service from one host on another server.

Provide Proxy Service

On the main server, close the proxyweb terminal (if already closed, ignore this) and enter the /etc/consul.d directory to delete the proxyweb.json file and reload the configuration:

consul reload

Then start the proxy feature (Consul Connect):

consul connect proxy -sidecar-for realweb

Proxy on Another Server

On the secondary server's /etc/consul.d/ directory, create a new proxyweb.json file with the following content:

{
  "service": {
    "name": "proxyweb",
    "connect": {
      "sidecar_service": {
        "proxy": {
          "upstreams": [
            {
              "destination_name": "realweb",
              "local_bind_port": 9191
            }
          ]
        }
      }
    }
  }
}  

Reload the configuration:

consul reload

Start the proxy service:

consul connect proxy -sidecar-for proxyweb

Verify Proxy

On the secondary server, open a new window and execute:

curl http://127.0.0.1:9191

You will see:

<h3>Congratulations, you have successfully deployed the Consul service!</h3><br><br><br><br>Remember to give the author a thumbs up~~~

This indicates that the proxy service allows one host's service (port) to be accessed on another host using a different port (or the same port).

TwoServerProxy

The introduction to Consul ends here. The author will continue to write about Consul, so stay tuned!

痴者工良

高级程序员劝退师

文章评论