diff --git a/cmd/kube-proxy/app/options.go b/cmd/kube-proxy/app/options.go index e63f6a6d610..de062e127f6 100644 --- a/cmd/kube-proxy/app/options.go +++ b/cmd/kube-proxy/app/options.go @@ -31,6 +31,8 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" cliflag "k8s.io/component-base/cli/flag" logsapi "k8s.io/component-base/logs/api/v1" + zpagesfeatures "k8s.io/component-base/zpages/features" + "k8s.io/component-base/zpages/flagz" "k8s.io/klog/v2" "k8s.io/kube-proxy/config/v1alpha1" "k8s.io/kubernetes/pkg/cluster/ports" @@ -63,6 +65,8 @@ type Options struct { proxyServer proxyRun // errCh is the channel that errors will be sent errCh chan error + // flagz is the Reader interface to get flags for the flagz page. + flagz flagz.Reader // The fields below here are placeholders for flags that can't be directly mapped into // config.KubeProxyConfiguration. @@ -233,7 +237,21 @@ func (o *Options) Complete(fs *pflag.FlagSet) error { return err } - return utilfeature.DefaultMutableFeatureGate.SetFromMap(o.config.FeatureGates) + if err := utilfeature.DefaultMutableFeatureGate.SetFromMap(o.config.FeatureGates); err != nil { + return err + } + + if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) { + nfs := cliflag.NamedFlagSets{ + FlagSets: make(map[string]*pflag.FlagSet), + } + nfs.FlagSets["generic"] = fs + o.flagz = flagz.NamedFlagSetsReader{ + FlagSets: nfs, + } + } + + return nil } // copyLogsFromFlags applies the logging flags from the given flag set to the given @@ -353,7 +371,7 @@ func (o *Options) Run(ctx context.Context) error { // We ignore err otherwise; the cleanup is best-effort, and the backends will have // logged messages if they failed in interesting ways. - proxyServer, err := newProxyServer(ctx, o.config, o.master, o.InitAndExit) + proxyServer, err := newProxyServer(ctx, o.config, o.master, o.InitAndExit, o.flagz) if err != nil { return err } diff --git a/cmd/kube-proxy/app/server.go b/cmd/kube-proxy/app/server.go index 385726f907e..1c6492633f4 100644 --- a/cmd/kube-proxy/app/server.go +++ b/cmd/kube-proxy/app/server.go @@ -60,6 +60,7 @@ import ( "k8s.io/component-base/metrics/prometheus/slis" "k8s.io/component-base/version" "k8s.io/component-base/version/verflag" + "k8s.io/component-base/zpages/flagz" nodeutil "k8s.io/component-helpers/node/util" "k8s.io/klog/v2" api "k8s.io/kubernetes/pkg/apis/core" @@ -162,6 +163,7 @@ type ProxyServer struct { Hostname string PrimaryIPFamily v1.IPFamily NodeIPs map[v1.IPFamily]net.IP + flagz flagz.Reader podCIDRs []string // only used for LocalModeNodeCIDR @@ -169,11 +171,12 @@ type ProxyServer struct { } // newProxyServer creates a ProxyServer based on the given config -func newProxyServer(ctx context.Context, config *kubeproxyconfig.KubeProxyConfiguration, master string, initOnly bool) (*ProxyServer, error) { +func newProxyServer(ctx context.Context, config *kubeproxyconfig.KubeProxyConfiguration, master string, initOnly bool, flagzReader flagz.Reader) (*ProxyServer, error) { logger := klog.FromContext(ctx) s := &ProxyServer{ Config: config, + flagz: flagzReader, } cz, err := configz.New(kubeproxyconfig.GroupName) @@ -435,7 +438,7 @@ func serveHealthz(ctx context.Context, hz *healthcheck.ProxierHealthServer, errC go wait.Until(fn, 5*time.Second, ctx.Done()) } -func serveMetrics(ctx context.Context, bindAddress string, proxyMode kubeproxyconfig.ProxyMode, enableProfiling bool, errCh chan error) { +func serveMetrics(ctx context.Context, bindAddress string, proxyMode kubeproxyconfig.ProxyMode, enableProfiling bool, flagzReader flagz.Reader, errCh chan error) { if len(bindAddress) == 0 { return } @@ -459,6 +462,10 @@ func serveMetrics(ctx context.Context, bindAddress string, proxyMode kubeproxyco configz.InstallHandler(proxyMux) + if flagzReader != nil { + flagz.Install(proxyMux, "kube-proxy", flagzReader) + } + fn := func() { var err error defer func() { @@ -526,7 +533,7 @@ func (s *ProxyServer) Run(ctx context.Context) error { serveHealthz(ctx, s.HealthzServer, healthzErrCh) // Start up a metrics server if requested - serveMetrics(ctx, s.Config.MetricsBindAddress, s.Config.Mode, s.Config.EnableProfiling, metricsErrCh) + serveMetrics(ctx, s.Config.MetricsBindAddress, s.Config.Mode, s.Config.EnableProfiling, s.flagz, metricsErrCh) noProxyName, err := labels.NewRequirement(apis.LabelServiceProxyName, selection.DoesNotExist, nil) if err != nil {