Could Kubernetes Pods Ever Become Deprecated?
Tags: kubernetes, devops, api
Published: 2021-07-14 18:37:36


In any software project, over time new features and APIs are added and from time-to-time some of them also become deprecated and eventually get removed. Even huge project such as Kubernetes is no exception to this, yet core parts of its API don't really come to mind when thinking about deprecating and eventual removal. So, the question is - could a core object or API in Kubernetes, such as Pod, Deployment or Service be removed and if so, how would that go? 

## Long Story Short

If the answer to this question was _"no"_, then there would be no reason for this article, so long story short - _"yes"_ - any core API object that's in GA, for example something from `v1` API group could absolutely be deprecated.

This simple general answer doesn't tell us much though. When it comes to deprecations, Kubernetes differentiates between couple types of objects, for example REST APIs, CLIs or feature gates. Each of them with its own set of objects with different level of maturity such as alpha, beta or GA. All of this plays role in how long and under what conditions some object - even something like Pod - could be deprecated. So, let's take a bit closer look at each, as well as some examples from the past and also some hypothetical ones that could happen in future. 

## The Long Story

Different rules apply for different objects/features, so before we talk about the deprecation rules and timelines, let's first go through all the different groups of objects:

- _REST objects_ - The part that we're most interested in - REST objects or REST APIs cover all the things that we interact with most often, that is - top-level objects such as Pods or Deployment, their schema fields, e.g. `containers`, `volumes` or `env` as well as constants such `Always`, `IfNotPresent` and `Never` that are used for `imagePullPolicy`.
- _Flags or CLIs_ - The second most relevant group covers all the CLIs. The obvious one here's the `kubectl`, but it also includes things like `kubelet`, `kube-apiserver` or `kube-scheduler` as well as all their subcommands and flags.
- _Features/behaviors_ - Not everything can be exactly labeled with APIs or become part of CLI. There are also behaviours of the whole system as well as experimental features with various levels of maturity. These also need (and have) their own deprecation process and timeline.
- _Metrics_ - Finally, Kubernetes also exposes a lot of metrics on `/metrics` endpoints of various services. Considering that a lot of them are being used for example for monitoring, they also can't just be changed or removed whenever, so they have their own set of rules.

## REST Objects

For REST APIs or objects the general rule is that after deprecation is announced, API versions must be supported for at least:

- GA: 12 months or 3 releases (whichever is longer)
- Beta: 9 months or 3 releases (whichever is longer)
- Alpha: 0 releases

That sounds pretty straightforward, but there are many other (not so understandable) rules that apply here, so let's just go straight to an example, that should make it clear. Let's imagine hypothetical API object called _Task_ (fun fact - that's actually the original name of _Pods_ - see [first commit of Kubernetes](https://github.com/boddumanohar/kubernetes-first-commit/blob/2c4b3a562ce34cddc3f8218a2c4d11c7310e6d56/pkg/client/client.go#L19)). This Task is GA in API version `v1` and it's decided that it should be deprecated, so what would really happen?

| Release | API Versions                         | Preferred | Action                                                                                                      |
|---------|--------------------------------------|-----------|-------------------------------------------------------------------------------------------------------------|
| X       | v1                                   | v1        | _Task_ object is GA and non-deprecated in v1                                                                |
| X+1     | v2alpha1, v1                         | v1        | _Task_ is announced as being deprecated, v2alpha1 is introduced, _Task_ object doesn't exist in new version |
| X+2     | v2alpha2, v1                         | v1        | v2alpha1 is replaced with v2alpha2                                                                          |
| X+3     | v2beta1, v1                          | v1        | v2alpha2 is replaced with v2beta1                                                                           |
| X+4     | v2beta2, ~~v2beta1~~, v1             | v1        | v2beta2 is introduced, v2beta1 still exists, but is now deprecated                                          |
| X+5     | v2, ~~v2beta2~~, ~~v2beta1~~, ~~v1~~ | v1        | v2 is introduced, all other versions including preferred v1 are deprecated                                  |
| X+6     | v2, ~~v2beta2~~, ~~v2beta1~~, ~~v1~~ | v2        | No version are being removed yet, but v2 is now preferred version                                           |
| X+7     | v2, ~~v2beta2~~, ~~v1~~              | v2        | v2beta1 gets removed                                                                                        |
| X+8     | v2, ~~v1~~                           | v2        | v2beta2 gets removed                                                                                        |
| X+9     | v2, ~~v1~~                           | v2        | Nothing changes, v1 has to live for one more release                                                        |
| X+10    | v2                                   | v2        | v1 is finally removed and with it also _Task_ object is gone                                                |

From the above table you can see that if the _Task_ object becomes deprecated in API version `v2alpha1`, it takes another 9 releases for it to be really gone from Kubernetes. Let me also remind you, that with [current release cadence](https://github.com/kubernetes/enhancements/tree/master/keps/sig-release/2572-release-cadence) of 3 releases per year, this whole deprecation process would take more than 3 years!

You should however consider all the objects that are not GA, yet we all are using them as if they were. One such example would be Ingress, which [became GA only in 1.19](https://opensource.googleblog.com/2020/09/kubernetes-ingress-goes-ga.html) or CronJob very recently in [1.21](https://kubernetes.io/blog/2021/04/09/kubernetes-release-1.21-cronjob-ga/). In case of these kinds of beta or even alpha features the deprecation schedule wold not be so generous. If you want to check into which category some resources fall, you can run for example `kubectl api-resources | grep beta` get list of all beta API in your cluster.

Pretty much same rules apply to whole REST API object as well as its fields, constant values or object structure. This means that constants such as `Always`, `IfNotPresent` and `Never` we all use for `imagePullPolicy` won't just disappear or change randomly and in the same way fields won't move from one section to another.

As for some real world examples - _PodSecurityPolicy_ is probably the biggest one in recent history. This API object is going from v1beta1 to EOL and it's deprecated as of v1.21 and will be removed in v1.25. For details take a look at [KEP-2579](https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/2579-psp-replacement/README.md).

Another important recent/ongoing deprecation is removal of `selfLink` field. This one is part of [KEP-1164](https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1164-remove-selflink) and work on this change is also tracked in this [GitHub issue](https://github.com/kubernetes/enhancements/issues/1164).

If you're curious about what other deprecations are there, what's their rationale or their whole process of removal, then you can search [kubernetes/enhancements repository](https://github.com/kubernetes/enhancements) for mentions of _"deprecate"_ and you will find all the relevant KEPs.

## Flags or CLI

Similarly to REST objects, also `kubectl` or `kubelet` subcommands or their flags can be deprecated and therefore have its own policy.

This is much simpler than the previous case. Here, for user-facing components, such as `kubectl` the policy is:

- GA: 12 months or 2 releases (whichever is longer)
- Beta: 3 months or 1 release (whichever is longer)
- Alpha: 0 releases

and for admin-facing components, such as `kubelet`, `kube-apiserver` or `kube-scheduler` it's:

- GA: 6 months or 1 release (whichever is longer)
- Beta: 3 months or 1 release (whichever is longer)
- Alpha: 0 releases

Big recent example of deprecation in this area would be `dockershim` which is part of `kubelet`. Its deprecation and removal is outlined in following [KEP](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2221-remove-dockershim) which includes whole section for _removal plan_ which lists release v1.20 as target for deprecation as well as release v1.24 as target for removal.

Another notable change in this area is `seccomp` profiles going to GA, outlined in this [KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/135-seccomp/README.md). `seccomp` profiles aren't actually direct change to flags or any CLI, but bringing them GA requires deprecation of `kubelet` flag `--seccomp-profile-root` which is noted [here](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/135-seccomp/README.md#seccomp-root-path-configuration)

So bottom line for this section would be that deprecation timeline for CLIs is also quite generous, but if you're using some `kubectl alpha ...` command for automation, then you better check deprecations before upgrading your cluster or even CLI binary/tool.

## Feature Gates

At any point in time, Kubernetes includes many experimental features. These features are controlled using so-called _feature gates_ which are key/value pairs that we can use to turn them on or off.

Considering that feature gates are used for experimental features, their deprecation policy differs from other Kubernetes objects. Also, as the feature moves through maturity stages, the behaviour of its gate changes. For alpha features, the gate is disabled by default; for beta features it's enabled by default; and when features reaches GA status the gate is not needed anymore and becomes deprecated and non-operational.

As for the time it takes to deprecate and remove these - alpha features can disappear anytime and beta ones after 1 release if they're being removed or after 2 releases if they're moving to GA status.

For a concrete examples you can checkout full list of feature gates [here](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/). There you can see for example `AffinityInAnnotations` feature which went from alpha to deprecated, for the ones that went all the way to GA we could list e.g. `BlockVolume`, `DryRun` or `EndpointSlice`. As for the case of feature getting deprecated after getting to beta stage - I wasn't able to find any.

If you decide to turn on any of these, make sure to check for changes in their status before upgrading your cluster, especially for the alpha ones which might just be gone after a cluster upgrade.

## Metrics

Last type of an object in this list are metrics, which also need to be preserved for considerable amount of time when deprecating because a lot of them are consumed and aggregated by monitoring tooling. Unlike the ones in previous sections, metrics are split only into 2 categories. Here we have only stable and alpha metrics, where stable ones may be removed 3 releases after announced deprecation, while alpha ones can be removed anytime.

For a sample of deprecated and removed metric you can take a look at this [commit](https://github.com/kubernetes/kubernetes/pull/83836) which removes `rest_client_request_latency_seconds` metric. You can also find it in release notes of v1.17 along with bunch of other [changed/deprecated metrics](https://v1-17.docs.kubernetes.io/docs/setup/release/notes/#deprecated-changed-metrics).

If you want to find out more about metrics lifecycle and its components you can take a look at this [docs page](https://kubernetes.io/docs/concepts/cluster-administration/system-metrics/).

## Conclusion

Nowadays, it seems like many projects adopt more of a _"moving fast and breaking things"_ approach to deprecations coupled with frequent heavy handed changes, so it's nice to see big project such as Kubernetes having well thought out deprecation process that leaves a lot of time for users to migrate away from APIs and features that are planned to be removed.

So, what is a takeaway from this article? - Can anything get deprecated? - _Yes_. Should you worry about it? - _Clearly no_. With how long some of the deprecation timelines are, there's no real reason to worry about having things taken away abruptly. With that said, you should probably check release notes and keep an eye out for all the alpha features you might be using as if they were GA. You can also checkout [Deprecated API Migration Guide](https://kubernetes.io/docs/reference/using-api/deprecation-guide/) which lists all the APIs that are going to be removed at some point in future. And final note - none of this necessarily applies to CRDs - for CRDs developed by external vendors you have to check their own policies as they can do whatever they want with their applications/integration/solutions.