-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #419 from ekoops/ekoops/k8s-polykube
pcn-loadbalancer-rp MULTI port mode and pcn-k8sdispatcher
- Loading branch information
Showing
70 changed files
with
7,480 additions
and
217 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ off on commits in the Polycube repository: | |
Gianluca Scopelliti [email protected] | ||
Giuseppe Ognibebe [email protected] | ||
Jianwen Pi [email protected] | ||
Leonardo Di Giovanna [email protected] | ||
Matteo Bertrone [email protected] | ||
Mauricio Vásquez Bernal [email protected] | ||
Nico Caprioli [email protected] | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# K8dispatcher | ||
|
||
The ``pcn-k8sdispatcher`` service is specifically designed as part of our Kubernetes networking solution (please see [polykube](https://github.com/polycube-network/polykube) to get more information about it). The service provides an eBPF implementation of a custom NAT: it performs different actions depending on the type and on the direction of the traffic. | ||
|
||
For Egress Traffic, the following flow chart can be used to explain the functioning of the service: | ||
|
||
![K8sdispatcher egress flow chart](egress.png) | ||
|
||
The Egress Traffic is the traffic generated by Pods and directed to the external world. | ||
This traffic can be generated by an internal Pod that wants to contact the external world or as a response to an | ||
external world request. For this traffic, the service maintains an egress session table containing information | ||
about the active egress sessions. The first time a Pod wants to contact the external world, no active egress session | ||
will be present in the table: in this scenario, the service performs SNAT, replacing the address of the Pod | ||
with the address of the node, and creates entries in the ingress and egress session table accordingly. | ||
If the outgoing traffic is generated as a response to an external request, it can only be originated as a response to | ||
a request made to a NodePort Service. For traffic related to NodePort Services with a CLUSTER ExternalTrafficPolicy, | ||
if an egress session table hit happens, the destination IP address and port are replaced accordingly to the session data. | ||
The traffic related to NodePort Services with a LOCAL ExternalTrafficPolicy is forwarded as it is to the next cube. | ||
|
||
For Ingress Traffic, the following flow chart can be used to explain the functioning of the service: | ||
|
||
![K8sdispatcher ingress flow chart](ingress.png) | ||
|
||
The Ingress Traffic can be differentiated in traffic directed to the host (either directly or because it needs VxLAN | ||
processing) and traffic directed to Pods. The traffic directed to Pods can be the traffic generated by an external host | ||
trying to contact a NodePort service or the return traffic generated by an external host providing a response to an | ||
internal Pod request. The service uses an ingress session table containing all the active ingress sessions. | ||
If a session table hit happens, the service apply NAT according to the session data. If no session table entry is | ||
associated with the incoming packet, the service tries to determine if a NodePort rule matches the packet | ||
characteristics. In case of no NodePort rule matching, the packet is sent to the Linux stack for further processing. | ||
In case of NodePort rule matching, different actions are applied according to the ExternalTrafficPolicy of the | ||
Kubernetes NodePort Service associated to the rule. If the policy is LOCAL, the traffic is allowed to reach only | ||
backend Pods located on the current node: in this case the packet can proceed towards the Pod without modifications. | ||
In case the policy is CLUSTER, the packet can also reach backend Pods located on other nodes: since later in | ||
the chain the packet will be processed by a load balancer and the return packet will have to transit through | ||
the same load balancer, SNAT is applied by replacing the source IP address with a specific reserved address belonging | ||
to the Pod CIDR of the node on which the k8sdispatcher is deployed. In this way the two nodes (the one that | ||
receives the request and the one running the selected backend Pod) will exchange the packets of the flow over | ||
the VxLAN interconnect. In this latter case, corresponding session entries are stored into the ingress and egress | ||
sessions tables. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Swagger Codegen Ignore | ||
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen | ||
|
||
# Use this file to prevent files from being overwritten by the generator. | ||
|
||
.swagger-codegen-ignore | ||
|
||
src/*.cpp | ||
src/*.h | ||
|
||
!src/*Interface.h | ||
!src/*JsonObject.h | ||
!src/*JsonObject.cpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
cmake_minimum_required (VERSION 3.2) | ||
|
||
set (CMAKE_CXX_STANDARD 11) | ||
|
||
add_subdirectory(src) |
173 changes: 173 additions & 0 deletions
173
src/services/pcn-k8sdispatcher/datamodel/k8sdispatcher.yang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
module k8sdispatcher { | ||
yang-version 1.1; | ||
namespace "http://polycube.network/k8sdispatcher"; | ||
prefix "k8sdispatcher"; | ||
|
||
import polycube-base { prefix "polycube-base"; } | ||
import polycube-standard-base { prefix "polycube-standard-base"; } | ||
|
||
import ietf-inet-types { prefix "inet"; } | ||
|
||
organization "Polycube open source project"; | ||
description "YANG data model for the Polycube K8s Dispatcher"; | ||
|
||
polycube-base:service-description "K8s Dispatcher Service"; | ||
polycube-base:service-version "2.0.0"; | ||
polycube-base:service-name "k8sdispatcher"; | ||
polycube-base:service-min-kernel-version "4.14.0"; | ||
|
||
typedef l4-proto { | ||
type enumeration { | ||
enum "TCP" { | ||
value 6; | ||
description "The TCP protocol type"; | ||
} | ||
enum "UDP" { | ||
value 17; | ||
description "The UDP protocol type"; | ||
} | ||
enum "ICMP" { | ||
value 1; | ||
description "The ICMP protocol type"; | ||
} | ||
} | ||
description "L4 protocol"; | ||
} | ||
|
||
uses "polycube-standard-base:standard-base-yang-module" { | ||
augment ports { | ||
leaf type { | ||
type enumeration { | ||
enum BACKEND { description "Port connected to the internal CNI topology"; } | ||
enum FRONTEND { description "Port connected to the node NIC"; } | ||
} | ||
description "Type of the K8s Dispatcher cube port (e.g. BACKEND or FRONTEND)"; | ||
mandatory true; | ||
polycube-base:init-only-config; | ||
} | ||
leaf ip { | ||
type inet:ipv4-address; | ||
description "IP address of the node interface (only for FRONTEND port)"; | ||
polycube-base:cli-example "10.10.1.1"; | ||
polycube-base:init-only-config; | ||
} | ||
} | ||
} | ||
|
||
leaf internal-src-ip { | ||
type inet:ipv4-address; | ||
description "Internal source IP address used for natting incoming packets directed to Kubernetes Services with a CLUSTER external traffic policy"; | ||
mandatory true; | ||
polycube-base:cli-example "10.10.1.1"; | ||
polycube-base:init-only-config; | ||
} | ||
|
||
leaf nodeport-range { | ||
type string; | ||
description "Port range used for NodePort Services"; | ||
default "30000-32767"; | ||
polycube-base:cli-example "30000-32767"; | ||
} | ||
|
||
list session-rule { | ||
key "direction src-ip dst-ip src-port dst-port proto"; | ||
description "Session entry related to a specific traffic direction"; | ||
config false; | ||
|
||
leaf direction { | ||
type enumeration { | ||
enum INGRESS { | ||
description "Direction of traffic going from the internal topology to the external world"; | ||
} | ||
enum EGRESS { | ||
description "Direction of traffic going from the external world to the internal CNI topology"; | ||
} | ||
} | ||
description "Session entry direction (e.g. INGRESS or EGRESS)"; | ||
} | ||
leaf src-ip { | ||
type inet:ipv4-address; | ||
description "Session entry source IP address"; | ||
} | ||
leaf dst-ip { | ||
type inet:ipv4-address; | ||
description "Session entry destination IP address"; | ||
} | ||
leaf src-port { | ||
type inet:port-number; | ||
description "Session entry source L4 port number"; | ||
} | ||
leaf dst-port { | ||
type inet:port-number; | ||
description "Session entry destination L4 port number"; | ||
} | ||
leaf proto { | ||
type l4-proto; | ||
description "Session entry L4 protocol"; | ||
polycube-base:cli-example "TCP, UDP, ICMP"; | ||
} | ||
|
||
leaf new-ip { | ||
type inet:ipv4-address; | ||
description "Translated IP address"; | ||
config false; | ||
} | ||
leaf new-port { | ||
type inet:port-number; | ||
description "Translated L4 port number"; | ||
config false; | ||
} | ||
leaf operation { | ||
type enumeration { | ||
enum XLATE_SRC { description "The source IP and port are replaced"; } | ||
enum XLATE_DST { description "The destination IP and port are replaced"; } | ||
} | ||
description "Operation applied on the original packet"; | ||
config false; | ||
} | ||
leaf originating-rule { | ||
type enumeration { | ||
enum POD_TO_EXT { | ||
description "Traffic related to communication between a Pod and the external world"; | ||
} | ||
enum NODEPORT_CLUSTER { | ||
description "Traffic related to communication involving a NodePort Service with having a CLUSTER external traffic policy"; | ||
} | ||
} | ||
description "Rule originating the session entry"; | ||
config false; | ||
} | ||
} | ||
|
||
list nodeport-rule { | ||
key "nodeport-port proto"; | ||
description "NodePort rule associated with a Kubernetes NodePort Service"; | ||
|
||
leaf nodeport-port { | ||
type inet:port-number; | ||
description "NodePort rule nodeport port number"; | ||
polycube-base:cli-example "30500"; | ||
} | ||
leaf proto { | ||
type l4-proto; | ||
description "NodePort rule L4 protocol"; | ||
polycube-base:cli-example "TCP, UDP, ICMP"; | ||
} | ||
|
||
leaf external-traffic-policy { | ||
type enumeration { | ||
enum LOCAL { description "Incoming traffic is allowed to be served only by local backends"; } | ||
enum CLUSTER { description "Incoming traffic is allowed to be served by any backend of the cluster"; } | ||
} | ||
default CLUSTER; | ||
description "The external traffic policy of the Kubernetes NodePort Service"; | ||
} | ||
leaf rule-name { | ||
type string; | ||
description "An optional name for the NodePort rule"; | ||
polycube-base:cli-example "my-nodeport-rule"; | ||
polycube-base:init-only-config; | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
include(${PROJECT_SOURCE_DIR}/cmake/LoadFileAsVariable.cmake) | ||
|
||
aux_source_directory(serializer SERIALIZER_SOURCES) | ||
aux_source_directory(api API_SOURCES) | ||
aux_source_directory(base BASE_SOURCES) | ||
|
||
include_directories(serializer) | ||
|
||
if (NOT DEFINED POLYCUBE_STANDALONE_SERVICE OR POLYCUBE_STANDALONE_SERVICE) | ||
find_package(PkgConfig REQUIRED) | ||
pkg_check_modules(POLYCUBE libpolycube) | ||
include_directories(${POLYCUBE_INCLUDE_DIRS}) | ||
endif (NOT DEFINED POLYCUBE_STANDALONE_SERVICE OR POLYCUBE_STANDALONE_SERVICE) | ||
|
||
# Needed to load files as variables | ||
include_directories(${CMAKE_CURRENT_BINARY_DIR}) | ||
|
||
add_library(pcn-k8sdispatcher SHARED | ||
${SERIALIZER_SOURCES} | ||
${API_SOURCES} | ||
${BASE_SOURCES} | ||
K8sdispatcher.cpp | ||
NodeportRule.cpp | ||
Ports.cpp | ||
SessionRule.cpp | ||
K8sdispatcher-lib.cpp | ||
Utils.cpp) | ||
|
||
# load ebpf datapath code a variable | ||
load_file_as_variable(pcn-k8sdispatcher | ||
K8sdispatcher_dp.c | ||
k8sdispatcher_code) | ||
|
||
# load datamodel in a variable | ||
load_file_as_variable(pcn-k8sdispatcher | ||
../datamodel/k8sdispatcher.yang | ||
k8sdispatcher_datamodel) | ||
|
||
target_link_libraries(pcn-k8sdispatcher ${POLYCUBE_LIBRARIES}) | ||
|
||
# Specify shared library install directory | ||
|
||
set(CMAKE_INSTALL_LIBDIR /usr/lib) | ||
|
||
install( | ||
TARGETS | ||
pcn-k8sdispatcher | ||
DESTINATION | ||
"${CMAKE_INSTALL_LIBDIR}" | ||
) |
Oops, something went wrong.