[Kubernetes 1.25] Added alpha support for user namespaces in pods phase 1

# はじめに
2022/08/23にKuberentes 1.25がリリースされました。
changelogを読むと、Stage:Alphaですが遂にPodでuser namespacesでサポートされたと記載がありました。
> Added alpha support for user namespaces in pods phase 1 (KEP 127, feature gate: UserNamespacesStatelessPodsSupport) (#111090, @rata)

user namespaceの利用により、WorkerNode上のUID空間から特定範囲のUIDを切り出し、PodのコンテナのUID 0〜65535をマッピングすることで、コンテナ内のプロセスがあたかもroot(UID:0)として動作しているように見えるようになり、コンテナのUIDやGIDをホストからの分離が可能となります。

これを利用することで、root権限なしで、rootでの操作が必要なファイルの実行ができるようになります。つまり、nginxなどrootでの起動が必要なアプリケーションも起動ができるということです。

# 現在の状況
前述した通り、現在はStage:Alphaです。
sig-nodeのkepにある、[Graduation Criteria](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/127-user-namespaces/README.md#graduation-criteria)を確認すると、AlphaではPhase1の実装が完了したらと記載があります。
> Graduation Criteria
Note this section is a WIP yet.
Alpha
・Phase 1 implemented
Beta
・Make plans on whether, when, and how to enable by default
・Should we reconsider making the mappings smaller by default?
・Should we allow any way for users to for "more" IDs mapped? If yes, how many more and how?
・Should we allow the user to ask for specific mappings?
>GA

各Phaseの詳細は同kepの[Phasesの節](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/127-user-namespaces/README.md#phases)に記載されていますが、Phase1は以下のvolumeがある、またはvolumeなしのPodに限りuser namespaceが利用できるようになっています。
>・configmap
・secret
・downwardAPI
・emptyDir
・projected

今後の状況はkepからでも[issue](https://github.com/kubernetes/enhancements/issues/127)からでも追えます。

# 動作
Podでuser namespacesを有効にする(設定方法は後述)と.spec.securityContext.fsGroupが0に設定されているかのように動作します。つまり見せかけ上はrootとして動いているように見えます。なお、.spec.securityContext.fsGroupを０以外にするとそれが優先されます。

# 有効化
## 前提
- FeatureGate:UserNamespacesStatelessPodsSupportが有効であること
- CRIがCRI-O v1.25以上であること
  containerdはv1.7からuser namespaceをサポート予定です。
## 有効化設定
.spec.hostUsersをfalseにするだけです。
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: userns
spec:
  hostUsers: false
  containers:
  - name: shell
    command: ["sleep", "infinity"]
    image: debian
```
Pod内および、WorkerNode上で、`cat /proc/self/uid_map`コマンドを実行することで、UIDがどのようにマッピングされているかを確認することが可能です。

# client-goのapplyconfiguration対応状況
client-go v0.25.0にて、type PodSpecApplyConfiguration.HostUsersおよびWithHostUsers関数が実装されています。HostUsersがApplyConfigurationに実装されていることで、Server-Side Applyでもuser namespaceを有効化できるようになっています。良き！！
実装時のcommit：
https://github.com/kubernetes/client-go/commit/828c3cb11b78326772b5c21c95fed4e3c81e5b2a
```golang
type PodSpecApplyConfiguration struct {
:
	HostUsers *bool `json:"hostUsers,omitempty"`
}

// WithHostUsers sets the HostUsers field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the HostUsers field is set to the value of the last call.
func (b *PodSpecApplyConfiguration) WithHostUsers(value *bool) *PodSpecApplyConfiguration {
	b.HostUsers = value
	return b
}
```


# さいごに
まだAlphaなのでGAまでは時間がかかりそうですが、user namespaceが使えるようになったことは喜ばしいことです。GAとなり本番にも導入できるようになれば、コンテナのroot権限奪取の心配も軽減されるようになると予想されます。楽しみにGAを待ちましょう。

# 参考資料
https://kubernetes.io/docs/concepts/workloads/pods/user-namespaces/
https://kubernetes.io/docs/tasks/configure-pod-container/user-namespaces/