Skip to content

Commit 7a6062f

Browse files
authored
Merge pull request kubernetes#122891 from siyuanfoundation/api-comp-ver1
apimachinery: API Emulation Versioning
2 parents 85ede67 + 379676c commit 7a6062f

File tree

85 files changed

+4714
-452
lines changed

Some content is hidden

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

85 files changed

+4714
-452
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ type Extra struct {
6363
MasterCount int
6464
}
6565

66-
// NewServerRunOptions creates a new ServerRunOptions object with default parameters
66+
// NewServerRunOptions creates and returns ServerRunOptions according to the given featureGate and effectiveVersion of the server binary to run.
6767
func NewServerRunOptions() *ServerRunOptions {
6868
s := ServerRunOptions{
6969
Options: controlplaneapiserver.NewOptions(),

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@ import (
2727
"github.com/spf13/pflag"
2828
noopoteltrace "go.opentelemetry.io/otel/trace/noop"
2929

30+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
3031
"k8s.io/apiserver/pkg/admission"
3132
apiserveroptions "k8s.io/apiserver/pkg/server/options"
3233
"k8s.io/apiserver/pkg/storage/etcd3"
3334
"k8s.io/apiserver/pkg/storage/storagebackend"
35+
utilversion "k8s.io/apiserver/pkg/util/version"
3436
auditbuffered "k8s.io/apiserver/plugin/pkg/audit/buffered"
3537
audittruncate "k8s.io/apiserver/plugin/pkg/audit/truncate"
3638
cliflag "k8s.io/component-base/cli/flag"
39+
"k8s.io/component-base/featuregate"
3740
"k8s.io/component-base/logs"
3841
"k8s.io/component-base/metrics"
3942
kapi "k8s.io/kubernetes/pkg/apis/core"
@@ -45,7 +48,13 @@ import (
4548
)
4649

4750
func TestAddFlags(t *testing.T) {
51+
componentGlobalsRegistry := utilversion.DefaultComponentGlobalsRegistry
52+
t.Cleanup(func() {
53+
componentGlobalsRegistry.Reset()
54+
})
4855
fs := pflag.NewFlagSet("addflagstest", pflag.PanicOnError)
56+
57+
utilruntime.Must(componentGlobalsRegistry.Register("test", utilversion.NewEffectiveVersion("1.32"), featuregate.NewFeatureGate()))
4958
s := NewServerRunOptions()
5059
for _, f := range s.Flags().FlagSets {
5160
fs.AddFlagSet(f)
@@ -121,8 +130,10 @@ func TestAddFlags(t *testing.T) {
121130
"--storage-backend=etcd3",
122131
"--service-cluster-ip-range=192.168.128.0/17",
123132
"--lease-reuse-duration-seconds=100",
133+
"--emulated-version=test=1.31",
124134
}
125135
fs.Parse(args)
136+
utilruntime.Must(componentGlobalsRegistry.Set())
126137

127138
// This is a snapshot of expected options parsed by args.
128139
expected := &ServerRunOptions{
@@ -136,6 +147,8 @@ func TestAddFlags(t *testing.T) {
136147
MinRequestTimeout: 1800,
137148
JSONPatchMaxCopyBytes: int64(3 * 1024 * 1024),
138149
MaxRequestBodyBytes: int64(3 * 1024 * 1024),
150+
ComponentGlobalsRegistry: componentGlobalsRegistry,
151+
ComponentName: utilversion.DefaultKubeComponent,
139152
},
140153
Admission: &kubeoptions.AdmissionOptions{
141154
GenericAdmission: &apiserveroptions.AdmissionOptions{
@@ -337,4 +350,8 @@ func TestAddFlags(t *testing.T) {
337350
if !reflect.DeepEqual(expected, s) {
338351
t.Errorf("Got different run options than expected.\nDifference detected on:\n%s", cmp.Diff(expected, s, cmpopts.IgnoreUnexported(admission.Plugins{}, kubeoptions.OIDCAuthenticationOptions{})))
339352
}
353+
testEffectiveVersion := s.GenericServerRunOptions.ComponentGlobalsRegistry.EffectiveVersionFor("test")
354+
if testEffectiveVersion.EmulationVersion().String() != "1.31" {
355+
t.Errorf("Got emulation version %s, wanted %s", testEffectiveVersion.EmulationVersion().String(), "1.31")
356+
}
340357
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
utilfeature "k8s.io/apiserver/pkg/util/feature"
2727
netutils "k8s.io/utils/net"
2828

29+
"k8s.io/apimachinery/pkg/util/version"
2930
controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver/options"
3031
"k8s.io/kubernetes/pkg/controlplane/reconcilers"
3132
"k8s.io/kubernetes/pkg/features"
@@ -139,5 +140,14 @@ func (s CompletedOptions) Validate() []error {
139140
errs = append(errs, fmt.Errorf("--apiserver-count should be a positive number, but value '%d' provided", s.MasterCount))
140141
}
141142

143+
// TODO: remove in 1.32
144+
// emulationVersion is introduced in 1.31, so it is only allowed to be equal to the binary version at 1.31.
145+
effectiveVersion := s.GenericServerRunOptions.ComponentGlobalsRegistry.EffectiveVersionFor(s.GenericServerRunOptions.ComponentName)
146+
binaryVersion := version.MajorMinor(effectiveVersion.BinaryVersion().Major(), effectiveVersion.BinaryVersion().Minor())
147+
if binaryVersion.EqualTo(version.MajorMinor(1, 31)) && !effectiveVersion.EmulationVersion().EqualTo(binaryVersion) {
148+
errs = append(errs, fmt.Errorf("emulation version needs to be equal to binary version(%s) in compatibility-version alpha, got %s",
149+
binaryVersion.String(), effectiveVersion.EmulationVersion().String()))
150+
}
151+
142152
return errs
143153
}

cmd/kube-apiserver/app/server.go

Lines changed: 9 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 {
67+
_, featureGate := utilversion.DefaultComponentGlobalsRegistry.ComponentGlobalsOrRegister(
68+
utilversion.DefaultKubeComponent, utilversion.DefaultBuildEffectiveVersion(), utilfeature.DefaultMutableFeatureGate)
6669
s := options.NewServerRunOptions()
70+
6771
cmd := &cobra.Command{
6872
Use: "kube-apiserver",
6973
Long: `The Kubernetes API server validates and configures data
@@ -74,6 +78,9 @@ cluster's shared state through which all other components interact.`,
7478
// stop printing usage when the command errors
7579
SilenceUsage: true,
7680
PersistentPreRunE: func(*cobra.Command, []string) error {
81+
if err := utilversion.DefaultComponentGlobalsRegistry.Set(); err != nil {
82+
return err
83+
}
7784
// silence client-go warnings.
7885
// kube-apiserver loopback clients should not log self-issued warnings.
7986
rest.SetDefaultWarningHandler(rest.NoWarnings{})
@@ -82,10 +89,9 @@ cluster's shared state through which all other components interact.`,
8289
RunE: func(cmd *cobra.Command, args []string) error {
8390
verflag.PrintAndExitIfRequested()
8491
fs := cmd.Flags()
85-
8692
// Activate logging as soon as possible, after that
8793
// show flags with the final logging configuration.
88-
if err := logsapi.ValidateAndApply(s.Logs, utilfeature.DefaultFeatureGate); err != nil {
94+
if err := logsapi.ValidateAndApply(s.Logs, featureGate); err != nil {
8995
return err
9096
}
9197
cliflag.PrintFlags(fs)
@@ -101,7 +107,7 @@ cluster's shared state through which all other components interact.`,
101107
return utilerrors.NewAggregate(errs)
102108
}
103109
// add feature enablement metrics
104-
utilfeature.DefaultMutableFeatureGate.AddMetrics()
110+
featureGate.AddMetrics()
105111
return Run(cmd.Context(), completedOptions)
106112
},
107113
Args: func(cmd *cobra.Command, args []string) error {

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,19 @@ import (
4343
"k8s.io/apimachinery/pkg/api/errors"
4444
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4545
utilerrors "k8s.io/apimachinery/pkg/util/errors"
46+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
4647
"k8s.io/apimachinery/pkg/util/wait"
4748
serveroptions "k8s.io/apiserver/pkg/server/options"
4849
"k8s.io/apiserver/pkg/storage/storagebackend"
4950
"k8s.io/apiserver/pkg/storageversion"
5051
utilfeature "k8s.io/apiserver/pkg/util/feature"
52+
utilversion "k8s.io/apiserver/pkg/util/version"
5153
"k8s.io/client-go/kubernetes"
5254
restclient "k8s.io/client-go/rest"
5355
clientgotransport "k8s.io/client-go/transport"
5456
"k8s.io/client-go/util/cert"
5557
"k8s.io/client-go/util/keyutil"
58+
featuregatetesting "k8s.io/component-base/featuregate/testing"
5659
logsapi "k8s.io/component-base/logs/api/v1"
5760
"k8s.io/klog/v2"
5861
"k8s.io/kube-aggregator/pkg/apiserver"
@@ -98,6 +101,9 @@ type TestServerInstanceOptions struct {
98101
// We specify this as on option to pass a common proxyCA to multiple apiservers to simulate
99102
// an apiserver version skew scenario where all apiservers use the same proxyCA to verify client connections.
100103
ProxyCA *ProxyCA
104+
// Set the BinaryVersion of server effective version.
105+
// Default to 1.31
106+
BinaryVersion string
101107
}
102108

103109
// TestServer return values supplied by kube-test-ApiServer
@@ -177,7 +183,18 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
177183

178184
fs := pflag.NewFlagSet("test", pflag.PanicOnError)
179185

186+
featureGate := utilfeature.DefaultMutableFeatureGate
187+
effectiveVersion := utilversion.DefaultKubeEffectiveVersion()
188+
if instanceOptions.BinaryVersion != "" {
189+
effectiveVersion = utilversion.NewEffectiveVersion(instanceOptions.BinaryVersion)
190+
}
191+
// need to call SetFeatureGateEmulationVersionDuringTest to reset the feature gate emulation version at the end of the test.
192+
featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, featureGate, effectiveVersion.EmulationVersion())
193+
utilversion.DefaultComponentGlobalsRegistry.Reset()
194+
utilruntime.Must(utilversion.DefaultComponentGlobalsRegistry.Register(utilversion.DefaultKubeComponent, effectiveVersion, featureGate))
195+
180196
s := options.NewServerRunOptions()
197+
181198
for _, f := range s.Flags().FlagSets {
182199
fs.AddFlagSet(f)
183200
}
@@ -321,6 +338,10 @@ func StartTestServer(t ktesting.TB, instanceOptions *TestServerInstanceOptions,
321338
return result, err
322339
}
323340

341+
if err := utilversion.DefaultComponentGlobalsRegistry.Set(); err != nil {
342+
return result, err
343+
}
344+
324345
saSigningKeyFile, err := os.CreateTemp("/tmp", "insecure_test_key")
325346
if err != nil {
326347
t.Fatalf("create temp file failed: %v", err)

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 & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ import (
4646
clientgoinformers "k8s.io/client-go/informers"
4747
clientgoclientset "k8s.io/client-go/kubernetes"
4848
"k8s.io/client-go/util/keyutil"
49-
"k8s.io/component-base/version"
5049
aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
5150
openapicommon "k8s.io/kube-openapi/pkg/common"
5251

@@ -172,9 +171,6 @@ func BuildGenericConfig(
172171
sets.NewString("attach", "exec", "proxy", "log", "portforward"),
173172
)
174173

175-
kubeVersion := version.Get()
176-
genericConfig.Version = &kubeVersion
177-
178174
if genericConfig.EgressSelector != nil {
179175
s.Etcd.StorageConfig.Transport.EgressLookup = genericConfig.EgressSelector.Lookup
180176
}
@@ -185,7 +181,9 @@ func BuildGenericConfig(
185181
}
186182

187183
storageFactoryConfig := kubeapiserver.NewStorageFactoryConfig()
184+
storageFactoryConfig.CurrentVersion = genericConfig.EffectiveVersion
188185
storageFactoryConfig.APIResourceConfig = genericConfig.MergedResourceConfig
186+
storageFactoryConfig.DefaultResourceEncoding.SetEffectiveVersion(genericConfig.EffectiveVersion)
189187
storageFactory, lastErr = storageFactoryConfig.Complete(s.Etcd).New()
190188
if lastErr != nil {
191189
return

pkg/controlplane/apiserver/config_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func TestBuildGenericConfig(t *testing.T) {
6666
t.Errorf("There are different StorageObjectCountTracker in genericConfig and storageFactory")
6767
}
6868

69-
restOptions, err := genericConfig.RESTOptionsGetter.GetRESTOptions(schema.GroupResource{Group: "", Resource: ""})
69+
restOptions, err := genericConfig.RESTOptionsGetter.GetRESTOptions(schema.GroupResource{Group: "", Resource: ""}, nil)
7070
if err != nil {
7171
t.Fatal(err)
7272
}

pkg/controlplane/apiserver/options/options.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ func (o *Options) Complete(alternateDNS []string, alternateIPs []net.IP) (Comple
202202
Options: *o,
203203
}
204204

205+
if err := completed.GenericServerRunOptions.Complete(); err != nil {
206+
return CompletedOptions{}, err
207+
}
208+
205209
// set defaults
206210
if err := completed.GenericServerRunOptions.DefaultAdvertiseAddress(completed.SecureServing.SecureServingOptions); err != nil {
207211
return CompletedOptions{}, err

0 commit comments

Comments
 (0)