In the end, I found a solution. It’s pretty simple and doesn’t consider isolation or anything like that, but hopefully, it can help anyone who needs it.
- I roughly referred to kubespawner and found that you can execute copy tasks and put them into the hub’s pod,
import asyncio
from kubernetes_asyncio import client, config
from kubernetes_asyncio.client import Configuration
import os
import time
async def create_job():
# check env
all_variables = os.environ
print("all_variables",all_variables)
config.load_incluster_config()
global_conf = Configuration.get_default_copy()
print("global_conf",vars(global_conf))
k8s_batch_client = client.BatchV1Api()
print("k8s batch client",k8s_batch_client)
source = "spinq-5fsw-5f001sw001firstserver"
destination = "mila-2duatmilafirstserver"
file_path = "sharefolder"
job = client.V1Job(
api_version="batch/v1",
kind="Job",
metadata=client.V1ObjectMeta(
# set job name
name="copy-files-" + time.strftime("%Y%m%d%H%M%S") ,
namespace="jhub"
),
spec=client.V1JobSpec(
template=client.V1PodTemplateSpec(
spec=client.V1PodSpec(
volumes=[
client.V1Volume(
name="source-pvc",
persistent_volume_claim=client.V1PersistentVolumeClaimVolumeSource(
claim_name="claim-"+source
)
),
client.V1Volume(
name="destination-pvc",
persistent_volume_claim=client.V1PersistentVolumeClaimVolumeSource(
claim_name="claim-"+destination
)
),
],
containers=[
client.V1Container(
name="task",
image="busybox",
command=["/bin/sh", "-c"],
args=[f"adduser -D -u 1000 jovyan && cp -R /src-dir/{file_path} /dst-dir/shared-workspace/ && chown -R jovyan /dst-dir"],
volume_mounts=[
client.V1VolumeMount(
name="source-pvc",
mount_path="/src-dir"
),
client.V1VolumeMount(
name="destination-pvc",
mount_path="/dst-dir"
),
],
),
],
restart_policy="Never",
),
),
),
)
print("job",job)
await k8s_batch_client.create_namespaced_job(namespace="jhub", body=job)
await k8s_batch_client.api_client.close()
# run
loop = asyncio.get_event_loop()
loop.run_until_complete(create_job())
loop.close()
- However, there was a problem: the hub does not have permission to create jobs. So next, I added the job creation authority for the hub in chart yaml template (/template/hub/rbac.yaml),
{{- if .Values.rbac.create -}}
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ include "jupyterhub.hub.fullname" . }}
labels:
{{- include "jupyterhub.labels" . | nindent 4 }}
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods", "persistentvolumeclaims", "secrets", "services"]
verbs: ["get", "watch", "list", "create", "delete"]
- apiGroups: [""] # "" indicates the core API group
resources: ["events"]
verbs: ["get", "watch", "list"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["create"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ include "jupyterhub.hub.fullname" . }}
labels:
{{- include "jupyterhub.labels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: {{ include "jupyterhub.hub-serviceaccount.fullname" . }}
namespace: "{{ .Release.Namespace }}"
roleRef:
kind: Role
name: {{ include "jupyterhub.hub.fullname" . }}
apiGroup: rbac.authorization.k8s.io
{{- end }}
- Finally, I added a file transfer interface for the hub.