Skip to content

Commit 3a68b84

Browse files
authored
Merge pull request kubernetes#120202 from sttts/sttts-controlplane-config-split
Step 2 – generic controlplane: split server
2 parents c6b6163 + 3b6d2a6 commit 3a68b84

File tree

11 files changed

+427
-320
lines changed

11 files changed

+427
-320
lines changed

cmd/kube-apiserver/app/server.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import (
2727
"os"
2828

2929
"github.com/spf13/cobra"
30-
3130
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3231
extensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
3332
"k8s.io/apimachinery/pkg/runtime"
@@ -185,7 +184,7 @@ func CreateServerChain(config CompletedConfig) (*aggregatorapiserver.APIAggregat
185184
}
186185

187186
// aggregator comes last in the chain
188-
aggregatorServer, err := createAggregatorServer(config.Aggregator, kubeAPIServer.GenericAPIServer, apiExtensionsServer.Informers, crdAPIEnabled)
187+
aggregatorServer, err := createAggregatorServer(config.Aggregator, kubeAPIServer.ControlPlane.GenericAPIServer, apiExtensionsServer.Informers, crdAPIEnabled)
189188
if err != nil {
190189
// we don't need special handling for innerStopCh because the aggregator server doesn't create any go routines
191190
return nil, err

pkg/controlplane/apiserver/apis.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package apiserver
18+
19+
import (
20+
"fmt"
21+
22+
"k8s.io/apiserver/pkg/registry/generic"
23+
genericapiserver "k8s.io/apiserver/pkg/server"
24+
serverstorage "k8s.io/apiserver/pkg/server/storage"
25+
"k8s.io/klog/v2"
26+
)
27+
28+
// RESTStorageProvider is a factory type for REST storage.
29+
type RESTStorageProvider interface {
30+
GroupName() string
31+
NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error)
32+
}
33+
34+
// InstallAPIs will install the APIs for the restStorageProviders if they are enabled.
35+
func (s *Server) InstallAPIs(restStorageProviders ...RESTStorageProvider) error {
36+
nonLegacy := []*genericapiserver.APIGroupInfo{}
37+
38+
// used later in the loop to filter the served resource by those that have expired.
39+
resourceExpirationEvaluator, err := genericapiserver.NewResourceExpirationEvaluator(*s.GenericAPIServer.Version)
40+
if err != nil {
41+
return err
42+
}
43+
44+
for _, restStorageBuilder := range restStorageProviders {
45+
groupName := restStorageBuilder.GroupName()
46+
apiGroupInfo, err := restStorageBuilder.NewRESTStorage(s.APIResourceConfigSource, s.RESTOptionsGetter)
47+
if err != nil {
48+
return fmt.Errorf("problem initializing API group %q: %w", groupName, err)
49+
}
50+
if len(apiGroupInfo.VersionedResourcesStorageMap) == 0 {
51+
// If we have no storage for any resource configured, this API group is effectively disabled.
52+
// This can happen when an entire API group, version, or development-stage (alpha, beta, GA) is disabled.
53+
klog.Infof("API group %q is not enabled, skipping.", groupName)
54+
continue
55+
}
56+
57+
// Remove resources that serving kinds that are removed.
58+
// We do this here so that we don't accidentally serve versions without resources or openapi information that for kinds we don't serve.
59+
// This is a spot above the construction of individual storage handlers so that no sig accidentally forgets to check.
60+
resourceExpirationEvaluator.RemoveDeletedKinds(groupName, apiGroupInfo.Scheme, apiGroupInfo.VersionedResourcesStorageMap)
61+
if len(apiGroupInfo.VersionedResourcesStorageMap) == 0 {
62+
klog.V(1).Infof("Removing API group %v because it is time to stop serving it because it has no versions per APILifecycle.", groupName)
63+
continue
64+
}
65+
66+
klog.V(1).Infof("Enabling API group %q.", groupName)
67+
68+
if postHookProvider, ok := restStorageBuilder.(genericapiserver.PostStartHookProvider); ok {
69+
name, hook, err := postHookProvider.PostStartHook()
70+
if err != nil {
71+
return fmt.Errorf("error building PostStartHook: %w", err)
72+
}
73+
s.GenericAPIServer.AddPostStartHookOrDie(name, hook)
74+
}
75+
76+
if len(groupName) == 0 {
77+
// the legacy group for core APIs is special that it is installed into /api via this special install method.
78+
if err := s.GenericAPIServer.InstallLegacyAPIGroup(genericapiserver.DefaultLegacyAPIPrefix, &apiGroupInfo); err != nil {
79+
return fmt.Errorf("error in registering legacy API: %w", err)
80+
}
81+
} else {
82+
// everything else goes to /apis
83+
nonLegacy = append(nonLegacy, &apiGroupInfo)
84+
}
85+
}
86+
87+
if err := s.GenericAPIServer.InstallAPIGroups(nonLegacy...); err != nil {
88+
return fmt.Errorf("error in registering group versions: %w", err)
89+
}
90+
return nil
91+
}

pkg/controlplane/apiserver/peer.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package apiserver
1818

1919
import (
2020
"fmt"
21+
"net"
22+
"strconv"
2123
"time"
2224

2325
"k8s.io/apimachinery/pkg/runtime"
@@ -87,3 +89,13 @@ func CreatePeerEndpointLeaseReconciler(c genericapiserver.Config, storageFactory
8789
reconciler, err := reconcilers.NewPeerEndpointLeaseReconciler(config, "/peerserverleases/", ttl)
8890
return reconciler, err
8991
}
92+
93+
// utility function to get the apiserver address that is used by peer apiservers to proxy
94+
// requests to this apiserver in case the peer is incapable of serving the request
95+
func getPeerAddress(peerAdvertiseAddress reconcilers.PeerAdvertiseAddress, publicAddress net.IP, publicServicePort int) string {
96+
if peerAdvertiseAddress.PeerAdvertiseIP != "" && peerAdvertiseAddress.PeerAdvertisePort != "" {
97+
return net.JoinHostPort(peerAdvertiseAddress.PeerAdvertiseIP, peerAdvertiseAddress.PeerAdvertisePort)
98+
} else {
99+
return net.JoinHostPort(publicAddress.String(), strconv.Itoa(publicServicePort))
100+
}
101+
}

0 commit comments

Comments
 (0)