Files
yucca/charts/platform/rook-ceph-cluster/templates/loop-device.yaml
T

92 lines
4.0 KiB
YAML

{{- if .Values.loopDevice.enabled }}
# DEV ONLY. k3d nodes have no spare block device, and Rook OSDs need raw block
# storage (k3d's local-path provisioner is filesystem-only). This privileged
# DaemonSet creates a sparse image on the node and losetup-attaches it to the
# loop device (storage.device) that the CephCluster names explicitly. The
# container stays alive so the attachment persists.
#
# It runs on cephImage rather than something small like alpine because every
# OSD in the cluster is blocked on this attachment: a registry the node has to
# reach for this pod alone is a single point of failure, and a hung pull of one
# surfaced half an hour later as an unrelated yucca-michael config error. This
# image the node must pull anyway, and Tilt prepulls it the moment the cluster
# exists. It carries losetup/truncate/mknod, so nothing has to be installed.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ .Values.clusterName }}-loop-device
labels:
app.kubernetes.io/name: rook-ceph-loop-device
spec:
selector:
matchLabels:
app.kubernetes.io/name: rook-ceph-loop-device
template:
metadata:
labels:
app.kubernetes.io/name: rook-ceph-loop-device
spec:
hostPID: true
containers:
- name: loop-device
image: {{ .Values.cephImage }}
securityContext:
privileged: true
command: ["/bin/sh", "-c"]
args:
- |
set -eu
IMG="{{ .Values.loopDevice.path }}"
DEV="{{ .Values.storage.device }}"
mkdir -p "$(dirname "$IMG")"
[ -f "$IMG" ] || truncate -s {{ .Values.loopDevice.sizeGiB }}G "$IMG"
# Loop attachments live in the HOST kernel, shared by every k3d
# cluster on it, and outlive the cluster that made them. One whose
# image is deleted belongs to a torn-down cluster (a k3d:reset, or
# a finished CI run on the same host) and would also make Rook skip
# the device for its stale bluestore signature.
for d in $(losetup -a | grep -F "($IMG (deleted))" | cut -d: -f1); do
losetup -d "$d" || true
done
# Every cluster's image has the same path, so BACK-FILE cannot tell
# ours from a live neighbour's; -j matches by inode. Sharing a
# neighbour's device leaves this cluster with no OSD and surfaces
# half an hour later as an unrelated timeout, so fail here instead.
if losetup "$DEV" >/dev/null 2>&1 && ! losetup -j "$IMG" | cut -d: -f1 | grep -qx "$DEV"; then
echo "$DEV is attached to another live cluster's image; give this cluster its own storage.device" >&2
exit 1
fi
# our image attached on some other device = corruption hazard
for d in $(losetup -j "$IMG" | cut -d: -f1); do
[ "$d" = "$DEV" ] || losetup -d "$d" || true
done
if ! losetup "$DEV" >/dev/null 2>&1; then
[ -e "$DEV" ] || mknod "$DEV" b 7 "${DEV#/dev/loop}"
losetup "$DEV" "$IMG"
fi
echo "loop device for Rook OSD: $(losetup -j "$IMG" | cut -d: -f1) ($IMG)"
# keep the container (and thus the loop attachment) alive
while true; do sleep 3600; done
readinessProbe:
exec:
command:
- /bin/sh
- -c
- 'losetup -j "{{ .Values.loopDevice.path }}" | cut -d: -f1 | grep -qx "{{ .Values.storage.device }}"'
periodSeconds: 5
volumeMounts:
- name: dev
mountPath: /dev
mountPropagation: Bidirectional
- name: rook-data
mountPath: {{ dir .Values.loopDevice.path }}
volumes:
- name: dev
hostPath:
path: /dev
- name: rook-data
hostPath:
path: {{ dir .Values.loopDevice.path }}
type: DirectoryOrCreate
{{- end }}