ติดตั้ง etcd Distributed Key-Value Store บน VPS
etcd เป็น distributed key-value store แบบ open-source ที่ใช้ Raft consensus protocol ในการจัดการข้อมูล ได้รับความนิยมจาก Kubernetes ในการเก็บ configuration state ของระบบ การติดตั้ง etcd บน VPS ช่วยให้คุณสามารถสร้าง highly available database clusters และเข้าใจการทำงานของระบบ distributed systems แบบจริง
etcd คืออะไร และทำไมต้องใช้
etcd (easy to command) เป็น distributed key-value database ที่ถูกออกแบบให้เก็บข้อมูลสำคัญ เช่น configuration settings, state information, และ metadata สำหรับระบบ distributed ลักษณะสำคัญของ etcd คือ
- Strongly Consistent - ทุกการอ่านข้อมูลจะได้ข้อมูลล่าสุดทุกครั้ง
- Distributed Consensus - ใช้ Raft algorithm ในการตัดสินใจระหว่าง nodes
- Watch Mechanism - สามารถ monitor ค่า keys และตอบสนองต่อการเปลี่ยนแปลง
- TTL Support - รองรับการ set expiration time สำหรับ keys
- HTTP/gRPC API - เข้าถึงได้ผ่าน REST API และ gRPC protocol
Kubernetes ใช้ etcd เก็บ state ของ cluster ทั้งหมด รวมถึง pod configuration, services, secrets, configmaps และข้อมูลสำคัญอื่นๆ
ติดตั้ง etcd บน Ubuntu/Debian
วิธีที่ง่ายที่สุดในการติดตั้ง etcd คือดาวน์โหลด binary จากเว็บ official เนื่องจากเวอร์ชั่นใน apt repository อาจเป็นเวอร์ชั่นเก่า
# ดาวน์โหลดเวอร์ชั่นล่าสุด (ตรวจสอบจาก GitHub releases)
ETCD_VER=v3.5.13
DOWNLOAD_URL=https://github.com/etcd-io/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz
cd /tmp
wget -q --show-progress "$DOWNLOAD_URL"
tar xzf etcd-${ETCD_VER}-linux-amd64.tar.gz
cd etcd-${ETCD_VER}-linux-amd64
# ทำให้ executable สามารถเรียกใช้ได้ที่ไหนก็ได้
sudo mv etcd etcdctl /usr/local/bin/
# ตรวจสอบเวอร์ชั่น
etcd --version
etcdctl version
หรือใช้ apt package manager ถ้าต้องการ
sudo apt-get update
sudo apt-get install -y etcd-client
# สำหรับเซิร์ฟเวอร์ etcd ต้องใช้ binary download
ตั้งค่า etcd Single Node
สำหรับการทดสอบ หรือใช้ในสภาพแวดล้อม development สามารถเริ่มต้น etcd ด้วยคำสั่ง default ได้ทันที
# เรียกใช้ etcd ด้วย default settings
etcd
# ในอีก terminal ทดสอบด้วย etcdctl
etcdctl put key1 "Hello etcd"
etcdctl get key1
สำหรับสภาพแวดล้อม production ต้องสร้าง systemd service
# สร้างผู้ใช้ etcd
sudo useradd -r -s /bin/false etcd
# สร้าง data directory
sudo mkdir -p /var/lib/etcd
sudo chown -R etcd:etcd /var/lib/etcd
# สร้าง configuration file
sudo tee /etc/etcd/etcd.conf.yml > /dev/null < /dev/null <
ตั้งค่า etcd Cluster 3 Nodes
การตั้ง cluster เป็นหัวใจสำคัญของ etcd เพราะ Raft consensus ต้องใช้ quorum (ส่วนใหญ่ของ nodes) เพื่อให้การตัดสินใจสำเร็จ cluster ขนาด 3 nodes สามารถทำให้ 1 node ล้มเหลวได้โดยยังคง maintain data consistency
# Node 1 (IP: 192.168.1.10) - etcd-node1
sudo tee /etc/etcd/etcd.conf.yml > /dev/null < /dev/null < /dev/null <
สิ่งสำคัญ: ทำการ initialize cluster บน node ทั้ง 3 พร้อมกัน (ในช่วงเวลาที่ไม่ห่างกัน) โดยไม่ควรมากกว่า 1-2 นาที หากใช้เวลานานเกินไป cluster อาจไม่สามารถ form ได้อย่างถูกต้อง
ใช้งาน etcdctl CLI
etcdctl เป็น command-line client สำหรับโต้ตอบกับ etcd โดยการตั้ง environment variable ชี้ไป cluster endpoints
# ตั้ง endpoints สำหรับ cluster
export ETCDCTL_ENDPOINTS=192.168.1.10:2379,192.168.1.11:2379,192.168.1.12:2379
# ทดสอบการเชื่อมต่อ
etcdctl endpoint health
# Output:
# 192.168.1.10:2379, healthy, took = 3.123ms
# 192.168.1.11:2379, healthy, took = 2.850ms
# 192.168.1.12:2379, healthy, took = 3.456ms
# Put key-value
etcdctl put /app/config "production"
etcdctl put /app/version "1.2.3"
etcdctl put /database/host "db.example.com"
# Get value
etcdctl get /app/config
# /app/config
# production
# Get ทั้งหมดที่ขึ้นต้นด้วย prefix
etcdctl get /app/ --prefix
# /app/config
# production
# /app/version
# 1.2.3
# Delete key
etcdctl del /app/version
# Watch for changes (จะ block จนกว่ามีการเปลี่ยนแปลง)
etcdctl watch /app/config &
# เมื่อมีการเปลี่ยนค่า ใน window อื่น:
etcdctl put /app/config "staging"
# จะแสดง:
# PUT
# /app/config
# staging
# Get statistics
etcdctl member list
etcdctl member status
Backup และ Restore etcd Database
การทำ backup เป็นสิ่งสำคัญเพราะ etcd เก็บ state ของระบบ หากสูญหาย อาจส่งผลกระทบมาก
# Backup จาก cluster ใดก็ได้ (ต้องไม่มี write operation ในช่วงเวลานี้)
etcdctl --endpoints=192.168.1.10:2379 snapshot save backup.db
# ตรวจสอบ snapshot
etcdctl snapshot status backup.db
# Restore เข้า node อื่นหรือ test environment
sudo systemctl stop etcd
sudo rm -rf /var/lib/etcd/*
# Restore from snapshot
etcdctl snapshot restore backup.db \
--name etcd-node1 \
--initial-cluster etcd-node1=http://192.168.1.10:2380 \
--initial-cluster-token etcd-cluster \
--initial-advertise-peer-urls http://192.168.1.10:2380 \
--data-dir=/var/lib/etcd
# เปลี่ยน ownership
sudo chown -R etcd:etcd /var/lib/etcd
# เริ่ม etcd อีกครั้ง
sudo systemctl start etcd
ตรวจสอบว่า etcd ทำงานถูกต้อง
ใช้คำสั่งต่อไปนี้เพื่อทำการตรวจสอบว่า etcd ทำงานอย่างถูกต้อง
# ตรวจสอบ status ของ service
sudo systemctl status etcd
# ตรวจสอบ health ของ cluster
etcdctl endpoint health --endpoints=192.168.1.10:2379,192.168.1.11:2379,192.168.1.12:2379
# ตรวจสอบเข้าถึง API
curl -s http://localhost:2379/version | jq .
# Output:
# {
# "etcdserver": "3.5.13",
# "etcdcluster": "3.5.0"
# }
# ตรวจสอบการเขียนและอ่าน
etcdctl put test-key "test-value"
etcdctl get test-key
# test-key
# test-value
# ดู member ของ cluster
etcdctl member list --endpoints=192.168.1.10:2379
# 1234567890abcdef, started, etcd-node1, http://192.168.1.10:2380, http://192.168.1.10:2379, false
# 2345678901bcdef0, started, etcd-node2, http://192.168.1.11:2380, http://192.168.1.11:2379, false
# 3456789012cdef01, started, etcd-node3, http://192.168.1.12:2380, http://192.168.1.12:2379, false
sudo journalctl -u etcd -n 50 -f หากมีปัญหา logs จะแสดงข้อเสนอแนะ
แก้ปัญหาที่พบบ่อย
Error: "connection refused" เมื่อเชื่อมต่อ etcd
ปัญหานี้เกิดจากคำสั่ง etcd ยังไม่ได้เริ่มขึ้น หรือ endpoint ไม่ถูกต้อง
# ตรวจสอบว่า etcd กำลังทำงาน
sudo systemctl status etcd
# ถ้ายังไม่ได้เริ่ม
sudo systemctl start etcd
# ตรวจสอบ port 2379 เปิดอยู่หรือไม่
sudo netstat -tlnp | grep 2379
# ตรวจสอบ firewall
sudo ufw allow 2379/tcp
sudo ufw allow 2380/tcp
Error: "election timeout" หรือ "no leaders"
เกิดจากปัญหาการสื่อสารระหว่าง nodes ใน cluster หรือ cluster ยังไม่สมบูรณ์
# ตรวจสอบ network connectivity ระหว่าง nodes
ping 192.168.1.10
ping 192.168.1.11
ping 192.168.1.12
# ตรวจสอบ peer-to-peer port (2380)
nc -zv 192.168.1.10 2380
nc -zv 192.168.1.11 2380
nc -zv 192.168.1.12 2380
# ดู logs เพื่อหาสาเหตุ
sudo journalctl -u etcd --no-pager | grep -i "election\|leader\|timeout"
# หาก network ปกติ ลอง restart etcd ทุก node
sudo systemctl restart etcd
Error: "database corruption" หรือ "bad magic"
เกิดจากการค้างของ etcd process หรือ disk error
# ตรวจสอบว่า etcd process ยังทำงานอยู่หรือไม่
ps aux | grep etcd
# หาก stuck ลองสั่ง kill
sudo systemctl stop etcd
# ถ้า graceful stop ไม่ได้
sudo pkill -9 etcd
# ลบ lock file
sudo rm -f /var/lib/etcd/lock
# เริ่มใหม่
sudo systemctl start etcd
Error: "failed to parse initial-cluster members"
เกิดจาก configuration file มี syntax error
# ตรวจสอบ configuration file
cat /etc/etcd/etcd.conf.yml
# ตรวจสอบให้แน่ใจว่า:
# 1. initial-cluster มีทั้ง 3 nodes
# 2. syntax ถูกต้อง (YAML format)
# 3. IP address และ port ถูกต้อง
# ตัวอย่างถูกต้อง:
# initial-cluster: 'etcd-node1=http://192.168.1.10:2380,etcd-node2=http://192.168.1.11:2380,etcd-node3=http://192.168.1.12:2380'
# ตรวจสอบ error ใน logs
sudo journalctl -u etcd -n 100
คำถามที่พบบ่อย
Q: etcd ต้องใช้ 3 nodes จำนวน 3 ที่ต้องเสมอหรือ?
ไม่จำเป็น cluster ขนาด 3 nodes ถือว่า best practice เพราะสามารถทำให้ 1 node ล้มเหลวได้ โดยยังคง maintain quorum (2 nodes) สำหรับการตัดสินใจ Raft consensus ต้องใช้ quorum ดังนั้น clusters ที่มี odd number จึงเหมาะสม (1, 3, 5, 7...) โดย cluster ขนาด 5 nodes สามารถให้ 2 nodes ล้มเหลว cluster ขนาด 1 node (single node) ใช้ได้สำหรับ development แต่ไม่ recommended สำหรับ production
Q: etcd ใช้ gRPC หรือ HTTP API ดีกว่า?
etcdctl ใช้ gRPC โดยค่าเริ่มต้นจาก version 3 ขึ้นไป gRPC มีข้อดี เช่น ความเร็ว ประสิทธิภาพ และ multiplexing แต่ HTTP API ยังใช้ได้อยู่ สำหรับคำสั่ง curl และการ debugging HTTP API ก็สะดวก ส่วนใหญ่แล้ว etcdctl ก็ดีพอแล้ว
Q: etcd ต้องใช้ persistent storage (disk) ทำไม?
etcd ต้องใช้ persistent storage เพื่อให้ข้อมูลยังคงอยู่แม้ว่า node จะ restart ซ้ำๆ ปกติแล้ว data-dir ชี้ไป /var/lib/etcd บน disk แต่ถ้าใช้บน cloud VPS ต้องแน่ใจว่า disk มี sufficient space และ I/O performance พอ เนื่องจาก etcd เขียน logs ทุกครั้งมีการ commit state นอกจากนี้ snapshot file ควรจะ backup ไปที่ storage อื่นด้วย