はじめに
このページではKubernetes v1.26 における SIG-Apps に関連する変更内容をまとめています。
SIG-AppsはKubernetesのワークロードの扱いなどの変更を主に扱っているため、他のSIGと関係する変更が多くなっております。
- 直近での過去の変更内容は以下になります。
SIG / SIG-Apps とは?
-
SIGとは?
- Special Interest Groups の略称
- 各 SIG には Subproject が与えられていて、 Subproject に対して独立して開発できるようになっています。
- Kubernetes は巨大なプロジェクトなので、各SIG 毎に担当(Subproject)が割り当てられていて、各SIG は独立して開発をしています。
- SIG 間を跨って話し合いをする必要が生じた場合は Working Groups が一時的に作られ、その枠組みの中で話し合うことになります。
-
SIG-Appsとは?
- Apps Special Interest Group の略称
- Kubernetes に対して、application を deploy したりすることに関することが対象。具体的には Pod, ReplicaSet, Deployments, DaemonSet, StatefulSet, Jobs, CronJob が対象。
- 詳細について知りたい方はこちらをご参照ください。
SIG-Apps 以外の SIG に関する変更は以下にまとめてありますので、合わせてご参照下さい。
注目の変更
Feature Gatesの中で今回Stageに変更のあったSig-Appsに関連する機能は以下になります。
- Pod
-
PDBUnhealthyPodEvictionPolicy
:Alpha
https://github.com/kubernetes/enhancements/issues/3017 -
PodDisruptionConditions
:Beta
https://github.com/kubernetes/enhancements/issues/3329
-
- Job
-
JobPodFailurePolicy
:Beta
https://github.com/kubernetes/enhancements/issues/3329
-
- StatefulSet
-
StatefulSetStartOrdinal
:Alpha
https://github.com/kubernetes/enhancements/issues/3335
-
上記のうちで今回追加されたPDBUnhealthyPodEvictionPolicy
とStatefulSetStartOrdinal
についてもう少し詳しく記載します。その他の機能については、過去のSIG-Apps の変更内容をご確認下さい。
Pod
Unhealthy Pod Eviction Policy
Pod の状態が .status.phase="Running"
ではあるが、Ready
出ない時の状態の挙動を PodDisruptionBudget を指定できるようになりました。
- 関連情報
KEP | KEP-3017 |
---|---|
Feature stage | Alpha |
Feature Gate | PDBUnhealthyPodEvictionPolicy |
issue | #3017 |
PR | #104915 |
参考 | 公式ドキュメント |
詳しい内容の説明 (クリックすると開きます)
PodDisruptionBudget
では対象となる Pod の .status.conditions
が type="Ready"
かつ status="True"
である数を .status.currentHealthy
としてカウントしており、 .status.desiredHealthy
で指定されている数より対象の Pod 数が下回らないように evict の要求を拒否します。
$ kubectl get pod <Pod 名> -o yaml
:
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2022-12-20T05:42:26Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2022-12-20T05:42:32Z"
+ status: "True"
+ type: Ready
:
$ kubectl get pdb <PDB 名> -o yaml
:
status:
conditions:
- lastTransitionTime: "2022-12-20T06:24:18Z"
message: ""
observedGeneration: 1
reason: SufficientPods
status: "True"
type: DisruptionAllowed
+ currentHealthy: 3
+ desiredHealthy: 2
disruptionsAllowed: 1
expectedPods: 3
observedGeneration: 1
:
この時に PodDisruptionBudget
に新しく追加された .spec.unhealthyPodEvictionPolicy
フィールドを使用することで .status.phase="Running"
であるが、Ready
でない状態の Pod を evict の要求が来た際にどうするか制御できるようになります。
-
IfHealthyBudget (未指定の場合のデフォルトの動作)
.status.phase="Running"
かつReady
でない Pod については以下の状態を満たす場合に evict の対象となります。
.status.currentHealthy
>=.status.desiredHealthy
-
AlwaysAllow
.status.phase="Running"
かつReady
でない Pod については無条件で evict の対象になります。
.spec.unhealthyPodEvictionPolicy="AlwaysAllow"
の選択肢が増えたことにより、PDB 設定時に .status.phase="Running"
であるが、Ready
でない状態の Pod によって、evict がデットロックするケースを回避する選択肢が得られるようになりました。
設定のイメージは以下
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: nginx
spec:
maxUnavailable: 25%
selector:
matchLabels:
app: nginx
+ unhealthyPodEvictionPolicy: AlwaysAllow
StatefulSet
StatefulSet Slice
StatefulSet で管理されている Pod 名に付与される index は 0
からの昇順で付与されますが、指定した任意の値から付与さえるように設定できます。
- 関連情報
KEP | KEP-3335 |
---|---|
Feature stage | Alpha |
Feature Gate | StatefulSetStartOrdinal |
issue | #3335 |
PR | #112744 |
参考 | 公式ドキュメント |
詳しい内容の説明 (クリックすると開きます)
StatefulSet が管理する Pod に付与される index は 0 〜 (spec.replicas
-1) の間で付与されていましたが、新しく追加された spec.ordinals.start
を使用すると index が spec.ordinals.start
〜 (spec.ordinals.start
+ spec.replicas
-1) の間で付与されるようになります。
以下に spec.ordinals.start
を使用した際の例を記載します。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 3
+ ordinals:
+ start: 4
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:latest
$ kubectl get po
NAME READY STATUS RESTARTS AGE
+web-4 1/1 Running 0 4s
+web-5 1/1 Running 0 3s
+web-6 0/1 ContainerCreating 0 2s
今までの StatefulSet では Pod 名が web-0
から順番に作成されるところ、 spec.ordinals.start
が機能して、 web-4
から順次作成されることが確認できます。
この機能を使用することで、現在起動しているアプリケーションを同一クラスタ内の別の namespace に移行したり、別の Kubernetes クラスタへ移行する際の選択肢が増えます。
また、StatefulSet を制御する Operator (e.g. ReplicaSet に対する Deployment) でローリングアップデートする際に現状よりも柔軟な設定が可能になると思います。
現状では以下のような replicas が 9 の StatefulSet を今回の機能を用いて、3つの StatefulSet に分割しようとすると
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
namespace: sts-slice
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 9
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
$ kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
sts-slice web-0 1/1 Running 0 96s
sts-slice web-1 1/1 Running 0 94s
sts-slice web-2 1/1 Running 0 93s
sts-slice web-3 1/1 Running 0 92s
sts-slice web-4 1/1 Running 0 91s
sts-slice web-5 1/1 Running 0 90s
sts-slice web-6 1/1 Running 0 20m
sts-slice web-7 1/1 Running 0 20m
sts-slice web-8 1/1 Running 0 20m
以下の制限があるので、StatefuSet の Namespace を分ける必要があります。
-
同一 Namespace 内に存在する StatefulSet の名前はユニークになる
-
Each Pod in a StatefulSet derives its hostname from the name of the StatefulSet and the ordinal of the Pod.
StatefulSet が管理する Pod の hostname は StatefulSet の名前と ordinal によって決まる
ref : https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-network-id
そのため、、以下のように同一の StatefulSet 名で Namespace
,replicas
,ordinals.start
の異なる Manifest を作成します。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
+ namespace: sts-slice1
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
+ replicas: 3
ordinals:
+ start: 0
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
+ namespace: sts-slice2
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
+ replicas: 3
ordinals:
+ start: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
+ namespace: sts-slice3
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
+ replicas: 3
ordinals:
+ start: 6
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
そうすると、以下のように StatefulSet を分割することができるようになります。
$ kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
sts-slice1 web-0 1/1 Running 0 10s
sts-slice1 web-1 1/1 Running 0 8s
sts-slice1 web-2 1/1 Running 0 7s
sts-slice2 web-3 1/1 Running 0 10s
sts-slice2 web-4 1/1 Running 0 9s
sts-slice2 web-5 1/1 Running 0 7s
sts-slice3 web-6 1/1 Running 0 10s
sts-slice3 web-7 1/1 Running 0 8s
sts-slice3 web-8 1/1 Running 0 6s
v1.26 Release Notes
v1.26 Release Notes の中で SIG-Apps に関するものについて以下に和訳したものを記載します。
がついた文章は、CHANGELOGの公式内容ではなく筆者の補足です。
Deprecation(非推奨)
- CLI フラグの
pod-eviction-timeout
は非推奨となりenable-taint-manager
と一緒に v1.27 削除予定となります。 (#113710, @kerthcet)
API Changes(API変更)
-
scheduler のコンポーネントのコンフィグ
v1beta2/v1beta3/v1
にpreEnqueue
extension point が追加されました。
(#113275, @Huang-Wei) -
DynamicResourceAllocation
feature gate を有効化して使用できるようになるresource.k8s.io/v1alpha1
API group にResourceClaim
API が追加されました。この新しい API は既存のデバイスプラグインをよりフレキシブルに使用するための機能で、Pod に特別なリソースのリクエストを許可し、ノードレベルで利用できるようにします。
(#111023, @pohly)- k8s v1.26 であたらに追加されたDynamic Resource Allocationに関する追加になります。
- KEP見たところ、通常の Pod では CPU/Memory をリクエストして設定しますが、それに加えて FPGA や GPU などのリソースを使用したい時などの利用を想定して追加された機能のようです。
-
コンテナの
preStop
とpostStart
lifecycle handlers でhttpGet
を使用する場合に指定したscheme
とheaders
フィールドを優先するようになりました。この設定によりカスタムの headers を設定したり startup/readiness/liveness probe と一貫性を持つように scheme をHTTPS
に変更することができるようになります。Lifecycle handlers で設定されたscheme: HTTPS
エラーに遭遇すると以前の互換性を保つために HTTP によるリクエストを実施します。それが起こった時には Pod の namespace にLifecycleHTTPFallback
イベントして記録され、kubelet にkubelet_lifecycle_handler_http_fallbacks_total
メトリクスとしてインクリメントされます。クラスタの管理者は kubelet に--feature-gates=ConsistentHTTPGetHandlers=false
と設定することで無効化できるようになります。(#86139, @jasimmons)-
preStop/postStart
でhttpGet
を利用時にhttpHeaders
の設定が優先されるようになったようです。利用イメージとしては以下のような感じですね。lifecycle: postStart: httpGet: port: 80 + httpHeaders: + - name: {HEADER} + value: {VALUE}
$ kubectl explain pod.spec.containers.lifecycle.preStop.httpGet : FIELDS: httpHeaders <[]Object> Custom headers to set in the request. HTTP allows repeated headers. :
-
通常は新しい機能は feature-gates で有効化しないと使えないのですが、今回は有効化の状態で提供されて
--feature-gates=ConsistentHTTPGetHandlers=false
で無効化ができるようです。
-
-
JobTrackingWithFinalizers
が stable になりました。この機能を有効化する前に作成された Job が finalizers がない状態で追跡されます。finalizers で追跡される Job には batch.kubernetes.io/job-tracking のアノテーションがあります。もし、現在アノテーションがついている状態でユーザが削除しようとすると、control plane がアノテーションを追加します。アノテーションbatch.kubernetes.io/job-tracking
は現在非推奨です。control plane は v1.27 で将来的にこれを無視し、新しい Job に追加するのをやめるようになります。(#113510, @alculquicondor) -
Kubelet に以下の Pod failure conditions が追加されました。
-
podTopologySpread
のNodeInclusionPolicy
plugin がデフォルトで有効になりました。
(#113500, @kerthcet) -
'
PodDisruptionBudget
に alpha でspec.unhealthyPodEvictionPolicy
フィールドが追加されました。
kube-apiserver
でPDBUnhealthyPodEvictionPolicy
feature-gate が有効になっている場合、
対象のフィールドに"AlwaysAllow"
設定されていると ready でない(PodDisruptionBudget が現在、healthy かどうかに関わらず) Pod の evict が許可されます。
(#113375, @atiratree)-
evocet の対象の Pod を
status.phase
に応じて細かく制御できる機能拡張になります。 - 詳細について公式 docs のこちらを参照ください
-
evocet の対象の Pod を
-
API オブジェクトに指定された
metav1.LabelSelectors
は無効なラベルの値が含まれていないか確認するようになりました。既存の無効なオブジェクトを変更することはできますが、新しいオブジェクトは検証されるようになります。(#113699, @liggitt) -
StatefulSet
の起動時の replicas を.spec.ordinals.start
field を元に任意の数を指定できる機能を追加しました。 (#112744, @pwschuurman) -
PersistentVolumeClaim
API に新しくアルファでDataSourceRef
フィールドが追加されました。(#113186, @ttakahashi21) -
Aggregated discovery は alpha 機能です。
AggregatedDiscoveryEndpoint
feature flag で切り替えが可能です。 (#113171, @Jefftree) -
"Retriable and non-retriable pod failures for jobs" が beta になりました。 (#113360, @mimowo)
- 前回の変更点調査で Pod failure policy と紹介したものが beta になりました。
- KEP に記載されているタイトルや、feture gate の flag 名で名前が違ったりしますが、内容は同じものになります。
-
kube-controller-manager
の '--concurrent-horizontal-pod-autoscaler-syncs' flag で horizontal pod autoscaler controller workers 数を設定できるようになります。 (#108501, @zroubalik)- HPA controller をスケールできるように機能が追加されたようです。
-
Event API オブジェクト(
events.k8s.io/v1
)更新時の不要なfield is immutable
バリデーションエラーを修正しました。 (#112183, @liggitt -
ServiceInternalTrafficPolicy
feature が GA になりました。(#113496, @avoltz) -
MixedProtocolLBService
が beta から GA になりました。(#112895, @janosi) -
新しい Pod API フィールド
.spec.schedulingGates
が導入され利用者は Pod が scheduling ready にマークされるタイミングを制御できるようになりました。 (#113274, @Huang-Wei) -
feature gates
ServiceLoadBalancerClass
とServiceLBNodePortControl
が削除されました。これらの機能はv1.24
から利用可能です。 (#112577, @andrewsykim) -
EndpointSliceTerminatingCondition
feature gate が GA になりました。 この feature gate は v1.28 で削除予定になります。 (#113351, @andrewsykim) -
DynamicKubeletConfig
feature gate は API server から削除されました。Dynamic kubelet reconfiguration はまだ古いノードが使用している場合でも利用できなくなります。これは Kubernetes version skew policy に沿った変更になります。(#112643, @SergeyKanzhelev)
Feature(機能追加)
-
HorizontalPodAutoscaler
に selector validation を追加しました。複数の HPA で同じ Pod が選択されている場合にスケールされなくなり、reason がAmbiguousSelector
になります。この変更は複数の HPA が同じ deployment を選択している場合にも機能します。(#112011, @pbeschetnov)- 複数の HPA が同一の Pod を意図せず対象としているケースは起こりうると思うので、これはいい変更だなと思いました。
-
RetroactiveDefaultStorageClass
が beta になりました。(#113329, @RomanBednar) -
新しい
pod_status_sync_duration_seconds
histogram が alpha metrics として記録されるようなり、kubelet が pod status の変更を書き込む時間が推定できるようになります。(#107896, @smarterclayton) -
新しい metric
job_controller_terminated_pods_tracking_finalizer
が追加されました。これにより job controller が完了した Pod から finalizers を削除して、Job の status に計上したか監視できるようになります。(#113176, @alculquicondor) -
TopologyAwareHints
の有効/無効化時に publishing events が追加されました。 (#113544, @LiorLieberman) -
kubelet の再起動時に SELinux mount context が再構築されるようになりました。
SELinuxMountReadWriteOncePod
が完全に実装され、kubelet process restart 時に SELinux contexts のキャッシュが消えないようになりました。 (#113596, @jsafrane) -
Pod GC Controller に
force_delete_pods_total
とforce_delete_pod_errors_total
のメトリクスが追加されました。 (#113519, @xing-yang) -
job_finished_total
メトリクスが拡張され、新しい reason label が追加され pod failures の失敗がカウントされるようになりました。
handled by pod failure policy with respect to the action applied. (#113324, @mimowo)- "BackoffLimitExceeded", "DeadlineExceeded", "PodFailurePolicy" の 3 つが reason label に追加されるようになっています。
-
1つ以上の StorageClass がデフォルトして設定されている場合 ("storageclass.kubernetes.io/is-default-class" annotation が設定されている)エラーを返す代わりに一番新しい StorageClass を選択するようにします。 (#110559, @danishprakash)
- エラーになった方が利用者が嬉しい気もしますが、StorageClass のデフォルトを更新する際に、今までの仕様だとまず既存の StorageClass のデフォルトを削除する必要があり、デフォルトが存在しないタイミングが発生するのでその対策で追加されてようです。
-
RetroactiveDefaultStorageClass
のメトリクスが利用できるようになりました。デフォルトに対する PVC のアップデートを遡って確認したい場合はretroactive_storageclass_total
メトリクスを、合計のエラー数はretroactive_storageclass_errors_total
を見ることで確認できます。 (#113323, @RomanBednar) -
WindowsHostProcessContainers
が stable になりました。 (#113476, @marosset) -
LegacyServiceAccountTokenNoAutoGeneration
が GA になりました。 (#112838, @zshihang) -
DaemonSet
の Pod の作成に失敗した時にステータスが更新されるように修正されました。(#112127, @gjkim42) -
PodDisruptionConditions
feature gate を有効化したときに、NoExecute
の taint が付与されているノードで実行されている Pod が実行され続ける問題を修正されました。 (#112518, @mimowo) -
job_finished_total
メトリクスが稀に二重でカウントされるのを修正しました。(#112948, @mimowo) -
endpointslice controller の最大の maximum backoff delay を service に sync するために期待される遅延に合わせて増加しました。 (#112353, @dgrisonnet)
-
既知の問題: Pod が終了する前に削除されると Job field
.spec.podFailurePolicy.rules[*].onExitCode
が無視される可能性がある。(#113856, @alculquicondor) -
kube-scheduler
とkube-controller-manager
は Pod の中断に関する conditions を設定するために server side apply を利用するようになりました。(#113304, @mimowo)
Documentation(ドキュメント改善)
特になし
ENHANCEMENT(機能改善)
特になし
Bug or Regression(バグ修正)
特になし
Other (その他の修正)
-
cronjob v2 controller に追従するために
cronjob_job_creation_skew
metric が stable になりました。それに合わせて以下のメトリク名が API guidelines に沿って変更になりました。 -
IndexedJobs が GA になったのに関連するメトリクスが stable になります。以下のメトリクスが metrics API guidelines に沿って名前が変更になります。
-
ServerSideApply
feature gate が true で固定されます。この機能は既に GA です。(#112748, @wojtek-t) -
test/e2e/framework
をリファクタリングしてコアのフレームワークが小さくなりました。resource monitoring、log size monitoring、metrics gathering、debug information dumping などのオプショナルな機能を利用する特定の e2e test suites ではインポートする必要があります。core framework のトラディショナルな機能を再び有効化するためのインポート可能な Init packages が提供されます。この PR のためにコンパイルできなくなったコードがある場合、コミットメッセージのスクリプトを使用してそのコードを更新することができます。(#112043, @pohly) -
IndexedJob
がSuspendJob
が 1.24 から GA になっており v1.26 で削除されました。(#112589, @SataQiu) -
OpenStack 用の in-tree cloud provider(cinder volume provider) が削除されました。代わりに外部の cloud provider と cloud-provider-openstackの csi driver を利用してい下さい。 (#67782, @dims)
所感
今回の sig-apps の変更の中だと JobPodFailurePolicy
が Beta になったので、利用できるようになったのが大きいかなと思います。新規機能追加については KEP もなく追加された preStop/postStart
で httpGet
を利用時に httpHeaders
が優先されるようになった機能が一番需要があるのでは?と思いました。StatefulSetStartOrdinal
は StatefulSet の利用者にとってはユースケースがそこそこあると思うので、順当に Beta になるが期待されますね。