はじめに
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を確認すると、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の節に記載されていますが、Phase1は以下のvolumeがある、またはvolumeなしのPodに限りuser namespaceが利用できるようになっています。
・configmap
・secret
・downwardAPI
・emptyDir
・projected
今後の状況はkepからでもissueからでも追えます。
動作
Podでuser namespacesを有効にする(設定方法は後述)と.spec.securityContext.fsGroupが0に設定されているかのように動作します。つまり見せかけ上はrootとして動いているように見えます。なお、.spec.securityContext.fsGroupを0以外にするとそれが優先されます。
有効化
前提
- FeatureGate:UserNamespacesStatelessPodsSupportが有効であること
- CRIがCRI-O v1.25以上であること
containerdはv1.7からuser namespaceをサポート予定です。
有効化設定
.spec.hostUsersをfalseにするだけです。
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
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/