Skip to content

Commit

Permalink
Configure pprof on controller-manager.
Browse files Browse the repository at this point in the history
Generated file.
Adding cluster mode changes.
Updated version for cluster mode.
Skipping version check on dev mode controllers.
Make pprof support case insensitive.
  • Loading branch information
cheftako committed Nov 5, 2024
1 parent 1e723b5 commit dd94ee5
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 3 deletions.
4 changes: 2 additions & 2 deletions go.work
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ go 1.22.5
use (
.
./dev/tools/controllerbuilder
./experiments/kompanion
./experiments/kubectl-plan
// ./experiments/kompanion
// ./experiments/kubectl-plan
./mockgcp
./mockgcp/tools/patch-proto
// ./third_party/github.com/hashicorp/terraform-provider-google-beta
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ spec:
spec:
description: ControllerReconcilerSpec is the specification of ControllerReconciler.
properties:
pprofConfig:
description: PprofConfigures the debug endpoint on the service.
properties:
pprofPort:
description: The port that the pprof server binds to if enabled
type: integer
pprofSupport:
description: Control if pprof should be turned on and which types
should be enabled.
enum:
- none
- all
type: string
type: object
rateLimit:
description: |-
RateLimit configures the token bucket rate limit to the kubernetes client used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ spec:
spec:
description: NamespacedControllerReconciler is the specification of NamespacedControllerReconciler.
properties:
pprofConfig:
description: PprofConfigures the debug endpoint on the service.
properties:
pprofPort:
description: The port that the pprof server binds to if enabled
type: integer
pprofSupport:
description: Control if pprof should be turned on and which types
should be enabled.
enum:
- none
- all
type: string
type: object
rateLimit:
description: |-
RateLimit configures the token bucket rate limit to the kubernetes client used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ type NamespacedControllerReconcilerSpec struct {
// If not specified, the default will be Token Bucket with qps 20, burst 30.
// +optional
RateLimit *RateLimit `json:"rateLimit,omitempty"`
// PprofConfigures the debug endpoint on the service.
// +optional
PprofConfig *PprofConfig `json:"pprofConfig,omitempty"`
}

type RateLimit struct {
Expand All @@ -52,6 +55,16 @@ type RateLimit struct {
Burst int `json:"burst,omitempty"`
}

type PprofConfig struct {
// Control if pprof should be turned on and which types should be enabled.
// +kubebuilder:validation:Enum=none;all
// +optional
PprofSupport string `json:"pprofSupport,omitempty"`
// The port that the pprof server binds to if enabled
// +optional
PprofPort int `json:"pprofPort,omitempty"`
}

// NamespacedControllerReconcilerStatus defines the observed state of NamespacedControllerReconciler.
type NamespacedControllerReconcilerStatus struct {
addonv1alpha1.CommonStatus `json:",inline"`
Expand Down Expand Up @@ -92,6 +105,9 @@ type ControllerReconcilerSpec struct {
// If not specified, the default will be Token Bucket with qps 20, burst 30.
// +optional
RateLimit *RateLimit `json:"rateLimit,omitempty"`
// PprofConfigures the debug endpoint on the service.
// +optional
PprofConfig *PprofConfig `json:"pprofConfig,omitempty"`
}

// ControllerReconcilerStatus defines the observed state of ControllerReconciler.
Expand All @@ -116,6 +132,10 @@ var ValidRateLimitControllers = []string{
"cnrm-controller-manager",
}

var SupportedPprofControllers = []string{
"cnrm-controller-manager",
}

func init() {
SchemeBuilder.Register(
&NamespacedControllerReconciler{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,10 @@ func (r *Reconciler) applyControllerReconcilerCR(ctx context.Context, cr *custom
r.log.Error(err, errMsg)
return r.handleApplyControllerReconcilerFailed(ctx, cr, errMsg)
}
if err := controllers.ApplyContainerPprofConfig(m, cr.Name, cr.Spec.PprofConfig); err != nil {
msg := fmt.Sprintf("failed to apply pprof config customization %s: %v", cr.Name, err)
return r.handleApplyControllerReconcilerFailed(ctx, cr, msg)
}
return r.handleApplyControllerReconcilerSucceeded(ctx, cr)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,10 @@ func (r *Reconciler) applyNamespacedControllerReconciler(ctx context.Context, cr
msg := fmt.Sprintf("failed to apply rate limit customization %s: %v", cr.Name, err)
return r.handleApplyNamespacedControllerReconcilerFailed(ctx, cr.Namespace, cr.Name, msg)
}
if err := controllers.ApplyContainerPprofConfig(m, cr.Name, cr.Spec.PprofConfig); err != nil {
msg := fmt.Sprintf("failed to apply pprof config customization %s: %v", cr.Name, err)
return r.handleApplyNamespacedControllerReconcilerFailed(ctx, cr.Namespace, cr.Name, msg)
}
return r.handleApplyNamespacedControllerReconcilerSucceeded(ctx, cr.Namespace, cr.Name)
}

Expand Down
83 changes: 83 additions & 0 deletions operator/pkg/controllers/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -586,3 +586,86 @@ func applyRateLimitToContainerArg(container map[string]interface{}, rateLimit *c
}
return nil
}

func ApplyContainerPprofConfig(m *manifest.Objects, targetControllerName string, pprofConfig *customizev1alpha1.PprofConfig) error {
if pprofConfig == nil {
return nil
}

var (
targetContainerName string
targetControllerGVK schema.GroupVersionKind
)
switch targetControllerName {
case "cnrm-controller-manager":
targetContainerName = "manager"
targetControllerGVK = schema.GroupVersionKind{
Group: appsv1.SchemeGroupVersion.Group,
Version: appsv1.SchemeGroupVersion.Version,
Kind: "StatefulSet",
}
default:
return fmt.Errorf("pprof config customization for %s is not supported. "+
"Supported controllers: %s",
targetControllerName, strings.Join(customizev1alpha1.SupportedPprofControllers, ", "))
}

for _, item := range m.Items {
if item.GroupVersionKind() != targetControllerGVK {
continue
}
if !strings.HasPrefix(item.GetName(), targetControllerName) {
continue
}
if err := item.MutateContainers(customizePprofConfigFn(targetContainerName, pprofConfig)); err != nil {
return err
}
break // we already found the matching controller, no need to keep looking.
}
return nil
}

func customizePprofConfigFn(target string, pprofConfig *customizev1alpha1.PprofConfig) func(container map[string]interface{}) error {
return func(container map[string]interface{}) error {
name, _, err := unstructured.NestedString(container, "name")
if err != nil {
return fmt.Errorf("error reading container name: %w", err)
}
if name != target {
return nil
}
return applyPprofConfigToContainerArg(container, pprofConfig)
}
}

func applyPprofConfigToContainerArg(container map[string]interface{}, pprofConfig *customizev1alpha1.PprofConfig) error {
if pprofConfig == nil {
return nil
}
origArgs, found, err := unstructured.NestedStringSlice(container, "args")
if err != nil {
return fmt.Errorf("error getting args in container: %w", err)
}
wantArgs := []string{}
if strings.ToUpper(pprofConfig.PprofSupport) == "ALL" {
wantArgs = append(wantArgs, "--enable-pprof=true")
} else {
wantArgs = append(wantArgs, "--enable-pprof=false")
}
if pprofConfig.PprofPort > 0 {
wantArgs = append(wantArgs, fmt.Sprintf("--pprof-port=%d", pprofConfig.PprofPort))
}
if found {
for _, arg := range origArgs {
if strings.Contains(arg, "--enable-pprof") || strings.Contains(arg, "--pprof-port") {
// drop the old value on the floor
continue
}
wantArgs = append(wantArgs, arg)
}
}
if err := unstructured.SetNestedStringSlice(container, wantArgs, "args"); err != nil {
return fmt.Errorf("error setting args in container: %w", err)
}
return nil
}
7 changes: 6 additions & 1 deletion operator/pkg/preflight/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import (
)

var (
ulog = ctrl.Log.WithName("UpgradeChecker")
ulog = ctrl.Log.WithName("UpgradeChecker")
devVersion = semver.MustParse("0.0.0-dev")
)

// NewUpgradeChecker provides an implementation of declarative.Preflight that
Expand Down Expand Up @@ -95,6 +96,10 @@ func (u *UpgradeChecker) Preflight(ctx context.Context, o declarative.Declarativ
}

func compareMajorOnly(v, w semver.Version) int {
if v.Equals(devVersion) {
// If we are using a dev controller ignore semver drift.
return 0
}
if v.Major != w.Major {
if v.Major > w.Major {
return 1
Expand Down

0 comments on commit dd94ee5

Please sign in to comment.