强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Alpine Linux 完全指南 / 第 06 章:服务管理

第 06 章:服务管理

掌握 Alpine Linux 的 OpenRC 服务管理系统和日志管理。

6.1 OpenRC 概述

OpenRC 是 Alpine Linux 使用的初始化系统(init system),与 systemd 不同,它更轻量和简洁。

OpenRC vs systemd

特性 OpenRC systemd
复杂度
启动速度 较快
Shell 脚本 Shell 配置文件
依赖管理
并行启动 有限 完整
日志系统 syslog journald
资源控制 有限 cgroups
Alpine 默认

核心概念

┌─────────────────────────────────────────┐
│            OpenRC 核心概念               │
├─────────────────────────────────────────┤
│  服务脚本  /etc/init.d/service-name     │
│  运行级别  /etc/runlevels/              │
│  配置文件  /etc/conf.d/service-name     │
│  日志      /var/log/                    │
└─────────────────────────────────────────┘

6.2 服务管理基础

基本命令

# 启动服务
rc-service nginx start
# 等价别名
service nginx start

# 停止服务
rc-service nginx stop

# 重启服务
rc-service nginx restart

# 重新加载配置
rc-service nginx reload

# 查看服务状态
rc-service nginx status

# 查看所有已启用服务
rc-status

# 查看所有可用服务
rc-status -l

# 列出所有服务
ls /etc/init.d/

运行级别管理

# 查看当前运行级别
rc-status -r

# 运行级别说明
# boot      - 系统启动早期
# sysinit   - 系统初始化
# default   - 默认运行级别(正常运行)
# shutdown  - 关机
# single    - 单用户模式
# nonetwork - 无网络模式

# 添加服务到运行级别(开机启动)
rc-update add nginx default
rc-update add sshd default
rc-update add crond default

# 从运行级别移除(取消开机启动)
rc-update del nginx default

# 查看某个运行级别的服务
rc-update show default

# 查看所有运行级别的服务
rc-update show -v

# 切换运行级别
openrc default
openrc nonetwork

服务配置文件

# 服务配置文件位于 /etc/conf.d/
cat /etc/conf.d/nginx
# 示例内容:
# NGINX_OPTS="-c /etc/nginx/nginx.conf"
# NGINX_PIDFILE="/run/nginx/nginx.pid"

# 自定义服务配置
cat > /etc/conf.d/myservice << 'EOF'
# 配置参数
MY_OPTS="--port 8080"
MY_LOGFILE="/var/log/myservice.log"
MY_USER="nobody"
EOF

6.3 编写自定义服务

服务脚本模板

# /etc/init.d/myservice
cat > /etc/init.d/myservice << 'SCRIPT'
#!/sbin/openrc-run

name="My Application"
description="My custom application service"
command="/usr/local/bin/myservice"
command_args="--config /etc/myservice/config.yaml"
command_user="myservice:myservice"
pidfile="/run/myservice.pid"
command_background=true

# 依赖关系
depend() {
    need net
    after firewall
    after postgresql
}

# 服务启动前的准备工作
start_pre() {
    # 创建运行目录
    checkpath --directory --owner ${command_user} --mode 0775 /run/myservice
    checkpath --directory --owner ${command_user} --mode 0775 /var/log/myservice
}

# 停止后清理
stop_post() {
    rm -rf /run/myservice
}
SCRIPT

chmod +x /etc/init.d/myservice

# 创建配置目录
mkdir -p /etc/myservice

# 添加到开机启动
rc-update add myservice default

服务脚本参考语法

#!/sbin/openrc-run

# 变量定义
name="服务名称"
description="服务描述"
command="/path/to/binary"
command_args="启动参数"
command_user="user:group"
command_background=true    # 后台运行
pidfile="/run/service.pid"  # PID 文件路径

# 依赖关系
depend() {
    need net                    # 需要网络
    after sshd                  # 在 sshd 之后启动
    before nginx                # 在 nginx 之前启动
    use logger dns              # 使用(软依赖)
    want postgresql             # 想要(不强制)
    keyword docker lxc          # 在容器环境下跳过
}

# 环境变量
export ENV_VAR="value"

# 钩子函数
start_pre() { return 0 }      # 启动前执行
start_post() { return 0 }     # 启动后执行
stop_pre() { return 0 }       # 停止前执行
stop_post() { return 0 }      # 停止后执行
reload() { return 0 }         # 自定义重载逻辑

实用服务示例:自动备份

# /etc/init.d/autobackup
cat > /etc/init.d/autobackup << 'SCRIPT'
#!/sbin/openrc-run

name="Auto Backup"
description="Scheduled backup service"
command="/usr/local/bin/backup.sh"
command_user="backup:backup"
pidfile="/run/autobackup.pid"
command_background=true

depend() {
    need net localmount
    after mysql
}

start_pre() {
    checkpath --directory --owner backup:backup /var/log/backup
    checkpath --directory --owner backup:backup /backup
}

start() {
    ebegin "Starting ${name:-$RC_SVCNAME}"
    start-stop-daemon --start --background \
        --make-pidfile --pidfile $pidfile \
        --exec $command -- $command_args
    eend $?
}
SCRIPT

chmod +x /etc/init.d/autobackup

6.4 常见服务配置

OpenSSH

# 安装
apk add openssh

# 生成主机密钥
ssh-keygen -A

# 配置文件
cat > /etc/ssh/sshd_config << 'EOF'
Port 22
Protocol 2
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowUsers myuser
EOF

# 启动并设置开机启动
rc-update add sshd default
rc-service sshd start

# 日志
tail -f /var/log/messages | grep sshd

Nginx

# 安装
apk add nginx

# 基础配置
cat > /etc/nginx/nginx.conf << 'EOF'
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /run/nginx/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';
    
    access_log /var/log/nginx/access.log main;
    sendfile on;
    keepalive_timeout 65;
    
    include /etc/nginx/conf.d/*.conf;
}
EOF

mkdir -p /etc/nginx/conf.d
mkdir -p /run/nginx

rc-update add nginx default
rc-service nginx start

MariaDB

# 安装
apk add mariadb mariadb-client mariadb-common

# 初始化数据库
mysql_install_db --user=mysql --datadir=/var/lib/mysql

# 启动服务
rc-update add mariadb default
rc-service mariadb start

# 安全初始化
mysql_secure_installation

PostgreSQL

# 安装
apk add postgresql16 postgresql16-client

# 初始化集群
mkdir -p /var/lib/postgresql/data
chown postgres:postgres /var/lib/postgresql/data
su - postgres -c "initdb -D /var/lib/postgresql/data"

# 启动
rc-update add postgresql default
rc-service postgresql start

Redis

# 安装
apk add redis

# 配置
cat > /etc/redis.conf << 'EOF'
bind 127.0.0.1
port 6379
daemonize no
dir /var/lib/redis
maxmemory 256mb
maxmemory-policy allkeys-lru
requirepass your_password_here
EOF

# 数据目录权限
mkdir -p /var/lib/redis
chown redis:redis /var/lib/redis

rc-update add redis default
rc-service redis start

Cron 定时任务

# 安装(Alpine 默认使用 BusyBox crond)
# BusyBox crond 默认已安装

# 如果需要 vixie-cron 功能
apk add dcron

# 添加 cron 服务
rc-update add crond default
rc-service crond start

# 编辑用户 crontab
crontab -e
# 每天凌晨 2 点备份
# 0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# 系统级 cron
vi /etc/crontabs/root

6.5 日志管理

BusyBox syslog

# Alpine 默认使用 BusyBox 的 syslogd
# 查看日志
cat /var/log/messages
tail -f /var/log/messages

# 日志轮转
# BusyBox 内置 logread 命令
logread                   # 读取日志缓冲区
logread -f                # 实时跟踪

安装 rsyslog

# rsyslog 提供更丰富的日志功能
apk add rsyslog

# 基础配置
cat > /etc/rsyslog.conf << 'EOF'
module(load="imuxsock")
module(load="imklog")

# 日志文件规则
*.info;mail.none;authpriv.none;cron.none  /var/log/messages
authpriv.*                                /var/log/auth.log
mail.*                                    -/var/log/maillog
cron.*                                    /var/log/cron
*.emerg                                   :omusrmsg:*
EOF

# 分应用日志配置
cat > /etc/rsyslog.d/nginx.conf << 'EOF'
:programname, isequal, "nginx" /var/log/nginx/access.log
& stop
EOF

rc-update add rsyslog default
rc-service rsyslog start

logrotate 日志轮转

# 安装
apk add logrotate

# Nginx 日志轮转配置
cat > /etc/logrotate.d/nginx << 'EOF'
/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0644 nginx nginx
    sharedscripts
    postrotate
        [ -f /run/nginx/nginx.pid ] && kill -USR1 $(cat /run/nginx/nginx.pid)
    endscript
}
EOF

# 系统日志轮转
cat > /etc/logrotate.d/syslog << 'EOF'
/var/log/messages {
    daily
    rotate 7
    missingok
    compress
    delaycompress
    postrotate
        /etc/init.d/syslog restart 2>/dev/null || true
    endscript
}
EOF

# 手动测试轮转
logrotate -d /etc/logrotate.conf  # 测试模式
logrotate -f /etc/logrotate.d/nginx  # 强制执行

# 定时执行 logrotate
# Alpine 使用 BusyBox crond
echo "0 0 * * * /usr/sbin/logrotate /etc/logrotate.conf" >> /etc/crontabs/root

集中日志方案

# 远程日志服务器配置
# 发送端 (rsyslog)
cat >> /etc/rsyslog.conf << 'EOF'
*.* @@192.168.1.200:514    # TCP
*.* @192.168.1.200:514     # UDP
EOF

# 接收端 (rsyslog)
cat >> /etc/rsyslog.conf << 'EOF'
module(load="imtcp")
input(type="imtcp" port="514")
template RemoteHost,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log"
*.* ?RemoteHost
EOF

6.6 系统监控

自动监控脚本

# 定期检查服务状态
cat > /usr/local/bin/service-check << 'SCRIPT'
#!/bin/sh
SERVICES="nginx mariadb redis sshd"
ALERT_EMAIL="admin@example.com"

for svc in $SERVICES; do
    if ! rc-service "$svc" status > /dev/null 2>&1; then
        echo "ALERT: $svc is down at $(date)" | logger -t service-check
        # 自动重启
        rc-service "$svc" start
        if [ $? -ne 0 ]; then
            echo "CRITICAL: Failed to restart $svc" | logger -t service-check
        fi
    fi
done
SCRIPT
chmod +x /usr/local/bin/service-check

# 定期执行
echo "*/5 * * * * /usr/local/bin/service-check" >> /etc/crontabs/root

6.7 本章小结

操作 命令
启动服务 rc-service <name> start
停止服务 rc-service <name> stop
重启服务 rc-service <name> restart
查看状态 rc-service <name> status
开机启动 rc-update add <name> default
取消启动 rc-update del <name> default
查看日志 tail -f /var/log/messages
服务配置 /etc/conf.d/<name>

扩展阅读


上一章第 05 章:存储管理 下一章第 07 章:桌面环境