mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 18:28:13 +00:00 
			
		
		
		
	Add flatz to kubelet auth.
Fix: Move flagz to InstallDebuggingHandlers. Move flagz to the lower switch statemen Fix linter Drop the function parameter for the read-only server.
This commit is contained in:
		| @@ -86,6 +86,8 @@ import ( | ||||
| 	"k8s.io/component-base/tracing" | ||||
| 	"k8s.io/component-base/version" | ||||
| 	"k8s.io/component-base/version/verflag" | ||||
| 	zpagesfeatures "k8s.io/component-base/zpages/features" | ||||
| 	"k8s.io/component-base/zpages/flagz" | ||||
| 	nodeutil "k8s.io/component-helpers/node/util" | ||||
| 	runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" | ||||
| 	kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1" | ||||
| @@ -267,6 +269,13 @@ is checked every 20 seconds (also configurable with a flag).`, | ||||
| 				return fmt.Errorf("failed to construct kubelet dependencies: %w", err) | ||||
| 			} | ||||
|  | ||||
| 			if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) { | ||||
| 				if cleanFlagSet != nil { | ||||
| 					namedFlagSet := map[string]*pflag.FlagSet{server.ComponentKubelet: cleanFlagSet} | ||||
| 					kubeletDeps.Flagz = flagz.NamedFlagSetsReader{FlagSets: cliflag.NamedFlagSets{FlagSets: namedFlagSet}} | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			if err := checkPermissions(); err != nil { | ||||
| 				klog.ErrorS(err, "kubelet running with insufficient permissions") | ||||
| 			} | ||||
|   | ||||
| @@ -68,6 +68,7 @@ import ( | ||||
| 	"k8s.io/client-go/util/certificate" | ||||
| 	"k8s.io/client-go/util/flowcontrol" | ||||
| 	cloudprovider "k8s.io/cloud-provider" | ||||
| 	"k8s.io/component-base/zpages/flagz" | ||||
| 	"k8s.io/component-helpers/apimachinery/lease" | ||||
| 	internalapi "k8s.io/cri-api/pkg/apis" | ||||
| 	runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" | ||||
| @@ -292,6 +293,7 @@ type Dependencies struct { | ||||
| 	Options []Option | ||||
|  | ||||
| 	// Injected Dependencies | ||||
| 	Flagz                     flagz.Reader | ||||
| 	Auth                      server.AuthInterface | ||||
| 	CAdvisorInterface         cadvisor.Interface | ||||
| 	Cloud                     cloudprovider.Interface | ||||
| @@ -616,6 +618,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, | ||||
| 		nodeStatusMaxImages:            nodeStatusMaxImages, | ||||
| 		tracer:                         tracer, | ||||
| 		nodeStartupLatencyTracker:      kubeDeps.NodeStartupLatencyTracker, | ||||
| 		flagz:                          kubeDeps.Flagz, | ||||
| 	} | ||||
|  | ||||
| 	if klet.cloud != nil { | ||||
| @@ -1433,6 +1436,9 @@ type Kubelet struct { | ||||
|  | ||||
| 	// Health check kubelet | ||||
| 	healthChecker watchdog.HealthChecker | ||||
|  | ||||
| 	// flagz is the Reader interface to get flags for flagz page. | ||||
| 	flagz flagz.Reader | ||||
| } | ||||
|  | ||||
| // ListPodStats is delegated to StatsProvider, which implements stats.Provider interface | ||||
| @@ -3084,12 +3090,12 @@ func (kl *Kubelet) BirthCry() { | ||||
| // ListenAndServe runs the kubelet HTTP server. | ||||
| func (kl *Kubelet) ListenAndServe(kubeCfg *kubeletconfiginternal.KubeletConfiguration, tlsOptions *server.TLSOptions, | ||||
| 	auth server.AuthInterface, tp trace.TracerProvider) { | ||||
| 	server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, kl.containerManager.GetHealthCheckers(), kubeCfg, tlsOptions, auth, tp) | ||||
| 	server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, kl.containerManager.GetHealthCheckers(), kl.flagz, kubeCfg, tlsOptions, auth, tp) | ||||
| } | ||||
|  | ||||
| // ListenAndServeReadOnly runs the kubelet HTTP server in read-only mode. | ||||
| func (kl *Kubelet) ListenAndServeReadOnly(address net.IP, port uint, tp trace.TracerProvider) { | ||||
| 	server.ListenAndServeKubeletReadOnlyServer(kl, kl.resourceAnalyzer, kl.containerManager.GetHealthCheckers(), address, port, tp) | ||||
| 	server.ListenAndServeKubeletReadOnlyServer(kl, kl.resourceAnalyzer, kl.containerManager.GetHealthCheckers(), kl.flagz, address, port, tp) | ||||
| } | ||||
|  | ||||
| // ListenAndServePodResources runs the kubelet podresources grpc service | ||||
|   | ||||
| @@ -27,6 +27,7 @@ import ( | ||||
| 	"k8s.io/apiserver/pkg/server/healthz" | ||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" | ||||
| 	"k8s.io/component-base/configz" | ||||
| 	"k8s.io/component-base/zpages/flagz" | ||||
| 	"k8s.io/component-base/zpages/statusz" | ||||
| 	"k8s.io/klog/v2" | ||||
| 	"k8s.io/kubernetes/pkg/features" | ||||
| @@ -74,6 +75,7 @@ func isSubpath(subpath, path string) bool { | ||||
| //	/runningPods/*	=> verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=pods,proxy | ||||
| //	/healthz/* 		=> verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=healthz,proxy | ||||
| //	/configz 		=> verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=configz,proxy | ||||
| //	/flagz 		    => verb=<api verb from request>, resource=nodes, name=<node name>, subresource(s)=configz,proxy | ||||
| func (n nodeAuthorizerAttributesGetter) GetRequestAttributes(u user.Info, r *http.Request) []authorizer.Attributes { | ||||
|  | ||||
| 	apiVerb := "" | ||||
| @@ -120,6 +122,8 @@ func (n nodeAuthorizerAttributesGetter) GetRequestAttributes(u user.Info, r *htt | ||||
| 		subresources = append(subresources, "checkpoint") | ||||
| 	case isSubpath(requestPath, statusz.DefaultStatuszPath): | ||||
| 		subresources = append(subresources, "statusz") | ||||
| 	case isSubpath(requestPath, flagz.DefaultFlagzPath): | ||||
| 		subresources = append(subresources, "configz") | ||||
| 	default: | ||||
| 		subresources = append(subresources, "proxy") | ||||
| 	} | ||||
|   | ||||
| @@ -125,6 +125,7 @@ func AuthzTestCases(fineGrained bool) []AuthzTestCase { | ||||
| 		"/attach/{podNamespace}/{podID}/{uid}/{containerName}": {"proxy"}, | ||||
| 		"/checkpoint/{podNamespace}/{podID}/{containerName}":   {"checkpoint"}, | ||||
| 		"/configz": {"proxy"}, | ||||
| 		"/flagz":   {"configz"}, | ||||
| 		"/statusz": {"statusz"}, | ||||
| 		"/containerLogs/{podNamespace}/{podID}/{containerName}": {"proxy"}, | ||||
| 		"/debug/flags/v":                                     {"proxy"}, | ||||
|   | ||||
| @@ -69,6 +69,7 @@ import ( | ||||
| 	"k8s.io/component-base/metrics/legacyregistry" | ||||
| 	"k8s.io/component-base/metrics/prometheus/slis" | ||||
| 	zpagesfeatures "k8s.io/component-base/zpages/features" | ||||
| 	"k8s.io/component-base/zpages/flagz" | ||||
| 	"k8s.io/component-base/zpages/statusz" | ||||
| 	runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" | ||||
| 	"k8s.io/cri-client/pkg/util" | ||||
| @@ -117,6 +118,7 @@ const ( | ||||
|  | ||||
| // Server is a http.Handler which exposes kubelet functionality over HTTP. | ||||
| type Server struct { | ||||
| 	flagz                flagz.Reader | ||||
| 	auth                 AuthInterface | ||||
| 	host                 HostInterface | ||||
| 	restfulCont          containerInterface | ||||
| @@ -167,6 +169,7 @@ func ListenAndServeKubeletServer( | ||||
| 	host HostInterface, | ||||
| 	resourceAnalyzer stats.ResourceAnalyzer, | ||||
| 	checkers []healthz.HealthChecker, | ||||
| 	flagz flagz.Reader, | ||||
| 	kubeCfg *kubeletconfiginternal.KubeletConfiguration, | ||||
| 	tlsOptions *TLSOptions, | ||||
| 	auth AuthInterface, | ||||
| @@ -175,7 +178,7 @@ func ListenAndServeKubeletServer( | ||||
| 	address := netutils.ParseIPSloppy(kubeCfg.Address) | ||||
| 	port := uint(kubeCfg.Port) | ||||
| 	klog.InfoS("Starting to listen", "address", address, "port", port) | ||||
| 	handler := NewServer(host, resourceAnalyzer, checkers, auth, kubeCfg) | ||||
| 	handler := NewServer(host, resourceAnalyzer, checkers, flagz, auth, kubeCfg) | ||||
|  | ||||
| 	if utilfeature.DefaultFeatureGate.Enabled(features.KubeletTracing) { | ||||
| 		handler.InstallTracingFilter(tp) | ||||
| @@ -210,11 +213,12 @@ func ListenAndServeKubeletReadOnlyServer( | ||||
| 	host HostInterface, | ||||
| 	resourceAnalyzer stats.ResourceAnalyzer, | ||||
| 	checkers []healthz.HealthChecker, | ||||
| 	flagz flagz.Reader, | ||||
| 	address net.IP, | ||||
| 	port uint, | ||||
| 	tp oteltrace.TracerProvider) { | ||||
| 	klog.InfoS("Starting to listen read-only", "address", address, "port", port) | ||||
| 	s := NewServer(host, resourceAnalyzer, checkers, nil, nil) | ||||
| 	s := NewServer(host, resourceAnalyzer, checkers, nil, nil, nil) | ||||
|  | ||||
| 	if utilfeature.DefaultFeatureGate.Enabled(features.KubeletTracing) { | ||||
| 		s.InstallTracingFilter(tp, otelrestful.WithPublicEndpoint()) | ||||
| @@ -291,10 +295,12 @@ func NewServer( | ||||
| 	host HostInterface, | ||||
| 	resourceAnalyzer stats.ResourceAnalyzer, | ||||
| 	checkers []healthz.HealthChecker, | ||||
| 	flagz flagz.Reader, | ||||
| 	auth AuthInterface, | ||||
| 	kubeCfg *kubeletconfiginternal.KubeletConfiguration) Server { | ||||
|  | ||||
| 	server := Server{ | ||||
| 		flagz:                flagz, | ||||
| 		host:                 host, | ||||
| 		resourceAnalyzer:     resourceAnalyzer, | ||||
| 		auth:                 auth, | ||||
| @@ -575,6 +581,13 @@ func (s *Server) InstallAuthRequiredHandlers() { | ||||
| 		statusz.Install(s.restfulCont, ComponentKubelet, statusz.NewRegistry(compatibility.DefaultBuildEffectiveVersion())) | ||||
| 	} | ||||
|  | ||||
| 	if utilfeature.DefaultFeatureGate.Enabled(zpagesfeatures.ComponentFlagz) { | ||||
| 		if s.flagz != nil { | ||||
| 			s.addMetricsBucketMatcher("flagz") | ||||
| 			flagz.Install(s.restfulCont, ComponentKubelet, s.flagz) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// The /runningpods endpoint is used for testing only. | ||||
| 	s.addMetricsBucketMatcher("runningpods") | ||||
| 	ws = new(restful.WebService) | ||||
|   | ||||
| @@ -59,6 +59,7 @@ import ( | ||||
| 	utilfeature "k8s.io/apiserver/pkg/util/feature" | ||||
| 	featuregatetesting "k8s.io/component-base/featuregate/testing" | ||||
| 	zpagesfeatures "k8s.io/component-base/zpages/features" | ||||
| 	"k8s.io/component-base/zpages/flagz" | ||||
| 	"k8s.io/kubelet/pkg/cri/streaming" | ||||
| 	"k8s.io/kubelet/pkg/cri/streaming/portforward" | ||||
| 	remotecommandserver "k8s.io/kubelet/pkg/cri/streaming/remotecommand" | ||||
| @@ -373,6 +374,7 @@ func newServerTestWithDebuggingHandlers(kubeCfg *kubeletconfiginternal.KubeletCo | ||||
| 		fw.fakeKubelet, | ||||
| 		stats.NewResourceAnalyzer(fw.fakeKubelet, time.Minute, &record.FakeRecorder{}), | ||||
| 		[]healthz.HealthChecker{}, | ||||
| 		flagz.NamedFlagSetsReader{}, | ||||
| 		fw.fakeAuth, | ||||
| 		kubeCfg, | ||||
| 	) | ||||
| @@ -646,6 +648,7 @@ func TestAuthFilters(t *testing.T) { | ||||
| 	// Enable features.ContainerCheckpoint during test | ||||
| 	featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ContainerCheckpoint, true) | ||||
| 	featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, zpagesfeatures.ComponentStatusz, true) | ||||
| 	featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, zpagesfeatures.ComponentFlagz, true) | ||||
|  | ||||
| 	fw := newServerTest() | ||||
| 	defer fw.testHTTPServer.Close() | ||||
| @@ -1729,9 +1732,11 @@ func TestMetricBuckets(t *testing.T) { | ||||
| 		"stats":                           {url: "/stats/", bucket: "stats"}, | ||||
| 		"stats summary sub":               {url: "/stats/summary", bucket: "stats"}, | ||||
| 		"statusz":                         {url: "/statusz", bucket: "statusz"}, | ||||
| 		"/flagz":                          {url: "/flagz", bucket: "flagz"}, | ||||
| 		"invalid path":                    {url: "/junk", bucket: "other"}, | ||||
| 		"invalid path starting with good": {url: "/healthzjunk", bucket: "other"}, | ||||
| 	} | ||||
| 	featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, zpagesfeatures.ComponentFlagz, true) | ||||
| 	fw := newServerTest() | ||||
| 	defer fw.testHTTPServer.Close() | ||||
|  | ||||
| @@ -1960,8 +1965,8 @@ func TestNewServerRegistersMetricsSLIsEndpointTwice(t *testing.T) { | ||||
| 	} | ||||
| 	resourceAnalyzer := stats.NewResourceAnalyzer(nil, time.Minute, &record.FakeRecorder{}) | ||||
|  | ||||
| 	server1 := NewServer(host, resourceAnalyzer, []healthz.HealthChecker{}, nil, nil) | ||||
| 	server2 := NewServer(host, resourceAnalyzer, []healthz.HealthChecker{}, nil, nil) | ||||
| 	server1 := NewServer(host, resourceAnalyzer, []healthz.HealthChecker{}, flagz.NamedFlagSetsReader{}, nil, nil) | ||||
| 	server2 := NewServer(host, resourceAnalyzer, []healthz.HealthChecker{}, flagz.NamedFlagSetsReader{}, nil, nil) | ||||
|  | ||||
| 	// Check if both servers registered the /metrics/slis endpoint | ||||
| 	assert.Contains(t, server1.restfulCont.RegisteredHandlePaths(), "/metrics/slis", "First server should register /metrics/slis") | ||||
|   | ||||
| @@ -30,6 +30,8 @@ import ( | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	DefaultFlagzPath = "/flagz" | ||||
|  | ||||
| 	flagzHeaderFmt = ` | ||||
| %s flags | ||||
| Warning: This endpoint is not meant to be machine parseable, has no formatting compatibility guarantees and is for debugging purposes only. | ||||
| @@ -56,7 +58,7 @@ func Install(m mux, componentName string, flagReader Reader) { | ||||
| } | ||||
|  | ||||
| func (reg *registry) installHandler(m mux, componentName string, flagReader Reader) { | ||||
| 	m.Handle("/flagz", reg.handleFlags(componentName, flagReader)) | ||||
| 	m.Handle(DefaultFlagzPath, reg.handleFlags(componentName, flagReader)) | ||||
| } | ||||
|  | ||||
| func (reg *registry) handleFlags(componentName string, flagReader Reader) http.HandlerFunc { | ||||
|   | ||||
| @@ -85,7 +85,7 @@ func TestFlagz(t *testing.T) { | ||||
| 			mux := http.NewServeMux() | ||||
| 			Install(mux, componentName, test.flagzReader) | ||||
|  | ||||
| 			req, err := http.NewRequest(http.MethodGet, "http://example.com/flagz", nil) | ||||
| 			req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://example.com%s", DefaultFlagzPath), nil) | ||||
| 			if err != nil { | ||||
| 				t.Fatalf("case[%d] Unexpected error: %v", i, err) | ||||
| 			} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 zhangzhifei16
					zhangzhifei16