kube-ovn icon indicating copy to clipboard operation
kube-ovn copied to clipboard

1.12.3 默认VPC内使用OVN EIP,但是ping的回包还是原ip

Open geniusxiong opened this issue 1 year ago • 21 comments

Bug Report

根据https://kubeovn.github.io/docs/v1.12.x/advance/ovn-eip-fip-snat/ 配置默认vpc内的一个虚机使用eip 图片 图片 图片

虽然可以ping通,但是不能ssh连接 但是ping的回包是原ip地址,没有做nat转换 图片 ssh连不上,也是没有eip的回包 图片 图片

Expected Behavior

ping的回包应该是eip地址,ssh要能通

Actual Behavior

Steps to Reproduce the Problem

Additional Info

  • Kubernetes version:

    Output of kubectl version:

1.18.6


- kube-ovn version:

```bash
1.12.3

  • operation-system/kernel version:

    Output of awk -F '=' '/PRETTY_NAME/ { print $2 }' /etc/os-release: Output of uname -r:

    4.19.113-3.nfs.x86_64
    
    

geniusxiong avatar Dec 07 '23 06:12 geniusxiong

麻烦贴下你的 install.sh 的 ENABLE_xx 那几行相关的配置,自定义 vpc 目前没这个 bug。 怀疑可能跟一些特性开启有关系

bobz965 avatar Dec 08 '23 01:12 bobz965

麻烦贴下你的 install.sh 的 ENABLE_xx 那几行相关的配置,自定义 vpc 目前没这个 bug。 怀疑可能跟一些特性开启有关系

好的 IPV6=${IPV6:-false} DUAL_STACK=${DUAL_STACK:-false} ENABLE_SSL=${ENABLE_SSL:-false} ENABLE_VLAN=${ENABLE_VLAN:-false} CHECK_GATEWAY=${CHECK_GATEWAY:-true} LOGICAL_GATEWAY=${LOGICAL_GATEWAY:-false} U2O_INTERCONNECTION=${U2O_INTERCONNECTION:-false} ENABLE_MIRROR=${ENABLE_MIRROR:-false} VLAN_NIC=${VLAN_NIC:-} HW_OFFLOAD=${HW_OFFLOAD:-false} ENABLE_LB=${ENABLE_LB:-true} ENABLE_NP=${ENABLE_NP:-true} ENABLE_EIP_SNAT=${ENABLE_EIP_SNAT:-true} LS_DNAT_MOD_DL_DST=${LS_DNAT_MOD_DL_DST:-true} ENABLE_EXTERNAL_VPC=${ENABLE_EXTERNAL_VPC:-true} CNI_CONFIG_PRIORITY=${CNI_CONFIG_PRIORITY:-01} ENABLE_LB_SVC=${ENABLE_LB_SVC:-false} ENABLE_NAT_GW=${ENABLE_NAT_GW:-false} ENABLE_KEEP_VM_IP=${ENABLE_KEEP_VM_IP:-true} ENABLE_ARP_DETECT_IP_CONFLICT=${ENABLE_ARP_DETECT_IP_CONFLICT:-true} NODE_LOCAL_DNS_IP=${NODE_LOCAL_DNS_IP:-} EXCHANGE_LINK_NAME=${EXCHANGE_LINK_NAME:-false} IFACE=${IFACE:-} DPDK_TUNNEL_IFACE=${DPDK_TUNNEL_IFACE:-br-phy} ENABLE_BIND_LOCAL_IP=${ENABLE_BIND_LOCAL_IP:-true} ENABLE_TPROXY=${ENABLE_TPROXY:-false} OVS_VSCTL_CONCURRENCY=${OVS_VSCTL_CONCURRENCY:-100} ENABLE_COMPACT=${ENABLE_COMPACT:-false}

DEBUG_WRAPPER=${DEBUG_WRAPPER:-}

您看看,自定义VPC好像是没问题,我这个问题出现在默认VPC

geniusxiong avatar Dec 08 '23 10:12 geniusxiong

我感觉配置没问题,应该就是引入了一个bug

bobz965 avatar Dec 08 '23 11:12 bobz965

我感觉配置没问题,应该就是引入了一个bug

有计划修复?

geniusxiong avatar Dec 11 '23 07:12 geniusxiong

@oilbeater 大佬,默认vpc好像引入了一个bug,感觉跟路由有关系,导致eip snat的流量没有经过nat规则转化就回包了

bobz965 avatar Dec 11 '23 10:12 bobz965

@oilbeater 大佬,这个有修改计划么?

geniusxiong avatar Dec 14 '23 07:12 geniusxiong

1.12.4 默认 VPC 也有同样的问题, ovn-eip 不生效。 NAT 行为只受 subnet ovn-default 的影响。natOutgoing: false ,修改这个参数会影响 NAT 但修改 ovn eip 在 默认 VPC 下不生效

a180285 avatar Jan 23 '24 06:01 a180285

经过一番研究发现,通过添加如下 route 可以实现 eip nat。 @geniusxiong 可以尝试一下

kubectl ko nbctl lr-policy-add ovn-cluster 31000 'ip4.src == 10.5.193.243' reroute 10.5.0.1
kubectl ko nbctl lr-policy-list ovn-cluster

其中

  • 10.5.193.243 是 pod 的 IP
  • 10.5.0.1 是物理 vlan 中的 gateway IP

怀疑可能是默认 VPC 下的 pod 全部路由到 join subnet ,而无法 snat 了 环境:

  • join subnet: 100.64.0.0/16
  • ovn-default subnet: 10.5.192.0/18
kubectl ko nbctl lr-policy-list ovn-cluster
Routing Policies
     31000                           ip4.dst == 10.5.192.0/18           allow
     31000                           ip4.dst == 100.64.0.0/16           allow
     30000                              ip4.dst == 10.5.0.143         reroute                100.64.0.2
     30000                              ip4.dst == 10.5.0.144         reroute                100.64.0.3
     30000                              ip4.dst == 10.5.0.145         reroute                100.64.0.4
     29000                           ip4.src == 10.5.192.0/18         reroute                100.64.0.2, 100.64.0.3, 100.64.0.4

kubectl ko nbctl lr-nat-list ovn-cluster
TYPE             GATEWAY_PORT          EXTERNAL_IP        EXTERNAL_PORT    LOGICAL_IP          EXTERNAL_MAC         LOGICAL_PORT
dnat_and_snat                          10.5.0.18                           10.5.193.243        00:00:00:D3:51:4B    default-pod4.default

@bobz965 上面的分析正确吗,是不是可以通过代码强制加 policy route 来修复这个问题呢

a180285 avatar Jan 23 '24 14:01 a180285

image

https://kubeovn.github.io/docs/v1.13.x/guide/eip-snat/

你对照下这个eip的使用方式是否可以正常使用? 然后对照下看是否是你的策略路由的维护逻辑。如果一致,应该就没问题。 只是这个功能我之前测试过很多次,都是可以正常使用的,之前不记得有配置这样的策略路由。

bobz965 avatar Jan 24 '24 01:01 bobz965

我之前 pod 没有加 annotation ,只是使用自定义 VPC 一样,使用了 ovnFIP 这个 yaml

@bobz965 是指所有 VPC (不管默认还是自定义 VPC) 的 pod 要使用 ovn EIP/FIP 都需要对应的 pod annotation 吗?还是默认 VPC 的 pod 才需要加这个 annotation ?

BTW: 我默认和自定义 VPC 下的 pod 都没加过个 annotation。我以为这个 annotation 是给 IptableEIP/FIP 使用的

a180285 avatar Jan 24 '24 03:01 a180285

我之前 pod 没有加 annotation ,只是使用自定义 VPC 一样,使用了 ovnFIP 这个 yaml

@bobz965 是指所有 VPC (不管默认还是自定义 VPC) 的 pod 要使用 ovn EIP/FIP 都需要对应的 pod annotation 吗?还是默认 VPC 的 pod 才需要加这个 annotation ?

BTW: 我默认和自定义 VPC 下的 pod 都没加过个 annotation。我以为这个 annotation 是给 IptableEIP/FIP 使用的

这个 annotation 和 ovn fip 是同样的 ovn 的资源,只不过只有在默认 vpc 下才能用。如果默认 vpc 下这个 annotation 的 eip 能够正常使用,我理解默认 vpc下的 ovn eip fip 保持同样的维护方式就能修复。

bobz965 avatar Jan 24 '24 06:01 bobz965

image

https://kubeovn.github.io/docs/v1.13.x/guide/eip-snat/

你对照下这个eip的使用方式是否可以正常使用? 然后对照下看是否是你的策略路由的维护逻辑。如果一致,应该就没问题。 只是这个功能我之前测试过很多次,都是可以正常使用的,之前不记得有配置这样的策略路由。

@bobz965 通过annotation绑定eip好像可以,但是实际使用的时候不好用,因为pod重建后,需要重新绑定eip,对于虚机来说,重启就会丢失eip,需要重新绑定。所以我们考虑用ovn eip fip方案替代直接通过annotation绑定eip。 谢谢 @a180285 提的修改方法,我回头试试。

geniusxiong avatar Jan 24 '24 09:01 geniusxiong

我这边使用 annotation 创建 pod 会报错

kube-ovn-controller 日志

I0124 21:46:30.063745       1 ovn-nb-logical_router_route.go:102] logical router ovn-cluster del static routes: []
E0124 21:46:30.070997       1 pod.go:405] error syncing 'default/default-pod9': generate operations for port group ovn.default.caas.144 update ports [default-pod9.default]: get port group ovn.default.caas.144: get port group ovn.default.caas.144: object not found, requeuing
I0124 21:46:30.071011       1 pod.go:559] handle add/update pod default/default-pod9
I0124 21:46:30.071314       1 pod.go:772] sync pod default/default-pod9 routed
I0124 21:46:30.071326       1 vpc.go:689] vpc ovn-cluster add static route: &{Policy:policySrc CIDR:10.5.192.68 NextHopIP:10.5.0.1 ECMPMode: BfdID: RouteTable:}
I0124 21:46:30.072349       1 ovn-nb-logical_router_route.go:102] logical router ovn-cluster del static routes: []
E0124 21:46:30.072663       1 pod.go:405] error syncing 'default/default-pod9': generate operations for port group ovn.default.caas.144 update ports [default-pod9.default]: get port group ovn.default.caas.144: get port group ovn.default.caas.144: object not found, requeuing
I0124 21:46:31.913792       1 pod.go:559] handle add/update pod default/default-pod9
I0124 21:46:31.913996       1 pod.go:772] sync pod default/default-pod9 routed
I0124 21:46:31.914009       1 vpc.go:689] vpc ovn-cluster add static route: &{Policy:policySrc CIDR:10.5.192.68 NextHopIP:10.5.0.1 ECMPMode: BfdID: RouteTable:}
I0124 21:46:31.914742       1 ovn-nb-logical_router_route.go:102] logical router ovn-cluster del static routes: []
E0124 21:46:31.915177       1 pod.go:405] error syncing 'default/default-pod9': generate operations for port group ovn.default.caas.144 update ports [default-pod9.default]: get port group ovn.default.caas.144: get port group ovn.default.caas.144: object not found, requeuing
I0124 21:46:33.000953       1 pod.go:950] handle delete pod default/default-pod9
I0124 21:46:33.000977       1 pod.go:438] take 0 ms to handle delete pod default/default-pod9

pod 状态

apiVersion: v1
kind: Pod
metadata:
  name: default-pod9
  namespace: default
  uid: 587dcfb4-6d9e-41fd-9bf3-e222052962d3
  resourceVersion: '4017839'
  creationTimestamp: '2024-01-24T13:46:29Z'
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: >
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"ovn.kubernetes.io/eip":"10.5.0.201"},"name":"default-pod9","namespace":"default"},"spec":{"containers":[{"command":["sleep","10d"],"image":"docker.io/jonlabelle/network-tools","name":"default-pod9"}]}}
    ovn.kubernetes.io/allocated: 'true'
    ovn.kubernetes.io/cidr: 10.5.192.0/18
    ovn.kubernetes.io/eip: 10.5.0.201
    ovn.kubernetes.io/gateway: 10.5.196.1
    ovn.kubernetes.io/ip_address: 10.5.192.68
    ovn.kubernetes.io/logical_router: ovn-cluster
    ovn.kubernetes.io/logical_switch: ovn-default
    ovn.kubernetes.io/mac_address: 00:00:00:97:E4:3F
    ovn.kubernetes.io/pod_nic_type: veth-pair
status:
  phase: Pending
  conditions:
    - type: Initialized
      status: 'True'
      lastProbeTime: null
      lastTransitionTime: '2024-01-24T13:46:30Z'
    - type: Ready
      status: 'False'
      lastProbeTime: null
      lastTransitionTime: '2024-01-24T13:46:30Z'
      reason: ContainersNotReady
      message: 'containers with unready status: [default-pod9]'
    - type: ContainersReady
      status: 'False'
      lastProbeTime: null
      lastTransitionTime: '2024-01-24T13:46:30Z'
      reason: ContainersNotReady
      message: 'containers with unready status: [default-pod9]'
    - type: PodScheduled
      status: 'True'
      lastProbeTime: null
      lastTransitionTime: '2024-01-24T13:46:30Z'
  hostIP: 10.5.0.144
  startTime: '2024-01-24T13:46:30Z'
  containerStatuses:
    - name: default-pod9
      state:
        waiting:
          reason: ContainerCreating
      lastState: {}
      ready: false
      restartCount: 0
      image: cr.sihe.cloud/docker.io/jonlabelle/network-tools
      imageID: ''
      started: false
  qosClass: BestEffort

创建 pod 的 yaml

apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: default-pod9
  annotations:
    ovn.kubernetes.io/eip: 10.5.0.201
spec:
  containers:
    - name: default-pod9
      image: docker.io/jonlabelle/network-tools
      command:
        - sleep
        - 10d

a180285 avatar Jan 24 '24 13:01 a180285

从日志看,使用 annotation 的情况下,会加一个 route ,看上去就是和我 PR 中做的事情一样,但不知道为什么 pod 没有创建成功

I0124 21:46:31.914009       1 vpc.go:689] vpc ovn-cluster add static route: &{Policy:policySrc CIDR:10.5.192.68 NextHopIP:10.5.0.1 ECMPMode: BfdID: RouteTable:}

a180285 avatar Jan 24 '24 13:01 a180285

看了一下 port group

确实没有上面日志说的 ovn.default.caas.144

E0124 21:46:31.915177       1 pod.go:405] error syncing 'default/default-pod9': generate operations for port group ovn.default.caas.144 update ports [default-pod9.default]: get port group ovn.default.caas.144: get port group ovn.default.caas.144: object not found, requeuing

_uuid               : f462af4f-fb01-4919-b860-f9a87b1d682f
acls                : []
external_ids        : {np="node/caas-144"}
name                : node.caas.144
ports               : []
root@caas-144:~# kubectl ko nbctl list Port_Group | grep name
name                : node.caas.145
name                : node.caas.143
name                : ovn.sg.sg.example
name                : ovn.sg.sg.kube.system
name                : ovn.sg.sg.example.2
name                : ovn.sg.kubeovn_deny_all
name                : node.caas.144

a180285 avatar Jan 24 '24 14:01 a180285

我通过临时创建同名 pg 先绕过了这个 issue ,让 pod 先创成功,但是发现

root@caas-143:~# kubectl ko nbctl lr-route-list ovn-cluster
IPv4 Routes
Route Table <main>:
              10.5.192.19                  10.5.0.1 src-ip
                0.0.0.0/0                100.64.0.1 dst-ip
root@caas-143:~# kubectl ko nbctl lr-policy-list ovn-cluster
Routing Policies
     31000                           ip4.dst == 10.5.192.0/18           allow
     31000                           ip4.dst == 100.64.0.0/16           allow
     30000                              ip4.dst == 10.5.0.143         reroute                100.64.0.2
     30000                              ip4.dst == 10.5.0.144         reroute                100.64.0.3
     30000                              ip4.dst == 10.5.0.145         reroute                100.64.0.4
     29000                           ip4.src == 10.5.192.0/18         reroute                100.64.0.2, 100.64.0.3, 100.64.0.4

似乎 policy route 覆盖了日志添加的 static route

pod 的流量还是从 node 出去了

default-pod8:/# traceroute -n 10.2.200.52
traceroute to 10.2.200.52 (10.2.200.52), 30 hops max, 46 byte packets
 1  10.5.196.1  2.598 ms  1.364 ms  0.691 ms
 2  10.5.0.143  0.865 ms  0.003 ms  0.002 ms
 3  10.5.0.1  2.591 ms  0.866 ms  0.811 ms
...

default-pod8:/# 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
1034: eth0@if1035: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP group default 
    link/ether 00:00:00:e0:b0:85 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.5.192.19/18 brd 10.5.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::200:ff:fee0:b085/64 scope link 
       valid_lft forever preferred_lft forever

a180285 avatar Jan 24 '24 15:01 a180285

经过一番研究发现,通过添加如下 route 可以实现 eip nat。 @geniusxiong 可以尝试一下

kubectl ko nbctl lr-policy-add ovn-cluster 31000 'ip4.src == 10.5.193.243' reroute 10.5.0.1
kubectl ko nbctl lr-policy-list ovn-cluster

其中

  • 10.5.193.243 是 pod 的 IP
  • 10.5.0.1 是物理 vlan 中的 gateway IP

怀疑可能是默认 VPC 下的 pod 全部路由到 join subnet ,而无法 snat 了 环境:

  • join subnet: 100.64.0.0/16
  • ovn-default subnet: 10.5.192.0/18
kubectl ko nbctl lr-policy-list ovn-cluster
Routing Policies
     31000                           ip4.dst == 10.5.192.0/18           allow
     31000                           ip4.dst == 100.64.0.0/16           allow
     30000                              ip4.dst == 10.5.0.143         reroute                100.64.0.2
     30000                              ip4.dst == 10.5.0.144         reroute                100.64.0.3
     30000                              ip4.dst == 10.5.0.145         reroute                100.64.0.4
     29000                           ip4.src == 10.5.192.0/18         reroute                100.64.0.2, 100.64.0.3, 100.64.0.4

kubectl ko nbctl lr-nat-list ovn-cluster
TYPE             GATEWAY_PORT          EXTERNAL_IP        EXTERNAL_PORT    LOGICAL_IP          EXTERNAL_MAC         LOGICAL_PORT
dnat_and_snat                          10.5.0.18                           10.5.193.243        00:00:00:D3:51:4B    default-pod4.default

@bobz965 上面的分析正确吗,是不是可以通过代码强制加 policy route 来修复这个问题呢

@bobz965 这个问题可能和之前multiple distributed gateway ports问题是一样的 https://github.com/kubeovn/ovn/pull/4 ,逻辑流表可能没有正确下发is_chassis_resident和outport,因为1.12没有引入我之前对ovn的修复。我待会儿测试一下是不是这个问题,按理说无需配置静态/策略路由。

修正:和multiple dgw的bug无关

zcq98 avatar Jan 25 '24 01:01 zcq98

@zcq98 和multiple dgw的bug无关的话。你本地可以复现这个 BUG 吗?还是你本地不能复现这个 BUG 呢

a180285 avatar Jan 26 '24 05:01 a180285

@zcq98 和multiple dgw的bug无关的话。你本地可以复现这个 BUG 吗?还是你本地不能复现这个 BUG 呢

1.12.4 可以复现,添加策略路由就正常了

zcq98 avatar Jan 26 '24 06:01 zcq98

@oilbeater 大佬对这个修复 PR 怎么看 https://github.com/kubeovn/kube-ovn/pull/3666

a180285 avatar Jan 26 '24 06:01 a180285

#### 默认vpc ovn eip 参考配置路由


kind: Vpc
apiVersion: kubeovn.io/v1
metadata:
  name: ovn-cluster
spec:
  namespaces:
  - default
  policyRoutes:
  - action: reroute
    match: ip4.src==10.16.0.0/16 && ip4.dst!=169.254.25.10 && ip4.dst!=10.96.0.0/12 && ip4.dst!=100.64.0.0/16 && ip4.dst!=<k8s node ip>
    nextHopIP: <公网网关>
    priority: 30001

https://github.com/kubeovn/kube-ovn/pull/3666 通过配置上述策略路由,在开启external的情况下可以保证默认子网下pod和node及svc的连通性,而其它网络则通过fip走external,你的PR默认用户开启fip后只能走fip。用户开启external后应该自己选择是否配置上述策略路由

zcq98 avatar Jan 30 '24 08:01 zcq98

Issues go stale after 60d of inactivity. Please comment or re-open the issue if you are still interested in getting this issue fixed.

github-actions[bot] avatar Mar 31 '24 00:03 github-actions[bot]