如何安全地关闭一个K3S集群?

2025-10-27 18:50:00
丁国栋
原创 62
摘要:本文记录和整理如何安全地关闭一个K3S集群。

如何安全地关闭一个K3S集群?

核心原则是:先优雅地停止工作负载,再停止 K3s 服务进程,最后关闭节点服务器。

以下是详细的步骤和不同场景下的操作方法。

核心概念:关闭顺序

一个标准的关闭顺序应该是: 工作负载(Pods) -> K3s 服务 -> 操作系统

  1. 优雅驱逐工作负载:通知 Kubernetes 优雅地终止 Pod。Kubernetes 会向 Pod 发送 SIGTERM 信号,等待其正常关闭(执行预定义的停止钩子),超过宽限期后强制停止。
  2. 停止 K3s 服务:在所有工作负载安全停止后,再停止 K3s 的 server 和 agent 服务。
  3. 关闭服务器:最后执行操作系统的关机或重启命令。

方法一:标准关闭流程(推荐)

这种方法最安全,适用于计划内的维护。

步骤 1: 驱逐节点上的所有 Pod

这一步是关键,它确保 Pod 被安全地迁移到其他节点(如果集群有多个节点)。

  1. 将节点标记为不可调度并驱逐 Pods:所有节点上(包括 server 节点和 agent 节点),依次执行以下命令。

    # 1. 将当前节点标记为不可调度(Cordon)
    # 这会阻止新的 Pod 被调度到该节点上
    kubectl cordon <当前节点的名称>
    # 例如,如果在节点 k3s-agent-1 上操作:
    # kubectl cordon k3s-agent-1
    # 2. 驱逐该节点上的所有 Pod(Drain)
    # 这会优雅地终止节点上的所有 Pod,并使它们在其他可用节点上重新启动。
    kubectl drain <当前节点的名称> \
      --ignore-daemonsets \  # 忽略 DaemonSet 管理的 Pod(如网络插件、日志收集器)
      --delete-emptydir-data  # 删除使用 emptyDir 卷的数据(确认可以丢失这些数据)
    • --ignore-daemonsets 是必须的,因为 DaemonSet 的 Pod 每个节点都必须运行一个,无法被驱逐。
    • 这个命令可能会需要一些时间,因为它会等待每个 Pod 优雅终止。

步骤 2: 停止 K3s 服务

在确保所有 Pod 都已被驱逐后,再停止 K3s 服务。

  • 在 Agent 节点上:

    # 使用 systemd(最常见的方式)
    sudo systemctl stop k3s-agent
    # 或者,如果使用内置的 service 脚本
    sudo service k3s-agent stop
  • 在 Server 节点上: 重要: 关闭 Server 节点时,请最后关闭拥有集群数据存储(如嵌入式 etcd)的节点。

    # 使用 systemd
    sudo systemctl stop k3s
    # 或者,如果使用内置的 service 脚本
    sudo service k3s stop

步骤 3: 关闭或重启服务器

现在可以安全地关闭或重启服务器了。

# 关机
sudo shutdown -h now
# 或重启
sudo reboot

方法二:快速关闭(单节点集群或测试环境)

对于单节点集群或可以容忍短暂服务中断的测试环境,可以简化流程。

  1. 直接停止 K3s 服务: K3s 服务在停止时,会自动向其管理的所有容器(Pod)发送 SIGTERM 信号,允许它们优雅退出。

    # 在 Server 节点上
    sudo systemctl stop k3s
    # 在 Agent 节点上(如果有)
    sudo systemctl stop k3s-agent
  2. 等待几秒钟,让容器有足够时间关闭。

  3. 关闭服务器。


方法三:操作系统关机时自动处理

如果直接使用 shutdownreboot 命令,systemd 会按照依赖关系依次停止服务。由于 K3s 服务(k3sk3s-agent)依赖于容器运行时(containerd),而 containerd 又依赖于所有容器,所以理论上 systemd 会先停止 K3s 服务,从而触发 Pod 的优雅终止。

这通常也能正常工作,但不如方法一那样可控。在复杂生产环境中,推荐使用方法一。


启动集群

启动集群的顺序与关闭顺序相反: 操作系统 -> K3s 服务 -> 工作负载(Pods)

  1. 先启动所有 Server 节点。等待它们完全启动并形成共识。
  2. 再启动 Agent 节点。它们会自动重新注册到 Server。
  3. Kubernetes 调度器会将 Pod 重新调度到可用的节点上。

故障排除技巧

  • 节点卡在 NotReady 状态: 如果节点因异常关机而未能正常清理,重启后可能一直处于 NotReady 状态。可以手动恢复:

    # 首先,确认节点已经重新启动并且 k3s 服务运行正常。
    # 然后,取消节点的不可调度状态。
    kubectl uncordon <节点名称>
  • Pod 一直处于 Terminating 状态: 如果某个 Pod 无法正常终止,可以强制删除(谨慎使用):

    kubectl delete pod <pod-name> --namespace <namespace> --force --grace-period=0

总结

场景 推荐方法 关键步骤
多节点生产集群 方法一(标准流程) 1. kubectl cordon && drain
2. systemctl stop k3s-agent/k3s
3. shutdown
单节点/测试集群 方法二(快速关闭) 1. systemctl stop k3s
2. 等待几秒
3. shutdown
简单非关键环境 方法三(直接关机) 直接 shutdownreboot,依赖 systemd 的依赖关系
发表评论
博客分类