本文档介绍如何配置 GKE on Bare Metal,为您的 pod 提供多个网络接口(多 NIC)。pod 的多 NIC 功能可以帮助分离控制平面流量和数据平面流量,从而在层面之间创建隔离。额外的网络接口还可以支持 pod 的多播功能。用户集群、混合集群和独立集群均支持 pod 的多 NIC 功能。管理员类型集群不允许使用该功能。
网络层面隔离对使用网络功能虚拟化 (NFV) 的系统非常重要,这包括广域网 (SD-WAN) 中的软件定义网络、云访问安全代理 (CASB) 和下一代防火墙 (NG-FW)。这些类型的 NFV 依赖于对多个接口的访问,以使管理和数据平面在作为容器运行时保持隔离。
多网络接口配置支持将网络接口与节点池相关联,从而提供性能优势。集群可以包含混合的节点类型。将高性能机器分组到一个节点池中时,您可以向节点池添加其他接口以改善流量。
设置多个网络接口
通常,为 pod 设置多个网络接口包括三个步骤:
使用集群自定义资源中的
multipleNetworkInterfaces
字段为集群启用多 NIC。使用
NetworkAttachmentDefinition
自定义资源指定网络接口。使用
k8s.v1.cni.cncf.io/networks
注解向 pod 分配网络接口。
我们还提供更多信息,帮助您以最符合您的网络要求的方式配置和使用多 NIC 功能。
启用多 NIC
如需为 pod 启用多 NIC,请将 multipleNetworkInterfaces
字段添加到集群自定义资源的 clusterNetwork
部分并将其设置为 true
。
...
clusterNetwork:
multipleNetworkInterfaces: true
pods:
cidrBlocks:
- 192.168.0.0/16
services:
cidrBlocks:
- 10.96.0.0/20
...
指定网络接口
使用 NetworkAttachmentDefinition
自定义资源指定其他网络接口。NetworkAttachmentDefinition
自定义资源对应于可用于您的 Pod 的网络。您可以在集群配置中指定自定义资源(如以下示例所示),也可以直接创建 NetworkAttachmentDefinition
自定义资源。
---
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
name: my-cluster
namespace: cluster-my-cluster
spec:
type: user
clusterNetwork:
multipleNetworkInterfaces: true
...
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: gke-network-1
namespace: cluster-my-cluster
spec:
config: '{
"cniVersion":"0.3.0",
"type": "ipvlan",
"master": "enp2342", # defines the node interface that this pod interface would
map to.
"mode": "l2",
"ipam": {
"type": "whereabouts",
"range": "172.120.0.0/24"
}
}'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: gke-network-2
namespace: cluster-my-cluster
spec:
config: '{
"cniVersion":"0.3.0",
"type": "macvlan",
"mode": "bridge",
"master": "vlan102",
"ipam": {
"type": "static",
"addresses": [
{
"address": "10.10.0.1/24",
"gateway": "10.10.0.254"
}
],
"routes": [
{ "dst": "192.168.0.0/16", "gw": "10.10.5.1" }
]
}
}'
在集群配置文件中指定 NetworkAttachmentDefinition
自定义资源时,GKE on Bare Metal 会使用此名称在集群创建后控制 NetworkAttachmentDefinition
自定义资源。GKE on Bare Metal 将集群命名空间内的此自定义资源视为可靠来源,并使其与目标集群的 default
命名空间保持一致。
下图说明了 GKE on Bare Metal 如何将特定于集群的命名空间中的 NetworkAttachmentDefinition
自定义资源与 default
命名空间协调。
虽然这是可选项,但我们建议您在集群创建期间以这种方式指定 NetworkAttachmentDefinition
自定义资源。在集群创建期间指定自定义资源时,用户集群将受益最大,因为您可以从管理员集群控制 NetworkAttachmentDefinition
自定义资源。
如果您选择在集群创建期间不指定 NetworkAttachmentDefinition
自定义资源,则可以之后将 NetworkAttachmentDefinition
自定义资源直接添加到现有目标集群。GKE on Bare Metal 与集群命名空间中定义的 NetworkAttachmentDefinition
自定义资源协调。在执行删除操作时也会进行协调。从集群命名空间中移除 NetworkAttachmentDefinition
自定义资源时,GKE on Bare Metal 会从目标集群中移除自定义资源。
将网络接口分配给 pod
使用 k8s.v1.cni.cncf.io/networks
注解为 pod 分配一个或多个网络接口。每个网络接口都使用命名空间和 NetworkAttachmentDefinition
自定义资源的名称指定,并以正斜杠 (/
) 分隔。
---
apiVersion: v1
kind: Pod
metadata:
name: samplepod
annotations:
k8s.v1.cni.cncf.io/networks: NAMESPACE/NAD_NAME
spec:
containers:
...
替换以下内容:
NAMESPACE
:命名空间。对于默认命名空间请使用default
,这是标准选项。如需了解例外情况,请参阅安全考量。NAD_NAME
:NetworkAttachmentDefinition
自定义资源的名称。
使用英文逗号分隔列表来指定多个网络接口。
在以下示例中,为 samplepod
Pod 分配了两个网络接口。网络接口由目标集群默认命名空间中的两个 NetworkAttachmentDefinition
自定义资源 gke-network-1
和 gke-network-2
的名称指定。
---
apiVersion: v1
kind: Pod
metadata:
name: samplepod
annotations:
k8s.v1.cni.cncf.io/networks: default/gke-network-1,default/gke-network-2
spec:
containers:
...
将网络接口限制为 NodePool
使用 k8s.v1.cni.cncf.io/nodeSelector
注解指定 NetworkAttachmentDefinition
自定义资源对其有效的节点池。GKE on Bare Metal 强制将引用此自定义资源的任何 Pod 部署到这些特定节点上。在以下示例中,GKE on Bare Metal 会强制部署将 gke-network-1
网络接口分配给 multinicNP
节点池的所有 Pod。GKE on Bare Metal 相应地使用 baremetal.cluster.gke.io/node-pool
标签标记节点池。
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
annotations:
k8s.v1.cni.cncf.io/nodeSelector: baremetal.cluster.gke.io/node-pool=multinicNP
name: gke-network-1
spec:
...
您可以使用标准标签以外的标签。您可以通过向节点应用自定义标签,从集群节点创建自己的自定义池。使用 kubectl label nodes
命令应用自定义标签:
kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE
替换以下内容:
NODE_NAME
:您要为其添加标签的节点的名称。LABEL_KEY
:要用于标签的键。LABEL_VALUE
:标签名称。
标记节点后,对该节点应用 baremetal.cluster.gke.io/label-taint-no-sync
注解,以防止 GKE on Bare Metal 协调标签。使用 kubectl get nodes --show-labels
命令验证是否已为节点添加标签。
安全考量
NetworkAttachmentDefinition
自定义资源提供对网络的完整访问权限,因此集群管理员在向其他用户提供创建、更新或删除权限时必须小心谨慎。如果必须隔离指定的 NetworkAttachmentDefinition
自定义资源,则可以将其放在非默认命名空间中,只有该命名空间中的 pod 才能访问它。对于集群配置文件中指定的 NetworkAttachmentDefinition
自定义资源,它们将始终放在默认命名空间中以供协调。
在下图中,default
命名空间中的 pod 无法访问 privileged
命名空间中的网络接口。
支持的 CNI 插件
本部分列出了 GKE on Bare Metal 的多 NIC 功能支持的 CNI 插件。在指定 NetworkAttachmentDefinition
自定义资源时,请仅使用以下插件。
接口创建:
ipvlan
macvlan
bridge
sriov
Meta 插件:
portmap
sbr
tuning
IPAM 插件:
host-local
static
whereabouts
路由配置
具有一个或多个已分配 NetworkAttachmentDefinition
自定义资源的 Pod 具有多个网络接口。在这种情况下,路由表默认仅通过已分配 NetworkAttachmentDefinition
自定义资源中本地可用的其他接口进行扩展。默认网关仍配置为使用 pod 的主/默认接口 eth0
。
您可以使用以下 CNI 插件修改此行为:
sbr
static
whereabouts
例如,您可能希望所有流量都通过默认网关和默认接口。但是,某些特定流量会经过一个非默认接口。根据目标 IP(正常路由)可能难以区分流量,因为这两种接口类型上的可用端点是同一个。在这种情况下,基于来源的路由 (SBR) 将能够发挥作用。
SBR 插件
sbr
插件可让应用控制路由决策。应用可以控制其建立的连接的来源 IP 地址。如果应用选择使用 NetworkAttachmentDefinition
自定义资源的 IP 地址作为其来源 IP 地址,则数据包会到达 sbr
设置的额外路由表。sbr
路由表将 NetworkAttachmentDefinition
自定义资源的接口指定为默认网关。该表中的默认网关 IP 由 whereabouts
或 static
插件中的 gateway
字段控制。将 sbr
插件作为链式插件提供。如需详细了解 sbr
插件(包括使用方法信息),请参阅基于来源的路由插件。
以下示例显示了 whereabouts
中设置的 "gateway":"21.0.111.254"
,以及 ipvlan
之后设置为链式插件的 sbr
:
# ip route
default via 192.168.0.64 dev eth0 mtu 1500
192.168.0.64 dev eth0 scope link
# ip route list table 100
default via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1
static 插件和 whereabouts 插件
whereabouts
插件基本上是 static
插件的扩展,二者共享路由配置。如需查看配置示例,请参阅静态 IP 地址管理插件。您可以定义要添加到 pod 的路由表的网关和路由。但是,您无法以这种方式修改 pod 的默认网关。
以下示例展示了如何在 NetworkAttachmentDefinition
自定义资源中添加 "routes": [{ "dst": "172.31.0.0/16" }]
:
# ip route
default via 192.168.0.64 dev eth0 mtu 1500
172.31.0.0/16 via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1
192.168.0.64 dev eth0 scope link
配置示例
本部分说明了多 NIC 功能支持的一些常见网络配置。
多个 pod 使用一个网络连接
一个 pod 使用多个网络连接
多个网络连接指向一个 pod 使用的同一接口
一个 pod 多次使用同一网络连接
问题排查
如果额外的网络接口配置有误,则它们分配到的 pod 将不会启动。本部分重点介绍如何查找信息以排查多 NIC 功能的问题。
检查 pod 事件
Multus 通过 Kubernetes pod 事件报告故障。使用以下 kubectl describe
命令查看一个给定 pod 的事件:
kubectl describe pod POD_NAME
检查日志
对于每个节点,您可以在以下位置找到 Whereabouts 和 Multus 日志:
/var/log/whereabouts.log
/var/log/multus.log
检查 pod 接口
使用 kubectl exec
命令检查 pod 接口。成功应用 NetworkAttachmentDefinition
自定义资源后,Pod 接口应如下所示:
$ kubectl exec samplepod-5c6df74f66-5jgxs -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: net1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
link/ether 00:50:56:82:3e:f0 brd ff:ff:ff:ff:ff:ff
inet 21.0.103.112/21 scope global net1
valid_lft forever preferred_lft forever
38: eth0@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 36:23:79:a9:26:b3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.2.191/32 scope global eth0
valid_lft forever preferred_lft forever
获取 pod 状态
使用 kubectl get
检索给定 pod 的网络状态:
kubectl get pods POD_NAME -oyaml
以下示例输出显示了具有多个网络的 pod 的状态:
apiVersion: v1
kind: Pod
metadata:
annotations:
k8s.v1.cni.cncf.io/network-status: |-
[{
"name": "",
"interface": "eth0",
"ips": [
"192.168.1.88"
],
"mac": "36:0e:29:e7:42:ad",
"default": true,
"dns": {}
},{
"name": "default/gke-network-1",
"interface": "net1",
"ips": [
"21.0.111.1"
],
"mac": "00:50:56:82:a7:ab",
"dns": {}
}]
k8s.v1.cni.cncf.io/networks: gke-network-1