Kubernetes v1.33: SIG-Authの変更内容

## はじめに
このページではKubernetes v1.33におけるSIG-Authに関連する取り組みについて、ChangelogのChanges By Kindの項目から紹介しています。ここに記載されていないものは別のまとめで記載されていると思いますので、ぜｈそれらも参照してみてください。

:pencil2: がついた文章は、CHANGELOGの公式内容ではなく筆者の補足です。

## 機能の更新・追加など

### Alphaで追加されたフィーチャーゲート

- `DRAPartitionableDevices` (default false)
- `KubeletServiceAccountTokenForCredentialProviders` (default false)
### Betaに昇格・追加されたフィーチャーゲート
- `StreamingCollectionEncodingToProtobuf` (default true)
- `DisableAllocatorDualWrite` (default false)
- `ClusterTrustBundle` (default false)
- `ClusterTrustBundleProjection` (default false)
- `KubeletFineGrainedAuthz` (default true)
### GAになったフィーチャーゲート
- `MultiCIDRServiceAllocator` (default true)
- `ServiceAccountTokenNodeBinding` (default true)
    - https://qiita.com/hiyosi/items/d0946fd0839cc4c6e3d2
### 削除されたフィーチャーゲート
- `PDBUnhealthyPodEvictionPolicy`
- `AppArmor`
## Changes by Kind

### Deprecation

- N/A
### API Change

- `DRAPartitionableDevices` フィーチャーゲートを追加しました。有効にすると、Dynamic Resource Allocation はパーティショニング可能なデバイスの割り当てをサポートします。([#130764](https://github.com/kubernetes/kubernetes/pull/130764))
- DRA: デバイスのtaintは、DRAドライバや管理者がデバイスを使用不可としてマークできるようにし、デバイスの割り当てが行わることを防ぎます。taintの重大度やclaimがそのtaintを許容しているかどうかに応じて、実行中のPodがデバイスの使用不可により退避されることもあります。([#130447](https://github.com/kubernetes/kubernetes/pull/130447))
- DRA: Kubernetes 1.33以降、`adminAccess` フィールドを使用して ResourceClaim や ResourceClaimTemplate オブジェクトを作成するには、`kubernetes.io/dra-admin-access` ラベルが付いた管理用ネームスペースへのアクセス権を持つユーザーに限られます。これらのユーザーのみが、Pod や Deployment の仕様内でそれらの ResourceClaim または ResourceClaimTemplate を参照することができます。([#130225](https://github.com/kubernetes/kubernetes/pull/130225))
- On-disk の kubelet クレデンシャルプロバイダ構成が拡張され、オプションの tokenAttribute フィールドを設定できるようになりました。これが設定されている場合、kubelet は指定されたオーディエンスを持つトークンを、現在の Pod とそのサービスアカウントにバインドして発行します。この KSA（Kubernetes Service Account）トークンは、設定で定義された KSA の必要なアノテーションとともに、（現在も送信されているイメージ情報と一緒に）標準入力経由でクレデンシャルプロバイダプラグインに送信されます。送信する KSA のアノテーションは、kubelet のクレデンシャルプロバイダのコンフィグレーションで設定可能です。([#128372](https://github.com/kubernetes/kubernetes/pull/128372))
	- KEP:
		- https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/4412-projected-service-account-tokens-for-kubelet-image-credential-providers/README.md
	- Doc: 
		- https://kubernetes.io/docs/tasks/administer-cluster/kubelet-credential-provider/
	- :pencil2: 
		- Provider毎にサービスアカウントトークンのaudience値を設定できるようなりました
		- アノテーションも設定できるようになりました
		- `ServiceAccountNodeAudienceRestriction`と併せてつかう場合はaudience値がチェックされるので注意が必要かもしれません

```yaml
apiVersion: kubelet.config.k8s.io/v1
kind: CredentialProviderConfig
providers:
  - name: ecr-credential-provider
    matchImages:
      - "*.dkr.ecr.*.amazonaws.com"
      - "*.dkr.ecr.*.amazonaws.com.cn"
      - "*.dkr.ecr-fips.*.amazonaws.com"
      - "*.dkr.ecr.us-iso-east-1.c2s.ic.gov"
      - "*.dkr.ecr.us-isob-east-1.sc2s.sgov.gov"
    defaultCacheDuration: "12h"
    apiVersion: credentialprovider.kubelet.k8s.io/v1
    env:
      - name: AWS_PROFILE
        value: example_profile
    tokenAttributes:
      serviceAccountTokenAudience: "<audience for the token>"
      requireServiceAccount: true
      requiredServiceAccountAnnotationKeys:
      - "example.com/required-annotation-key-1"
      - "example.com/required-annotation-key-2"
      optionalServiceAccountAnnotationKeys:
      - "example.com/optional-annotation-key-1"
      - "example.com/optional-annotation-key-2"
```

- godoc におけるバリデーションルールの例が修正されました: JWT authenticatorを設定する際、username.expression に 'claims.email' を使用している場合は、`username.expression`、`extra[_].valueExpression`、または `claimValidationRules[_].expression` のいずれかに 'claims.email_verified' も使用されていなければなりません。たとえば、username.claim に 'email' を設定した場合に自動的に適用されるバリデーションと一致する claimValidationRules の例としては、以下のような表現になります: `claims.?email_verified.orValue(true) == true` .このように明示的に true と比較することで、型チェックにより結果がブール値であることが認識され、ブール値でない email_verified クレームが実行時に検出されるようになります。 ([#130875](https://github.com/kubernetes/kubernetes/pull/130875))
- APIサーバが **list** リクエストに対して、レスポンス形式が Protobuf にネゴシエートされた場合の応答方法が改善されました。Protobuf 形式の list レスポンスでは、要素を1つずつマーシャルするようになり、大規模なコレクションを処理する際のメモリ使用量が大幅に削減されます。このストリーミング形式での list レスポンスは、StreamingCollectionEncodingToProtobuf フィーチャーゲートを使って無効にすることができます。([#129407](https://github.com/kubernetes/kubernetes/pull/129407))
- Kubernetes のコンポーネントで X.509 クライアント証明書認証を受け付けるものは、証明書のサブジェクト名の RDNのうち、オブジェクト ID `1.3.6.1.4.1.57683.2` を持つものからユーザー UID を読み取るようになりました。このオブジェクト ID を持つ RDN は、文字列値を含み、証明書のサブジェクト内に1つだけ存在している必要があります。この RDN からのユーザー UID の読み取りは、ベータ機能ゲート AllowParsingUserUIDFromCertAuth を false に設定することで無効にできます（この機能ゲートが GAに移行するまでは）。
	- :pencil2: 
		- X.509クライアント証明書認証においてもUIDをサポートします。UIDは上記のOIDから読み取ります。
		- e.g. `Subject: C = JP, O = Example Corp, OU = Test, CN = user1, 1.3.6.1.4.1.57683.2 = 123e4567-e89b-12d3-a456-426614174000`
 - kubelet に新しい設定が導入され、コンテナイメージと、それらのイメージのプルに成功した際に使用された認証情報のリストを追跡できるようになりました。このデータは、ホストの再起動や kubelet の再起動後も保持されます。kubelet は、認証が必要なイメージについて、該当の認証情報がまだ存在しない場合は必ずイメージをプルするようになり、認証または再認証を強制します。つまり、ポッドが IfNotPresent のイメージプルポリシーを指定している場合でも、イメージのプルが試みられる可能性があり、Never を指定していて以前の成功したプルに使われた認証情報が提示できない場合は、ポッドが起動しないこともあります。([#128152](https://github.com/kubernetes/kubernetes/pull/128152))
	- KEP
		-  https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2535-ensure-secret-pulled-images/README.md
	- :pencil2: 
		- Namespace を跨いで pull 済みイメージが再利用されてしまうセキュリティ問題に対応しています。
		- https://github.com/kubernetes/kubernetes/issues/18787
		- kubeletはディスクに永続されたキャッシュによりイメージのプルに成功した認証情報を追跡します。 匿名プルやノード全体のクレデンシャルを使用したプルも含まれます。
		- キャシュのガベージコレクションは、kubeletによるイメージのガベージコレクションに関連づいていると書かれています。これによるキャッシュサイズについてはalphaリリースで検証されるとのこと。
e.g. シークレットを使っていないまたは全Pod共通の場合
```json
{
  "kind": "ImagePulledRecord",
  "apiVersion": "kubelet.config.k8s.io/v1alpha1",
  "lastUpdatedTime": "2024-10-21T12:26:40Z",
  "imageRef": "testimage-anonpull",
  "credentialMapping": {
    "docker.io/testing/test": {
      "nodePodsAccessible": true
    }
  }
}
```
e.g.  イメージプルで使ったシークレット情報を記録する場合
```json
{
  "kind": "ImagePulledRecord",
  "apiVersion": "kubelet.config.k8s.io/v1alpha1",
  "lastUpdatedTime": "2024-10-21T12:26:40Z",
  "imageRef": "testimageref",
  "credentialMapping": {
    "docker.io/testing/test": {
      "kubernetesSecrets": [
        {
          "uid": "testsecretuid",
          "namespace": "default",
          "name": "pull-secret",
          "credentialHash": "testsecrethash"
        }
      ]
    }
  }
}
```
-  GA済みの`PDBUnhealthyPodEvictionPolicy`フィーチャーゲートを削除しました。([#129500](https://github.com/kubernetes/kubernetes/pull/129500))
-  `MultiCIDRServiceAllocator` フィーチャーゲートがstableに昇格し、`DisableAllocatorDualWrite` フィーチャーゲートがbetaにになりました(デフォルト無効)。Kubernetes クラスタ管理者およびクラスタの Serviceクラスタの Service CIDR を API オブジェクト（ServiceCIDR）を使って定義できるようになりました。Kubernetes のディストリビューションやクラスタ管理者は、クラスタに追加される新しい Service CIDR が、クラスタ内の他のネットワークと重複しないよう特定の IP 範囲のみに属するように制限した場合があります。またこれまで通り、クラスタごとに 1 つの Service CIDR のみを許可する動作を維持することを好むかもしれません。  これらの目的を達成するには、ValidatingAdmissionPolicy を利用することができます。([#128971](https://github.com/kubernetes/kubernetes/pull/128971))
- `ClusterTrustBundle` API は `v1beta1` に移行しています。kubelet 側で `ClusterTrustBundleProjection` 機能を動作させるためには、`ClusterTrustBundle` API が v1beta1 バージョンで利用可能であり、かつ `ClusterTrustBundleProjection` フィーチャーゲートが有効である必要があります。もし kubelet の起動後に API が利用可能になった場合は、この機能を有効にするために kubelet を再起動してください。 ([#128499](https://github.com/kubernetes/kubernetes/pull/128499))
	- KEP: 
		- https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/3257-cluster-trust-bundles/README.md
	- :pencil2: 
		- ClusterTrustBundleProjectionを使うとPodの`spec.volumes`にてClusterTrustBundleオブジェクトのnameまたはsignerNameを指定することでそのTrustBundleをマウントすることができます。
		- ClusterTrustBundleオブジェクトへのアクセスはRBACで制御でき、デフォルトではget, list, watchが許可されています。
		- クラスターワイドである点や構造としてsingerとトラストバンドルの紐付けが管理でき整合性の面でメリットがありそうです。
```yaml
apiVersion: certificates.k8s.io/v1beta1
kind: ClusterTrustBundle
metadata:
  name: example.com:pod-mtls:root
spec:
  signerName: example.com/pod-mtls
  trustBundle: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
```

```yaml
  volumes:
  - name: token-vol
    projected:
      sources:
        - clusterTrustBundle:
          signerName: "example.com/pod-mtls" 
          path: mtls-roots.pem
```

-  `resource.k8s.io/v1beta1`  APIは非推奨となり、1.36で削除されます。`v1beta2`を代わりに使ってください。 ([#129970](https://github.com/kubernetes/kubernetes/pull/129970))
### Feature
-  監査ログに `apiserver.latency.k8s.io/authentication` アノテーションが追加され、遅延のあるリクエストに対して認証にかかった時間が記録されるようになりました。また、`apiserver.latency.k8s.io/authorization` アノテーションも追加され、遅延のあるリクエストに対して認可にかかった時間が記録されるようになりました。([#130571](https://github.com/kubernetes/kubernetes/pull/130571))
	- :pencil2:
		- これまで監査ログでは全体の時間を知ることができたようですが、
- Restricted PSA（Pod Security Admission）プロファイルで ImageVolume が許可されるようになりました。 ([#130394](https://github.com/kubernetes/kubernetes/pull/130394))
	- 時間があれば
- node audience restriction機能の一環として、kubelet がトークンを要求する際のサービスアカウント名およびオーディエンスを動的に設定できるようになりました。 ([#130485](https://github.com/kubernetes/kubernetes/pull/130485))
	- :pencil2:  
		- v1.33のタグが付いていますが 2025/05/08 時点では v1.33.0に含まれていないように思います
- `cel-go`は`v0.23.2`にあがりました。 ([#129844](https://github.com/kubernetes/kubernetes/pull/129844))
- DRA: Kubernetes 1.33 以降、Namespaceスコープのクラスタ `edit` ロールが割り当てられた一般ユーザーは、`resourceclaims`、`resourceclaims/status`、`resourceclaimtemplates` に対する `read` 権限を持ちます。また、`resourceclaims`、`resourceclaimtemplates` に対する `write` 権限を持ちます。([#130738](https://github.com/kubernetes/kubernetes/pull/130738))
- kube-apiserver のループバッククライアント証明書の有効期間を 14 ヶ月に延長し、更新された Kubernetes のサポートライフサイクルに合わせました。 ([#130047](https://github.com/kubernetes/kubernetes/pull/130047))
- `KubeletFineGrainedAuthz` フィーチャーゲートがbetaに昇格しました。このゲートはデフォルトで有効になります。([#129656](https://github.com/kubernetes/kubernetes/pull/129656))
- `client-go/rest` においてコンテキスト付きロギングの完全なサポートを実装しました。呼び出し元がスリープを中断できるようにするため、`BackoffManager` の代わりに `BackoffManagerWithContext` が使用されました。([#127709](https://github.com/kubernetes/kubernetes/pull/127709))
- kube-apiserver: `ServiceAccountTokenNodeBinding`フィーチャーゲートがGAに昇格しました。現在はenabledに固定されています。 ([#129591](https://github.com/kubernetes/kubernetes/pull/129591))
- NodeRestriction admissionは、kubelet がサービスアカウントトークンを要求する際の audience 値が Pod の spec のボリュームに含まれていることを検証するようになりました。kube-apiserver の FeatureGate `ServiceAccountNodeAudienceRestriction` は、バージョン 1.33 でデフォルトで有効になっています。([#130017](https://github.com/kubernetes/kubernetes/pull/130017))
	- :pencil2:
		- v1.32.0 でデフォルト有効(beta)
		- v1.32.2  でリグレッションによりデフォルト無効(beta) 
		- v1.33.0 でデフォルト有効(beta)
- kube-apiserver への認証済みリクエストに対して、APIServer のトレーシング用に受信したトレースコンテキストを尊重するようになりました。 ([#127053](https://github.com/kubernetes/kubernetes/pull/127053))
- `SELinuxChangePolicy` と `SELinuxMount` が Beta に昇格しました。`SELinuxMount` はデフォルトでは無効のままです。 ([#130544](https://github.com/kubernetes/kubernetes/pull/130544))
	- 時間があれば
- `RemoteRequestHeaderUID` 機能が Beta に移行し、デフォルトで有効になりました。これにより、kube-apiserver は集約 API サーバーへのリクエストで `X-Remote-Uid` ヘッダーに含まれる UID を伝播するようになります。このヘッダーは、受信リクエストに対してはデフォルトでは無視されますが、`--requestheader-uid-headers` フラグを明示的に設定することで有効にできます。([#130560](https://github.com/kubernetes/kubernetes/pull/130560))
	- 時間があれば
### Documentation
- N/A
### Bug or Regression

- CVE-2024-51744 を修正しました([#128621](https://github.com/kubernetes/kubernetes/pull/128621))
	- :pencil2:
		- github.com/golang-jwt の `ParseWithClaims` が複数のエラーを返すため、エラーハンドリングが正しく行われていない場合、無効なトークンを受け入れてしまう可能性のある脆弱性
		- 無効な署名である場合は即座にリターンするように修正されています
		- ワークアラウンド → https://github.com/golang-jwt/jwt/security/advisories/GHSA-29wx-vh33-7x7r
- Pod にephemeral containerを追加する際、新しい Secret や ConfigMap を参照している場合に、その Secret や ConfigMap へのアクセス権が Pod に付与されない不具合を修正しました。([#114984](https://github.com/kubernetes/kubernetes/pull/114984))
 - WebSocket の HTTPS プロキシ対応を追加しました。([#129872](https://github.com/kubernetes/kubernetes/pull/129872))
 - `ServiceAccountNodeAudienceRestriction` 機能において、azureFile ボリュームが'failed to get service account token attributes' エラーが発生する回帰バグを修正しました。([#129993](https://github.com/kubernetes/kubernetes/pull/129993)
	 - :pencil2: 
		 - `ServiceAccountNodeAudienceRestriction`はv1.32でbeta (default true)として導入されたが、この不具合によりdefault falseに変更されています([#130015](https://github.com/kubernetes/kubernetes/pull/130015))
		 - v1.33で改めてdefault trueになっています([#130017](https://github.com/kubernetes/kubernetes/pull/130017))
- kube-apiserver: `--service-account-max-token-expiration` フラグは、外部token signer `--service-account-signing-endpoint` と組み合わせて使用できるようになりました。ただし、有効期間は外部サイナーの最大有効期間を超えてはなりません。([#129816](https://github.com/kubernetes/kubernetes/pull/129816))
-  `storage-version-migrator-controller` を追加しました。([#130405](https://github.com/kubernetes/kubernetes/pull/130405))
 - E2e.test: デフォルトで有効になっていない FeatureGate を指定したテスト名に [Feature:OffByDefault] を追加しました。([#130655](https://github.com/kubernetes/kubernetes/pull/130655))
 - kube-apiserver: `authentication.k8s.io/v1alpha1` API に対する非アクティブなサービングコードを削除しました。([#129186](https://github.com/kubernetes/kubernetes/pull/129186))
- GAになったフィーチャーゲート`AppArmor`を削除しました。([#129375](https://github.com/kubernetes/kubernetes/pull/129375))
- etcd クライアントライブラリを v3.5.21 に更新しました。([#131103](https://github.com/kubernetes/kubernetes/pull/131103))