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

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

第 06 章:服务管理

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

6.1 OpenRC 概述

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

OpenRC vs systemd

特性OpenRCsystemd
复杂度
启动速度较快
Shell 脚本Shell配置文件
依赖管理
并行启动有限完整
日志系统syslogjournald
资源控制有限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="[email protected]"

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 章:桌面环境