- はじめに
- Pod Security Standards (PSS) と Pod Security Admission (PSA)
- OpenShift 4.11におけるPSA Label
- SCC (Security Context Constraints) への影響
- Pod Security Admission Label Synchronization
- pkg/cmd/controller/psalabelsyncer.go
- pkg/psalabelsyncer/podsecurity_label_sync_controller.go
- pkg/psalabelsyncer/scctopsamapping.go
- さいごに
- References
はじめに
みなさんこんにちは、最近パンを焼いている者です。
バゲット焼いたねん🥖 pic.twitter.com/UB02BZLlFk
— nishipy (@iamnishipy) November 6, 2022
これは「OpenShift Advent Calendar 2022」 17日目の記事です。OpenShiftの他に、KubernetesとAnsibleのAdvent Calendarにも参加したので、よければご覧ください〜。
- kubeletのPLEGをソースコード読んで理解したかった – Kubernetes Advent Calendar 6日目
-
ansible-lint にPull Request送ってみた – Ansible Advent Calendar 7日目
今回はOpenShift特有の機能 PSA Label Synchronization がよくわからなかったのでソースコード読んでみました。なお、以下に出てくるドキュメントやソースコードは、OpenShift 4.11のものです。
Pod Security Standards (PSS) と Pod Security Admission (PSA)
Kubernetes 1.25では、従来のPod Security Policy (PSP) が削除され、 Pod Security Admission (PSA) という新しいAdmission Controllerに置き換えられました。詳細はKEP参照。
また以下の動画もわかりやすかったです。
Pod Security Standards (PSS)
一応もう少し説明すると、Pod Security Standards (PSS) には3つのpolicy level (Privileged, Baseline, Restricted)が予め定義されています。ドキュメント内の表を引用すると、それぞれ概要は以下の通りです。とてもシンプル。
Profile Description Privileged Unrestricted policy, providing the widest possible level of permissions. This policy allows for known privilege escalations. Baseline Minimally restrictive policy which prevents known privilege escalations. Allows the default (minimally specified) Pod configuration. Restricted Heavily restricted policy, following current Pod hardening best practices. 引用元: https://kubernetes.io/docs/concepts/security/pod-security-standards/
Pod Security Admission (PSA)
Pod Security Admission (PSA)は、Pod Security Standards (PSS)を適用するための新しいAdmission Controllerです。適用時には3つのmodeが用意されています。最も厳しいenforce
modeの場合、Podの実行自体が拒否されます。
Mode Description enforce Policy violations will cause the pod to be rejected. audit Policy violations will trigger the addition of an audit annotation to the event recorded in the audit log, but are otherwise allowed. warn Policy violations will trigger a user-facing warning, but are otherwise allowed. 引用元: https://kubernetes.io/docs/concepts/security/pod-security-admission/
基本的にはNamespace単位で pod-security.kubernetes.io/<MODE>: <LEVEL>
みたいなlabelを付与することで、適用するPSS levelとそのmodeを指定できます。
OpenShift 4.11におけるPSA Label
新規作成したProject/Namespaceを見ると、restricted
policyがaudit
/warn
modeで有効化されているのがわかります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# oc get ns test -o yaml apiVersion: v1 kind: Namespace metadata: ~~ labels: kubernetes.io/metadata.name: test pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/audit-version: v1.24 pod-security.kubernetes.io/warn: restricted pod-security.kubernetes.io/warn-version: v1.24 name: test resourceVersion: "23857343" uid: 2fee4923-8c15-4dce-b4bf-17240f4d1a2b spec: finalizers: - kubernetes status: phase: Active |
SCC (Security Context Constraints) への影響
OpenShift としてはPSPではなくSCC (Security Context Constraints)を利用していましたが、今回の変更の影響は少なからずあったようです。詳細は、Important OpenShift changes to Pod Security Standards という記事にも載っています。
具体的には、OpenShift 4.11では、新しいSCC policy (restricted-v2, nonroot-v2, hostnetwork-v2)が導入されています。これは、PSSに従ってワークロードを認可するためのものです。
restricted/restricted-v2を少しみてみます。yamlのannitationに、v1からの変更点が書いてあり親切でした。手元で見えたSCCをコピペしますので興味あればdiffとってみてください。
restricted-v2 denies access to all host features and requires pods to be run with a UID, and SELinux context that are allocated to the namespace. This is the most restrictive SCC and it is used by default for authenticated users. On top of the legacy ‘restricted’ SCC, it also requires to drop ALL capabilities and does not allow privilege escalation binaries. It will also default the seccomp profile to runtime/default if unset, otherwise this seccomp profile is required.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
(restricted-v2) allowHostDirVolumePlugin: false allowHostIPC: false allowHostNetwork: false allowHostPID: false allowHostPorts: false allowPrivilegeEscalation: false allowPrivilegedContainer: false allowedCapabilities: - NET_BIND_SERVICE apiVersion: security.openshift.io/v1 defaultAddCapabilities: null fsGroup: type: MustRunAs groups: [] kind: SecurityContextConstraints metadata: annotations: include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" include.release.openshift.io/single-node-developer: "true" kubernetes.io/description: restricted-v2 denies access to all host features and requires pods to be run with a UID, and SELinux context that are allocated to the namespace. This is the most restrictive SCC and it is used by default for authenticated users. On top of the legacy 'restricted' SCC, it also requires to drop ALL capabilities and does not allow privilege escalation binaries. It will also default the seccomp profile to runtime/default if unset, otherwise this seccomp profile is required. creationTimestamp: "2022-10-07T02:11:24Z" generation: 1 name: restricted-v2 ownerReferences: - apiVersion: config.openshift.io/v1 kind: ClusterVersion name: version uid: b105b4e0-d6c2-4681-a0c9-99c210876715 resourceVersion: "1757" uid: 6a58e651-46cc-4446-a725-cadb9d62a3c8 priority: null readOnlyRootFilesystem: false requiredDropCapabilities: - ALL runAsUser: type: MustRunAsRange seLinuxContext: type: MustRunAs seccompProfiles: - runtime/default supplementalGroups: type: RunAsAny users: [] volumes: - configMap - downwardAPI - emptyDir - persistentVolumeClaim - projected - secret |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
(restricted-v1) allowHostDirVolumePlugin: false allowHostIPC: false allowHostNetwork: false allowHostPID: false allowHostPorts: false allowPrivilegeEscalation: true allowPrivilegedContainer: false allowedCapabilities: null apiVersion: security.openshift.io/v1 defaultAddCapabilities: null fsGroup: type: MustRunAs groups: [] kind: SecurityContextConstraints metadata: annotations: include.release.openshift.io/ibm-cloud-managed: "true" include.release.openshift.io/self-managed-high-availability: "true" include.release.openshift.io/single-node-developer: "true" kubernetes.io/description: restricted denies access to all host features and requires pods to be run with a UID, and SELinux context that are allocated to the namespace. release.openshift.io/create-only: "true" creationTimestamp: "2022-10-07T02:11:25Z" generation: 1 name: restricted resourceVersion: "343" uid: 97fe7985-1144-4815-818e-ed09fc93ceec priority: null readOnlyRootFilesystem: false requiredDropCapabilities: - KILL - MKNOD - SETUID - SETGID runAsUser: type: MustRunAsRange seLinuxContext: type: MustRunAs supplementalGroups: type: RunAsAny users: [] volumes: - configMap - downwardAPI - emptyDir - persistentVolumeClaim - projected - secret |
Pod Security Admission Label Synchronization
前置きが長すぎましたが、いよいよ今回調べてみたかったPod Security Admission Label Synchronizationのお話です。
OpenShiftには、Service Accountに付与されているSCCの設定にあわせて、Namespaceに付与するPSAのラベルを調整する機能 Pod Security Admission Label Synchronization があります。これによりSCCが適切に設定されていれば、適切なPSAラベルがNamespaceに自動で付与され、基本的にPodの実行が拒否されたりWarningが表示されることはなくなります。
こいつの仕組みについてよくわからないので、PSA Label Synchronization Controllerのソースコードを眺めて完全に理解したいと思います。
pkg/cmd/controller/psalabelsyncer.go
まず、controllerがどのように呼び出されているか見てみます。runPodSecurityAdmissionLabelSynchronizationController()
の実装を見てみると、cluster-policy-controller/pkg/psalabelsyncer
パッケージのNewPodSecurityAdmissionLabelSynchronizationController()
でインスタンス化したあと、goroutineとして controllerを起動(Run())しています
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
// pkg/cmd/controller/psalabelsyncer.go package controller import ( "context" "github.com/openshift/cluster-policy-controller/pkg/psalabelsyncer" ) func runPodSecurityAdmissionLabelSynchronizationController(ctx context.Context, controllerCtx *EnhancedControllerContext) (bool, error) { kubeClient, err := controllerCtx.ClientBuilder.Client(podSecurityAdmissionLabelSyncerControllerServiceAccountName) if err != nil { return true, err } controller, err := psalabelsyncer.NewPodSecurityAdmissionLabelSynchronizationController( kubeClient.CoreV1().Namespaces(), controllerCtx.KubernetesInformers.Core().V1().Namespaces(), controllerCtx.KubernetesInformers.Rbac().V1(), controllerCtx.KubernetesInformers.Core().V1().ServiceAccounts(), controllerCtx.SecurityInformers.Security().V1().SecurityContextConstraints(), controllerCtx.EventRecorder.ForComponent("podsecurity-admission-label-sync-controller"), ) if err != nil { return true, err } go controller.Run(ctx, 1) return true, nil } |
pkg/psalabelsyncer/podsecurity_label_sync_controller.go
PodSecurityAdmissionLabelSynchronizationController構造体
PodSecurityAdmissionLabelSynchronizationController
構造体は以下のように定義されています。コメントに記載があるように、Namespaceに"security.openshift.io/scc.podSecurityLabelSync: <true or false>"
ラベルをつけることで、Label Synchronization自体を有効/無効化できるようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// pkg/psalabelsyncer/podsecurity_label_sync_controller.go // PodSecurityAdmissionLabelSynchronizationController watches over namespaces labelled with // "security.openshift.io/scc.podSecurityLabelSync: true" and configures the PodSecurity // admission namespace label to match the user account privileges in terms of being able // to use SCCs type PodSecurityAdmissionLabelSynchronizationController struct { namespaceClient corev1client.NamespaceInterface namespaceLister corev1listers.NamespaceLister serviceAccountLister corev1listers.ServiceAccountLister sccLister securityv1listers.SecurityContextConstraintsLister nsLabelSelector labels.Selector workQueue workqueue.RateLimitingInterface saToSCCsCache SAToSCCCache } |
メンバーはご覧の通りで、client-goのclientや各種lister、Work queueが含まれます。この辺の登場人物は、Sample Controllerのドキュメントがわかりやすいかもしれません。
引用元: https://github.com/kubernetes/sample-controller/blob/master/docs/controller-client-go.md
またKubernetesのCustom Controllerについては、わかりやすい書籍があります。
NewPodSecurityAdmissionLabelSynchronizationController()
PodSecurityAdmissionLabelSynchronizationController
を生成する関数です。
まず、RoleBinding、ClusterRoleBindingのIndexerを追加しています。saToSCCCache
に使用されるようです。saToSCCCacheは、RoleとRoleBindingをキャッシュし、それに基づいてクラスタに存在するSCCをキャッシュする構造体で、これにより与えられたServiceAccountとSCCのセットを取得することができます。
次にcontrolledNamespacesLabelSelector
や SyncContext
を生成しています。controlledNamespacesLabelSelector
は PodSecurityAdmissionLabelSynchronizationController
で使用するラベルセレクターを返し、SyncContext は Sync()
関数に渡されるコンテキストを表します。workQueue
には、SyncContext.Queue() で返されるキューを指定するようです。
そして、saToSCCCache
と PodSecurityAdmissionLabelSynchronizationController
を生成して、Controllerを返します。最後のControllerを返すところでWithSync(c.sync)
を指定しているので、後ほど出てくる *PodSecurityAdmissionLabelSynchronizationController.sync()
で同期処理が行われているのがわかります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
// pkg/psalabelsyncer/podsecurity_label_sync_controller.go func NewPodSecurityAdmissionLabelSynchronizationController( namespaceClient corev1client.NamespaceInterface, namespaceInformer corev1informers.NamespaceInformer, rbacInformers rbacv1informers.Interface, serviceAccountInformer corev1informers.ServiceAccountInformer, sccInformer securityv1informers.SecurityContextConstraintsInformer, eventRecorder events.Recorder, ) (factory.Controller, error) { // add the indexers that are used in the SAToSCC cache if err := rbacInformers.RoleBindings().Informer().AddIndexers( cache.Indexers{BySAIndexName: BySAIndexKeys}, ); err != nil { return nil, err } if err := rbacInformers.ClusterRoleBindings().Informer().AddIndexers( cache.Indexers{BySAIndexName: BySAIndexKeys}, ); err != nil { return nil, err } controlledNamespacesLabelSelector, err := controlledNamespacesLabelSelector() if err != nil { return nil, err } syncCtx := factory.NewSyncContext(controllerName, eventRecorder.WithComponentSuffix(controllerName)) c := &PodSecurityAdmissionLabelSynchronizationController{ namespaceClient: namespaceClient, namespaceLister: namespaceInformer.Lister(), serviceAccountLister: serviceAccountInformer.Lister(), sccLister: sccInformer.Lister(), nsLabelSelector: controlledNamespacesLabelSelector, workQueue: syncCtx.Queue(), } saToSCCCache := NewSAToSCCCache(rbacInformers, sccInformer).WithExternalQueueEnqueue(c.saToSCCCAcheEnqueueFunc) c.saToSCCsCache = saToSCCCache return factory.New(). WithSync(c.sync). WithSyncContext(syncCtx). WithFilteredEventsInformersQueueKeysFunc( c.queueKeysRuntimeForObj, c.saToSCCsCache.IsRoleBindingRelevant, rbacInformers.RoleBindings().Informer(), rbacInformers.ClusterRoleBindings().Informer(), ). WithFilteredEventsInformersQueueKeysFunc( nameToKey, func(obj interface{}) bool { ns, ok := obj.(*corev1.Namespace) if !ok { // we don't care if the NS is being deleted so we're not checking // for a tombstone return false } return isNSControlled(ns) }, namespaceInformer.Informer(), ). WithInformersQueueKeysFunc( c.queueKeysRuntimeForObj, serviceAccountInformer.Informer(), ). ToController( controllerName, eventRecorder.WithComponentSuffix(controllerName), ), nil } |
*PodSecurityAdmissionLabelSynchronizationController.sync()
同期処理の実装はここに書いています。
まずWorkQueueからキーを取り出し、キーをもとにNamespaceを取得します。そして、PodSecurityAdmissionLabelSynchronizationControllerの管理対象のNamespaceでかつNamespaceのStatusがTerminatingでない場合のみ、syncNamespace()
を実行します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// pkg/psalabelsyncer/podsecurity_label_sync_controller.go func (c *PodSecurityAdmissionLabelSynchronizationController) sync(ctx context.Context, controllerContext factory.SyncContext) error { const errFmt = "failed to synchronize namespace %q: %w" qKey := controllerContext.QueueKey() ns, err := c.namespaceLister.Get(qKey) if err != nil { return fmt.Errorf(errFmt, qKey, err) } if !isNSControlled(ns) { return nil } if ns.Status.Phase == corev1.NamespaceTerminating { klog.Infof("skipping synchronizing namespace %q because it is terminating", ns.Name) return nil } if err := c.syncNamespace(ctx, controllerContext, ns); err != nil { return fmt.Errorf(errFmt, qKey, err) } return nil } |
特にif !isNSControlled(ns)
のところで、対象Namespaceが管理対象のものか判定します。isNSControlled()
関数はこんな感じで、OpenShift/Kubernetesシステムに関するNamespaceにはfalseを返し、他のNamespaceはついてはsecurity.openshift.io/scc.podSecurityLabelSync
ラベルの値を見ています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// pkg/psalabelsyncer/podsecurity_label_sync_controller.go func isNSControlled(ns *corev1.Namespace) bool { nsName := ns.Name if systemNSSyncExemptions.Has(nsName) { return false } // while "openshift-" namespaces should be considered controlled, there are some // edge cases where users can also create them. Consider these a special case // and delegate the decision to sync on the user who should know what they are // doing when creating a NS that appears to be system-controlled. if strings.HasPrefix(nsName, "openshift-") { return ns.Labels[labelSyncControlLabel] == "true" } if ns.Labels[labelSyncControlLabel] != "false" { return true } return false } |
*PodSecurityAdmissionLabelSynchronizationController.syncNamespace()
一番重要そうな syncNamespace()
メソッドに辿り着きました。ちょっと長いです。
最初のところでは、対象のNamespace内のServiceAccountを全て取得し、各ServiceAccountが与えられたNamespace内でPodを実行する時に使用可能なSCCを取得し、nsSCCs
にInsertしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// pkg/psalabelsyncer/podsecurity_label_sync_controller.go func (c *PodSecurityAdmissionLabelSynchronizationController) syncNamespace(ctx context.Context, controllerContext factory.SyncContext, ns *corev1.Namespace) error { // We cannot safely determine the SCC level for an NS until it gets the UID annotation. // No need to care about re-queueing the key, we should get the NS once it is updated // with the annotation. if len(ns.Annotations[securityv1.UIDRangeAnnotation]) == 0 { return nil } serviceAccounts, err := c.serviceAccountLister.ServiceAccounts(ns.Name).List(labels.Everything()) if err != nil { return fmt.Errorf("failed to list service accounts for %s: %w", ns.Name, err) } if len(serviceAccounts) == 0 { klog.Infof("no service accounts were found in the %q NS", ns.Name) return nil } nsSCCs := sets.NewString() for _, sa := range serviceAccounts { allowedSCCs, err := c.saToSCCsCache.SCCsFor(sa) if err != nil { return fmt.Errorf("failed to determine SCCs for ServiceAccount '%s/%s': %w", sa.Namespace, sa.Name, err) } nsSCCs.Insert(allowedSCCs.UnsortedList()...) } // ~~ |
次に対象Namespaceの現在のSCCの状況がわかったのでPSA levelを求めます。nsSCCs
に入れておいたSCCを順に見ていき、convertSCCToPSALevel()
で変換しています。currentNSLevel
としては最も緩いものを採用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// ~~ var currentNSLevel uint8 for _, sccName := range nsSCCs.UnsortedList() { scc, err := c.sccLister.Get(sccName) if err != nil { return fmt.Errorf("failed to retrieve an SCC: %w", err) } sccPSaLevel, err := convertSCCToPSALevel(ns, scc) if err != nil { return fmt.Errorf("couldn't convert SCC %q to PSa level: %w", scc.Name, err) } if sccPSaLevel > currentNSLevel { currentNSLevel = sccPSaLevel } // can't go more privileged if currentNSLevel == privileged { break } } // ~~ |
現状のNamespaceのラベルが、先ほど求めたPSA levelや定数で定義されているPSA versionと異なる場合にラベルを更新します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// ~~ psaLevel := internalRestrictivnessToPSaLevel(currentNSLevel) if len(psaLevel) == 0 { return fmt.Errorf("unknown PSa level for namespace %q", ns.Name) } nsCopy := ns.DeepCopy() var changed bool for typeLabel, versionLabel := range map[string]string{ psapi.WarnLevelLabel: psapi.WarnVersionLabel, psapi.AuditLevelLabel: psapi.AuditVersionLabel, } { if ns.Labels[typeLabel] != string(psaLevel) || ns.Labels[versionLabel] != currentPSaVersion { changed = true if nsCopy.Labels == nil { nsCopy.Labels = map[string]string{} } nsCopy.Labels[typeLabel] = string(psaLevel) nsCopy.Labels[versionLabel] = currentPSaVersion } } if changed { _, err := c.namespaceClient.Update(ctx, nsCopy, metav1.UpdateOptions{}) if err != nil { return fmt.Errorf("failed to update the namespace: %w", err) } } return nil } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// pkg/psalabelsyncer/scctopsamapping.go func internalRestrictivnessToPSaLevel(restr uint8) psapi.Level { switch restr { case restricted: return psapi.LevelRestricted case baseline: return psapi.LevelBaseline case privileged: return psapi.LevelPrivileged default: return "" } } |
以上により、Pod Security Admission Label Synchronization Controllerくんは無事にSCCからPSA levelを算出し、NamespaceのPSAラベルとして適用することができました。めでたしめでたし。
pkg/psalabelsyncer/scctopsamapping.go
convertSCCToPSALevel()
あまり深入りしませんが、どんなSCCがどんなPSA Levelに変換されるかは、こちらに実装されています。SCCの各フィールドを見ていき、内容に応じて、privileged / baseline / restricted を返します。
PSA Label Synchronizationの Enhancement の資料の中に、SCC to PSa Level Transformation という章があったので、これを読むのがわかりやすそうです (なお私は読んでません)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
// pkg/psalabelsyncer/scctopsamapping.go func convertSCCToPSALevel(namespace *corev1.Namespace, scc *securityv1.SecurityContextConstraints) (uint8, error) { sccRestrictivness := make([]uint8, 0, 10) sccRestrictivness = append(sccRestrictivness, convert_hostDir(scc.AllowHostDirVolumePlugin, scc.Volumes), convert_hostNamespace(scc.AllowHostIPC, scc.AllowHostNetwork, scc.AllowHostPID), convert_hostPorts(scc.AllowHostPorts), convert_allowPrivilegeEscalation(scc.AllowPrivilegeEscalation), convert_allowPrivilegedContainer(scc.AllowPrivilegedContainer), convert_allowedCapabilities(scc.AllowedCapabilities, scc.RequiredDropCapabilities), convert_unsafeSysctls(scc.AllowedUnsafeSysctls), convert_volumes(scc.Volumes), convert_seLinuxOptions(&scc.SELinuxContext), convert_seccompProfile(scc.SeccompProfiles), ) if restrictivness, err := convert_runAsUser(namespace, &scc.RunAsUser); err != nil { return privileged, fmt.Errorf("failed to convert SCC %q in namespace %q: %w", scc.Name, namespace.Name, err) } else { sccRestrictivness = append(sccRestrictivness, restrictivness) } // scc.ForbiddenSysctls <-- only restricts the current allowed set, unused for conversion // scc.AllowedFlexVolumes <-- only restricts the current allowed set, unused for conversion // scc.DefaultAddCapabilities <-- this is still restricted by the set of allowed capabilities // scc.DefaultAllowPrivilegeEscalation <-- this is still restricted by scc.AllowPrivilegeEscalation // scc.FSGroup <-- seems to be ignored by PSa // scc.ReadOnlyRootFilesystem <-- seems to be ignored by PSa // scc.SupplementalGroups <-- seems to be ignored by PSa var restrictiveness = restricted for _, r := range sccRestrictivness { if r == privileged { return privileged, nil } if r > restrictiveness { restrictiveness = r } } return restrictiveness, nil } |
さいごに
2022年ありがとうございました。2023年もよろしくお願いいたします。それでは、良いお年を〜
References
- Pod Security Policies – Kubernetes Documentation
- Pod Security Admission – Kubernetes Documentation
- Pod Security Standards – Kubernetes Documentation
- KEP-2579: Pod Security Admission Control – GitHub
- The Hitchhiker’s Guide to Pod Security – Lachlan Evenson, Microsoft – YouTube
- Managing security context constraints – OpenShift Documentation
- Important OpenShift changes to Pod Security Standards – Red Hat Partner Connect
- Pod Security Admission in OpenShift 4.11
- cluster-policy-controller/pkg/psalabelsyncer at release-4.11 – GitHub
- kubernetes/sample-controller – GitHub
- openshift/enhancements – GitHub
コメント