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

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-typesshSSH 服务器
nginx-service-typewebNginx Web 服务器
postgresql-service-typedatabasesPostgreSQL 数据库
mysql-service-typedatabasesMySQL 数据库
redis-service-typedatabasesRedis 缓存
dhcp-client-service-typenetworkingDHCP 客户端
static-networking-service-typenetworking静态网络
network-manager-service-typenetworkingNetworkManager
ntp-service-typenetworkingNTP 时间同步
docker-service-typedockerDocker 容器引擎
tor-service-typenetworkingTor 匿名网络
cups-service-typecups打印服务
bluetooth-service-typebluetooth蓝牙
gdm-service-typexorgGNOME 显示管理器
xorg-server-service-typexorgX11 服务器

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 herdherd
启动时机系统引导用户登录
配置位置/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 statusherd 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 的服务管理体系:

  1. Shepherd 初始化系统——Guix 使用的 PID 1 进程
  2. 系统服务——SSH、Nginx、PostgreSQL 等常用服务配置
  3. 修改基础服务——使用 modify-services 定制 %base-services
  4. 用户服务——Guix Home 中的用户级服务
  5. 自定义服务——创建自己的 Shepherd 服务
  6. 故障排查——日志查看和问题诊断

下一章我们将学习容器与隔离技术。


扩展阅读