Skip to content

Commit

Permalink
Support multicast statistics
Browse files Browse the repository at this point in the history
This PR added multicast statistics support for the following cases:

- Supplements current networkpolicy statistics implementation by parsing
  multicast related flows, which can be displayed as
  kubectl get antreanetworkpolicystats multicast-networkpolicy-name.

- Add a node-level antctl command antctl get multicaststats,
  showing inbound and outbound packet count for each pod interface.

- Add an extra kubectl get multicastgroupmembers command.
  This command shows which pods have joined multicast group
  for the whole cluster.

Signed-off-by: ceclinux <src655@gmail.com>
  • Loading branch information
ceclinux committed May 15, 2022
1 parent ff0bd60 commit e78668d
Show file tree
Hide file tree
Showing 35 changed files with 1,957 additions and 159 deletions.
3 changes: 3 additions & 0 deletions build/charts/antrea/conf/antrea-controller.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ featureGates:
# Enable collecting and exposing NetworkPolicy statistics.
{{- include "featureGate" (dict "featureGates" .Values.featureGates "name" "NetworkPolicyStats" "default" true) }}

# Enable multicast traffic. This feature is supported only with noEncap mode.
{{- include "featureGate" (dict "featureGates" .Values.featureGates "name" "Multicast" "default" false) }}

# Enable controlling SNAT IPs of Pod egress traffic.
{{- include "featureGate" (dict "featureGates" .Values.featureGates "name" "Egress" "default" true) }}

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 @@ -319,6 +319,9 @@ data:
# Enable collecting and exposing NetworkPolicy statistics.
# NetworkPolicyStats: true
# Enable multicast traffic. This feature is supported only with noEncap mode.
# Multicast: false
# Enable controlling SNAT IPs of Pod egress traffic.
# Egress: true
Expand Down Expand Up @@ -3517,7 +3520,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: 4554a36b927c6e64fdbc53b4d4c64673d48c9c829ec444e3be6e699ade8481b6
checksum/config: 781ffc2b1ad3c5e5ae33b35c6f707998a4e05d3b144bdd9ca17c8f1f692f54f4
labels:
app: antrea
component: antrea-agent
Expand Down Expand Up @@ -3757,7 +3760,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: 4554a36b927c6e64fdbc53b4d4c64673d48c9c829ec444e3be6e699ade8481b6
checksum/config: 781ffc2b1ad3c5e5ae33b35c6f707998a4e05d3b144bdd9ca17c8f1f692f54f4
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 @@ -319,6 +319,9 @@ data:
# Enable collecting and exposing NetworkPolicy statistics.
# NetworkPolicyStats: true
# Enable multicast traffic. This feature is supported only with noEncap mode.
# Multicast: false
# Enable controlling SNAT IPs of Pod egress traffic.
# Egress: true
Expand Down Expand Up @@ -3517,7 +3520,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: 4554a36b927c6e64fdbc53b4d4c64673d48c9c829ec444e3be6e699ade8481b6
checksum/config: 781ffc2b1ad3c5e5ae33b35c6f707998a4e05d3b144bdd9ca17c8f1f692f54f4
labels:
app: antrea
component: antrea-agent
Expand Down Expand Up @@ -3759,7 +3762,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: 4554a36b927c6e64fdbc53b4d4c64673d48c9c829ec444e3be6e699ade8481b6
checksum/config: 781ffc2b1ad3c5e5ae33b35c6f707998a4e05d3b144bdd9ca17c8f1f692f54f4
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 @@ -319,6 +319,9 @@ data:
# Enable collecting and exposing NetworkPolicy statistics.
# NetworkPolicyStats: true
# Enable multicast traffic. This feature is supported only with noEncap mode.
# Multicast: false
# Enable controlling SNAT IPs of Pod egress traffic.
# Egress: true
Expand Down Expand Up @@ -3517,7 +3520,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: edef4c00e4f28a10dc1e077086ef68641a9a3b53d0fe7d47ff3dafc2ce5d5c9b
checksum/config: 5ffb7abdf639485d4d2c5132a42453e75134a875e7f6be684500d179c70a52cc
labels:
app: antrea
component: antrea-agent
Expand Down Expand Up @@ -3757,7 +3760,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: edef4c00e4f28a10dc1e077086ef68641a9a3b53d0fe7d47ff3dafc2ce5d5c9b
checksum/config: 5ffb7abdf639485d4d2c5132a42453e75134a875e7f6be684500d179c70a52cc
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 @@ -332,6 +332,9 @@ data:
# Enable collecting and exposing NetworkPolicy statistics.
# NetworkPolicyStats: true
# Enable multicast traffic. This feature is supported only with noEncap mode.
# Multicast: false
# Enable controlling SNAT IPs of Pod egress traffic.
# Egress: true
Expand Down Expand Up @@ -3530,7 +3533,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: 50cc962db93c0354f5eaa088e51d690e779692979cbafac0c3e27a88fc2c0c7c
checksum/config: 222e80b392cb7610647055a4300bb466d819d54d5d5380031c6fc4e4f6d2da5b
checksum/ipsec-secret: d0eb9c52d0cd4311b6d252a951126bf9bea27ec05590bed8a394f0f792dcb2a4
labels:
app: antrea
Expand Down Expand Up @@ -3806,7 +3809,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: 50cc962db93c0354f5eaa088e51d690e779692979cbafac0c3e27a88fc2c0c7c
checksum/config: 222e80b392cb7610647055a4300bb466d819d54d5d5380031c6fc4e4f6d2da5b
labels:
app: antrea
component: antrea-controller
Expand Down
23 changes: 10 additions & 13 deletions cmd/antrea-agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,6 @@ func run(o *Options) error {
return fmt.Errorf("error creating new NetworkPolicy controller: %v", err)
}

// statsCollector collects stats and reports to the antrea-controller periodically. For now it's only used for
// NetworkPolicy stats.
var statsCollector *stats.Collector
if features.DefaultFeatureGate.Enabled(features.NetworkPolicyStats) {
statsCollector = stats.NewCollector(antreaClientProvider, ofClient, networkPolicyController)
}

var egressController *egress.EgressController

var externalIPPoolController *externalippool.ExternalIPPoolController
Expand Down Expand Up @@ -560,10 +553,6 @@ func run(o *Options) error {
go externalIPController.Run(stopCh)
}

if features.DefaultFeatureGate.Enabled(features.NetworkPolicyStats) {
go statsCollector.Run(stopCh)
}

if features.DefaultFeatureGate.Enabled(features.Traceflow) {
go traceflowController.Run(stopCh)
}
Expand All @@ -585,13 +574,13 @@ func run(o *Options) error {
klog.InfoS("AntreaProxy is ready")
}
}

var mcastController *multicast.Controller
if multicastEnabled {
multicastSocket, err := multicast.CreateMulticastSocket()
if err != nil {
return fmt.Errorf("failed to create multicast socket")
}
mcastController := multicast.NewMulticastController(
mcastController = multicast.NewMulticastController(
ofClient,
v4GroupIDAllocator,
nodeConfig,
Expand All @@ -608,6 +597,13 @@ func run(o *Options) error {
go mcastController.Run(stopCh)
}

// statsCollector collects stats and reports to the antrea-controller periodically. For now it's only used for
// NetworkPolicy stats and Multicast stats.
var statsCollector *stats.Collector
if features.DefaultFeatureGate.Enabled(features.NetworkPolicyStats) {
statsCollector = stats.NewCollector(antreaClientProvider, ofClient, networkPolicyController, mcastController, multicastEnabled)
go statsCollector.Run(stopCh)
}
agentQuerier := querier.NewAgentQuerier(
nodeConfig,
networkConfig,
Expand All @@ -617,6 +613,7 @@ func run(o *Options) error {
ovsBridgeClient,
proxier,
networkPolicyController,
mcastController,
o.config.APIPort)

agentMonitor := monitor.NewAgentMonitor(crdClient, agentQuerier)
Expand Down
2 changes: 2 additions & 0 deletions pkg/agent/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"antrea.io/antrea/pkg/agent/apiserver/handlers/agentinfo"
"antrea.io/antrea/pkg/agent/apiserver/handlers/appliedtogroup"
"antrea.io/antrea/pkg/agent/apiserver/handlers/featuregates"
"antrea.io/antrea/pkg/agent/apiserver/handlers/multicast"
"antrea.io/antrea/pkg/agent/apiserver/handlers/networkpolicy"
"antrea.io/antrea/pkg/agent/apiserver/handlers/ovsflows"
"antrea.io/antrea/pkg/agent/apiserver/handlers/ovstracing"
Expand Down Expand Up @@ -74,6 +75,7 @@ func (s *agentAPIServer) Run(stopCh <-chan struct{}) error {

func installHandlers(aq agentquerier.AgentQuerier, npq querier.AgentNetworkPolicyInfoQuerier, s *genericapiserver.GenericAPIServer) {
s.Handler.NonGoRestfulMux.HandleFunc("/loglevel", loglevel.HandleFunc())
s.Handler.NonGoRestfulMux.HandleFunc("/multicaststats", multicast.HandleFunc(aq))
s.Handler.NonGoRestfulMux.HandleFunc("/featuregates", featuregates.HandleFunc())
s.Handler.NonGoRestfulMux.HandleFunc("/agentinfo", agentinfo.HandleFunc(aq))
s.Handler.NonGoRestfulMux.HandleFunc("/podinterfaces", podinterface.HandleFunc(aq))
Expand Down
78 changes: 78 additions & 0 deletions pkg/agent/apiserver/handlers/multicast/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2022 Antrea Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package multicast

import (
"encoding/json"
"net/http"
"strconv"

"antrea.io/antrea/pkg/agent/interfacestore"
"antrea.io/antrea/pkg/agent/multicast"
"antrea.io/antrea/pkg/agent/querier"
"antrea.io/antrea/pkg/antctl/transform/common"
"antrea.io/antrea/pkg/features"
)

type Response struct {
PodString string `json:"podString,omitempty"`
Inbound string `json:"inbound,omitempty"`
Outbound string `json:"outbound,omitempty"`
}

func generateResponse(iface *interfacestore.InterfaceConfig, trafficStats *multicast.PodTrafficStats) Response {
return Response{
PodString: iface.PodNamespace + "/" + iface.PodName,
Inbound: strconv.FormatInt(int64(trafficStats.Inbound), 10),
Outbound: strconv.FormatInt(int64(trafficStats.Outbound), 10),
}
}

// HandleFunc returns the function which can handle queries issued by 'antctl get multicaststats' command.
// It will return per-pod multicast traffic statistics for the local node.
func HandleFunc(aq querier.AgentQuerier) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if !features.DefaultFeatureGate.Enabled(features.Multicast) {
http.Error(w, "Multicast is not enabled", http.StatusServiceUnavailable)
return
}
stats := aq.GetMulticastInfoQuerier().GetPerPodStats()
responses := make([]Response, 0)
for iface, trafficStats := range stats {
if trafficStats.Inbound == 0 && trafficStats.Outbound == 0 {
continue
}
responses = append(responses, generateResponse(iface, trafficStats))
}
err := json.NewEncoder(w).Encode(responses)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
}
}
}

var _ common.TableOutput = new(Response)

func (r Response) GetTableHeader() []string {
return []string{"POD", "INBOUND", "OUTBOUND"}
}

func (r Response) GetTableRow(_ int) []string {
return []string{r.PodString, r.Inbound, r.Outbound}
}

func (r Response) SortRows() bool {
return true
}
Loading

0 comments on commit e78668d

Please sign in to comment.