diff --git a/build/charts/antrea/templates/webhooks/validating/crdvalidator.yaml b/build/charts/antrea/templates/webhooks/validating/crdvalidator.yaml index 0dfe1f8acd3..9bc1141c009 100644 --- a/build/charts/antrea/templates/webhooks/validating/crdvalidator.yaml +++ b/build/charts/antrea/templates/webhooks/validating/crdvalidator.yaml @@ -184,3 +184,18 @@ webhooks: admissionReviewVersions: ["v1", "v1beta1"] sideEffects: None timeoutSeconds: 5 + - name: "packetsamplingvalidator.antrea.io" + clientConfig: + service: + name: "antrea" + namespace: {{ .Release.Namespace }} + path: "/validate/packetsampling" + rules: + - operations: ["CREATE", "UPDATE"] + apiGroups: ["crd.antrea.io"] + apiVersions: ["v1alpha1"] + resources: ["packetsampling"] + scope: "Cluster" + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + timeoutSeconds: 5 \ No newline at end of file diff --git a/build/yamls/antrea-aks.yml b/build/yamls/antrea-aks.yml index fce8bdd5e94..c80204b5d27 100644 --- a/build/yamls/antrea-aks.yml +++ b/build/yamls/antrea-aks.yml @@ -7647,3 +7647,18 @@ webhooks: admissionReviewVersions: ["v1", "v1beta1"] sideEffects: None timeoutSeconds: 5 + - name: "packetsamplingvalidator.antrea.io" + clientConfig: + service: + name: "antrea" + namespace: kube-system + path: "/validate/packetsampling" + rules: + - operations: ["CREATE", "UPDATE"] + apiGroups: ["crd.antrea.io"] + apiVersions: ["v1alpha1"] + resources: ["packetsampling"] + scope: "Cluster" + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + timeoutSeconds: 5 diff --git a/build/yamls/antrea-eks.yml b/build/yamls/antrea-eks.yml index 95f1957e5ff..9c2ab1bd00d 100644 --- a/build/yamls/antrea-eks.yml +++ b/build/yamls/antrea-eks.yml @@ -7648,3 +7648,18 @@ webhooks: admissionReviewVersions: ["v1", "v1beta1"] sideEffects: None timeoutSeconds: 5 + - name: "packetsamplingvalidator.antrea.io" + clientConfig: + service: + name: "antrea" + namespace: kube-system + path: "/validate/packetsampling" + rules: + - operations: ["CREATE", "UPDATE"] + apiGroups: ["crd.antrea.io"] + apiVersions: ["v1alpha1"] + resources: ["packetsampling"] + scope: "Cluster" + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + timeoutSeconds: 5 diff --git a/build/yamls/antrea-gke.yml b/build/yamls/antrea-gke.yml index 377c73e027b..a150740409c 100644 --- a/build/yamls/antrea-gke.yml +++ b/build/yamls/antrea-gke.yml @@ -7645,3 +7645,18 @@ webhooks: admissionReviewVersions: ["v1", "v1beta1"] sideEffects: None timeoutSeconds: 5 + - name: "packetsamplingvalidator.antrea.io" + clientConfig: + service: + name: "antrea" + namespace: kube-system + path: "/validate/packetsampling" + rules: + - operations: ["CREATE", "UPDATE"] + apiGroups: ["crd.antrea.io"] + apiVersions: ["v1alpha1"] + resources: ["packetsampling"] + scope: "Cluster" + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + timeoutSeconds: 5 diff --git a/build/yamls/antrea-ipsec.yml b/build/yamls/antrea-ipsec.yml index a40fee8991c..90bea4181fc 100644 --- a/build/yamls/antrea-ipsec.yml +++ b/build/yamls/antrea-ipsec.yml @@ -7704,3 +7704,18 @@ webhooks: admissionReviewVersions: ["v1", "v1beta1"] sideEffects: None timeoutSeconds: 5 + - name: "packetsamplingvalidator.antrea.io" + clientConfig: + service: + name: "antrea" + namespace: kube-system + path: "/validate/packetsampling" + rules: + - operations: ["CREATE", "UPDATE"] + apiGroups: ["crd.antrea.io"] + apiVersions: ["v1alpha1"] + resources: ["packetsampling"] + scope: "Cluster" + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + timeoutSeconds: 5 diff --git a/build/yamls/antrea.yml b/build/yamls/antrea.yml index a89948c8288..b60fb0caabc 100644 --- a/build/yamls/antrea.yml +++ b/build/yamls/antrea.yml @@ -7645,3 +7645,18 @@ webhooks: admissionReviewVersions: ["v1", "v1beta1"] sideEffects: None timeoutSeconds: 5 + - name: "packetsamplingvalidator.antrea.io" + clientConfig: + service: + name: "antrea" + namespace: kube-system + path: "/validate/packetsampling" + rules: + - operations: ["CREATE", "UPDATE"] + apiGroups: ["crd.antrea.io"] + apiVersions: ["v1alpha1"] + resources: ["packetsampling"] + scope: "Cluster" + admissionReviewVersions: ["v1", "v1beta1"] + sideEffects: None + timeoutSeconds: 5 diff --git a/pkg/agent/controller/packetsampling/packetin.go b/pkg/agent/controller/packetsampling/packetin.go index 3057385ce0b..2bc2c884341 100644 --- a/pkg/agent/controller/packetsampling/packetin.go +++ b/pkg/agent/controller/packetsampling/packetin.go @@ -33,11 +33,11 @@ import ( // Once the total number reaches the target one, the PacketSampling will be marked as Succeed. func (c *Controller) HandlePacketIn(pktIn *ofctrl.PacketIn) error { klog.V(4).InfoS("PacketIn for PacketSampling", "PacketIn", pktIn.PacketIn) - samplingState, shouldSkip, err := c.parsePacketIn(pktIn) + samplingState, samplingFinished, err := c.parsePacketIn(pktIn) if err != nil { return fmt.Errorf("parsePacketIn error: %v", err) } - if shouldSkip { + if samplingFinished { return nil } ps, err := c.packetSamplingInformer.Lister().Get(samplingState.name) @@ -54,7 +54,7 @@ func (c *Controller) HandlePacketIn(pktIn *ofctrl.PacketIn) error { if err != nil { return fmt.Errorf("failed to update the PacketSampling: %w", err) } - klog.InfoS("Updated PacketSampling", "ps", klog.KObj(ps), "status", update.Status) + klog.InfoS("Updated PacketSampling", "packetsampling", klog.KObj(ps), "status", update.Status) if samplingState != nil { rawData := pktIn.Data.(*util.Buffer).Bytes() ci := gopacket.CaptureInfo{ @@ -80,7 +80,7 @@ func (c *Controller) HandlePacketIn(pktIn *ofctrl.PacketIn) error { // parsePacketIn parses the packet-in message and returns // 1. the sampling state of the PacketSampling (on sampling mode) -func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (_ *packetSamplingState, shouldSkip bool, _ error) { +func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (_ *packetSamplingState, samplingFinished bool, _ error) { var tag uint8 samplingState := packetSamplingState{} matchers := pktIn.GetMatches() diff --git a/pkg/agent/controller/packetsampling/packetsampling_controller.go b/pkg/agent/controller/packetsampling/packetsampling_controller.go index 4bef50e44cc..319d89108d5 100644 --- a/pkg/agent/controller/packetsampling/packetsampling_controller.go +++ b/pkg/agent/controller/packetsampling/packetsampling_controller.go @@ -87,7 +87,7 @@ var ( ) func getPacketDirectory() string { - return filepath.Join(os.TempDir(), "packetsampling", "packets") + return filepath.Join(os.TempDir(), "antrea", "packetsampling", "packets") } type packetSamplingState struct { diff --git a/pkg/apis/crd/v1alpha1/types.go b/pkg/apis/crd/v1alpha1/types.go index 8659318e4a4..b8c820c2b09 100644 --- a/pkg/apis/crd/v1alpha1/types.go +++ b/pkg/apis/crd/v1alpha1/types.go @@ -978,20 +978,29 @@ type PacketSampling struct { } type PacketSamplingSpec struct { - Timeout uint16 `json:"timeout,omitempty"` - Type PacketSamplingType `json:"type,omitempty"` - FirstNSamplingConfig *FirstNSamplingConfig `json:"firstNSamplingConfig,omitempty"` - Source Source `json:"source,omitempty"` - Destination Destination `json:"destination,omitempty"` - Packet Packet `json:"packet,omitempty"` - FileServer BundleFileServer `json:"fileServer,omitempty"` - Authentication BundleServerAuthConfiguration `json:"authentication,omitempty"` + Timeout uint16 `json:"timeout,omitempty"` + // Type is the sampling type. Currently only FirstN is supported. + Type PacketSamplingType `json:"type,omitempty"` + // FirstNSamplingConfig contains the config for the FirstN type sampling. The only supported parameter is + // `Number` at the moment, means capture the first specified number of packet in a flow. + FirstNSamplingConfig *FirstNSamplingConfig `json:"firstNSamplingConfig,omitempty"` + Source Source `json:"source,omitempty"` + Destination Destination `json:"destination,omitempty"` + Packet Packet `json:"packet,omitempty"` + // FileServer the sftp url config for the fileServer. Captured packets will be uploaded to this server. + FileServer BundleFileServer `json:"fileServer,omitempty"` + Authentication BundleServerAuthConfiguration `json:"authentication,omitempty"` } type PacketSamplingStatus struct { - Phase PacketSamplingPhase `json:"phase,omitempty"` - Reason string `json:"reason,omitempty"` - NumCapturedPackets int32 `json:"numCapturedPackets,omitempty"` - PacketsPath string `json:"packetsPath,omitempty"` - StartTime *metav1.Time `json:"startTime,omitempty"` + Phase PacketSamplingPhase `json:"phase,omitempty"` + // Reason recorded the failed reason when the sampling failed. + Reason string `json:"reason,omitempty"` + // NumCapturedPackets record how many packets has been captured. If it reach the target number, the sampling + // can be considered as finished. + NumCapturedPackets int32 `json:"numCapturedPackets,omitempty"` + // PacketsPath is the path where the captured packets are temporarily stored in the container. It will be + // removed after the PacketSampling is deleted. + PacketsPath string `json:"packetsPath,omitempty"` + StartTime *metav1.Time `json:"startTime,omitempty"` } diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index 452d823e451..bc3068d23a7 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -18,8 +18,6 @@ import ( "context" "time" - "antrea.io/antrea/pkg/controller/packetsampling" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -68,6 +66,7 @@ import ( "antrea.io/antrea/pkg/controller/externalippool" "antrea.io/antrea/pkg/controller/ipam" controllernetworkpolicy "antrea.io/antrea/pkg/controller/networkpolicy" + "antrea.io/antrea/pkg/controller/packetsampling" "antrea.io/antrea/pkg/controller/querier" "antrea.io/antrea/pkg/controller/stats" controllerbundlecollection "antrea.io/antrea/pkg/controller/supportbundlecollection" diff --git a/test/e2e/framework.go b/test/e2e/framework.go index a3df3169f69..561b9e7df07 100644 --- a/test/e2e/framework.go +++ b/test/e2e/framework.go @@ -1534,12 +1534,12 @@ func (data *TestData) createUDPServerPod(name string, ns string, portNum int32, } port := corev1.ContainerPort{Name: fmt.Sprintf("port-%d", portNum), ContainerPort: portNum} return NewPodBuilder(name, ns, agnhostImage). - OnNode(serverNode). - WithContainerName("agnhost"). - WithCommand(cmd). - WithArgs(args). - WithPorts([]corev1.ContainerPort{port}). - Create(testData) + OnNode(serverNode). + WithContainerName("agnhost"). + WithCommand(cmd). + WithArgs(args). + WithPorts([]corev1.ContainerPort{port}). + Create(testData) } // createServerPod creates a Pod that can listen to specified port and have named port set.