1. systemd 自定义启动项

/etc/systemd/system/usr/lib/systemd/system 的区别和用途,为什么优先使用 /etc/systemd/system

  • systemd 读取单元文件时,会按照优先级搜索:

    1. /etc/systemd/system

    2. /run/systemd/system

    3. /usr/lib/systemd/system

  • 这样可以让管理员通过在 /etc/systemd/system 放置自定义单元文件或者覆盖已有单元,实现定制化而不影响系统默认文件。

  • 举例:如果你想修改一个默认服务的启动参数,建议复制对应文件到 /etc/systemd/system,然后修改;系统升级时不会覆盖你的改动。

1.1 k8s-modules.service

cat > /etc/systemd/system/k8s-modules.service <<EOF
# 描述:开机自动加载 Kubernetes 所需内核模块,并自动启动 sysctl-k8s 服务
[Unit]
Description=Load Kubernetes required kernel modules
# 保证在网络初始化之前加载内核模块
Before=network-pre.target
# 希望 network-pre.target 启动,也希望自动启动 sysctl-k8s.service
Wants=network-pre.target sysctl-k8s.service
# 关闭默认依赖,手动控制依赖关系顺序
DefaultDependencies=no

[Service]
# 一次性任务,执行完即退出
Type=oneshot
# 加载k8s需要用到的内核模块
ExecStart=/etc/sysconfig/modules/ipvs.modules
ExecStart=/etc/sysconfig/modules/br_netfilter.modules
# 执行完成后服务状态保持激活
RemainAfterExit=yes

[Install]
# 系统进入多用户运行级别时自动启动
WantedBy=multi-user.target
EOF

1.2 sysctl-k8s.service

cat > /etc/systemd/system/sysctl-k8s.service <<EOF
[Unit]
Description=应用 Kubernetes 所需的 sysctl 内核参数(适配麒麟系统)
# 确保该服务在网络初始化前执行,以便内核参数(如 ip_forward)及时生效
Before=network-pre.target
Wants=network-pre.target

# 确保内核模块先加载,避免 sysctl 参数路径不存在
After=k8s-modules.service
Requires=k8s-modules.service

# 禁用默认依赖,防止 systemd 自动附加不必要的依赖链,确保尽早启动
DefaultDependencies=no

# 关于为什么不用 sysctl --system:
# sysctl --system 会加载多个路径的 *.conf 配置文件
# 但其依赖 systemd-sysctl.service 来实现自动执行,而麒麟系统中该服务可能未启用或执行顺序靠后
# 导致某些关键参数(如 ip_forward)在 kubelet 或网络插件启动前未生效
# 所以使用 systemd 单独编排此 service 是更稳定可靠的做法

[Service]
Type=oneshot
# 加载我们自定义的 Kubernetes 所需 sysctl 配置
ExecStart=/usr/sbin/sysctl -p /etc/sysctl.d/k8s.conf
RemainAfterExit=true

[Install]
# 设置为在多用户模式下自动启动,确保开机时加载
WantedBy=multi-user.target
EOF