7.9 Kubernetes对IPv4和IPv6双栈的支持

随着IPv6的逐渐普及,物联网、边缘计算等行业大量使用IPv6部署各种设备和边缘设备,在Kubernetes中运行的容器和服务也需要支持IPv6。Kubernetes从1.16版本开始引入对IPv4和IPv6双栈的支持,当前为Alpha阶段。

在Kubernetes集群中启用IPv4和IPv6双栈可以提供以下功能。

◎ 为Pod分配一个IPv4地址和一个IPv6地址。

◎ 为Service分配一个IPv4地址或一个IPv6地址,只能使用一种地址类型。

◎ Pod可以同时通过IPv4地址和IPv6地址路由到集群外部(egress)的网络(如Internet)。

为了在Kubernetes集群中使用IPv4和IPv6双栈功能,需要满足以下前提条件。

◎ 使用Kubernetes 1.16及以上版本。

◎ Kubernetes集群的基础网络环境必须支持双栈网络,即提供可路由的IPv4和IPv6网络接口。

◎ 支持双栈的网络插件,例如Calico或Kubenet。

7.9.1 为Kubernetes集群启用IPv4和IPv6双栈

为Kubernetes集群启用IPv4和IPv6双栈功能前,首先需要在kube-apiserver、kube-controller-manager、kubelet和kube-proxy服务中设置启动参数以开启双栈特性,并设置Pod的IP CIDR范围(--cluster-cidr)和Service的IP CIDR范围(--service-cluster-ip-range)。各服务的启动参数设置如下。

(1)kube-apiserver服务。

◎ --feature-gates="...,IPv6DualStack=true":开启IPv6DualStack特性开关。

◎ --service-cluster-ip-range=<IPv4 CIDR>,<IPv6 CIDR>:设置Service的IPv4和IPv6 CIDR地址范围,例如--service-cluster-ip-range=169.169.0.0/16,3000::0/112。

(2)kube-controller-manager服务。

◎ --feature-gates="...,IPv6DualStack=true":开启IPv6DualStack特性开关。

◎ --cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>:设置Pod的IPv4和IPv6 CIDR地址范围,例如--cluster-cidr=10.0.0.0/16,fa00::0/112。

◎ --service-cluster-ip-range=<IPv4 CIDR>,<IPv6 CIDR>:设置Service的IPv4和IPv6 CIDR地址范围,例如--service-cluster-ip-range=169.169.0.0/16,3000::0/112。

◎ --node-cidr-mask-size-ipv4:设置IPv4子网掩码,默认为/24。

◎ --node-cidr-mask-size-ipv6:设置IPv6子网掩码,默认为/64。

(3)kubelet服务。

◎ --feature-gates="...,IPv6DualStack=true":开启IPv6DualStack特性开关。

(4)kube-proxy服务。

◎ --proxy-mode=ipvs:必须使用ipvs代理模式。

◎ --feature-gates="...,IPv6DualStack=true":开启IPv6DualStack特性开关。

◎ --cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>:设置Pod的IPv4和IPv6 CIDR地址范围,例如--cluster-cidr=10.0.0.0/16,fa00::0/112。

为了支持Pod的IPv4和IPv6双栈网络,还需要在Kubernetes集群中部署支持双栈的网络组件(如CNI插件),这里以Calico为例进行说明。Calico对IPv4和IPv6双栈的支持包括以下配置。

(1)在ConfigMap“calico-config”中,CNI网络配置“cni_network_config”的ipam段落增加了assign_ipv4=true和assign_ipv6=true的配置,例如(省略的内容详见7.7.4节的说明):

(2)在容器calico-node的环境变量中新增IPv6的相关配置,例如(省略的内容详见7.7.4节的说明):

其中,CALICO_IPV4POOL_CIDR和CALICO_IPV6POOL_CIDR设置的IP CIDR地址范围应与Kubernetes集群中的设置相同(kube-controller-manager和kube-proxy服务--cluster-cidr参数的设置)。

通过kubectl create命令创建Calico CNI插件后,确保calico-node运行正常:

7.9.2 Pod双栈IP地址验证

在启用了IPv4和IPv6双栈的Kubernetes集群中,根据上述配置,创建的每个Pod都会被CNI插件设置一个IPv4地址和一个IPv6地址。

以下面的Deployment为例:

创建这个Deployment:

查看Pod信息(在kubectl get命令返回的结果中只能看到IPv4地址):

登录容器,通过ip命令查看其IP地址,可以看到系统为其设置的IPv4和IPv6地址:

另外,在/etc/hosts文件中也进行了设置:

下面对通过IPv6地址访问其他容器提供的Web服务进行验证,例如从webapp-67cfbd687f-w6ssb容器内访问Pod webapp-67cfbd687f-tth9v(IPv6地址为fda3:eccf:c536:b27d:668b:ae7f:c66b:41c4)在8080端口号提供的Web服务,访问成功:

7.9.3 Service双栈IP地址验证

对于Service来说,一个Service只能设置IPv4或者IPv6一种IP地址类型,这需要在Service的YAML定义中通过ipFamily字段进行设置。该字段是可选配置,如果不指定,则使用kube-controller-manager服务--service-cluster-ip-range参数设置的第1个IP地址的地址类型。ipFamily字段可以设置的值为“IPv4”或“IPv6”。

下面通过两个不同IP地址类型的Service进行说明。

1)具有IPv4地址的Service

由于在前文中配置的--service-cluster-ip-range的第1个参数为IPv4地址范围(--service-cluster-ip-range=169.169.0.0/16,3000::0/112),所以下面的例子在不指定ipFamily字段的情况下,Kubernetes将为该Service分配IPv4地址:

创建这个Service,可以看到它的IP地址为IPv4地址:

查看Service详情,可以看到它的后端Endpoint的地址也为IPv4地址:

通过Service的IPv4地址访问服务成功:

2)具有IPv6地址的Service

下面的例子指定ipFamily=IPv6,系统将为这个Service分配一个IPv6地址:

创建这个Service,可以看到它的IP地址为IPv6地址:

查看Service详情,可以看到它的后端Endpoint的地址也为IPv6地址:

通过Service的IPv6地址访问服务也是成功的: