Skip to content

Instantly share code, notes, and snippets.

@feiskyer
Created September 19, 2016 00:44
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save feiskyer/8d41ec27ce449e162d8e18f643fcca29 to your computer and use it in GitHub Desktop.
Save feiskyer/8d41ec27ce449e162d8e18f643fcca29 to your computer and use it in GitHub Desktop.
Kubernetes flex volume

Flexvolume

Flexvolume enables users to mount vendor volumes into kubernetes. It expects vendor drivers are installed in the volume plugin path on every kubelet node.

It allows for vendors to develop their own drivers to mount volumes on nodes.

Note: Flexvolume is an alpha feature and is most likely to change in future

Prerequisites

Install the vendor driver on all nodes in the kubelet plugin path. Path for installing the plugin: /usr/libexec/kubernetes/kubelet-plugins/volume/exec/<vendor~driver>/<driver>

For example to add a 'cifs' driver, by vendor 'foo' install the driver at: /usr/libexec/kubernetes/kubelet-plugins/volume/exec/<foo~cifs>/cifs

Plugin details

Driver will be invoked with 'Init' to initalize the driver. It will be invoked with 'attach' to attach the volume and with 'detach' to detach the volume from the kubelet node. It also supports custom mounts using 'mount' and 'unmount' callouts to the driver.

Driver invocation model:

Init: <driver executable> init

Attach: <driver executable> attach <json options>

Detach: <driver executable> detach <mount device>

Mount: <driver executable> mount <target mount dir> <mount device> <json options>

Unmount: <driver executable> unmount <mount dir>

See lvm[lvm] for a quick example on how to write a simple flexvolume driver.

Example of Flexvolume

See nginx.yaml[nginx.yaml] for a quick example on how to use Flexvolume in a pod.

#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# Licensed 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.
usage() {
err "Invalid usage. Usage: "
err "\t$0 init"
err "\t$0 attach <json params>"
err "\t$0 detach <mount device>"
err "\t$0 mount <mount dir> <mount device> <json params>"
err "\t$0 unmount <mount dir>"
exit 1
}
err() {
echo -ne $* 1>&2
}
log() {
echo -ne $* >&1
}
ismounted() {
MOUNT=`findmnt -n ${MNTPATH} 2>/dev/null | cut -d' ' -f1`
if [ "${MOUNT}" == "${MNTPATH}" ]; then
echo "1"
else
echo "0"
fi
}
attach() {
VOLUMEID=$(echo $1 | jq -r '.volumeID')
SIZE=$(echo $1 | jq -r '.size')
VG=$(echo $1|jq -r '.volumegroup')
DMDEV="/dev/mapper/${VG}-${VOLUMEID}"
if [ ! -b "${DMDEV}" ]; then
err "{\"status\": \"Failure\", \"message\": \"Volume ${VOLUMEID} does not exist\"}"
exit 1
fi
log "{\"status\": \"Success\", \"device\":\"${DMDEV}\"}"
exit 0
}
detach() {
log "{\"status\": \"Success\"}"
exit 0
}
domount() {
MNTPATH=$1
DMDEV=$2
FSTYPE=$(echo $3|jq -r '.["kubernetes.io/fsType"]')
if [ ! -b "${DMDEV}" ]; then
err "{\"status\": \"Failure\", \"message\": \"${DMDEV} does not exist\"}"
exit 1
fi
if [ $(ismounted) -eq 1 ] ; then
log "{\"status\": \"Success\"}"
exit 0
fi
VOLFSTYPE=`blkid -o udev ${DMDEV} 2>/dev/null|grep "ID_FS_TYPE"|cut -d"=" -f2`
if [ "${VOLFSTYPE}" == "" ]; then
mkfs -t ${FSTYPE} ${DMDEV}
if [ $? -ne 0 ]; then
err "{ \"status\": \"Failure\", \"message\": \"Failed to create fs ${FSTYPE} on device ${DMDEV}\"}"
exit 1
fi
fi
mkdir -p ${MNTPATH} &> /dev/null
mount ${DMDEV} ${MNTPATH} &> /dev/null
if [ $? -ne 0 ]; then
err "{ \"status\": \"Failure\", \"message\": \"Failed to mount device ${DMDEV} at ${MNTPATH}\"}"
exit 1
fi
log "{\"status\": \"Success\"}"
exit 0
}
unmount() {
MNTPATH=$1
if [ $(ismounted) -eq 0 ] ; then
log "{\"status\": \"Success\"}"
exit 0
fi
umount ${MNTPATH} &> /dev/null
if [ $? -ne 0 ]; then
err "{ \"status\": \"Failed\", \"message\": \"Failed to unmount volume at ${MNTPATH}\"}"
exit 1
fi
rmdir ${MNTPATH} &> /dev/null
log "{\"status\": \"Success\"}"
exit 0
}
op=$1
if [ "$op" = "init" ]; then
log "{\"status\": \"Success\"}"
exit 0
fi
if [ $# -lt 2 ]; then
usage
fi
shift
case "$op" in
attach)
attach $*
;;
detach)
detach $*
;;
mount)
domount $*
;;
unmount)
unmount $*
;;
*)
usage
esac
exit 1
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: test
mountPath: /data
ports:
- containerPort: 80
volumes:
- name: test
flexVolume:
driver: "kubernetes.io/lvm"
fsType: "ext4"
options:
volumeID: "vol1"
size: "1000m"
volumegroup: "kube_vg"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment