Kube-OVN系列 - VPC 的使用

本篇文章介绍 Kube-OVN 中 VPC 的使用,前置的内容可以参考:

VPC 的作用主要是进行租户隔离,想象一个场景,我们在搭建一个云计算平台,有很多厂商想在这个平台上开通虚机来部署自己的应用,这时候我们至少要满足两个需求:

  1. 不同厂商之间的网络是隔离的,如厂商 A 和厂商 B 间网络应该不通;
  2. 厂商的不同应用之间是隔离的,如厂商 A 的应用 1 和 应用 2 网络应该不通;

对于这类需求,我们就可以使用 VPC 和 Subnet 来实现,通过 VPC 实现厂商(租户)间的隔离,通过 Subnet 来实现应用间的隔离(当然有很多灵活的用法)。我们在上一篇介绍 Kube-OVN Subnet 的文章中可以看到,如果我们在创建 Subnet 的时候没有指定 VPC,那该 Subnet 默认会关联上 Kube-OVN 初始化时创建的ovn-cluster VPC,但在例如我们当前举例的云计算平台的场景下,所有租户都使用默认的 VPC 显然是无法达到很好的隔离性的。所以,仅使用默认的ovn-cluster VPC 和 默认的ovn-default Subnet 只能应对一些相对简单的场景,对于更复杂的场景就需要我们对 VPC 和 Subnet 有一个更好的认识,下面就从几个方面简单介绍下 VPC 的功能:

  • VPC 与 Subnet 的隔离性
  • VPC 网关
  • VPC QoS 配置

VPC 与 Sunbet 的隔离性

我们通过两个场景来验证 VPC 和 Subnet 的隔离性:

  • 相同 VPC 间 Sunbet 是否互相隔离
  • 不同 VPC 间 Subnet 是否互相隔离

资源环境准备

首先创建两个 namespace:ns1ns2,将vpc1关联上ns1,而vpc2关联上ns2,通过指明 VPC 和 namespace 的关联关系,可以明确 VPC 仅能被特定的 namespace 使用。

# 创建 namespace
$ kubectl create ns ns1
$ kubectl create ns ns2

# 创建 VPC
$ cat vpc1.yaml
kind: Vpc
apiVersion: kubeovn.io/v1
metadata:
  name: vpc1
spec:
  namespaces:
  - ns1

$ cat vpc2.yaml
kind: Vpc
apiVersion: kubeovn.io/v1
metadata:
  name: vpc2
spec:
  namespaces:
  - ns2

$ kubectl apply -f vpc1.yaml -f vpc2.yaml 

# 可以看到 vpc1 和 vpc2 已经创建成功
$ kubectl get vpc
NAME          ENABLEEXTERNAL   ENABLEBFD   STANDBY   SUBNETS                           NAMESPACES
ovn-cluster   false            false       true      ["join","ovn-default"]
vpc1          false            false       true      []                                ["ns1"]
vpc2          false            false       true      []                                ["ns2"]

然后我们再来创建 Subnet,我们将vpc1-subnet1关联上vpc1,将vpc2-subnet1vpc2-subnet2关联上vpc2

# 创建 vpc1 下的 Subnet
$ cat vpc1-subnet1.yaml
kind: Subnet
apiVersion: kubeovn.io/v1
metadata:
  name: vpc1-subnet1
spec:
  vpc: vpc1
  cidrBlock: 10.1.1.0/24
  protocol: IPv4
  namespaces:
    - ns1

$ kubectl apply -f vpc1-subnet1.yaml

# 创建 vpc2 下的 Subnet
$ cat vpc2-subnet1.yaml
kind: Subnet
apiVersion: kubeovn.io/v1
metadata:
  name: vpc2-subnet1
spec:
  vpc: vpc2
  cidrBlock: 10.2.1.0/24
  protocol: IPv4
  namespaces:
    - ns2
$ cat vpc2-subnet2.yaml
kind: Subnet
apiVersion: kubeovn.io/v1
metadata:
  name: vpc2-subnet2
spec:
  vpc: vpc2
  cidrBlock: 10.2.2.0/24
  protocol: IPv4
  namespaces:
    - ns2

$ kubectl apply -f vpc2-subnet1.yaml -f vpc2-subnet2.yaml

# 查看新建的 3 个 Subnet
$ kubectl get subnet
NAME           PROVIDER   VPC           PROTOCOL   CIDR            PRIVATE   NAT     DEFAULT   GATEWAYTYPE   V4USED   V4AVAILABLE   V6USED   V6AVAILABLE   EXCLUDEIPS       U2OINTERCONNECTIONIP
...
vpc1-subnet1   ovn        vpc1          IPv4       10.1.1.0/24     false     false   false     distributed   0        253           0        0             ["10.1.1.1"]
vpc2-subnet1   ovn        vpc2          IPv4       10.2.1.0/24     false     false   false     distributed   0        253           0        0             ["10.2.1.1"]
vpc2-subnet2   ovn        vpc2          IPv4       10.2.2.0/24     false     false   false     distributed   0        253           0        0             ["10.2.2.1"]

VPC 和 Subnet 都准备好了,现在我们创建 3 个 pod 来验证隔离性。

$ cat vpc1-subnet1-pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    ovn.kubernetes.io/logical_switch: vpc1-subnet1
  namespace: ns1
  name: vpc1-subnet1-pod1
spec:
  containers:
    - name: pod
      image: docker.io/kubeovn/perf

$ cat vpc2-subnet1-pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    ovn.kubernetes.io/logical_switch: vpc2-subnet1
  namespace: ns2
  name: vpc2-subnet1-pod1
spec:
  containers:
    - name: pod
      image: docker.io/library/nginx:alpine

$ cat vpc2-subnet2-pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    ovn.kubernetes.io/logical_switch: vpc2-subnet2
  namespace: ns2
  name: vpc2-subnet2-pod1
spec:
  containers:
    - name: pod2
      image: docker.io/library/nginx:alpine

$ kubectl apply -f vpc1-subnet1-pod1.yaml -f vpc2-subnet1-pod1.yaml -f vpc2-subnet2-pod1.yaml

$ kubectl get po -A -owide
NAMESPACE     NAME                                   READY   STATUS    RESTARTS       AGE   IP              NODE    NOMINATED NODE   READINESS GATES
...
ns1           vpc1-subnet1-pod1                      1/1     Running   0              19s   10.1.1.2        node1   <none>           <none>
ns2           vpc2-subnet1-pod1                      1/1     Running   0              7s    10.2.1.2        node1   <none>           <none>
ns2           vpc2-subnet2-pod1                      1/1     Running   0              7s    10.2.2.2        node2   <none>           <none>

好,现在我们创建好了 3 个 pod,vpc1-subnet1-pod1在单独的 VPC,vpc2-subnet1-pod1vpc2-subnet2-pod1处在相同 VPC 的不同 Subnet。

相同 VPC 间 Subnet 隔离性验证

通过vpc2-subnet1-pod1 ping vpc2-subnet2-pod1,我们可以看到在相同 VPC 下的不同 Subnet 间默认是打通的。

$ kubectl exec -it vpc2-subnet1-pod1 -n ns2 -- ping -c 1 10.2.2.2
PING 10.2.2.2 (10.2.2.2): 56 data bytes
64 bytes from 10.2.2.2: seq=0 ttl=63 time=3.521 ms
--- 10.2.2.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 3.521/3.521/3.521 ms

我们来看一下 Kube-OVN 构建的逻辑上的网络拓扑信息,可以看到 pod vpc2-subnet1-pod1.ns2vpc2-subnet2-pod1.ns2是分别插到 Logic Switch(L2 Network) vpc2-subnet1vpc2-subnet2上的,而这两个 Logic Switch 又是插到同一个 Logic Router(L3 Network) vpc2来打通三层网络的。

$ kubectl ko nbctl show
...
router 84a16ead-547c-4562-bab2-895162bcedfc (vpc2)
    port vpc2-vpc2-subnet2
        mac: "00:00:00:66:EB:29"
        networks: ["10.2.2.1/24"]
    port vpc2-vpc2-subnet1
        mac: "00:00:00:84:47:EB"
        networks: ["10.2.1.1/24"]
switch b6b30649-aeae-4263-84d8-225bd43b6f03 (vpc2-subnet1)
    port vpc2-subnet1-pod1.ns2
        addresses: ["00:00:00:5D:BC:A2 10.2.1.2"]
    port vpc2-subnet1-vpc2
        type: router
        router-port: vpc2-vpc2-subnet1
switch 498bf085-350f-4181-af1f-ef436de353d5 (vpc2-subnet2)
    port vpc2-subnet2-pod1.ns2
        addresses: ["00:00:00:8F:2F:F8 10.2.2.2"]
    port vpc2-subnet2-vpc2
        type: router
        router-port: vpc2-vpc2-subnet2
...

所以,依据这个拓扑信息,可以理解同一 VPC 的不同 Subnet 间默认是可以互通的。
可以设置成不通吗?当然也是可以的,Subnet 提供了 private 的配置项,只要将其设置为 true,则与其它 Subnet 不再互通。

$ kubectl edit subnet vpc2-subnet2
kind: Subnet
apiVersion: kubeovn.io/v1
metadata:
  name: vpc2-subnet2
spec:
  vpc: vpc2
  cidrBlock: 10.2.2.0/24
  protocol: IPv4
  private: true # 修改为 true
  namespaces:
    - ns2

修改完成后通过vpc2-subnet1-pod1 ping vpc2-subnet2-pod1,发现确实不通了。

$ kubectl exec -it vpc2-subnet1-pod1 -n ns2 -- ping -c 1 10.2.2.2
PING 10.2.2.2 (10.2.2.2): 56 data bytes
--- 10.2.2.2 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

当我们将 Subnet 的 private 配置项设置为 true 时,Kube-OVN 会在该 Subnet 关联的 Logic Swtich 上添加对应的 ACL 规则,通过 nbctl 查看具体的规则项,可以看到除 join 100.64.0.0/16vpc2-subnet2 10.2.2.0/24两个网段的包之外,其它的包都被 drop 掉了。所以,同一 VPC 下的不同 Subnet 如果不想互通,可以通过 ACL 来实现。

$ kubectl ko nbctl acl-list vpc2-subnet2
  to-lport  3000 (ip4.src == 100.64.0.0/16) allow-related
  to-lport  1001 (ip4.src == 10.2.2.0/24 && ip4.dst == 10.2.2.0/24) allow-related
  to-lport  1000 (ip) drop log(name=vpc2-subnet2,severity=warning)

不同 VPC 间 Subnet 隔离性验证

按照刚才同一 VPC 的逻辑网络拓扑,我们容易能推断出来不同的 VPC 其实对应不同的 Logic Router,所以在没有经过额外配置的前提下,是无法互通的。

# vpc1 和 vpc2 相当于不同的 Logic Router
$ kubectl ko nbctl show
...
router 3e023a8b-bea2-44c7-bcd4-4e3ed56801a9 (vpc1)
    port vpc1-vpc1-subnet1
        mac: "00:00:00:BA:74:FF"
        networks: ["10.1.1.1/24"]
router 84a16ead-547c-4562-bab2-895162bcedfc (vpc2)
    port vpc2-vpc2-subnet2
        mac: "00:00:00:66:EB:29"
        networks: ["10.2.2.1/24"]
    port vpc2-vpc2-subnet1
        mac: "00:00:00:84:47:EB"
        networks: ["10.2.1.1/24"]

# 通过 vpc2-subnet1-pod1 ping vpc1-subnet1-pod1 无法连通
$ kubectl exec -it vpc2-subnet1-pod1 -n ns2 -- ping -c 1 10.1.1.2
PING 10.1.1.2 (10.1.1.2): 56 data bytes
--- 10.1.1.2 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

当然,Kube-OVN 也提供了机制可以让两个不同的 VPC 互联:

$ kubectl edit vpc vpc1
apiVersion: kubeovn.io/v1
kind: Vpc
spec:
  namespaces:
  - ns1
  staticRoutes:
  - cidr: 10.2.1.0/24
    nextHopIP: 169.254.0.2
    policy: policyDst
  - cidr: 10.2.2.0/24
    nextHopIP: 169.254.0.2
    policy: policyDst
  vpcPeerings:
  - localConnectIP: 169.254.0.1/30
    remoteVpc: vpc2

$ kubectl edit vpc vpc2
apiVersion: kubeovn.io/v1
kind: Vpc
spec:
  namespaces:
  - ns2
  staticRoutes:
  - cidr: 10.1.1.0/24
    nextHopIP: 169.254.0.1
    policy: policyDst
  vpcPeerings:
  - localConnectIP: 169.254.0.2/30
    remoteVpc: vpc1

通过 vpc peering 的配置,可以将两个 VPC 通过逻辑路由的方式打通,使得这两个 VPC 内的 pod 可以直接互访,而不需经过任何 NAT 转发。

$ kubectl exec -it vpc1-subnet1-pod1 -n ns1 -- ping -c 1 10.2.1.2
PING 10.2.1.2 (10.2.1.2): 56 data bytes
64 bytes from 10.2.1.2: seq=0 ttl=62 time=1.351 ms
--- 10.2.1.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.351/1.351/1.351 ms

$ kubectl exec -it vpc1-subnet1-pod1 -n ns1 -- ping -c 1 10.2.2.2
PING 10.2.2.2 (10.2.2.2): 56 data bytes
64 bytes from 10.2.2.2: seq=0 ttl=62 time=2.484 ms
--- 10.2.2.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 2.484/2.484/2.484 ms

$ kubectl exec -it vpc2-subnet1-pod1 -n ns2 -- ping -c 1 10.1.1.2
PING 10.1.1.2 (10.1.1.2): 56 data bytes
64 bytes from 10.1.1.2: seq=0 ttl=62 time=1.385 ms
--- 10.1.1.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 1.385/1.385/1.385 ms

VPC 网关

在上一篇介绍 Kube-OVN Subnet 的文章中,我们有看到对默认的ovn-cluster VPC,其关联的 Subnet 可以通过配置 natOutgoing 来实现对外部网络的访问,但自定义的 VPC 并不支持这种方式。

自定义的 VPC 要访问外部网络的话,需要通过 VPC 网关来实现。

启用 VPC 网关

首先,需要在 Kube-OVN 中启用相关配置:

$ cat config.yaml 
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: ovn-vpc-nat-config
  namespace: kube-system
data:
  image: 'docker.io/kubeovn/vpc-nat-gateway:v1.12.1' 
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: ovn-vpc-nat-gw-config
  namespace: kube-system
data:
  enable-vpc-nat-gw: 'true'

$ kubectl apply -f config.yaml

配置外部网络

然后我们需要配置外部网络,这里的外部网络的网段与你自身的环境有关。在我的场景里,我是一台宿主机192.168.31.182连接到一个路由器192.168.31.1,在宿主机中我通过桥接模式开通了两台虚机192.168.31.29192.168.31.68,我的 Kubernetes + Kube-OVN 的环境是在这两台虚机中搭建的,所以我使用的外部网络是192.168.31.0/24(具体可以参考 Kubernetes + Kube-OVN 环境搭建):

$ cat external-network.yaml 
apiVersion: kubeovn.io/v1
kind: Subnet
metadata:
  name: ovn-vpc-external-network
spec:
  protocol: IPv4
  provider: ovn-vpc-external-network.kube-system
  cidrBlock: 192.168.31.0/24 # 外部网络的网段
  gateway: 192.168.31.1  # 外部网络的物理网关的地址
  excludeIps:
  - 192.168.31.1..192.168.31.100
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: ovn-vpc-external-network
  namespace: kube-system
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "macvlan",
      "master": "enp1s0", # 这里需要修改为自己的物理网卡
      "mode": "bridge",
      "ipam": {
        "type": "kube-ovn",
        "server_socket": "/run/openvswitch/kube-ovn-daemon.sock",
        "provider": "ovn-vpc-external-network.kube-system"
      }
    }'

$ kubectl apply -f external-network.yaml 

执行完成后,可以看到新创建的 Subnet:

$ kubectl get subnet
NAME                       PROVIDER                               VPC           PROTOCOL   CIDR              PRIVATE   NAT     DEFAULT   GATEWAYTYPE   V4USED   V4AVAILABLE   V6USED   V6AVAILABLE   EXCLUDEIPS                                                          U2OINTERCONNECTIONIP
...
ovn-vpc-external-network   ovn-vpc-external-network.kube-system                 IPv4       192.168.31.0/24   false     false   false     distributed   0        250           0        0             ["192.168.31.1","192.168.31.182","192.168.31.29","192.168.31.68"]

创建 VPC 网关 & 配置默认路由

然后再创建 VPC 网关,需要指定关联的 VPC 和 Subnet:

$ cat vpc1-subnet1-gateway.yaml
kind: VpcNatGateway
apiVersion: kubeovn.io/v1
metadata:
  name: vpc1-subnet1-gateway
spec:
  vpc: vpc1
  subnet: vpc1-subnet1
  lanIp: 10.1.1.254
  selector:
    - "kubernetes.io/os: linux"
  externalSubnets:
    - ovn-vpc-external-network

$ kubectl apply -f vpc1-subnet1-gateway.yaml

$ kubectl get po -A -owide
NAMESPACE     NAME                                   READY   STATUS    RESTARTS         AGE     IP              NODE    NOMINATED NODE   READINESS GATES
...
kube-system   vpc-nat-gw-vpc1-subnet1-gateway-0      1/1     Running   0                5s      10.1.1.254      node1   <none>           <none>

这时候我们看到已经拉起了 pod vpc-nat-gw-vpc1-subnet1-gateway-0,该 pod 的 ip 是10.1.1.254,按逻辑推断这个 pod 就应该是作为当前 VPC 的网关,但是当前 VPC 下的业务 pod 还并不知道有这个网关的存在,所以我们需要创建默认路由,将 VPC 下的流量都转到该网关:

$ kubectl edit vpc vpc1
spec:
  namespaces:
  - ns1
  staticRoutes:
  - cidr: 0.0.0.0/0
    nextHopIP: 10.1.1.254
    policy: policyDst

绑定 EIP & 配置 SNAT 规则

这时候 VPC 下的业务 pod 的流量已经可以转到 VPC 网关了,我们再向 VPC 网关绑定一个 EIP 和 SNAT 的规则,使其能够通过 NAT 出网:

$ cat eip.yaml
kind: IptablesEIP
apiVersion: kubeovn.io/v1
metadata:
  name: eip1
spec:
  v4ip: 192.168.31.200
  natGwDp: vpc1-subnet1-gateway
$  cat snat.yaml
kind: IptablesSnatRule
apiVersion: kubeovn.io/v1
metadata:
  name: snat01
spec:
  eip: eip1
  internalCIDR: 10.1.1.0/24
  
$ kubectl apply -f eip.yaml -f snat.yaml

我们查看一下 VPC 网关的网卡信息,可以看到eth0上绑定的是 VPC 上的 Subnet 的 IP 10.1.1.254,用于 VPC 内部通信。而附加的net1的网卡上绑定了刚才创建的192.168.31.200的外部网络的 IP,用于与外部网络通信。通过ip -d link show dev,我们也能确定net1就是通过 macvlan 创建的网卡,用于打通外部网络和租户网络。

$ kubectl exec -it vpc-nat-gw-vpc1-subnet1-gateway-0 -n kube-system -- ip a
...
2: net1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 9a:d8:b6:12:b9:7d brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.31.2/24 brd 192.168.31.255 scope global net1
       valid_lft forever preferred_lft forever
    inet 192.168.31.200/24 scope global secondary net1
       valid_lft forever preferred_lft forever
    inet6 fe80::98d8:b6ff:fe12:b97d/64 scope link proto kernel_ll
       valid_lft forever preferred_lft forever
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP group default
    link/ether 00:00:00:b5:f2:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.1.1.254/24 brd 10.1.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::200:ff:feb5:f201/64 scope link proto kernel_ll
       valid_lft forever preferred_lft forever

$ kubectl exec -it vpc-nat-gw-vpc1-subnet1-gateway-0 -n kube-system -- ip -d link show dev net1
2: net1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 9a:d8:b6:12:b9:7d brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 0 allmulti 0 minmtu 68 maxmtu 65535
    macvlan mode bridge bcqueuelen 1000 usedbcqueuelen 1000 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 tso_max_size 65536 tso_max_segs 65535 gro_max_size 65536

我们再查看一下 VPC 网关内的 NAT 规则,刚才配置的 SNAT 规则也已经生效。

$ kubectl exec -it vpc-nat-gw-vpc1-subnet1-gateway-0 -n kube-system -- iptables -t nat -L
...
Chain SHARED_SNAT (1 references)
target     prot opt source               destination
SNAT       all  --  10.1.1.0/24          anywhere             to:192.168.31.200 random-fully
...

此时 pod 中也就能够访问外部网络了,流量会先通过默认路由到 VPC 网关,再通过 NAT 转发。

$ kubectl exec -it vpc1-subnet1-pod1 -n ns1 -- ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=107 time=165.265 ms
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 165.265/165.265/165.265 ms

VPC QoS 配置

我们来尝试对 EIP 进行限速,先在vpc1-subnet1-pod1中通过 iperf3 监听 5201 端口,通过 DNAT 规则使其暴露到外部网络的192.168.31.100:15201,再在外部网络通过 iperf3 进行压测。

首先测试没有限速的情况,在vpc1-subnet1-pod1中启动 iperf3:

$ kubectl exec -it vpc1-subnet1-pod1 -n ns1 -- iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------

然后创建 DNAT 规则,使外部可以通过192.168.31.100:15201来访问 iperf3 的服务:

$ cat dnat.yaml
---
kind: IptablesDnatRule
apiVersion: kubeovn.io/v1
metadata:
  name: dnat01
spec:
  eip: eip1
  externalPort: '15201'
  internalIp: 10.1.1.2
  internalPort: '5201'
  protocol: tcp
  
$ kubectl apply -f dnat.yaml

然后在外部网络的物理机上进行压测,查看数据:

$ iperf3 -c 192.168.31.200 -p 15201
Connecting to host 192.168.31.200, port 15201
[  5] local 192.168.31.68 port 54050 connected to 192.168.31.200 port 15201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  1.94 GBytes  16.7 Gbits/sec    0   3.05 MBytes
[  5]   1.00-2.00   sec  2.06 GBytes  17.7 Gbits/sec    0   3.05 MBytes
[  5]   2.00-3.00   sec  2.22 GBytes  19.1 Gbits/sec    0   3.05 MBytes
[  5]   3.00-4.00   sec  2.33 GBytes  20.0 Gbits/sec    0   3.05 MBytes
[  5]   4.00-5.00   sec  2.17 GBytes  18.7 Gbits/sec    0   3.05 MBytes
[  5]   5.00-6.00   sec  2.25 GBytes  19.3 Gbits/sec    0   3.05 MBytes
[  5]   6.00-7.00   sec  1.98 GBytes  17.0 Gbits/sec    0   3.05 MBytes
[  5]   7.00-8.00   sec  1.82 GBytes  15.7 Gbits/sec    0   3.05 MBytes
[  5]   8.00-9.00   sec  2.06 GBytes  17.7 Gbits/sec    0   3.05 MBytes
[  5]   9.00-10.00  sec  2.22 GBytes  19.1 Gbits/sec    0   3.05 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  21.1 GBytes  18.1 Gbits/sec    0             sender
[  5]   0.00-10.00  sec  21.1 GBytes  18.1 Gbits/sec                  receiver

iperf Done.

这时候我们再对 EIP 增加 QoS 策略限制:

$ cat qos.yaml
apiVersion: kubeovn.io/v1
kind: QoSPolicy
metadata:
  name: qos-eip-example
spec:
  shared: false
  bindingType: EIP
  bandwidthLimitRules:
  - name: eip-ingress
    rateMax: "100" # Mbps
    burstMax: "100" # Mbps
    priority: 1
    direction: ingress
  - name: eip-egress
    rateMax: "100" # Mbps
    burstMax: "100" # Mbps
    priority: 1
    direction: egress
    
$ kubectl edit eip eip1
apiVersion: kubeovn.io/v1
kind: IptablesEIP
spec:
  natGwDp: vpc1-subnet1-gateway
  qosPolicy: qos-eip-example # 关联 QoS 策略
  v4ip: 192.168.31.200

关联完成后再重新压测,可以看到带宽已经得到有效的限制:

$ iperf3 -c 192.168.31.200 -p 15201
Connecting to host 192.168.31.200, port 15201
[  5] local 192.168.31.68 port 58924 connected to 192.168.31.200 port 15201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   114 MBytes   958 Mbits/sec  2375   3.95 KBytes
[  5]   1.00-2.00   sec  11.2 MBytes  94.4 Mbits/sec  633   27.6 KBytes
[  5]   2.00-3.00   sec  11.2 MBytes  94.4 Mbits/sec  618   63.2 KBytes
[  5]   3.00-4.00   sec  13.8 MBytes   115 Mbits/sec  664   13.2 KBytes
[  5]   4.00-5.00   sec  10.0 MBytes  83.9 Mbits/sec  512   17.1 KBytes
[  5]   5.00-6.00   sec  13.8 MBytes   115 Mbits/sec  648   75.0 KBytes
[  5]   6.00-7.00   sec  11.2 MBytes  94.4 Mbits/sec  858   3.95 KBytes
[  5]   7.00-8.00   sec  11.2 MBytes  94.4 Mbits/sec  603   11.8 KBytes
[  5]   8.00-9.00   sec  11.2 MBytes  94.4 Mbits/sec  532   46.1 KBytes
[  5]   9.00-10.00  sec  13.8 MBytes   115 Mbits/sec  778   55.3 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec   222 MBytes   186 Mbits/sec  8221             sender
[  5]   0.00-10.00  sec   218 MBytes   183 Mbits/sec                  receiver

iperf Done.

好,对于 Kube-OVN 的 VPC 的常规能力介绍就到此为止。

如果对文章内容有疑问,或者有其他技术上的交流,可以关注我的公众号:李若年

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值