Skip to content

Commit

Permalink
[receiver/awscontainerinsightreceiver] Parameterize EKS CI leader loc… (
Browse files Browse the repository at this point in the history
open-telemetry#4)

[receiver/awscontainerinsightreceiver] Parameterize EKS CI leader lock name
  • Loading branch information
sky333999 authored Apr 19, 2023
1 parent 1f07035 commit 5cc5b76
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 14 deletions.
4 changes: 4 additions & 0 deletions receiver/awscontainerinsightreceiver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
```
Expand Down
5 changes: 5 additions & 0 deletions receiver/awscontainerinsightreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
}
12 changes: 12 additions & 0 deletions receiver/awscontainerinsightreceiver/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func TestLoadConfig(t *testing.T) {
ContainerOrchestrator: "eks",
TagService: true,
PrefFullPodName: false,
LeaderLockName: "otel-container-insight-clusterleader",
},
},
{
Expand All @@ -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",
},
},
}
Expand Down
4 changes: 4 additions & 0 deletions receiver/awscontainerinsightreceiver/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -67,6 +70,7 @@ func createDefaultConfig() component.Config {
PrefFullPodName: defaultPrefFullPodName,
AddFullPodNameMetricLabel: defaultAddFullPodNameMetricLabel,
ClusterName: defaultClusterName,
LeaderLockName: defaultLeaderLockName,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -217,26 +220,26 @@ 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))
}

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))
Expand Down
2 changes: 1 addition & 1 deletion receiver/awscontainerinsightreceiver/receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
4 changes: 3 additions & 1 deletion receiver/awscontainerinsightreceiver/testdata/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ awscontainerinsightreceiver:
awscontainerinsightreceiver/collection_interval_settings:
collection_interval: 60s
awscontainerinsightreceiver/cluster_name:
cluster_name: override_cluster
cluster_name: override_cluster
awscontainerinsightreceiver/leader_lock_name:
leader_lock_name: override-container-insight-clusterleader

0 comments on commit 5cc5b76

Please sign in to comment.