Issue 1:
The unversioned concept is not needed. Every object demonstrably has a schema that constitutes a single version (there is no object without a version). Unversioned is a limited concept intended to solve two cases - api objects that are not retrieved in the context of a locked version (/apis/, /api/, Status errors encountered outside a scheme), and the reuse of objects across versions. The latter is better served by type aliasing (declaring that v1beta1 Status has the equivalent to schema of v1 Status) or type duplication (copy v1 Status into v1beta1 and register it). The former still has a schema that requires exposure through swagger, and for which certain code that already handles versioned code is directly better. The contract of backwards compatibility for unversioned API endpoints requires that we not deliver backwards incompatible schemas to clients, but that does not limit us to the exposure of new API groups on different server implementations that have newer implementations of status.

The unversioned package should be changed:

We should create a "v1" unversioned package (indicating these are versioned types) that contains everything in "v1".

The parent package name should be renamed to "common" or "server"

No backwards incompatible changes are allowed in this package (same statement as today)

We can put common types into here that individual implementations of APIs get to pick from - for instance, an API can choose to take v1 Status or v2 Status

API status, when returned by an API versioned url path (/apis/group/version/*) should be versioned - the Go type common/v1/Status should be registered into each API version under the name Status, and the returned group and version of the object from the API would be the group and version they are under

Top level, non-version-lockedAPIs should return kind: "Status", version: "v1" which is backwards compatible with what we launched with. That means they obey the schema registered under "version 1" which is in the legacy group.

Any new top level object returned from a non-locked API today should return version "v1" (APIGroup, others)

In the future, when we have to add incompatible objects, we will rev the whole server endpoint (/apis.2/ etc)

The changes above mean that there is no need for internal versions to know about "unversioned" - they always have an API group they serve from (unversioned is v1). Encoding will properly fail if the type is not registered and locked into a type. We will declare that any object retrieved outside of a versioned endpoint must be added to the common/v1 package, and otherwise requires no special handling.

Examples:

/api/ returns v1 Status

/apis/ returns v1 APIGroupList

a 403 error on /api/ returns v1 Status

a 403 error on /api/v1/foo returns v1 Status

a 403 error on /apis/extensions/v1beta1/foo returns v1beta1 Status

Swagger returns v1beta1 Status for extensions that has the same schema as v1 Status

@kubernetes/sig-api-machinery

Issue 2:
Is this a request for help? (If yes, you should use our troubleshooting guide and community support channels, see http://kubernetes.io/docs/troubleshooting/.):

What keywords did you search in Kubernetes issues before filing this one? (If you have found any duplicates, you should instead reply there.):

---Handling environments like DEV, TEST, CERT, PROD

Is this a BUG REPORT or FEATURE REQUEST? (choose one):

Feature Request

Looking for an option to differentiate various environments

Kubernetes version (use kubectl version):

Environment:

Cloud provider or hardware configuration:

OS (e.g. from /etc/os-release):

Kernel (e.g. uname -a):

Install tools:

Others:

Others

What happened:

Looking for an option to handle DEV, TEST, CERT and PROD environments.

What you expected to happen:

I would like to have these environments in different clusters

How to reproduce it (as minimally and precisely as possible):

Anything else do we need to know:

Looking for best practice