容器網路Cilium:DualStack雙棧特性分析

2023-12-15 12:00:09

本文分享自華為雲社群《容器網路Cilium入門系列之DualStack雙棧特性分析》,作者: 可以交個朋友。

一 、 關於IPV6/IPV4 雙棧

目前很多公司開始將自己的業務由ipv4切換成ipv6,或者ipv4,ipv6共存。

ipv4 ipv6共存(DualStack)有兩種方式:

  • 一個網路卡上有兩個IP地址,一個是ipv4,一個是ipv6。標準實現方式。

  • 兩個同樣功能的網路卡介面,一個提供ipv4,一個提供ipv6。通過負載均衡機制,將對應地址的請求傳送到對應的網路卡。

目前k8s叢集已經支援ipv4/ipv6雙棧,從1.21的alpha版本到如今1.23的stable版本。

同樣cilium cni也對雙棧技術做了實現,是一個inCluster層面的實現,如果資料流量要進出叢集,就需要平臺級的實現。

二 、Cilium DualStack 雙棧環境搭建

依舊是kind快速搭建k8s叢集

#1-setup-env.sh
#! /bin/bash
date
set -v

# 1.prep nocNI env
cat <<EOF |kind create cluster --name=cilium-dual-stack --image=kindest/node:v1.23.4  --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
  disableDefaultCNI: true  #kind 預設使用rancher cni,我們不需要該cni
  ipFamily: dual
nodes:
  - role: control-plane
  - role: worker
  - role: worker

EOF

# 2. remove taints
controller_node=`kubectl get nodes --no-headers -o custom-columns=NAME:.metadata.name |grep control-plane`
kubectl taint nodes $controller_node node-role.kubernetes.io/master:NoSchedule-
kubectl get nodes -owide

# 3.  install cni
helm repo add cilium  https://helm.cilium.io > /dev/null 2>&1
helm repo update > /dev/null  2>&1

helm  install cilium  cilium/cilium --set k8sServiceHost=$controller_node --set k8sServicePort=6443 --version 1.13.0-rc5 \
--namespace kube-system --set debug.enabled=true --set debug.verbose=datapath --set monitorAggregation=none \
--set ipam.mode=kubernetes --set cluster.name=cilium-dual-stack --set tunnel=vxlan  --set kubeProxyReplacement=disabled \
--set ipv6.enabled=true

#4. install necessary tools
for i in $(docker ps -a --format "table {{.Names}}" |grep cilium-dual-stack)
do
                echo $i
                #docker cp ./bridge $i:/opt/cni/bin/
                docker cp /usr/bin/ping $i:/usr/bin/ping
                docker exec -it $i bash -c "sed -i -e  's/jp.archive.ubuntu.com\|archive.ubuntu.com\|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list"
                docker exec -it $i bash -c "apt-get -y update > /dev/null && apt-get -y install net-tools tcpdump lrzsz > /dev/null 2>&1"
done

其中關鍵設定有:

  • ipFamily: dual 建立叢集需要為叢集開啟雙棧設定
  • set kubeProxyReplacement=disabled 雙棧依賴kube-proxy
  • set ipv6.enabled=true ipv4是預設開啟的,ipv6需要手動開啟
  • set tunnel=vxlan vxlan模式下,安裝更簡單

部署demo應用

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  labels:
    app: app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
      - name: nettool
        image: burlyluo/nettool
        securityContext:
          privileged: true

---
apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  ipFamilyPolicy: PreferDualStack
  ipFamilies:
  - IPv6
  - IPv4
  type: ClusterIP
  selector:
    app: app
  ports:
  - name: app
    port: 8080
    targetPort: 80

叢集搭建成功:

image-20230710142021073.png

確認IPv4 IPv6 雙棧啟用成功

Pod:

image-20230710142254444.png

image-20230710142726833.png

image-20230710193525436.png

service:

image-20230710142436797.png

三 、Cilium DualStack 模式分析

IPv4 模式下分析pod內的路由規則

image-20230710145552437.png

pod出網需要經過eth0網路卡,下一跳地址是10.244.1.3,下一跳是宿主機上的cilium_host網路卡

image-20230710150306114.png

IPv6 模式下pod內的路由規則

ip -6 route show

image-20230710190611493.png
它的下一跳所在的地址fd00:10:244:1::20f3 不一定在宿主機的名稱空間裡面,所在在主機上找不到對應的網路卡介面

IPv6模式下的ping測

pod-a IPv6 地址: fd00:10:244:1::89bc

pod-b IPv6 地址: fd00:10:244:2::3573

image-20230710192115503.png

pod內eth0網路卡抓包分析封包

image-20230710192508635.png

源Mac: f2:65:2b:03:4c:22 為源pod的eth0網路卡的mac地址;

IPv6: fd00:10:244:1::89bc 為源pod的IPv6地址

目標IPv6: fd00:10:244:2::3573 為目標pod的IPv6地址

目標Mac: 8a:be:1f:9b:eb:9d 為源pod所在宿主機上的lxc網路卡

image-20230710194219009.png

所以即使在pod內檢視IPv6的路由規則,找不到對應的下一跳位置,也不影響資料包文的封裝。

類似於calico的169.254.1.1,這個地址不一定要有,但是封包往上面發的時候,只要有一個hook能劫持,並且讓其他網路卡回覆對應的mac地址就行了。

這樣在封裝報文的時候,srcMac srcIP,dstMac,dstIP 都具備了,這樣一個封包才能完整的傳送出去。

整個流程差不多就是 根據容器內IPv6的下一跳 抓包找到對應的mac地址,然後根據mac地址的來源做一個推理。

IPv6 的優點

一個封包如果到達IP層才能感知可以丟包,但是IPv6 在二層就能感知到,不是自己的包就可以丟掉。

提供了更多的IP地址,但是複雜性也增加了。

image-20230710201514974.png

service的雙棧

image-20230710203440376.png

fd00:10:96::94f8 為IPv6的clusterIP; 10.96.247.62 為IPv4的clusterIP

可以進入容器進行service 的IPv4和IPv6 地址的解析進行驗證:

image-20230710204552391.png

點選關注,第一時間瞭解華為雲新鮮技術~