Kubernetes 1.27: 変更点まとめ(What's new!)とアップグレード時の注意事項

# はじめに

このエントリは、Kubernetes 1.27 の [CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.27.md) 及び[Kubernetes v1.27: Chill Vibes | Kubernetes](https://kubernetes.io/blog/2023/04/11/kubernetes-v1-27-release/#respect-podtopologyspread-after-rolling-upgrades)からWhat's new!とアップグレード時の注意事項、各変更点についてまとめたページへのリンクです。
詳細については各まとめページを参照してください。

- [Metrics Changes と SIG Instrumentation](https://qiita.com/watawuwu/items/92e849642f4477b10a20) @watawuwu
- [SIG Apps](https://qiita.com/yosshi_/items/607b4a69642d92057ef6) @yosshi_ 
- [SIG API Machinery](https://qiita.com/Ladicle/items/2ac5c4f838458161dc4c) @Ladicle 
- [SIG Auth](https://qiita.com/hiyosi/items/27a2326b5b6b42706242) @hiyosi
- [SIG CLI](https://qiita.com/superbrothers/items/16212fc088bfb2849585) @superbrothers
- [SIG Cluster Lifecycle](https://qiita.com/yuanying/items/e4df09989e76da763d9b) @yuanying
- [SIG Storage](https://qiita.com/ysakashita/items/d369f23dfe9503ac1ecb) @ysakashita 
- [SIG Network](https://qiita.com/tkusumi/items/e50129395698d2a15e73) @tkusumi
- [SIG Scheduling](https://qiita.com/ordovicia/items/6046be0f50f999cdb063) @ordovicia
- [SIG Node](https://qiita.com/y1r96/items/899e654506dcac4b3a91) @y1r96

## What's New (Major Themes)

<!-- https://github.com/kubernetes/website/blob/main/content/en/blog/_posts/2023-04-11-kubernetes-1.27-blog.md -->

<!--
# Release theme and logo

**Kubernetes v1.27: Chill Vibes**

The theme for Kubernetes v1.27 is *Chill Vibes*.

{{< figure src="/images/blog/2023-04-11-kubernetes-1.27-blog/kubernetes-1.27.png" alt="Kubernetes 1.27 Chill Vibes logo" class="release-logo" >}}


It's a little silly, but there were some important shifts in this release that helped inspire the theme. Throughout a typical Kubernetes release cycle, there are several deadlines that features need to meet to remain included. If a feature misses any of these deadlines, there is an exception process they can go through. Handling these exceptions is a very normal part of the release. But v1.27 is the first release that anyone can remember where we didn't receive a single exception request after the enhancements freeze. Even as the release progressed, things remained much calmer than any of us are used to.

There's a specific reason we were able to enjoy a more calm release this time around, and that's all the work that folks put in behind the scenes to improve how we manage the release. That's what this theme celebrates, people putting in the work to make things better for the community.

Special thanks to [Britnee Laverack](https://www.instagram.com/artsyfie/) for creating the logo. Britnee also designed the logo for [Kubernetes 1.24: Stargazer](https://kubernetes.io/blog/2022/05/03/kubernetes-1-24-release-announcement/#release-theme-and-logo).
-->

<!--
Announcing the release of Kubernetes v1.27, the first release of 2023!
This release consist of 60 enhancements. 18 of those enhancements are entering Alpha, 29 are graduating to Beta, and 13 are graduating to Stable.
-->

2023年の最初のKubernetesのリリースであるv1.27がリリースされました :tada:
このリリースは60のエンハンスメントを含みます。このうち18のエンハンスメントはalphaへ、29はBetaへ昇格し、13はStableへ昇格しました。

### Freeze k8s.gcr.io image registry 

<!--
Replacing the old image registry, [k8s.gcr.io](https://cloud.google.com/container-registry/) with [registry.k8s.io](https://github.com/kubernetes/registry.k8s.io) which has been generally available for several months. The Kubernetes project created and runs the `registry.k8s.io` image registry, which is fully controlled by the community.
This means that the old registry `k8s.gcr.io` will be frozen and no further images for Kubernetes and related sub-projects will be published to the old registry. 

What does this change mean for contributors?

* If you are a maintainer of a sub-project, you will need to update your manifests and Helm charts to use the new registry. For more information, checkout this [project](https://github.com/kubernetes-sigs/community-images).

What does this change mean for end users?

* Kubernetes `v1.27` release will not be published to the `k8s.gcr.io` registry.

* Patch releases for `v1.24`, `v1.25`, and `v1.26` will no longer be published to the old registry after April. 

* Starting in v1.25, the default image registry has been set to `registry.k8s.io`. This value is overridable in kubeadm and kubelet but setting it to `k8s.gcr.io` will fail for new releases after April as they won’t be present in the old registry.

* If you want to increase the reliability of your cluster and remove dependency on the community-owned registry or you are running Kubernetes in networks where external traffic is restricted, you should consider hosting local image registry mirrors. Some cloud vendors may offer hosted solutions for this.
-->

古いイメージレジストリである[k8s.gcr.io](https://cloud.google.com/container-registry/)を数ヶ月前GAとなった[registry.k8s.io](https://github.com/kubernetes/registry.k8s.io)へ置き換えます。Kubernetesプロジェクトはコミュニティーにより完全にコントロールされる`registry.k8s.io`イメージレジストリを作成し、運営しています。
これは古いレジストリである`k8s.gcr.io`は凍結される予定であり、これ以上Kubernetesや関連するサブプロジェクトのためのイメージは古いレジストリへ公開されないことを意味しています。

##### この変更がコントリビュータにとって何を意味するのか？

- サブプロジェクトのメンテナーである場合、マニフェストとHelmチャートを新しいレジストリを利用するように更新してください。詳細は、この[プロジェクト](https://github.com/kubernetes-sigs/community-images)を確認してください。

##### この変更はエンドユーザにとって何を意味するのか？

- Kubernetes`v1.27`のリリースは`k8s.gcr.io`レジストリで公開されません。
- `v1.24`, `v1.25`, そして`v1.26`のためのパッチリリースは4月以降古いレジストリへ公開されなくなります。
- v1.25からデフォルトイメージレジストリは`registry.k8s.io`へセットされます。この値はkubeadmやkubeletで`k8s.gcr.io`へ上書きすると、4月以降の新しいリリースでは古いレジストリに存在しないため失敗します。
- クラスタの信頼性を向上させるためコミュニティが所有するレジストリへの依存を排除したい場合、または外部トラフィックが制限されたネットワークでKubernetesを運用している場合、ローカルのイメージレジストリーのミラーを検討すべきです。いくつかのクラウドベンダーはこのためにホスティングソリューションを提供している場合があります。

### `SeccompDefault` graduates to stable

<!--
## `SeccompDefault` graduates to stable

To use seccomp profile defaulting, you must run the kubelet with the `--seccomp-default` [command line flag](/docs/reference/command-line-tools-reference/kubelet) enabled for each node where you want to use it. 
If enabled, the kubelet will use the `RuntimeDefault` seccomp profile by default, which is defined by the container runtime, instead of using the `Unconfined` (seccomp disabled) mode. The default profiles aim to provide a strong set of security defaults while preserving the functionality of the workload. It is possible that the default profiles differ between container runtimes and their release versions.

You can find detailed information about a possible upgrade and downgrade strategy in the related Kubernetes Enhancement Proposal (KEP): [Enable seccomp by default](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2413-seccomp-by-default).
-->

seccomp profile defaultingを利用するには、kubeletで`--seccomp-default`[コマンドラインフラグ](/docs/reference/command-line-tools-reference/kubelet)を利用したいそれぞれのノードで有効化しなければなりません。
有効化された場合、kubeletは`Unconfined`(seccompが無効)を利用する代わりに、コンテナランタイムにより定義されている`RuntimeDefault` seccomp profileをデフォルトで利用します。デフォルトのプロファイルの目的はワークロードの機能は維持しつつ、強固なセキュリティのデフォルトを提供することです。デフォルトのプロファイルはコンテナランタイムやそれらのリリースバージョンにより異なる可能性があります。

可能なアップグレードやダウングレードの方法については、関連するKubernetes Enhancement Proposal (KEP)である[Enable seccomp by default](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2413-seccomp-by-default)で詳細情報を確認できます。

- :pencil: v1.24まではPSPによりRuntimeDefaultがPodのSpecへMutatingすることで、この機能を実現できていました。PSPの廃止されたv1.25でSeccompDefaultがbetaとなりましたが、v1.27でstableになりました。
- :pencil: SeccompDefaultの詳細を知りたい方は、[KubernetesのSeccompDefaultを試した - Qiita](https://qiita.com/uesyn/items/3fc1b25eafa0939aebb8)も併せてご確認ください。

### Mutable scheduling directives for Jobs graduates to GA

<!--
This was introduced in v1.22 and started as a beta level, now it's stable. In most cases a parallel job will want the pods to run with constraints, like all in the same zone, or all either on GPU model x or y but not a mix of both. The `suspend` field is the first step towards achieving those semantics. `suspend` allows a custom queue controller to decide when a job should start. However, once a job is unsuspended, a custom queue controller has no influence on where the pods of a job will actually land.

This feature allows updating a Job's scheduling directives before it starts, which gives custom queue controllers
the ability to influence pod placement while at the same time offloading actual pod-to-node assignment to
kube-scheduler. This is allowed only for suspended Jobs that have never been unsuspended before.
The fields in a Job's pod template that can be updated are node affinity, node selector, tolerations, labels
,annotations, and [scheduling gates](/docs/concepts/scheduling-eviction/pod-scheduling-readiness/).
Find more details in the KEP:
[Allow updating scheduling directives of jobs](https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/2926-job-mutable-scheduling-directives).
-->

これはv1.22で導入されbetaレベルとして開始され、現在それはstableです。多くの場合、並列ジョブはポッドを同じゾーンで動作させるか、GPUモデルのxかyのどちらかで動作させ、両方を混在させないといった制約が必要です。`suspend`フィールドはこれらのセマンティクスを達成するための最初のステップです。`suspend`はカスタムキューコントローラがいつJobをスタートすべきか決定できるようにします。しかしながら、一度Jobがsuspendを解除されると、カスタムキューコントローラはJobのPodが実際に起動される場所に影響を与えることができません。

この機能はJobのスタート前にスケジューリングディレクティブを更新できるようにし、実際のPodをノードへアサインはkube-schedulerへオフロードしますが、カスタムキューコントローラがPodの配置に影響を与えることができるようにします。これはsuspendされ一度もsuspendを解除されていないJobだけに許されています。
Jobのpod templateのフィールドでnode affinity, node selector, toleration, label, annotation, [scheduling gates](/docs/concepts/scheduling-eviction/pod-scheduling-readiness/)が更新可能です。
詳細はKEPをご確認ください: [Allow updating scheduling directives of jobs](https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/2926-job-mutable-scheduling-directives).

### DownwardAPIHugePages graduates to stable 

<!--
In Kubernetes v1.20, support for `requests.hugepages-<pagesize>` and `limits.hugepages-<pagesize>` was added
to the [downward API](/docs/concepts/workloads/pods/downward-api/) to be consistent with other resources like cpu, memory, and ephemeral storage.
This feature graduates to stable in this release. You can find more details in the KEP:
[Downward API HugePages](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2053-downward-api-hugepages).
-->

Kubernetes v1.20で`requests.hugepages-<pagesize>`と`limits.hugepages-<pagesize>`がサポートされ、他のcpu, memory, ephemeral storageのようなリソースと整合性を取るために[downward API](/docs/concepts/workloads/pods/downward-api/)へ追加されました。この機能はこのリリースでstableへ昇格しました。
詳細はKEPをご確認ください: 
[Downward API HugePages](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2053-downward-api-hugepages).

### Pod Scheduling Readiness goes to beta 

<!--
Upon creation, Pods are ready for scheduling. Kubernetes scheduler does its due diligence to find nodes to place all pending Pods. However, in a real-world case, some Pods may stay in a _missing-essential-resources_ state for a long period. These Pods actually churn the scheduler (and downstream integrators like Cluster Autoscaler) in an unnecessary manner.

By specifying/removing a Pod's `.spec.schedulingGates`, you can control when a Pod is ready to be considered for scheduling.

The `schedulingGates` field contains a list of strings, and each string literal is perceived as a criteria that must be satisfied before a Pod is considered schedulable. This field can be initialized only when a Pod is created (either by the client, or mutated during admission). After creation, each schedulingGate can be removed in an arbitrary order, but addition of a new scheduling gate is disallowed.
-->

Podを作成すると、Podはスケジュールできる状態となる。Kubernetes schedulerは全てのpendingのPodを配置するためのノードを見つけるために努力します。しかしながら、現実の場合、いくつかのPodはしばらくの間必要不可欠なリソースの不足の状態のままとなっていることがあります。これらのPodは不必要な方法でスケジューラ(やCluster Autoscalerのような下流のインテグレータ)を混乱させます。

Podの`.spec.schedulingGates`を指定・削除することで、Podがスケジュールされても良いタイミングをコントロールできます。

`schedulingGates` フィールドは文字列のリストを含み、それぞれの文字列リテラルはPodがスケジューラブルと考慮される前に満たされなければならない基準として認知されます。このフィールドはPod作成時にのみ初期化できます(クライアントもしくはadmissionの間の変更されます)。作成後、schedulingGateの中身は任意の順序で削除可能ですが追加は許可されていません。

### Node log access via Kubernetes API

<!--
This feature helps cluster administrators debug issues with services running on nodes by allowing them to query service logs. To use this feature, ensure that the `NodeLogQuery` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled on that node, and that the kubelet configuration options `enableSystemLogHandler` and `enableSystemLogQuery` are both set to true. 
On Linux, we assume that service logs are available via journald. On Windows, we assume that service logs are available in the application log provider. You can also fetch logs from the `/var/log/` and `C:\var\log` directories on Linux and Windows, respectively.

A cluster administrator can try out this alpha feature across all nodes of their cluster, or on a subset of them.
-->

この機能はクラスタ管理者がサービスのログのクエリを許可することにより、ノード上に稼働するサービスの問題をデバッグします。この機能を利用するために、`NodeLogQuery` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)がノード上で有効化され、kubeletの設定で`enableSystemLogHandler`と`enableSystemLogQuery`がtrueへセットされている必要があります。
Linux上ではjounald経由でサービスログが利用可能であることを想定しています。Windows上ではapplication log providerで利用可能なサービスログを想定しています。またLinuxでは`/var/log`、Windowsでは`C:\var\log`ディレクトリからログを取得できます。

クラスタ管理者はクラスタの全て、またはそのサブセットのノードでこのアルファ機能を試すことができます。

- :pencil: さらっとノードのログを確認したい時に便利そうですね！

### ReadWriteOncePod PersistentVolume access mode goes to beta 

<!--
Kuberentes `v1.22` introduced a new access mode `ReadWriteOncePod` for [PersistentVolumes](/docs/concepts/storage/persistent-volumes/#persistent-volumes) (PVs) and [PersistentVolumeClaims](/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) (PVCs). This access mode enables you to restrict volume access to a single pod in the cluster, ensuring that only one pod can write to the volume at a time. This can be particularly useful for stateful workloads that require single-writer access to storage.

The ReadWriteOncePod beta adds support for [scheduler preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/)
of pods that use ReadWriteOncePod PVCs.
Scheduler preemption allows higher-priority pods to preempt lower-priority pods. For example when a pod (A) with a `ReadWriteOncePod` PVC is scheduled, if another pod (B) is found using the same PVC and pod (A) has higher priority, the scheduler will return an `Unschedulable` status and attempt to preempt pod (B).
For more context, see the KEP: [ReadWriteOncePod PersistentVolume AccessMode](https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/2485-read-write-once-pod-pv-access-mode).
-->

Kubernetes v1.22で[PersistentVolumes](/docs/concepts/storage/persistent-volumes/#persistent-volumes)(PV)と[PersistentVolumeClaims](/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims)(PVC)のための新しいアクセスモードである`ReadWriteOncePod`を導入しました。このアクセスモードでは、クラスター内の単一のPodにボリュームアクセスを制限し、一度に1つのPodのみがボリュームに書き込めるようにします。これは、ストレージへのシングルライター・アクセスを必要とするステートフルなワークロードに特に有用です。

ReadWriteOncePodのbetaではReadWriteOncePodのPVCを利用するPodの[scheduler preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/)のサポートを追加しました。
Scheduler preemptionはより高いプライオリティのPodがより低いプライオリティのPodをpreemptionできるようにします。例えば、`ReadWriteOncePod`のPVCを持つPod(A)スケジュールされる時、他のPod(B)が同じPVCを利用があり、かつPod(A)の方がプライオリティが高い場合、schedulerは`Unschedulable`ステータスを返し、Pod(B)をpreemptionしようと試みます。
詳細はKEPをご参照ください: [ReadWriteOncePod PersistentVolume AccessMode](https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/2485-read-write-once-pod-pv-access-mode)

### Respect PodTopologySpread after rolling upgrades

<!--
`matchLabelKeys` is a list of pod label keys used to select the pods over which spreading will be calculated. The keys are used to lookup values from the pod labels. Those key-value labels are ANDed with `labelSelector` to select the group of existing pods over which spreading will be calculated for the incoming pod. Keys that don't exist in the pod labels will be ignored. A null or empty list means only match against the `labelSelector`.

With `matchLabelKeys`, users don't need to update the `pod.spec` between different revisions. The controller/operator just needs to set different values to the same `label` key for different revisions. The scheduler will assume the values automatically based on `matchLabelKeys`. For example, if users use Deployment, they can use the label keyed with `pod-template-hash`, which is added automatically by the Deployment controller, to distinguish between different revisions in a single Deployment.
-->

`matchLabelKeys`はPodのラベルキーのリストで拡散を計算するPodを選択するために利用されます。それらのキーはPodラベルから値を調べるために利用されます。これらのキーと値のラベルは `labelSelector` とANDして、これから作成されるPodに対して拡散を計算する対象となる既存のPodのグループを選択します。キーを持たないPodは無視されます。nullまたは空のリストは`labelSelector`に対してのみマッチする ことを意味します。

`matchLabelKeys`を用いると、異なるリビジョン間でユーザは`pod.spec`を更新する必要がありません。controllerやoperatorは異なるリビジョンで同じ`label`キーに異なる値をセットすることだけが求められます。例えば、ユーザーがDeploymentを使用する場合、Deploymentコントローラによって自動的に追加される`pod-template-hash`をキーとするラベルを使用して、1つのDeploymentの異なるリビジョンを区別することができます。

- :pencil: これによりローリングアップグレード時にskewが発生する問題が解消しそうですね！嬉しい！

### Faster SELinux volume relabeling using mounts

<!--
In this release, how SELinux labels are applied to volumes used by Pods is graduating to beta. This feature speeds up container startup by mounting volumes with the correct SELinux label instead of changing each file on the volumes recursively. Linux kernel with SELinux support allows the first mount of a volume to set SELinux label on the whole volume using `-o context=` mount option. This way, all files will have assigned the given label in a constant time, without recursively walking through the whole volumes.

The `context` mount option cannot be applied to bind mounts or re-mounts of already mounted volumes.
For CSI storage, a CSI driver does the first mount of a volume, and so it must be the CSI driver that actually
applies this mount option. We added a new field `SELinuxMount` to CSIDriver objects, so that drivers can
announce whether they support the `-o context` mount option.

If Kubernetes knows the SELinux label of a Pod **and** the  CSI driver responsible for a pod's volume
announces `SELinuxMount: true` **and** the volume has Access Mode `ReadWriteOncePod`, then it
will ask the CSI driver to mount the volume with mount option `context=` **and** it will tell the container
runtime not to relabel content of the volume (because all files already have the right label).
Get more information on this from the KEP: [Speed up SELinux volume relabeling using mounts](https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1710-selinux-relabeling).
-->

このリリースで、Podが利用するボリュームへSELinuxラベルを適用する方法がbetaへ昇格しました。この機能は再帰的のボリューム上のそれぞれのファイルを変更する代わりに、正しいSELinuxラベルマウントすることでコンテナの起動の高速化します。SELinuxをサポートするLinux kernelは、初回のボリュームマウントで`-o context=`マウントオプションを利用することでボリューム全体へSELinuxラベルをセットできるようにあします。この方法により、全てのファイルは与えられたラベルを一定の時間で割り当てられ、ボリューム全体を通して再帰的に処理する必要がなくなりました。

`context`マウントオプションはbind mountまたはすでにマウントされたボリュームの再マウントには適用できません。
CSIストレージでは、CSI driverはボリュームの初回マウントを実施するため、このマウントオプションをCSI driverが適用しなければなりません。新しいフィールドである`SELinuxMount`をCSIDriverオブジェクトへ追加され、driverが`-o context`マウントオプションをサポートしているかどうかをアナウンスできます。

KubernetesがPodのSELinuxラベルを知っており、Podのボリュームに責任を持つCSI driverが`SELinuxMount: true`をアナウンスしており、ボリュームが`ReadWriteOncePod`のアクセスモードを持つ場合、KubernetesはCSI driverへ`context=`マウントオプションを付与した状態でボリュームをマウントするようリクエストし、コンテナランタイムがボリュームのコンテンツを再ラベルしないように伝えます(なぜなら全てのファイルはすでに正しいラベルをもつため)。
より詳細を確認したい場合はKEPをご参照ください: [Speed up SELinux volume relabeling using mounts](https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1710-selinux-relabeling)

### Robust VolumeManager reconstruction goes to beta

<!--
This is a volume manager refactoring that allows the kubelet to populate additional information about how
existing volumes are mounted during the kubelet startup. In general, this makes volume cleanup more robust. 
If you enable the `NewVolumeManagerReconstruction` feature gate on a node, you'll get enhanced discovery of mounted volumes during kubelet startup.

Before Kubernetes v1.25, the kubelet used different default behavior for discovering mounted volumes during the kubelet startup. If you disable this feature gate (it's enabled by default), you select the legacy discovery behavior.

In Kubernetes v1.25 and v1.26, this behavior toggle was part of the `SELinuxMountReadWriteOncePod` feature gate.
-->

これはvolume managerのリファクタリングで、kubeletが起動中に既存のボリュームがマウントされている方法の追加情報を入手できるようにするものです。一般的に、この変更はボリュームのcleanupをより強固にします。
`NewVolumeManagerReconstruction` feature gateがノード上で有効化されている場合、kubelet起動時にマウントされたボリュームの検出が強化されます。

Kubernetes v1.25より前では、kubeletは起動中にマウントされたボリュームを検出するために異なるデフォルト動作を利用していました。
このfeature gateが無効化されると(デフォルトは有効)、古いディスカバリの動作を選択することとなります。

Kubernetes v1.25とv1.26では、この動作の切り替えは`SELinuxMountReadWriteOncePod` feature gateの一部となっていました。

## Mutable Pod Scheduling Directives goes to beta

<!--
This allows mutating a pod that is blocked on a scheduling readiness gate with a more constrained node affinity/selector. It gives the ability to mutate a pods scheduling directives before it is allowed to be scheduled and gives an external resource controller the ability to influence pod placement while at the same time offload actual pod-to-node assignment to kube-scheduler.

This opens the door for a new pattern of adding scheduling features to Kubernetes.  Specifically, building lightweight schedulers that implement features not supported by kube-scheduler, while relying on the existing kube-scheduler to support all upstream features and handle the pod-to-node binding. This pattern should be the preferred one if the custom feature doesn't require implementing a schedule plugin, which entails re-building and maintaining a custom kube-scheduler binary.
-->

これによりscheduling readiness gateでブロックされたPodをより制約の多いノードのaffinity/selectorでmutatingできるようになります。Podがスケジュールされるのを許可される前に、Podのスケジューリングディレクティブを変更できるようになり、kube-schedulerがPodをNodeへ割り当てる時、外部のリソースコントローラがPodの配置へ影響を与えることができるようになりました。

これはKubernetesへ新しいスケジューリング機能のパターンの扉を開くものです。特に、アップストリームの全ての機能をサポートし、PodをNodeへのバインディングを処理する既存のkube-schedulerへ依存しながら、kube-schedulerによってサポートされていない機能を実装した軽量なスケジューラを構築できます。カスタムのkube-schedulerバイナリのリビルドやメンテナンスを伴うschedule pluginの実装を必要としない場合、このパターンは好ましい方法となるでしょう。

## Feature graduations and deprecations in Kubernetes v1.27

### Graduations to stable

このリリースでは合計9つのエンハンスメントがStableへ昇格しました。

* [Default container annotation that to be used by kubectl](https://github.com/kubernetes/enhancements/issues/2227)
* [TimeZone support in CronJob](https://github.com/kubernetes/enhancements/issues/3140)
* [Expose metrics about resource requests and limits that represent the pod model](https://github.com/kubernetes/enhancements/issues/1748)
* [Server Side Unknown Field Validation](https://github.com/kubernetes/enhancements/issues/2885)
* [Node Topology Manager](https://github.com/kubernetes/enhancements/issues/693)
* [Add gRPC probe to Pod.Spec.Container.{Liveness,Readiness,Startup} Probe](https://github.com/kubernetes/enhancements/issues/2727)
* [Add configurable grace period to probes](https://github.com/kubernetes/enhancements/issues/2238)
* [OpenAPI v3](https://github.com/kubernetes/enhancements/issues/2896)
* [Stay on supported Go versions](https://github.com/kubernetes/enhancements/issues/3744)

### Deprecations and removals

このリリースではいくつかの機能の削除も含みます。

* [Removal of `storage.k8s.io/v1beta1` from CSIStorageCapacity](https://github.com/kubernetes/kubernetes/pull/108445)
* [Removal of support for deprecated seccomp annotations](https://github.com/kubernetes/kubernetes/pull/114947)
* [Removal of `--master-service-namespace` command line argument](https://github.com/kubernetes/kubernetes/pull/112797)
* [Removal of the `ControllerManagerLeaderMigration` feature gate](https://github.com/kubernetes/kubernetes/pull/113534)
* [Removal of `--enable-taint-manager` command line argument](https://github.com/kubernetes/kubernetes/pull/111411)
* [Removal of `--pod-eviction-timeout` command line argument](https://github.com/kubernetes/kubernetes/pull/113710)
* [Removal of the `CSI Migration` feature gate](https://github.com/kubernetes/kubernetes/pull/110410)
* [Removal of `CSIInlineVolume` feature gate](https://github.com/kubernetes/kubernetes/pull/111258)
* [Removal of `EphemeralContainers` feature gate](https://github.com/kubernetes/kubernetes/pull/111402)
* [Removal of `LocalStorageCapacityIsolation` feature gate](https://github.com/kubernetes/kubernetes/pull/111513)
* [Removal of `NetworkPolicyEndPort` feature gate](https://github.com/kubernetes/kubernetes/pull/110868)
* [Removal of `StatefulSetMinReadySeconds` feature gate](https://github.com/kubernetes/kubernetes/pull/110896)
* [Removal of `IdentifyPodOS` feature gate](https://github.com/kubernetes/kubernetes/pull/111229)
* [Removal of `DaemonSetUpdateSurge` feature gate](https://github.com/kubernetes/kubernetes/pull/111194)

## Known Issues

### The PreEnqueue extension point doesn't work for Pods going to activeQ through backoffQ

<!--
The PreEnqueue extension point doesn't work for Pods going to activeQ through backoffQ
In v1.26.0, we've found the bug that the PreEnqueue extension point doesn't work for Pods going to activeQ through backoffQ. It doesn't affect any of the vanilla Kubernetes behavior, but, may break custom PreEnqueue plugins.

The cause PR is reverted by v1.26.1.
-->

1.27.0において、私たちはPreEnqueue拡張ポイントがbackoffQを経由してactiveQに移行するPodに対して機能しないバグを発見しました。これは、バニラKubernetesの動作には影響を与えませんが、カスタムPreEnqueueプラグインを壊す可能性があります。

[原因のPull Request](https://github.com/kubernetes/kubernetes/pull/117194)はv1.27.1によって元に戻されました。

## Urgent Upgrade Notes 

### (No, really, you MUST read this before you upgrade)

<!--
- 'The `IPv6DualStack` feature gate for external cloud providers was removed.

  (The feature became GA in 1.23 and the gate was removed for all other components several releases ago.) If you were still manually enabling it you must stop now.' ([#116255](https://github.com/kubernetes/kubernetes/pull/116255), [@danwinship](https://github.com/danwinship))

- Give terminal phase correctly to all pods that will not be restarted. 

  In particular, assign Failed phase to pods which are deleted while pending. Also, assign a terminal phase (Succeeded or Failed, depending on the exit statuses of the pod containers) to pods which are deleted while running.

  This fixes the issue for jobs using pod failure policy (with JobPodFailurePolicy and PodDisruptionConditions feature gates enabled) that their pods could get stuck in the pending phase when deleted.

  Users who maintain controllers which relied on the fact that pods with RestartPolicy=Always never enter the Succeeded phase may need to adapt their controllers. This is because as a consequence of the change pods which use RestartPolicy=Always may end up in the Succeeded phase in two scenarios: pod deletion and graceful node shutdown. ([#115331](https://github.com/kubernetes/kubernetes/pull/115331), [@mimowo](https://github.com/mimowo)) [SIG Cloud Provider, Node and Testing]
-->

- external cloud providerのための`IPv6DualStack` feature gateは削除されました。

  (この機能はv1.23でGAとなり、他の全てのコンポーネントについては数リリース前にゲートが削除されました。)
  もし手動で有効にしているなら、すぐに止めなければなりません。([#116255](https://github.com/kubernetes/kubernetes/pull/116255), [@danwinship](https://github.com/danwinship))

- 再起動されない全てのPodへ正しくterminal phaseを与えます。

  特に、Pending中に削除されたPodへFailed phaseを割り当てます。また、terminal phase(SucceededまたはFailed, Podのコンテナのexit statusに依存)をrunning中に削除されたPodへ割り当てます。
  これはpod failure policy(JobPodFailurePolicyとPodSDisruptionConditions feature gateの有効な場合)を利用するJobにおいて、Podが削除時にpending phaseでスタックする問題を修正します。
  RestartPolicy=Alwaysが設定されたPodは決してSucceeded phaseへ入らないという事実に依存しているコントローラをメンテナンスしているユーザは、それらのコントローラを対応する必要があるかもしれません。これは、RestartPolicy=Alwaysを使用するPodが、Pod削除とgraceful node shutdownの2つのシナリオでSucceededフェーズに入る可能性があるためです。([#115331](https://github.com/kubernetes/kubernetes/pull/115331), [@mimowo](https://github.com/mimowo)) [SIG Cloud Provider, Node and Testing]