cilium-chain和ClusterIP

概述

Cilium v1.14.4 默认安装不会设置 kubeProxyReplacement 参数,默认情况下只会开启 ClusterIP,也就是可以部分支持 Service 的功能,如果还需要 NodePort 功能,还需要单独设置。

# helm get values cilium
USER-SUPPLIED VALUES:
cni:
  chainingMode: generic-veth
  configMap: cni-configuration
  customConf: true
enableIPv4Masquerade: false
k8sServiceHost: 192.168.1.200
k8sServicePort: 6443
routingMode: native

本文主要分析 Cilium 是如何实现 ClusterIP 功能,以及分析 Flannel 结合 cilium-chain 下,ClusterIP 是如何于其他 CNI 合作。

配置信息

查看 cilium-agent 内部的一些信息(省略了跟Service无关的部分)。

# cilium status --verbose
Kubernetes:             Ok   1.20 (v1.20.3) [linux/amd64]
KubeProxyReplacement:   False
CNI Chaining:           generic-veth
Cilium:                 Ok   1.14.4 (v1.14.4-87dd2b64)
IPAM:                   IPv4: 1/254 allocated from 10.0.2.0/24,
KubeProxyReplacement Details:
  Status:                 False
  Socket LB:              Disabled
  Socket LB Tracing:      Disabled
  Socket LB Coverage:     Full
  Session Affinity:       Disabled
  Graceful Termination:   Enabled
  NAT46/64 Support:       Disabled
  Services:
  - ClusterIP:      Enabled
  - NodePort:       Disabled
  - LoadBalancer:   Disabled
  - externalIPs:    Disabled
  - HostPort:       Disabled
BPF Maps:   dynamic sizing: on (ratio: 0.002500)
  Name                          Size
  Auth                          524288
  Non-TCP connection tracking   65536
  TCP connection tracking       131072
  Endpoint policy               65535
  IP cache                      512000
  IPv4 masquerading agent       16384
  IPv6 masquerading agent       16384
  IPv4 fragmentation            8192
  IPv4 service                  65536
  IPv6 service                  65536
  IPv4 service backend          65536
  IPv6 service backend          65536
  IPv4 service reverse NAT      65536
  IPv6 service reverse NAT      65536
  Metrics                       1024
  NAT                           131072
  Neighbor table                131072
  Global policy                 16384
  Session affinity              65536
  Sock reverse NAT              65536
  Tunnel                        65536

代码框架

cilium-agent 会 watch Kubernetes 关于 Service/Endpoint/EndpointSlice 等资源,然后根据这些资源的变化,对 eBPF 的 Service LB 的 Map 做 CRUD。

d.k8sWatcher.RunK8sServiceHandler()                         //daemon/cmd/daemon.go
|-k8s.UpdateService                                         //pkg/k8s/watchers/watcher.go
|-K8sWatcher.addK8sSVCs                                     //pkg/k8s/watchers/watcher.go
|-k.svcManager.UpsertService(p)                             //pkg/k8s/watchers/watcher.go
  |-s.upsertService(params)                                 //pkg/service/service.go
  |-s.upsertServiceIntoLBMaps                               //pkg/service/service.go
  |-s.lbmap.AddBackend                                      //pkg/service/service.go
    |-LBBPFMap.AddBackend                                   //pkg/maps/lbmap/lbmap.go
    |-updateBackend                                         //pkg/maps/lbmap/lbmap.go
    |-backend.Map().OpenOrCreate()                          //pkg/maps/lbmap/lbmap.go
  |-s.lbmap.UpsertService(p)                                //pkg/service/service.go
    |-upsertServiceProto                                    //pkg/maps/lbmap/lbmap.go
    |-LBBPFMap.UpsertService                                //pkg/maps/lbmap/lbmap.go
    |-updateServiceEndpoint                                 //pkg/maps/lbmap/lbmap.go
      |-Update                                              //pkg/bpf/map_linux.go
       |- Update                                            //vendor/github.com/cilium/ebpf/map.go
        |- MapUpdateElem
          |- BPF(cmd Cmd, attr unsafe.Pointer, size uintptr)
            |- unix.Syscall(unix.SYS_BPF, uintptr(cmd), uintptr(attr), size) //系统调用

Service IP到Pod IP

这里的 Pod IP 是指 Service 关联的 Endpoint,也可以理解成是 Service 的后端 Pod IP。

// bpf/bpf_lxc.c

测试案例

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: kube-system
  name: nm-test
spec:
  selector:
    matchLabels:
      app: nm-test
  template:
    metadata:
      labels:
        app: nm-test
    spec:
      nodeSelector:
        kubernetes.io/os: linux
        os-type: openeuler
        kubernetes.io/hostname: 10.189.212.124
      containers:
        - name: nm-test
          image: runzhliu/network-multitool:latest
          command: ["/bin/bash", "-c", "sleep infinity"]
          securityContext:
            privileged: true
EOF

可用范围

从上面的分析可以知道,Cilium 之所以声称可以完全的 kube-proxy free,是因为 cilium-agent 在节点层面上,维护了一个 lbMap 的结构,这个结构会将 Service 的 ClusterIP 和后端的 Endpoint 的 IP 完成映射,并且一直会 watch 整个集群内部的 Service 等相关的资源的变化情况。

因此在没有部署 cilium-agent 的节点上,也包括 Kubernetes 集群外,Service 的 ClusterIP 是无法使用的,因为节点上没有相关的 lbMap 结构来完成 Service IP 到 Endpoint 的映射。

另外关于一些开源组件的 webhook 等应用,在当前我们的 Kubernetes 架构上也无法直接使用,本质原因是我们集群的 kube-apiserver 是独立部署,而不是用静态 Pod 这些形式搭建的,也就是说 kube-apiserver 的节点上,同样是没有 cilium-agent,因此如果需要使用 webhook 等功能,还是需要像之前的集群那样,通过注册 VGW 等形式曲线实现。

img.png

总结

cilium-chain 的 ClusterIP 的实现跟 Cilium 本身没有本质的区别,区别主要是在于后端绑定的 Pod IP 是 cilium-chain 的主网卡还是 Cilium 自行创建的。

参考资料

  1. Cilium相关命令解读
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、基础环境准备: 创建nfs后端存储: root@ha1:~# apt install nfs-server r...
    wys阅读 437评论 0 0
  • kube-proxy是管理service的访问入口,包括集群内Pod到Service的访问和集群外访问servic...
    程序员札记阅读 2,081评论 0 2
  • 一、K8S简介: Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes...
    RuiZhi_L阅读 2,112评论 0 0
  • 二、Kubernetes和其网络实现 2.1 kubernetes 基础 单主机容器不能满足性能、高可靠、...
    NEOLV阅读 896评论 0 1
  • 简述ETCD及其特点? etcd 是 CoreOS 团队发起的开源项目,是一个管理配置信息和服务发现(servic...
    成浅阅读 364评论 0 1