Skip to content

Commit 1ba3eb2

Browse files
Add securityContext to RayCluster based on Namespace labels
1 parent cbbee9d commit 1ba3eb2

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

config/rbac/role.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ rules:
1414
- patch
1515
- update
1616
- watch
17+
- apiGroups:
18+
- ""
19+
resources:
20+
- namespaces
21+
verbs:
22+
- get
23+
- list
24+
- watch
1725
- apiGroups:
1826
- ""
1927
resources:

pkg/controllers/raycluster_webhook.go

+30
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"k8s.io/apimachinery/pkg/util/validation/field"
2828
"k8s.io/utils/ptr"
2929
ctrl "sigs.k8s.io/controller-runtime"
30+
"sigs.k8s.io/controller-runtime/pkg/client"
3031
logf "sigs.k8s.io/controller-runtime/pkg/log"
3132
"sigs.k8s.io/controller-runtime/pkg/webhook"
3233
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
@@ -46,6 +47,7 @@ var rayclusterlog = logf.Log.WithName("raycluster-resource")
4647
func SetupRayClusterWebhookWithManager(mgr ctrl.Manager, cfg *config.KubeRayConfiguration) error {
4748
rayClusterWebhookInstance := &rayClusterWebhook{
4849
Config: cfg,
50+
Client: mgr.GetClient(),
4951
}
5052
return ctrl.NewWebhookManagedBy(mgr).
5153
For(&rayv1.RayCluster{}).
@@ -56,9 +58,11 @@ func SetupRayClusterWebhookWithManager(mgr ctrl.Manager, cfg *config.KubeRayConf
5658

5759
// +kubebuilder:webhook:path=/mutate-ray-io-v1-raycluster,mutating=true,failurePolicy=fail,sideEffects=None,groups=ray.io,resources=rayclusters,verbs=create,versions=v1,name=mraycluster.ray.openshift.ai,admissionReviewVersions=v1
5860
// +kubebuilder:webhook:path=/validate-ray-io-v1-raycluster,mutating=false,failurePolicy=fail,sideEffects=None,groups=ray.io,resources=rayclusters,verbs=create;update,versions=v1,name=vraycluster.ray.openshift.ai,admissionReviewVersions=v1
61+
// +kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;watch
5962

6063
type rayClusterWebhook struct {
6164
Config *config.KubeRayConfiguration
65+
Client client.Client
6266
}
6367

6468
var _ webhook.CustomDefaulter = &rayClusterWebhook{}
@@ -123,6 +127,32 @@ func (w *rayClusterWebhook) Default(ctx context.Context, obj runtime.Object) err
123127
}
124128
}
125129

130+
hasSecurityLabels, err := namespaceHasSecurityLabels(ctx, w.Client, rayCluster.Namespace)
131+
if err != nil {
132+
rayclusterlog.Error(err, "Failed to check namespace resource labels")
133+
return err
134+
}
135+
if hasSecurityLabels {
136+
secureContext := corev1.SecurityContext{
137+
AllowPrivilegeEscalation: ptr.To(false),
138+
Capabilities: &corev1.Capabilities{
139+
Drop: []corev1.Capability{"ALL"},
140+
},
141+
SeccompProfile: &corev1.SeccompProfile{
142+
Type: "RuntimeDefault",
143+
},
144+
}
145+
// Set the security context for the head container and worker containers
146+
for i := range rayCluster.Spec.HeadGroupSpec.Template.Spec.Containers {
147+
rayCluster.Spec.HeadGroupSpec.Template.Spec.Containers[i].SecurityContext = &secureContext
148+
}
149+
for i := range rayCluster.Spec.WorkerGroupSpecs {
150+
for j := range rayCluster.Spec.WorkerGroupSpecs[i].Template.Spec.Containers {
151+
rayCluster.Spec.WorkerGroupSpecs[i].Template.Spec.Containers[j].SecurityContext = &secureContext
152+
}
153+
}
154+
}
155+
126156
return nil
127157
}
128158

pkg/controllers/support.go

+16
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
package controllers
22

33
import (
4+
"context"
5+
46
rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
57

68
corev1 "k8s.io/api/core/v1"
79
networkingv1 "k8s.io/api/networking/v1"
810
"k8s.io/apimachinery/pkg/api/equality"
11+
"k8s.io/apimachinery/pkg/labels"
912
"k8s.io/apimachinery/pkg/util/intstr"
1013
"k8s.io/apimachinery/pkg/util/validation/field"
1114
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
1215
networkingv1ac "k8s.io/client-go/applyconfigurations/networking/v1"
16+
"sigs.k8s.io/controller-runtime/pkg/client"
1317

1418
routeapply "github.com/openshift/client-go/route/applyconfigurations/route/v1"
1519
)
@@ -156,3 +160,15 @@ func withEnvVarName(name string) compare[corev1.EnvVar] {
156160
return e1.Name == name
157161
}
158162
}
163+
164+
func namespaceHasSecurityLabels(ctx context.Context, kubeClient client.Client, namespaceName string) (bool, error) {
165+
namespace := &corev1.Namespace{}
166+
if err := kubeClient.Get(ctx, client.ObjectKey{Name: namespaceName}, namespace); err != nil {
167+
return false, err
168+
}
169+
labelSelector := labels.SelectorFromSet(labels.Set{
170+
"pod-security.kubernetes.io/enforce": "restricted",
171+
"pod-security.kubernetes.io/enforce-version": "v1.24",
172+
})
173+
return labelSelector.Matches(labels.Set(namespace.Labels)), nil
174+
}

0 commit comments

Comments
 (0)