Skip to content

Commit b32ddf4

Browse files
committed
feat: start of work to support dra
We want to test if DRA (and dranet) can better utilize the infiniband devices. We have them working with UCX, and actually I am not sure if this will add anything, but it was worth trying for minimally the learning. Signed-off-by: vsoch <vsoch@users.noreply.github.com>
1 parent 611c0ba commit b32ddf4

8 files changed

Lines changed: 129 additions & 24 deletions

File tree

Dockerfile.dra

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM ghcr.io/google/dranet:v0.4.0 AS builder
2+
3+
# podman build --userns-uid-map=0:0:1 --userns-uid-map=1:1:1999 --userns-uid-map=65534:2000:2 -f $(pwd)/Dockerfile.dra -t usernetes_dra $(pwd)
4+
# docker build -t ghcr.io/converged-computing/usernetes:dra .
5+
# make up && make kubeadm-init && make dra && make kubeconfig && kubectl apply -f Makefile.d/dra/rbac.yaml && podman restart dranet-driver
6+
7+
# We can likely use ubuntu:24.04, I am reproducing the node environment as much as possible.
8+
FROM docker.io/kindest/node:v1.33.0@sha256:91e9ed777db80279c22d1d1068c091b899b2078506e4a0f797fbf6e397c0b0b2
9+
RUN apt-get update && apt-get install -y ca-certificates
10+
COPY cspca.llnl.gov.cer.pem /usr/local/share/ca-certificates/
11+
COPY cspca.cer.pem /usr/local/share/ca-certificates/
12+
RUN update-ca-certificates
13+
RUN apt-get update && \
14+
apt-get install -y --no-install-recommends kmod libibverbs-dev librdmacm-dev rdma-core libnl-3-dev ibverbs-utils libnl-route-3-dev
15+
16+
COPY --from=builder /dranet /dranet
17+
ENTRYPOINT ["/dranet"]

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ up: check-preflight
8484
# Podman creates cni files in a shared location, this ensures unique names that do not clobbed one another
8585
sed -i "s/default_network/$(HOSTNAME)/g" docker-compose.yaml
8686
$(COMPOSE) up --build -d
87+
$(NODE_SHELL) /bin/bash /usernetes/Makefile.d/dra/update-containerd.sh
8788

8889
.PHONY: down
8990
down:
@@ -111,6 +112,15 @@ ifeq ($(shell command -v kubectl 2> /dev/null),)
111112
@echo "make kubectl"
112113
endif
113114

115+
.PHONY: kubeconfig
116+
dra:
117+
$(NODE_SHELL) kubectl apply -f /usernetes/Makefile.d/dra/rbac.yaml
118+
# These are needed if you want ibv_devinfo to work
119+
#$(CONTAINER_ENGINE) exec dranet-driver mkdir -p /etc/libibverbs.d
120+
#$(CONTAINER_ENGINE) exec dranet-driver echo "driver mlx4" >> /etc/libibverbs.d/mlx4.driver
121+
#$(CONTAINER_ENGINE) exec dranet-driver echo "driver mlx5" >> /etc/libibverbs.d/mlx5.driver
122+
123+
114124
.PHONY: kubectl
115125
kubectl:
116126
$(COMPOSE) exec -T --workdir=/usr/bin $(NODE_SERVICE_NAME) tar c kubectl | tar xv

Makefile.d/dra/rbac.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
apiVersion: rbac.authorization.k8s.io/v1
2+
kind: ClusterRole
3+
metadata:
4+
name: dranet-admin-role
5+
rules:
6+
- apiGroups: ["resource.k8s.io"]
7+
resources: ["resourceslices", "resourceclaims", "resourceclaimtemplates"]
8+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
9+
---
10+
apiVersion: rbac.authorization.k8s.io/v1
11+
kind: ClusterRoleBinding
12+
metadata:
13+
name: dranet-admin-binding
14+
subjects:
15+
- kind: User
16+
name: kubernetes-admin
17+
apiGroup: rbac.authorization.k8s.io
18+
roleRef:
19+
kind: ClusterRole
20+
name: dranet-admin-role
21+
apiGroup: rbac.authorization.k8s.io
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
set -o errexit
3+
set -o pipefail
4+
set -o nounset
5+
set -x
6+
if grep -q "io.containerd.nri.v1.nri" /etc/containerd/config.toml
7+
then
8+
echo "containerd config contains NRI reference already; taking no action"
9+
else
10+
echo "containerd config does not mention NRI, thus enabling it";
11+
printf '%s\n' "[plugins.\"io.containerd.nri.v1.nri\"]" " disable = false" " disable_connections = false" " plugin_config_path = \"/etc/nri/conf.d\"" " plugin_path = \"/opt/nri/plugins\"" " plugin_registration_timeout = \"5s\"" " plugin_request_timeout = \"5s\"" " socket_path = \"/var/run/nri/nri.sock\"" >> /etc/containerd/config.toml
12+
echo "restarting containerd"
13+
systemctl restart containerd
14+
fi

docker-compose.yaml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ services:
1010
networks:
1111
default_network:
1212
ipv4_address: ${NODE_IP}
13+
expose:
14+
- "${PORT_KUBE_APISERVER}"
1315
ports:
1416
# <host>:<container>
1517
# etcd (default: 2379)
@@ -27,8 +29,7 @@ services:
2729
- node-var:/var
2830
- node-opt:/opt
2931
- node-etc:/etc
30-
- type: tmpfs
31-
target: /run
32+
- node-run:/run
3233
- type: tmpfs
3334
target: /tmp
3435
working_dir: /usernetes
@@ -45,6 +46,29 @@ services:
4546
"nerdctl/bypass4netns": "${BYPASS4NETNS:-false}"
4647
"nerdctl/bypass4netns-ignore-bind": "true"
4748
"nerdctl/bypass4netns-ignore-subnets": "${BYPASS4NETNS_IGNORE_SUBNETS:-}"
49+
50+
dranet:
51+
image: usernetes_dra
52+
imagePullPolicy: Always
53+
container_name: dranet-driver
54+
privileged: true
55+
restart: always
56+
# DraNet needs to see the host network to manage its devices
57+
network_mode: "host"
58+
volumes:
59+
- /boot:/boot:ro
60+
- /lib/modules:/lib/modules:ro
61+
- node-var:/var
62+
- node-run:/run:ro
63+
- node-etc:/etc
64+
extra_hosts:
65+
# We need to be able to see the api server
66+
- "${NODE_NAME}:${HOST_IP}"
67+
command:
68+
- --kubeconfig=/etc/kubernetes/admin.conf
69+
- --hostname-override=${NODE_NAME}
70+
- --filter=true
71+
4872
networks:
4973
default_network:
5074
ipam:
@@ -53,6 +77,7 @@ networks:
5377
# The node IP here is not accessible from other nodes.
5478
- subnet: ${NODE_SUBNET}
5579
volumes:
80+
node-run: {}
5681
node-var: {}
5782
node-opt: {}
5883
node-etc: {}

kubeadm-config.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ apiServer:
1515
extraArgs:
1616
- name: etcd-servers
1717
value: https://127.0.0.1:${PORT_ETCD}
18+
- name: runtime-config
19+
value: "api/beta=true"
1820
- name: advertise-address
1921
value: ${HOST_IP}
2022
- name: secure-port
@@ -42,6 +44,8 @@ apiVersion: kubelet.config.k8s.io/v1beta1
4244
failSwapOn: false
4345
port: ${PORT_KUBELET}
4446
featureGates:
47+
DRAResourceClaimDeviceStatus: true
48+
DynamicResourceAllocation: true
4549
KubeletInUserNamespace: true
4650
---
4751
apiVersion: kubeproxy.config.k8s.io/v1alpha1
@@ -54,3 +58,4 @@ conntrack:
5458
tcpEstablishedTimeout: 0s
5559
# Skip setting "net.netfilter.nf_conntrack_tcp_timeout_close"
5660
tcpCloseWaitTimeout: 0s
61+

service/usernetes-start-control-plane.sh

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,24 @@ set -euo pipefail
55
# These are variables we likely will change
66
# LC only supplies podman
77
USERNETES_CONTAINER_TECH=${1:-"podman"}
8-
USERNETES_TEMPLATE_PATH=/usr/workspace/usernetes/usernetes-06-26-2025
8+
USERNETES_TEMPLATE_PATH=/usr/workspace/usernetes/usernetes-dra
99

1010
# We will copy join command here
1111
shared_join_command_dir="/usr/workspace/usernetes"
1212

1313
# The user needs to run the setup script
1414
USERNAME=$(whoami)
1515

16+
# Logging functions for consistency (like Akihiro!)
17+
log() {
18+
echo "$(date '+%Y-%m-%d %H:%M:%S') - INFO - $1"
19+
}
20+
21+
error_exit() {
22+
echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR - $1" >&2
23+
exit 1
24+
}
25+
1626
# This is way a lot for just deriving home, but I'm not convinced it will always
1727
# be defined in the environment
1828
if [[ -z "${HOME:-}" || ! -d "${HOME}" ]]; then
@@ -37,16 +47,6 @@ which podman-compose
3747
# We don't want to use /var because that is a memory based fs
3848
export TMPDIR="/tmp/${USERNAME}"
3949

40-
# Logging functions for consistency (like Akihiro!)
41-
log() {
42-
echo "$(date '+%Y-%m-%d %H:%M:%S') - INFO - $1"
43-
}
44-
45-
error_exit() {
46-
echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR - $1" >&2
47-
exit 1
48-
}
49-
5050
install_kubectl() {
5151
if ! command -v kubectl > /dev/null; then
5252
log "Installing kubectl..."
@@ -131,6 +131,7 @@ sleep 3 # Allow filesystem operations to settle if needed
131131

132132
log "👷 Building Usernetes container image 'usernetes_node'"
133133
${container_runtime_path} build --userns-uid-map=0:0:1 --userns-uid-map=1:1:1999 --userns-uid-map=65534:2000:2 -f $(pwd)/Dockerfile -t usernetes_node $(pwd)
134+
${container_runtime_path} build --userns-uid-map=0:0:1 --userns-uid-map=1:1:1999 --userns-uid-map=65534:2000:2 -f $(pwd)/Dockerfile.dra -t usernetes_dra $(pwd)
134135

135136
cleanup() {
136137
log "🧹 Cleaning up old networks or volumes (best effort)"
@@ -150,12 +151,19 @@ if ! make up; then
150151
fi
151152
sleep 3
152153

154+
153155
log "🔐 Running kubeadm-init with 'make kubeadm-init'"
154156
if ! make kubeadm-init; then
155157
error_exit "Failed 'make kubeadm-init'."
156158
fi
157159
sleep 3
158160

161+
log "👾 Setting up dynamic resource allocation"
162+
if ! make dra; then
163+
error_exit "Failed 'make kubeadm-init'."
164+
fi
165+
sleep 3
166+
159167
log "🥷 Creating kubeconfig with 'make kubeconfig'"
160168
if ! make kubeconfig; then
161169
error_exit "Failed 'make kubeconfig'."
@@ -171,6 +179,10 @@ chmod 600 "${KUBECONFIG}"
171179
# source <(kubectl completion bash)
172180
sleep 3
173181

182+
log "🥷 Install rbac for dranet-driver"
183+
kubectl apply -f Makefile.d/dra/rbac.yaml
184+
${container_runtime_path} restart dranet-driver
185+
174186
# Get control plane node name robustly
175187
log "🍑 Untainting control plane and labeling node"
176188
control_plane_node=""

service/usernetes-start-worker.sh

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set -euo pipefail
55
# These are variables we likely will change
66
# LC only supplies podman
77
USERNETES_CONTAINER_TECH=${1:-"podman"}
8-
USERNETES_TEMPLATE_PATH=/usr/workspace/usernetes/usernetes-06-26-2025
8+
USERNETES_TEMPLATE_PATH=/usr/workspace/usernetes/usernetes-dra
99

1010
# The join command needs to be here
1111
shared_join_command_dir="/usr/workspace/usernetes"
@@ -17,6 +17,16 @@ fi
1717
# The user needs to run the setup script
1818
USERNAME=$(whoami)
1919

20+
# Logging functions for consistency (like Akihiro!)
21+
log() {
22+
echo "$(date '+%Y-%m-%d %H:%M:%S') - INFO - $1"
23+
}
24+
25+
error_exit() {
26+
echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR - $1" >&2
27+
exit 1
28+
}
29+
2030
# This is way a lot for just deriving home, but I'm not convinced it will always
2131
# be defined in the environment
2232
if [[ -z "${HOME:-}" || ! -d "${HOME}" ]]; then
@@ -38,16 +48,6 @@ log " Updated PATH: ${PATH}"
3848
# We don't want to use /var because that is a memory based fs
3949
export TMPDIR="/tmp/${USERNAME}"
4050

41-
# Logging functions for consistency (like Akihiro!)
42-
log() {
43-
echo "$(date '+%Y-%m-%d %H:%M:%S') - INFO - $1"
44-
}
45-
46-
error_exit() {
47-
echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR - $1" >&2
48-
exit 1
49-
}
50-
5151
install_kubectl() {
5252
if ! command -v kubectl > /dev/null; then
5353
log "Installing kubectl..."
@@ -135,6 +135,7 @@ sleep 3
135135

136136
log "👷 Building Usernetes container image 'usernetes_node'"
137137
${container_runtime_path} build --userns-uid-map=0:0:1 --userns-uid-map=1:1:1999 --userns-uid-map=65534:2000:2 -f $(pwd)/Dockerfile -t usernetes_node $(pwd)
138+
${container_runtime_path} build --userns-uid-map=0:0:1 --userns-uid-map=1:1:1999 --userns-uid-map=65534:2000:2 -f $(pwd)/Dockerfile.dra -t usernetes_dra $(pwd)
138139

139140
cleanup() {
140141
log "🧹 Cleaning up old networks or volumes (best effort)"

0 commit comments

Comments
 (0)