From 1289bdaba41848c0d19892cc749798e540b56e8a Mon Sep 17 00:00:00 2001 From: Jefftree Date: Tue, 12 Nov 2019 17:35:45 -0800 Subject: [PATCH] network proxy with admission wh --- cmd/kube-apiserver/app/server.go | 6 ++-- pkg/kubeapiserver/admission/BUILD | 1 + pkg/kubeapiserver/admission/config.go | 5 +-- .../pkg/cmd/server/options/options.go | 2 +- .../k8s.io/apiserver/pkg/util/webhook/BUILD | 1 + .../pkg/util/webhook/authentication.go | 35 +++++++++++++++++-- 6 files changed, 41 insertions(+), 9 deletions(-) diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index f12a55f8ac8..12ad9f4d46d 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -176,7 +176,7 @@ func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan // If additional API servers are added, they should be gated. apiExtensionsConfig, err := createAPIExtensionsConfig(*kubeAPIServerConfig.GenericConfig, kubeAPIServerConfig.ExtraConfig.VersionedInformers, pluginInitializer, completedOptions.ServerRunOptions, completedOptions.MasterCount, - serviceResolver, webhook.NewDefaultAuthenticationInfoResolverWrapper(proxyTransport, kubeAPIServerConfig.GenericConfig.LoopbackClientConfig)) + serviceResolver, webhook.NewDefaultAuthenticationInfoResolverWrapper(proxyTransport, kubeAPIServerConfig.GenericConfig.EgressSelector, kubeAPIServerConfig.GenericConfig.LoopbackClientConfig)) if err != nil { return nil, err } @@ -491,7 +491,7 @@ func buildGenericConfig( } serviceResolver = buildServiceResolver(s.EnableAggregatorRouting, genericConfig.LoopbackClientConfig.Host, versionedInformers) - authInfoResolverWrapper := webhook.NewDefaultAuthenticationInfoResolverWrapper(proxyTransport, genericConfig.LoopbackClientConfig) + authInfoResolverWrapper := webhook.NewDefaultAuthenticationInfoResolverWrapper(proxyTransport, genericConfig.EgressSelector, genericConfig.LoopbackClientConfig) lastErr = s.Audit.ApplyTo( genericConfig, @@ -507,7 +507,7 @@ func buildGenericConfig( return } - pluginInitializers, admissionPostStartHook, err = admissionConfig.New(proxyTransport, serviceResolver) + pluginInitializers, admissionPostStartHook, err = admissionConfig.New(proxyTransport, genericConfig.EgressSelector, serviceResolver) if err != nil { lastErr = fmt.Errorf("failed to create admission plugin initializer: %v", err) return diff --git a/pkg/kubeapiserver/admission/BUILD b/pkg/kubeapiserver/admission/BUILD index 60584cab146..979f7a35203 100644 --- a/pkg/kubeapiserver/admission/BUILD +++ b/pkg/kubeapiserver/admission/BUILD @@ -16,6 +16,7 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/server/egressselector:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library", "//staging/src/k8s.io/client-go/discovery/cached/memory:go_default_library", "//staging/src/k8s.io/client-go/informers:go_default_library", diff --git a/pkg/kubeapiserver/admission/config.go b/pkg/kubeapiserver/admission/config.go index 21e8bc80bcc..8eb1c095d83 100644 --- a/pkg/kubeapiserver/admission/config.go +++ b/pkg/kubeapiserver/admission/config.go @@ -27,6 +27,7 @@ import ( "k8s.io/apiserver/pkg/admission" webhookinit "k8s.io/apiserver/pkg/admission/plugin/webhook/initializer" genericapiserver "k8s.io/apiserver/pkg/server" + egressselector "k8s.io/apiserver/pkg/server/egressselector" "k8s.io/apiserver/pkg/util/webhook" cacheddiscovery "k8s.io/client-go/discovery/cached/memory" externalinformers "k8s.io/client-go/informers" @@ -44,8 +45,8 @@ type Config struct { } // New sets up the plugins and admission start hooks needed for admission -func (c *Config) New(proxyTransport *http.Transport, serviceResolver webhook.ServiceResolver) ([]admission.PluginInitializer, genericapiserver.PostStartHookFunc, error) { - webhookAuthResolverWrapper := webhook.NewDefaultAuthenticationInfoResolverWrapper(proxyTransport, c.LoopbackClientConfig) +func (c *Config) New(proxyTransport *http.Transport, egressSelector *egressselector.EgressSelector, serviceResolver webhook.ServiceResolver) ([]admission.PluginInitializer, genericapiserver.PostStartHookFunc, error) { + webhookAuthResolverWrapper := webhook.NewDefaultAuthenticationInfoResolverWrapper(proxyTransport, egressSelector, c.LoopbackClientConfig) webhookPluginInitializer := webhookinit.NewPluginInitializer(webhookAuthResolverWrapper, serviceResolver) var cloudConfig []byte diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server/options/options.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server/options/options.go index b624f0b1033..786dc60ab53 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server/options/options.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server/options/options.go @@ -104,7 +104,7 @@ func (o CustomResourceDefinitionsServerOptions) Config() (*apiserver.Config, err ExtraConfig: apiserver.ExtraConfig{ CRDRESTOptionsGetter: NewCRDRESTOptionsGetter(*o.RecommendedOptions.Etcd), ServiceResolver: &serviceResolver{serverConfig.SharedInformerFactory.Core().V1().Services().Lister()}, - AuthResolverWrapper: webhook.NewDefaultAuthenticationInfoResolverWrapper(nil, serverConfig.LoopbackClientConfig), + AuthResolverWrapper: webhook.NewDefaultAuthenticationInfoResolverWrapper(nil, nil, serverConfig.LoopbackClientConfig), }, } return config, nil diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD b/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD index d8b20370007..91717516b83 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD @@ -29,6 +29,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", + "//staging/src/k8s.io/apiserver/pkg/server/egressselector:go_default_library", "//staging/src/k8s.io/client-go/rest:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/authentication.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/authentication.go index 9d78e936a54..042879dade9 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/authentication.go +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/authentication.go @@ -26,6 +26,8 @@ import ( "time" corev1 "k8s.io/api/core/v1" + utilnet "k8s.io/apimachinery/pkg/util/net" + egressselector "k8s.io/apiserver/pkg/server/egressselector" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" @@ -38,6 +40,7 @@ type AuthenticationInfoResolverWrapper func(AuthenticationInfoResolver) Authenti // NewDefaultAuthenticationInfoResolverWrapper builds a default authn resolver wrapper func NewDefaultAuthenticationInfoResolverWrapper( proxyTransport *http.Transport, + egressSelector *egressselector.EgressSelector, kubeapiserverClientConfig *rest.Config) AuthenticationInfoResolverWrapper { webhookAuthResolverWrapper := func(delegate AuthenticationInfoResolver) AuthenticationInfoResolver { @@ -46,7 +49,23 @@ func NewDefaultAuthenticationInfoResolverWrapper( if hostPort == "kubernetes.default.svc:443" { return kubeapiserverClientConfig, nil } - return delegate.ClientConfigFor(hostPort) + ret, err := delegate.ClientConfigFor(hostPort) + if err != nil { + return nil, err + } + + if egressSelector != nil { + networkContext := egressselector.Master.AsNetworkContext() + var egressDialer utilnet.DialFunc + egressDialer, err = egressSelector.Lookup(networkContext) + + if err != nil { + return nil, err + } + + ret.Dial = egressDialer + } + return ret, nil }, ClientConfigForServiceFunc: func(serviceName, serviceNamespace string, servicePort int) (*rest.Config, error) { if serviceName == "kubernetes" && serviceNamespace == corev1.NamespaceDefault && servicePort == 443 { @@ -56,10 +75,20 @@ func NewDefaultAuthenticationInfoResolverWrapper( if err != nil { return nil, err } - if proxyTransport != nil && proxyTransport.DialContext != nil { + + if egressSelector != nil { + networkContext := egressselector.Cluster.AsNetworkContext() + var egressDialer utilnet.DialFunc + egressDialer, err = egressSelector.Lookup(networkContext) + if err != nil { + return nil, err + } + + ret.Dial = egressDialer + } else if proxyTransport != nil && proxyTransport.DialContext != nil { ret.Dial = proxyTransport.DialContext } - return ret, err + return ret, nil }, } }