Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L7 Network Flow Export support in Antrea #5218

Merged
merged 2 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build/charts/antrea/conf/antrea-agent.conf
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ featureGates:
# Allow users to apply ClusterNetworkPolicy to Kubernetes Nodes.
{{- include "featureGate" (dict "featureGates" .Values.featureGates "name" "NodeNetworkPolicy" "default" false) }}

# Enable L7FlowExporter on Pods and Namespaces to export the application layer flows such as HTTP flows.
{{- include "featureGate" (dict "featureGates" .Values.featureGates "name" "L7FlowExporter" "default" false) }}

# Name of the OpenVSwitch bridge antrea-agent will create and use.
# Make sure it doesn't conflict with your existing OpenVSwitch bridges.
ovsBridge: {{ .Values.ovs.bridgeName | quote }}
Expand Down
7 changes: 5 additions & 2 deletions build/yamls/antrea-aks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5628,6 +5628,9 @@ data:
# Allow users to apply ClusterNetworkPolicy to Kubernetes Nodes.
# NodeNetworkPolicy: false

# Enable L7FlowExporter on Pods and Namespaces to export the application layer flows such as HTTP flows.
# L7FlowExporter: false

# Name of the OpenVSwitch bridge antrea-agent will create and use.
# Make sure it doesn't conflict with your existing OpenVSwitch bridges.
ovsBridge: "br-int"
Expand Down Expand Up @@ -6928,7 +6931,7 @@ spec:
kubectl.kubernetes.io/default-container: antrea-agent
# Automatically restart Pods with a RollingUpdate if the ConfigMap changes
# See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/config: f4ad8910666191c02982d1b7b202e3c4bd20fb4a8179dcb5696119f3b1490a72
checksum/config: 30843b57762c91dfcffb560917191e3bc7e662c06552759bac2a173bc060b82c
labels:
app: antrea
component: antrea-agent
Expand Down Expand Up @@ -7166,7 +7169,7 @@ spec:
annotations:
# Automatically restart Pod if the ConfigMap changes
# See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/config: f4ad8910666191c02982d1b7b202e3c4bd20fb4a8179dcb5696119f3b1490a72
checksum/config: 30843b57762c91dfcffb560917191e3bc7e662c06552759bac2a173bc060b82c
labels:
app: antrea
component: antrea-controller
Expand Down
7 changes: 5 additions & 2 deletions build/yamls/antrea-eks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5628,6 +5628,9 @@ data:
# Allow users to apply ClusterNetworkPolicy to Kubernetes Nodes.
# NodeNetworkPolicy: false

# Enable L7FlowExporter on Pods and Namespaces to export the application layer flows such as HTTP flows.
# L7FlowExporter: false

# Name of the OpenVSwitch bridge antrea-agent will create and use.
# Make sure it doesn't conflict with your existing OpenVSwitch bridges.
ovsBridge: "br-int"
Expand Down Expand Up @@ -6928,7 +6931,7 @@ spec:
kubectl.kubernetes.io/default-container: antrea-agent
# Automatically restart Pods with a RollingUpdate if the ConfigMap changes
# See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/config: f4ad8910666191c02982d1b7b202e3c4bd20fb4a8179dcb5696119f3b1490a72
checksum/config: 30843b57762c91dfcffb560917191e3bc7e662c06552759bac2a173bc060b82c
labels:
app: antrea
component: antrea-agent
Expand Down Expand Up @@ -7167,7 +7170,7 @@ spec:
annotations:
# Automatically restart Pod if the ConfigMap changes
# See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/config: f4ad8910666191c02982d1b7b202e3c4bd20fb4a8179dcb5696119f3b1490a72
checksum/config: 30843b57762c91dfcffb560917191e3bc7e662c06552759bac2a173bc060b82c
labels:
app: antrea
component: antrea-controller
Expand Down
7 changes: 5 additions & 2 deletions build/yamls/antrea-gke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5628,6 +5628,9 @@ data:
# Allow users to apply ClusterNetworkPolicy to Kubernetes Nodes.
# NodeNetworkPolicy: false

# Enable L7FlowExporter on Pods and Namespaces to export the application layer flows such as HTTP flows.
# L7FlowExporter: false

# Name of the OpenVSwitch bridge antrea-agent will create and use.
# Make sure it doesn't conflict with your existing OpenVSwitch bridges.
ovsBridge: "br-int"
Expand Down Expand Up @@ -6928,7 +6931,7 @@ spec:
kubectl.kubernetes.io/default-container: antrea-agent
# Automatically restart Pods with a RollingUpdate if the ConfigMap changes
# See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/config: a54768c79d693083be554386f268c93bbbd0fdf5b334edd9aff31c13151c4e29
checksum/config: d5cdb5356795c44a69c66fad1b4d67f7c00cdcbe837f3b3b50260e4d9dfd1e7e
labels:
app: antrea
component: antrea-agent
Expand Down Expand Up @@ -7164,7 +7167,7 @@ spec:
annotations:
# Automatically restart Pod if the ConfigMap changes
# See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/config: a54768c79d693083be554386f268c93bbbd0fdf5b334edd9aff31c13151c4e29
checksum/config: d5cdb5356795c44a69c66fad1b4d67f7c00cdcbe837f3b3b50260e4d9dfd1e7e
labels:
app: antrea
component: antrea-controller
Expand Down
7 changes: 5 additions & 2 deletions build/yamls/antrea-ipsec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5641,6 +5641,9 @@ data:
# Allow users to apply ClusterNetworkPolicy to Kubernetes Nodes.
# NodeNetworkPolicy: false

# Enable L7FlowExporter on Pods and Namespaces to export the application layer flows such as HTTP flows.
# L7FlowExporter: false

# Name of the OpenVSwitch bridge antrea-agent will create and use.
# Make sure it doesn't conflict with your existing OpenVSwitch bridges.
ovsBridge: "br-int"
Expand Down Expand Up @@ -6941,7 +6944,7 @@ spec:
kubectl.kubernetes.io/default-container: antrea-agent
# Automatically restart Pods with a RollingUpdate if the ConfigMap changes
# See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/config: 7ce7d85bc08079d1cef3b1d44f31e2139961f9ae49f71d79ff3b28e7e9ad6325
checksum/config: 50f2864cf09e4732327b963130bd59a9fc06c560784b161c94e813c000367615
checksum/ipsec-secret: d0eb9c52d0cd4311b6d252a951126bf9bea27ec05590bed8a394f0f792dcb2a4
labels:
app: antrea
Expand Down Expand Up @@ -7223,7 +7226,7 @@ spec:
annotations:
# Automatically restart Pod if the ConfigMap changes
# See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/config: 7ce7d85bc08079d1cef3b1d44f31e2139961f9ae49f71d79ff3b28e7e9ad6325
checksum/config: 50f2864cf09e4732327b963130bd59a9fc06c560784b161c94e813c000367615
labels:
app: antrea
component: antrea-controller
Expand Down
7 changes: 5 additions & 2 deletions build/yamls/antrea.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5628,6 +5628,9 @@ data:
# Allow users to apply ClusterNetworkPolicy to Kubernetes Nodes.
# NodeNetworkPolicy: false

# Enable L7FlowExporter on Pods and Namespaces to export the application layer flows such as HTTP flows.
# L7FlowExporter: false

# Name of the OpenVSwitch bridge antrea-agent will create and use.
# Make sure it doesn't conflict with your existing OpenVSwitch bridges.
ovsBridge: "br-int"
Expand Down Expand Up @@ -6928,7 +6931,7 @@ spec:
kubectl.kubernetes.io/default-container: antrea-agent
# Automatically restart Pods with a RollingUpdate if the ConfigMap changes
# See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/config: 290f0c748863a7dad1e9d53d62c74f8108a44c5cc803306d351c108062cc1378
checksum/config: ac3c14eed7ca0dc28bf2d659cd2c4e4a39d55278fb9a8759c30ea12eff89e518
labels:
app: antrea
component: antrea-agent
Expand Down Expand Up @@ -7164,7 +7167,7 @@ spec:
annotations:
# Automatically restart Pod if the ConfigMap changes
# See https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
checksum/config: 290f0c748863a7dad1e9d53d62c74f8108a44c5cc803306d351c108062cc1378
checksum/config: ac3c14eed7ca0dc28bf2d659cd2c4e4a39d55278fb9a8759c30ea12eff89e518
labels:
app: antrea
component: antrea-controller
Expand Down
2 changes: 1 addition & 1 deletion ci/kind/test-e2e-kind.sh
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ if $multicast; then
manifest_args="$manifest_args --multicast"
fi
if $flow_visibility; then
manifest_args="$manifest_args --feature-gates FlowExporter=true --extra-helm-values-file $FLOW_VISIBILITY_HELM_VALUES"
manifest_args="$manifest_args --feature-gates FlowExporter=true,L7FlowExporter=true --extra-helm-values-file $FLOW_VISIBILITY_HELM_VALUES"
fi

COMMON_IMAGES_LIST=("registry.k8s.io/e2e-test-images/agnhost:2.29" \
Expand Down
27 changes: 25 additions & 2 deletions cmd/antrea-agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ import (
"antrea.io/antrea/pkg/agent/config"
"antrea.io/antrea/pkg/agent/controller/egress"
"antrea.io/antrea/pkg/agent/controller/ipseccertificate"
"antrea.io/antrea/pkg/agent/controller/l7flowexporter"
"antrea.io/antrea/pkg/agent/controller/networkpolicy"
"antrea.io/antrea/pkg/agent/controller/networkpolicy/l7engine"
"antrea.io/antrea/pkg/agent/controller/noderoute"
"antrea.io/antrea/pkg/agent/controller/serviceexternalip"
"antrea.io/antrea/pkg/agent/controller/traceflow"
Expand Down Expand Up @@ -141,6 +143,7 @@ func run(o *Options) error {
enableBridgingMode := enableAntreaIPAM && o.config.EnableBridgingMode
l7NetworkPolicyEnabled := features.DefaultFeatureGate.Enabled(features.L7NetworkPolicy)
nodeNetworkPolicyEnabled := features.DefaultFeatureGate.Enabled(features.NodeNetworkPolicy)
l7FlowExporterEnabled := features.DefaultFeatureGate.Enabled(features.L7FlowExporter)
enableMulticlusterGW := features.DefaultFeatureGate.Enabled(features.Multicluster) && o.config.Multicluster.EnableGateway
enableMulticlusterNP := features.DefaultFeatureGate.Enabled(features.Multicluster) && o.config.Multicluster.EnableStretchedNetworkPolicy
enableFlowExporter := features.DefaultFeatureGate.Enabled(features.FlowExporter) && o.config.FlowExporter.Enable
Expand Down Expand Up @@ -170,6 +173,7 @@ func run(o *Options) error {
connectUplinkToBridge,
multicastEnabled,
features.DefaultFeatureGate.Enabled(features.TrafficControl),
l7FlowExporterEnabled,
enableMulticlusterGW,
groupIDAllocator,
*o.config.EnablePrometheusMetrics,
Expand Down Expand Up @@ -292,7 +296,8 @@ func run(o *Options) error {
o.config.ExternalNode.ExternalNodeNamespace,
connectUplinkToBridge,
o.enableAntreaProxy,
l7NetworkPolicyEnabled)
l7NetworkPolicyEnabled,
l7FlowExporterEnabled)
err = agentInitializer.Initialize()
if err != nil {
return fmt.Errorf("error initializing agent: %v", err)
Expand Down Expand Up @@ -466,6 +471,10 @@ func run(o *Options) error {
if o.nodeType == config.ExternalNode {
nodeKey = k8s.NamespacedName(o.config.ExternalNode.ExternalNodeNamespace, nodeKey)
}
var l7Reconciler *l7engine.Reconciler
if l7NetworkPolicyEnabled || l7FlowExporterEnabled {
l7Reconciler = l7engine.NewReconciler()
}
networkPolicyController, err := networkpolicy.NewNetworkPolicyController(
antreaClientProvider,
ofClient,
Expand Down Expand Up @@ -493,10 +502,22 @@ func run(o *Options) error {
tunPort,
nodeConfig,
podNetworkWait,
l7Reconciler,
)
if err != nil {
return fmt.Errorf("error creating new NetworkPolicy controller: %v", err)
}
var l7FlowExporterController *l7flowexporter.L7FlowExporterController
if l7FlowExporterEnabled {
l7FlowExporterController = l7flowexporter.NewL7FlowExporterController(
ofClient,
ifaceStore,
localPodInformer.Get(),
namespaceInformer,
l7Reconciler,
)
go l7FlowExporterController.Run(stopCh)
}

var egressController *egress.EgressController

Expand Down Expand Up @@ -650,7 +671,9 @@ func run(o *Options) error {
o.enableAntreaProxy,
networkPolicyController,
flowExporterOptions,
egressController)
egressController,
l7FlowExporterController,
l7FlowExporterEnabled)
if err != nil {
return fmt.Errorf("error when creating IPFIX flow exporter: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion docs/antrea-l7-network-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ forwarded to an application-aware engine for protocol detection and rule enforce
the layer 7 criteria is also matched, otherwise it will be dropped. Therefore, any rules after a layer 7 rule will not
be enforced for the traffic that match the layer 7 rule's layer 3/4 criteria.

As of now, the only supported layer 7 protocol is HTTP. More protocols will be supported in the near future, and we
As of now, the only supported layer 7 protocol is HTTP. Support for more protocols may be added in the future and we
welcome feature requests for protocols that you are interested in.

### HTTP
Expand Down
10 changes: 10 additions & 0 deletions docs/feature-gates.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ edit the Agent configuration in the
| `EgressTrafficShaping` | Agent | `false` | Alpha | v1.14 | N/A | N/A | Yes | OVS meters should be supported |
| `EgressSeparateSubnet` | Agent | `false` | Alpha | v1.15 | N/A | N/A | No | |
| `NodeNetworkPolicy` | Agent | `false` | Alpha | v1.15 | N/A | N/A | Yes | |
| `L7FlowExporter` | Agent | `false` | Alpha | v1.15 | N/A | N/A | Yes | |

## Description and Requirements of Features

Expand Down Expand Up @@ -428,3 +429,12 @@ to be supported in the datapath.

`EgressSeparateSubnet` allows users to allocate Egress IPs from a different subnet from the default Node subnet.
Refer to this [document](egress.md#subnetinfo) for more information.

### L7FlowExporter

`L7FlowExporter` enables users to export application-layer flow data using Pod or Namespace annotations.
Refer to this [document](network-flow-visibility.md#l7-visibility) for more information.

#### Requirements for this Feature

- Linux Nodes only.
59 changes: 59 additions & 0 deletions docs/network-flow-visibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
- [Output Flow Records](#output-flow-records)
- [Grafana Flow Collector (migrated)](#grafana-flow-collector-migrated)
- [ELK Flow Collector (removed)](#elk-flow-collector-removed)
- [Layer 7 Network Flow Exporter](#layer-7-network-flow-exporter)
- [Prerequisites](#prerequisites)
- [Usage](#usage)
<!-- /toc -->

## Overview
Expand Down Expand Up @@ -610,3 +613,59 @@ and other Theia features, please refer to the
**Starting with Antrea v1.7, support for the ELK Flow Collector has been removed.**
Please consider using the [Grafana Flow Collector](#grafana-flow-collector-migrated)
instead, which is actively maintained.

## Layer 7 Network Flow Exporter

In addition to layer 4 network visibility, Antrea adds layer 7 network flow
export.

### Prerequisites

To achieve L7 (Layer 7) network flow export, the `L7FlowExporter` feature gate
must be enabled.

### Usage

To export layer 7 flows of a Pod or a Namespace, user can annotate Pods or
Namespaces with the annotation key `visibility.antrea.io/l7-export` and set the
value to indicate the traffic flow direction, which can be `ingress`, `egress`
or `both`.

For example, to enable L7 flow export in the ingress direction on
Pod test-pod in the default Namespace, you can use:

```bash
kubectl annotate pod test-pod visibility.antrea.io/l7-export=ingress
```

Based on the annotation, Flow Exporter will export the L7 flow data to the
Flow Aggregator or configured IPFix collector using the fields `appProtocolName`
and `httpVals`.

* `appProtocolName` field is used to indicate the application layer protocol
name (e.g. http) and it will be empty if application layer data is not exported.
* `httpVals` stores a serialized JSON dictionary with every HTTP request for
a connection mapped to a unique transaction ID. This format lets us group all
the HTTP transactions pertaining to the same connection, into the same exported
record.

An example of `httpVals` is :

`"{\"0\":{\"hostname\":\"10.10.0.1\",\"url\":\"/public/\",\"http_user_agent\":\"curl/7.74.0\",\"http_content_type\":\"text/html\",\"http_method\":\"GET\",\"protocol\":\"HTTP/1.1\",\"status\":200,\"length\":153}}"`

HTTP fields in the `httpVals` are:

| Http field | Description |
|-------------------|--------------------------------------------------------|
| hostname | IP address of the sender |
| URL | url requested on the server |
| http_user_agent | application used for HTTP |
| http_content_type | type of content being returned by the server |
| http_method | HTTP method used for the request |
| protocol | HTTP protocol version used for the request or response |
| status | HTTP status code |
| length | size of the response body |

As of now, the only supported layer 7 protocol is `HTTP1.1`. Support for more
protocols may be added in the future. Antrea supports L7FlowExporter feature only
on Linux Nodes.
9 changes: 6 additions & 3 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ type Initializer struct {
serviceConfig *config.ServiceConfig
l7NetworkPolicyConfig *config.L7NetworkPolicyConfig
enableL7NetworkPolicy bool
enableL7FlowExporter bool
connectUplinkToBridge bool
enableAntreaProxy bool
// podNetworkWait should be decremented once the Node's network is ready.
Expand Down Expand Up @@ -151,6 +152,7 @@ func NewInitializer(
connectUplinkToBridge bool,
enableAntreaProxy bool,
enableL7NetworkPolicy bool,
enableL7FlowExporter bool,
) *Initializer {
return &Initializer{
ovsBridgeClient: ovsBridgeClient,
Expand All @@ -175,6 +177,7 @@ func NewInitializer(
connectUplinkToBridge: connectUplinkToBridge,
enableAntreaProxy: enableAntreaProxy,
enableL7NetworkPolicy: enableL7NetworkPolicy,
enableL7FlowExporter: enableL7FlowExporter,
}
}

Expand Down Expand Up @@ -423,9 +426,9 @@ func (i *Initializer) Initialize() error {
return err
}

if i.enableL7NetworkPolicy {
// prepareL7NetworkPolicyInterfaces must be executed after setupOVSBridge since it requires interfaceStore.
if err := i.prepareL7NetworkPolicyInterfaces(); err != nil {
if i.enableL7NetworkPolicy || i.enableL7FlowExporter {
// prepareL7EngineInterfaces must be executed after setupOVSBridge since it requires interfaceStore.
if err := i.prepareL7EngineInterfaces(); err != nil {
return err
}
}
Expand Down
Loading
Loading