Drbd
在容器中编译drbd,将编译后的drbd模块加载到宿主机内核中。然后,容器退出。
docker run \
-v /sys:/sys \
-v /dev:/dev \
-v /usr/src:/usr/src:ro \
-v /lib/modules:/lib/modules \
-e LB_HOW=compile \
-e LB_INSTALL=yes \
--privileged \
--rm \
-i piraeusdatastore/drbd9-centos7:v9.1.7
–privileged: 否则无法执行insmod或modprobe指令 -v /lib/modules:/lib/modules :LB_INSTALL=yes时,编译后,将内核模块拷贝到/lib/modules/$(uname -r)/updates/目录下
rmmod drbd_transport_tcp drbd
rm -rf /lib/modules/$(uname -r)/updates/drbd*
#!/bin/bash
SIGN_KEY=https://packages.linbit.com/package-signing-pubkey.asc
PKGS=/pkgs
HOSTRELEASE=/etc/host-release
die() {
>&2 echo
>&2 echo -e "$1"
exit 1
}
debug() {
[ -n "$LB_DEBUG" ] || return 0
>&2 echo
>&2 echo "DEBUG: $1"
>&2 echo
}
map_dist() {
# allow to override
[ -n "$LB_DIST" ] && { echo "$LB_DIST"; return 0; }
# if we got called, and are that far we can assume this mapped file has to exist
[ -f "$HOSTRELEASE" ] || die "You have to bind-mount /etc/os-release to the container's $HOSTRELEASE"
lbdisttool.py --os-release $HOSTRELEASE -l || echo ""
return 0
}
print_drbd_version() {
echo
echo "DRBD version loaded:"
cat /proc/drbd
}
print_drbd_version_and_exit() {
print_drbd_version
exit 0
}
HOW_DEPSONLY=deps_only
HOW_REPOFILE=repo_file; HOW_HASH=node_hash; HOW_FROMSRC=compile; HOW_FROMSHIPPED=shipped_modules
how_to_get() {
local repo="$1"
local how=""
if [ -n "$LB_HOW" ]; then # allow to override
how="$LB_HOW"
elif [ -f "$repo" ]; then
how=$HOW_REPOFILE
elif [ -n "$LB_HASH" ]; then
how=$HOW_HASH
elif mountpoint -q /usr/src; then
how=$HOW_FROMSRC
else
how=$HOW_FROMSHIPPED
fi
echo "$how"
return 0
}
needs_dist() {
local how="$1"
local needsdist=n
if [[ $how == "$HOW_HASH" ]]; then
needsdist=y
fi
echo "$needsdist"
return 0
}
HOW_LOAD_FROM_RAM=RAM # insmod
HOW_INSTALL=install # make install && modprobe
how_to_load() {
[[ $LB_INSTALL == yes ]] && echo "$HOW_INSTALL" || echo "$HOW_LOAD_FROM_RAM"
return 0
}
repo::rpm::getrepofile() {
echo /etc/yum.repos.d/linbit.repo
}
repo::deb::getrepofile() {
echo /etc/apt/sources.list.d/linbit.list
}
repo::rpm::getsignkey() {
rpm --import $SIGN_KEY
}
repo::deb::getsignkey() {
wget -qO - $SIGN_KEY | apt-key add -
}
repo::rpm::createrepo() {
local dist="$1"
local hash="$2"
cat << EOF > "$(repo::rpm::getrepofile)"
[drbd-9]
name=DRBD9 - \$basearch
baseurl=http://packages.linbit.com/${hash}/yum/${dist}/drbd-9/\$basearch
gpgkey=$SIGN_KEY
gpgcheck=1
enabled=1
EOF
}
repo::deb::createrepo() {
local dist="$1"
local hash="$2"
cat << EOF > "$(repo::deb::getrepofile)"
deb http://packages.linbit.com/${hash}/ ${dist} drbd-9
EOF
}
kos::fromsrc() {
local pkgdir="$1"
local kodir="$2"
cd "$pkgdir" || die "Could not cd to $pkgdir"
tar xf /drbd.tar.gz
# cd $(ls -1 | head -1) || die "Could not cd"
cd drbd-* || die "Could not cd to drbd src dir"
make $LB_MAKEOPTS
}
kos::rpm::extract() {
local pkgdir="$1"
cd "$pkgdir" || die "Could not cd to $pkgdir"
rpm2cpio ./*.rpm | cpio -idmv 2>/dev/null
}
kos::deb::extract() {
local pkgdir="$1"
cd "$pkgdir" || die "Could not cd to $pkgdir"
dpkg -x ./*.deb "$pkgdir"
}
kos::rpm::fromrepo() {
local pkgdir="$1"
cd "$pkgdir" || die "Could not cd to $pkgdir"
yumdownloader -y --disablerepo="*" --enablerepo=drbd-9 kmod-drbd || yum download -y --disablerepo="*" --enablerepo=drbd-9 kmod-drbd
kos::rpm::extract "$pkgdir"
}
kos::deb::fromrepo() {
local pkgdir="$1"
local pkg
chown _apt "$pkgdir"
cd "$pkgdir" || die "Could not cd to $pkgdir"
pkg=drbd-module-"$(uname -r)"
apt-get update -o Dir::Etc::sourcelist="sources.list.d/linbit.list" \
-o Dir::Etc::sourceparts="-" \
-o APT::Get::List-Cleanup="0" && apt-get -y download "$pkg"
kos::deb::extract "$pkgdir"
}
kos::rpm::fromshipped() {
local pkgdir="$1"
local family
local best
family="$(lbdisttool.py --family)"
best="$(lbdisttool.py --force-name "$family" -k "${PKGS}/${family}"*/*.rpm)"
[ -n "$best" ] || die "Could not find matching rpm package for your kernel"
debug "Best kernel module package: \"$best\""
cp "$best" "$pkgdir"
kos::rpm::extract "$pkgdir"
}
kos::deb::fromshipped() {
local pkgdir="$1"
cp "$PKGS"/*/"drbd-module-$(uname -r)_"*.deb "$pkgdir"
nr_debs=$(find "$pkgdir" -name "*.deb" | wc -l)
[[ $nr_debs -eq 1 ]] || die "Expected to find 1 matching package, but got: $nr_debs"
kos::deb::extract "$pkgdir"
}
load_from_ram() {
local pkgdir="$1"
local kodir="$2"
find "$pkgdir" -name "*.ko" -exec cp {} "$kodir" \;
cd "$kodir" || die "Could not cd to $kodir"
if [ ! -f drbd.ko ] || [ ! -f drbd_transport_tcp.ko ]; then
die "Could not find the expexted *.ko, see stderr for more details"
fi
insmod ./drbd.ko usermode_helper=disabled
insmod ./drbd_transport_tcp.ko
insmod ./drbd_transport_rdma.ko 2>/dev/null || true
}
modprobe_deps() {
# we are not too strict about these, not all are required everywhere
#
# libcrc32c: dependency for DRBD
# nvmet_rdma, nvme_rdma: LINSTOR NVME layer
# loop: LINSTOR when using loop devices as backing disks
# dm_writecache: LINSTOR writecache layer
# dm_cache: LINSTOR cache layer
# dm_thin_pool: LINSTOR thinly provisioned storage
# dm_snapshot: LINSTOR snapshotting
# dm_crypt: LINSTOR encrypted volumes
local s;
for m in libcrc32c nvmet_rdma nvme_rdma loop dm_writecache dm_cache dm_thin_pool dm_snapshot dm_crypt; do
modprobe "$m" 2>/dev/null && s=success || s=failed
debug "Loading ${m}: ${s}"
done
return 0
}
### main
# SIGN_KEY=https://packages.linbit.com/package-signing-pubkey.asc
# PKGS=/pkgs
# HOSTRELEASE=/etc/host-release
# HOW_DEPSONLY=deps_only
# HOW_REPOFILE=repo_file;
# HOW_HASH=node_hash;
# HOW_FROMSRC=compile;
# HOW_FROMSHIPPED=shipped_modules
# HOW_LOAD_FROM_RAM=RAM # insmod
# HOW_INSTALL=install # make install && modprobe
modprobe_deps
[[ $LB_HOW == "$HOW_DEPSONLY" ]] && { debug "dependencies loading only, exiting now"; exit 0; }
if grep -q '^drbd ' /proc/modules; then
echo "DRBD module is already loaded"
print_drbd_version
[[ $LB_FAIL_IF_USERMODE_HELPER_NOT_DISABLED == yes ]] && ! grep -qw disabled /sys/module/drbd/parameters/usermode_helper &&
die "- load the drbd module on the host with the module parameter 'usermode_helper=disabled' OR\n- let this container handle that for you by not already loading the drbd module on the host"
exit 0
fi
pkgdir=/tmp/pkg
kodir=/tmp/ko
rm -rf "$pkgdir" "$kodir"
mkdir -p "$pkgdir" "$kodir"
fmt=rpm
if [ -n "$(type -p dpkg)" ]; then
fmt=deb
elif [ -n "$(type -p emerge)" ]; then
fmt=emerge
fi
case $fmt in
rpm|deb)
repo=$(repo::$fmt::getrepofile) # repo=/etc/apt/sources.list.d/linbit.list
how_get=$(how_to_get "$repo") || exit 1 # how_get=compile
;;
emerge)
# Cannot easily use how_to_get(), as we usually have /usr/src bind-mounted in that case.
# On flatcar this does not exist and we strictly only support building from source there anyway.
how_get=$HOW_FROMSRC
;;
esac
debug "Detected kmod method: \"$how_get\""
dist=we_do_not_care
need_dist=$(needs_dist "$how_get") # need_dist=n
debug "Needs host distribution info: \"$need_dist\""
if [[ $need_dist == y ]]; then
dist=$(map_dist "$LB_DIST") || exit 1
debug "Detected distribution: \"$dist\""
fi
case $how_get in
"$HOW_FROMSRC")
kos::fromsrc "$pkgdir" "$kodir" # 编译drbd模块
;;
"$HOW_REPOFILE"|"$HOW_HASH")
repo::$fmt::getsignkey
[[ $how_get == "$HOW_HASH" ]] && repo::$fmt::createrepo "$dist" "$LB_HASH"
kos::$fmt::fromrepo "$pkgdir"
;;
"$HOW_FROMSHIPPED")
kos::$fmt::fromshipped "$pkgdir"
;;
*) die "$how_get" ;;
esac
how_load=$(how_to_load) || exit 1 # how_load=RAM
debug "Detected load method: \"$how_load\""
if [[ $how_get == "$HOW_FROMSRC" ]] && [[ $how_load == "$HOW_INSTALL" ]]; then
cd "$pkgdir" || die "Could not cd to $pkgdir"
cd drbd-* || die "Could not cd to drbd src dir"
make install # 内核模块拷贝到/lib/modules/$(uname -r)/updates/目录下
modprobe drbd usermode_helper=disabled
modprobe drbd_transport_tcp
modprobe drbd_transport_rdma 2>/dev/null || true
else
# load_from_ram "$pkgdir" "$kodir"
local pkgdir="$1"
local kodir="$2"
find "$pkgdir" -name "*.ko" -exec cp {} "$kodir" \;
cd "$kodir" || die "Could not cd to $kodir"
if [ ! -f drbd.ko ] || [ ! -f drbd_transport_tcp.ko ]; then
die "Could not find the expexted *.ko, see stderr for more details"
fi
insmod ./drbd.ko usermode_helper=disabled
insmod ./drbd_transport_tcp.ko
insmod ./drbd_transport_rdma.ko 2>/dev/null || true
fi
grep -q '^drbd_transport_tcp' /proc/modules || die "Could not load DRBD kernel modules"
print_drbd_version_and_exit
工具 http://github.com/linbit/drbd-utils 这个是自己编译制作的镜像,提供 drbdadm 和 drbdsetup 管理工具