github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/monitor/internal/k8s/on_startup.go (about)

     1  package k8smonitor
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"sync"
     7  
     8  	"go.aporeto.io/enforcerd/internal/extractors/containermetadata"
     9  	"go.uber.org/zap"
    10  
    11  	runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
    12  )
    13  
    14  func (m *K8sMonitor) onStartup(ctx context.Context, startEvent startEventFunc) error {
    15  	// wait for runc-proxy to be started before continuing with syncing state
    16  	if !m.isCniInstalledOrRuncProxyStarted() {
    17  		zap.L().Info("K8sMonitor: waiting for CNI plugin to be installed and configured...")
    18  		select {
    19  		case <-ctx.Done():
    20  			return fmt.Errorf("K8sMonitor: startup was canceled: %w", ctx.Err())
    21  		case <-m.cniInstalledOrRuncProxyStartedCh:
    22  			zap.L().Info("K8sMonitor: CNI plugin is ready. Continuing startup.")
    23  		}
    24  	}
    25  
    26  	sandboxList, err := m.criRuntimeService.ListPodSandbox(&runtimeapi.PodSandboxFilter{
    27  		State: &runtimeapi.PodSandboxStateValue{
    28  			State: runtimeapi.PodSandboxState_SANDBOX_READY,
    29  		},
    30  	})
    31  	if err != nil {
    32  		return err
    33  	}
    34  
    35  	var wg sync.WaitGroup
    36  	m.handlers.ResyncLock.RLock()
    37  	defer m.handlers.ResyncLock.RUnlock()
    38  	for _, sandbox := range sandboxList {
    39  		// extract common Kubernetes metadata from the filesystem
    40  		// technically CRI provides us with everything we need right now,
    41  		// however, this way the results are consistent and easier to maintain in the future
    42  		sandboxID := sandbox.GetId()
    43  		kmd, err := extractKmdFromCRISandbox(sandboxID)
    44  		if err != nil {
    45  			zap.L().Error("K8sMonitor: onStartup: failed to extract sandbox metadata. Skipping initialization for this pod...", zap.String("sandboxID", sandboxID), zap.Error(err))
    46  			continue
    47  		}
    48  
    49  		// fire away a start event
    50  		wg.Add(1)
    51  		go func(ctx context.Context, id string, m containermetadata.CommonKubernetesContainerMetadata) {
    52  			if err := startEvent(ctx, m, 0); err != nil {
    53  				zap.L().Error("K8sMonitor: onStartup: failed to send start event", zap.String("sandboxID", id), zap.Error(err))
    54  			}
    55  			wg.Done()
    56  		}(ctx, sandboxID, kmd)
    57  	}
    58  	wg.Wait()
    59  
    60  	return nil
    61  }
    62  
    63  var extractor = containermetadata.AutoDetect()
    64  
    65  func extractKmdFromCRISandbox(sandboxID string) (containermetadata.CommonKubernetesContainerMetadata, error) {
    66  	if sandboxID == "" {
    67  		return nil, fmt.Errorf("sandbox ID empty")
    68  	}
    69  	containerArgs := containermetadata.NewRuncArguments(containermetadata.StartAction, sandboxID)
    70  	if !extractor.Has(containerArgs) {
    71  		return nil, fmt.Errorf("failed to detect sandbox on filesystem")
    72  	}
    73  	_, kmd, err := extractor.Extract(containerArgs)
    74  	if err != nil {
    75  		return nil, fmt.Errorf("failed to extract metadata of sandbox from filesystem: %s", err)
    76  	}
    77  	if kmd == nil {
    78  		zap.L().Error("K8sMonitor: onStartup: failed to this container as Kubernetes sandbox from filesystem", zap.String("sandboxID", sandboxID), zap.Error(err))
    79  		return nil, fmt.Errorf("failed to detect this container as Kubernetes sandbox from filesystem")
    80  	}
    81  	return kmd, nil
    82  }