CloudNative 架构

CloudNative|云原生应用架构|云原生架构|容器化架构|微服务架构|平台架构|基础架构


  • 首页

  • 标签

  • 分类

  • 归档

  • k8s离线安装包

  • 搜索

docker 卡死引起的 container runtime is down

发表于 2020-10-26 | 分类于 docker , error | | 热度: ℃
字数统计: 9,328 字 | 阅读时长 ≈ 49 分钟

1 背景

最近升级了一版 kubelet,修复因 kubelet 删除 Pod 慢导致平台删除集群超时的问题。在灰度 redis 隔离集群的时候,发现升级 kubelet 并重启服务后,少量宿主状态变成了 NotReady,并且回滚 kubelet 至之前版本,宿主状态仍然是 NotReady。查看宿主状态时提示 ‘container runtime is down’ ,根据经验,此时一般就是容器运行时出了问题。弹性云使用的容器运行时是 docker,我们就去检查 docker 的状态,检测结果如下:

  • docker ps 查看所有容器状态,执行正常
  • docker inspect 查看某一容器详细状态,执行阻塞

典型的 docker hang 死行为。因为我们最近在升级 docker 版本,存量宿主 docker 的版本为 1.13.1,并且在逐步升级至 18.06.3,新宿主的 docker 版本都是 18.06.3。docker hang 死问题在 1.13.1 版本上表现得更彻底,在执行 docker ps 的时候就已经 hang 死了,一旦某个容器出了问题,docker 就处于无响应状态;而 docker 18.06.3 做了一点小小的优化,在执行 docker ps 时去掉了针对容器级别的加锁操作,但是 docker inspect 依然会加容器锁,因此某一个容器出现问题,并不会造成 docker 服务不可响应,受影响的也仅仅是该容器,无法执行任何操作。

至于为什么以 docker ps 与 docker inspect 为指标检查 docker 状态,因为 kubelet 就是依赖这两个 docker API 获取容器状态。

所以,现在问题有二:

  1. docker hang 死的根因是什么?
  2. docker hang 死时,为什么重启 kubelet,会导致宿主状态变为 NotReady?
    阅读全文 »

使用 Linux tracepoint、perf 和 eBPF 跟踪数据包

发表于 2020-10-25 | 分类于 抓包 , debug | | 热度: ℃
字数统计: 5,596 字 | 阅读时长 ≈ 25 分钟

一段时间以来,我一直在寻找 Linux 上的底层网络调试(debug)工具。

Linux 允许在主机上用虚拟网卡(virtual interface)和网络命名空间(network namespace)构建复杂的网络。但出现故障时,排障(troubleshooting)相当痛苦。如果是 3 层路由问题,mtr 可以排上用场。但如果是更底层的问题,我通常只能手动检查每个网 卡/网桥/网络命名空间/iptables 规则,用 tcpdump 抓一些包,以确定到底是什么状况。如 果不了解故障之前的网络设置,那感觉就像在走迷宫。

阅读全文 »

Docker 中 Storage-driver 启用 Overlay2 并限制单个容器的磁盘空间

发表于 2020-10-23 | 分类于 docker | | 热度: ℃
字数统计: 2,059 字 | 阅读时长 ≈ 8 分钟

1 简介

目前 docker 中常见的 Storage-driver 主要有 AUFS、Devicemapper 以及 Overlay2,这三种文件存储驱动这里简单介绍下。同时着重介绍 Overlay2 的使用事项。

阅读全文 »

带你了解 Kube-proxy 工作原理

发表于 2020-10-22 | 分类于 kubrenetes , kube-proxy | | 热度: ℃
字数统计: 8,482 字 | 阅读时长 ≈ 38 分钟

kube-proxy介绍

为什么需要kube-proxy

我们知道容器的特点是快速创建、快速销毁,Kubernetes Pod 和容器一样只具有临时的生命周期,一个 Pod 随时有可能被终止或者漂移,随着集群的状态变化而变化,一旦Pod 变化,则该 Pod 提供的服务也就无法访问,如果直接访问 Pod 则无法实现服务的连续性和高可用性,因此显然不能使用 Pod 地址作为服务暴露端口。

解决这个问题的办法和传统数据中心解决无状态服务高可用的思路完全一样,通过负载均衡和 VIP 实现后端真实服务的自动转发、故障转移。

这个负载均衡在 Kubernetes 中称为 Service,VIP 即 Service ClusterIP,因此可以认为Kubernetes 的 Service 就是一个四层负载均衡,Kubernetes 对应的还有七层负载均衡 Ingress,本文仅介绍 Kubernetes Service。

这个 Service 就是由 kube-proxy 实现的,ClusterIP 不会因为 Pod 状态改变而变,需要注意的是 VIP 即 ClusterIP 是个假的 IP,这个 IP 在整个集群中根本不存在,当然也就无法通过IP协议栈无法路由,底层 underlay 设备更无法感知这个 IP 的存在,因此 ClusterIP 只能是单主机(Host Only)作用域可见,这个IP在其他节点以及集群外均无法访问。

Kubernetes 为了实现在集群所有的节点都能够访问 Service,kube-proxy 默认会在所有的 Node 节点都创建这个 VIP 并且实现负载,所以在部署 Kubernetes 后发现 kube-proxy 是一个 DaemonSet。

阅读全文 »

使用 eBPF 调试生产环境的 Go 程序

发表于 2020-10-21 | 分类于 golang , debug | | 热度: ℃
字数统计: 3,103 字 | 阅读时长 ≈ 12 分钟

不用重新编译/部署线上程序而是借助 eBPF 即可实现对程序进行调试,接下来我们会用一个系列文章介绍我们是怎么做的,这是开篇。本篇描述了如何使用 gobpf 和 uprobe 来构建一个跟踪 Go 程序函数入口参数变化的应用。这里介绍的技术可以扩展到其它编译型语言,如 C++, Rust 等等。本系列文章后续将会讨论如何使用 eBPF 来跟踪 HTTP/gRPC 数据和 SSL 等等。

介绍

当调试程序时,我们一般对捕获程序的运行时状态非常感兴趣。因为这可以让我们检查程序在干什么,并能让我们确定 bug 出现在程序的哪一块。观察运行时状态的一个简单方式是使用调试器。比如针对 Go 程序,我们可以使用 Delve 和 gdb。

Delve 和 gdb 在开发环境中做调试表现没得说,但是我们一般不会在线上使用此类工具。它们的长处同时也是它们的短处,因为调试器会导致线上程序中断,甚至如果在调试过程中不小心改错某个变量的值而导致线上程序出现异常。

为了让线上调试过程的侵入和影响更小,我们将会探索使用增强版的 BPF (eBPF, Linux 4.x+ 内核可用)和更高级的 Go 库 gobpf 来达成目标。

阅读全文 »
1…567…22
icyboy

icyboy

109 日志
98 分类
182 标签
RSS
GitHub 微博 知乎
友情链接
  • 张家港水蜜桃
  • 运维开发
  • DevOps
© 2016 — 2021 icyboy | Site words total count: 330.8k
本站访客数:
博客全站共330.8k字