- Part One: Consul Basics
- Part Two: In-Depth Consul
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.
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:
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.
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:
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.
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.
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
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.
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.
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.
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).
The introduction to Consul ends here. The author will continue to write about Consul, so stay tuned!
文章评论