``` $ apt-cache search consul | grep ^consul consul - tool for service discovery, monitoring and configuration ```
Consul là một phần mềm còn khá mới (bản 1.0 từ 2017 https://github.com/hashicorp/consul/tree/v1.0.0), được ra đời ban đầu như một giải pháp cho "Service Discovery", kèm KeyValue storage.
Sau này phát triển thêm nhiều tính năng khác như Service Mesh.
#### Service Discovery là gì
Khái niệm service discovery không mới mẻ, nhưng chỉ thực sự phổ biến vói từ khóa này khi Microservices trở thành trào lưu (~ từ 2015). Service Discovery
là việc tìm địa chỉ IP/port của một service trong hệ thống, trở nên phức tạp khi trong hệ thống có nhiều service. Đặc biệt khi chạy trên cloud (AWS, Azure, GCP...), IP của các service thay đổi thường xuyên hơn do việc tạo/xóa máy ảo (hay container) là chuyện thường ngày trong môi trường cloud.
Việc tìm từ tên ra IP không đâu xa lạ, chính là việc DNS server đã làm từ khi có internet tới giờ. Thay vì gõ địa chỉ IP để vào 1 website, người dùng gõ 1 cái tên (domain), các dịch vụ
DNS sẽ đổi từ tên đó ra địa chỉ IP tương ứng. Các phần mềm DNS server phổ biến trên `*NIX` là BIND, Unbound, ...
Chuyện thay đổi "động" IP khi thêm service hay thay đổi máy chạy service cũng đã được giải quyết với DNS server truyền thống qua một cơ chế có tên "Dynamic DNS", nhưng việc sử dụng cũng không dễ tới mức gọi là "đơn giản".
Consul ban đầu là một Dynamic DNS server giúp cho việc này trở thành cực kỳ đơn giản. Ngoài consul, một phần mềm khác cũng không kém
phổ biến trong lĩnh vực này là `etcd` kết hợp với `SkyDNS` (bộ đôi này được dùng trong core của Kubernetes).
Consul có chức năng `HealthCheck`, nó liên tục kiểm tra xem service có truy cập được không, và chỉ trả về các service "sống" khi được hỏi. Tưởng tượng có 10 máy chạy service web, khi 3 máy down, service worker hỏi `consul` sẽ chỉ nhận về danh sách 7 máy còn sống.
Consul nằm trong bộ
software của Hashicorp, cùng những cái tên đình đám khác như: Vault, Terraform, Nomad. Consul đã được dùng trong production của nhiều công ty lớn, ví dụ như [GitLab](https://about.gitlab.com/blog/2019/11/08/the-consul-outage-that-never-happened/).
#### Ai cần dùng Service Discovery
Khi cần quản lý nhiều service tương tác với nhau. Khi địa chỉ các máy thay đổi thưởng xuyên. Hay đơn giản khi cần quản lý các thiết bị trong nhà
(Raspberry Pi cũng có thể chạy consul).
### Cài đặt
Mặc dù có thể cài bằng apt nhưng phiên bản trên apt rất cũ, không nên dùng.
``` $ apt-cache policy consul consul: Installed: (none) Candidate: 0.6.4~dfsg-3 Version table: 0.6.4~dfsg-3 500 500
http://vn.archive.ubuntu.com/ubuntu bionic/universe amd64 Packages ```
Phiên bản mới nhất hiện tại
``` $ curl -L api.github.com/repos/hashicorp/consul/tags 2>/dev/null | /usr/bin/python -c 'import sys,json; print([i["name"] for i in json.load(sys.stdin) if "beta" not in i["name"]][0])' v1.6.2 ```
Tải bản mới nhất qua https://www.consul.io/downloads.html
`consul` được viết bằng Golang, nên sản phẩm để mang đi deploy chỉ là 1 file binary duy nhất. File này giải nén ra có kích thước ~ 100M
(yeahhhh)
``` $ unzip consul_1.6.2_linux_amd64.zip Archive: consul_1.6.2_linux_amd64.zip inflating: consul $ du consul -h 104M consul ```
### Chạy ở dev mode
Consul khi chạy service có 2 chế độ: server hoặc agent. Một chế độ đặc biệt thứ 3 là `dev` dùng để chạy thử nghiệm.
``` $ ./consul version Consul v1.6.2 Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
$ ./consul agent -dev ==> Starting Consul agent... Version: 'v1.6.2' Node ID: 'a7e68a9a-77bd-6559-ae17-a302860a6e0d' Node name:
'hvnzen' Datacenter: 'dc1' (Segment: '<all>') Server: true (Bootstrap: false) Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600) Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302) Encrypt: Gossip: false, TLS-Outgoing:
false, TLS-Incoming: false, Auto-Encrypt-TLS: false ... 2020/01/05 01:02:17 [INFO] serf: EventMemberJoin: hvnzen.dc1 127.0.0.1 2020/01/05 01:02:17 [INFO] serf: EventMemberJoin: hvnzen 127.0.0.1 2020/01/05 01:02:17 [INFO] consul: Adding LAN server hvnzen (Addr: tcp/127.0.0.1:8300) (DC: dc1) ... 2020/01/05 01:02:17 [INFO] agent: Started DNS server 127.0.0.1:8600 (tcp)
2020/01/05 01:02:17 [INFO] agent: Started DNS server 127.0.0.1:8600 (udp) 2020/01/05 01:02:17 [INFO] agent: Started HTTP server on 127.0.0.1:8500 (tcp) 2020/01/05 01:02:17 [INFO] agent: Started gRPC server on 127.0.0.1:8502 (tcp) ==> Consul agent running! 2020/01/05 01:02:17 [INFO] raft: Node at 127.0.0.1:8300 [Candidate] entering Candidate state in term 2 ... 2020/01/05 01:02:17
[INFO] raft: Node at 127.0.0.1:8300 [Leader] entering Leader state ... ```
Chú ý: consul sử dụng các port sau:
``` $ lsof -n -P -p `pgrep consul` COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME consul 24079 hvn cwd DIR 259,6 4096 5641002
/home/hvn/me/consullab consul 24079 hvn rtd DIR 259,4 4096 2 / consul 24079 hvn txt REG 259,6 108053286 5641005 /home/hvn/me/consullab/consul consul 24079 hvn 0u CHR 136,1 0t0
4 /dev/pts/1 consul 24079 hvn 1u CHR 136,1 0t0 4 /dev/pts/1 consul 24079 hvn 2u CHR 136,1 0t0 4 /dev/pts/1 consul 24079 hvn 3u IPv4 1340781
0t0 TCP 127.0.0.1:8300 (LISTEN) consul 24079 hvn 4u a_inode 0,13 0 11931 [eventpoll] consul 24079 hvn 5u IPv4 1340782 0t0 TCP 127.0.0.1:8302 (LISTEN) consul 24079 hvn 6u IPv4
1340783 0t0 UDP 127.0.0.1:8302 consul 24079 hvn 7u IPv4 1340784 0t0 TCP 127.0.0.1:8301 (LISTEN) consul 24079 hvn 8u IPv4 1340785 0t0 UDP 127.0.0.1:8301 consul 24079 hvn
9u IPv4 1340786 0t0 UDP 127.0.0.1:8600 consul 24079 hvn 10u IPv4 1339562 0t0 TCP 127.0.0.1:8600 (LISTEN) consul 24079 hvn 11u IPv4 1339564 0t0 TCP 127.0.0.1:8500 (LISTEN) consul
24079 hvn 12u IPv4 1339566 0t0 TCP 127.0.0.1:8502 (LISTEN) consul 24079 hvn 13u IPv4 1340787 0t0 TCP 127.0.0.1:42547->127.0.0.1:8300 (ESTABLISHED) consul 24079 hvn 14u IPv4 1337143 0t0
TCP 127.0.0.1:8300->127.0.0.1:42547 (ESTABLISHED) ```
### Ports
- TCP 8300: Consul RPC Server / Raft Server - TCP 8500: WebUI / HTTP API - TCP 8502: gRPC - TCP|UDP 8301: LAN - TCP|UDP 8302: WAN - TCP|UDP 8600: DNS
### DNS
Dùng lệnh `dig` để tra cứu thông tin về service tên `consul` xem nó chạy ở đâu, dùng port nào: