前几天有个朋友把他们的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. 【转载】 HTTP中的响应协议及302、304的含义

    原文地址: https://www.cnblogs.com/chenyablog/p/9197305.html ============================== 响应协议 HTTP/1.1 ...

  2. git 如何在本地批量删除匹配名称分支

    背景 有时间创建了一大堆的dev/*分支,远程合并完就删除了,但本地还留下一大堆,自己又忘记删除了.一个个删除太麻烦.后面发现居然有批量删除的方法 备注:这里是window下powershell的命令 ...

  3. Java核心技术之Date相关

    import java.time.DayOfWeek; import java.time.LocalDate; import java.util.Scanner; /** * @author Suns ...

  4. Vim 全局配置 / 设置鼠标模式

    新搞的 Linux (Debian) 上的 vim 一右击粘贴就变成 insert (Visual) 模式,上网查了一下,要 set mouse=,但是每次设置太麻烦了,另外我也想改一下全局配色. 定 ...

  5. 使用FModel提取黑神话悟空的资产

    目录 前言 设置 效果展示 闲聊 可能遇到的问题 没有相应的UE引擎版本选项 前言 黑神话悟空昨天上线了,解个包looklook. 本文内容比较简洁,仅介绍解包黑神话所需的专项配置,关于FModel的 ...

  6. tlmgr 操作

    宏包管理 sudo tlmgr install <package> # 安装宏包 sudo tlmgr install scheme-full # 安装全部宏包 sudo tlmgr re ...

  7. 连续因子一个正整数 N

    一个正整数 N 的因子中可能存在若干连续的数字.例如 630 可以分解为 3×5×6×7,其中 5.6.7 就是 3 个连续的数字.给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的 ...

  8. Java实现英语作文单词扫盲程序

    来自背英语四级单词的突发奇想: 是否可以通过Java语言实现一个随机抽取作文中单词进行复习的程序. 首先,展示下成果: 点击查看代码 package Demo; import java.util.Ar ...

  9. sql查询死锁

    --每秒死锁数量 SELECT * FROM sys.dm_os_performance_counters WHERE counter_name LIKE 'Number of Deadlocksc% ...

  10. Google – Reviews

    前言 继上一篇 Facebook – Reviews (Graph API) 后, 这篇继续介绍另一个 Reviews 大平台 Google Reviews. 想通过 API 获取 Google Re ...