master.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  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. "context"
  16. "fmt"
  17. "net"
  18. "net/http"
  19. "reflect"
  20. "strconv"
  21. "time"
  22. admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
  23. admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
  24. appsv1 "k8s.io/api/apps/v1"
  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. discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
  41. eventsv1beta1 "k8s.io/api/events/v1beta1"
  42. extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1"
  43. flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1"
  44. networkingapiv1 "k8s.io/api/networking/v1"
  45. networkingapiv1beta1 "k8s.io/api/networking/v1beta1"
  46. nodev1alpha1 "k8s.io/api/node/v1alpha1"
  47. nodev1beta1 "k8s.io/api/node/v1beta1"
  48. policyapiv1beta1 "k8s.io/api/policy/v1beta1"
  49. rbacv1 "k8s.io/api/rbac/v1"
  50. rbacv1alpha1 "k8s.io/api/rbac/v1alpha1"
  51. rbacv1beta1 "k8s.io/api/rbac/v1beta1"
  52. schedulingapiv1 "k8s.io/api/scheduling/v1"
  53. schedulingv1alpha1 "k8s.io/api/scheduling/v1alpha1"
  54. schedulingapiv1beta1 "k8s.io/api/scheduling/v1beta1"
  55. settingsv1alpha1 "k8s.io/api/settings/v1alpha1"
  56. storageapiv1 "k8s.io/api/storage/v1"
  57. storageapiv1alpha1 "k8s.io/api/storage/v1alpha1"
  58. storageapiv1beta1 "k8s.io/api/storage/v1beta1"
  59. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  60. utilnet "k8s.io/apimachinery/pkg/util/net"
  61. "k8s.io/apimachinery/pkg/util/runtime"
  62. "k8s.io/apiserver/pkg/endpoints/discovery"
  63. "k8s.io/apiserver/pkg/registry/generic"
  64. genericapiserver "k8s.io/apiserver/pkg/server"
  65. "k8s.io/apiserver/pkg/server/dynamiccertificates"
  66. "k8s.io/apiserver/pkg/server/healthz"
  67. serverstorage "k8s.io/apiserver/pkg/server/storage"
  68. storagefactory "k8s.io/apiserver/pkg/storage/storagebackend/factory"
  69. utilfeature "k8s.io/apiserver/pkg/util/feature"
  70. "k8s.io/client-go/informers"
  71. "k8s.io/client-go/kubernetes"
  72. corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
  73. discoveryclient "k8s.io/client-go/kubernetes/typed/discovery/v1beta1"
  74. api "k8s.io/kubernetes/pkg/apis/core"
  75. "k8s.io/kubernetes/pkg/features"
  76. kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
  77. kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
  78. "k8s.io/kubernetes/pkg/master/controller/clusterauthenticationtrust"
  79. "k8s.io/kubernetes/pkg/master/reconcilers"
  80. "k8s.io/kubernetes/pkg/master/tunneler"
  81. "k8s.io/kubernetes/pkg/routes"
  82. "k8s.io/kubernetes/pkg/serviceaccount"
  83. nodeutil "k8s.io/kubernetes/pkg/util/node"
  84. "k8s.io/klog"
  85. // RESTStorage installers
  86. admissionregistrationrest "k8s.io/kubernetes/pkg/registry/admissionregistration/rest"
  87. appsrest "k8s.io/kubernetes/pkg/registry/apps/rest"
  88. auditregistrationrest "k8s.io/kubernetes/pkg/registry/auditregistration/rest"
  89. authenticationrest "k8s.io/kubernetes/pkg/registry/authentication/rest"
  90. authorizationrest "k8s.io/kubernetes/pkg/registry/authorization/rest"
  91. autoscalingrest "k8s.io/kubernetes/pkg/registry/autoscaling/rest"
  92. batchrest "k8s.io/kubernetes/pkg/registry/batch/rest"
  93. certificatesrest "k8s.io/kubernetes/pkg/registry/certificates/rest"
  94. coordinationrest "k8s.io/kubernetes/pkg/registry/coordination/rest"
  95. corerest "k8s.io/kubernetes/pkg/registry/core/rest"
  96. discoveryrest "k8s.io/kubernetes/pkg/registry/discovery/rest"
  97. eventsrest "k8s.io/kubernetes/pkg/registry/events/rest"
  98. extensionsrest "k8s.io/kubernetes/pkg/registry/extensions/rest"
  99. flowcontrolrest "k8s.io/kubernetes/pkg/registry/flowcontrol/rest"
  100. networkingrest "k8s.io/kubernetes/pkg/registry/networking/rest"
  101. noderest "k8s.io/kubernetes/pkg/registry/node/rest"
  102. policyrest "k8s.io/kubernetes/pkg/registry/policy/rest"
  103. rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
  104. schedulingrest "k8s.io/kubernetes/pkg/registry/scheduling/rest"
  105. settingsrest "k8s.io/kubernetes/pkg/registry/settings/rest"
  106. storagerest "k8s.io/kubernetes/pkg/registry/storage/rest"
  107. )
  108. const (
  109. // DefaultEndpointReconcilerInterval is the default amount of time for how often the endpoints for
  110. // the kubernetes Service are reconciled.
  111. DefaultEndpointReconcilerInterval = 10 * time.Second
  112. // DefaultEndpointReconcilerTTL is the default TTL timeout for the storage layer
  113. DefaultEndpointReconcilerTTL = 15 * time.Second
  114. )
  115. // ExtraConfig defines extra configuration for the master
  116. type ExtraConfig struct {
  117. ClusterAuthenticationInfo clusterauthenticationtrust.ClusterAuthenticationInfo
  118. APIResourceConfigSource serverstorage.APIResourceConfigSource
  119. StorageFactory serverstorage.StorageFactory
  120. EndpointReconcilerConfig EndpointReconcilerConfig
  121. EventTTL time.Duration
  122. KubeletClientConfig kubeletclient.KubeletClientConfig
  123. // Used to start and monitor tunneling
  124. Tunneler tunneler.Tunneler
  125. EnableLogsSupport bool
  126. ProxyTransport http.RoundTripper
  127. // Values to build the IP addresses used by discovery
  128. // The range of IPs to be assigned to services with type=ClusterIP or greater
  129. ServiceIPRange net.IPNet
  130. // The IP address for the GenericAPIServer service (must be inside ServiceIPRange)
  131. APIServerServiceIP net.IP
  132. // dual stack services, the range represents an alternative IP range for service IP
  133. // must be of different family than primary (ServiceIPRange)
  134. SecondaryServiceIPRange net.IPNet
  135. // the secondary IP address the GenericAPIServer service (must be inside SecondaryServiceIPRange)
  136. SecondaryAPIServerServiceIP net.IP
  137. // Port for the apiserver service.
  138. APIServerServicePort int
  139. // TODO, we can probably group service related items into a substruct to make it easier to configure
  140. // the API server items and `Extra*` fields likely fit nicely together.
  141. // The range of ports to be assigned to services with type=NodePort or greater
  142. ServiceNodePortRange utilnet.PortRange
  143. // Additional ports to be exposed on the GenericAPIServer service
  144. // extraServicePorts is injectable in the event that more ports
  145. // (other than the default 443/tcp) are exposed on the GenericAPIServer
  146. // and those ports need to be load balanced by the GenericAPIServer
  147. // service because this pkg is linked by out-of-tree projects
  148. // like openshift which want to use the GenericAPIServer but also do
  149. // more stuff.
  150. ExtraServicePorts []apiv1.ServicePort
  151. // Additional ports to be exposed on the GenericAPIServer endpoints
  152. // Port names should align with ports defined in ExtraServicePorts
  153. ExtraEndpointPorts []apiv1.EndpointPort
  154. // If non-zero, the "kubernetes" services uses this port as NodePort.
  155. KubernetesServiceNodePort int
  156. // Number of masters running; all masters must be started with the
  157. // same value for this field. (Numbers > 1 currently untested.)
  158. MasterCount int
  159. // MasterEndpointReconcileTTL sets the time to live in seconds of an
  160. // endpoint record recorded by each master. The endpoints are checked at an
  161. // interval that is 2/3 of this value and this value defaults to 15s if
  162. // unset. In very large clusters, this value may be increased to reduce the
  163. // possibility that the master endpoint record expires (due to other load
  164. // on the etcd server) and causes masters to drop in and out of the
  165. // kubernetes service record. It is not recommended to set this value below
  166. // 15s.
  167. MasterEndpointReconcileTTL time.Duration
  168. // Selects which reconciler to use
  169. EndpointReconcilerType reconcilers.Type
  170. ServiceAccountIssuer serviceaccount.TokenGenerator
  171. ServiceAccountMaxExpiration time.Duration
  172. // ServiceAccountIssuerDiscovery
  173. ServiceAccountIssuerURL string
  174. ServiceAccountJWKSURI string
  175. ServiceAccountPublicKeys []interface{}
  176. VersionedInformers informers.SharedInformerFactory
  177. }
  178. // Config defines configuration for the master
  179. type Config struct {
  180. GenericConfig *genericapiserver.Config
  181. ExtraConfig ExtraConfig
  182. }
  183. type completedConfig struct {
  184. GenericConfig genericapiserver.CompletedConfig
  185. ExtraConfig *ExtraConfig
  186. }
  187. // CompletedConfig embeds a private pointer that cannot be instantiated outside of this package
  188. type CompletedConfig struct {
  189. *completedConfig
  190. }
  191. // EndpointReconcilerConfig holds the endpoint reconciler and endpoint reconciliation interval to be
  192. // used by the master.
  193. type EndpointReconcilerConfig struct {
  194. Reconciler reconcilers.EndpointReconciler
  195. Interval time.Duration
  196. }
  197. // Master contains state for a Kubernetes cluster master/api server.
  198. type Master struct {
  199. GenericAPIServer *genericapiserver.GenericAPIServer
  200. ClusterAuthenticationInfo clusterauthenticationtrust.ClusterAuthenticationInfo
  201. }
  202. func (c *Config) createMasterCountReconciler() reconcilers.EndpointReconciler {
  203. endpointClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
  204. var endpointSliceClient discoveryclient.EndpointSlicesGetter
  205. if utilfeature.DefaultFeatureGate.Enabled(features.EndpointSlice) {
  206. endpointSliceClient = discoveryclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
  207. }
  208. endpointsAdapter := reconcilers.NewEndpointsAdapter(endpointClient, endpointSliceClient)
  209. return reconcilers.NewMasterCountEndpointReconciler(c.ExtraConfig.MasterCount, endpointsAdapter)
  210. }
  211. func (c *Config) createNoneReconciler() reconcilers.EndpointReconciler {
  212. return reconcilers.NewNoneEndpointReconciler()
  213. }
  214. func (c *Config) createLeaseReconciler() reconcilers.EndpointReconciler {
  215. endpointClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
  216. var endpointSliceClient discoveryclient.EndpointSlicesGetter
  217. if utilfeature.DefaultFeatureGate.Enabled(features.EndpointSlice) {
  218. endpointSliceClient = discoveryclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
  219. }
  220. endpointsAdapter := reconcilers.NewEndpointsAdapter(endpointClient, endpointSliceClient)
  221. ttl := c.ExtraConfig.MasterEndpointReconcileTTL
  222. config, err := c.ExtraConfig.StorageFactory.NewConfig(api.Resource("apiServerIPInfo"))
  223. if err != nil {
  224. klog.Fatalf("Error determining service IP ranges: %v", err)
  225. }
  226. leaseStorage, _, err := storagefactory.Create(*config)
  227. if err != nil {
  228. klog.Fatalf("Error creating storage factory: %v", err)
  229. }
  230. masterLeases := reconcilers.NewLeases(leaseStorage, "/masterleases/", ttl)
  231. return reconcilers.NewLeaseEndpointReconciler(endpointsAdapter, masterLeases)
  232. }
  233. func (c *Config) createEndpointReconciler() reconcilers.EndpointReconciler {
  234. klog.Infof("Using reconciler: %v", c.ExtraConfig.EndpointReconcilerType)
  235. switch c.ExtraConfig.EndpointReconcilerType {
  236. // there are numerous test dependencies that depend on a default controller
  237. case "", reconcilers.MasterCountReconcilerType:
  238. return c.createMasterCountReconciler()
  239. case reconcilers.LeaseEndpointReconcilerType:
  240. return c.createLeaseReconciler()
  241. case reconcilers.NoneEndpointReconcilerType:
  242. return c.createNoneReconciler()
  243. default:
  244. klog.Fatalf("Reconciler not implemented: %v", c.ExtraConfig.EndpointReconcilerType)
  245. }
  246. return nil
  247. }
  248. // Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
  249. func (c *Config) Complete() CompletedConfig {
  250. cfg := completedConfig{
  251. c.GenericConfig.Complete(c.ExtraConfig.VersionedInformers),
  252. &c.ExtraConfig,
  253. }
  254. serviceIPRange, apiServerServiceIP, err := ServiceIPRange(cfg.ExtraConfig.ServiceIPRange)
  255. if err != nil {
  256. klog.Fatalf("Error determining service IP ranges: %v", err)
  257. }
  258. if cfg.ExtraConfig.ServiceIPRange.IP == nil {
  259. cfg.ExtraConfig.ServiceIPRange = serviceIPRange
  260. }
  261. if cfg.ExtraConfig.APIServerServiceIP == nil {
  262. cfg.ExtraConfig.APIServerServiceIP = apiServerServiceIP
  263. }
  264. discoveryAddresses := discovery.DefaultAddresses{DefaultAddress: cfg.GenericConfig.ExternalAddress}
  265. discoveryAddresses.CIDRRules = append(discoveryAddresses.CIDRRules,
  266. discovery.CIDRRule{IPRange: cfg.ExtraConfig.ServiceIPRange, Address: net.JoinHostPort(cfg.ExtraConfig.APIServerServiceIP.String(), strconv.Itoa(cfg.ExtraConfig.APIServerServicePort))})
  267. cfg.GenericConfig.DiscoveryAddresses = discoveryAddresses
  268. if cfg.ExtraConfig.ServiceNodePortRange.Size == 0 {
  269. // TODO: Currently no way to specify an empty range (do we need to allow this?)
  270. // We should probably allow this for clouds that don't require NodePort to do load-balancing (GCE)
  271. // but then that breaks the strict nestedness of ServiceType.
  272. // Review post-v1
  273. cfg.ExtraConfig.ServiceNodePortRange = kubeoptions.DefaultServiceNodePortRange
  274. klog.Infof("Node port range unspecified. Defaulting to %v.", cfg.ExtraConfig.ServiceNodePortRange)
  275. }
  276. if cfg.ExtraConfig.EndpointReconcilerConfig.Interval == 0 {
  277. cfg.ExtraConfig.EndpointReconcilerConfig.Interval = DefaultEndpointReconcilerInterval
  278. }
  279. if cfg.ExtraConfig.MasterEndpointReconcileTTL == 0 {
  280. cfg.ExtraConfig.MasterEndpointReconcileTTL = DefaultEndpointReconcilerTTL
  281. }
  282. if cfg.ExtraConfig.EndpointReconcilerConfig.Reconciler == nil {
  283. cfg.ExtraConfig.EndpointReconcilerConfig.Reconciler = c.createEndpointReconciler()
  284. }
  285. return CompletedConfig{&cfg}
  286. }
  287. // New returns a new instance of Master from the given config.
  288. // Certain config fields will be set to a default value if unset.
  289. // Certain config fields must be specified, including:
  290. // KubeletClientConfig
  291. func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) (*Master, error) {
  292. if reflect.DeepEqual(c.ExtraConfig.KubeletClientConfig, kubeletclient.KubeletClientConfig{}) {
  293. return nil, fmt.Errorf("Master.New() called with empty config.KubeletClientConfig")
  294. }
  295. s, err := c.GenericConfig.New("kube-apiserver", delegationTarget)
  296. if err != nil {
  297. return nil, err
  298. }
  299. if c.ExtraConfig.EnableLogsSupport {
  300. routes.Logs{}.Install(s.Handler.GoRestfulContainer)
  301. }
  302. if utilfeature.DefaultFeatureGate.Enabled(features.ServiceAccountIssuerDiscovery) {
  303. // Metadata and keys are expected to only change across restarts at present,
  304. // so we just marshal immediately and serve the cached JSON bytes.
  305. md, err := serviceaccount.NewOpenIDMetadata(
  306. c.ExtraConfig.ServiceAccountIssuerURL,
  307. c.ExtraConfig.ServiceAccountJWKSURI,
  308. c.GenericConfig.ExternalAddress,
  309. c.ExtraConfig.ServiceAccountPublicKeys,
  310. )
  311. if err != nil {
  312. // If there was an error, skip installing the endpoints and log the
  313. // error, but continue on. We don't return the error because the
  314. // metadata responses require additional, backwards incompatible
  315. // validation of command-line options.
  316. msg := fmt.Sprintf("Could not construct pre-rendered responses for"+
  317. " ServiceAccountIssuerDiscovery endpoints. Endpoints will not be"+
  318. " enabled. Error: %v", err)
  319. if c.ExtraConfig.ServiceAccountIssuerURL != "" {
  320. // The user likely expects this feature to be enabled if issuer URL is
  321. // set and the feature gate is enabled. In the future, if there is no
  322. // longer a feature gate and issuer URL is not set, the user may not
  323. // expect this feature to be enabled. We log the former case as an Error
  324. // and the latter case as an Info.
  325. klog.Error(msg)
  326. } else {
  327. klog.Info(msg)
  328. }
  329. } else {
  330. routes.NewOpenIDMetadataServer(md.ConfigJSON, md.PublicKeysetJSON).
  331. Install(s.Handler.GoRestfulContainer)
  332. }
  333. }
  334. m := &Master{
  335. GenericAPIServer: s,
  336. ClusterAuthenticationInfo: c.ExtraConfig.ClusterAuthenticationInfo,
  337. }
  338. // install legacy rest storage
  339. if c.ExtraConfig.APIResourceConfigSource.VersionEnabled(apiv1.SchemeGroupVersion) {
  340. legacyRESTStorageProvider := corerest.LegacyRESTStorageProvider{
  341. StorageFactory: c.ExtraConfig.StorageFactory,
  342. ProxyTransport: c.ExtraConfig.ProxyTransport,
  343. KubeletClientConfig: c.ExtraConfig.KubeletClientConfig,
  344. EventTTL: c.ExtraConfig.EventTTL,
  345. ServiceIPRange: c.ExtraConfig.ServiceIPRange,
  346. SecondaryServiceIPRange: c.ExtraConfig.SecondaryServiceIPRange,
  347. ServiceNodePortRange: c.ExtraConfig.ServiceNodePortRange,
  348. LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
  349. ServiceAccountIssuer: c.ExtraConfig.ServiceAccountIssuer,
  350. ServiceAccountMaxExpiration: c.ExtraConfig.ServiceAccountMaxExpiration,
  351. APIAudiences: c.GenericConfig.Authentication.APIAudiences,
  352. }
  353. if err := m.InstallLegacyAPI(&c, c.GenericConfig.RESTOptionsGetter, legacyRESTStorageProvider); err != nil {
  354. return nil, err
  355. }
  356. }
  357. // The order here is preserved in discovery.
  358. // If resources with identical names exist in more than one of these groups (e.g. "deployments.apps"" and "deployments.extensions"),
  359. // the order of this list determines which group an unqualified resource name (e.g. "deployments") should prefer.
  360. // This priority order is used for local discovery, but it ends up aggregated in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go
  361. // with specific priorities.
  362. // TODO: describe the priority all the way down in the RESTStorageProviders and plumb it back through the various discovery
  363. // handlers that we have.
  364. restStorageProviders := []RESTStorageProvider{
  365. auditregistrationrest.RESTStorageProvider{},
  366. authenticationrest.RESTStorageProvider{Authenticator: c.GenericConfig.Authentication.Authenticator, APIAudiences: c.GenericConfig.Authentication.APIAudiences},
  367. authorizationrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer, RuleResolver: c.GenericConfig.RuleResolver},
  368. autoscalingrest.RESTStorageProvider{},
  369. batchrest.RESTStorageProvider{},
  370. certificatesrest.RESTStorageProvider{},
  371. coordinationrest.RESTStorageProvider{},
  372. discoveryrest.StorageProvider{},
  373. extensionsrest.RESTStorageProvider{},
  374. networkingrest.RESTStorageProvider{},
  375. noderest.RESTStorageProvider{},
  376. policyrest.RESTStorageProvider{},
  377. rbacrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer},
  378. schedulingrest.RESTStorageProvider{},
  379. settingsrest.RESTStorageProvider{},
  380. storagerest.RESTStorageProvider{},
  381. flowcontrolrest.RESTStorageProvider{},
  382. // keep apps after extensions so legacy clients resolve the extensions versions of shared resource names.
  383. // See https://github.com/kubernetes/kubernetes/issues/42392
  384. appsrest.RESTStorageProvider{},
  385. admissionregistrationrest.RESTStorageProvider{},
  386. eventsrest.RESTStorageProvider{TTL: c.ExtraConfig.EventTTL},
  387. }
  388. if err := m.InstallAPIs(c.ExtraConfig.APIResourceConfigSource, c.GenericConfig.RESTOptionsGetter, restStorageProviders...); err != nil {
  389. return nil, err
  390. }
  391. if c.ExtraConfig.Tunneler != nil {
  392. m.installTunneler(c.ExtraConfig.Tunneler, corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig).Nodes())
  393. }
  394. m.GenericAPIServer.AddPostStartHookOrDie("start-cluster-authentication-info-controller", func(hookContext genericapiserver.PostStartHookContext) error {
  395. kubeClient, err := kubernetes.NewForConfig(hookContext.LoopbackClientConfig)
  396. if err != nil {
  397. return err
  398. }
  399. controller := clusterauthenticationtrust.NewClusterAuthenticationTrustController(m.ClusterAuthenticationInfo, kubeClient)
  400. // prime values and start listeners
  401. if m.ClusterAuthenticationInfo.ClientCA != nil {
  402. if notifier, ok := m.ClusterAuthenticationInfo.ClientCA.(dynamiccertificates.Notifier); ok {
  403. notifier.AddListener(controller)
  404. }
  405. if controller, ok := m.ClusterAuthenticationInfo.ClientCA.(dynamiccertificates.ControllerRunner); ok {
  406. // runonce to be sure that we have a value.
  407. if err := controller.RunOnce(); err != nil {
  408. runtime.HandleError(err)
  409. }
  410. go controller.Run(1, hookContext.StopCh)
  411. }
  412. }
  413. if m.ClusterAuthenticationInfo.RequestHeaderCA != nil {
  414. if notifier, ok := m.ClusterAuthenticationInfo.RequestHeaderCA.(dynamiccertificates.Notifier); ok {
  415. notifier.AddListener(controller)
  416. }
  417. if controller, ok := m.ClusterAuthenticationInfo.RequestHeaderCA.(dynamiccertificates.ControllerRunner); ok {
  418. // runonce to be sure that we have a value.
  419. if err := controller.RunOnce(); err != nil {
  420. runtime.HandleError(err)
  421. }
  422. go controller.Run(1, hookContext.StopCh)
  423. }
  424. }
  425. go controller.Run(1, hookContext.StopCh)
  426. return nil
  427. })
  428. return m, nil
  429. }
  430. // InstallLegacyAPI will install the legacy APIs for the restStorageProviders if they are enabled.
  431. func (m *Master) InstallLegacyAPI(c *completedConfig, restOptionsGetter generic.RESTOptionsGetter, legacyRESTStorageProvider corerest.LegacyRESTStorageProvider) error {
  432. legacyRESTStorage, apiGroupInfo, err := legacyRESTStorageProvider.NewLegacyRESTStorage(restOptionsGetter)
  433. if err != nil {
  434. return fmt.Errorf("error building core storage: %v", err)
  435. }
  436. controllerName := "bootstrap-controller"
  437. coreClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
  438. bootstrapController := c.NewBootstrapController(legacyRESTStorage, coreClient, coreClient, coreClient, coreClient.RESTClient())
  439. m.GenericAPIServer.AddPostStartHookOrDie(controllerName, bootstrapController.PostStartHook)
  440. m.GenericAPIServer.AddPreShutdownHookOrDie(controllerName, bootstrapController.PreShutdownHook)
  441. if err := m.GenericAPIServer.InstallLegacyAPIGroup(genericapiserver.DefaultLegacyAPIPrefix, &apiGroupInfo); err != nil {
  442. return fmt.Errorf("error in registering group versions: %v", err)
  443. }
  444. return nil
  445. }
  446. func (m *Master) installTunneler(nodeTunneler tunneler.Tunneler, nodeClient corev1client.NodeInterface) {
  447. nodeTunneler.Run(nodeAddressProvider{nodeClient}.externalAddresses)
  448. err := m.GenericAPIServer.AddHealthChecks(healthz.NamedCheck("SSH Tunnel Check", tunneler.TunnelSyncHealthChecker(nodeTunneler)))
  449. if err != nil {
  450. klog.Errorf("Failed adding ssh tunnel health check %v\n", err)
  451. }
  452. }
  453. // RESTStorageProvider is a factory type for REST storage.
  454. type RESTStorageProvider interface {
  455. GroupName() string
  456. NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool, error)
  457. }
  458. // InstallAPIs will install the APIs for the restStorageProviders if they are enabled.
  459. func (m *Master) InstallAPIs(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, restStorageProviders ...RESTStorageProvider) error {
  460. apiGroupsInfo := []*genericapiserver.APIGroupInfo{}
  461. for _, restStorageBuilder := range restStorageProviders {
  462. groupName := restStorageBuilder.GroupName()
  463. if !apiResourceConfigSource.AnyVersionForGroupEnabled(groupName) {
  464. klog.V(1).Infof("Skipping disabled API group %q.", groupName)
  465. continue
  466. }
  467. apiGroupInfo, enabled, err := restStorageBuilder.NewRESTStorage(apiResourceConfigSource, restOptionsGetter)
  468. if err != nil {
  469. return fmt.Errorf("problem initializing API group %q : %v", groupName, err)
  470. }
  471. if !enabled {
  472. klog.Warningf("API group %q is not enabled, skipping.", groupName)
  473. continue
  474. }
  475. klog.V(1).Infof("Enabling API group %q.", groupName)
  476. if postHookProvider, ok := restStorageBuilder.(genericapiserver.PostStartHookProvider); ok {
  477. name, hook, err := postHookProvider.PostStartHook()
  478. if err != nil {
  479. klog.Fatalf("Error building PostStartHook: %v", err)
  480. }
  481. m.GenericAPIServer.AddPostStartHookOrDie(name, hook)
  482. }
  483. apiGroupsInfo = append(apiGroupsInfo, &apiGroupInfo)
  484. }
  485. if err := m.GenericAPIServer.InstallAPIGroups(apiGroupsInfo...); err != nil {
  486. return fmt.Errorf("error in registering group versions: %v", err)
  487. }
  488. return nil
  489. }
  490. type nodeAddressProvider struct {
  491. nodeClient corev1client.NodeInterface
  492. }
  493. func (n nodeAddressProvider) externalAddresses() ([]string, error) {
  494. preferredAddressTypes := []apiv1.NodeAddressType{
  495. apiv1.NodeExternalIP,
  496. }
  497. nodes, err := n.nodeClient.List(context.TODO(), metav1.ListOptions{})
  498. if err != nil {
  499. return nil, err
  500. }
  501. var matchErr error
  502. addrs := []string{}
  503. for ix := range nodes.Items {
  504. node := &nodes.Items[ix]
  505. addr, err := nodeutil.GetPreferredNodeAddress(node, preferredAddressTypes)
  506. if err != nil {
  507. if _, ok := err.(*nodeutil.NoMatchError); ok {
  508. matchErr = err
  509. continue
  510. }
  511. return nil, err
  512. }
  513. addrs = append(addrs, addr)
  514. }
  515. if len(addrs) == 0 && matchErr != nil {
  516. // We only return an error if we have items.
  517. // Currently we return empty list/no error if Items is empty.
  518. // We do this for backward compatibility reasons.
  519. return nil, matchErr
  520. }
  521. return addrs, nil
  522. }
  523. // DefaultAPIResourceConfigSource returns default configuration for an APIResource.
  524. func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig {
  525. ret := serverstorage.NewResourceConfig()
  526. // NOTE: GroupVersions listed here will be enabled by default. Don't put alpha versions in the list.
  527. ret.EnableVersions(
  528. admissionregistrationv1.SchemeGroupVersion,
  529. admissionregistrationv1beta1.SchemeGroupVersion,
  530. apiv1.SchemeGroupVersion,
  531. appsv1.SchemeGroupVersion,
  532. authenticationv1.SchemeGroupVersion,
  533. authenticationv1beta1.SchemeGroupVersion,
  534. authorizationapiv1.SchemeGroupVersion,
  535. authorizationapiv1beta1.SchemeGroupVersion,
  536. autoscalingapiv1.SchemeGroupVersion,
  537. autoscalingapiv2beta1.SchemeGroupVersion,
  538. autoscalingapiv2beta2.SchemeGroupVersion,
  539. batchapiv1.SchemeGroupVersion,
  540. batchapiv1beta1.SchemeGroupVersion,
  541. certificatesapiv1beta1.SchemeGroupVersion,
  542. coordinationapiv1.SchemeGroupVersion,
  543. coordinationapiv1beta1.SchemeGroupVersion,
  544. discoveryv1beta1.SchemeGroupVersion,
  545. eventsv1beta1.SchemeGroupVersion,
  546. extensionsapiv1beta1.SchemeGroupVersion,
  547. networkingapiv1.SchemeGroupVersion,
  548. networkingapiv1beta1.SchemeGroupVersion,
  549. nodev1beta1.SchemeGroupVersion,
  550. policyapiv1beta1.SchemeGroupVersion,
  551. rbacv1.SchemeGroupVersion,
  552. rbacv1beta1.SchemeGroupVersion,
  553. storageapiv1.SchemeGroupVersion,
  554. storageapiv1beta1.SchemeGroupVersion,
  555. schedulingapiv1beta1.SchemeGroupVersion,
  556. schedulingapiv1.SchemeGroupVersion,
  557. )
  558. // enable non-deprecated beta resources in extensions/v1beta1 explicitly so we have a full list of what's possible to serve
  559. ret.EnableResources(
  560. extensionsapiv1beta1.SchemeGroupVersion.WithResource("ingresses"),
  561. )
  562. // disable alpha versions explicitly so we have a full list of what's possible to serve
  563. ret.DisableVersions(
  564. auditregistrationv1alpha1.SchemeGroupVersion,
  565. batchapiv2alpha1.SchemeGroupVersion,
  566. nodev1alpha1.SchemeGroupVersion,
  567. rbacv1alpha1.SchemeGroupVersion,
  568. schedulingv1alpha1.SchemeGroupVersion,
  569. settingsv1alpha1.SchemeGroupVersion,
  570. storageapiv1alpha1.SchemeGroupVersion,
  571. flowcontrolv1alpha1.SchemeGroupVersion,
  572. )
  573. return ret
  574. }