You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

单节点Kubernetes集群重启后组件陷入CrashLoopBackOff状态的问题咨询

单节点Kubernetes集群重启后组件陷入CrashLoopBackOff状态的问题咨询

您好,针对您遇到的单节点kubeadm部署K8s集群重启后组件连锁CrashLoopBackOff的问题,尤其是kube-scheduler先故障引发多米诺效应的情况,我结合单节点集群的特殊性给您梳理几个排查和解决方向:

一、先揪出kube-scheduler崩溃的核心原因

既然kube-scheduler是第一个出问题的组件,咱们得先搞清楚它崩溃的具体原因,这是解决连锁反应的关键。您可以通过这两个方式查看它的日志:

# 用kubectl查看最新日志
kubectl logs -n kube-system kube-scheduler-$(hostname) --tail=50
# 或者直接查看节点上的静态Pod日志文件(kubeadm部署的默认路径)
cat /var/log/pods/kube-system_kube-scheduler-$(hostname)_*/kube-scheduler/*.log

常见的触发原因大概有这几种:

  • etcd连接超时:重启后etcd还没完全就绪,scheduler就急着连接导致失败
  • 证书异常:重启后kube-scheduler的客户端证书权限或路径被意外重置
  • 端口占用:其他进程抢占了scheduler默认的10259端口

二、给核心组件设置启动顺序/延迟

单节点环境下,K8s默认是并行启动所有静态Pod的,没有依赖顺序,这很容易导致依赖上游组件的服务(比如scheduler依赖api-server,api-server依赖etcd)因为上游没就绪而崩溃。咱们可以通过两种方式调整:

1. 给kube-scheduler加启动延迟

编辑/etc/kubernetes/manifests/kube-scheduler.yaml,在容器的command开头加一个sleep命令,让它等一等etcd和api-server:

spec:
  containers:
  - command:
    - sh
    - -c
    - "sleep 30 && kube-scheduler --config=/var/lib/kube-scheduler/config.yaml ..." # 保留原来的所有参数,只在最前面加sleep 30

注意要把原来的完整command参数保留,只是套上sleep的壳子,延迟时间可以根据您集群的启动速度调整(比如30-60秒)。

2. 按文件名排序控制静态Pod启动顺序(kubeadm 1.24+适用)

从K8s 1.24版本开始,kubelet会按照静态Pod目录(/etc/kubernetes/manifests)下的文件名字典序来启动Pod。咱们可以给核心组件的manifest文件改名,强制指定顺序:

  • 把etcd的manifest改名为00-etcd.yaml(最先启动)
  • api-server改名为01-kube-apiserver.yaml
  • controller-manager改名为02-kube-controller-manager.yaml
  • scheduler改名为03-kube-scheduler.yaml
    这样kubelet就会严格按这个顺序启动组件,从依赖最底层的etcd开始,避免启动时序冲突。

三、检查网络组件的就绪状态

您用了cilium作为CNI,重启后要确认cilium agent是否在coredns之前就绪——如果cilium网络还没起来,coredns会因为无法解析服务而异常,进而影响其他组件。您可以查看cilium agent的日志确认:

kubectl logs -n kube-system cilium-agent-$(hostname) --tail=50

如果cilium启动较慢,可以给它的DaemonSet加一个initContainer来等待网络就绪,或者同样给cilium agent加启动延迟。

四、优化组件的健康检查参数

之前您调整过failureThreshold,但可能还需要调整initialDelaySeconds(健康检查的初始等待时间)。比如给kube-scheduler的存活探针和就绪探针增加初始延迟,避免过早触发健康检查导致Pod被重启:

livenessProbe:
  httpGet:
    path: /healthz
    port: 10259
    scheme: HTTPS
  initialDelaySeconds: 60 # 从默认的10秒改成60秒,给足够的启动时间
  periodSeconds: 10
  timeoutSeconds: 15
readinessProbe:
  httpGet:
    path: /healthz
    port: 10259
    scheme: HTTPS
  initialDelaySeconds: 30
  periodSeconds: 10

同样的逻辑也适用于api-server、controller-manager等核心组件,适当延长初始等待时间,给组件足够的启动和连接上游的时间。

五、单节点集群的额外优化点

针对单节点环境,还有两个小细节可以优化:

  • 如果您已经用cilium替代kube-proxy(cilium支持kube-proxy replacement),可以关闭kube-proxy的strictARP配置,避免网络规则冲突
  • 确认etcd的数据目录权限正确:chown -R etcd:etcd /var/lib/etcd,防止重启后etcd无法加载数据

修改完成后,您可以重启kubelet验证效果:

systemctl restart kubelet

然后用kubectl get pods -n kube-system观察组件的启动状态,看是否还会出现CrashLoopBackOff的情况。

备注:内容来源于stack exchange,提问作者rafiki

火山引擎 最新活动