mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Add LRU Expire cache to webhook authorizer.
This commit is contained in:
		@@ -60,6 +60,8 @@ kube-apiserver
 | 
			
		||||
      --authentication-token-webhook-config-file="": File with webhook configuration for token authentication in kubeconfig format. The API server will query the remote service to determine authentication for bearer tokens.
 | 
			
		||||
      --authorization-mode="AlwaysAllow": Ordered list of plug-ins to do authorization on secure port. Comma-delimited list of: AlwaysAllow,AlwaysDeny,ABAC,Webhook
 | 
			
		||||
      --authorization-policy-file="": File with authorization policy in csv format, used with --authorization-mode=ABAC, on the secure port.
 | 
			
		||||
      --authorization-webhook-cache-authorized-ttl=5m0s: The duration to cache 'authorized' responses from the webhook authorizer. Default is 5m.
 | 
			
		||||
      --authorization-webhook-cache-unauthorized-ttl=30s: The duration to cache 'unauthorized' responses from the webhook authorizer. Default is 30s.
 | 
			
		||||
      --authorization-webhook-config-file="": File with webhook configuration in kubeconfig format, used with --authorization-mode=Webhook. The API server will query the remote service to determine access on the API server's secure port.
 | 
			
		||||
      --basic-auth-file="": If set, the file that will be used to admit requests to the secure port of the API server via http basic authentication.
 | 
			
		||||
      --bind-address=0.0.0.0: The IP address on which to listen for the --secure-port port. The associated interface(s) must be reachable by the rest of the cluster, and by CLI/web clients. If blank, all interfaces will be used (0.0.0.0).
 | 
			
		||||
@@ -121,7 +123,7 @@ kube-apiserver
 | 
			
		||||
      --watch-cache-sizes=[]: List of watch cache sizes for every resource (pods, nodes, etc.), comma separated. The individual override format: resource#size, where size is a number. It takes effect when watch-cache is enabled.
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
###### Auto generated by spf13/cobra on 17-May-2016
 | 
			
		||||
###### Auto generated by spf13/cobra on 18-May-2016
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,8 @@ authentication-token-webhook-config-file
 | 
			
		||||
authorization-mode
 | 
			
		||||
authorization-policy-file
 | 
			
		||||
authorization-webhook-config-file
 | 
			
		||||
authorization-webhook-cache-authorized-ttl
 | 
			
		||||
authorization-webhook-cache-unauthorized-ttl
 | 
			
		||||
babysit-daemons
 | 
			
		||||
basic-auth-file
 | 
			
		||||
bench-pods
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ package apiserver
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/pkg/auth/authorizer"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/auth/authorizer/abac"
 | 
			
		||||
@@ -77,6 +78,10 @@ type AuthorizationConfig struct {
 | 
			
		||||
 | 
			
		||||
	// Kubeconfig file for Webhook authorization plugin.
 | 
			
		||||
	WebhookConfigFile string
 | 
			
		||||
	// TTL for caching of authorized responses from the webhook server.
 | 
			
		||||
	WebhookCacheAuthorizedTTL time.Duration
 | 
			
		||||
	// TTL for caching of unauthorized responses from the webhook server.
 | 
			
		||||
	WebhookCacheUnauthorizedTTL time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewAuthorizerFromAuthorizationConfig returns the right sort of union of multiple authorizer.Authorizer objects
 | 
			
		||||
@@ -114,7 +119,9 @@ func NewAuthorizerFromAuthorizationConfig(authorizationModes []string, config Au
 | 
			
		||||
			if config.WebhookConfigFile == "" {
 | 
			
		||||
				return nil, errors.New("Webhook's configuration file not passed")
 | 
			
		||||
			}
 | 
			
		||||
			webhookAuthorizer, err := webhook.New(config.WebhookConfigFile)
 | 
			
		||||
			webhookAuthorizer, err := webhook.New(config.WebhookConfigFile,
 | 
			
		||||
				config.WebhookCacheAuthorizedTTL,
 | 
			
		||||
				config.WebhookCacheUnauthorizedTTL)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/pkg/admission"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api"
 | 
			
		||||
@@ -103,10 +104,14 @@ type ServerRunOptions struct {
 | 
			
		||||
 | 
			
		||||
func NewServerRunOptions() *ServerRunOptions {
 | 
			
		||||
	return &ServerRunOptions{
 | 
			
		||||
		APIGroupPrefix:          "/apis",
 | 
			
		||||
		APIPrefix:               "/api",
 | 
			
		||||
		AdmissionControl:        "AlwaysAdmit",
 | 
			
		||||
		AuthorizationMode:       "AlwaysAllow",
 | 
			
		||||
		APIGroupPrefix:    "/apis",
 | 
			
		||||
		APIPrefix:         "/api",
 | 
			
		||||
		AdmissionControl:  "AlwaysAdmit",
 | 
			
		||||
		AuthorizationMode: "AlwaysAllow",
 | 
			
		||||
		AuthorizationConfig: apiserver.AuthorizationConfig{
 | 
			
		||||
			WebhookCacheAuthorizedTTL:   5 * time.Minute,
 | 
			
		||||
			WebhookCacheUnauthorizedTTL: 30 * time.Second,
 | 
			
		||||
		},
 | 
			
		||||
		BindAddress:             net.ParseIP("0.0.0.0"),
 | 
			
		||||
		CertDirectory:           "/var/run/kubernetes",
 | 
			
		||||
		DefaultStorageMediaType: "application/json",
 | 
			
		||||
@@ -220,6 +225,8 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
 | 
			
		||||
 | 
			
		||||
	fs.StringVar(&s.AuthorizationConfig.PolicyFile, "authorization-policy-file", s.AuthorizationConfig.PolicyFile, "File with authorization policy in csv format, used with --authorization-mode=ABAC, on the secure port.")
 | 
			
		||||
	fs.StringVar(&s.AuthorizationConfig.WebhookConfigFile, "authorization-webhook-config-file", s.AuthorizationConfig.WebhookConfigFile, "File with webhook configuration in kubeconfig format, used with --authorization-mode=Webhook. The API server will query the remote service to determine access on the API server's secure port.")
 | 
			
		||||
	fs.DurationVar(&s.AuthorizationConfig.WebhookCacheAuthorizedTTL, "authorization-webhook-cache-authorized-ttl", s.AuthorizationConfig.WebhookCacheAuthorizedTTL, "The duration to cache 'authorized' responses from the webhook authorizer. Default is 5m.")
 | 
			
		||||
	fs.DurationVar(&s.AuthorizationConfig.WebhookCacheUnauthorizedTTL, "authorization-webhook-cache-unauthorized-ttl", s.AuthorizationConfig.WebhookCacheUnauthorizedTTL, "The duration to cache 'unauthorized' responses from the webhook authorizer. Default is 30s.")
 | 
			
		||||
 | 
			
		||||
	fs.StringVar(&s.BasicAuthFile, "basic-auth-file", s.BasicAuthFile, "If set, the file that will be used to admit requests to the secure port of the API server via http basic authentication.")
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,11 +18,14 @@ limitations under the License.
 | 
			
		||||
package webhook
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/unversioned"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/apis/authorization/v1beta1"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/auth/authorizer"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/cache"
 | 
			
		||||
	"k8s.io/kubernetes/plugin/pkg/webhook"
 | 
			
		||||
 | 
			
		||||
	_ "k8s.io/kubernetes/pkg/apis/authorization/install"
 | 
			
		||||
@@ -37,6 +40,9 @@ var _ authorizer.Authorizer = (*WebhookAuthorizer)(nil)
 | 
			
		||||
 | 
			
		||||
type WebhookAuthorizer struct {
 | 
			
		||||
	*webhook.GenericWebhook
 | 
			
		||||
	responseCache   *cache.LRUExpireCache
 | 
			
		||||
	authorizedTTL   time.Duration
 | 
			
		||||
	unauthorizedTTL time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New creates a new WebhookAuthorizer from the provided kubeconfig file.
 | 
			
		||||
@@ -59,12 +65,12 @@ type WebhookAuthorizer struct {
 | 
			
		||||
//
 | 
			
		||||
// For additional HTTP configuration, refer to the kubeconfig documentation
 | 
			
		||||
// http://kubernetes.io/v1.1/docs/user-guide/kubeconfig-file.html.
 | 
			
		||||
func New(kubeConfigFile string) (*WebhookAuthorizer, error) {
 | 
			
		||||
func New(kubeConfigFile string, authorizedTTL, unauthorizedTTL time.Duration) (*WebhookAuthorizer, error) {
 | 
			
		||||
	gw, err := webhook.NewGenericWebhook(kubeConfigFile, groupVersions)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &WebhookAuthorizer{gw}, nil
 | 
			
		||||
	return &WebhookAuthorizer{gw, cache.NewLRUExpireCache(1024), authorizedTTL, unauthorizedTTL}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Authorize makes a REST request to the remote service describing the attempted action as a JSON
 | 
			
		||||
@@ -134,13 +140,27 @@ func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (err error) {
 | 
			
		||||
			Verb: attr.GetVerb(),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	result := w.RestClient.Post().Body(r).Do()
 | 
			
		||||
	if err := result.Error(); err != nil {
 | 
			
		||||
	key, err := json.Marshal(r.Spec)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := result.Into(r); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	if entry, ok := w.responseCache.Get(string(key)); ok {
 | 
			
		||||
		r.Status = entry.(v1beta1.SubjectAccessReviewStatus)
 | 
			
		||||
	} else {
 | 
			
		||||
		result := w.RestClient.Post().Body(r).Do()
 | 
			
		||||
		if err := result.Error(); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if err := result.Into(r); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		go func() {
 | 
			
		||||
			if r.Status.Allowed {
 | 
			
		||||
				w.responseCache.Add(string(key), r.Status, w.authorizedTTL)
 | 
			
		||||
			} else {
 | 
			
		||||
				w.responseCache.Add(string(key), r.Status, w.unauthorizedTTL)
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
	}
 | 
			
		||||
	if r.Status.Allowed {
 | 
			
		||||
		return nil
 | 
			
		||||
 
 | 
			
		||||
@@ -182,7 +182,7 @@ current-context: default
 | 
			
		||||
				return fmt.Errorf("failed to execute test template: %v", err)
 | 
			
		||||
			}
 | 
			
		||||
			// Create a new authorizer
 | 
			
		||||
			_, err = New(p)
 | 
			
		||||
			_, err = New(p, 0, 0)
 | 
			
		||||
			return err
 | 
			
		||||
		}()
 | 
			
		||||
		if err != nil && !tt.wantErr {
 | 
			
		||||
@@ -283,7 +283,7 @@ func newAuthorizer(callbackURL string, clientCert, clientKey, ca []byte) (*Webho
 | 
			
		||||
	if err := json.NewEncoder(tempfile).Encode(config); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return New(p)
 | 
			
		||||
	return New(p, 0, 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestTLSConfig(t *testing.T) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user