Raven

This document introduces how to install raven and use raven to enhance edge-edge and edge-cloud network communication in an edge cluster.

Suppose you have an edge kubernetes cluster with nodes in different physical regions, and already deploy the Raven Controller Manager and Raven Agent in this cluster,You can refer to the installation tutorial if you do not have Raven installed, the details of Raven Controller Manager are in here. raven_deploy

Label nodes in different physical regions

As follows, suppose the cluster has five nodes, located in three different regions, where the node master is cloud node.

  1. $ kubectl get nodes -o wide
  2. NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
  3. izbp15inok0kbfkg3in52rz Ready Edge-HZ-1 27h v1.22.11 172.16.2.103 <none> CentOS Linux 7 (Core) 3.10.0-1160.81.1.el7.x86_64 docker://19.3.15
  4. izbp15inok0kbfkg3in52sz Ready Edge-HZ-2 26h v1.22.11 172.16.2.104 <none> CentOS Linux 7 (Core) 3.10.0-1160.81.1.el7.x86_64 docker://19.3.15
  5. izm5eb24dmjfimuaybpnqzz Ready Edge-QD-1 29h v1.22.11 172.16.1.89 <none> CentOS Linux 7 (Core) 3.10.0-1160.80.1.el7.x86_64 docker://19.3.15
  6. izm5eb24dmjfimuaybpnr0z Ready Edge-QD-2 29h v1.22.11 172.16.1.90 <none> CentOS Linux 7 (Core) 3.10.0-1160.80.1.el7.x86_64 docker://19.3.15
  7. izwz9dohcv74iegqecp4axz Ready control-plane,master 5d21h v1.22.11 192.168.0.195 <none> CentOS Linux 7 (Core) 3.10.0-1160.80.1.el7.x86_64 docker://20.10.2
  8. izwz9ey0js5z7mornclpd6z Ready cloud 3h3m v1.22.11 192.168.0.196 <none> CentOS Linux 7 (Core) 3.10.0-1160.80.1.el7.x86_64 docker://20.10.2

We use a Gateway CR to manage nodes in different physical regions, and label nodes to indicate which Gateway these nodes are managed by.

For example, We label nodes in region hangzhou with value gw-hangzhou, indicating that these nodes are managed by the gw-hangzhou gateway.

  1. $ kubectl label nodes izbp15inok0kbfkg3in52rz izbp15inok0kbfkg3in52sz raven.openyurt.io/gateway=gw-hangzhou
  2. node/izbp15inok0kbfkg3in52rz not labeled
  3. node/izbp15inok0kbfkg3in52sz not labeled

Similarly, we label node in cloud with value gw-cloud, and nodes in region qingdao with value gw-qingdao.

  1. $ kubectl label nodes izwz9dohcv74iegqecp4axz izwz9ey0js5z7mornclpd6z raven.openyurt.io/gateway=gw-cloud
  2. node/izwz9dohcv74iegqecp4axz labeled
  3. node/izwz9ey0js5z7mornclpd6z labeled
  1. $ kubectl label nodes izm5eb24dmjfimuaybpnqzz izm5eb24dmjfimuaybpnr0z raven.openyurt.io/gateway=gw-qingdao
  2. node/izm5eb24dmjfimuaybpnqzz labeled
  3. node/izm5eb24dmjfimuaybpnr0z labeled

Apply the following command to check that raven is running properly

  1. $ kubectl get pod -n kube-system | grep raven-agent-ds
  2. raven-agent-ds-4b587 1/1 Running 0 25h
  3. raven-agent-ds-dmh66 1/1 Running 0 25h
  4. raven-agent-ds-gb5qj 1/1 Running 0 25h
  5. raven-agent-ds-gzpfh 1/1 Running 0 170m
  6. raven-agent-ds-ksxq6 1/1 Running 0 25h
  7. raven-agent-ds-qhjtb 1/1 Running 0 25h

2. How to use

2.1 Gateways

  • Create Gateway CR
  1. $ cat <<EOF | kubectl apply -f -
  2. apiVersion: raven.openyurt.io/v1beta1
  3. kind: Gateway
  4. metadata:
  5. name: gw-hangzhou
  6. spec:
  7. proxyConfig:
  8. Replicas: 1
  9. tunnelConfig:
  10. Replicas: 1
  11. endpoints:
  12. - nodeName: izbp15inok0kbfkg3in52rz
  13. underNAT: true
  14. port: 10262
  15. type: proxy
  16. - nodeName: izbp15inok0kbfkg3in52rz
  17. underNAT: true
  18. port: 4500
  19. underNAT: true
  20. type: tunnel
  21. ---
  22. apiVersion: raven.openyurt.io/v1alpha1
  23. kind: Gateway
  24. metadata:
  25. name: gw-cloud
  26. spec:
  27. exposeType: PublicIP
  28. proxyConfig:
  29. Replicas: 1
  30. proxyHTTPPort: 10255,9445
  31. proxyHTTPSPort: 10250,9100
  32. tunnelConfig:
  33. Replicas: 1
  34. endpoints:
  35. - nodeName: izwz9dohcv74iegqecp4axz
  36. underNAT: false
  37. port: 10262
  38. type: proxy
  39. publicIP: 120.79.xxx.xxx
  40. - nodeName: izwz9dohcv74iegqecp4axz
  41. underNAT: false
  42. port: 4500
  43. type: tunnel
  44. publicIP: 120.79.xxx.xxx
  45. ---
  46. apiVersion: raven.openyurt.io/v1alpha1
  47. kind: Gateway
  48. metadata:
  49. name: gw-qingdao
  50. spec:
  51. proxyConfig:
  52. Replicas: 1
  53. tunnelConfig:
  54. Replicas: 1
  55. endpoints:
  56. - nodeName: izm5eb24dmjfimuaybpnqzz
  57. underNAT: true
  58. port: 10262
  59. type: proxy
  60. - nodeName: izm5eb24dmjfimuaybpnr0z
  61. underNAT: true
  62. port: 4500
  63. type: tunnel
  64. EOF
  • Parameters Introduction:
  1. spec.exposedType: The type of public network exposure, empty indicates that the gateway will not be exposed, either LoadBalancer or PublicIP can be used to exposed gateway in internet.
  2. spec.endpoints: Indicates a set of alternative gateway endpoints, some of which are selected by the yurtmanager as gateway endpoints based on node status
  3. spec.endpoints.nodeName: The name of gateway endpoints
    1. spec.endpoints.type: The type of gateway endpoints, the value is set to proxy if the node is proxy mode endpoints, and the value is also can be set to tunnel if the node is tunnel mode endpoints.
  4. spec.endpoints.port: Ports exposed by the gateway endpoints service: TCP 10262 in proxy mode and UDP 4500 in tunnel mode
  5. spec.endpoints.publicIP: The public ip of gateway endpoints
  6. spec.endpoints.underNAT: Whether to use NAT to access the public network. Generally, false is set on the cloud, and true is set on the edge
  7. spec.proxyConfig.Replicas: Replicas of gateway endpoints in enable proxy mode
  8. spec.proxyConfig.proxyHTTPPort: A insecure port for a cloud-side proxy mode communication agent, such as port 10255, which kubelet listens for
  9. spec.proxyConfig.proxyHTTPPort: A secure port for a cloud-side proxy mode communication agent, such as port 10250, which kubelet listens for
  10. spec.tunnelConfig.Replicas: Replicas of gateway endpoints in enable tunnel mode,which must be 1 currently
  • Describe the status of all gateways
  1. Check whether the Gateway node is elected in the Status of the gateway. The Yurt Manager component, GatewayPickup Controller, is responsible for the election.
  2. Check whether the public IP address and exposed port are correct
  3. Check whether the enabled mode meets the expectations
  1. $ kubectl get cm raven-cfg -n kube-system -o yaml
  2. apiVersion: v1
  3. data:
  4. enable-l3-tunnel: "true"
  5. enable-l7-proxy: "true"
  6. kind: ConfigMap
  7. metadata:
  8. annotations:
  9. meta.helm.sh/release-name: raven-agent
  10. meta.helm.sh/release-namespace: kube-system
  11. creationTimestamp: "2023-11-24T06:44:54Z"
  12. labels:
  13. app.kubernetes.io/managed-by: Helm
  14. name: raven-cfg
  15. namespace: kube-system
  1. $ kubectl get gateways
  2. NAME AGE
  3. gw-cloud 22h
  4. gw-hangzhou 22h
  5. gw-qingdao 22h
  6. $ kubectl get gateway gw-cloud -o yaml
  7. apiVersion: raven.openyurt.io/v1alpha1
  8. kind: Gateway
  9. metadata:
  10. name: gw-cloud
  11. spec:
  12. exposeType: PublicIP
  13. proxyConfig:
  14. Replicas: 1
  15. proxyHTTPPort: 10255,9445
  16. proxyHTTPSPort: 10250,9100
  17. tunnelConfig:
  18. Replicas: 1
  19. endpoints:
  20. - nodeName: izwz9dohcv74iegqecp4axz
  21. underNAT: false
  22. port: 10262
  23. type: proxy
  24. publicIP: 120.79.xxx.xxx
  25. - nodeName: izwz9dohcv74iegqecp4axz
  26. underNAT: false
  27. port: 4500
  28. type: tunnel
  29. publicIP: 120.79.xxx.xxx
  30. status:
  31. activeEndpoints:
  32. - config:
  33. enable-l7-proxy: "true"
  34. nodeName: izwz9dohcv74iegqecp4axz
  35. port: 10262
  36. publicIP: 47.xxx.xxx.xxx
  37. type: proxy
  38. - config:
  39. enable-l3-tunnel: "true"
  40. nodeName: izwz9dohcv74iegqecp4axz
  41. port: 4500
  42. publicIP: 47.xxx.xxx.xxx
  43. type: tunnel
  44. nodes:
  45. - nodeName: izwz9dohcv74iegqecp4axz
  46. privateIP: 192.168.0.195
  47. subnets:
  48. - 10.224.0.128/26
  49. - nodeName: izwz9ey0js5z7mornclpd6z
  50. privateIP: 192.168.0.196
  51. subnets:
  52. - 10.224.0.0/26
  53. $ kubectl get gateway gw-hangzhou -o yaml
  54. apiVersion: raven.openyurt.io/v1beta1
  55. kind: Gateway
  56. metadata:
  57. name: gw-hangzhou
  58. spec:
  59. proxyConfig:
  60. Replicas: 1
  61. tunnelConfig:
  62. Replicas: 1
  63. endpoints:
  64. - nodeName: izbp15inok0kbfkg3in52rz
  65. underNAT: true
  66. port: 10262
  67. type: proxy
  68. - nodeName: izbp15inok0kbfkg3in52rz
  69. underNAT: true
  70. port: 4500
  71. underNAT: true
  72. type: tunnel
  73. status:
  74. activeEndpoints:
  75. - config:
  76. enable-l7-proxy: "true"
  77. nodeName: izbp15inok0kbfkg3in52rz
  78. port: 10262
  79. publicIP: 120.79.xxx.xxx
  80. type: proxy
  81. - config:
  82. enable-l3-tunnel: "true"
  83. nodeName: izbp15inok0kbfkg3in52rz
  84. port: 4500
  85. publicIP: 120.79.xxx.xxx
  86. type: tunnel
  87. nodes:
  88. - nodeName: izbp15inok0kbfkg3in52rz
  89. privateIP: 172.16.2.103
  90. subnets:
  91. - 10.224.1.128/26
  92. - nodeName: izbp15inok0kbfkg3in52sz
  93. privateIP: 172.16.2.104
  94. subnets:
  95. - 10.224.1.0/26

Test pod-to-pod networking (tunnel mode)

  • Create test pod
  1. $ cat <<EOF | kubectl apply -f -
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: busy-box
  6. spec:
  7. replicas: 4
  8. selector:
  9. matchLabels:
  10. app: busy-box
  11. template:
  12. metadata:
  13. labels:
  14. app: busy-box
  15. spec:
  16. containers:
  17. - name: busy-box
  18. image: busybox
  19. command:
  20. - /bin/sh
  21. - -c
  22. - sleep 3000
  23. nodeSelector:
  24. openyurt.io/is-edge-worker: "true"
  25. EOF
  • Get test pod
  1. $ kubectl get pod -o wide
  2. busy-box-6f46f8585b-48zb9 1/1 Running 0 76s 10.244.19.3 izbp15inok0kbfkg3in52sz <none> <none>
  3. busy-box-6f46f8585b-9nm64 1/1 Running 0 76s 10.244.16.161 izm5eb24dmjfimuaybpnqzz <none> <none>
  4. busy-box-6f46f8585b-kv4dw 1/1 Running 0 76s 10.244.17.19 izm5eb24dmjfimuaybpnr0z <none> <none>
  5. busy-box-6f46f8585b-t5v9d 1/1 Running 0 76s 10.244.18.4 izbp15inok0kbfkg3in52rz <none> <none>
  • Test networking across edge
  1. $ kubectl exec -it busy-box-6f46f8585b-48zb9 -- sh
  2. / # ping 10.244.17.19 -c 4
  3. PING 10.244.17.19 (10.244.17.19): 56 data bytes
  4. 64 bytes from 10.244.17.19: seq=0 ttl=59 time=78.048 ms
  5. 64 bytes from 10.244.17.19: seq=1 ttl=59 time=77.424 ms
  6. 64 bytes from 10.244.17.19: seq=2 ttl=59 time=77.490 ms
  7. 64 bytes from 10.244.17.19: seq=3 ttl=59 time=77.472 ms
  8. --- 10.244.17.19 ping statistics ---
  9. 4 packets transmitted, 4 packets received, 0% packet loss
  10. round-trip min/avg/max = 77.424/77.608/78.048 ms
  • Log in to the non-gateway node Edge-HZ-2 and ping the non-gateway node Edge-QD-2 to test the connectivity of nodes across network domains,
  1. # Edge-HZ-2(Non-Gateway):
  2. ping 172.16.1.90 -c 4
  3. PING 172.16.1.90 (172.16.1.90) 56(84) bytes of data.
  4. 64 bytes from 172.16.1.90: icmp_seq=1 ttl=61 time=77.5 ms
  5. 64 bytes from 172.16.1.90: icmp_seq=2 ttl=61 time=77.3 ms
  6. 64 bytes from 172.16.1.90: icmp_seq=3 ttl=61 time=78.5 ms
  7. 64 bytes from 172.16.1.90: icmp_seq=4 ttl=61 time=77.3 ms
  8. --- 172.16.1.90 ping statistics ---
  9. 4 packets transmitted, 4 received, 0% packet loss, time 3003ms
  10. rtt min/avg/max/mdev = 77.314/77.682/78.531/0.533 ms
  1. # Capture package
  2. # Edge-HZ-1 (Gateway):
  3. tcpdump -i raven0
  4. tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  5. listening on raven0, link-type EN10MB (Ethernet), capture size 262144 bytes
  6. 16:13:12.132496 IP 172.16.2.104 > 172.16.1.90: ICMP echo request, id 2, seq 1, length 64
  7. 16:13:13.133606 IP 172.16.2.104 > 172.16.1.90: ICMP echo request, id 2, seq 2, length 64
  8. 16:13:14.134172 IP 172.16.2.104 > 172.16.1.90: ICMP echo request, id 2, seq 3, length 64
  9. 16:13:15.135570 IP 172.16.2.104 > 172.16.1.90: ICMP echo request, id 2, seq 4, length 64
  1. # Capture package
  2. # Edge-QD-1 (Gateway):
  3. tcpdump -i raven0
  4. tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  5. listening on raven0, link-type EN10MB (Ethernet), capture size 262144 bytes
  6. 16:13:12.174023 IP 172.16.1.90 > 172.16.2.104: ICMP echo reply, id 2, seq 1, length 64
  7. 16:13:13.175096 IP 172.16.1.90 > 172.16.2.104: ICMP echo reply, id 2, seq 2, length 64
  8. 16:13:14.176813 IP 172.16.1.90 > 172.16.2.104: ICMP echo reply, id 2, seq 3, length 64
  9. 16:13:15.177024 IP 172.16.1.90 > 172.16.2.104: ICMP echo reply, id 2, seq 4, length 64
  1. # Capture package
  2. # Edge-QD-2(Non-Gateway):
  3. tcpdump -i raven0
  4. tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  5. listening on raven0, link-type EN10MB (Ethernet), capture size 262144 bytes
  6. 16:13:12.173087 IP iZm5eb24dmjfimuaybpnr0Z > 172.16.2.104: ICMP echo reply, id 2, seq 1, length 64
  7. 16:13:13.174148 IP iZm5eb24dmjfimuaybpnr0Z > 172.16.2.104: ICMP echo reply, id 2, seq 2, length 64
  8. 16:13:14.175884 IP iZm5eb24dmjfimuaybpnr0Z > 172.16.2.104: ICMP echo reply, id 2, seq 3, length 64
  9. 16:13:15.176090 IP iZm5eb24dmjfimuaybpnr0Z > 172.16.2.104: ICMP echo reply, id 2, seq 4, length 64

Test cross-domain http networking (proxy mode)

In the edge scenario, the Intranet IP addresses of the edge devices often conflict with each other in closed Intranet environments, and the tunnel mode cannot support host communication in IP conflict scenarios. Therefore, the proxy mode must be enabled to support cross-domain HTTP/HTTPS requests. enable proxy model, and set enable-l7-proxy: "true"

  1. $ kubectl get cm raven-cfg -n kube-system -o yaml
  2. apiVersion: v1
  3. data:
  4. enable-l3-tunnel: "true"
  5. enable-l7-proxy: "true"
  6. kind: ConfigMap
  7. metadata:
  8. annotations:
  9. meta.helm.sh/release-name: raven-agent
  10. meta.helm.sh/release-namespace: kube-system
  11. creationTimestamp: "2023-11-24T06:44:54Z"
  12. labels:
  13. app.kubernetes.io/managed-by: Helm
  14. name: raven-cfg
  15. namespace: kube-system
  1. $ kubectl exec -it busy-box-6f46f8585b-48zb9 -- sh
  2. echo hello word
  3. hello word

Other Features:

By default, raven uses IPSec as the VPN back end, and we also provide WireGuard as an alternative. You can do the following to switch to the WireGuard back end.

  • Raven requires the WireGuard kernel module to be loaded on the gateway node in the cluster. As of Linux 5.6, the kernel includes WireGuard in-tree; Linux distributions with older kernels will need WireGuard installed. For most Linux distributions, this can be done using the system package manager. For more information, see Installing WireGuard.

    • The gateway node will require an open UDP port to communicate. By default, the WireGuard uses UDP port 51820. Run the following command.

      1. cd raven
      2. git checkout v0.4.1
      3. VPN_DRIVER=wireguard make deploy

Using VPN Tunnel

If using an IPSec tunnel (implemented via libreswan) as the backend, you can enter the raven agent container and check the relevant status by using the command ipsec status/look or /usr/libexec/ipsec status/look. Additionally, make appropriate use of the ipsec tool to troubleshoot related issues. If using a Wireguard tunnel as the backend implementation for the VPN, you can enter the raven agent container, install the wireguard-tools tool, and refer to the tool’s instructions to troubleshoot related issues. Raven relies entirely on open-source IPSec and Wireguard tools without any customization. You can refer to open-source communities and related technical blogs to resolve everyday issues.