@@ -28,10 +28,14 @@ import (
2828 "sigs.k8s.io/controller-runtime/pkg/webhook"
2929)
3030
31- // log is for logging in this package.
32- var rayclusterlog = logf .Log .WithName ("raycluster-resource" )
31+ var (
32+ // log is for logging in this package.
33+ rayclusterlog = logf .Log .WithName ("raycluster-resource" )
34+ baseDomain string = ""
35+ )
3336
34- func (r * RayClusterDefaulter ) SetupWebhookWithManager (mgr ctrl.Manager ) error {
37+ func (r * RayClusterDefaulter ) SetupWebhookWithManager (mgr ctrl.Manager , domain string ) error {
38+ baseDomain = domain
3539 return ctrl .NewWebhookManagedBy (mgr ).
3640 For (& rayv1.RayCluster {}).
3741 WithDefaulter (& RayClusterDefaulter {}).
@@ -49,17 +53,36 @@ func (r *RayClusterDefaulter) Default(ctx context.Context, obj runtime.Object) e
4953 raycluster := obj .(* rayv1.RayCluster )
5054
5155 rayclusterlog .Info ("default" , "name" , raycluster .Name )
56+ oauthExists := false
57+ initHeadExists := false
58+ workerHeadExists := false
5259 // Check and add OAuth proxy if it does not exist.
53- alreadyExists := false
5460 for _ , container := range raycluster .Spec .HeadGroupSpec .Template .Spec .Containers {
5561 if container .Name == "oauth-proxy" {
5662 rayclusterlog .Info ("OAuth sidecar already exists, no patch needed" )
57- alreadyExists = true
63+ oauthExists = true
64+ break // exits the for loop
65+ }
66+ }
67+
68+ // Check for the create-cert Init Containers
69+ for _ , container := range raycluster .Spec .HeadGroupSpec .Template .Spec .InitContainers {
70+ if container .Name == "create-cert" {
71+ rayclusterlog .Info ("Head Init Containers already exist, no patch needed" )
72+ initHeadExists = true
73+ break // exits the for loop
74+ }
75+ }
76+ // Check fot the create-cert Init Container WorkerGroupSpec
77+ for _ , container := range raycluster .Spec .WorkerGroupSpecs [0 ].Template .Spec .InitContainers {
78+ if container .Name == "create-cert" {
79+ rayclusterlog .Info ("Worker Init Containers already exist, no patch needed" )
80+ workerHeadExists = true
5881 break // exits the for loop
5982 }
6083 }
6184
62- if ! alreadyExists {
85+ if ! oauthExists {
6386 rayclusterlog .Info ("Adding OAuth sidecar container" )
6487 // definition of the new container
6588 newOAuthSidecar := corev1.Container {
@@ -119,5 +142,127 @@ func (r *RayClusterDefaulter) Default(ctx context.Context, obj runtime.Object) e
119142 raycluster .Spec .HeadGroupSpec .Template .Spec .ServiceAccountName = raycluster .Name + "-oauth-proxy"
120143 }
121144 }
145+ mtlsPatch (raycluster , initHeadExists , workerHeadExists )
122146 return nil
123147}
148+
149+ func mtlsPatch (raycluster * rayv1.RayCluster , initHeadExists bool , workerHeadExists bool ) {
150+
151+ rayclusterlog .Info ("creating json patch for RayCluster initContainers" )
152+
153+ // Volume Mounts for the Init Containers
154+ key_volumes := []corev1.VolumeMount {
155+ {
156+ Name : "ca-vol" ,
157+ MountPath : "/home/ray/workspace/ca" ,
158+ ReadOnly : true ,
159+ },
160+ {
161+ Name : "server-cert" ,
162+ MountPath : "/home/ray/workspace/tls" ,
163+ ReadOnly : false ,
164+ },
165+ }
166+
167+ // Service name for basic interactive
168+ svcDomain := raycluster .Name + "-head-svc." + raycluster .Namespace + ".svc"
169+ // Ca Secret generated by the SDK
170+ secretName := `ca-secret-` + raycluster .Name
171+
172+ // Env variables for Worker & Head Containers
173+ envList := []corev1.EnvVar {
174+ {
175+ Name : "MY_POD_IP" ,
176+ ValueFrom : & corev1.EnvVarSource {
177+ FieldRef : & corev1.ObjectFieldSelector {
178+ FieldPath : "status.podIP" ,
179+ },
180+ },
181+ },
182+ {
183+ Name : "RAY_USE_TLS" ,
184+ Value : "1" ,
185+ },
186+ {
187+ Name : "RAY_TLS_SERVER_CERT" ,
188+ Value : "/home/ray/workspace/tls/server.crt" ,
189+ },
190+ {
191+ Name : "RAY_TLS_SERVER_KEY" ,
192+ Value : "/home/ray/workspace/tls/server.key" ,
193+ },
194+ {
195+ Name : "RAY_TLS_CA_CERT" ,
196+ Value : "/home/ray/workspace/tls/ca.crt" ,
197+ },
198+ }
199+
200+ // Volumes for the main container of Head and worker
201+ caVolumes := []corev1.Volume {
202+ {
203+ Name : "ca-vol" ,
204+ VolumeSource : corev1.VolumeSource {
205+ Secret : & corev1.SecretVolumeSource {
206+ SecretName : secretName ,
207+ },
208+ },
209+ },
210+ {
211+ Name : "server-cert" ,
212+ VolumeSource : corev1.VolumeSource {
213+ EmptyDir : & corev1.EmptyDirVolumeSource {},
214+ },
215+ },
216+ }
217+
218+ if ! initHeadExists {
219+ rayClientRoute := "rayclient-" + raycluster .Name + "-" + raycluster .Namespace + "." + baseDomain
220+ initContainerHead := corev1.Container {
221+ Name : "create-cert" ,
222+ Image : "quay.io/project-codeflare/ray:latest-py39-cu118" ,
223+ Command : []string {
224+ "sh" ,
225+ "-c" ,
226+ `cd /home/ray/workspace/tls && openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr -subj '/CN=ray-head' && printf "authorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nsubjectAltName = @alt_names\n[alt_names]\nDNS.1 = 127.0.0.1\nDNS.2 = localhost\nDNS.3 = ${FQ_RAY_IP}\nDNS.4 = $(awk 'END{print $1}' /etc/hosts)\nDNS.5 = ` + rayClientRoute + `\nDNS.6 = ` + svcDomain + `">./domain.ext && cp /home/ray/workspace/ca/* . && openssl x509 -req -CA ca.crt -CAkey ca.key -in server.csr -out server.crt -days 365 -CAcreateserial -extfile domain.ext` ,
227+ },
228+ VolumeMounts : key_volumes ,
229+ }
230+
231+ // Append the list of environment variables for the ray-head container
232+ for index , container := range raycluster .Spec .HeadGroupSpec .Template .Spec .Containers {
233+ if container .Name == "ray-head" {
234+ raycluster .Spec .HeadGroupSpec .Template .Spec .Containers [index ].Env = append (raycluster .Spec .HeadGroupSpec .Template .Spec .Containers [index ].Env , envList ... )
235+ }
236+ }
237+
238+ // Append the create-cert Init Container
239+ raycluster .Spec .HeadGroupSpec .Template .Spec .InitContainers = append (raycluster .Spec .HeadGroupSpec .Template .Spec .InitContainers , initContainerHead )
240+
241+ // Append the CA volumes
242+ raycluster .Spec .HeadGroupSpec .Template .Spec .Volumes = append (raycluster .Spec .HeadGroupSpec .Template .Spec .Volumes , caVolumes ... )
243+ }
244+
245+ if ! workerHeadExists {
246+ initContainerWorker := corev1.Container {
247+ Name : "create-cert" ,
248+ Image : "quay.io/project-codeflare/ray:latest-py39-cu118" ,
249+ Command : []string {
250+ "sh" ,
251+ "-c" ,
252+ `cd /home/ray/workspace/tls && openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr -subj '/CN=ray-head' && printf "authorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nsubjectAltName = @alt_names\n[alt_names]\nDNS.1 = 127.0.0.1\nDNS.2 = localhost\nDNS.3 = ${FQ_RAY_IP}\nDNS.4 = $(awk 'END{print $1}' /etc/hosts)">./domain.ext && cp /home/ray/workspace/ca/* . && openssl x509 -req -CA ca.crt -CAkey ca.key -in server.csr -out server.crt -days 365 -CAcreateserial -extfile domain.ext` ,
253+ },
254+ VolumeMounts : key_volumes ,
255+ }
256+ // Append the CA volumes
257+ raycluster .Spec .WorkerGroupSpecs [0 ].Template .Spec .Volumes = append (raycluster .Spec .WorkerGroupSpecs [0 ].Template .Spec .Volumes , caVolumes ... )
258+ // Append the create-cert Init Container
259+ raycluster .Spec .WorkerGroupSpecs [0 ].Template .Spec .InitContainers = append (raycluster .Spec .WorkerGroupSpecs [0 ].Template .Spec .InitContainers , initContainerWorker )
260+
261+ // Append the list of environment variables for the machine-learning container
262+ for index , container := range raycluster .Spec .WorkerGroupSpecs [0 ].Template .Spec .Containers {
263+ if container .Name == "machine-learning" {
264+ raycluster .Spec .WorkerGroupSpecs [0 ].Template .Spec .Containers [index ].Env = append (raycluster .Spec .WorkerGroupSpecs [0 ].Template .Spec .Containers [index ].Env , envList ... )
265+ }
266+ }
267+ }
268+ }
0 commit comments