Extract etcd options from genericapiserver.

This commit is contained in:
mksalawa 2016-08-09 13:35:53 +02:00
parent 899d98ad15
commit a806351cc3
13 changed files with 179 additions and 91 deletions

View File

@ -24,7 +24,7 @@ import (
// NewFederationAPIServer creates a new hyperkube Server object that includes the
// description and flags.
func NewFederationAPIServer() *Server {
s := genericoptions.NewServerRunOptions()
s := genericoptions.NewServerRunOptions().WithEtcdOptions()
hks := Server{
SimpleUsage: "federation-apiserver",
@ -33,6 +33,7 @@ func NewFederationAPIServer() *Server {
return app.Run(s)
},
}
s.AddFlags(hks.Flags())
s.AddUniversalFlags(hks.Flags())
s.AddEtcdStorageFlags(hks.Flags())
return &hks
}

View File

@ -47,7 +47,7 @@ type APIServer struct {
// NewAPIServer creates a new APIServer object with default parameters
func NewAPIServer() *APIServer {
s := APIServer{
ServerRunOptions: genericoptions.NewServerRunOptions(),
ServerRunOptions: genericoptions.NewServerRunOptions().WithEtcdOptions(),
EventTTL: 1 * time.Hour,
KubeletConfig: kubeletclient.KubeletClientConfig{
Port: ports.KubeletPort,
@ -62,7 +62,9 @@ func NewAPIServer() *APIServer {
// AddFlags adds flags for a specific APIServer to the specified FlagSet
func (s *APIServer) AddFlags(fs *pflag.FlagSet) {
// Add the generic flags.
s.ServerRunOptions.AddFlags(fs)
s.ServerRunOptions.AddUniversalFlags(fs)
//Add etcd specific flags.
s.ServerRunOptions.AddEtcdStorageFlags(fs)
// Note: the weird ""+ in below lines seems to be the only way to get gofmt to
// arrange these text blocks sensibly. Grrr.

View File

@ -46,6 +46,7 @@ import (
"k8s.io/kubernetes/pkg/controller/framework/informers"
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
"k8s.io/kubernetes/pkg/genericapiserver"
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/master"
"k8s.io/kubernetes/pkg/registry/cachesize"
@ -81,6 +82,7 @@ cluster's shared state through which all other components interact.`,
// Run runs the specified APIServer. This should never exit.
func Run(s *options.APIServer) error {
genericvalidation.VerifyEtcdServersList(s.ServerRunOptions)
genericapiserver.DefaultAndValidateRunOptions(s.ServerRunOptions)
capabilities.Initialize(capabilities.Capabilities{

View File

@ -28,6 +28,7 @@ import (
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/genericapiserver"
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
"k8s.io/kubernetes/pkg/storage/storagebackend"
// Install the testgroup API
@ -51,7 +52,7 @@ func newStorageFactory() genericapiserver.StorageFactory {
}
func NewServerRunOptions() *genericoptions.ServerRunOptions {
serverOptions := genericoptions.NewServerRunOptions()
serverOptions := genericoptions.NewServerRunOptions().WithEtcdOptions()
serverOptions.InsecurePort = InsecurePort
return serverOptions
}
@ -61,7 +62,8 @@ func Run(serverOptions *genericoptions.ServerRunOptions) error {
_, serviceClusterIPRange, _ := net.ParseCIDR("10.0.0.0/24")
serverOptions.ServiceClusterIPRange = *serviceClusterIPRange
serverOptions.StorageConfig.ServerList = []string{"http://127.0.0.1:4001"}
genericapiserver.ValidateRunOptions(serverOptions)
genericvalidation.ValidateRunOptions(serverOptions)
genericvalidation.VerifyEtcdServersList(serverOptions)
config := genericapiserver.NewConfig(serverOptions)
config.Serializer = api.Codecs
s, err := genericapiserver.New(config)

View File

@ -28,7 +28,8 @@ func main() {
serverRunOptions := apiserver.NewServerRunOptions()
// Parse command line flags.
serverRunOptions.AddFlags(pflag.CommandLine)
serverRunOptions.AddUniversalFlags(pflag.CommandLine)
serverRunOptions.AddEtcdStorageFlags(pflag.CommandLine)
flag.InitFlags()
if err := apiserver.Run(serverRunOptions); err != nil {

View File

@ -36,8 +36,9 @@ import (
func main() {
rand.Seed(time.Now().UTC().UnixNano())
s := genericoptions.NewServerRunOptions()
s.AddFlags(pflag.CommandLine)
s := genericoptions.NewServerRunOptions().WithEtcdOptions()
s.AddUniversalFlags(pflag.CommandLine)
s.AddEtcdStorageFlags(pflag.CommandLine)
flag.InitFlags()
util.InitLogs()

View File

@ -35,6 +35,7 @@ import (
"k8s.io/kubernetes/pkg/controller/framework/informers"
"k8s.io/kubernetes/pkg/genericapiserver"
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/util/wait"
@ -42,8 +43,9 @@ import (
// NewAPIServerCommand creates a *cobra.Command object with default parameters
func NewAPIServerCommand() *cobra.Command {
s := genericoptions.NewServerRunOptions()
s.AddFlags(pflag.CommandLine)
s := genericoptions.NewServerRunOptions().WithEtcdOptions()
s.AddUniversalFlags(pflag.CommandLine)
s.AddEtcdStorageFlags(pflag.CommandLine)
cmd := &cobra.Command{
Use: "federation-apiserver",
Long: `The Kubernetes federation API server validates and configures data
@ -59,6 +61,7 @@ cluster's shared state through which all other components interact.`,
// Run runs the specified APIServer. This should never exit.
func Run(s *genericoptions.ServerRunOptions) error {
genericvalidation.VerifyEtcdServersList(s)
genericapiserver.DefaultAndValidateRunOptions(s)
// TODO: register cluster federation resources here.

View File

@ -36,7 +36,7 @@ import (
)
func TestLongRunningRequestRegexp(t *testing.T) {
regexp := regexp.MustCompile(options.NewServerRunOptions().LongRunningRequestRE)
regexp := regexp.MustCompile(options.NewServerRunOptions().WithEtcdOptions().LongRunningRequestRE)
dontMatch := []string{
"/api/v1/watch-namespace/",
"/api/v1/namespace-proxy/",
@ -84,7 +84,7 @@ var groupVersions = []unversioned.GroupVersion{
}
func TestRun(t *testing.T) {
s := options.NewServerRunOptions()
s := options.NewServerRunOptions().WithEtcdOptions()
s.InsecurePort = insecurePort
_, ipNet, _ := net.ParseCIDR("10.10.10.0/24")
s.ServiceClusterIPRange = *ipNet

View File

@ -42,6 +42,7 @@ import (
"k8s.io/kubernetes/pkg/auth/handlers"
"k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/genericapiserver/options"
genericvalidation "k8s.io/kubernetes/pkg/genericapiserver/validation"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/registry/generic/registry"
ipallocator "k8s.io/kubernetes/pkg/registry/service/ipallocator"
@ -536,17 +537,6 @@ func (s *GenericAPIServer) installGroupsDiscoveryHandler() {
})
}
// TODO: Longer term we should read this from some config store, rather than a flag.
func verifyClusterIPFlags(options *options.ServerRunOptions) {
if options.ServiceClusterIPRange.IP == nil {
glog.Fatal("No --service-cluster-ip-range specified")
}
var ones, bits = options.ServiceClusterIPRange.Mask.Size()
if bits-ones > 20 {
glog.Fatal("Specified --service-cluster-ip-range is too large")
}
}
func NewConfig(options *options.ServerRunOptions) *Config {
return &Config{
APIGroupPrefix: options.APIGroupPrefix,
@ -570,46 +560,8 @@ func NewConfig(options *options.ServerRunOptions) *Config {
}
}
func verifyServiceNodePort(options *options.ServerRunOptions) {
if options.KubernetesServiceNodePort < 0 || options.KubernetesServiceNodePort > 65535 {
glog.Fatalf("--kubernetes-service-node-port %v must be between 0 and 65535, inclusive. If 0, the Kubernetes master service will be of type ClusterIP.", options.KubernetesServiceNodePort)
}
if options.KubernetesServiceNodePort > 0 && !options.ServiceNodePortRange.Contains(options.KubernetesServiceNodePort) {
glog.Fatalf("Kubernetes service port range %v doesn't contain %v", options.ServiceNodePortRange, (options.KubernetesServiceNodePort))
}
}
func verifyEtcdServersList(options *options.ServerRunOptions) {
if len(options.StorageConfig.ServerList) == 0 {
glog.Fatalf("--etcd-servers must be specified")
}
}
func verifySecureAndInsecurePort(options *options.ServerRunOptions) {
if options.SecurePort < 0 || options.SecurePort > 65535 {
glog.Fatalf("--secure-port %v must be between 0 and 65535, inclusive. 0 for turning off secure port.", options.SecurePort)
}
// TODO: Allow 0 to turn off insecure port.
if options.InsecurePort < 1 || options.InsecurePort > 65535 {
glog.Fatalf("--insecure-port %v must be between 1 and 65535, inclusive.", options.InsecurePort)
}
if options.SecurePort == options.InsecurePort {
glog.Fatalf("--secure-port and --insecure-port cannot use the same port.")
}
}
func ValidateRunOptions(options *options.ServerRunOptions) {
verifyClusterIPFlags(options)
verifyServiceNodePort(options)
verifyEtcdServersList(options)
verifySecureAndInsecurePort(options)
}
func DefaultAndValidateRunOptions(options *options.ServerRunOptions) {
ValidateRunOptions(options)
genericvalidation.ValidateRunOptions(options)
// If advertise-address is not specified, use bind-address. If bind-address
// is not usable (unset, 0.0.0.0, or loopback), we will use the host's default

View File

@ -0,0 +1,51 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package options
import (
"github.com/spf13/pflag"
)
const (
DefaultEtcdPathPrefix = "/registry"
)
// AddEtcdFlags adds flags related to etcd storage for a specific APIServer to the specified FlagSet
func (s *ServerRunOptions) AddEtcdStorageFlags(fs *pflag.FlagSet) {
fs.StringSliceVar(&s.EtcdServersOverrides, "etcd-servers-overrides", s.EtcdServersOverrides, ""+
"Per-resource etcd servers overrides, comma separated. The individual override "+
"format: group/resource#servers, where servers are http://ip:port, semicolon separated.")
fs.StringSliceVar(&s.StorageConfig.ServerList, "etcd-servers", s.StorageConfig.ServerList,
"List of etcd servers to connect with (http://ip:port), comma separated.")
fs.StringVar(&s.StorageConfig.Prefix, "etcd-prefix", s.StorageConfig.Prefix,
"The prefix for all resource paths in etcd.")
fs.StringVar(&s.StorageConfig.KeyFile, "etcd-keyfile", s.StorageConfig.KeyFile,
"SSL key file used to secure etcd communication.")
fs.StringVar(&s.StorageConfig.CertFile, "etcd-certfile", s.StorageConfig.CertFile,
"SSL certification file used to secure etcd communication.")
fs.StringVar(&s.StorageConfig.CAFile, "etcd-cafile", s.StorageConfig.CAFile,
"SSL Certificate Authority file used to secure etcd communication.")
fs.BoolVar(&s.StorageConfig.Quorum, "etcd-quorum-read", s.StorageConfig.Quorum,
"If true, enable quorum read.")
}

View File

@ -39,7 +39,6 @@ import (
)
const (
DefaultEtcdPathPrefix = "/registry"
DefaultDeserializationCacheSize = 50000
// TODO: This can be tightened up. It still matches objects named watch or proxy.
@ -119,10 +118,6 @@ func NewServerRunOptions() *ServerRunOptions {
CertDirectory: "/var/run/kubernetes",
DefaultStorageMediaType: "application/json",
DefaultStorageVersions: registered.AllPreferredGroupVersions(),
StorageConfig: storagebackend.Config{
Prefix: DefaultEtcdPathPrefix,
DeserializationCacheSize: DefaultDeserializationCacheSize,
},
DeleteCollectionWorkers: 1,
EnableLogsSupport: true,
EnableProfiling: true,
@ -141,6 +136,14 @@ func NewServerRunOptions() *ServerRunOptions {
}
}
func (o *ServerRunOptions) WithEtcdOptions() *ServerRunOptions {
o.StorageConfig = storagebackend.Config{
Prefix: DefaultEtcdPathPrefix,
DeserializationCacheSize: DefaultDeserializationCacheSize,
}
return o
}
// StorageGroupsToEncodingVersion returns a map from group name to group version,
// computed from the s.DeprecatedStorageVersion and s.StorageVersions flags.
func (s *ServerRunOptions) StorageGroupsToEncodingVersion() (map[string]unversioned.GroupVersion, error) {
@ -212,7 +215,7 @@ func (s *ServerRunOptions) NewSelfClient() (clientset.Interface, error) {
}
// AddFlags adds flags for a specific APIServer to the specified FlagSet
func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
// Note: the weird ""+ in below lines seems to be the only way to get gofmt to
// arrange these text blocks sensibly. Grrr.
@ -301,10 +304,6 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&s.EnableWatchCache, "watch-cache", s.EnableWatchCache,
"Enable watch caching in the apiserver")
fs.StringSliceVar(&s.EtcdServersOverrides, "etcd-servers-overrides", s.EtcdServersOverrides, ""+
"Per-resource etcd servers overrides, comma separated. The individual override "+
"format: group/resource#servers, where servers are http://ip:port, semicolon separated.")
fs.IntVar(&s.TargetRAMMB, "target-ram-mb", s.TargetRAMMB,
"Memory limit for apiserver in MB (used to configure sizes of caches, etc.)")
@ -405,24 +404,6 @@ func (s *ServerRunOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.StorageConfig.Type, "storage-backend", s.StorageConfig.Type,
"The storage backend for persistence. Options: 'etcd2' (default), 'etcd3'.")
fs.StringSliceVar(&s.StorageConfig.ServerList, "etcd-servers", s.StorageConfig.ServerList,
"List of etcd servers to connect with (http://ip:port), comma separated.")
fs.StringVar(&s.StorageConfig.Prefix, "etcd-prefix", s.StorageConfig.Prefix,
"The prefix for all resource paths in etcd.")
fs.StringVar(&s.StorageConfig.KeyFile, "etcd-keyfile", s.StorageConfig.KeyFile,
"SSL key file used to secure etcd communication.")
fs.StringVar(&s.StorageConfig.CertFile, "etcd-certfile", s.StorageConfig.CertFile,
"SSL certification file used to secure etcd communication.")
fs.StringVar(&s.StorageConfig.CAFile, "etcd-cafile", s.StorageConfig.CAFile,
"SSL Certificate Authority file used to secure etcd communication.")
fs.BoolVar(&s.StorageConfig.Quorum, "etcd-quorum-read", s.StorageConfig.Quorum,
"If true, enable quorum read.")
fs.IntVar(&s.StorageConfig.DeserializationCacheSize, "deserialization-cache-size", s.StorageConfig.DeserializationCacheSize,
"Number of deserialized json objects to cache in memory.")

View File

@ -0,0 +1,28 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/genericapiserver/options"
)
func VerifyEtcdServersList(options *options.ServerRunOptions) {
if len(options.StorageConfig.ServerList) == 0 {
glog.Fatalf("--etcd-servers must be specified")
}
}

View File

@ -0,0 +1,64 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/genericapiserver/options"
)
// TODO: Longer term we should read this from some config store, rather than a flag.
func verifyClusterIPFlags(options *options.ServerRunOptions) {
if options.ServiceClusterIPRange.IP == nil {
glog.Fatal("No --service-cluster-ip-range specified")
}
var ones, bits = options.ServiceClusterIPRange.Mask.Size()
if bits-ones > 20 {
glog.Fatal("Specified --service-cluster-ip-range is too large")
}
}
func verifyServiceNodePort(options *options.ServerRunOptions) {
if options.KubernetesServiceNodePort < 0 || options.KubernetesServiceNodePort > 65535 {
glog.Fatalf("--kubernetes-service-node-port %v must be between 0 and 65535, inclusive. If 0, the Kubernetes master service will be of type ClusterIP.", options.KubernetesServiceNodePort)
}
if options.KubernetesServiceNodePort > 0 && !options.ServiceNodePortRange.Contains(options.KubernetesServiceNodePort) {
glog.Fatalf("Kubernetes service port range %v doesn't contain %v", options.ServiceNodePortRange, (options.KubernetesServiceNodePort))
}
}
func verifySecureAndInsecurePort(options *options.ServerRunOptions) {
if options.SecurePort < 0 || options.SecurePort > 65535 {
glog.Fatalf("--secure-port %v must be between 0 and 65535, inclusive. 0 for turning off secure port.", options.SecurePort)
}
// TODO: Allow 0 to turn off insecure port.
if options.InsecurePort < 1 || options.InsecurePort > 65535 {
glog.Fatalf("--insecure-port %v must be between 1 and 65535, inclusive.", options.InsecurePort)
}
if options.SecurePort == options.InsecurePort {
glog.Fatalf("--secure-port and --insecure-port cannot use the same port.")
}
}
func ValidateRunOptions(options *options.ServerRunOptions) {
verifyClusterIPFlags(options)
verifyServiceNodePort(options)
verifySecureAndInsecurePort(options)
}