Skip to content

Commit

Permalink
Merge pull request #2025 from FabianKramm/main
Browse files Browse the repository at this point in the history
fix: metrics server hpa problem
  • Loading branch information
FabianKramm authored Aug 5, 2024
2 parents ec2c9af + 7b40fb7 commit 5e32ac8
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 20 deletions.
64 changes: 45 additions & 19 deletions pkg/apiservice/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
Expand Down Expand Up @@ -139,7 +142,14 @@ func createOperation(ctrlCtx *synccontext.ControllerContext, serviceName string,
}
}

func StartAPIServiceProxy(ctx *synccontext.ControllerContext, targetServiceName, targetServiceNamespace string, targetPort, hostPort int) error {
func StartAPIServiceProxy(
ctx *synccontext.ControllerContext,
targetServiceName,
targetServiceNamespace string,
targetPort,
hostPort int,
extraHandlers ...func(h http.Handler) http.Handler,
) error {
tlsCertFile := ctx.Config.VirtualClusterKubeConfig().ServerCACert
tlsKeyFile := ctx.Config.VirtualClusterKubeConfig().ServerCAKey

Expand All @@ -162,25 +172,21 @@ func StartAPIServiceProxy(ctx *synccontext.ControllerContext, targetServiceName,
return fmt.Errorf("create host proxy handler: %w", err)
}

s := serializer.NewCodecFactory(scheme.Scheme)
server := &http.Server{
Addr: "localhost:" + strconv.Itoa(hostPort),
Handler: http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
// we only allow traffic to discovery paths
if !isAPIServiceProxyPathAllowed(request.Method, request.URL.Path) {
klog.FromContext(ctx).Info("Denied access to api service proxy at path", "path", request.URL.Path, "method", request.Method)
responsewriters.ErrorNegotiated(
kerrors.NewForbidden(metav1.SchemeGroupVersion.WithResource("proxy").GroupResource(), "proxy", fmt.Errorf("paths other than discovery paths are not allowed")),
s,
corev1.SchemeGroupVersion,
writer,
request,
)
return
}
h := serveHandler(ctx, proxyHandler)

// add custom handlers
for _, extraHandler := range extraHandlers {
h = extraHandler(h)
}

h = genericapifilters.WithRequestInfo(h, &request.RequestInfoFactory{
APIPrefixes: sets.NewString("api", "apis"),
GrouplessAPIPrefixes: sets.NewString("api"),
})

proxyHandler.ServeHTTP(writer, request)
}),
server := &http.Server{
Addr: "localhost:" + strconv.Itoa(hostPort),
Handler: h,
}

go func() {
Expand All @@ -195,6 +201,26 @@ func StartAPIServiceProxy(ctx *synccontext.ControllerContext, targetServiceName,
return nil
}

func serveHandler(ctx context.Context, next http.Handler) http.Handler {
s := serializer.NewCodecFactory(scheme.Scheme)
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
// we only allow traffic to discovery paths
if !isAPIServiceProxyPathAllowed(request.Method, request.URL.Path) {
klog.FromContext(ctx).Info("Denied access to api service proxy at path", "path", request.URL.Path, "method", request.Method)
responsewriters.ErrorNegotiated(
kerrors.NewForbidden(metav1.SchemeGroupVersion.WithResource("proxy").GroupResource(), "proxy", fmt.Errorf("paths other than discovery paths are not allowed")),
s,
corev1.SchemeGroupVersion,
writer,
request,
)
return
}

next.ServeHTTP(writer, request)
})
}

func isAPIServiceProxyPathAllowed(method, path string) bool {
if strings.ToUpper(method) != http.MethodGet {
return false
Expand Down
11 changes: 10 additions & 1 deletion pkg/integrations/metricsserver/metricsserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,16 @@ func Register(ctx *synccontext.ControllerContext) error {
targetService := cmp.Or(ctx.Config.Integrations.MetricsServer.APIService.Service.Name, "metrics-server")
targetServiceNamespace := cmp.Or(ctx.Config.Integrations.MetricsServer.APIService.Service.Namespace, "kube-system")
targetServicePort := cmp.Or(ctx.Config.Integrations.MetricsServer.APIService.Service.Port, 443)
err := apiservice.StartAPIServiceProxy(ctx, targetService, targetServiceNamespace, targetServicePort, hostPort)
err := apiservice.StartAPIServiceProxy(
ctx,
targetService,
targetServiceNamespace,
targetServicePort,
hostPort,
func(h http.Handler) http.Handler {
return WithMetricsServerProxy(h, ctx.ToRegisterContext())
},
)
if err != nil {
return fmt.Errorf("start api service proxy: %w", err)
}
Expand Down

0 comments on commit 5e32ac8

Please sign in to comment.