master.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. /*
  2. Copyright 2014 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package master
  14. import (
  15. "fmt"
  16. "net"
  17. "net/http"
  18. "reflect"
  19. "strconv"
  20. "time"
  21. admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
  22. appsv1 "k8s.io/api/apps/v1"
  23. appsv1beta1 "k8s.io/api/apps/v1beta1"
  24. appsv1beta2 "k8s.io/api/apps/v1beta2"
  25. auditregistrationv1alpha1 "k8s.io/api/auditregistration/v1alpha1"
  26. authenticationv1 "k8s.io/api/authentication/v1"
  27. authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
  28. authorizationapiv1 "k8s.io/api/authorization/v1"
  29. authorizationapiv1beta1 "k8s.io/api/authorization/v1beta1"
  30. autoscalingapiv1 "k8s.io/api/autoscaling/v1"
  31. autoscalingapiv2beta1 "k8s.io/api/autoscaling/v2beta1"
  32. autoscalingapiv2beta2 "k8s.io/api/autoscaling/v2beta2"
  33. batchapiv1 "k8s.io/api/batch/v1"
  34. batchapiv1beta1 "k8s.io/api/batch/v1beta1"
  35. batchapiv2alpha1 "k8s.io/api/batch/v2alpha1"
  36. certificatesapiv1beta1 "k8s.io/api/certificates/v1beta1"
  37. coordinationapiv1 "k8s.io/api/coordination/v1"
  38. coordinationapiv1beta1 "k8s.io/api/coordination/v1beta1"
  39. apiv1 "k8s.io/api/core/v1"
  40. eventsv1beta1 "k8s.io/api/events/v1beta1"
  41. extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1"
  42. networkingapiv1 "k8s.io/api/networking/v1"
  43. networkingapiv1beta1 "k8s.io/api/networking/v1beta1"
  44. nodev1alpha1 "k8s.io/api/node/v1alpha1"
  45. nodev1beta1 "k8s.io/api/node/v1beta1"
  46. policyapiv1beta1 "k8s.io/api/policy/v1beta1"
  47. rbacv1 "k8s.io/api/rbac/v1"
  48. rbacv1alpha1 "k8s.io/api/rbac/v1alpha1"
  49. rbacv1beta1 "k8s.io/api/rbac/v1beta1"
  50. schedulingapiv1 "k8s.io/api/scheduling/v1"
  51. schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1"
  52. schedulingapiv1beta1 "k8s.io/api/scheduling/v1beta1"
  53. settingsv1alpha1 "k8s.io/api/settings/v1alpha1"
  54. storageapiv1 "k8s.io/api/storage/v1"
  55. storageapiv1alpha1 "k8s.io/api/storage/v1alpha1"
  56. storageapiv1beta1 "k8s.io/api/storage/v1beta1"
  57. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  58. utilnet "k8s.io/apimachinery/pkg/util/net"
  59. "k8s.io/apiserver/pkg/endpoints/discovery"
  60. "k8s.io/apiserver/pkg/registry/generic"
  61. genericapiserver "k8s.io/apiserver/pkg/server"
  62. "k8s.io/apiserver/pkg/server/healthz"
  63. serverstorage "k8s.io/apiserver/pkg/server/storage"
  64. storagefactory "k8s.io/apiserver/pkg/storage/storagebackend/factory"
  65. "k8s.io/client-go/informers"
  66. corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
  67. api "k8s.io/kubernetes/pkg/apis/core"
  68. kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
  69. kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
  70. "k8s.io/kubernetes/pkg/master/reconcilers"
  71. "k8s.io/kubernetes/pkg/master/tunneler"
  72. "k8s.io/kubernetes/pkg/routes"
  73. "k8s.io/kubernetes/pkg/serviceaccount"
  74. nodeutil "k8s.io/kubernetes/pkg/util/node"
  75. "github.com/prometheus/client_golang/prometheus"
  76. "k8s.io/klog"
  77. // RESTStorage installers
  78. admissionregistrationrest "k8s.io/kubernetes/pkg/registry/admissionregistration/rest"
  79. appsrest "k8s.io/kubernetes/pkg/registry/apps/rest"
  80. auditregistrationrest "k8s.io/kubernetes/pkg/registry/auditregistration/rest"
  81. authenticationrest "k8s.io/kubernetes/pkg/registry/authentication/rest"
  82. authorizationrest "k8s.io/kubernetes/pkg/registry/authorization/rest"
  83. autoscalingrest "k8s.io/kubernetes/pkg/registry/autoscaling/rest"
  84. batchrest "k8s.io/kubernetes/pkg/registry/batch/rest"
  85. certificatesrest "k8s.io/kubernetes/pkg/registry/certificates/rest"
  86. coordinationrest "k8s.io/kubernetes/pkg/registry/coordination/rest"
  87. corerest "k8s.io/kubernetes/pkg/registry/core/rest"
  88. eventsrest "k8s.io/kubernetes/pkg/registry/events/rest"
  89. extensionsrest "k8s.io/kubernetes/pkg/registry/extensions/rest"
  90. networkingrest "k8s.io/kubernetes/pkg/registry/networking/rest"
  91. noderest "k8s.io/kubernetes/pkg/registry/node/rest"
  92. policyrest "k8s.io/kubernetes/pkg/registry/policy/rest"
  93. rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
  94. schedulingrest "k8s.io/kubernetes/pkg/registry/scheduling/rest"
  95. settingsrest "k8s.io/kubernetes/pkg/registry/settings/rest"
  96. storagerest "k8s.io/kubernetes/pkg/registry/storage/rest"
  97. )
  98. const (
  99. // DefaultEndpointReconcilerInterval is the default amount of time for how often the endpoints for
  100. // the kubernetes Service are reconciled.
  101. DefaultEndpointReconcilerInterval = 10 * time.Second
  102. // DefaultEndpointReconcilerTTL is the default TTL timeout for the storage layer
  103. DefaultEndpointReconcilerTTL = 15 * time.Second
  104. )
  105. type ExtraConfig struct {
  106. ClientCARegistrationHook ClientCARegistrationHook
  107. APIResourceConfigSource serverstorage.APIResourceConfigSource
  108. StorageFactory serverstorage.StorageFactory
  109. EndpointReconcilerConfig EndpointReconcilerConfig
  110. EventTTL time.Duration
  111. KubeletClientConfig kubeletclient.KubeletClientConfig
  112. // Used to start and monitor tunneling
  113. Tunneler tunneler.Tunneler
  114. EnableLogsSupport bool
  115. ProxyTransport http.RoundTripper
  116. // Values to build the IP addresses used by discovery
  117. // The range of IPs to be assigned to services with type=ClusterIP or greater
  118. ServiceIPRange net.IPNet
  119. // The IP address for the GenericAPIServer service (must be inside ServiceIPRange)
  120. APIServerServiceIP net.IP
  121. // Port for the apiserver service.
  122. APIServerServicePort int
  123. // TODO, we can probably group service related items into a substruct to make it easier to configure
  124. // the API server items and `Extra*` fields likely fit nicely together.
  125. // The range of ports to be assigned to services with type=NodePort or greater
  126. ServiceNodePortRange utilnet.PortRange
  127. // Additional ports to be exposed on the GenericAPIServer service
  128. // extraServicePorts is injectable in the event that more ports
  129. // (other than the default 443/tcp) are exposed on the GenericAPIServer
  130. // and those ports need to be load balanced by the GenericAPIServer
  131. // service because this pkg is linked by out-of-tree projects
  132. // like openshift which want to use the GenericAPIServer but also do
  133. // more stuff.
  134. ExtraServicePorts []apiv1.ServicePort
  135. // Additional ports to be exposed on the GenericAPIServer endpoints
  136. // Port names should align with ports defined in ExtraServicePorts
  137. ExtraEndpointPorts []apiv1.EndpointPort
  138. // If non-zero, the "kubernetes" services uses this port as NodePort.
  139. KubernetesServiceNodePort int
  140. // Number of masters running; all masters must be started with the
  141. // same value for this field. (Numbers > 1 currently untested.)
  142. MasterCount int
  143. // MasterEndpointReconcileTTL sets the time to live in seconds of an
  144. // endpoint record recorded by each master. The endpoints are checked at an
  145. // interval that is 2/3 of this value and this value defaults to 15s if
  146. // unset. In very large clusters, this value may be increased to reduce the
  147. // possibility that the master endpoint record expires (due to other load
  148. // on the etcd server) and causes masters to drop in and out of the
  149. // kubernetes service record. It is not recommended to set this value below
  150. // 15s.
  151. MasterEndpointReconcileTTL time.Duration
  152. // Selects which reconciler to use
  153. EndpointReconcilerType reconcilers.Type
  154. ServiceAccountIssuer serviceaccount.TokenGenerator
  155. ServiceAccountMaxExpiration time.Duration
  156. VersionedInformers informers.SharedInformerFactory
  157. }
  158. type Config struct {
  159. GenericConfig *genericapiserver.Config
  160. ExtraConfig ExtraConfig
  161. }
  162. type completedConfig struct {
  163. GenericConfig genericapiserver.CompletedConfig
  164. ExtraConfig *ExtraConfig
  165. }
  166. type CompletedConfig struct {
  167. // Embed a private pointer that cannot be instantiated outside of this package.
  168. *completedConfig
  169. }
  170. // EndpointReconcilerConfig holds the endpoint reconciler and endpoint reconciliation interval to be
  171. // used by the master.
  172. type EndpointReconcilerConfig struct {
  173. Reconciler reconcilers.EndpointReconciler
  174. Interval time.Duration
  175. }
  176. // Master contains state for a Kubernetes cluster master/api server.
  177. type Master struct {
  178. GenericAPIServer *genericapiserver.GenericAPIServer
  179. ClientCARegistrationHook ClientCARegistrationHook
  180. }
  181. func (c *Config) createMasterCountReconciler() reconcilers.EndpointReconciler {
  182. endpointClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
  183. return reconcilers.NewMasterCountEndpointReconciler(c.ExtraConfig.MasterCount, endpointClient)
  184. }
  185. func (c *Config) createNoneReconciler() reconcilers.EndpointReconciler {
  186. return reconcilers.NewNoneEndpointReconciler()
  187. }
  188. func (c *Config) createLeaseReconciler() reconcilers.EndpointReconciler {
  189. endpointClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
  190. ttl := c.ExtraConfig.MasterEndpointReconcileTTL
  191. config, err := c.ExtraConfig.StorageFactory.NewConfig(api.Resource("apiServerIPInfo"))
  192. if err != nil {
  193. klog.Fatalf("Error determining service IP ranges: %v", err)
  194. }
  195. leaseStorage, _, err := storagefactory.Create(*config)
  196. if err != nil {
  197. klog.Fatalf("Error creating storage factory: %v", err)
  198. }
  199. masterLeases := reconcilers.NewLeases(leaseStorage, "/masterleases/", ttl)
  200. return reconcilers.NewLeaseEndpointReconciler(endpointClient, masterLeases)
  201. }
  202. func (c *Config) createEndpointReconciler() reconcilers.EndpointReconciler {
  203. klog.Infof("Using reconciler: %v", c.ExtraConfig.EndpointReconcilerType)
  204. switch c.ExtraConfig.EndpointReconcilerType {
  205. // there are numerous test dependencies that depend on a default controller
  206. case "", reconcilers.MasterCountReconcilerType:
  207. return c.createMasterCountReconciler()
  208. case reconcilers.LeaseEndpointReconcilerType:
  209. return c.createLeaseReconciler()
  210. case reconcilers.NoneEndpointReconcilerType:
  211. return c.createNoneReconciler()
  212. default:
  213. klog.Fatalf("Reconciler not implemented: %v", c.ExtraConfig.EndpointReconcilerType)
  214. }
  215. return nil
  216. }
  217. // Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
  218. func (cfg *Config) Complete() CompletedConfig {
  219. c := completedConfig{
  220. cfg.GenericConfig.Complete(cfg.ExtraConfig.VersionedInformers),
  221. &cfg.ExtraConfig,
  222. }
  223. serviceIPRange, apiServerServiceIP, err := DefaultServiceIPRange(c.ExtraConfig.ServiceIPRange)
  224. if err != nil {
  225. klog.Fatalf("Error determining service IP ranges: %v", err)
  226. }
  227. if c.ExtraConfig.ServiceIPRange.IP == nil {
  228. c.ExtraConfig.ServiceIPRange = serviceIPRange
  229. }
  230. if c.ExtraConfig.APIServerServiceIP == nil {
  231. c.ExtraConfig.APIServerServiceIP = apiServerServiceIP
  232. }
  233. discoveryAddresses := discovery.DefaultAddresses{DefaultAddress: c.GenericConfig.ExternalAddress}
  234. discoveryAddresses.CIDRRules = append(discoveryAddresses.CIDRRules,
  235. discovery.CIDRRule{IPRange: c.ExtraConfig.ServiceIPRange, Address: net.JoinHostPort(c.ExtraConfig.APIServerServiceIP.String(), strconv.Itoa(c.ExtraConfig.APIServerServicePort))})
  236. c.GenericConfig.DiscoveryAddresses = discoveryAddresses
  237. if c.ExtraConfig.ServiceNodePortRange.Size == 0 {
  238. // TODO: Currently no way to specify an empty range (do we need to allow this?)
  239. // We should probably allow this for clouds that don't require NodePort to do load-balancing (GCE)
  240. // but then that breaks the strict nestedness of ServiceType.
  241. // Review post-v1
  242. c.ExtraConfig.ServiceNodePortRange = kubeoptions.DefaultServiceNodePortRange
  243. klog.Infof("Node port range unspecified. Defaulting to %v.", c.ExtraConfig.ServiceNodePortRange)
  244. }
  245. if c.ExtraConfig.EndpointReconcilerConfig.Interval == 0 {
  246. c.ExtraConfig.EndpointReconcilerConfig.Interval = DefaultEndpointReconcilerInterval
  247. }
  248. if c.ExtraConfig.MasterEndpointReconcileTTL == 0 {
  249. c.ExtraConfig.MasterEndpointReconcileTTL = DefaultEndpointReconcilerTTL
  250. }
  251. if c.ExtraConfig.EndpointReconcilerConfig.Reconciler == nil {
  252. c.ExtraConfig.EndpointReconcilerConfig.Reconciler = cfg.createEndpointReconciler()
  253. }
  254. return CompletedConfig{&c}
  255. }
  256. // New returns a new instance of Master from the given config.
  257. // Certain config fields will be set to a default value if unset.
  258. // Certain config fields must be specified, including:
  259. // KubeletClientConfig
  260. func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) (*Master, error) {
  261. if reflect.DeepEqual(c.ExtraConfig.KubeletClientConfig, kubeletclient.KubeletClientConfig{}) {
  262. return nil, fmt.Errorf("Master.New() called with empty config.KubeletClientConfig")
  263. }
  264. s, err := c.GenericConfig.New("kube-apiserver", delegationTarget)
  265. if err != nil {
  266. return nil, err
  267. }
  268. if c.ExtraConfig.EnableLogsSupport {
  269. routes.Logs{}.Install(s.Handler.GoRestfulContainer)
  270. }
  271. m := &Master{
  272. GenericAPIServer: s,
  273. }
  274. // install legacy rest storage
  275. if c.ExtraConfig.APIResourceConfigSource.VersionEnabled(apiv1.SchemeGroupVersion) {
  276. legacyRESTStorageProvider := corerest.LegacyRESTStorageProvider{
  277. StorageFactory: c.ExtraConfig.StorageFactory,
  278. ProxyTransport: c.ExtraConfig.ProxyTransport,
  279. KubeletClientConfig: c.ExtraConfig.KubeletClientConfig,
  280. EventTTL: c.ExtraConfig.EventTTL,
  281. ServiceIPRange: c.ExtraConfig.ServiceIPRange,
  282. ServiceNodePortRange: c.ExtraConfig.ServiceNodePortRange,
  283. LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
  284. ServiceAccountIssuer: c.ExtraConfig.ServiceAccountIssuer,
  285. ServiceAccountMaxExpiration: c.ExtraConfig.ServiceAccountMaxExpiration,
  286. APIAudiences: c.GenericConfig.Authentication.APIAudiences,
  287. }
  288. m.InstallLegacyAPI(&c, c.GenericConfig.RESTOptionsGetter, legacyRESTStorageProvider)
  289. }
  290. // The order here is preserved in discovery.
  291. // If resources with identical names exist in more than one of these groups (e.g. "deployments.apps"" and "deployments.extensions"),
  292. // the order of this list determines which group an unqualified resource name (e.g. "deployments") should prefer.
  293. // This priority order is used for local discovery, but it ends up aggregated in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go
  294. // with specific priorities.
  295. // TODO: describe the priority all the way down in the RESTStorageProviders and plumb it back through the various discovery
  296. // handlers that we have.
  297. restStorageProviders := []RESTStorageProvider{
  298. auditregistrationrest.RESTStorageProvider{},
  299. authenticationrest.RESTStorageProvider{Authenticator: c.GenericConfig.Authentication.Authenticator, APIAudiences: c.GenericConfig.Authentication.APIAudiences},
  300. authorizationrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer, RuleResolver: c.GenericConfig.RuleResolver},
  301. autoscalingrest.RESTStorageProvider{},
  302. batchrest.RESTStorageProvider{},
  303. certificatesrest.RESTStorageProvider{},
  304. coordinationrest.RESTStorageProvider{},
  305. extensionsrest.RESTStorageProvider{},
  306. networkingrest.RESTStorageProvider{},
  307. noderest.RESTStorageProvider{},
  308. policyrest.RESTStorageProvider{},
  309. rbacrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer},
  310. schedulingrest.RESTStorageProvider{},
  311. settingsrest.RESTStorageProvider{},
  312. storagerest.RESTStorageProvider{},
  313. // keep apps after extensions so legacy clients resolve the extensions versions of shared resource names.
  314. // See https://github.com/kubernetes/kubernetes/issues/42392
  315. appsrest.RESTStorageProvider{},
  316. admissionregistrationrest.RESTStorageProvider{},
  317. eventsrest.RESTStorageProvider{TTL: c.ExtraConfig.EventTTL},
  318. }
  319. m.InstallAPIs(c.ExtraConfig.APIResourceConfigSource, c.GenericConfig.RESTOptionsGetter, restStorageProviders...)
  320. if c.ExtraConfig.Tunneler != nil {
  321. m.installTunneler(c.ExtraConfig.Tunneler, corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig).Nodes())
  322. }
  323. m.GenericAPIServer.AddPostStartHookOrDie("ca-registration", c.ExtraConfig.ClientCARegistrationHook.PostStartHook)
  324. return m, nil
  325. }
  326. func (m *Master) InstallLegacyAPI(c *completedConfig, restOptionsGetter generic.RESTOptionsGetter, legacyRESTStorageProvider corerest.LegacyRESTStorageProvider) {
  327. legacyRESTStorage, apiGroupInfo, err := legacyRESTStorageProvider.NewLegacyRESTStorage(restOptionsGetter)
  328. if err != nil {
  329. klog.Fatalf("Error building core storage: %v", err)
  330. }
  331. controllerName := "bootstrap-controller"
  332. coreClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
  333. bootstrapController := c.NewBootstrapController(legacyRESTStorage, coreClient, coreClient, coreClient, coreClient.RESTClient())
  334. m.GenericAPIServer.AddPostStartHookOrDie(controllerName, bootstrapController.PostStartHook)
  335. m.GenericAPIServer.AddPreShutdownHookOrDie(controllerName, bootstrapController.PreShutdownHook)
  336. if err := m.GenericAPIServer.InstallLegacyAPIGroup(genericapiserver.DefaultLegacyAPIPrefix, &apiGroupInfo); err != nil {
  337. klog.Fatalf("Error in registering group versions: %v", err)
  338. }
  339. }
  340. func (m *Master) installTunneler(nodeTunneler tunneler.Tunneler, nodeClient corev1client.NodeInterface) {
  341. nodeTunneler.Run(nodeAddressProvider{nodeClient}.externalAddresses)
  342. m.GenericAPIServer.AddHealthzChecks(healthz.NamedCheck("SSH Tunnel Check", tunneler.TunnelSyncHealthChecker(nodeTunneler)))
  343. prometheus.NewGaugeFunc(prometheus.GaugeOpts{
  344. Name: "apiserver_proxy_tunnel_sync_duration_seconds",
  345. Help: "The time since the last successful synchronization of the SSH tunnels for proxy requests.",
  346. }, func() float64 { return float64(nodeTunneler.SecondsSinceSync()) })
  347. prometheus.NewGaugeFunc(prometheus.GaugeOpts{
  348. Name: "apiserver_proxy_tunnel_sync_latency_secs",
  349. Help: "(Deprecated) The time since the last successful synchronization of the SSH tunnels for proxy requests.",
  350. }, func() float64 { return float64(nodeTunneler.SecondsSinceSync()) })
  351. }
  352. // RESTStorageProvider is a factory type for REST storage.
  353. type RESTStorageProvider interface {
  354. GroupName() string
  355. NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool)
  356. }
  357. // InstallAPIs will install the APIs for the restStorageProviders if they are enabled.
  358. func (m *Master) InstallAPIs(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, restStorageProviders ...RESTStorageProvider) {
  359. apiGroupsInfo := []*genericapiserver.APIGroupInfo{}
  360. for _, restStorageBuilder := range restStorageProviders {
  361. groupName := restStorageBuilder.GroupName()
  362. if !apiResourceConfigSource.AnyVersionForGroupEnabled(groupName) {
  363. klog.V(1).Infof("Skipping disabled API group %q.", groupName)
  364. continue
  365. }
  366. apiGroupInfo, enabled := restStorageBuilder.NewRESTStorage(apiResourceConfigSource, restOptionsGetter)
  367. if !enabled {
  368. klog.Warningf("Problem initializing API group %q, skipping.", groupName)
  369. continue
  370. }
  371. klog.V(1).Infof("Enabling API group %q.", groupName)
  372. if postHookProvider, ok := restStorageBuilder.(genericapiserver.PostStartHookProvider); ok {
  373. name, hook, err := postHookProvider.PostStartHook()
  374. if err != nil {
  375. klog.Fatalf("Error building PostStartHook: %v", err)
  376. }
  377. m.GenericAPIServer.AddPostStartHookOrDie(name, hook)
  378. }
  379. apiGroupsInfo = append(apiGroupsInfo, &apiGroupInfo)
  380. }
  381. if err := m.GenericAPIServer.InstallAPIGroups(apiGroupsInfo...); err != nil {
  382. klog.Fatalf("Error in registering group versions: %v", err)
  383. }
  384. }
  385. type nodeAddressProvider struct {
  386. nodeClient corev1client.NodeInterface
  387. }
  388. func (n nodeAddressProvider) externalAddresses() ([]string, error) {
  389. preferredAddressTypes := []apiv1.NodeAddressType{
  390. apiv1.NodeExternalIP,
  391. }
  392. nodes, err := n.nodeClient.List(metav1.ListOptions{})
  393. if err != nil {
  394. return nil, err
  395. }
  396. var matchErr error
  397. addrs := []string{}
  398. for ix := range nodes.Items {
  399. node := &nodes.Items[ix]
  400. addr, err := nodeutil.GetPreferredNodeAddress(node, preferredAddressTypes)
  401. if err != nil {
  402. if _, ok := err.(*nodeutil.NoMatchError); ok {
  403. matchErr = err
  404. continue
  405. }
  406. return nil, err
  407. }
  408. addrs = append(addrs, addr)
  409. }
  410. if len(addrs) == 0 && matchErr != nil {
  411. // We only return an error if we have items.
  412. // Currently we return empty list/no error if Items is empty.
  413. // We do this for backward compatibility reasons.
  414. return nil, matchErr
  415. }
  416. return addrs, nil
  417. }
  418. func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig {
  419. ret := serverstorage.NewResourceConfig()
  420. // NOTE: GroupVersions listed here will be enabled by default. Don't put alpha versions in the list.
  421. ret.EnableVersions(
  422. admissionregistrationv1beta1.SchemeGroupVersion,
  423. apiv1.SchemeGroupVersion,
  424. appsv1.SchemeGroupVersion,
  425. authenticationv1.SchemeGroupVersion,
  426. authenticationv1beta1.SchemeGroupVersion,
  427. authorizationapiv1.SchemeGroupVersion,
  428. authorizationapiv1beta1.SchemeGroupVersion,
  429. autoscalingapiv1.SchemeGroupVersion,
  430. autoscalingapiv2beta1.SchemeGroupVersion,
  431. autoscalingapiv2beta2.SchemeGroupVersion,
  432. batchapiv1.SchemeGroupVersion,
  433. batchapiv1beta1.SchemeGroupVersion,
  434. certificatesapiv1beta1.SchemeGroupVersion,
  435. coordinationapiv1.SchemeGroupVersion,
  436. coordinationapiv1beta1.SchemeGroupVersion,
  437. eventsv1beta1.SchemeGroupVersion,
  438. extensionsapiv1beta1.SchemeGroupVersion,
  439. networkingapiv1.SchemeGroupVersion,
  440. networkingapiv1beta1.SchemeGroupVersion,
  441. nodev1beta1.SchemeGroupVersion,
  442. policyapiv1beta1.SchemeGroupVersion,
  443. rbacv1.SchemeGroupVersion,
  444. rbacv1beta1.SchemeGroupVersion,
  445. storageapiv1.SchemeGroupVersion,
  446. storageapiv1beta1.SchemeGroupVersion,
  447. schedulingapiv1beta1.SchemeGroupVersion,
  448. schedulingapiv1.SchemeGroupVersion,
  449. )
  450. // enable non-deprecated beta resources in extensions/v1beta1 explicitly so we have a full list of what's possible to serve
  451. ret.EnableResources(
  452. extensionsapiv1beta1.SchemeGroupVersion.WithResource("ingresses"),
  453. )
  454. // enable deprecated beta resources in extensions/v1beta1 explicitly so we have a full list of what's possible to serve
  455. ret.EnableResources(
  456. extensionsapiv1beta1.SchemeGroupVersion.WithResource("daemonsets"),
  457. extensionsapiv1beta1.SchemeGroupVersion.WithResource("deployments"),
  458. extensionsapiv1beta1.SchemeGroupVersion.WithResource("networkpolicies"),
  459. extensionsapiv1beta1.SchemeGroupVersion.WithResource("podsecuritypolicies"),
  460. extensionsapiv1beta1.SchemeGroupVersion.WithResource("replicasets"),
  461. extensionsapiv1beta1.SchemeGroupVersion.WithResource("replicationcontrollers"),
  462. )
  463. // enable deprecated beta versions explicitly so we have a full list of what's possible to serve
  464. ret.EnableVersions(
  465. appsv1beta1.SchemeGroupVersion,
  466. appsv1beta2.SchemeGroupVersion,
  467. )
  468. // disable alpha versions explicitly so we have a full list of what's possible to serve
  469. ret.DisableVersions(
  470. auditregistrationv1alpha1.SchemeGroupVersion,
  471. batchapiv2alpha1.SchemeGroupVersion,
  472. nodev1alpha1.SchemeGroupVersion,
  473. rbacv1alpha1.SchemeGroupVersion,
  474. schedulingv1alpha1.SchemeGroupVersion,
  475. settingsv1alpha1.SchemeGroupVersion,
  476. storageapiv1alpha1.SchemeGroupVersion,
  477. )
  478. return ret
  479. }