From 5cc5b765e1b12bd287e7ba183d8f09d2cb43eecf Mon Sep 17 00:00:00 2001 From: Kaushik Surya <108111936+sky333999@users.noreply.github.com> Date: Wed, 19 Apr 2023 10:18:36 -0500 Subject: [PATCH] =?UTF-8?q?[receiver/awscontainerinsightreceiver]=20Parame?= =?UTF-8?q?terize=20EKS=20CI=20leader=20loc=E2=80=A6=20(#4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [receiver/awscontainerinsightreceiver] Parameterize EKS CI leader lock name --- .../awscontainerinsightreceiver/README.md | 4 +++ .../awscontainerinsightreceiver/config.go | 5 ++++ .../config_test.go | 12 +++++++++ .../awscontainerinsightreceiver/factory.go | 4 +++ .../internal/k8sapiserver/k8sapiserver.go | 27 ++++++++++--------- .../awscontainerinsightreceiver/receiver.go | 2 +- .../testdata/config.yaml | 4 ++- 7 files changed, 44 insertions(+), 14 deletions(-) diff --git a/receiver/awscontainerinsightreceiver/README.md b/receiver/awscontainerinsightreceiver/README.md index d6fedcd3d449..5e5bd243570f 100644 --- a/receiver/awscontainerinsightreceiver/README.md +++ b/receiver/awscontainerinsightreceiver/README.md @@ -59,6 +59,10 @@ The "FullPodName" attribute is the pod name including suffix. If false FullPodNa "ClusterName" can be used to explicitly provide the cluster's name for EKS/ECS NOT on EC2 since it's not possible to auto-detect it using EC2 tags. +**leader_lock_name (optional)** + +"LeaderLockName" can be used to optionally override the lock resource name to be used during leader election for EKS Container Insights. The elected leader is responsible for scraping cluster level metrics. The default value is "otel-container-insight-clusterleader". + ## Sample configuration for Container Insights This is a sample configuration for AWS Container Insights using the `awscontainerinsightreceiver` and `awsemfexporter` for an EKS cluster: ``` diff --git a/receiver/awscontainerinsightreceiver/config.go b/receiver/awscontainerinsightreceiver/config.go index 6f0495f6094d..1b084e2110d6 100644 --- a/receiver/awscontainerinsightreceiver/config.go +++ b/receiver/awscontainerinsightreceiver/config.go @@ -43,4 +43,9 @@ type Config struct { // ClusterName can be used to explicitly provide the Cluster's Name for scenarios where it's not // possible to auto-detect it using EC2 tags. ClusterName string `mapstructure:"cluster_name"` + + // LeaderLockName is an optional attribute to override the name of the locking resource (e.g. config map) used during the leader + // election process for EKS Container Insights. The elected leader is responsible for scraping cluster level metrics. + // The default value is "otel-container-insight-clusterleader". + LeaderLockName string `mapstructure:"leader_lock_name"` } diff --git a/receiver/awscontainerinsightreceiver/config_test.go b/receiver/awscontainerinsightreceiver/config_test.go index fc075153aed9..9854084b3da5 100644 --- a/receiver/awscontainerinsightreceiver/config_test.go +++ b/receiver/awscontainerinsightreceiver/config_test.go @@ -46,6 +46,7 @@ func TestLoadConfig(t *testing.T) { ContainerOrchestrator: "eks", TagService: true, PrefFullPodName: false, + LeaderLockName: "otel-container-insight-clusterleader", }, }, { @@ -56,6 +57,17 @@ func TestLoadConfig(t *testing.T) { TagService: true, PrefFullPodName: false, ClusterName: "override_cluster", + LeaderLockName: "otel-container-insight-clusterleader", + }, + }, + { + id: component.NewIDWithName(typeStr, "leader_lock_name"), + expected: &Config{ + CollectionInterval: 60 * time.Second, + ContainerOrchestrator: "eks", + TagService: true, + PrefFullPodName: false, + LeaderLockName: "override-container-insight-clusterleader", }, }, } diff --git a/receiver/awscontainerinsightreceiver/factory.go b/receiver/awscontainerinsightreceiver/factory.go index e1042019be99..8df6fc3d82ba 100644 --- a/receiver/awscontainerinsightreceiver/factory.go +++ b/receiver/awscontainerinsightreceiver/factory.go @@ -48,6 +48,9 @@ const ( // Rely on EC2 tags to auto-detect cluster name by default defaultClusterName = "" + + // Default locking resource name during EKS leader election + defaultLeaderLockName = "otel-container-insight-clusterleader" ) // NewFactory creates a factory for AWS container insight receiver @@ -67,6 +70,7 @@ func createDefaultConfig() component.Config { PrefFullPodName: defaultPrefFullPodName, AddFullPodNameMetricLabel: defaultAddFullPodNameMetricLabel, ClusterName: defaultClusterName, + LeaderLockName: defaultLeaderLockName, } } diff --git a/receiver/awscontainerinsightreceiver/internal/k8sapiserver/k8sapiserver.go b/receiver/awscontainerinsightreceiver/internal/k8sapiserver/k8sapiserver.go index f9de9fee9cbf..0a1cf7ae9435 100644 --- a/receiver/awscontainerinsightreceiver/internal/k8sapiserver/k8sapiserver.go +++ b/receiver/awscontainerinsightreceiver/internal/k8sapiserver/k8sapiserver.go @@ -41,10 +41,6 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/k8s/k8sclient" ) -const ( - lockName = "otel-container-insight-clusterleader" -) - // eventBroadcaster is adpated from record.EventBroadcaster type eventBroadcaster interface { // StartRecordingToSink starts sending events received from this EventBroadcaster to the given @@ -74,8 +70,9 @@ type K8sAPIServer struct { clusterNameProvider clusterNameProvider cancel context.CancelFunc - mu sync.Mutex - leading bool + mu sync.Mutex + leading bool + leaderLockName string k8sClient K8sClient // *k8sclient.K8sClient epClient k8sclient.EpClient @@ -92,10 +89,16 @@ type clusterNameProvider interface { GetClusterName() string } -type k8sAPIServerOption func(*K8sAPIServer) +type Option func(*K8sAPIServer) + +func WithLeaderLockName(name string) Option { + return func(server *K8sAPIServer) { + server.leaderLockName = name + } +} // New creates a k8sApiServer which can generate cluster-level metrics -func New(clusterNameProvider clusterNameProvider, logger *zap.Logger, options ...k8sAPIServerOption) (*K8sAPIServer, error) { +func New(clusterNameProvider clusterNameProvider, logger *zap.Logger, options ...Option) (*K8sAPIServer, error) { k := &K8sAPIServer{ logger: logger, clusterNameProvider: clusterNameProvider, @@ -217,13 +220,13 @@ func (k *K8sAPIServer) init() error { clientSet := k.k8sClient.GetClientSet() configMapInterface := clientSet.CoreV1().ConfigMaps(lockNamespace) - if configMap, err := configMapInterface.Get(ctx, lockName, metav1.GetOptions{}); configMap == nil || err != nil { + if configMap, err := configMapInterface.Get(ctx, k.leaderLockName, metav1.GetOptions{}); configMap == nil || err != nil { k.logger.Info(fmt.Sprintf("Cannot get the leader config map: %v, try to create the config map...", err)) configMap, err = configMapInterface.Create(ctx, &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: lockNamespace, - Name: lockName, + Name: k.leaderLockName, }, }, metav1.CreateOptions{}) k.logger.Info(fmt.Sprintf("configMap: %v, err: %v", configMap, err)) @@ -231,12 +234,12 @@ func (k *K8sAPIServer) init() error { lock, err := resourcelock.New( resourcelock.ConfigMapsLeasesResourceLock, - lockNamespace, lockName, + lockNamespace, k.leaderLockName, clientSet.CoreV1(), clientSet.CoordinationV1(), resourcelock.ResourceLockConfig{ Identity: k.nodeName, - EventRecorder: k.createRecorder(lockName, lockNamespace), + EventRecorder: k.createRecorder(k.leaderLockName, lockNamespace), }) if err != nil { k.logger.Warn("Failed to create resource lock", zap.Error(err)) diff --git a/receiver/awscontainerinsightreceiver/receiver.go b/receiver/awscontainerinsightreceiver/receiver.go index 8e81b2816004..5b3c20fd97d1 100644 --- a/receiver/awscontainerinsightreceiver/receiver.go +++ b/receiver/awscontainerinsightreceiver/receiver.go @@ -86,7 +86,7 @@ func (acir *awsContainerInsightReceiver) Start(ctx context.Context, host compone if err != nil { return err } - acir.k8sapiserver, err = k8sapiserver.New(hostinfo, acir.settings.Logger) + acir.k8sapiserver, err = k8sapiserver.New(hostinfo, acir.settings.Logger, k8sapiserver.WithLeaderLockName(acir.config.LeaderLockName)) if err != nil { return err } diff --git a/receiver/awscontainerinsightreceiver/testdata/config.yaml b/receiver/awscontainerinsightreceiver/testdata/config.yaml index 14a59af03746..7dc50b329ec7 100644 --- a/receiver/awscontainerinsightreceiver/testdata/config.yaml +++ b/receiver/awscontainerinsightreceiver/testdata/config.yaml @@ -3,4 +3,6 @@ awscontainerinsightreceiver: awscontainerinsightreceiver/collection_interval_settings: collection_interval: 60s awscontainerinsightreceiver/cluster_name: - cluster_name: override_cluster \ No newline at end of file + cluster_name: override_cluster +awscontainerinsightreceiver/leader_lock_name: + leader_lock_name: override-container-insight-clusterleader \ No newline at end of file