Repository: kubernetes/kubernetes (language: go)

Issue:
Add flagz endpoint for kube-controller-manager
### What would you like to be added?

Part of 
- https://github.com/kubernetes/enhancements/issues/4828

Add the `/flagz` endpoint for kube-controller-manager.

Sample response:
```
----------------------------
title: Kubernetes Flagz
description: Command line flags that Kubernetes component was started with.
----------------------------

default-watch-cache-size=100
delete-collection-workers=1
enable-garbage-collector=true
encryption-provider-config-automatic-reload=false
...
```

/sig instrumentation

### Why is this needed?

Refer to [Motivation setcion](https://github.com/kubernetes/enhancements/blob/master/keps/sig-instrumentation/4828-component-flagz/README.md#motivation) in KEP.


Discussion / hints:

Fix patch:
diff --git a/cmd/kube-controller-manager/app/config/config.go b/cmd/kube-controller-manager/app/config/config.go
index feb25bfc7d5b1..e841d109dd1fb 100644
--- a/cmd/kube-controller-manager/app/config/config.go
+++ b/cmd/kube-controller-manager/app/config/config.go
@@ -22,11 +22,15 @@ import (
 	restclient "k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/record"
 	basecompatibility "k8s.io/component-base/compatibility"
+	"k8s.io/component-base/zpages/flagz"
 	kubectrlmgrconfig "k8s.io/kubernetes/pkg/controller/apis/config"
 )
 
 // Config is the main context object for the controller manager.
 type Config struct {
+	// Flagz is the Reader interface to get flags for the flagz page.
+	Flagz flagz.Reader
+
 	ComponentConfig kubectrlmgrconfig.KubeControllerManagerConfiguration
 
 	SecureServing *apiserver.SecureServingInfo
diff --git a/cmd/kube-controller-manager/app/controllermanager.go b/cmd/kube-controller-manager/app/controllermanager.go
index 19723b82c19fd..dc847d66e5d59 100644
--- a/cmd/kube-controller-manager/app/controllermanager.go
+++ b/cmd/kube-controller-manager/app/controllermanager.go
@@ -66,6 +66,7 @@ import (
 	utilversion "k8s.io/component-base/version"
 	"k8s.io/component-base/version/verflag"
 	zpagesfeatures "k8s.io/component-base/zpages/features"
+	"k8s.io/component-base/zpages/flagz"
 	"k8s.io/component-base/zpages/statusz"
 	genericcontrollermanager "k8s.io/controller-manager/app"
 	"k8s.io/controller-manager/controller"
@@ -156,6 +157,7 @@ controller, and serviceaccounts controller.`,
 
 	fs := cmd.Flags()
 	namedFlagSets := s.Flags(KnownControllers(), ControllersDisabledByDefault(), ControllerAliases())
+	s.ParsedFlags = &namedFlagSets
 	verflag.AddFlags(namedFlagSets.FlagSet("global"))
 	globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmd.Name(), logs.SkipLoggingConfigurationFlags())
 	for _, f := range namedFlagSets.FlagSets {
@@ -213,6 +215,11 @@ func Run(ctx context.Context, c *config.CompletedConfig) error {
 	if c.SecureServing != nil {
 		unsecuredMux = genericcontrollermanager.NewBaseHandler(&c.ComponentConfig.Generic.Debugging, healthzHandler)
 		slis.SLIMetricsWithReset{}.Install(unsecuredMux)
+		if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) {
+			if c.Flagz != nil {
+				flagz.Install(unsecuredMux, kubeControllerManager, c.Flagz)
+			}
+		}
 
 		if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentStatusz) {
 			statusz.Install(unsecuredMux, kubeControllerManager, statusz.NewRegistry(c.ComponentGlobalsRegistry.EffectiveVersionFor(basecompatibility.DefaultKubeComponent)))
diff --git a/cmd/kube-controller-manager/app/options/options.go b/cmd/kube-controller-manager/app/options/options.go
index e046fb4a200d6..e21f9b4fdbfcd 100644
--- a/cmd/kube-controller-manager/app/options/options.go
+++ b/cmd/kube-controller-manager/app/options/options.go
@@ -42,6 +42,7 @@ import (
 	"k8s.io/component-base/logs"
 	logsapi "k8s.io/component-base/logs/api/v1"
 	"k8s.io/component-base/metrics"
+	"k8s.io/component-base/zpages/flagz"
 	cmoptions "k8s.io/controller-manager/options"
 	"k8s.io/klog/v2"
 	kubectrlmgrconfigv1alpha1 "k8s.io/kube-controller-manager/config/v1alpha1"
@@ -108,6 +109,9 @@ type KubeControllerManagerOptions struct {
 
 	// ComponentGlobalsRegistry is the registry where the effective versions and feature gates for all components are stored.
 	ComponentGlobalsRegistry basecompatibility.ComponentGlobalsRegistry
+
+	// Parsedflags holds the parsed CLI flags.
+	ParsedFlags *cliflag.NamedFlagSets
 }
 
 // NewKubeControllerManagerOptions creates a new KubeControllerManagerOptions with a default config.
@@ -510,5 +514,11 @@ func (s KubeControllerManagerOptions) Config(allControllers []string, disabledBy
 	}
 	s.Metrics.Apply()
 
+	if s.ParsedFlags != nil {
+		c.Flagz = flagz.NamedFlagSetsReader{
+			FlagSets: *s.ParsedFlags,
+		}
+	}
+
 	return c, nil
 }


Test patch:
diff --git a/cmd/kube-controller-manager/app/testing/testserver.go b/cmd/kube-controller-manager/app/testing/testserver.go
index c29ada8f566c2..0b064b4732911 100644
--- a/cmd/kube-controller-manager/app/testing/testserver.go
+++ b/cmd/kube-controller-manager/app/testing/testserver.go
@@ -102,6 +102,7 @@ func StartTestServer(ctx context.Context, customFlags []string) (result TestServ
 		fs.AddFlagSet(f)
 	}
 	fs.Parse(customFlags)
+	s.ParsedFlags = &namedFlagSets
 
 	if s.SecureServing.BindPort != 0 {
 		s.SecureServing.Listener, s.SecureServing.BindPort, err = createListenerOnFreePort()