Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions bin/dockerfiles/mounter.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

# The texera-mounter runs as a per-node privileged DaemonSet. It performs the GeeseFS
# FUSE mount that computing-unit pods used to do themselves, so that CU pods (which run
# untrusted user code) can be unprivileged. It needs python3 (the mounter), fuse3 + geesefs
# (to mount), and util-linux (umount) — all part of a minimal Debian base.
FROM debian:bookworm-slim

ARG GEESEFS_VERSION=v0.43.8
RUN apt-get update \
&& apt-get install -y --no-install-recommends python3 fuse3 mount ca-certificates curl \
&& curl -fsSL -o /usr/local/bin/geesefs \
"https://github.com/yandex-cloud/geesefs/releases/download/${GEESEFS_VERSION}/geesefs-linux-$(dpkg --print-architecture)" \
&& chmod 755 /usr/local/bin/geesefs \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
# allow FUSE mounts to be accessible by other users (the unprivileged CU pod's UID)
&& echo "user_allow_other" >> /etc/fuse.conf

COPY bin/mounter/mounter.py /opt/mounter/mounter.py

EXPOSE 8100
ENTRYPOINT ["python3", "/opt/mounter/mounter.py"]
75 changes: 75 additions & 0 deletions bin/k8s/templates/base/mounter/mounter-daemonset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

# Per-node privileged mounter that performs the GeeseFS FUSE mount on behalf of
# (unprivileged) computing-unit pods. It mounts under a host directory and the mount
# propagates into each CU pod via mountPropagation, so CU pods — which run untrusted user
# code — never need to be privileged. This is the ONLY privileged component of the mount
# feature, and it runs only trusted mount code (never user code).
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ .Release.Name }}-mounter
namespace: {{ .Release.Namespace }}
labels:
app: {{ .Release.Name }}-mounter
spec:
selector:
matchLabels:
app: {{ .Release.Name }}-mounter
template:
metadata:
labels:
app: {{ .Release.Name }}-mounter
spec:
serviceAccountName: {{ .Values.mounter.serviceAccountName }}
tolerations:
- operator: "Exists"
containers:
- name: mounter
image: {{ .Values.texera.imageRegistry }}/{{ .Values.mounter.imageName }}:{{ .Values.texera.imageTag }}
imagePullPolicy: {{ .Values.mounter.imagePullPolicy }}
securityContext:
privileged: true
ports:
- name: mounter
containerPort: {{ .Values.mounter.port }}
hostPort: {{ .Values.mounter.port }}
env:
- name: MOUNTER_PORT
value: "{{ .Values.mounter.port }}"
- name: MOUNT_ROOT
value: "{{ .Values.mounter.hostMountRoot }}"
- name: POOL_NAMESPACE
value: "{{ .Values.workflowComputingUnitPool.namespace }}"
- name: CU_POD_NAME_PREFIX
value: "{{ .Values.workflowComputingUnitPool.podNamePrefix }}"
readinessProbe:
httpGet:
path: /healthz
port: mounter
initialDelaySeconds: 3
periodSeconds: 10
volumeMounts:
- name: texera-mounts
mountPath: {{ .Values.mounter.hostMountRoot }}
mountPropagation: Bidirectional
volumes:
- name: texera-mounts
hostPath:
path: {{ .Values.mounter.hostMountRoot }}
type: DirectoryOrCreate
48 changes: 48 additions & 0 deletions bin/k8s/templates/base/mounter/mounter-rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

# The mounter watches computing-unit pods (in the pool namespace) so it can unmount a CU's
# mounts as soon as its pod is deleted. It needs only read access to pods.
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.mounter.serviceAccountName }}
namespace: {{ .Release.Namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ .Release.Name }}-mounter
namespace: {{ .Values.workflowComputingUnitPool.namespace }}
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ .Release.Name }}-mounter-binding
namespace: {{ .Values.workflowComputingUnitPool.namespace }}
subjects:
- kind: ServiceAccount
name: {{ .Values.mounter.serviceAccountName }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: Role
name: {{ .Release.Name }}-mounter
apiGroup: rbac.authorization.k8s.io
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ spec:
value: {{ .Values.workflowComputingUnitPool.namespace }}
- name: KUBERNETES_COMPUTE_UNIT_SERVICE_NAME
value: {{ .Values.workflowComputingUnitPool.name }}-svc
- name: KUBERNETES_COMPUTE_UNIT_POD_NAME_PREFIX
value: {{ .Values.workflowComputingUnitPool.podNamePrefix }}
- name: KUBERNETES_IMAGE_NAME
value: {{ .Values.texera.imageRegistry }}/{{ .Values.workflowComputingUnitPool.imageName }}:{{ .Values.texera.imageTag }}
# TexeraDB Access
Expand Down
13 changes: 13 additions & 0 deletions bin/k8s/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,9 @@ workflowComputingUnitPool:
name: texera-workflow-computing-unit
# Note: the namespace of the workflow computing unit pool might conflict when there are multiple texera deployments in the same cluster
namespace: texera-workflow-computing-unit-pool
# Computing unit pods are named "<podNamePrefix>-<cuid>". The manager creates them under
# this name and the mounter reads a CU's id back out of it, so both are given this value.
podNamePrefix: computing-unit
# Max number of resources allocated for computing units
maxRequestedResources:
cpu: 100
Expand All @@ -298,6 +301,16 @@ workflowComputingUnitPool:
port: 8085
targetPort: 8085

# Per-node privileged DaemonSet that performs the GeeseFS FUSE mount for computing-unit
# pods, so the CU pods stay unprivileged. port/hostMountRoot MUST match the values read by
# the computing-unit manager (kubernetes.mounter-port / kubernetes.mounter-host-root).
mounter:
imageName: texera-mounter
imagePullPolicy: IfNotPresent
port: 8100
hostMountRoot: /var/lib/texera-mounts
serviceAccountName: texera-mounter-service-account

texeraEnvVars:
- name: USER_SYS_ADMIN_USERNAME
value: "texera"
Expand Down
Loading
Loading