คู่มือการใช้งาน Runit: Init System ที่เรียบง่ายและมีประสิทธิภาพ

Introduction: ทำความรู้จักกับ Init System

Init System คืออะไร?

Init System เป็นโปรแกรมแรกที่ระบบปฏิบัติการ Linux เริ่มทำงานหลังจาก kernel โหลดเสร็จสิ้น มีหน้าที่สำคัญดังนี้:

  1. Process ID 1 (PID 1) - เป็น parent process ของทุก process ในระบบ
  2. Service Management - จัดการการเริ่มต้น หยุด และรีสตาร์ท services
  3. Dependency Handling - จัดการลำดับการเริ่มต้น services ตาม dependencies
  4. Process Supervision - ตรวจสอบและรีสตาร์ท processes ที่ล้มเหลว
  5. System Shutdown - จัดการการปิดระบบอย่างถูกต้อง

ประวัติและวิวัฒนาการของ Init Systems

%%{init: {'theme':'base', 'themeVariables': {'primaryTextColor':'#000000', 'secondaryTextColor':'#000000', 'tertiaryTextColor':'#000000', 'fontSize':'16px'}}}%%
timeline
    title Timeline ของ Init System ของ Linux
    
    1983 : SysV init
         : System V Unix init
         : ระบบ init แบบดั้งเดิม
    
    1991 : Linux เกิดขึ้น
         : ใช้ SysV init style
    
    2001 : daemontools
         : runit เริ่มพัฒนา
         : ทางเลือกสำหรับ SysV
    
    2006 : Upstart
         : พัฒนาโดย Canonical (Ubuntu)
         : Event-based init
         : แทนที่ SysV ใน Ubuntu
    
    2007 : OpenRC
         : พัฒนาโดย Gentoo
         : Dependency-based init
    
    2010 : systemd เริ่มต้น
         : พัฒนาโดย Lennart Poettering
         : ประกาศโครงการ
    
    2011 : systemd v1.0
         : Fedora 15 นำมาใช้
    
    2012 : systemd แพร่หลาย
         : Arch Linux นำมาใช้
         : openSUSE นำมาใช้
    
    2014 : Debian ใช้ systemd
         : การโหวตเลือก systemd
         : Ubuntu เปลี่ยนมาใช้ systemd
    
    2015 : systemd กลายเป็น standard
         : ใช้ใน distro ส่วนใหญ่
         : RHEL 7 ใช้ systemd
    
    2016-ปัจจุบัน : systemd ครองตลาด
                : ใช้ใน major distros เกือบทั้งหมด
                : OpenRC, runit ยังมีใน niche distros
                : Gentoo, Void Linux ใช้ทางเลือกอื่น

Runit คืออะไร?

Runit เป็น init system และ process supervision suite ที่ออกแบบมาให้เรียบง่าย รวดเร็ว และเชื่อถือได้ สร้างโดย Gerrit Pape เป็นทางเลือกแทน SysV init และ systemd

คุณสมบัติเด่นของ Runit

ส่วนประกอบหลักของ Runit

graph TD
    A[Runit Init System] --> B[runit]
    A --> C[runsvdir]
    A --> D[runsv]
    A --> E[sv]
    A --> F[svlogd]
    
    B[runit] --> B1[Stage 1: System Boot]
    B --> B2[Stage 2: Run Services]
    B --> B3[Stage 3: System Shutdown]
    
    C[runsvdir] --> C1[Scan service directories]
    C --> C2[Start runsv for each service]
    
    D[runsv] --> D1[Supervise service process]
    D --> D2[Restart on failure]
    
    E[sv] --> E1[Control services]
    E --> E2[Check service status]
    
    F[svlogd] --> F1[Log management]
    F --> F2[Automatic rotation]

เปรียบเทียบ Init Systems

ตารางเปรียบเทียบ Init Systems ยอดนิยม

คุณสมบัติ Runit systemd SysV Init OpenRC s6
ความเรียบง่าย ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐
ความเร็วในการ Boot ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
Process Supervision ✅ Built-in ⚠️ ต้องตั้งค่า ⚠️ ต้องติดตั้งเพิ่ม ✅ Built-in
ขนาดโค้ด ~10,000 lines ~1,200,000 lines ~15,000 lines ~30,000 lines ~7,000 lines
Parallel Startup
Dependency Management Manual Automatic Manual Automatic Manual
Log Management svlogd journald syslog syslog s6-log
Socket Activation ⚠️ จำกัด
Memory Footprint ~1-2 MB ~5-10 MB ~500 KB ~2-3 MB ~500 KB
Service Config Format Shell scripts Unit files Shell scripts Shell scripts Text files
Learning Curve ต่ำ สูง ปานกลาง ปานกลาง ปานกลาง
Documentation ดี ดีมาก ปานกลาง ดี ดี
Community Support ปานกลาง มาก น้อย ปานกลาง น้อย
ใช้งานใน Distros Void Linux, Artix Most modern Legacy systems Gentoo, Alpine Minor distros

ข้อดีและข้อเสียของ Runit

✅ ข้อดี

  1. เรียบง่ายและชัดเจน - โครงสร้างไฟล์และโค้ดเข้าใจง่าย
  2. เชื่อถือได้สูง - ออกแบบมาเพื่อทำงานต่อเนื่อง ไม่ crash
  3. Process Supervision แบบ Built-in - ไม่ต้องติดตั้งเครื่องมือเพิ่มเติม
  4. Memory Efficient - ใช้ทรัพยากรน้อย
  5. ความเร็ว - Boot เร็วมาก
  6. Portable - ใช้ได้กับหลาย Unix-like systems
  7. Predictable - พฤติกรรมชัดเจน ไม่มี "magic"

❌ ข้อเสีย

  1. Manual Dependency Management - ต้องจัดการ dependencies เอง
  2. Limited Adoption - ใช้งานน้อยกว่า systemd
  3. ไม่มี Socket Activation - ไม่รองรับ on-demand service start
  4. Documentation - น้อยกว่า systemd
  5. Third-party Integration - บาง software ออกแบบมาเฉพาะ systemd

สถาปัตยกรรมของ Runit

โครงสร้างการทำงาน 3 Stages

graph LR
    A[Kernel Boot] --> B[Stage 1: System Initialization]
    B --> C[Stage 2: Service Supervision]
    C --> D{System Running}
    D --> E[User Request Shutdown]
    E --> F[Stage 3: System Shutdown]
    F --> G[System Halt/Reboot]
    
    C --> C
    
    style B fill:#ffcccc
    style C fill:#ccffcc
    style F fill:#ccccff

Stage 1: System Initialization (/etc/runit/1)

ทำงานครั้งเดียวเมื่อระบบเริ่มต้น มีหน้าที่:

Stage 2: Service Supervision (/etc/runit/2)

ระยะหลักของระบบ:

Stage 3: System Shutdown (/etc/runit/3)

ปิดระบบอย่างสง่างาม:

โครงสร้างไดเรกทอรี

/etc/runit/
├── 1                      # Stage 1 script
├── 2                      # Stage 2 script
├── 3                      # Stage 3 script
├── ctrlaltdel            # Ctrl+Alt+Del handler
└── runsvdir/
    └── default/          # Service directory
        ├── service1/
        ├── service2/
        └── ...

/etc/sv/                  # Service definitions
├── service1/
│   ├── run              # Main service script
│   ├── finish           # Cleanup script (optional)
│   ├── down             # Disable service (if exists)
│   ├── log/             # Logging configuration
│   │   └── run          # Log script
│   └── supervise/       # Runtime data (created by runsv)
└── service2/
    └── ...

/var/service/            # Active services (symlinks to /etc/sv/)
├── service1 -> /etc/sv/service1
└── service2 -> /etc/sv/service2

การติดตั้ง Runit

ติดตั้งบน Void Linux (Native)

Void Linux ใช้ Runit เป็น init system หลักอยู่แล้ว:

# Runit มากับระบบแล้ว ไม่ต้องติดตั้งเพิ่ม
# ตรวจสอบเวอร์ชัน
sv --version

# แสดงรายการ services ที่ทำงานอยู่
sv status /var/service/*

ติดตั้งบน Debian/Ubuntu

ขั้นตอนที่ 1: ติดตั้ง Runit Package

# อัปเดต package list
sudo apt update

# ติดตั้ง runit และ runit-init
sudo apt install runit runit-init

# สำหรับการใช้งานร่วมกับ systemd
sudo apt install runit-systemd

ขั้นตอนที่ 2: กำหนดค่า Bootloader (ถ้าต้องการใช้แทน systemd)

แก้ไขไฟล์ /etc/default/grub:

# เปิดไฟล์ด้วย editor
sudo nano /etc/default/grub

# เพิ่ม init=/sbin/runit-init ใน GRUB_CMDLINE_LINUX_DEFAULT
GRUB_CMDLINE_LINUX_DEFAULT="quiet init=/sbin/runit-init"

# อัปเดต GRUB
sudo update-grub

# รีบูต
sudo reboot

ติดตั้งบน Arch Linux

# ติดตั้งจาก AUR
yay -S runit-artix

# หรือใช้ Artix Linux ที่มี Runit built-in

ติดตั้งจาก Source Code

ขั้นตอนที่ 1: ดาวน์โหลด Source

# ดาวน์โหลด Runit
wget http://smarden.org/runit/runit-2.1.2.tar.gz

# แตกไฟล์
tar xzf runit-2.1.2.tar.gz
cd admin/runit-2.1.2

ขั้นตอนที่ 2: Compile และติดตั้ง

# Compile
package/compile

# ติดตั้ง
sudo package/install

# สร้างไดเรกทอรีที่จำเป็น
sudo mkdir -p /etc/runit/runsvdir/default
sudo mkdir -p /etc/sv
sudo mkdir -p /var/service

ขั้นตอนที่ 3: สร้าง Stage Scripts

สร้างไฟล์ /etc/runit/1:

#!/bin/sh
# Stage 1: System initialization

# Mount filesystems
mount -a

# Configure hostname
hostname -F /etc/hostname

# Setup network
ip link set lo up

echo "Stage 1: System initialization complete"

สร้างไฟล์ /etc/runit/2:

#!/bin/sh
# Stage 2: Start supervision

PATH=/usr/local/bin:/usr/bin:/bin
export PATH

# Start runsvdir
exec runsvdir /etc/runit/runsvdir/default

สร้างไฟล์ /etc/runit/3:

#!/bin/sh
# Stage 3: System shutdown

echo "Stopping services..."
sv -w 10 force-stop /var/service/*

echo "Unmounting filesystems..."
umount -a -r

echo "Shutdown complete"

ตั้งค่าสิทธิ์:

sudo chmod +x /etc/runit/1 /etc/runit/2 /etc/runit/3

การใช้งานพื้นฐาน

คำสั่ง sv - Service Control

คำสั่ง sv เป็นเครื่องมือหลักในการจัดการ services:

# รูปแบบคำสั่ง
sv [COMMAND] [SERVICE_NAME]

คำสั่งพื้นฐาน

1. ตรวจสอบสถานะ Service

# ดูสถานะ service เดียว
sv status /var/service/nginx

# Output ตัวอย่าง:
# run: /var/service/nginx: (pid 1234) 123s

# ดูสถานะทุก services
sv status /var/service/*

2. เริ่มและหยุด Service

# เริ่ม service
sudo sv start nginx

# หยุด service
sudo sv stop nginx

# หยุดแบบบังคับ (ถ้า stop ไม่สำเร็จ)
sudo sv force-stop nginx

3. Restart Service

# Restart service (หยุดแล้วเริ่มใหม่)
sudo sv restart nginx

# Restart แบบ graceful (รอให้จบงานปัจจุบัน)
sudo sv down nginx
sudo sv up nginx

4. Reload Service Configuration

# ส่งสัญญาณ HUP (reload config)
sudo sv reload nginx

# หรือใช้ hup
sudo sv hup nginx

สัญญาณ (Signals) ที่ใช้บ่อย

# TERM - ขอให้ shutdown อย่างสง่างาม
sudo sv term SERVICE

# KILL - บังคับหยุดทันที
sudo sv kill SERVICE

# HUP - Reload configuration
sudo sv hup SERVICE

# INT - Interrupt signal
sudo sv int SERVICE

# USR1/USR2 - Custom signals
sudo sv 1 SERVICE  # USR1
sudo sv 2 SERVICE  # USR2

ตัวอย่างการตรวจสอบข้อมูล Service

ตรวจสอบสถานะละเอียด

# ดู PID และเวลาที่ทำงาน
sv status /var/service/nginx
# Output: run: /var/service/nginx: (pid 1234) 3600s

# ตรวจสอบว่า service กำลังทำงานหรือไม่
sv check /var/service/nginx
# Return code: 0 = running, 1 = not running

# รอให้ service เริ่มทำงาน (timeout 7 วินาที)
sv -w 7 start /var/service/nginx

ดูข้อมูลจาก supervise directory

# เข้าไปดูข้อมูล runtime
cd /var/service/nginx/supervise

# ดู PID
cat pid

# ดูสถานะ
cat status

# ดู stat
cat stat

คำสั่ง runsvdir และ runsv

# runsvdir - scan และจัดการ service directories
# ปกติจะถูกเรียกโดย Stage 2 script
runsvdir /var/service

# runsv - supervise service เดียว
# ถูกเรียกโดย runsvdir อัตโนมัติ
runsv /var/service/nginx

การจัดการ Service

สร้าง Service ใหม่

ขั้นตอนที่ 1: สร้างไดเรกทอรี Service

# สร้างโครงสร้างไดเรกทอรี
sudo mkdir -p /etc/sv/myapp
sudo mkdir -p /etc/sv/myapp/log

ขั้นตอนที่ 2: สร้าง Run Script

สร้างไฟล์ /etc/sv/myapp/run:

#!/bin/sh
exec 2>&1

# ตั้งค่า environment variables
export PATH=/usr/local/bin:/usr/bin:/bin
export APP_ENV=production

# เปลี่ยน user (ถ้าต้องการ)
# exec chpst -u myapp:myapp /path/to/app

# เริ่มต้น application
exec /usr/local/bin/myapp --port 8080

ตั้งค่าสิทธิ์:

sudo chmod +x /etc/sv/myapp/run

ขั้นตอนที่ 3: สร้าง Log Service

สร้างไฟล์ /etc/sv/myapp/log/run:

#!/bin/sh

# สร้างไดเรกทอรี log
mkdir -p /var/log/myapp

# ใช้ svlogd จัดการ logs
exec svlogd -tt /var/log/myapp

ตั้งค่าสิทธิ์:

sudo chmod +x /etc/sv/myapp/log/run

ขั้นตอนที่ 4: Enable Service

# สร้าง symlink ไปยัง /var/service
sudo ln -s /etc/sv/myapp /var/service/

# ตรวจสอบว่า service เริ่มทำงาน
sudo sv status myapp

ตัวอย่าง Service Scripts แบบต่าง ๆ

ตัวอย่างที่ 1: Web Server (Nginx)

/etc/sv/nginx/run:

#!/bin/sh
exec 2>&1

# ตรวจสอบ config ก่อนเริ่ม
nginx -t || exit 1

# เริ่ม nginx แบบ foreground
exec nginx -g "daemon off;"

ตัวอย่างที่ 2: Database (PostgreSQL)

/etc/sv/postgresql/run:

#!/bin/sh
exec 2>&1

# ตัวแปร
PGDATA=/var/lib/postgresql/data
PGUSER=postgres

# ตรวจสอบว่า data directory มีอยู่
[ -d "$PGDATA" ] || {
    echo "PGDATA directory not found!"
    exit 1
}

# เริ่ม PostgreSQL
exec chpst -u $PGUSER postgres -D $PGDATA

ตัวอย่างที่ 3: Node.js Application

/etc/sv/nodeapp/run:

#!/bin/sh
exec 2>&1

# ตั้งค่า environment
export NODE_ENV=production
export PORT=3000

# เปลี่ยนไปยัง app directory
cd /opt/nodeapp || exit 1

# เริ่ม Node.js app
exec chpst -u nodeapp:nodeapp node server.js

ตัวอย่างที่ 4: Python Application (Gunicorn)

/etc/sv/pythonapp/run:

#!/bin/sh
exec 2>&1

# Activate virtual environment
. /opt/pythonapp/venv/bin/activate

# เปลี่ยนไปยัง app directory
cd /opt/pythonapp || exit 1

# เริ่ม Gunicorn
exec chpst -u pythonapp:pythonapp \
    gunicorn \
    --bind 0.0.0.0:8000 \
    --workers 4 \
    --access-logfile - \
    --error-logfile - \
    wsgi:app

การตั้งค่า Service ขั้นสูง

1. Finish Script (Cleanup)

สร้างไฟล์ /etc/sv/myapp/finish:

#!/bin/sh

# Cleanup script จะทำงานเมื่อ service หยุด
echo "Service stopped at $(date)" >> /var/log/myapp/finish.log

# ลบ temporary files
rm -f /var/run/myapp.pid

# ส่ง notification (optional)
# curl -X POST https://monitoring.example.com/alert

exit 0

ตั้งค่าสิทธิ์:

sudo chmod +x /etc/sv/myapp/finish

2. Environment Variables

สร้างไฟล์ /etc/sv/myapp/env/:

# สร้างไดเรกทอรี env
sudo mkdir -p /etc/sv/myapp/env

# สร้างตัวแปร
echo "production" | sudo tee /etc/sv/myapp/env/APP_ENV
echo "5432" | sudo tee /etc/sv/myapp/env/DB_PORT
echo "myapp.db" | sudo tee /etc/sv/myapp/env/DB_NAME

ใช้ใน run script:

#!/bin/sh
exec 2>&1

# โหลด environment variables
[ -d ./env ] && export $(cat ./env/* | xargs)

# เริ่ม application
exec /usr/local/bin/myapp

3. การจำกัดทรัพยากรด้วย chpst

#!/bin/sh
exec 2>&1

# จำกัดทรัพยากร:
# -u user:group = เปลี่ยน user และ group
# -m bytes = จำกัด memory
# -o files = จำกัดจำนวนไฟล์ที่เปิดได้
# -p processes = จำกัดจำนวน processes

exec chpst \
    -u myapp:myapp \
    -m 512000000 \
    -o 1024 \
    -p 10 \
    /usr/local/bin/myapp

การจัดการ Dependencies

Runit ไม่มี automatic dependency management แต่เราสามารถจัดการได้ด้วย scripts:

วิธีที่ 1: ใช้ sv check ใน run script

/etc/sv/webapp/run:

#!/bin/sh
exec 2>&1

# รอให้ database service พร้อม
echo "Waiting for database..."
sv -w 30 check postgresql || exit 1

# รอให้ redis service พร้อม
echo "Waiting for redis..."
sv -w 30 check redis || exit 1

# เริ่ม web application
exec /usr/local/bin/webapp

วิธีที่ 2: ใช้ check script

สร้างไฟล์ /etc/sv/webapp/check:

#!/bin/sh

# ตรวจสอบว่า dependencies พร้อมหรือไม่
sv check postgresql || exit 1
sv check redis || exit 1

# ตรวจสอบ network connectivity
nc -z localhost 5432 || exit 1
nc -z localhost 6379 || exit 1

exit 0

ตั้งค่าสิทธิ์:

sudo chmod +x /etc/sv/webapp/check

Disable/Enable Service

Disable Service (ไม่ให้เริ่มอัตโนมัติ)

# วิธีที่ 1: ลบ symlink
sudo rm /var/service/myapp

# วิธีที่ 2: สร้างไฟล์ down
sudo touch /etc/sv/myapp/down

# วิธีที่ 3: ใช้ sv down
sudo sv down myapp

Enable Service

# วิธีที่ 1: สร้าง symlink
sudo ln -s /etc/sv/myapp /var/service/

# วิธีที่ 2: ลบไฟล์ down
sudo rm /etc/sv/myapp/down

# วิธีที่ 3: ใช้ sv up
sudo sv up myapp

ตัวอย่างการจัดการ Service ทั้งหมด

# หยุด services ทั้งหมด
for service in /var/service/*; do
    sudo sv stop "$service"
done

# เริ่ม services ทั้งหมด
for service in /var/service/*; do
    sudo sv start "$service"
done

# Restart services ทั้งหมด
for service in /var/service/*; do
    sudo sv restart "$service"
done

# แสดงสถานะทั้งหมดในรูปแบบตาราง
printf "%-30s %-10s %-10s\n" "SERVICE" "STATUS" "PID"
echo "=================================================="
for service in /var/service/*; do
    name=$(basename "$service")
    status=$(sv status "$service" 2>/dev/null | awk '{print $1}')
    pid=$(sv status "$service" 2>/dev/null | grep -o 'pid [0-9]*' | awk '{print $2}')
    printf "%-30s %-10s %-10s\n" "$name" "$status" "${pid:-N/A}"
done

การใช้งานขั้นสูง

Log Management ด้วย svlogd

การตั้งค่า Log Rotation

สร้างไฟล์ /var/log/myapp/config:

# ขนาดไฟล์สูงสุด (bytes)
s1000000

# จำนวนไฟล์ log ที่เก็บไว้
n10

# Timeout สำหรับการ rotate (seconds)
t86400

# Compress rotated logs
!gzip

Advanced Log Configuration

# Filter logs ด้วย pattern
+*ERROR*
-*DEBUG*

# ส่ง logs ไปยังหลายที่
# ใช้ processor script
!processor-script.sh

# ตั้งค่า timestamp format
# t = tai64n (default)
# T = human-readable timestamp

# ตั้งค่า prefix
pMYAPP:

ตัวอย่าง log/run ขั้นสูง:

#!/bin/sh

# สร้าง log directories
mkdir -p /var/log/myapp/main
mkdir -p /var/log/myapp/errors

# Configure logging
cat > /var/log/myapp/main/config <<EOF
s10000000
n20
t3600
EOF

# Separate error logs
exec svlogd \
    -tt \
    /var/log/myapp/main \
    '+*ERROR* /var/log/myapp/errors'

การทำ Health Checks

ตัวอย่างที่ 1: HTTP Health Check

สร้าง /etc/sv/webapp/check:

#!/bin/sh

# ตรวจสอบว่า web service ตอบกลับหรือไม่
curl -sf http://localhost:8080/health > /dev/null
exit $?

ตัวอย่างที่ 2: Database Health Check

สร้าง /etc/sv/postgresql/check:

#!/bin/sh

# ตรวจสอบ PostgreSQL connection
pg_isready -h localhost -p 5432 -U postgres
exit $?

ตัวอย่างที่ 3: Complex Health Check

#!/bin/sh

# ตรวจสอบหลายเงื่อนไข
check_port() {
    nc -z localhost $1 2>/dev/null
    return $?
}

check_http() {
    response=$(curl -s -o /dev/null -w "%{http_code}" "$1")
    [ "$response" = "200" ]
    return $?
}

check_disk_space() {
    usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
    [ "$usage" -lt 90 ]
    return $?
}

# Run checks
check_port 8080 || exit 1
check_http "http://localhost:8080/health" || exit 1
check_disk_space || exit 1

exit 0

One-shot Services

บาง services ไม่ต้องการ supervision (ทำงานครั้งเดียวแล้วจบ):

#!/bin/sh
exec 2>&1

# ทำงาน
/usr/local/bin/backup-script.sh

# หยุด service เอง (ไม่ restart)
sv down backup-task

# หรือให้ runsv หยุด supervise
exec pause

การทำ Graceful Restart

สำหรับ zero-downtime deployments:

วิธีที่ 1: ใช้ USR2 Signal

/etc/sv/webapp/run:

#!/bin/sh
exec 2>&1

# ฟังก์ชัน reload
reload() {
    echo "Reloading application..."
    # Logic สำหรับ reload
    kill -HUP $PID
}

# ตั้ง trap สำหรับ USR2
trap reload USR2

# เริ่ม application
/usr/local/bin/webapp &
PID=$!

wait $PID

ใช้งาน:

# ส่งสัญญาณ USR2 เพื่อ reload
sudo sv 2 webapp

วิธีที่ 2: Blue-Green Deployment

มี 2 instances:

# สร้าง 2 services
/etc/sv/webapp-blue/
/etc/sv/webapp-green/

# ใช้ nginx เป็น load balancer
# Rotate traffic ระหว่าง blue และ green

การทำ Monitoring และ Alerting

สคริปต์ตรวจสอบสถานะ

สร้างไฟล์ /usr/local/bin/check-services.sh:

#!/bin/bash

ALERT_EMAIL="admin@example.com"
FAILED_SERVICES=""

for service in /var/service/*; do
    name=$(basename "$service")
    
    if ! sv check "$service" > /dev/null 2>&1; then
        FAILED_SERVICES="$FAILED_SERVICES\n- $name"
    fi
done

if [ -n "$FAILED_SERVICES" ]; then
    echo -e "Failed services:$FAILED_SERVICES" | \
        mail -s "Service Alert" "$ALERT_EMAIL"
fi

ตั้งค่า cron job:

# เพิ่มใน crontab
*/5 * * * * /usr/local/bin/check-services.sh

Integration กับ Monitoring Systems

ส่งข้อมูลไปยัง Prometheus:

#!/bin/bash

# สร้าง metrics file
cat > /var/www/metrics <<EOF
# HELP runit_service_up Service is running
# TYPE runit_service_up gauge
EOF

for service in /var/service/*; do
    name=$(basename "$service")
    
    if sv check "$service" > /dev/null 2>&1; then
        status=1
    else
        status=0
    fi
    
    echo "runit_service_up{service=\"$name\"} $status" >> /var/www/metrics
done

การทำ Container Integration

Docker Container ที่ใช้ Runit

Dockerfile:

FROM debian:bookworm

# ติดตั้ง Runit
RUN apt-get update && \
    apt-get install -y runit && \
    rm -rf /var/lib/apt/lists/*

# สร้างโครงสร้าง
RUN mkdir -p /etc/service

# Copy service definitions
COPY sv/ /etc/sv/

# Enable services
RUN ln -s /etc/sv/* /etc/service/

# เริ่ม Runit
CMD ["/usr/bin/runsvdir", "/etc/service"]

Custom Control Scripts

สร้าง wrapper script สำหรับการจัดการ:

/usr/local/bin/service-manager.sh:

#!/bin/bash

usage() {
    echo "Usage: $0 {list|start|stop|restart|status|logs} [service_name]"
    exit 1
}

list_services() {
    echo "Active Services:"
    for service in /var/service/*; do
        name=$(basename "$service")
        status=$(sv status "$service" 2>/dev/null)
        echo "  $name: $status"
    done
}

show_logs() {
    service=$1
    [ -z "$service" ] && usage
    
    if [ -d "/var/log/$service" ]; then
        tail -f "/var/log/$service/current" | tai64nlocal
    else
        echo "No logs found for $service"
    fi
}

case "$1" in
    list)
        list_services
        ;;
    start|stop|restart|status)
        [ -z "$2" ] && usage
        sv "$1" "/var/service/$2"
        ;;
    logs)
        show_logs "$2"
        ;;
    *)
        usage
        ;;
esac

ตั้งค่าสิทธิ์:

sudo chmod +x /usr/local/bin/service-manager.sh

ใช้งาน:

# แสดงรายการ services
service-manager.sh list

# จัดการ service
service-manager.sh start nginx
service-manager.sh stop nginx
service-manager.sh restart nginx
service-manager.sh status nginx

# ดู logs
service-manager.sh logs nginx

Best Practices

1. Service Design

✅ ควรทำ

❌ ไม่ควรทำ

2. Log Management

# ตั้งค่า log rotation ที่เหมาะสม
# /var/log/service/config
s10000000    # 10MB per file
n30          # เก็บ 30 files
t86400       # rotate ทุก 24 ชั่วโมง
!gzip        # compress

# ใช้ structured logging
logger -t myapp "ERROR: $(date): Failed to connect to database"

3. Security

# เปลี่ยน user และ group
exec chpst -u www-data:www-data nginx

# จำกัดทรัพยากร
exec chpst \
    -u myapp:myapp \
    -m 512000000 \
    -o 1024 \
    /usr/local/bin/myapp

# ตั้งค่า umask
umask 0027

4. Monitoring

# สร้าง health check endpoint
# /etc/sv/myapp/check
#!/bin/sh
curl -sf http://localhost:8080/health || exit 1

# ตั้งค่า timeout
sv -w 10 check myapp

5. Documentation

สร้าง README สำหรับแต่ละ service:

/etc/sv/myapp/README.md:

# MyApp Service

## Description
Web application service running on port 8080

## Dependencies
- PostgreSQL (service: postgresql)
- Redis (service: redis)

## Configuration
Environment variables in `env/` directory:
- APP_ENV: production/development
- DB_HOST: Database hostname
- DB_PORT: Database port

## Logs
Located in `/var/log/myapp/`

## Health Check
HTTP GET http://localhost:8080/health
Should return 200 OK

## Maintenance
- Restart: `sv restart myapp`
- Logs: `tail -f /var/log/myapp/current | tai64nlocal`

6. Backup และ Recovery

# Backup service definitions
tar czf /backup/services-$(date +%Y%m%d).tar.gz /etc/sv/*

# Backup logs
tar czf /backup/logs-$(date +%Y%m%d).tar.gz /var/log/*

# Test restore
mkdir -p /tmp/test-restore
tar xzf /backup/services-latest.tar.gz -C /tmp/test-restore

7. Performance Tuning

# ปรับ runsvdir scan interval
# ใน /etc/runit/2
exec runsvdir -P /var/service

# จำกัด CPU และ Memory
exec chpst \
    -m $((512 * 1024 * 1024)) \
    -o 1024 \
    -p 10 \
    /usr/local/bin/myapp

สรุป

สรุปคุณสมบัติของ Runit

%%{init: {'theme':'base', 'themeVariables': {'primaryTextColor':'#ebdbb2', 'secondaryTextColor':'#ebdbb2', 'fontSize':'16px', 'fontFamily':'arial'}}}%%
mindmap
  root((Runit))
    Simplicity
      Small codebase
      Easy to understand
      Minimal dependencies
    Reliability
      Process supervision
      Auto restart
      Predictable behavior
    Performance
      Fast boot
      Low memory usage
      Parallel startup
    Flexibility
      Portable
      Customizable
      Scriptable

ข้อควรพิจารณาในการเลือกใช้

เหมาะสำหรับ:

อาจไม่เหมาะสำหรับ:

แนวทางการเริ่มต้นใช้งาน

  1. เรียนรู้พื้นฐาน - ทำความเข้าใจโครงสร้างและหลักการ
  2. ทดลองบน VM - ติดตั้งและทดสอบก่อนใช้งานจริง
  3. สร้าง service ง่าย ๆ - เริ่มจาก service ธรรมดาก่อน
  4. ศึกษา examples - ดูตัวอย่างจาก distributions ที่ใช้ Runit
  5. Migration แบบค่อย ๆ - ย้ายที service ละตัว ทดสอบให้มั่นใจ

Resources และการเรียนรู้เพิ่มเติม

Community และการสนับสนุน


เอกสารอ้างอิง

  1. Pape, G. (2007). runit - a UNIX init scheme with service supervision. http://smarden.org/runit/
  2. Void Linux Documentation. (2024). Void Linux Handbook - Services. https://docs.voidlinux.org/
  3. Poettering, L. & Kay, S. (2010). systemd System and Service Manager. freedesktop.org
  4. Skarnet, L. (2011). s6: skarnet's small & secure supervision software suite. skarnet.org

หมายเหตุ: บทความนี้จัดทำขึ้นเพื่อการศึกษาและเป็นแนวทางในการใช้งาน Runit ควรปรับใช้ตามบริบทและความต้องการของระบบแต่ละระบบ