知其然
问题背景
因项目现场的网络正逐步从IPv4向IPv6迁移,这几年现场服务器基本上都配置了双栈;但随着IPv6铺开,出现了很多纯IPv6的服务器,并且要求通信优先使用IPv6。
在项目建设之初,其实就考虑了上述情况,所以在部署Kubernetes集群的时候,就将集群配置为了支持IPv4和IPv6双栈。正因如此,前几天用户要求完全切换到IPv6,Pod内部服务连接外网IPv6的时候,发现竟然无法连通。
问题定位
1、问题表现:(1)IPv4在本地局域网(单个L2网络)和跨网均正常;(2)IPv6在本地局域网(单个L2网络)正常和跨网通信异常;
2、开始以为是现场IPv6网络策略导致的不通,用户协助定位发现,目标主机抓包报文(来自Pod内服务请求)头部中的源IP地址竟然是Pod内的虚拟IPv6,并未进行NAT转换。
3、那么,显然就是Kubernetes集群使用的网络组件的问题了;我们使用的是Calico,查看了Calico的启动配置YAML文件(超级多内容)一时也未发现问题在哪。但是,想来应该跟overlay网络配置有关系。
4、既然无法在已有配置中直接发现问题,那么,不如直接在网上直接搜索:Calico IPv6支持。没准能发现蛛丝马迹。最后证明这个思路是对的。
问题解决和验证
上面查找到的蛛丝马迹就是:CALICO_IPV6POOL_VXLAN、CALICO_IPV6POOL_NAT_OUTGOING;
1、查看Calico IP池的信息
~]# kubectl get ippools
NAME AGE
default-ipv4-ippool 15h
default-ipv6-ippool 15h
2、查看跟IPv6相关的地址池配置信息
~]# kubectl get ippools default-ipv6-ippool -o yaml
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
……
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 122
cidr: fa00:cafe:42::/56
ipipMode: Never
nodeSelector: all()
vxlanMode: Never
ipipMode和vxlanMode均为Never,并且也没有natOutgoing(默认为false)相关配置。
3、如下图修改Calico启动配置文件,增加红色部分配置(通过命令kubectl edit ds -n kube-system calico-node,在线编辑增加配置,calico-node重启后并没有生效,ippools中的vxlanMode仍然为Never,也无natOutgoing)
4、重新部署Calico
kubectl delete -f calico.yaml
kubectl apply -f calico.yaml
5、验证是否生效
~]# kubectl get ippools default-ipv6-ippool -o yaml
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
……
spec:
……
natOutgoing: true
vxlanMode: CrossSubnet
~]# ip6tables-save -t nat|grep -i cali
:cali-PREROUTING - [0:0]
:cali-fip-dnat - [0:0]
:cali-POSTROUTING - [0:0]
:cali-fip-snat - [0:0]
:cali-nat-outgoing - [0:0]
:cali-OUTPUT - [0:0]
-A PREROUTING -m comment --comment "cali:6gwbT8clXdHdC1b1" -j cali-PREROUTING
-A POSTROUTING -m comment --comment "cali:O3lYWMrLQYEMJtB5" -j cali-POSTROUTING
-A OUTPUT -m comment --comment "cali:tVnHkvAo15HuiPy0" -j cali-OUTPUT
-A cali-PREROUTING -m comment --comment "cali:r6XmIziWUJsdOK6Z" -j cali-fip-dnat
-A cali-POSTROUTING -m comment --comment "cali:Z-c7XtVd2Bq7s_hA" -j cali-fip-snat
-A cali-POSTROUTING -m comment --comment "cali:nYKhEzDlr11Jccal" -j cali-nat-outgoing
-A cali-POSTROUTING -o vxlan-v6.calico -m comment --comment "cali:MtS-9OgAQy-fAM-w" -m addrtype ! --src-type LOCAL --limit-iface-out -m addrtype --src-type LOCAL -j MASQUERADE --random-fully
-A cali-nat-outgoing -m comment --comment "cali:Ir_z2t1P6-CxTDof" -m set --match-set cali60masq-ipam-pools src -m set ! --match-set cali60all-ipam-pools dst -j MASQUERADE --random-fully
-A cali-OUTPUT -m comment --comment "cali:GBTAv2p5CwevEyJm" -j cali-fip-dnat
6、进入到Pod内部测试,问题解决。
知其所以然
Calico 3.x版本常用命令
kubectl get networkpolicies
:列出所有的网络策略。kubectl get ipamblocks
:列出所有的IP地址块。kubectl get ipamhandles
:列出所有的IP地址分配。kubectl get felixconfigurations
:列出所有的Felix配置。kubectl get ippools
:列出所有的IP地址池配置。kubectl -n kube-system logs -l k8s-app=calico-node
:Calico 日志查看kubectl delete pod -n kube-system -l k8s-app=calico-node
:重启 Calico Felix 容器以应用更改kubectl get pods -n kube-system -l k8s-app=calico-node -o wide
:查看已经安装并启用了 Calicokubectl get configmap calico-config -n kube-system -o yaml
:获取Calico配置的ConfigMap配置kubectl describe configmap calico-config -n kube-system
:获取calico-config
ConfigMap 的详细信息kubectl get felixconfiguration default -n kube-system -o yaml
:获取 Calico 的默认配置信息
Calico 网络组件介绍
Calico 是一个开源的网络和网络安全解决方案,专为容器、虚拟机和裸机工作负载设计。它使用 BGP(边界网关协议)来路由流量,支持多种网络模式,包括纯三层模式和覆盖网络模式。
Calico 的主要组件包括:
-
calico-node:运行在每个节点上,负责设置路由、管理 IP 地址,并通过 Felix 实现网络策略的执行。
-
BGP Daemon (Bird):负责节点之间的路由传播,以实现不同节点 Pod 之间的流量路由。
-
Felix:作为 Calico 的主代理,负责监控 etcd 中存储的网络策略并将其应用于节点的网络接口,同时负责设置 IP 路由、管理 ACLs 以确保流量符合策略。
-
Typha:当节点数较多时,可以通过 Typha 组件来减少 etcd 的访问负载。它会将 etcd 中的策略变化缓存起来,并同步给每个节点的 Felix 代理。
-
etcd:Calico 使用 etcd 作为存储后端,用于存储网络策略、IP 池等配置。也可以使用 Kubernetes 的 API Server 作为存储后端,便于集成。
Calico的backend类型
calico_backend:Calico的后端,默认为bird。
kubectl get configmap calico-config -n kube-system -o yaml
apiVersion: v1
data:
calico_backend: bird
cni_network_config: |-
{
……
类型 | 说明 |
---|---|
bird | BIRD是一种路由守护进程,Calico使用BIRD来实现路由功能。BIRD支持多种路由协议,包括BGP,可以用于在Calico节点之间分发路由信息。 |
vxlan | VXLAN(Virtual Extensible LAN)是一种网络虚拟化技术,用于在不同子网之间封装数据包。Calico支持VXLAN封装方式,适用于云环境受限场景。ipip模式转vxlan:将calico_backend参数由bird 设置为vxlan ,因为vxlan部署不使用bgp。 |
ipip | IP-in-IP是一种封装协议,用于在不同子网之间封装数据包。Calico支持IP-in-IP封装方式,适用于跨子网的场景。 |
Calico doesn't support tunneling for the IPv6, so "vxlan" and "ipip" backend wouldn't work. If you need to have cross-pod connectivity, you need to use "bird" as a backend mode. In any other mode the pods would be able to reach only pods on the same node.
Calico不支持IPv6隧道,所以“vxlan”和“ipip”后端不能工作。如果您需要跨pod连接,则需要使用“bird”作为后端模式。在任何其他模式下,pod都只能到达同一节点上的pod。
----引用自《IPv4/IPv6 Dual-Stack Networking - Documentation》
根据 Calico 的官方文档,Calico 的 IPIP 模式目前只支持 IPv4,不支持 IPv6。如果你的环境需要 IPv6 的隧道封装,建议使用 Calico 提供的 VXLAN 模式。
----来自于ChatGPT的回答
BGP
BGP(边界网关协议)是用于跨网络共享路由的基于标准的网络协议。它是互联网的基本组成部分之一,具有出色的扩展特性。
Calico内置了对BGP的支持。在本地部署中,这使Calico可以与物理网络(通常连接到Top或Rack路由器)建立对等关系以交换路由,从而形成一个none-overlay网络,其中Pod IP地址可以在更广泛的网络中路由,就像附加的任何其他工作负载一样到网络。
Overlay网络模式
Calico可以提供VXLAN或IP-in-IP网络,包括cross-subnet模式。
Non-overlay网络模式
Calico可以提供在任何基础L2网络之上运行的non-overlay网络,或者是具有适当的云提供商集成的公共云网络或支持BGP的L3网络(通常是具有标准Top-of-Rack路由器)。
Calico本地部署
Calico本地部署最常见的网络设置是non-overlay模式,该模式使用BGP与物理网络(通常是机架路由器的顶部)对等,以使Pod IP可在集群外部路由。(当然,可以根据需要配置其余的本地部署网络,以限制群集外的Pod IP路由的范围。)此设置提供了丰富的Calico高级功能,包括公告Kubernetes serviceIP的能力(cluster IPs or external IPs),以及在Pod,名称空间或节点级别控制IP地址管理的能力,以支持与现有企业网络和安全要求集成的各种可能性。
注:在这种模式下,物理路由器需要进行相应的配置,以便与 Calico 节点建立 BGP 对等关系。具体来说,物理路由器需要配置 BGP 对等体,指向 Calico 节点的 IP 地址,并设置相应的自治系统号(AS 号)。这样,物理路由器就可以接收来自 Calico 节点的 BGP 路由信息,并将这些路由信息传播到整个物理网络中
Policy | IPAM | CNI | Overlay | Routing |
---|---|---|---|---|
Calico | Calico | Calico | No | BGP |
如果不能将BGP对等连接到物理网络,并且群集在单个L2网络中,则还可以运行non-overlay模式,而Calico只能在群集中的节点之间对等BGP。即使这不是严格的overlay网络,也无法在集群外部路由Pod IP,因为基础网络没有Pod IP的路由。
Policy | IPAM | CNI | Overlay | Routing |
---|---|---|---|---|
Calico | Calico | Calico | No | BGP |
或者,可以在VXLAN或IP-in-IP模式下运行Calico,并使用cross-subnet模式来优化每个L2子网内的性能。
推荐方案:
Policy | IPAM | CNI | Overlay | Routing |
---|---|---|---|---|
Calico | Calico | Calico | VXLAN | Calico |
替代方案:
Policy | IPAM | CNI | Overlay | Routing |
---|---|---|---|---|
Calico | Calico | Calico | IPIP | BGP |