【深度解析】详细梳理Kubernetes的网络模型,总结网络故障排查核心思路

本文旨在梳理网络模型,总结出通用并且高可行性的故障排查思路,并且能通过自动化检测减少中大规模集群的手动排查工作。

1
默认读者已熟悉四层/七层网络模型,相关概念不再赘述

一、Linux中的基础网络技术

这里只会提及相关的Linux指令,不深入技术原理,只会一笔带过,不然文章会很冗长。

1. Network namespace

我们知道两个POD的网络相互隔离,实际在操作系统中是通过命名空间实现的。

Network namespace用于支持网络协议栈的多个实例。通过对网络资源的隔离,就能在一个宿主机上虚拟出多个不同的网络环境。docker利用NS实现了不同容器的网络隔离。 Network namespace可以提供独立的路由表和iptables来设置包转发、nat以及ip包过滤等功能,提供完整且独立的协议栈。

1
2
3
4
## 创建一个新的网络命名空间
sudo ip netns add my_namespace
## 进入my_namespace的内部 shell 界面
sudo ip netns exec my_namespace bash

2. veth设备对

那如何我们如何为两个不同命名空间下的进程之间实现通信呢?

可以通过引入Veth设备对,Veth设备都是成对出现的,其中一端成为另一端的peer,在Veth设备的一端发送数据时,会将数据发送到另一端,并触发接收数据的操作。

Read more...

【问题大排查】通用Linux环境的网络排障(部分包含容器环境)

因为最近一段时间,一直在处理各种网路问题,所以痛定思痛从头梳理一般运维环境下的网络状况

网络不通(持续性)

这个情况没啥好说的,只要不是 DNS 问题,就是服务器挂掉或者端口被禁

端口监听挂掉

如果容器内的端口已经没有进程监听了,内核就会返回 Reset 包,客户端就会报错连接被拒绝,可以进容器 netns 检查下端口是否存活:

1
netstat -tunlp

iptables 规则问题

检查报文是否有命中丢弃报文的 iptables 规则:

1
2
3
4
5
iptables -t filter -nvL
iptables -t nat -nvL
iptables -t raw -nvL
iptables -t mangle -nvL
iptables-save
Read more...

【深度解析】Kube Proxy如何监听Service和Endpoint以及更新策略规则

本文会探讨Kubernetes另一个核心网络组件Kube-Proxy,它承担着Service及其后端Pod对宿主机配置的影响。

一、 先聊一下三个核心API

这三个API在不同版本下的Kube-Proxy发挥着主要作用,尤其是后两者。先上几个三个资源的常用配置一步步展开。

1. Service

Service作用核心其实就是提供一个ClusterIP和域名的配置容器以及EP/EPS组织,并没有一个单独的controller进行管理,而是被endpointslice-controller所控制。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: default
  labels:
    app: my-app
  annotations:
    description: "This is a demo service"
spec:
  selector:
    app: my-app
    tier: backend
  type: ClusterIP
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      name: http
  ## 粘性会话,一般用于长连接并且开启ClusterIP的场景
  sessionAffinity: None
  ## Cluster和Local,默认前者,后者用于本地流量请求
  ## 例如说,在Node1的PodA请求ServiceB,只能路由到Node1的ServiceB的Pod地址,如果本地没有则无法请求,报文会被iptables drop掉
  externalTrafficPolicy: Cluster
  ## 控制NotReady的Pod是否要包含进Service,为true的话有可能导致流量损失
  publishNotReadyAddresses: false
  ipFamilyPolicy: SingleStack
  ipFamilies:
    - IPv4
  healthCheckNodePort: 30009

2. Endpoints、EndpointSlice

EndpointSlice是在k8s 1.19版本开始默认支持的,相较于Endpoints能支持更大规模部署,受限于etcd的value值大小,ep即一个Service只能部署6000个节点, 而eps理论上可以无上限,并且eps支持网络拓扑,它可以根据集群节点的资源信息,按需部署Pod数量。具体文档在这K8s文档-EndpointSlice

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  annotations:
    ## 每一次Service或Pod改动都会update这个字段
    endpoints.kubernetes.io/last-change-trigger-time: "2022-08-19T03:32:20Z"
  generateName: python-server-headless-
  generation: 27
  labels:
    endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io
    kubernetes.io/service-name: python-server-headless
    service.kubernetes.io/headless: ""
  name: python-server-headless-5xvm5
  namespace: net-test
  ownerReferences:
    - apiVersion: v1
      blockOwnerDeletion: true
      controller: true
      kind: Service
      name: python-server-headless
      uid: fb7d24b3-c7cb-4b1a-8bc2-7caf2cb32101
  resourceVersion: "6538663"
  uid: d7475629-ac4f-46bc-9aeb-479417162ec3
addressType: IPv4
endpoints:
- addresses:
  - 10.100.58.221
  conditions:
    ready: true
    serving: true
    terminating: false
  nodeName: k8s-node02
  ## 控制器基本上靠着这些信息对eps进行增删改查
  targetRef:
    kind: Pod
    name: python-server-65b886d59c-nnktx
    namespace: net-test
    uid: b3cf8828-5311-44cc-b9b1-6e8165f793f4
ports:
  - name: ""
    port: 80
    protocol: TCP

二、Kube-Proxy的源码分析

首先我们还是需要先认识一下Kube-Proxy的整体架构:

  • cmd/kube-proxy/app/server.go 这是程序主入口,对宿主机的参数和启动参数进行注入
    • cmd/kube-proxy/app/server_linux.go 对应不同编译平台的代码,这里会继续设置部分协议栈的一些配置,如nf_conntrack、iptables等
      • 这里就会应用到pkg/proxy中的各种 Proxy 创建器,根据不同设置有对应的代理
        • pkg/proxy/iptables/proxier.go
        • pkg/proxy/ipvs/proxier.go
      • pkg/util/async/bounded_frequency_runner.go 这是控制更新iptables/ipvs的核心组件,可以自定义更新的频率窗口
      • 两个资源的同步器,被绑定在infomer的回调函数上,用来存储监听到的缓存
        • pkg/proxy/endpointschangetracker.go
        • pkg/proxy/servicechangetracker.go

下面是kube-proxy的代码主流程,没有太复杂的内容

kube-proxy.png

Read more...