Change:
We are getting the following error when the apiserver connects the webhook on localhost (configured via URL). We should only use the SSL tunnel for the connections to nodes when the webhooks are running as services. /sig api-machinery /kind bug /assign
/close

Discussion:
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName) } <del> webhookAuthResolver := func(delegate webhookconfig.AuthenticationInfoResolver) webhookconfig.AuthenticationInfoResolver { return webhookconfig.AuthenticationInfoResolverFunc(func(server string) (*rest.Config, error) { if server == "kubernetes.default.svc" { return genericConfig.LoopbackClientConfig, nil } ret, err := delegate.ClientConfigFor(server) if err != nil { return nil, err } if proxyTransport != nil && proxyTransport.Dial != nil { ret.Dial = proxyTransport.Dial } return ret, err }) </del> <ins> webhookAuthResolverWrapper := func(delegate webhookconfig.AuthenticationInfoResolver) webhookconfig.AuthenticationInfoResolver { return &webhookconfig.AuthenticationInfoResolverDelegator{ ClientConfigForFunc: func(server string) (*rest.Config, error) { if server == "kubernetes.default.svc" { return genericConfig.LoopbackClientConfig, nil } return delegate.ClientConfigFor(server) }, ClientConfigForServiceFunc: func(serviceName, serviceNamespace string) (*rest.Config, error) { if serviceName == "kubernetes" && serviceNamespace == "default" { return genericConfig.LoopbackClientConfig, nil } ret, err := delegate.ClientConfigForService(serviceName, serviceNamespace) if err != nil { return nil, err } if proxyTransport != nil && proxyTransport.Dial != nil { ret.Dial = proxyTransport.Dial } return ret, err }, } </ins> } pluginInitializers, err := BuildAdmissionPluginInitializers( s, client, sharedInformers, serviceResolver, <del> webhookAuthResolver, </del> <ins> webhookAuthResolverWrapper, </ins> ) if err != nil { return nil, nil, nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %v", err)

// rest.Config generated by the resolver. type AuthenticationInfoResolverWrapper func(AuthenticationInfoResolver) AuthenticationInfoResolver <del> // AuthenticationInfoResolver builds rest.Config base on the server name. </del> <ins> // AuthenticationInfoResolver builds rest.Config base on the server or service // name and service namespace. </ins> type AuthenticationInfoResolver interface { <ins> // ClientConfigFor builds rest.Config based on the server. </ins> ClientConfigFor(server string) (*rest.Config, error) <ins> // ClientConfigForService builds rest.Config based on the serviceName and // serviceNamespace. ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error) </ins> } <del> // AuthenticationInfoResolverFunc implements AuthenticationInfoResolver. type AuthenticationInfoResolverFunc func(server string) (*rest.Config, error) </del> <ins> // AuthenticationInfoResolverDelegator implements AuthenticationInfoResolver. type AuthenticationInfoResolverDelegator struct { ClientConfigForFunc        func(server string) (*rest.Config, error) ClientConfigForServiceFunc func(serviceName, serviceNamespace string) (*rest.Config, error) } func (a *AuthenticationInfoResolverDelegator) ClientConfigFor(server string) (*rest.Config, error) { return a.ClientConfigForFunc(server) } </ins> <del> //ClientConfigFor implements AuthenticationInfoResolver. func (a AuthenticationInfoResolverFunc) ClientConfigFor(server string) (*rest.Config, error) { return a(server) </del> <ins> func (a *AuthenticationInfoResolverDelegator) ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error) { return a.ClientConfigForServiceFunc(serviceName, serviceNamespace) </ins> } type defaultAuthenticationInfoResolver struct {

} func (c *defaultAuthenticationInfoResolver) ClientConfigFor(server string) (*rest.Config, error) { <ins> return c.clientConfig(server) } func (c *defaultAuthenticationInfoResolver) ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error) { return c.clientConfig(serviceName + "." + serviceNamespace + ".svc") } func (c *defaultAuthenticationInfoResolver) clientConfig(target string) (*rest.Config, error) { </ins> // exact match <del> if authConfig, ok := c.kubeconfig.AuthInfos[server]; ok { </del> <ins> if authConfig, ok := c.kubeconfig.AuthInfos[target]; ok { </ins> return restConfigFromKubeconfig(authConfig) } // star prefixed match <del> serverSteps := strings.Split(server, ".") </del> <ins> serverSteps := strings.Split(target, ".") </ins> for i := 1; i < len(serverSteps); i++ { nickName := "*." + strings.Join(serverSteps[i:], ".") if authConfig, ok := c.kubeconfig.AuthInfos[nickName]; ok {

} // if we're trying to hit the kube-apiserver and there wasn't an explicit config, use the in-cluster config <del> if server == "kubernetes.default.svc" { </del> <ins> if target == "kubernetes.default.svc" { </ins> // if we can find an in-cluster-config use that.  If we can't, fall through. inClusterConfig, err := rest.InClusterConfig() if err == nil {

} if svc := h.ClientConfig.Service; svc != nil { <del> serverName := svc.Name + "." + svc.Namespace + ".svc" restConfig, err := cm.authInfoResolver.ClientConfigFor(serverName) </del> <ins> restConfig, err := cm.authInfoResolver.ClientConfigForService(svc.Name, svc.Namespace) </ins> if err != nil { return nil, err } cfg := rest.CopyConfig(restConfig) <ins> serverName := svc.Name + "." + svc.Namespace + ".svc" </ins> host := serverName + ":443" cfg.Host = "https://" + host if svc.Path != nil {

return c.restConfig, nil } <ins> func (c *fakeAuthenticationInfoResolver) ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error) { atomic.AddInt32(c.cachedCount, 1) return c.restConfig, nil } </ins> func newMatchEverythingRules() []registrationv1beta1.RuleWithOperations { return []registrationv1beta1.RuleWithOperations{{ Operations: []registrationv1beta1.OperationType{registrationv1beta1.OperationAll},