ตั้ง Consul Service Discovery บน VPS

ตั้ง Consul Service Discovery บน VPS

กรกฎาคม 2026 · อ่าน 8 นาที

Consul คือเครื่องมือ service discovery จาก HashiCorp ที่ช่วยให้ microservices บน VPS สามารถค้นหากันเองได้โดยอัตโนมัติ ไม่ต้องเก็บ IP address แบบ hardcoded บน config file Consul ทำหน้าที่จดทะเบียนบริการ ตรวจสอบสุขภาพ (health check) และเก็บค่าคอนฟิกแบบ distributed key-value store ทำให้ระบบ microservices ปรับตัวได้ง่ายตอนเซิร์ฟเวอร์ขึ้น-ลง หรือเมื่อต้องการเปลี่ยนแปลง configuration โดยไม่ต้อง restart service ทั้งเว็บ

ติดตั้ง Consul

วิธีง่ายที่สุดคือ download binary จาก hashicorp.com:

# ดาวน์โหลด Consul เวอร์ชันล่าสุด
cd /tmp
wget https://releases.hashicorp.com/consul/1.18.0/consul_1.18.0_linux_amd64.zip

# แตกไฟล์และย้ายไปยัง /usr/local/bin
unzip consul_1.18.0_linux_amd64.zip
sudo mv consul /usr/local/bin/
chmod +x /usr/local/bin/consul

# ตรวจว่าติดตั้งได้สำเร็จ
consul version

หรือใช้ apt package manager หากมี repository:

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt update
sudo apt install consul -y

รัน Consul Agent เป็นตัวแรก (Development)

สำหรับการทดสอบบน VPS ตัวเดียว ให้รัน agent เป็น server mode โดยใช้ bootstrap-expect=1:

# สร้าง directory สำหรับเก็บ data
mkdir -p /opt/consul

# รัน Consul server ตัวแรก
sudo consul agent -server \
  -ui \
  -bootstrap-expect=1 \
  -data-dir=/opt/consul \
  -client=0.0.0.0 \
  -bind=127.0.0.1 \
  -node=consul-server-1

เมื่อ Consul เริ่มทำงานจะเห็น log ประมาณนี้:

==> Starting Consul agent...
==> Consul agent running!
         Node name: consul-server-1
        Datacenter: dc1
            Server: true (bootstrap: true)
       Client Addr: 127.0.0.1 (HTTP: 8500, DNS: 8600)
      Cluster Addr: 127.0.0.1 (LAN: 8301 TCP/UDP, WAN: 8302 TCP/UDP)
Tip: วิธีนี้เหมาะสำหรับเซิร์ฟเวอร์ตัวเดียวหรือการทดสอบเท่านั้น สำหรับ production cluster หลายเซิร์ฟเวอร์ต้องตั้ง bootstrap-expect ให้ตรงกับจำนวน server (เช่น 3 servers ตั้ง bootstrap-expect=3) และใช้ config file แบบ HCL แทนการส่ง flag ผ่าน command line

จดทะเบียน Service ด้วย Configuration File

สร้าง JSON file เพื่อบอก Consul ว่าบริการไหนกำลังทำงาน:

# สร้าง /etc/consul.d/services.json
{
  "services": [
    {
      "id": "web-1",
      "name": "web",
      "port": 8080,
      "address": "127.0.0.1",
      "check": {
        "http": "http://127.0.0.1:8080/health",
        "interval": "10s"
      }
    },
    {
      "id": "api-1",
      "name": "api",
      "port": 3000,
      "address": "127.0.0.1",
      "check": {
        "http": "http://127.0.0.1:3000/status",
        "interval": "10s"
      }
    }
  ]
}

บอก Consul ให้อ่าน config นี้ เมื่อ restart:

sudo curl -X PUT --data-binary @/etc/consul.d/services.json \
  http://127.0.0.1:8500/v1/agent/reload

ใช้ Consul KV Store สำหรับ Configuration

Consul มี built-in key-value store ที่เก็บ config แบบ centralized:

# เก็บค่า configuration
consul kv put app/config/db_host "postgres.internal"
consul kv put app/config/db_port "5432"
consul kv put app/config/redis_url "redis://cache.internal:6379"

# ดึงค่ากลับมา
consul kv get app/config/db_host
consul kv get -recurse app/config/

Application สามารถดึงค่าจาก Consul ผ่าน HTTP API:

curl http://127.0.0.1:8500/v1/kv/app/config/db_host?raw

ตรวจสอบว่า Consul ทำงานถูกต้อง

# ดู Consul members ทั้งหมด (node ที่เชื่อมต่ออยู่)
consul members

# ดูบริการทั้งหมดที่มีการจดทะเบียน
consul catalog services

# ดูรายละเอียด node ตัวเอง
consul info

# ตรวจสอบสุขภาพบริการผ่าน HTTP API
curl http://127.0.0.1:8500/v1/health/state/passing

# ดูรายการ health check ทั้งหมด
curl http://127.0.0.1:8500/v1/agent/checks
Tip: เปิด Consul UI ผ่านเว็บเบราว์เซอร์ที่ http://127.0.0.1:8500 เพื่อดูภาพรวม services, nodes, และ key-value store อย่างสะดวก

แก้ปัญหาที่พบบ่อย

Error: "Address already in use" (Port 8500 conflict)

Port 8500 (HTTP API) หรือ 8301 (LAN gossip) ถูกยึดโดย process อื่น ให้ตรวจหา process ที่ใช้พอร์ตนั้น:

sudo lsof -i :8500
sudo lsof -i :8301

# ถ้าเป็น process อื่น ให้ kill หรือเปลี่ยน port ใน Consul config
sudo consul agent -server -http-addr 127.0.0.1:8501 -client=0.0.0.0

Error: "agent: failed to sync remote state: permission denied"

Consul ไม่มีสิทธิ์อ่าน/เขียน directory data หรือ config file ให้ตรวจสิทธิ์:

sudo chown -R consul:consul /opt/consul
sudo chown -R consul:consul /etc/consul.d
sudo chmod 755 /opt/consul /etc/consul.d

Health check ล้มเหลว (health status red)

Service บอก Consul ว่าสุขภาพไม่ดี ตรวจว่า HTTP endpoint ตอบสนองได้:

# ลองเรียก health endpoint ด้วยตัวเอง
curl http://127.0.0.1:8080/health -v

# ดูรายละเอียด health check ใน Consul
curl http://127.0.0.1:8500/v1/agent/checks | jq '.'

# ตรวจ error log
grep "health check" /var/log/syslog

Service ไม่โผล่ใน catalog แม้ว่าได้ register แล้ว

ตรวจว่า service definition JSON ถูกต้อง และ restart Consul:

# ตรวจ syntax ของ JSON
cat /etc/consul.d/services.json | jq .

# reload agent
consul reload

# ตรวจว่า service อยู่ใน list ไหม
consul catalog services -service=web

Agent เชื่อมต่อกับ cluster ไม่ได้ (failed to join)

ตรวจว่า firewall เปิด port และ address ที่บอกให้ join ถูกต้อง:

# ลองเชื่อม cluster เดิม
consul join 192.168.1.100:8301

# ถ้ายังไม่ได้ ตรวจ firewall
sudo ufw allow 8300/tcp
sudo ufw allow 8301/tcp
sudo ufw allow 8301/udp
sudo ufw allow 8302/tcp
sudo ufw allow 8302/udp

คำถามที่พบบ่อย

Consul ต่างจาก Eureka หรือ etcd อย่างไร?

Consul เป็น all-in-one tool ที่รวม service discovery, health checking, KV store และ distributed datacenter support ส่วน Eureka เป็น service discovery เฉพาะ (ใช้ใน Spring Cloud) etcd ใช้เป็น KV store จึงต้องคู่กับเครื่องมืออื่นเพื่อ service discovery Consul ถูกออกแบบมาให้ง่ายขึ้นโดยไม่ต้องอาศัยเครื่องมืออื่นหลาย ตัว

ต้องมี load balancer หรือ health check ระดับ OS หรือไม่?

Consul health check เป็นแค่เครื่องมือบ่งบอกสถานะ application ไม่ใช่ automated failover ถ้าต้องการให้ service restart อัตโนมัติเมื่อ fail ต้องคู่กับ systemd unit (ตั้ง Restart=on-failure) หรือ orchestration tool เช่น Kubernetes หรือ Docker Swarm เพียง health check อย่างเดียวไม่พอ

Consul มี HA mode สำหรับ production ไหม?

ใช่ สำหรับ production ต้องตั้ง Consul cluster ที่มี 3 หรือ 5 servers (จำนวนคี่) ตั้ง bootstrap-expect ให้ตรงกับจำนวนนั้น server ทั้งหมดต้องคุยกันได้ผ่าน gossip protocol บน port 8301 และต้องมี quorum (เสียงข้างมาก) เพื่อให้ Raft algorithm เลือก leader ได้ เช่นถ้ามี 3 servers และ 1 ตัวล่ม ยังเหลืออีก 2 ตัวที่เป็นเสียงข้างมาก จึงยังเลือก leader และทำงานต่อได้ปกติ