Skip to content

Commit 47fce56

Browse files
committed
feat: target group info metric
1 parent 95e362a commit 47fce56

File tree

6 files changed

+114
-28
lines changed

6 files changed

+114
-28
lines changed

controllers/ingress/group_controller.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/go-logr/logr"
88
"github.com/pkg/errors"
9+
"github.com/prometheus/client_golang/prometheus"
910
corev1 "k8s.io/api/core/v1"
1011
networking "k8s.io/api/networking/v1"
1112
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -43,11 +44,21 @@ const (
4344
)
4445

4546
// NewGroupReconciler constructs new GroupReconciler
46-
func NewGroupReconciler(cloud aws.Cloud, k8sClient client.Client, eventRecorder record.EventRecorder,
47-
finalizerManager k8s.FinalizerManager, networkingSGManager networkingpkg.SecurityGroupManager,
48-
networkingSGReconciler networkingpkg.SecurityGroupReconciler, subnetsResolver networkingpkg.SubnetsResolver,
49-
elbv2TaggingManager elbv2deploy.TaggingManager, controllerConfig config.ControllerConfig, backendSGProvider networkingpkg.BackendSGProvider,
50-
sgResolver networkingpkg.SecurityGroupResolver, logger logr.Logger) *groupReconciler {
47+
func NewGroupReconciler(
48+
cloud aws.Cloud,
49+
k8sClient client.Client,
50+
eventRecorder record.EventRecorder,
51+
finalizerManager k8s.FinalizerManager,
52+
networkingSGManager networkingpkg.SecurityGroupManager,
53+
networkingSGReconciler networkingpkg.SecurityGroupReconciler,
54+
subnetsResolver networkingpkg.SubnetsResolver,
55+
elbv2TaggingManager elbv2deploy.TaggingManager,
56+
targetGroupMetric *prometheus.GaugeVec,
57+
controllerConfig config.ControllerConfig,
58+
backendSGProvider networkingpkg.BackendSGProvider,
59+
sgResolver networkingpkg.SecurityGroupResolver,
60+
logger logr.Logger,
61+
) *groupReconciler {
5162

5263
annotationParser := annotations.NewSuffixAnnotationParser(annotations.AnnotationPrefixIngress)
5364
authConfigBuilder := ingress.NewDefaultAuthConfigBuilder(annotationParser)
@@ -62,7 +73,7 @@ func NewGroupReconciler(cloud aws.Cloud, k8sClient client.Client, eventRecorder
6273
controllerConfig.DefaultSSLPolicy, controllerConfig.DefaultTargetType, backendSGProvider, sgResolver,
6374
controllerConfig.EnableBackendSecurityGroup, controllerConfig.DisableRestrictedSGRules, controllerConfig.FeatureGates.Enabled(config.EnableIPTargetType), logger)
6475
stackMarshaller := deploy.NewDefaultStackMarshaller()
65-
stackDeployer := deploy.NewDefaultStackDeployer(cloud, k8sClient, networkingSGManager, networkingSGReconciler, elbv2TaggingManager,
76+
stackDeployer := deploy.NewDefaultStackDeployer(cloud, k8sClient, networkingSGManager, networkingSGReconciler, elbv2TaggingManager, targetGroupMetric,
6677
controllerConfig, ingressTagPrefix, logger)
6778
classLoader := ingress.NewDefaultClassLoader(k8sClient, true)
6879
classAnnotationMatcher := ingress.NewDefaultClassAnnotationMatcher(controllerConfig.IngressConfig.IngressClass)

controllers/service/service_controller.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/go-logr/logr"
88
"github.com/pkg/errors"
9+
"github.com/prometheus/client_golang/prometheus"
910
corev1 "k8s.io/api/core/v1"
1011
"k8s.io/apimachinery/pkg/types"
1112
"k8s.io/client-go/tools/record"
@@ -35,11 +36,22 @@ const (
3536
controllerName = "service"
3637
)
3738

38-
func NewServiceReconciler(cloud aws.Cloud, k8sClient client.Client, eventRecorder record.EventRecorder,
39-
finalizerManager k8s.FinalizerManager, networkingSGManager networking.SecurityGroupManager,
40-
networkingSGReconciler networking.SecurityGroupReconciler, subnetsResolver networking.SubnetsResolver,
41-
vpcInfoProvider networking.VPCInfoProvider, elbv2TaggingManager elbv2deploy.TaggingManager, controllerConfig config.ControllerConfig,
42-
backendSGProvider networking.BackendSGProvider, sgResolver networking.SecurityGroupResolver, logger logr.Logger) *serviceReconciler {
39+
func NewServiceReconciler(
40+
cloud aws.Cloud,
41+
k8sClient client.Client,
42+
eventRecorder record.EventRecorder,
43+
finalizerManager k8s.FinalizerManager,
44+
networkingSGManager networking.SecurityGroupManager,
45+
networkingSGReconciler networking.SecurityGroupReconciler,
46+
subnetsResolver networking.SubnetsResolver,
47+
vpcInfoProvider networking.VPCInfoProvider,
48+
elbv2TaggingManager elbv2deploy.TaggingManager,
49+
targetGroupMetric *prometheus.GaugeVec,
50+
controllerConfig config.ControllerConfig,
51+
backendSGProvider networking.BackendSGProvider,
52+
sgResolver networking.SecurityGroupResolver,
53+
logger logr.Logger,
54+
) *serviceReconciler {
4355

4456
annotationParser := annotations.NewSuffixAnnotationParser(serviceAnnotationPrefix)
4557
trackingProvider := tracking.NewDefaultProvider(serviceTagPrefix, controllerConfig.ClusterName)
@@ -49,7 +61,7 @@ func NewServiceReconciler(cloud aws.Cloud, k8sClient client.Client, eventRecorde
4961
controllerConfig.DefaultSSLPolicy, controllerConfig.DefaultTargetType, controllerConfig.FeatureGates.Enabled(config.EnableIPTargetType), serviceUtils,
5062
backendSGProvider, sgResolver, controllerConfig.EnableBackendSecurityGroup, controllerConfig.DisableRestrictedSGRules)
5163
stackMarshaller := deploy.NewDefaultStackMarshaller()
52-
stackDeployer := deploy.NewDefaultStackDeployer(cloud, k8sClient, networkingSGManager, networkingSGReconciler, elbv2TaggingManager, controllerConfig, serviceTagPrefix, logger)
64+
stackDeployer := deploy.NewDefaultStackDeployer(cloud, k8sClient, networkingSGManager, networkingSGReconciler, elbv2TaggingManager, targetGroupMetric, controllerConfig, serviceTagPrefix, logger)
5365
return &serviceReconciler{
5466
k8sClient: k8sClient,
5567
eventRecorder: eventRecorder,

main.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package main
1818

1919
import (
2020
"os"
21+
22+
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/metrics"
2123
elbv2deploy "sigs.k8s.io/aws-load-balancer-controller/pkg/deploy/elbv2"
2224

2325
"github.com/go-logr/logr"
@@ -46,7 +48,7 @@ import (
4648
ctrl "sigs.k8s.io/controller-runtime"
4749
"sigs.k8s.io/controller-runtime/pkg/healthz"
4850
"sigs.k8s.io/controller-runtime/pkg/log/zap"
49-
"sigs.k8s.io/controller-runtime/pkg/metrics"
51+
k8smetric "sigs.k8s.io/controller-runtime/pkg/metrics"
5052
// +kubebuilder:scaffold:imports
5153
)
5254

@@ -76,7 +78,7 @@ func main() {
7678
}
7779
ctrl.SetLogger(getLoggerWithLogLevel(controllerCFG.LogLevel))
7880

79-
cloud, err := aws.NewCloud(controllerCFG.AWSConfig, metrics.Registry)
81+
cloud, err := aws.NewCloud(controllerCFG.AWSConfig, k8smetric.Registry)
8082
if err != nil {
8183
setupLog.Error(err, "unable to initialize AWS cloud")
8284
os.Exit(1)
@@ -114,11 +116,15 @@ func main() {
114116
cloud.VpcID(), cloud.EC2(), mgr.GetClient(), controllerCFG.DefaultTags, ctrl.Log.WithName("backend-sg-provider"))
115117
sgResolver := networking.NewDefaultSecurityGroupResolver(cloud.EC2(), cloud.VpcID())
116118
elbv2TaggingManager := elbv2deploy.NewDefaultTaggingManager(cloud.ELBV2(), cloud.VpcID(), controllerCFG.FeatureGates, cloud.RGT(), ctrl.Log)
119+
targetGroupMetric, err := metrics.RegisterTargetGroupInfoMetric(k8smetric.Registry)
120+
if err != nil {
121+
setupLog.Error(err, "failed to register target binding information metric")
122+
}
117123
ingGroupReconciler := ingress.NewGroupReconciler(cloud, mgr.GetClient(), mgr.GetEventRecorderFor("ingress"),
118-
finalizerManager, sgManager, sgReconciler, subnetResolver, elbv2TaggingManager,
124+
finalizerManager, sgManager, sgReconciler, subnetResolver, elbv2TaggingManager, targetGroupMetric,
119125
controllerCFG, backendSGProvider, sgResolver, ctrl.Log.WithName("controllers").WithName("ingress"))
120126
svcReconciler := service.NewServiceReconciler(cloud, mgr.GetClient(), mgr.GetEventRecorderFor("service"),
121-
finalizerManager, sgManager, sgReconciler, subnetResolver, vpcInfoProvider, elbv2TaggingManager,
127+
finalizerManager, sgManager, sgReconciler, subnetResolver, vpcInfoProvider, elbv2TaggingManager, targetGroupMetric,
122128
controllerCFG, backendSGProvider, sgResolver, ctrl.Log.WithName("controllers").WithName("service"))
123129
tgbReconciler := elbv2controller.NewTargetGroupBindingReconciler(mgr.GetClient(), mgr.GetEventRecorderFor("targetGroupBinding"),
124130
finalizerManager, tgbResManager,

pkg/aws/metrics/target_group.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package metrics
2+
3+
import (
4+
"strings"
5+
6+
"github.com/prometheus/client_golang/prometheus"
7+
elbv2api "sigs.k8s.io/aws-load-balancer-controller/apis/elbv2/v1beta1"
8+
)
9+
10+
const (
11+
metricTargetGroupBinding = "target_group_info"
12+
13+
labelNamespace = "namespace"
14+
// Name matches label when importing target group metrics using cloudwatch_exporter
15+
labelTargetGroup = "target_group"
16+
)
17+
18+
func RegisterTargetGroupInfoMetric(registerer prometheus.Registerer) (*prometheus.GaugeVec, error) {
19+
20+
targetGroupInfo := prometheus.NewGaugeVec(prometheus.GaugeOpts{
21+
Subsystem: metricSubsystemAWS,
22+
Name: metricTargetGroupBinding,
23+
Help: "Information available about target group",
24+
}, []string{labelNamespace, labelService, labelTargetGroup})
25+
26+
err := registerer.Register(targetGroupInfo)
27+
return targetGroupInfo, err
28+
}
29+
30+
func LabelsForTargetGroupBinding(resTGB *elbv2api.TargetGroupBinding) map[string]string {
31+
32+
// Extracting value of TargetGroup dimension in CloudWatch
33+
// https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html#load-balancer-metric-dimensions-alb
34+
targetGroup := resTGB.Spec.TargetGroupARN[strings.LastIndex(resTGB.Spec.TargetGroupARN, ":")+1:]
35+
return map[string]string{
36+
labelNamespace: resTGB.Namespace,
37+
labelService: resTGB.Spec.ServiceRef.Name,
38+
labelTargetGroup: targetGroup,
39+
}
40+
}

pkg/deploy/elbv2/target_group_binding_manager.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,23 @@ package elbv2
22

33
import (
44
"context"
5+
"time"
6+
57
awssdk "github.com/aws/aws-sdk-go/aws"
68
"github.com/go-logr/logr"
79
"github.com/pkg/errors"
10+
"github.com/prometheus/client_golang/prometheus"
811
corev1 "k8s.io/api/core/v1"
912
"k8s.io/apimachinery/pkg/api/equality"
1013
apierrors "k8s.io/apimachinery/pkg/api/errors"
1114
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1215
"k8s.io/apimachinery/pkg/util/wait"
1316
elbv2api "sigs.k8s.io/aws-load-balancer-controller/apis/elbv2/v1beta1"
17+
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/metrics"
1418
"sigs.k8s.io/aws-load-balancer-controller/pkg/deploy/tracking"
1519
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
1620
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
1721
"sigs.k8s.io/controller-runtime/pkg/client"
18-
"time"
1922
)
2023

2124
const (
@@ -35,11 +38,12 @@ type TargetGroupBindingManager interface {
3538
}
3639

3740
// NewDefaultTargetGroupBindingManager constructs new defaultTargetGroupBindingManager
38-
func NewDefaultTargetGroupBindingManager(k8sClient client.Client, trackingProvider tracking.Provider, logger logr.Logger) *defaultTargetGroupBindingManager {
41+
func NewDefaultTargetGroupBindingManager(k8sClient client.Client, trackingProvider tracking.Provider, logger logr.Logger, metric *prometheus.GaugeVec) *defaultTargetGroupBindingManager {
3942
return &defaultTargetGroupBindingManager{
40-
k8sClient: k8sClient,
41-
trackingProvider: trackingProvider,
42-
logger: logger,
43+
k8sClient: k8sClient,
44+
trackingProvider: trackingProvider,
45+
logger: logger,
46+
targetGroupInfoMetric: metric,
4347

4448
waitTGBObservedPollInterval: defaultWaitTGBObservedPollInterval,
4549
waitTGBObservedTimout: defaultWaitTGBObservedTimeout,
@@ -52,9 +56,10 @@ var _ TargetGroupBindingManager = &defaultTargetGroupBindingManager{}
5256

5357
// default implementation for TargetGroupBindingManager.
5458
type defaultTargetGroupBindingManager struct {
55-
k8sClient client.Client
56-
trackingProvider tracking.Provider
57-
logger logr.Logger
59+
k8sClient client.Client
60+
trackingProvider tracking.Provider
61+
logger logr.Logger
62+
targetGroupInfoMetric *prometheus.GaugeVec
5863

5964
waitTGBObservedPollInterval time.Duration
6065
waitTGBObservedTimout time.Duration
@@ -88,6 +93,7 @@ func (m *defaultTargetGroupBindingManager) Create(ctx context.Context, resTGB *e
8893
"stackID", resTGB.Stack().StackID(),
8994
"resourceID", resTGB.ID(),
9095
"targetGroupBinding", k8s.NamespacedName(k8sTGB))
96+
m.targetGroupInfoMetric.With(metrics.LabelsForTargetGroupBinding(k8sTGB)).Set(1)
9197
return buildResTargetGroupBindingStatus(k8sTGB), nil
9298
}
9399

@@ -96,6 +102,7 @@ func (m *defaultTargetGroupBindingManager) Update(ctx context.Context, resTGB *e
96102
if err != nil {
97103
return elbv2model.TargetGroupBindingResourceStatus{}, err
98104
}
105+
m.targetGroupInfoMetric.With(metrics.LabelsForTargetGroupBinding(k8sTGB)).Set(1)
99106
if equality.Semantic.DeepEqual(k8sTGB.Spec, k8sTGBSpec) {
100107
return buildResTargetGroupBindingStatus(k8sTGB), nil
101108
}
@@ -130,6 +137,7 @@ func (m *defaultTargetGroupBindingManager) Delete(ctx context.Context, tgb *elbv
130137
}
131138
m.logger.Info("deleted targetGroupBinding",
132139
"targetGroupBinding", k8s.NamespacedName(tgb))
140+
m.targetGroupInfoMetric.Delete(metrics.LabelsForTargetGroupBinding(tgb))
133141
return nil
134142
}
135143

pkg/deploy/stack_deployer.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package deploy
22

33
import (
44
"context"
5+
56
"github.com/go-logr/logr"
7+
"github.com/prometheus/client_golang/prometheus"
68
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws"
79
"sigs.k8s.io/aws-load-balancer-controller/pkg/config"
810
"sigs.k8s.io/aws-load-balancer-controller/pkg/deploy/ec2"
@@ -23,10 +25,17 @@ type StackDeployer interface {
2325
}
2426

2527
// NewDefaultStackDeployer constructs new defaultStackDeployer.
26-
func NewDefaultStackDeployer(cloud aws.Cloud, k8sClient client.Client,
27-
networkingSGManager networking.SecurityGroupManager, networkingSGReconciler networking.SecurityGroupReconciler,
28+
func NewDefaultStackDeployer(
29+
cloud aws.Cloud,
30+
k8sClient client.Client,
31+
networkingSGManager networking.SecurityGroupManager,
32+
networkingSGReconciler networking.SecurityGroupReconciler,
2833
elbv2TaggingManager elbv2.TaggingManager,
29-
config config.ControllerConfig, tagPrefix string, logger logr.Logger) *defaultStackDeployer {
34+
targetGroupMetric *prometheus.GaugeVec,
35+
config config.ControllerConfig,
36+
tagPrefix string,
37+
logger logr.Logger,
38+
) *defaultStackDeployer {
3039

3140
trackingProvider := tracking.NewDefaultProvider(tagPrefix, config.ClusterName)
3241
ec2TaggingManager := ec2.NewDefaultTaggingManager(cloud.EC2(), networkingSGManager, cloud.VpcID(), logger)
@@ -43,7 +52,7 @@ func NewDefaultStackDeployer(cloud aws.Cloud, k8sClient client.Client,
4352
elbv2LSManager: elbv2.NewDefaultListenerManager(cloud.ELBV2(), trackingProvider, elbv2TaggingManager, config.ExternalManagedTags, config.FeatureGates, logger),
4453
elbv2LRManager: elbv2.NewDefaultListenerRuleManager(cloud.ELBV2(), trackingProvider, elbv2TaggingManager, config.ExternalManagedTags, config.FeatureGates, logger),
4554
elbv2TGManager: elbv2.NewDefaultTargetGroupManager(cloud.ELBV2(), trackingProvider, elbv2TaggingManager, cloud.VpcID(), config.ExternalManagedTags, logger),
46-
elbv2TGBManager: elbv2.NewDefaultTargetGroupBindingManager(k8sClient, trackingProvider, logger),
55+
elbv2TGBManager: elbv2.NewDefaultTargetGroupBindingManager(k8sClient, trackingProvider, logger, targetGroupMetric),
4756
wafv2WebACLAssociationManager: wafv2.NewDefaultWebACLAssociationManager(cloud.WAFv2(), logger),
4857
wafRegionalWebACLAssociationManager: wafregional.NewDefaultWebACLAssociationManager(cloud.WAFRegional(), logger),
4958
shieldProtectionManager: shield.NewDefaultProtectionManager(cloud.Shield(), logger),

0 commit comments

Comments
 (0)