Skip to content

16.8 Infrastructure evolution

บทนี้วางแผนการวิวัฒนาการของ infrastructure ควบคู่กับการแยก service ใน Wave 2-3

สถานะปัจจุบัน

                       ┌─────────────────────┐
                       │  Internet           │
                       └──────────┬──────────┘

                       ┌──────────▼──────────┐
                       │  Nginx (reverse     │
                       │  proxy, SSL term)   │
                       └──────────┬──────────┘

        ┌─────────────────────────┼──────────────────────────┐
        │                         │                          │
┌───────▼────────┐      ┌─────────▼─────────┐      ┌─────────▼────────┐
│ vtrc-api       │      │ vtrc-web          │      │ vtrc-rc-backoffice│
│ (Docker)       │      │ (Nginx static)    │      │ (Nginx static)    │
└───────┬────────┘      └───────────────────┘      └──────────────────┘

        ├──► MariaDB (on-prem)
        ├──► Redis (on-prem)
        ├──► cu-central-api (Docker) ← live bridge ผ่าน END_POINT_CENTRALIZE / _AUTH
        ├──► LDAP / AD
        └──► centralize-api (Docker, isolated; caller จาก vtrc-api ยังไม่ยืนยัน)

จุดอ่อนของสถานะปัจจุบัน

  • ไม่มี monitoring (ดู Volume 13.11)
  • ไม่มี log aggregation
  • network_mode: host ในบาง container
  • ไม่มี health check
  • deploy ด้วยมือ (manual docker pull)
  • SSL ต่ออายุด้วยมือ

เป้าหมายเมื่อสิ้นสุด modernization

                       ┌─────────────────────────────────┐
                       │  Cloudflare / CDN               │
                       │  (DDoS protection, WAF, cache)  │
                       └────────────────┬────────────────┘

                       ┌────────────────▼────────────────┐
                       │  Nginx / Caddy (TLS auto-renew) │
                       │  + rate limit + circuit breaker │
                       └────────────────┬────────────────┘

                       ┌────────────────▼────────────────┐
                       │  Internal API gateway /         │
                       │  service mesh lite (Traefik)    │
                       └────────────────┬────────────────┘

       ┌──────────────────┬─────────────┼──────────────┬──────────────────┐
       │                  │             │              │                  │
┌──────▼─────┐    ┌───────▼─────┐  ┌────▼─────┐  ┌─────▼──────┐  ┌────────▼─────┐
│ identity   │    │ leave       │  │ payroll  │  │ welfare    │  │ document-    │
│ service    │    │ service     │  │ service  │  │ service    │  │ renderer     │
└──────┬─────┘    └─────────────┘  └──────────┘  └────────────┘  └──────────────┘

       ├──► MariaDB (managed หรือ on-prem HA)
       ├──► Redis (managed หรือ on-prem HA)
       ├──► event bus (Redis Streams หรือ Kafka)
       ├──► observability stack (Prometheus, Loki, Tempo)
       └──► secret manager (Vault, GCP Secret Manager)

ระยะการพัฒนา

ระยะ 1 · Wave 0 (สัปดาห์ที่ 1-2)

เป้าหมาย: ลด Critical risk โดยไม่เปลี่ยน architecture

งาน infrastructure:

  • ปิด phpMyAdmin (debt PERF-7)
  • ตั้ง uptime monitor (UptimeRobot)
  • ตั้ง disk alert ที่ 80%
  • backup script + ทดสอบ restore

ระยะ 2 · Wave 1 (เดือนที่ 1-3)

เป้าหมาย: observability พื้นฐาน + CI/CD

2.1 · Centralized logging

deploy Loki + Promtail + Grafana บน VM ใหม่:

yaml
# docker-compose.logging.yml
services:
  loki:
    image: grafana/loki:2.9.0
    ports: ['3100:3100']

  promtail:
    image: grafana/promtail:2.9.0
    volumes:
      - /var/log:/var/log:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - ./promtail.yml:/etc/promtail/config.yml:ro

  grafana:
    image: grafana/grafana:10.0.0
    ports: ['3001:3000']

promtail เก็บ log จาก Docker container และ Nginx ส่งไป Loki ดูใน Grafana

2.2 · Monitoring + alerting

Prometheus + Grafana สำหรับ metric:

yaml
services:
  prometheus:
    image: prom/prometheus:v2.45.0
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    ports: ['9090:9090']

  node-exporter:
    image: prom/node-exporter:v1.6.0
    ports: ['9100:9100']

  # ติดตั้ง redis_exporter, mysqld_exporter

Alert rule ขั้นต่ำ:

  • CPU > 80% นาน 5 นาที
  • Disk > 80%
  • Service down (scrape fail)
  • Error rate > 1%
  • Memory > 90%

ส่ง alert ไป LINE Notify หรือ Slack

2.3 · CI/CD สำหรับ 5 repos

Bitbucket Pipelines สำหรับทุก repo (ตอนนี้มีแค่ vtrc-api, vtrc-web):

yaml
# bitbucket-pipelines.yml (สำหรับ backend service)
pipelines:
  branches:
    main:
      - step:
          name: Lint + Test
          services: [docker]
          script:
            - npm ci
            - npm run lint
            - npm test
      - step:
          name: Build image
          services: [docker]
          script:
            - docker build -t $IMAGE_NAME .
            - docker push $REGISTRY/$IMAGE_NAME
      - step:
          name: Deploy to UAT
          deployment: uat
          trigger: manual
          script:
            - ssh $UAT_HOST "docker pull $REGISTRY/$IMAGE_NAME && docker-compose up -d"

2.4 · Health endpoint ทุก service

javascript
app.get('/health', async (req, res) => {
  try {
    await db.authenticate();
    await redis.ping();
    res.json({ status: 'ok', db: true, redis: true });
  } catch (err) {
    res.status(503).json({ status: 'fail', error: err.message });
  }
});

docker-compose healthcheck:

yaml
services:
  vtrc-api:
    healthcheck:
      test: ['CMD', 'curl', '-f', 'http://localhost:8081/health']
      interval: 30s
      timeout: 10s
      retries: 3

ระยะ 3 · Wave 2 (เดือนที่ 4-15)

เป้าหมาย: infrastructure สำหรับ multi-service

3.1 · Internal network + service discovery

ปัจจุบัน container คุยกันผ่าน network_mode: host (debt PERF-7) — ไม่ปลอดภัยและทำให้สับสน

เปลี่ยนเป็น Docker network ที่กำหนด:

yaml
# docker-compose.yml
networks:
  vtrc-net:
    driver: bridge

services:
  vtrc-api:
    networks: [vtrc-net]
    # ไม่มี network_mode: host อีก

  redis:
    networks: [vtrc-net]

ใช้ Docker DNS — service อ้างชื่อกันได้โดยตรง (redis:6379, vtrc-api:8081)

3.2 · Service registry (ถ้าจำเป็น)

ถ้าจำนวน service เพิ่มเป็น 5+ ตัว พิจารณาใช้:

  • Traefik (recommended) — auto-discover Docker container, ทำ TLS, load balance
  • Consul (heavyweight กว่า)

ตัวอย่าง Traefik สำหรับ internal routing:

yaml
services:
  traefik:
    image: traefik:v2.10
    command:
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
    ports: ['80:80', '443:443', '8080:8080']
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

3.3 · Event bus

เมื่อ bounded context เริ่มแยก และต้องการ async communication:

ตัวเลือก:

ตัวเลือกข้อดีข้อเสีย
Redis Streams (recommended)ใช้ Redis ที่มี, simple, ไม่ต้องการ infra ใหม่throughput จำกัด, persistence ไม่ดีเท่า Kafka
Kafkathroughput สูง, persistence ดีinfra ซับซ้อน, overkill สำหรับ VTRC
RabbitMQfeature ครบ, message routingอีก service ต้องดูแล

ใช้ Redis Streams ก่อน ค่อยพิจารณา Kafka ถ้า volume สูง

3.4 · Secret management

ปัจจุบัน secret อยู่ใน .env บน host — ไม่ดี (debt SEC-3, SEC-4, SEC-11)

ตัวเลือก:

ตัวเลือกเหมาะกับ
GCP Secret Manager (recommended ถ้ามี GCP)cloud-native, integrate กับ Bitbucket Pipelines
HashiCorp Vault (self-hosted)on-prem, feature ครบ
Docker secrets (basic)เริ่มต้น, ดีกว่า .env

3.5 · Database HA

ปัจจุบัน MariaDB บน host เดียว — SPOF

ตัวเลือก:

ตัวเลือกเหมาะกับ
MariaDB Galera Cluster (3 node)on-prem, sync replication
Cloud SQL / RDS (ถ้าย้าย cloud)managed, auto-backup
Primary-replica (basic)ลด risk น้อยสุด

ระยะ 4 · Wave 3 (เดือนที่ 7-21)

4.1 · CDN + WAF

วาง Cloudflare ด้านหน้า:

  • DDoS protection
  • WAF rule
  • Static asset cache
  • SSL terminate (ลดภาระ Nginx)

4.2 · Kubernetes (พิจารณ์)

เมื่อ service เพิ่มเป็น 7+ ตัว และทีมพร้อม — พิจารณา K8s

หรือใช้ Docker Swarm ที่เรียนรู้ง่ายกว่า

4.3 · Distributed tracing

ติดตั้ง Tempo (หรือ Jaeger) เพื่อ trace request ข้าม service

ลำดับความสำคัญของ infrastructure debt

DebtPriorityEffortWave
ไม่มี monitoringสูงมาก1 สัปดาห์0 (or 1 ต้น)
network_mode: hostสูง2-3 วัน1
ไม่มี health checkสูง1-2 วัน1
ไม่มี log aggregationสูง1 สัปดาห์1
SSL ต่ออายุด้วยมือปานกลาง1 วัน1
CI/CD ไม่ครบสูง1 สัปดาห์1
ไม่มี secret managerปานกลาง1 สัปดาห์2
ไม่มี event busปานกลาง1 สัปดาห์2
DB ไม่ HAปานกลางหลายสัปดาห์2
ไม่มี CDN/WAFต่ำ1 วัน3
ไม่มี K8sต่ำหลายเดือน3 (optional)

ข้อควรระวัง

1. อย่าย้ายของทุกอย่างไป cloud ในครั้งเดียว

VTRC มีข้อมูลประชากรและข้อมูลการเงิน — การย้ายไป cloud อาจมี compliance issue (PDPA, ม.ม. ที่เกี่ยวข้อง) พิจารณา hybrid (เก็บ DB on-prem, compute cloud หรือ cluster)

2. observability ก่อน complexity

อย่าเพิ่ม service mesh / K8s ก่อนทีมจะสามารถ debug บน Docker compose ได้คล่อง

3. แต่ละ infrastructure change ต้องมี rollback

ย้ายจาก Docker Compose → K8s ต้องสามารถ rollback ได้ (เก็บ Compose file ไว้)

สรุป

Infrastructure evolution ค่อย ๆ เป็น:

  1. Wave 0: แกด Critical + ตั้ง monitor พื้นฐาน
  2. Wave 1: observability + CI/CD + health check
  3. Wave 2: multi-service network + event bus + secret manager
  4. Wave 3: CDN/WAF + (optional) K8s

บทถัดไปจะครอบคลุม risk management ของ modernization ทั้งหมด