Skip to content

Commit 403301b

Browse files
apiserver: Add API emulation versioning.
Co-authored-by: Siyuan Zhang <[email protected]> Co-authored-by: Joe Betz <[email protected]> Co-authored-by: Alex Zielenski <[email protected]> Signed-off-by: Siyuan Zhang <[email protected]>
1 parent d0579b6 commit 403301b

File tree

86 files changed

+3414
-421
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+3414
-421
lines changed

cmd/kube-apiserver/app/options/options.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import (
2626
utilnet "k8s.io/apimachinery/pkg/util/net"
2727
cliflag "k8s.io/component-base/cli/flag"
2828

29+
utilversion "k8s.io/apiserver/pkg/util/version"
30+
"k8s.io/component-base/featuregate"
2931
api "k8s.io/kubernetes/pkg/apis/core"
3032
"k8s.io/kubernetes/pkg/cluster/ports"
3133
controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver/options"
@@ -63,10 +65,10 @@ type Extra struct {
6365
MasterCount int
6466
}
6567

66-
// NewServerRunOptions creates a new ServerRunOptions object with default parameters
67-
func NewServerRunOptions() *ServerRunOptions {
68+
// NewServerRunOptions creates and returns ServerRunOptions according to the given featureGate and effectiveVersion of the server binary to run.
69+
func NewServerRunOptions(featureGate featuregate.FeatureGate, effectiveVersion utilversion.EffectiveVersion) *ServerRunOptions {
6870
s := ServerRunOptions{
69-
Options: controlplaneapiserver.NewOptions(),
71+
Options: controlplaneapiserver.NewOptions(featureGate, effectiveVersion),
7072
CloudProvider: kubeoptions.NewCloudProviderOptions(),
7173

7274
Extra: Extra{

cmd/kube-apiserver/app/options/options_test.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ import (
3131
apiserveroptions "k8s.io/apiserver/pkg/server/options"
3232
"k8s.io/apiserver/pkg/storage/etcd3"
3333
"k8s.io/apiserver/pkg/storage/storagebackend"
34+
utilversion "k8s.io/apiserver/pkg/util/version"
3435
auditbuffered "k8s.io/apiserver/plugin/pkg/audit/buffered"
3536
audittruncate "k8s.io/apiserver/plugin/pkg/audit/truncate"
3637
cliflag "k8s.io/component-base/cli/flag"
38+
"k8s.io/component-base/featuregate"
3739
"k8s.io/component-base/logs"
3840
"k8s.io/component-base/metrics"
3941
kapi "k8s.io/kubernetes/pkg/apis/core"
@@ -46,10 +48,15 @@ import (
4648

4749
func TestAddFlags(t *testing.T) {
4850
fs := pflag.NewFlagSet("addflagstest", pflag.PanicOnError)
49-
s := NewServerRunOptions()
51+
52+
featureGate := featuregate.NewFeatureGate()
53+
effectiveVersion := utilversion.NewEffectiveVersion("1.32")
54+
s := NewServerRunOptions(featureGate, effectiveVersion)
5055
for _, f := range s.Flags().FlagSets {
5156
fs.AddFlagSet(f)
5257
}
58+
featureGate.AddFlag(fs, "")
59+
effectiveVersion.AddFlags(fs, "")
5360

5461
args := []string{
5562
"--enable-admission-plugins=AlwaysDeny",
@@ -121,6 +128,7 @@ func TestAddFlags(t *testing.T) {
121128
"--storage-backend=etcd3",
122129
"--service-cluster-ip-range=192.168.128.0/17",
123130
"--lease-reuse-duration-seconds=100",
131+
"--emulated-version=1.31",
124132
}
125133
fs.Parse(args)
126134

@@ -136,6 +144,8 @@ func TestAddFlags(t *testing.T) {
136144
MinRequestTimeout: 1800,
137145
JSONPatchMaxCopyBytes: int64(3 * 1024 * 1024),
138146
MaxRequestBodyBytes: int64(3 * 1024 * 1024),
147+
FeatureGate: featureGate,
148+
EffectiveVersion: effectiveVersion,
139149
},
140150
Admission: &kubeoptions.AdmissionOptions{
141151
GenericAdmission: &apiserveroptions.AdmissionOptions{
@@ -337,4 +347,8 @@ func TestAddFlags(t *testing.T) {
337347
if !reflect.DeepEqual(expected, s) {
338348
t.Errorf("Got different run options than expected.\nDifference detected on:\n%s", cmp.Diff(expected, s, cmpopts.IgnoreUnexported(admission.Plugins{}, kubeoptions.OIDCAuthenticationOptions{})))
339349
}
350+
351+
if s.GenericServerRunOptions.EffectiveVersion.EmulationVersion().String() != "1.31" {
352+
t.Errorf("Got emulation version %s, wanted %s", s.GenericServerRunOptions.EffectiveVersion.EmulationVersion().String(), "1.31")
353+
}
340354
}

cmd/kube-apiserver/app/server.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
serverstorage "k8s.io/apiserver/pkg/server/storage"
3737
utilfeature "k8s.io/apiserver/pkg/util/feature"
3838
"k8s.io/apiserver/pkg/util/notfoundhandler"
39+
utilversion "k8s.io/apiserver/pkg/util/version"
3940
"k8s.io/apiserver/pkg/util/webhook"
4041
clientgoinformers "k8s.io/client-go/informers"
4142
"k8s.io/client-go/rest"
@@ -63,7 +64,10 @@ func init() {
6364

6465
// NewAPIServerCommand creates a *cobra.Command object with default parameters
6566
func NewAPIServerCommand() *cobra.Command {
66-
s := options.NewServerRunOptions()
67+
effectiveVersion, featureGate := utilversion.DefaultComponentGlobalsRegistry.ComponentGlobalsOrRegister(
68+
utilversion.ComponentGenericAPIServer, utilversion.DefaultBuildEffectiveVersion(), utilfeature.DefaultMutableFeatureGate)
69+
s := options.NewServerRunOptions(featureGate, effectiveVersion)
70+
6771
cmd := &cobra.Command{
6872
Use: "kube-apiserver",
6973
Long: `The Kubernetes API server validates and configures data
@@ -83,9 +87,13 @@ cluster's shared state through which all other components interact.`,
8387
verflag.PrintAndExitIfRequested()
8488
fs := cmd.Flags()
8589

90+
if err := utilversion.DefaultComponentGlobalsRegistry.SetAllComponents(); err != nil {
91+
return err
92+
}
93+
8694
// Activate logging as soon as possible, after that
8795
// show flags with the final logging configuration.
88-
if err := logsapi.ValidateAndApply(s.Logs, utilfeature.DefaultFeatureGate); err != nil {
96+
if err := logsapi.ValidateAndApply(s.Logs, featureGate); err != nil {
8997
return err
9098
}
9199
cliflag.PrintFlags(fs)
@@ -101,7 +109,7 @@ cluster's shared state through which all other components interact.`,
101109
return utilerrors.NewAggregate(errs)
102110
}
103111
// add feature enablement metrics
104-
utilfeature.DefaultMutableFeatureGate.AddMetrics()
112+
featureGate.AddMetrics()
105113
return Run(cmd.Context(), completedOptions)
106114
},
107115
Args: func(cmd *cobra.Command, args []string) error {
@@ -118,6 +126,9 @@ cluster's shared state through which all other components interact.`,
118126
fs := cmd.Flags()
119127
namedFlagSets := s.Flags()
120128
verflag.AddFlags(namedFlagSets.FlagSet("global"))
129+
featureGate.AddFlag(namedFlagSets.FlagSet("global"), "")
130+
effectiveVersion.AddFlags(namedFlagSets.FlagSet("global"), "")
131+
121132
globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmd.Name(), logs.SkipLoggingConfigurationFlags())
122133
options.AddCustomGlobalFlags(namedFlagSets.FlagSet("generic"))
123134
for _, f := range namedFlagSets.FlagSets {

cmd/kube-apiserver/app/testing/testserver.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import (
4848
"k8s.io/apiserver/pkg/storage/storagebackend"
4949
"k8s.io/apiserver/pkg/storageversion"
5050
utilfeature "k8s.io/apiserver/pkg/util/feature"
51+
utilversion "k8s.io/apiserver/pkg/util/version"
5152
"k8s.io/client-go/kubernetes"
5253
restclient "k8s.io/client-go/rest"
5354
clientgotransport "k8s.io/client-go/transport"
@@ -98,6 +99,9 @@ type TestServerInstanceOptions struct {
9899
// We specify this as on option to pass a common proxyCA to multiple apiservers to simulate
99100
// an apiserver version skew scenario where all apiservers use the same proxyCA to verify client connections.
100101
ProxyCA *ProxyCA
102+
// Set the BinaryVersion of server effective version.
103+
// Default to 1.31
104+
BinaryVersion string
101105
}
102106

103107
// TestServer return values supplied by kube-test-ApiServer
@@ -177,10 +181,21 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
177181

178182
fs := pflag.NewFlagSet("test", pflag.PanicOnError)
179183

180-
s := options.NewServerRunOptions()
184+
featureGate := utilfeature.DefaultMutableFeatureGate
185+
binaryVersion := utilversion.DefaultKubeEffectiveVersion().BinaryVersion().String()
186+
if instanceOptions.BinaryVersion != "" {
187+
binaryVersion = instanceOptions.BinaryVersion
188+
}
189+
effectiveVersion := utilversion.NewEffectiveVersion(binaryVersion)
190+
_ = utilversion.DefaultComponentGlobalsRegistry.Register(utilversion.ComponentGenericAPIServer, effectiveVersion, featureGate, true)
191+
192+
s := options.NewServerRunOptions(featureGate, effectiveVersion)
193+
181194
for _, f := range s.Flags().FlagSets {
182195
fs.AddFlagSet(f)
183196
}
197+
featureGate.AddFlag(fs, "")
198+
effectiveVersion.AddFlags(fs, "")
184199

185200
s.SecureServing.Listener, s.SecureServing.BindPort, err = createLocalhostListenerOnFreePort()
186201
if err != nil {
@@ -321,6 +336,10 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
321336
return result, err
322337
}
323338

339+
if err := utilversion.DefaultComponentGlobalsRegistry.SetAllComponents(); err != nil {
340+
return result, err
341+
}
342+
324343
saSigningKeyFile, err := os.CreateTemp("/tmp", "insecure_test_key")
325344
if err != nil {
326345
t.Fatalf("create temp file failed: %v", err)

cmd/kube-controller-manager/app/options/options.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ func (s *KubeControllerManagerOptions) Flags(allControllers []string, disabledBy
273273
fs := fss.FlagSet("misc")
274274
fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig).")
275275
fs.StringVar(&s.Generic.ClientConnection.Kubeconfig, "kubeconfig", s.Generic.ClientConnection.Kubeconfig, "Path to kubeconfig file with authorization and master location information (the master location can be overridden by the master flag).")
276-
utilfeature.DefaultMutableFeatureGate.AddFlag(fss.FlagSet("generic"))
276+
utilfeature.DefaultMutableFeatureGate.AddFlag(fss.FlagSet("generic"), "")
277277

278278
return fss
279279
}

cmd/kube-scheduler/app/options/options.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ func (o *Options) initFlags() {
189189
o.Authorization.AddFlags(nfs.FlagSet("authorization"))
190190
o.Deprecated.AddFlags(nfs.FlagSet("deprecated"))
191191
options.BindLeaderElectionFlags(o.LeaderElection, nfs.FlagSet("leader election"))
192-
utilfeature.DefaultMutableFeatureGate.AddFlag(nfs.FlagSet("feature gate"))
192+
utilfeature.DefaultMutableFeatureGate.AddFlag(nfs.FlagSet("feature gate"), "")
193193
o.Metrics.AddFlags(nfs.FlagSet("metrics"))
194194
logsapi.AddFlags(o.Logs, nfs.FlagSet("logs"))
195195

pkg/controlplane/apiserver/apiextensions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ limitations under the License.
1717
package apiserver
1818

1919
import (
20-
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2120
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
2221
apiextensionsapiserver "k8s.io/apiextensions-apiserver/pkg/apiserver"
2322
apiextensionsoptions "k8s.io/apiextensions-apiserver/pkg/cmd/server/options"
@@ -27,6 +26,7 @@ import (
2726
"k8s.io/apiserver/pkg/server"
2827
"k8s.io/apiserver/pkg/util/webhook"
2928
"k8s.io/client-go/informers"
29+
v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
3030

3131
"k8s.io/kubernetes/pkg/controlplane/apiserver/options"
3232
)

pkg/controlplane/apiserver/apis.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ func (s *Server) InstallAPIs(restStorageProviders ...RESTStorageProvider) error
8888
nonLegacy := []*genericapiserver.APIGroupInfo{}
8989

9090
// used later in the loop to filter the served resource by those that have expired.
91-
resourceExpirationEvaluator, err := genericapiserver.NewResourceExpirationEvaluator(*s.GenericAPIServer.Version)
91+
resourceExpirationEvaluator, err := genericapiserver.NewResourceExpirationEvaluator(s.GenericAPIServer.EffectiveVersion.EmulationVersion())
9292
if err != nil {
9393
return err
9494
}

pkg/controlplane/apiserver/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,9 @@ func BuildGenericConfig(
185185
}
186186

187187
storageFactoryConfig := kubeapiserver.NewStorageFactoryConfig()
188+
storageFactoryConfig.CurrentVersion = genericConfig.EffectiveVersion
188189
storageFactoryConfig.APIResourceConfig = genericConfig.MergedResourceConfig
190+
storageFactoryConfig.DefaultResourceEncoding.SetEffectiveVersion(genericConfig.EffectiveVersion)
189191
storageFactory, lastErr = storageFactoryConfig.Complete(s.Etcd).New()
190192
if lastErr != nil {
191193
return

pkg/controlplane/apiserver/config_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
"k8s.io/apimachinery/pkg/runtime"
2525
"k8s.io/apimachinery/pkg/runtime/schema"
2626
apiserveroptions "k8s.io/apiserver/pkg/server/options"
27+
utilversion "k8s.io/apiserver/pkg/util/version"
28+
"k8s.io/component-base/featuregate"
2729
aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme"
2830
"k8s.io/kubernetes/pkg/api/legacyscheme"
2931
"k8s.io/kubernetes/pkg/controlplane/apiserver/options"
@@ -32,7 +34,9 @@ import (
3234
)
3335

3436
func TestBuildGenericConfig(t *testing.T) {
35-
opts := options.NewOptions()
37+
featureGate := featuregate.NewFeatureGate()
38+
effectiveVersion := utilversion.DefaultKubeEffectiveVersion()
39+
opts := options.NewOptions(featureGate, effectiveVersion)
3640
s := (&apiserveroptions.SecureServingOptions{
3741
BindAddress: netutils.ParseIPSloppy("127.0.0.1"),
3842
}).WithLoopback()
@@ -66,7 +70,7 @@ func TestBuildGenericConfig(t *testing.T) {
6670
t.Errorf("There are different StorageObjectCountTracker in genericConfig and storageFactory")
6771
}
6872

69-
restOptions, err := genericConfig.RESTOptionsGetter.GetRESTOptions(schema.GroupResource{Group: "", Resource: ""})
73+
restOptions, err := genericConfig.RESTOptionsGetter.GetRESTOptions(schema.GroupResource{Group: "", Resource: ""}, nil)
7074
if err != nil {
7175
t.Fatal(err)
7276
}

0 commit comments

Comments
 (0)