GNU Guix 函数式包管理教程 / 第七章 服务管理
第七章:服务管理
7.1 Guix 服务体系概述
Guix System 使用 GNU Shepherd 作为初始化系统(init system),取代了传统的 systemd 或 SysV init。所有系统服务和用户服务都由 Shepherd 管理。
7.1.1 Shepherd 简介
Shepherd 是一个用 Guile Scheme 编写的初始化系统,它:
- 作为 PID 1 运行(系统初始化进程)
- 管理所有系统服务的启动、停止和依赖
- 支持用户级实例(管理用户服务)
- 与 Guix 的声明式配置深度集成
7.1.2 Guix 服务架构
operating-system
└── services 列表
├── service-type 1
│ └── service-configuration
├── service-type 2
│ └── service-configuration
└── %base-services(基础服务集)
guix system reconfigure
└── 构建 Shepherd 服务定义
└── Shepherd 启动/停止/重启服务
7.1.3 服务与服务类型
| 概念 | 说明 |
|---|---|
| Service Type | 服务的"类型"或"模板",定义服务如何配置和运行 |
| Service | 服务类型的具体实例,关联了特定的配置 |
| Service Extension | 服务类型之间的连接机制(如:nginx 扩展了 Shepherd) |
| Shepherd Service | 实际运行的服务守护进程 |
7.2 系统服务
7.2.1 使用系统服务
(use-service-modules networking ssh web
databases admin
docker virtualization)
(operating-system
;; ...
(services
(cons*
;; 每个 service 调用创建一个服务实例
(service openssh-service-type
(openssh-configuration
(permit-root-login 'prohibit-password)
(port-number 22)))
(service nginx-service-type
(nginx-configuration
(server-blocks
(list (nginx-server-configuration
(server-name '("example.com"))
(root "/var/www/html"))))))
;; 基础服务集
%base-services)))
7.2.2 常用系统服务速查表
| 服务类型 | 模块 | 说明 |
|---|---|---|
openssh-service-type | ssh | SSH 服务器 |
nginx-service-type | web | Nginx Web 服务器 |
postgresql-service-type | databases | PostgreSQL 数据库 |
mysql-service-type | databases | MySQL 数据库 |
redis-service-type | databases | Redis 缓存 |
dhcp-client-service-type | networking | DHCP 客户端 |
static-networking-service-type | networking | 静态网络 |
network-manager-service-type | networking | NetworkManager |
ntp-service-type | networking | NTP 时间同步 |
docker-service-type | docker | Docker 容器引擎 |
tor-service-type | networking | Tor 匿名网络 |
cups-service-type | cups | 打印服务 |
bluetooth-service-type | bluetooth | 蓝牙 |
gdm-service-type | xorg | GNOME 显示管理器 |
xorg-server-service-type | xorg | X11 服务器 |
7.3 服务配置详解
7.3.1 SSH 服务配置
(service openssh-service-type
(openssh-configuration
;; 监听端口
(port-number 2222)
;; 根用户登录策略
(permit-root-login 'prohibit-password)
;; 'yes — 允许密码和密钥
;; 'no — 完全禁止
;; 'prohibit-password — 仅允许密钥(推荐)
;; 密码认证
(password-authentication? #f)
;; 允许的用户
(allow-agent-forwarding? #t)
(allow-tcp-forwarding? #t)
;; 守护进程配置
(log-level 'VERBOSE)
;; 额外配置
(extra-content "
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 60
ClientAliveInterval 300
ClientAliveCountMax 2
")))
7.3.2 Nginx 服务配置
(service nginx-service-type
(nginx-configuration
;; 全局配置
(server-blocks
(list
;; HTTP → HTTPS 重定向
(nginx-server-configuration
(server-name '("example.com"))
(listen '("80"))
(locations
(list (nginx-location-configuration
(uri "/")
(body '("return 301 https://$host$request_uri;"))))))
;; HTTPS 站点
(nginx-server-configuration
(server-name '("example.com"))
(listen '("443 ssl"))
(root "/var/www/example.com")
(ssl-certificate "/etc/ssl/certs/example.com.pem")
(ssl-certificate-key "/etc/ssl/private/example.com.key")
(locations
(list
;; 静态文件
(nginx-location-configuration
(uri "/static/")
(body '("alias /var/www/example.com/static/;"
"expires 30d;")))
;; API 代理
(nginx-location-configuration
(uri "/api/")
(body '("proxy_pass http://127.0.0.1:8000;"
"proxy_set_header Host $host;"
"proxy_set_header X-Real-IP $remote_addr;"))))))))
;; 全局额外配置
(extra-content "
worker_processes auto;
worker_rlimit_nofile 65535;
")))
7.3.3 PostgreSQL 服务配置
(service postgresql-service-type
(postgresql-configuration
(postgresql postgresql-15)
(port 5432)
(data-directory "/var/lib/postgresql/data")
(extra-config
'(("shared_buffers" . "256MB")
("work_mem" . "8MB")
("maintenance_work_mem" . "128MB")
("effective_cache_size" . "1GB")
("max_connections" . "200")
("log_min_duration_statement" . "1000")
("timezone" . "Asia/Shanghai")))))
7.4 修改基础服务
7.4.1 modify-services 宏
%base-services 包含了系统所需的基础服务集(如 mingetty、syslog、udev)。要修改其中的服务,使用 modify-services:
(services
(cons*
;; 添加新服务...
(service openssh-service-type ...)
;; 修改基础服务
(modify-services %base-services
;; 修改 syslog 服务
(syslog-service-type config =>
(syslog-configuration
(inherit config)
(extra-content "
# 自定义日志规则
*.info;mail.none;authpriv.none;cron.none /var/log/messages
")))
;; 删除不需要的服务
(delete mingetty-service-type)
(delete mingetty-service-type) ; 删除所有 mingetty
;; 修改 guix-service
(guix-service-type config =>
(guix-configuration
(inherit config)
(substitute-urls
(append '("https://substitutes.nonguix.org")
%default-substitute-urls))
(authorized-keys
(append (list (plain-file "nonguix.pub" "..."))
%default-authorized-guix-keys)))))))
7.4.2 常见修改场景
禁用不需要的 TTY:
(modify-services %base-services
;; 只保留 tty1
(delete mingetty-service-type))
配置替代源(Substitute):
(guix-service-type config =>
(guix-configuration
(inherit config)
(substitute-urls
'("https://ci.guix.gnu.org"
"https://substitutes.nonguix.org"))
(authorized-keys
(append (list (plain-file "nonguix.pub" "..."))
%default-authorized-guix-keys))))
7.5 用户服务(User Services)
Guix Home 支持用户级服务,在用户登录后由 Shepherd 用户实例管理。
7.5.1 用户服务 vs 系统服务
| 特性 | 系统服务 | 用户服务 |
|---|---|---|
| 运行身份 | root | 当前用户 |
| 管理工具 | sudo herd | herd |
| 启动时机 | 系统引导 | 用户登录 |
| 配置位置 | /etc/config.scm | ~/.config/guix/home-configuration.scm |
| 影响范围 | 整个系统 | 仅当前用户 |
7.5.2 常用用户服务
(use-modules (gnu home services)
(gnu home services guix)
(gnu home services shells)
(gnu home services gnupg)
(gnu home services ssh)
(gnu home services desktop))
(home-environment
;; ...
(services
(list
;; Bash 配置
(service home-bash-service-type
(home-bash-configuration
(aliases
'(("ll" . "ls -alh")
("gs" . "git status")
("gp" . "git push")))
(bashrc
(list (plain-file "bashrc" "
export EDITOR=vim
export VISUAL=vim
export LANG=zh_CN.UTF-8
")))))
;; GPG Agent
(service home-gpg-agent-service-type
(home-gpg-agent-configuration
(pinentry-program
(file-append pinentry-qt "/bin/pinentry-qt"))
(ssh-support? #t)
(default-cache-ttl 3600)
(max-cache-ttl 86400)))
;; SSH Agent
(service home-ssh-agent-service-type
(home-ssh-agent-configuration
(extra-content "AddKeysToAgent yes")))
;; 用户 Shepherd 服务
(service home-shepherd-service-type
(home-shepherd-configuration
(services
(list
;; 后台同步文件的服务
(shepherd-service
(provision '(file-sync))
(requirement '(user-processes))
(one-shot? #t)
(start #~(lambda ()
(system* #$(file-append rsync "/bin/rsync")
"-avz" "/home/user/docs/"
"backup:/backups/docs/")
#t))
(documentation "Sync files to backup server")))))))))
7.6 自定义服务
7.6.1 创建自定义 Shepherd 服务
(use-modules (gnu services)
(gnu services shepherd)
(guix gexp)
(guix records))
;; 定义服务配置记录
(define-record-type* <my-app-configuration>
my-app-configuration make-my-app-configuration
my-app-configuration?
(package my-app-configuration-package
(default my-app))
(port my-app-configuration-port
(default 8080))
(config-file my-app-configuration-config-file
(default "/etc/my-app/config.yaml"))
(user my-app-configuration-user
(default "myapp")))
;; 定义服务类型
(define my-app-service-type
(service-type
(name 'my-app)
(description "Run the My-App web service.")
(extensions
(list
;; 扩展 Shepherd 以管理此服务
(service-extension shepherd-root-service-type
(lambda (config)
(list (shepherd-service
(provision '(my-app))
(requirement '(networking file-systems))
(documentation "Run My-App server.")
(start #~(make-forkexec-constructor
(list #$(file-append
(my-app-configuration-package config)
"/bin/my-app")
"--port"
(number->string
(my-app-configuration-port config))
"--config"
(my-app-configuration-config-file config))
#:user #$(my-app-configuration-user config)
#:group #$(my-app-configuration-user config)
#:log-file "/var/log/my-app.log"))
(stop #~(make-kill-destructor))
(respawn? #t)))))
;; 扩展系统包列表
(service-extension profile-service-type
(lambda (config)
(list (my-app-configuration-package config))))))
(default-value (my-app-configuration))))
;; 使用自定义服务
(services
(cons*
(service my-app-service-type
(my-app-configuration
(port 9090)
(config-file "/etc/my-app/production.yaml")))
%base-services))
7.6.2 添加系统用户的服务扩展
;; 如果服务需要专用系统用户
(service-extension account-service-type
(lambda (config)
(list (user-account
(name (my-app-configuration-user config))
(group (my-app-configuration-user config))
(system? #t)
(home-directory "/var/empty")
(shell (file-append shadow "/sbin/nologin")))
(user-group
(name (my-app-configuration-user config))
(system? #t)))))
7.6.3 添加激活脚本
;; 服务激活时运行的脚本(reconfigure 时执行)
(service-extension activation-service-type
(lambda (config)
#~(begin
(mkdir-p "/etc/my-app")
(mkdir-p "/var/log/my-app")
(chmod "/var/log/my-app" #o755))))
7.7 Shepherd 命令行操作
7.7.1 系统级操作
# 查看所有服务状态
sudo herd status
# 查看特定服务
sudo herd status sshd
# 启动服务
sudo herd start nginx
# 圜止服务
sudo herd stop nginx
# 重启服务
sudo herd restart nginx
# 查看服务日志
sudo herd log sshd
7.7.2 用户级操作
# 用户服务不使用 sudo
herd status
herd start file-sync
herd stop gpg-agent
7.7.3 常用 Shepherd 操作速查表
| 操作 | 系统服务 | 用户服务 |
|---|---|---|
| 查看状态 | sudo herd status | herd status |
| 启动 | sudo herd start <name> | herd start <name> |
| 停止 | sudo herd stop <name> | herd stop <name> |
| 重启 | sudo herd restart <name> | herd restart <name> |
| 查看日志 | sudo herd log <name> | herd log <name> |
7.8 服务故障排查
7.8.1 常见诊断命令
# 查看服务是否正在运行
sudo herd status nginx
# 查看服务日志
sudo herd log nginx
# 查看系统日志
journalctl -u shepherd
# 查看服务的 PID
sudo herd eval '(service-running? (lookup-service (quote nginx)))'
# 手动运行服务命令调试
sudo -u myapp /gnu/store/.../bin/my-app --port 8080 --debug
7.8.2 常见问题表
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 服务无法启动 | 配置错误 | 检查 herd log |
| 端口冲突 | 多个服务使用同一端口 | 修改端口配置 |
| 权限不足 | 文件权限或 SELinux | 检查用户和权限 |
| 依赖未满足 | 启动顺序问题 | 在 requirement 中声明依赖 |
| 服务不断重启 | 应用崩溃 | 查看日志和崩溃原因 |
7.8.3 调试自定义服务
;; 在 shepherd-service 中添加更详细的日志
(shepherd-service
(provision '(my-app))
(start #~(make-forkexec-constructor
(list #$(file-append my-app-package "/bin/my-app")
"--debug" ; 开启调试模式
"--log-level=trace")
#:log-file "/var/log/my-app-debug.log"
#:environment-variables
(list "RUST_LOG=debug"
"MY_APP_DEBUG=1")))
;; 失败后不自动重启(便于调试)
(respawn? #f))
7.9 服务组合模式
7.9.1 LAMP 栈配置
;; Linux + Apache/Nginx + MySQL/MariaDB + PHP/Python
(services
(cons*
;; Nginx
(service nginx-service-type
(nginx-configuration
(server-blocks
(list (nginx-server-configuration
(server-name '("myapp.com"))
(root "/var/www/myapp")
(listen '("80")))))))
;; MySQL
(service mysql-service-type
(mysql-configuration
(mysql mysql-8)
(port 3306)
(extra-content "[mysqld]\ncharacter-set-server=utf8mb4\n")))
;; Redis
(service redis-service-type
(redis-configuration
(port 6379)
(maxmemory "256mb")))
;; SSH
(service openssh-service-type
(openssh-configuration
(permit-root-login 'prohibit-password)))
%base-services))
7.9.2 微服务架构配置
;; 定义多个自定义微服务
(services
(cons*
(service api-gateway-service-type
(api-gateway-configuration (port 8080)))
(service user-service-type
(user-service-configuration (port 8001)))
(service order-service-type
(order-service-configuration (port 8002)))
(service message-queue-service-type
(message-queue-configuration (port 5672)))
%base-services))
7.10 总结
本章讲解了 Guix 的服务管理体系:
- Shepherd 初始化系统——Guix 使用的 PID 1 进程
- 系统服务——SSH、Nginx、PostgreSQL 等常用服务配置
- 修改基础服务——使用
modify-services定制%base-services - 用户服务——Guix Home 中的用户级服务
- 自定义服务——创建自己的 Shepherd 服务
- 故障排查——日志查看和问题诊断
下一章我们将学习容器与隔离技术。