Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9e42d3f
pkg/metrics/metrics.go: Use controller-runtime metrics
lilic Nov 29, 2018
cfc26da
pkg/k8sutil/k8sutil.go: Make function take in args
lilic Nov 29, 2018
6030574
pkg/*: Move metric specific constant
lilic Nov 29, 2018
c4e89c3
pkg/scaffold/operator.go: Remove metrics port
lilic Nov 29, 2018
557c2b2
pkg/scaffold/cmd.go: Add metrics to operators
lilic Nov 29, 2018
19a2cb1
pkg/scaffold/cmd_test.go: Adjust test
lilic Nov 29, 2018
0a64797
pkg/scaffold/cmd_test.go: Adjust test
lilic Nov 29, 2018
b5a0e7b
pkg/scaffold/operator_test.go: Adjust test
lilic Nov 29, 2018
e6b6f85
Update pkg/metrics/metrics.go
estroz Nov 30, 2018
4d0706a
*: Adjust tests
lilic Nov 30, 2018
509442c
pkg/scaffold: Adjust test
lilic Nov 30, 2018
02a27cd
pkg/scaffold: Use different default port
lilic Dec 3, 2018
aecbeb5
pkg/scaffold: Add error check
lilic Dec 5, 2018
ce72d95
pkg/metrics: Remove constant from constants file
lilic Dec 5, 2018
1ab7fca
pkg/k8sutil: Use port number
lilic Dec 6, 2018
48364ad
Gopkg.lock: Run dep ensure
lilic Dec 10, 2018
76312ac
pkg/scaffold/cmd.go: Skip erroring out on Service
lilic Dec 10, 2018
2a3eb48
pkg/scaffold: Skip exit if metrics fail to be setup
lilic Jan 7, 2019
84a2213
Gopkg.toml: Add override for kube-openapi
lilic Jan 8, 2019
a71a3b2
pkg/scaffold: Refactor
lilic Jan 8, 2019
2adb7f6
pkg/*: Move InitOperatorService helper to metrics
lilic Jan 10, 2019
18cc5ce
pkg/*: Move Service creation logic to metrics helper
lilic Jan 21, 2019
04898f9
Merge branch 'master' of github.com:operator-framework/operator-sdk i…
lilic Jan 21, 2019
89144da
pkg/metrics: Add missing import
lilic Jan 21, 2019
8397c39
pkg/scaffold: Stringify error
lilic Jan 21, 2019
23c7aca
pkg/scaffold: Do not set service
lilic Jan 21, 2019
c4e1922
pkg*: Accept port32 in func
lilic Jan 21, 2019
e6fe5cc
pkg/metrics: Add error handling
lilic Jan 21, 2019
f2f2e91
pkg/metrics: Return Service if it exists
lilic Jan 22, 2019
91f8a59
Update pkg/metrics/metrics.go
hasbro17 Jan 24, 2019
410be12
Update pkg/metrics/metrics.go
hasbro17 Jan 24, 2019
ddda0f4
Update pkg/metrics/metrics.go
hasbro17 Jan 24, 2019
68452c3
pkg/metrics/metrics.go: Skip errors when running
lilic Jan 24, 2019
84d2432
pkg/*: Create new client for Service get/create
lilic Jan 24, 2019
c6bf9ea
CHANGELOG: Document metrics addition
lilic Jan 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### Added

- By default the controller-runtime metrics are exposed on port 8383. This is done as part of the scaffold in the main.go file, the port can be adjusted by modifying the `metricsPort` variable. [#786](https://github.com/operator-framework/operator-sdk/pull/786)

### Changed

### Deprecated
Expand Down
1 change: 0 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
name = "k8s.io/cli-runtime"
version = "kubernetes-1.12.3"

[[override]]
name = "k8s.io/kube-openapi"
revision = "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803"

[[constraint]]
name = "sigs.k8s.io/controller-runtime"
version = "=v0.1.8"
Expand Down
3 changes: 0 additions & 3 deletions commands/operator-sdk/cmd/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ spec:
containers:
- name: memcached-operator
image: quay.io/coreos/operator-sdk-dev:test-framework-operator
ports:
- containerPort: 60000
name: metrics
command:
- memcached-operator
imagePullPolicy: Always
Expand Down
6 changes: 0 additions & 6 deletions pkg/k8sutil/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,4 @@ const (
// OperatorNameEnvVar is the constant for env variable OPERATOR_NAME
// wich is the name of the current operator
OperatorNameEnvVar = "OPERATOR_NAME"

// PrometheusMetricsPort defines the port which expose prometheus metrics
PrometheusMetricsPort = 60000

// PrometheusMetricsPortName define the port name used in kubernetes deployment and service
PrometheusMetricsPortName = "metrics"
)
41 changes: 0 additions & 41 deletions pkg/k8sutil/k8sutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ import (
"os"
"strings"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
intstr "k8s.io/apimachinery/pkg/util/intstr"
discovery "k8s.io/client-go/discovery"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
)
Expand Down Expand Up @@ -68,44 +65,6 @@ func GetOperatorName() (string, error) {
return operatorName, nil
}

// InitOperatorService return the static service which expose operator metrics
func InitOperatorService() (*v1.Service, error) {
operatorName, err := GetOperatorName()
if err != nil {
return nil, err
}
namespace, err := GetOperatorNamespace()
if err != nil {
return nil, err
}
service := &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: operatorName,
Namespace: namespace,
Labels: map[string]string{"name": operatorName},
},
TypeMeta: metav1.TypeMeta{
Kind: "Service",
APIVersion: "v1",
},
Spec: v1.ServiceSpec{
Ports: []v1.ServicePort{
{
Port: PrometheusMetricsPort,
Protocol: v1.ProtocolTCP,
TargetPort: intstr.IntOrString{
Type: intstr.String,
StrVal: PrometheusMetricsPortName,
},
Name: PrometheusMetricsPortName,
},
},
Selector: map[string]string{"name": operatorName},
},
}
return service, nil
}

// ResourceExists returns true if the given resource kind exists
// in the given api groupversion
func ResourceExists(dc discovery.DiscoveryInterface, apiGroupVersion, kind string) (bool, error) {
Expand Down
112 changes: 89 additions & 23 deletions pkg/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,111 @@ package metrics

import (
"context"
"net/http"
"strconv"
"fmt"

"github.com/operator-framework/operator-sdk/pkg/k8sutil"

"github.com/prometheus/client_golang/prometheus/promhttp"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/config"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/rest"
crclient "sigs.k8s.io/controller-runtime/pkg/client"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
)

var log = logf.Log.WithName("metrics")

// ExposeMetricsPort generate a Kubernetes Service to expose metrics port
func ExposeMetricsPort() *v1.Service {
http.Handle("/"+k8sutil.PrometheusMetricsPortName, promhttp.Handler())
go http.ListenAndServe(":"+strconv.Itoa(k8sutil.PrometheusMetricsPort), nil)
// PrometheusPortName defines the port name used in kubernetes deployment and service resources
const PrometheusPortName = "metrics"

service, err := k8sutil.InitOperatorService()
// ExposeMetricsPort creates a Kubernetes Service to expose the passed metrics port.
func ExposeMetricsPort(ctx context.Context, port int32) (*v1.Service, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 On passing in the context.

Will we want to change this function signature at all if kubernetes-sigs/controller-runtime#273 gets merged? Would we go back to passing in the manager (or maybe the client directly)?

If so, I'm wondering if it would be worth anticipating that now to avoid an API change, or if we should just wait since we don't know exactly how it'll look.

Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If so, I'm wondering if it would be worth anticipating that now to avoid an API change, or if we should just wait since we don't know exactly how it'll look.

Yes was thinking about that as well, but as currently we have no idea if that will get merged and how it will look like in the end, so not sure we can fully predict it and think about not breaking the API. And we will have to change Leader functions signature in the case we use from above PR, not sure it makes a difference here. So yes, most likely if that gets merged we will break the API, or just decide to leave it as is, we always have that choice.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point about needing to change the leader election API as well.

In that case, I agree with waiting and breaking the API for both if necessary.

// We do not need to check the validity of the port, as controller-runtime
// would error out and we would never get to this stage.
s, err := initOperatorService(port, PrometheusPortName)
if err != nil {
log.Error(err, "Failed to initialize service object for operator metrics")
return nil
if err == k8sutil.ErrNoNamespace {
log.Info("Skipping metrics Service creation; not running in a cluster.")
return nil, nil
}
return nil, fmt.Errorf("failed to initialize service object for metrics: %v", err)
}
kubeconfig, err := config.GetConfig()
service, err := createService(ctx, s)
if err != nil {
panic(err)
return nil, fmt.Errorf("failed to create or get service for metrics: %v", err)
}
runtimeClient, err := client.New(kubeconfig, client.Options{})

return service, nil
}

func createService(ctx context.Context, s *v1.Service) (*v1.Service, error) {
config, err := rest.InClusterConfig()
if err != nil {
panic(err)
return nil, err
}
err = runtimeClient.Create(context.TODO(), service)
if err != nil && !errors.IsAlreadyExists(err) {
log.Error(err, "Failed to create service for operator metrics")
return nil

client, err := crclient.New(config, crclient.Options{})
if err != nil {
return nil, err
}

if err := client.Create(ctx, s); err != nil {
if !apierrors.IsAlreadyExists(err) {
return nil, err
}
// Get existing Service and return it
existingService := &v1.Service{}
err := client.Get(ctx, types.NamespacedName{
Name: s.Name,
Namespace: s.Namespace,
}, existingService)
if err != nil {
return nil, err
}
log.Info("Metrics Service object already exists", "name", existingService.Name)
return existingService, nil
}

log.Info("Metrics service created.", "ServiceName", service.Name)
return service
log.Info("Metrics Service object created", "name", s.Name)
return s, nil
}

// initOperatorService returns the static service which exposes specifed port.
func initOperatorService(port int32, portName string) (*v1.Service, error) {
operatorName, err := k8sutil.GetOperatorName()
if err != nil {
return nil, err
}
namespace, err := k8sutil.GetOperatorNamespace()
if err != nil {
return nil, err
}
service := &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: operatorName,
Namespace: namespace,
Labels: map[string]string{"name": operatorName},
},
TypeMeta: metav1.TypeMeta{
Kind: "Service",
APIVersion: "v1",
},
Spec: v1.ServiceSpec{
Ports: []v1.ServicePort{
{
Port: port,
Protocol: v1.ProtocolTCP,
TargetPort: intstr.IntOrString{
Type: intstr.Int,
IntVal: port,
},
Name: portName,
},
},
Selector: map[string]string{"name": operatorName},
},
}
return service, nil
}
3 changes: 0 additions & 3 deletions pkg/scaffold/ansible/deploy_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ spec:
- name: {{.ProjectName}}
# Replace this with the built image name
image: "{{ "{{ REPLACE_IMAGE }}" }}"
ports:
- containerPort: 60000
name: metrics
imagePullPolicy: "{{ "{{ pull_policy|default('Always') }}"}}"
env:
- name: WATCH_NAMESPACE
Expand Down
21 changes: 19 additions & 2 deletions pkg/scaffold/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (

"github.com/operator-framework/operator-sdk/pkg/k8sutil"
"github.com/operator-framework/operator-sdk/pkg/leader"
"github.com/operator-framework/operator-sdk/pkg/metrics"
sdkVersion "github.com/operator-framework/operator-sdk/version"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
"sigs.k8s.io/controller-runtime/pkg/client/config"
Expand All @@ -56,6 +57,11 @@ import (
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
)

// Change below variables to serve metrics on different host or port.
var (
metricsHost = "0.0.0.0"
metricsPort int32 = 8383
)
var log = logf.Log.WithName("cmd")

func printVersion() {
Expand Down Expand Up @@ -87,16 +93,21 @@ func main() {
log.Error(err, "")
os.Exit(1)
}

ctx := context.TODO()

// Become the leader before proceeding
err = leader.Become(context.TODO(), "{{ .ProjectName }}-lock")
err = leader.Become(ctx, "{{ .ProjectName }}-lock")
if err != nil {
log.Error(err, "")
os.Exit(1)
}

// Create a new Cmd to provide shared dependencies and start components
mgr, err := manager.New(cfg, manager.Options{Namespace: namespace})
mgr, err := manager.New(cfg, manager.Options{
Namespace: namespace,
MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),
})
if err != nil {
log.Error(err, "")
os.Exit(1)
Expand All @@ -116,6 +127,12 @@ func main() {
os.Exit(1)
}

// Create Service object to expose the metrics port.
_, err = metrics.ExposeMetricsPort(ctx, metricsPort)
if err != nil {
log.Info(err.Error())
}

log.Info("Starting the Cmd.")

// Start the Cmd
Expand Down
21 changes: 19 additions & 2 deletions pkg/scaffold/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import (
"github.com/example-inc/app-operator/pkg/controller"
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
"github.com/operator-framework/operator-sdk/pkg/leader"
"github.com/operator-framework/operator-sdk/pkg/metrics"
sdkVersion "github.com/operator-framework/operator-sdk/version"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
"sigs.k8s.io/controller-runtime/pkg/client/config"
Expand All @@ -54,6 +55,11 @@ import (
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
)

// Change below variables to serve metrics on different host or port.
var (
metricsHost = "0.0.0.0"
metricsPort int32 = 8383
)
var log = logf.Log.WithName("cmd")

func printVersion() {
Expand Down Expand Up @@ -86,15 +92,20 @@ func main() {
os.Exit(1)
}

ctx := context.TODO()

// Become the leader before proceeding
err = leader.Become(context.TODO(), "app-operator-lock")
err = leader.Become(ctx, "app-operator-lock")
if err != nil {
log.Error(err, "")
os.Exit(1)
}

// Create a new Cmd to provide shared dependencies and start components
mgr, err := manager.New(cfg, manager.Options{Namespace: namespace})
mgr, err := manager.New(cfg, manager.Options{
Namespace: namespace,
MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),
})
if err != nil {
log.Error(err, "")
os.Exit(1)
Expand All @@ -114,6 +125,12 @@ func main() {
os.Exit(1)
}

// Create Service object to expose the metrics port.
_, err = metrics.ExposeMetricsPort(ctx, metricsPort)
if err != nil {
log.Info(err.Error())
}

log.Info("Starting the Cmd.")

// Start the Cmd
Expand Down
4 changes: 4 additions & 0 deletions pkg/scaffold/gopkgtoml.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ required = [
branch = "master" #osdk_branch_annotation
# version = "=v0.4.0" #osdk_version_annotation

[[override]]
name = "k8s.io/kube-openapi"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this up with the other k8s.io overrides?

Also, looks like an extra space made it in:

Suggested change
name = "k8s.io/kube-openapi"
name = "k8s.io/kube-openapi"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lilic We still need to change this right?

revision = "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803"

[prune]
go-tests = true
non-go = true
Expand Down
4 changes: 4 additions & 0 deletions pkg/scaffold/gopkgtoml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ required = [
branch = "master" #osdk_branch_annotation
# version = "=v0.4.0" #osdk_version_annotation

[[override]]
name = "k8s.io/kube-openapi"
revision = "0cf8f7e6ed1d2e3d47d02e3b6e559369af24d803"

[prune]
go-tests = true
non-go = true
Expand Down
3 changes: 0 additions & 3 deletions pkg/scaffold/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ spec:
- name: {{.ProjectName}}
# Replace this with the built image name
image: REPLACE_IMAGE
ports:
- containerPort: 60000
name: metrics
command:
- {{.ProjectName}}
imagePullPolicy: Always
Expand Down
Loading