前几天有个朋友把他们的kubernetes集群搞挂了,让我帮忙恢复一下,由于很多现场都没有了,这里提供一下解决思路。

环境问题

该环境有一个master节点,即控制面pod(etcd、scheduler等)也都只有一个pod

问题起因是他们的服务访问出了点问题,为修复该问题,他:

  • 备份了etcd数据(数据是3天前的)
  • 重启了docker
  • 将etcd数据恢复(数据是3天前的)

然后访问服务依然不通。

问题诊断

deployment reversion不匹配

首先看到pod并非running状态,直接删除pod,让其重建,查看pod创建过程,发现pod并没有分配到node。

问题分析

首先怀疑可能kube-scheduler出现了问题:

  1. 删除kube-scheduler pod发现无法重建该pod
  2. 最后通过将/etc/kubernetes/manifests/kube-scheduler.yaml文件移出再移入的方式创建出scheduler pod

此时仍然无法调度pod,因此怀疑是在scheduler之前出现了问题,查看api-server的日志,发现有很多reversion版本不匹配的错误,应该是集群中的资源版本和etcd中的资源版本不匹配导致的:

  1. 使用etctctl检查etcd的状态,发现etcd一切正常

    etcdctl endpoint health
    etcdctl endpoint status --write-out=table
  2. 使用kubectl rollout history deployment/<deployment_name>查看etcd中保存的的deployment的版本,然后执行kubectl rollout undo daemonset/<deployment_name> --to-revision=<version>回滚到与etcd匹配的版本。

    回滚之前可以通过kubectl rollout history daemonset/<deployment_name> --revision=<version>对比etcd和环境中的配置区别

  3. 回滚之后发现pod可以正常创建出来

Iptables丢失问题

pod起来之后,服务访问仍然不通。使用kubectl describe命令查看服务的service,发现没有找到service对应的endpoints,一开始还以为是service的yaml的问题,debug了大半天发现绝大部分services都没有endpoints。。。

问题分析

service找不到endpoints,体现在系统中就是可能没有创建出iptables规则:

  1. 使用iptables-save命令查看,发现果然没有kubernetes的iptables规则
  2. 该环境使用的是ipvs模式,使用ipvsadm -l -n也发现service的cluster IP没有对应的pod IP
  3. 查看kube-proxy日志,并未发现任何异常

此时想到的方式有:

  1. 重新创建pod和对应的service,刷新iptables:尝试失败,重建之后并未生成iptables
  2. 重建节点:所有节点都存在问题,无法通过kubectl drain迁移pod
  3. 手动添加iptables:太过复杂,即便成功,也会污染节点的iptables规则。
  4. 重新创建kube-proxy pod:重启kube-proxy pod之后也并未创建iptables规则

最后怀疑kube-proxy也可能出现问题,需要重新初始化kube-proxy,恰好kubeadm有如下命令可以重新初始化kube-proxy:

kubeadm init phase addon kube-proxy --kubeconfig ~/.kube/config --apiserver-advertise-address <api-server-ip>

在重新初始化kube-proxy之后发现iptables规则创建成功,删除并创建pod和service之后可以正确创建出对应的iptables规则,此时service也有了endpoints。

CNI连接错误

在上一步重启pod之后,发现有一个webhook对应的pod没有重启成功,用kubectl describe 该pod发现如下错误:

networkPlugin cni failed to set up pod "webhook-1" network: Get "https://[10.233.0.1]:443/api/v1/namespaces/volcano-system": dial tcp 10.233.0.1:443: i/o timeout

该集群使用的是calico CNI,查看该CNI对应的daemonset,发现只有5个pod是ready的。

删除"webhook-1" pod所在的节点的"calico-node" pod,发现该"calico-node" pod启动失败。

问题分析

在上述错误中,"10.233.0.1"为kubernetes apiserver的service cluster IP,由于"clico-node" pod使用的是hostnetwork,因此可以直接在node上测试联通性,使用telnet 10.233.0.1 443测试,发现果然不通。

calico的/etc/cni/net.d/10-calico.conflist配置文件中定义了连接apiserver所需的kubeconfig文件:

{
"name": "cni0",
"cniVersion":"0.3.1",
"plugins":[
{
...
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
...
]
}

/etc/cni/net.d/calico-kubeconfig中就定义了连接apiserver所需的地址和端口,因此只需将该地址端口换成apiserver pod的地址和端口应该就可以解决该问题:

# cat /etc/cni/net.d/calico-kubeconfig
# Kubeconfig file for Calico CNI plugin.
apiVersion: v1
kind: Config
clusters:
- name: local
cluster:
server: https://[10.233.0.1]:443
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0...
users:
- name: calico
user:
token: eyJhbGciOiJSUzI1NiIsImtpZC...
contexts:
- name: calico-context
context:
cluster: local
user: calico

Calico提供了如下两个环境变量用于修改生成的kubeconfig中的apiserver的地址和端口,将如下环境变量加入calico的daemonset,重新创建calico-node pod即可:

- name: KUBERNETES_SERVICE_HOST
value: <api-server-pod-ip>
- name: KUBERNETES_SERVICE_PORT
value: "6443"

至此,问题基本解决。由于错误的操作,该集群出现了大量问题,后续可以通过驱逐节点pod的方式,重新初始化整个节点,逐步重置集群节点配置。

修复一个kubernetes集群的更多相关文章

  1. kubeadm部署一个Kubernetes集群

    kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具.这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点 $ kubeadm in ...

  2. 第3章:快速部署一个Kubernetes集群

    kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点$ kubeadm in ...

  3. K8S学习笔记之二进制的方式创建一个Kubernetes集群

    0x00 单节点搭建和简述 minikube Minikube是一个工具,可以在本地快速运行一个单点的Kubernetes,尝试Kubernetes或日常开发的用户使用.不能用于生产环境. 官方地址: ...

  4. Kubernetes 学习笔记(二):本地部署一个 kubernetes 集群

    前言 前面用到过的 minikube 只是一个单节点的 k8s 集群,这对于学习而言是不够的.我们需要有一个多节点集群,才能用到各种调度/监控功能.而且单节点只能是一个加引号的"集群&quo ...

  5. 快速部署一个Kubernetes集群

    官方提供的三种部署方式 minikube Minikube是一个工具,可以在本地快速运行一个单点的Kubernetes,仅用于尝试Kubernetes或日常开发的用户使用. 部署地址:https:// ...

  6. 使用 Kubeadm+Containerd 部署一个 Kubernetes 集群

    本文独立博客阅读地址:https://ryan4yin.space/posts/kubernetes-deployemnt-using-kubeadm/ 本文由个人笔记 ryan4yin/knowle ...

  7. 阿里云上万个 Kubernetes 集群大规模管理实践

    点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 | 汤志敏,阿里 ...

  8. Kubeadm部署K8S(kubernetes)集群(测试、学习环境)-单主双从

    1. kubernetes介绍 1.1 kubernetes简介 kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理.目的是实现资源管理的自动 ...

  9. 快速安装与配置kubernetes集群搭

    Kubernetes是什么? 首先,它是一个全新的基于容器技术的分布式架构领先方案.这个方案尽然很新,但它是谷歌十几年以来大规模应用容器技术的经验积累和升华的一个重要成果.确切地说,kubernete ...

  10. kubernetes集群部署

    鉴于Docker如此火爆,Google推出kubernetes管理docker集群,不少人估计会进行尝试.kubernetes得到了很多大公司的支持,kubernetes集群部署工具也集成了gce,c ...

随机推荐

  1. conda中安装GCC/G++

    参考: https://www.5axxw.com/questions/content/h0e4te ========================================== 一般在lin ...

  2. Apache SeaTunnel 4月回顾:明星贡献者与技术突破

    各位热爱 SeaTunnel 的小伙伴们,SeaTunnel 社区 4 月份月报来啦!这里将记录 SeaTunnel 社区每月的重要更新,欢迎关注! 月度 Merge 之星 感谢以下小伙伴 4 月为 ...

  3. 结构开发笔记(三):solidworks软件(二):小试牛刀,绘制一个立方体

    前言   solidworks草图大师,基本的使用过程.  所有的零件基础都是从平面绘制开始,然后凸出来厚度.  本篇绘制一个简单的立方体,熟悉基本操作.   立方体绘制过程   选取一个平面绘制一个 ...

  4. 在Debian上安装freeswitch

    在Debian上安装freeswitch 说明: 首次发表日期:2024-08-12 参考文档: https://medium.com/@jogikrunal9477/ultimate-guide-t ...

  5. java中的几种锁

    一.公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁. 非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁.有可能,会造成优先级反转或者饥饿 ...

  6. ClassFinal防JAVA代码反编译

    亲测可用!不过项目暂停更新了. 传送地址:https://gitee.com/roseboy/classfinal#%E5%8A%A0%E5%AF%86

  7. 【测试平台开发】——01Vue前端框架实操

    一.VScode官网地址 https://code.visualstudio.com/ 但是官网下载贼慢,需要修改下国内地址: 原地址:https://az764295.vo.msecnd.net/s ...

  8. Java基础 韩顺平老师的 泛型 的部分笔记

    553,泛型引入 package com.hspedu.list_; import java.util.*; import java.util.concurrent.CompletionService ...

  9. ChatGPT中Java相关问答(包括Java基础知识和一些面试题)

    分享一个自己学习Java时的记录ChatGPT中的对话:https://chatgpt.com/share/66e8f009-0fd0-8000-b458-8c5812d0b631 包括如下问题 Ho ...

  10. JAVAEE——maven安装

    一.安装本地Maven 注意:检查JAVA_HOME环境变量, maven本身就是java写的,所以要求必须先安装JDK,检查本机jak环境win+r后输入cmd,然后输入java -version, ...