iSCSI-Storage@FreeBSD/FreeNAS: iSER, der Block-Storage-Turbo

iSCSI-Storage@FreeBSD/FreeNAS: iSER, der Block-Storage-Turbo

Performance auf shared iSCSI Storage ist Pflicht, wenn man viele VMs auf einem Proxmox-Cluster betreiben möchte.

Wie sich dabei die einzelnen Protokolle und Implementierungen verhalten, ist hier in der Übersicht zu sehen:

Zeta Systems hat genauestens untersucht, welche Performance aktuell von welchem Protokoll zu erwarten ist:
http://www.zeta.systems/blog/2016/09/21/iSCSI-vs-iSER-vs-SRP-on-Ethernet-&-InfiniBand/

Es soll somit iSER sein. Beschäftigt man sich damit, stellt man fest, dass die Technologie bereits sehr lange existiert, aber scheinbar bisher ein wenig unter gegangen ist.

Eine Präsentation von 2008:
https://www.snia.org/sites/default/orig/sdc_archives/2008_presentations/wednesday/PeterDunlap_OpenSolaris_iSER.pdf

Die Infiniband-Basics auf dem FreeBSD-Wiki:
https://wiki.freebsd.org/InfiniBand

Und hier ein Beitrag von 2016 auf der FreeBSD SCSI Liste:
https://freebsd-scsi.freebsd.narkive.com/sQG1P9kO/help-to-make-iser-working

Hier trägt Ben Rubson das wesentliche zusammen:

 


Ben RUBSON
4 years ago

Hi,

I went with a fresh new install to have a clean status.

What I did :

// FreeBSD 11-RC1 installation
# echo "WITH_OFED=YES" > /etc/make.conf
# cd /usr/src/ ; make buildkernel KERNCONF=GENERIC ; make installkernel KERNCONF=GENERIC
# cd /usr/src/sys/modules/mlx4 ; make ; make install
# cd /usr/src/sys/modules/mlxen ; make ; make install
# cd /usr/src/sys/modules/iser ; make ; make install
# echo "mlx4_load=YES" >> /boot/loader.conf
# echo "mlxen_load=YES" >> /boot/loader.conf
# echo "iser_load=YES" >> /boot/loader.conf
# reboot

Everything went fine, no code modition needed or whatever, perfect.

# iscsictl -A -t iqn.2012-06.com.test:target1 -p 192.168.2.2
On the target, I get :
tgtd[1912]: tgtd: login_start(502) Target iqn.2012-06.com.test:target1 is RDMA, but conn cid:0 from iqn.1994-09.org.freebsd:srv1 is TCP
Perfect, the target is correctly iSER enabled.

# iscsictl -A -t iqn.2012-06.com.test:target1 -p 192.168.2.2 -r
I still get the following error :
iscsid[1062]: 192.168.2.2 (iqn.2012-06.com.test:target1): failed to connect to 192.168.2.2 using ICL kernel proxy: ISCSIDCONNECT: Input/output error
kernel: INFO: iser_free_ib_conn_res: freeing conn 0xfffff80147771000 cma_id 0 qp 0
kernel: DEBUG: iser_conn_connect: before cv_wait: 0xfffff80147771000
kernel: INFO: iser_cma_handler: event 1 status -19 conn 0xfffff80147771000 id 0xfffff8005f0e5400
kernel: ERROR: iser_connect_error: conn 0xfffff80147771000
kernel: DEBUG: iser_conn_connect: after cv_wait: 0xfffff80147771000
iscsid[853]: child process 1062 terminated with exit status 1

Waiting for your instructions, would really be nice to have it working for 11 release.

Many thanks !

Best regards,

Ben
...
Ben RUBSON
4 years ago
Permalink
...
This was missing :
cd /usr/src/sys/modules/mlx4ib/ ; make ; make install ; kldload mlx4ib.ko

Now it works perfectly...
I'm really sorry for the useless noise on this list...

I hope this above howto will help others.

Thank you again for your support, and sorry again :-/

Benchmarks will of course follow.

Best regards,

Ben

iSer läuft mittlerweile auf FreeBSD, aber eben nicht unter FreeNAS.
Ein Kommentar auf iXsystems Jira lässt hoffen, klar ist das aber nicht:

Kris Moore added a comment - 11/Jan/20 2:53 PM

We're considering some changes this year which may include down
the road iSER support. Closing for now, but stay tuned later
in 2020.

Es sieht also danach aus, dass man sich damit gerade beschäftigt. Ob das Feature aber TrueNAS Core oder TrueNAS Enterprise sein wird, wissen wir nicht.

Daher ist der Weg für uns erst einmal, dass wir das selbst implementieren. Wir brauchen das JETZT, nicht erst im Sommer 2020.

Wie die Story weiter geht, erfahrt Ihr nun.

FreeNAS hat sich bei unseren Tests als nicht gangbar erwiesen.
Problem ist einerseits die ungenügende Mellanox-Unterstützung und andererseits die allgemeine Bestrebung von OSS-Unternehmen, Teile des Codes closed source zu machen und dies als Enterprise-Version zu vermarkten.

Support alleine macht nicht glücklich. Man versucht, dauerhafte Einnahmen zu etablieren, um planbarer zu sein.

Aber zurück zum Thema iSER.
Da Linux eine hervorragende iSER Unterstützung mitbringt und eine der führenden Distributionen sowieso schon im Haus ist, lag es am nahe, zu unseren Proxmox VE Cluster-Knoten auch den restlichen Bereich damit abzudecken: Proxmox iSER/iSCSI-Server, Proxmox Mail Gateway, Proxmox Backupserver.

Proxmox setzen wir auf mit einem ZFS-Pool raidz-1 auf zwei gespiegelten Intel NVMe SSD DC P4511 mit je 900GB. Das hätte es zwar nicht gebraucht, aber die lagen noch im Regal.

Erster Schritt, evtl. noch vorhandene ZFS-Metadaten löschen, und zwar am Ende und am Anfang der Platten.


dd bs=512 if=/dev/zero of=/dev/nvme0n1 count=2048 seek=$(($(blockdev --getsz /dev/nvme0n1) - 2048))
dd bs=512 if=/dev/zero of=/dev/nvme0n1 count=2048
dd bs=512 if=/dev/zero of=/dev/nvme1n1 count=2048 seek=$(($(blockdev --getsz /dev/nvme1n1) - 2048))
dd bs=512 if=/dev/zero of=/dev/nvme1n1 count=2048

Nach Erstinstallation bootet das System aber nicht.
Ok., Proxmox VE im Debug Modus starten, dabei stoppt das System an mehreren Stellen, was man mit exit weiter laufen lässt. Am Ende hat man eine root Shell mit allen notwendigen Werkzeugen.

Ein „zpool import“ offenbart, dass der Pool online ist.
Weiterhin lässt er sich problemlos importieren und mounten.


mkdir /mnt/rpool
zpool import -R /mnt/rpool rpool
zpool export

Das Problem war hier der BIOS legacy mode.
Nach einem „zpool destroy -f rpool“, Umstellung auf UEFI und Neuinstallation mit UEFI-Boot von Proxmox VE 6.4, war das Boot-Problem behoben.

Basisinstallation iSCSI/Infiniband Tools, opensm Infiniband Subnet Manager, NFS-Server und targetcli-fb zum managen von iSER Devices:


apt-get install apt-file net-tools opensm nfs-kernel-server rtr-tools scsitools scsitools targetcli-fb librdmacm1 ibacm infiniband-diags srptools vim  ibutils ibverbs-providers ibverbs-utils rdmacm-utils perftest tgt open-iscsi lsscsi tgt multipath-tools -y
apt-file update

Anlegen der /etc/rc.local mit folgendem Inhalt:


#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# run at startup
echo 0 > /proc/sys/kernel/hung_task_timeout_secs
/usr/local/bin/iser-performance-tuning.sh
exit 0

Anlegen des iser-performance-tuning.sh Skripts /usr/local/bin/iser-performance-tuning.sh:


#!/bin/bash
target=pvecn0
verbose=0
messenger(){
if [ "$verbose" = "1" ]
then printf "$MSG\n"
fi
}
# iSER LIO server is target, clients are initiators
if [ "$(hostname)" = "$target" ]
then iSERtype="target"
else iSERtype="initiator"
fi
MSG="iSER type is:\t$iSERtype"
messenger
irq_affinity(){
#relevant for target and initiator
MSG="IRQ affinity setup..."
messenger
#service irqbalancer stop 2>&1>/dev/null
IRQS=$(cat /proc/interrupts | egrep 'mlx4|mlx5' | awk '{print $1}' | sed 's/://')
cores=($(seq 1 $(grep -c processor /proc/cpuinfo)))
i=0
#echo ${#cores[@]}
for IRQ in $IRQS
do
core=${cores[$i]}
let "mask=2**(core-1)"
#printf "IRQ\t:\t$IRQ\nIndex\t:\t$i\ncore\t:\t$core\nmask\t:\t$mask\n"
echo $(printf "%x" $mask) > /proc/irq/$IRQ/smp_affinity
i=$(($i+1))
if [ "$i" = "${#cores[@]}" ]; then i=0
fi
done
}
cpu_performance_scaling(){
# relevant for target and initiator
MSG="CPU performance setup..."
messenger
for i in $(ls /sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_governor | sed -e "s/ /\n/g")
{
echo performance >$i
}
}
block_layer_staging(){
# relevant for initiators only
MSG="Block layer staging..."
messenger
# set IO scheduler to do no-operation.
# IO schedulers try to accelerate HDD access time by minimizing seeks.
# When working with SAN targets normally it is better to let the target machine do these optimizations if needed (normally a single LUN is not made of a single HDD...).
#In addition, SDDs do not suffer from seek time.
for i in $(ls /sys/block/[a-z]*/queue/scheduler)
{
echo "noop" >$i 2>&1>/dev/null
}
# Normally the block layer will try to merge IOs to consecutive offsets.
# On fast SAN networks it may be better not to merge, and save the CPU utilization.
for i in $(ls /sys/block/[a-z]*/queue/nomerges)
{
echo 2 >$i
}
# The system uses physical devices to gather randomness for its random numbers generator.
# Can save some utilization by turning this off.
for i in $(ls /sys/block/[a-z]*/queue/add_random)
{
echo 0 >$i
}
# Deliver IO completion on the same core that handled the request.
for i in $(ls /sys/block/[a-z]*/queue/rq_affinity)
{
echo 1 >$i
}
}
set_nv_huge_pages(){
# relevant for targets only
MSG="Huge paging setup..."
messenger
# In case of kernel space target suech as LIO or SCST, set a low (or zero) number of HugePages (Increases page-cache)
echo 0 > /proc/sys/vm/nr_hugepages
}
if [ "$iSERtype" = "target" ]
then
MSG="Running target optimizations..."
messenger
irq_affinity
cpu_performance_scaling
set_nv_huge_pages
fi
if [ "$iSERtype" = "initiator" ]
then
MSG="Running initiator optimizations..."
messenger
irq_affinity
cpu_performance_scaling
block_layer_staging
fi

Anlegen von /usr/local/bin/iscsi-autologin.sh:


#!/bin/bash
### enable autologin to iSCSI target ###
iscsiadm --mode node -T iqn.2020-03.de.pawott.pvecn0.hddpool -o update -n node.startup -v automatic
iscsiadm --mode node -T iqn.2020-03.de.pawott.pvecn0.ssdpool -o update -n node.startup -v automatic
cd /etc/iscsi
grep -R node.startup * | grep -v manual
SSH-Keys id_rsa und id_rsa.pub erzeugen und verteilen auf alle Knoten nach
/root/.ssh/
/etc/pve/priv/authorized_keys

Einstellungen für remote shell
/root/.bashrc


# ~/.bashrc: executed by bash(1) for non-login shells.
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# Note: PS1 and umask are already set in /etc/profile. You should not
# need this unless you want different defaults for root.
# PS1='${debian_chroot:+($debian_chroot)}\h:\w\$ '
# umask 022
# You may uncomment the following lines if you want `ls' to be colorized:
# export LS_OPTIONS='--color=auto'
# eval "`dircolors`"
alias ls='ls $LS_OPTIONS'
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'
#
# Some more alias to avoid making mistakes:
# alias rm='rm -i'
# alias cp='cp -i'
# alias mv='mv -i'
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
if [ -f /etc/bash.bashrc.local ]; then
. /etc/bash.bashrc.local
fi

Farbcodes in Ausgaben:
/etc/rc.status


# Definition of boot script return messages
#
#   The bootscripts should use the variables rc_done and rc_failed to
#   report whether they failed or succeeded.  See /etc/init.d/skeleton for
#   an example how the shell functions rc_status and rc_reset are used.
#
#   These functions make use of the variables rc_done and rc_failed;
#   rc_done_up and rc_failed_up are the same as rc_done and rc_failed
#   but contain a terminal code to move up one line before the output
#   of the actual string. (This is particularly useful when the script
#    starts a daemon which produces user output with a newline character)
#
#   The variable rc_reset is used by the master resource control script
#   /etc/init.d/rc to turn off all attributes and switch to the standard
#   character set.
#
#    \033          ascii ESCape
#    \033[G   move to column  (linux console, xterm, not vt100)
#    \033[C   move  columns forward but only upto last column
#    \033[D   move  columns backward but only upto first column
#    \033[A   move  rows up
#    \033[B   move  rows down
#    \033[1m       switch on bold
#    \033[31m      switch on red
#    \033[32m      switch on green
#    \033[33m      switch on yellow
#    \033[m        switch off color/bold
#    \017          exit alternate mode (xterm, vt100, linux console)
#    \033[10m      exit alternate mode (linux console)
#    \015          carriage return (without newline)
if test -z "$LINES" -o -z "$COLUMNS" ; then
eval `exec 3<&1; stty size <&3 2>/dev/null | (read L C; \
echo LINES=${L:-24} COLUMNS=${C:-80})`
fi
test $LINES -eq 0 && LINES=24
test $COLUMNS -eq 0 && COLUMNS=80
export LINES COLUMNS
# Make sure we have /sbin and /usr/sbin in PATH
case $PATH in
*sbin*)
;;
*)
export PATH=/sbin:/usr/sbin:$PATH
;;
esac
if test -t 1 -a "$TERM" != "raw" -a "$TERM" != "dumb" && stty size <&1 > /dev/null 2>&1 ; then
esc=`echo -en "\033"`
extd="${esc}[1m"
warn="${esc}[1;31m"
done="${esc}[1;32m"
attn="${esc}[1;33m"
norm=`echo -en "${esc}[m\017"`
stat=`echo -en "\015${esc}[${COLUMNS}C${esc}[10D"`
rc_done="${stat}${done}done${norm}"
rc_running="${stat}${done}running${norm}"
rc_failed="${stat}${warn}failed${norm}"
rc_missed="${stat}${warn}missing${norm}"
rc_skipped="${stat}${attn}skipped${norm}"
rc_dead="${stat}${warn}dead${norm}"
rc_unused="${stat}${extd}unused${norm}"
rc_unknown="${stat}${attn}unknown${norm}"
rc_done_up="${esc}[1A${rc_done}"
rc_failed_up="${esc}[1A${rc_failed}"
rc_reset="${norm}${esc}[?25h"
rc_save="${esc}7${esc}[?25l"
rc_restore="${esc}8${esc}[?25h"
function rc_cuu () { test $1 -eq 0 && return; echo -en "\033[${1}A"; }
function rc_cud () { test $1 -eq 0 && return; echo -en "\033[${1}B"; }
function rc_timer_on () {
# Draw seconds of running timout to column.
# Two arguments: timeout in seconds and offset
local n=$1
local c=$2
(trap "exit 0" TERM
while test $((n--)) -gt 0; do
sleep 1;
if test $n -gt 9 ; then
echo -en "${attn}\015${esc}[${c}C(${n}s)${norm} "
else
echo -en "${attn}\015${esc}[${c}C( ${n}s)${norm} "
fi
done) & _rc_timer_pid=$!
}
function rc_timer_off () {
if test -n "$_rc_timer_pid" ; then
kill -TERM $_rc_timer_pid > /dev/null 2>&1
fi
unset _rc_timer_pid
}
else
esc=""
extd=""
warn=""
done=""
attn=""
norm=""
stat=""
rc_done="..done"
rc_running="..running"
rc_failed="..failed"
rc_missed="..missing"
rc_skipped="..skipped"
rc_dead="..dead"
rc_unused="..unused"
rc_unknown="..unknown"
rc_done_up="${rc_done}"
rc_failed_up="${rc_failed}"
rc_reset=""
rc_save=""
rc_restore=""
function rc_cuu () { return; }
function rc_cud () { return; }
function rc_timer_on () { return; }
function rc_timer_off () { return; }
fi
_rc_service=${0##*/[SK][0-9][0-9]}
_rc_status=0
_rc_status_all=0
_rc_todo=$1
function rc_check ()
{
_rc_status_ret=$?
test $_rc_status_ret -eq 0 || _rc_status=$_rc_status_ret
test $_rc_status -eq 0 || _rc_status_all=$_rc_status
return $_rc_check_ret
}
function rc_reset ()
{
_rc_status=0
_rc_status_all=0
rc_check
return 0
}
if test "$_rc_todo" = "status" ; then
function rc_status ()
{
rc_check
_rc_status_ret=$_rc_status
local i
for i ; do
case "$i" in
-v|-v[1-9]|-v[1-9][0-9])
local vrt=""
local out=1
local opt="en"
test -n "${i#-v}" && vrt="$vrt${esc}[${i#-v}A" || opt="e"
case "$_rc_status" in
0) vrt="$vrt$rc_running"; ;; # service running
1) vrt="$vrt$rc_dead" ; out=2 ;; # service dead (but has pid file)
2) vrt="$vrt$rc_dead" ; out=2 ;; # service dead (but has lock file)
3) vrt="$vrt$rc_unused" ; ;; # service not running
4) vrt="$vrt$rc_unknown"; ;; # status is unknown
esac
echo -$opt "$rc_save$vrt$rc_restore" 1>&$out
# reset _rc_status to 0 after verbose case
_rc_status=0 ;;
-r) rc_reset ;;
-s) echo -e "$rc_skipped" ; rc_failed 3 ;;
-u) echo -e "$rc_unused" ; rc_failed 3 ;;
*) echo "rc_status: Usage: [-v[] [-r]|-s|-u]" 1>&2 ; return 0 ;;
esac
done
return $_rc_status_ret
}
elif test -n "$_rc_todo" ; then
function rc_status ()
{
rc_check
test "$_rc_status" -gt 7 && rc_failed 1
_rc_status_ret=$_rc_status
case "$_rc_todo" in
stop)
# program is not running which
# is success if we stop service
test "$_rc_status" -eq 7 && rc_failed 0 ;;
esac
local i
for i ; do
case "$i" in
-v|-v[1-9]|-v[1-9][0-9])
local vrt=""
local out=1
local opt="en"
test -n "${i#-v}" && vrt="$vrt${esc}[${i#-v}A" || opt="e"
case "$_rc_status" in
0) vrt="$vrt$rc_done" ; ;; # success
1) vrt="$vrt$rc_failed" ; out=2 ;; # generic or unspecified error
2) vrt="$vrt$rc_failed" ; out=2 ;; # invalid or excess args
3) vrt="$vrt$rc_missed" ; out=2 ;; # unimplemented feature
4) vrt="$vrt$rc_failed" ; out=2 ;; # insufficient privilege
5) vrt="$vrt$rc_skipped"; out=2 ;; # program is not installed
6) vrt="$vrt$rc_unused" ; out=2 ;; # program is not configured
7) vrt="$vrt$rc_failed" ; out=2 ;; # program is not running
*) vrt="$vrt$rc_failed" ; out=2 ;; # unknown (maybe used in future)
esac
echo -$opt "$rc_save$vrt$rc_restore" 1>&$out
# reset _rc_status to 0 after verbose case
_rc_status=0 ;;
-r) rc_reset ;;
-s) echo -e "$rc_skipped" 1>&2 ; rc_failed 5 ;;
-u) echo -e "$rc_unused" 1>&2 ; rc_failed 6 ;;
*) echo "rc_status: Usage: [-v[] [-r]|-s|-u]" 1>&2 ; return 0 ;;
esac
done
return $_rc_status_ret
}
else
function rc_status ()
{
rc_check
_rc_status_ret=$_rc_status
local i
for i ; do
case "$i" in
-v|-v[1-9]|-v[1-9][0-9])
local vrt=""
local out=1
local opt="en"
test -n "${i#-v}" && vrt="$vrt${esc}[${i#-v}A" || opt="e"
case "$_rc_status" in
0) vrt="$vrt$rc_done" ; ;; # success
*) vrt="$vrt$rc_failed"; out=2 ;; # failed
esac
echo -$opt "$rc_save$vrt$rc_restore" 1>&$out
# reset _rc_status to 0 after verbose case
_rc_status=0 ;;
-r) rc_reset ;;
-s) echo -e "$rc_skipped" ; return 0 ;;
-u) echo -e "$rc_unused" ; return 0 ;;
*) echo "rc_status: Usage: [-v[] [-r]|-s|-u]" 1>&2 ; return 0 ;;
esac
done
return $_rc_status_ret
}
fi
function rc_failed ()
{
rc_reset
case "$1" in
[0-7]) _rc_status=$1 ;;
"") _rc_status=1
esac
rc_check
return $_rc_status
}
function rc_exit ()
{
exit $_rc_status_all
}
function rc_confirm()
{
local timeout="30"
local answer=""
local ret=0
case "$1" in
-t) timeout=$2; shift 2 ;;
esac
local message="$@, (Y)es/(N)o/(C)ontinue? [y] "
: ${REDIRECT:=/dev/tty}
while true ; do
read -t ${timeout} -n 1 -p "${message}" answer < $REDIRECT > $REDIRECT 2>&1
case "$answer" in
[yY]|"") ret=0; break ;;
[nN]) ret=1; break ;;
[cC]) ret=2; break ;;
*) echo; continue
esac
done
echo
return $ret
}
function rc_active ()
{
local x
for x in /etc/init.d/*.d/S[0-9][0-9]${1} ; do
test -e $x || break
return 0
done
return 1
}
function rc_splash()
{
return 0
}

Lokale globale /etc/bash.bashrc.local


# bash completion for the `wp` command
_wp_complete() {
local OLD_IFS="$IFS"
local cur=${COMP_WORDS[COMP_CWORD]}
IFS=$'\n'; # want to preserve spaces at the end
local opts="$(wp cli completions --line="$COMP_LINE" --point="$COMP_POINT")"
if [[ "$opts" =~ \<file\>\s* ]]
then
COMPREPLY=( $(compgen -f -- $cur) )
elif [[ $opts = "" ]]
then
COMPREPLY=( $(compgen -f -- $cur) )
else
COMPREPLY=( ${opts[*]} )
fi
IFS="$OLD_IFS"
return 0
}
complete -o nospace -F _wp_complete wp
if [ "$PS1" ]; then
PS1='\u@\h:\w\$ '
ROTH="\[\033[1;31m\]"
ROT="\[\033[0;31m\]"
GRUEN="\[\033[0;32m\]"
BLAU="\[\033[0;34m\]"
YELLOW="\[\033[1;33m\]"
NOCOLOR="\[\033[0m\]"
[ "$UID" == "0" ] && USRCLR="$ROT\\u$NOCOLOR" || USRCLR="\\u"
PS1="${ROTH}Remote: $GRUEN\$(date +%H:%M:%S)h$ROTH@$YELLOW\h ${BLAU}[$GRUEN$USRCLR$ROTH@$ROTH${debian_chroot:+($debian_chroot)}$GRUEN\w${BLAU}]\n$NOCOLOR#"
shopt -s checkwinsize
# You may uncomment the following lines if you want `ls' to be colorized:
export LS_OPTIONS='--color=auto'
eval "`dircolors`"
alias ls='ls $LS_OPTIONS'
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'
alias mce='mcedit'
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
if [ -f /etc/bash.aliases ]; then
. /etc/bash.aliases
fi
export LANG=de_DE.UTF-8
. /etc/rc.status
echo -en "\033[1m"
echo "${done}"
echo "UPTIME / SYSINFOS :"
echo ""
echo "___________________________________________________________________________"
echo ""
uptime
echo -en "\033[1m"
echo "___________________________________________________________________________"
echo "${norm}"
/usr/local/bin/checkspace
echo ""
echo -en "\033[1m"
fi
if [ $UID != 0 ]
then
echo ""
echo -en "\033[1m"
echo -en "\033[34m"
cal
echo -en "${done}"
else
echo -en "\033[0;31m"
echo "_________________________"
echo "| |"
echo "| root weiss was er tut! |"
echo "|________________________|"
echo ""
fi
export HISTTIMEFORMAT='%F %T '
export HISTSIZE=150000
export HISTSIZEFILE=150000
export LANG=de_DE.UTF-8
export LANGUAGE=
export LC_CTYPE="de_DE.UTF-8"
export LC_NUMERIC="de_DE.UTF-8"
export LC_TIME="de_DE.UTF-8"
export LC_COLLATE="de_DE.UTF-8"
export LC_MONETARY="de_DE.UTF-8"
export LC_MESSAGES="de_DE.UTF-8"
export LC_PAPER="de_DE.UTF-8"
export LC_NAME="de_DE.UTF-8"
export LC_ADDRESS="de_DE.UTF-8"
export LC_TELEPHONE="de_DE.UTF-8"
export LC_MEASUREMENT="de_DE.UTF-8"
export LC_IDENTIFICATION="de_DE.UTF-8"
export LC_ALL="de_DE.UTF-8"

Anpassung locale:


sed -i "s/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/" /etc/locale.gen
locale-gen

Falls beim SSH login folgende Meldung auftaucht:


Offending key for IP in /home/${user}/.ssh/known_hosts:220

oder


Offending key for IP in /etc/ssh/ssh_known_hosts:8

ist folgendes zu tun:


sed -i '220d' ~/.ssh/known_host

bzw.


sed -i '8d' /etc/ssh/ssh_known_hosts

Notwendige Kernel-Module Client, ib_isert würde nicht benötigt, wird aber dennoch mit geladen:


mlx4_en               118784  0
mlx4_ib               196608  0
ib_uverbs             126976  32 mlx4_ib,rdma_ucm
ib_core               311296  13 rdma_cm,ib_ipoib,rpcrdma,mlx4_ib,ib_srp,iw_cm,ib_iser,ib_umad,ib_isert,rdma_ucm,ib_uverbs,ib_cm
mlx4_core             307200  2 mlx4_ib,mlx4_en

Notwendige Kernel-Module Server:

mlx4_en               118784  0
mlx4_ib               196608  0
ib_uverbs             126976  32 mlx4_ib,rdma_ucm
ib_core               311296  13 rdma_cm,ib_ipoib,rpcrdma,mlx4_ib,ib_srp,iw_cm,ib_iser,ib_umad,ib_isert,rdma_ucm,ib_uverbs,ib_cm
mlx4_core             307200  2 mlx4_ib,mlx4_en

Interfaces /etc/network/interfaces, je Mellanox Infiniband ein eigenes Subnetz:


# network interface settings; autogenerated
# Please do NOT modify this file directly, unless you know what
# you're doing.
#
# If you want to manage parts of the network configuration manually,
# please utilize the 'source' or 'source-directory' directives to do
# so.
# PVE will preserve these directives, but will NOT read its network
# configuration from sourced files, so do not attempt to move any of
# the PVE managed interfaces into external files!

auto lo
iface lo inet loopback
iface eno3 inet manual

iface eno1 inet manual

iface eno4 inet manual

iface eno2 inet manual

auto bond0
iface bond0 inet manual
 bond-slaves eno1 eno2
 bond-miimon 100
 bond-mode 802.3ad
 bond-xmit-hash-policy layer3+4
 #SFP+ Bond

auto vmbr1
iface vmbr1 inet static
 address 10.40.2.100/24
 bridge-ports eno3
 bridge-stp off
 bridge-fd 0
 # gateway 10.40.2.1

#Proxmox INFRASTRUCTURE/FAILOVER1
auto vmbr0
iface vmbr0 inet static
 address 10.40.0.100/24
 bridge-ports bond0
 bridge-stp off
 bridge-fd 0
 bridge-vlan-aware yes
 bridge-vids 2-4094
 #Bonding Bridge VMs
auto vmbr1:0
iface vmbr1:0 inet static
 address 192.168.0.100/24
 gateway 192.168.0.1
 #Temporary IP alias
 auto vmbr2
 iface vmbr2 inet static
 address 10.40.7.100/24
 bridge-ports eno4
 bridge-stp off
 bridge-fd 0

#Proxmox FAILOVER2
auto ibp3s0
iface ibp3s0 inet static
 address 10.40.10.100/24
 pre-up echo connected > /sys/class/net/ibp3s0/mode
 post-up /usr/sbin/ip link set ibp3s0 mtu 4092
 post-up echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
 post-up echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
 post-up echo 1 > /proc/sys/net/ipv4/conf/ibp3s0/arp_ignore

auto ibp4s0
iface ibp4s0 inet static
 address 10.40.20.100/24
 pre-up echo connected > /sys/class/net/ibp4s0/mode
 post-up /usr/sbin/ip link set ibp4s0 mtu 4092
 post-up echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
 post-up echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
 post-up echo 1 > /proc/sys/net/ipv4/conf/ibp4s0/arp_ignore

auto ibp3s0d1
iface ibp3s0d1 inet static
 address 10.40.30.100/24
 pre-up echo connected > /sys/class/net/ibp3s0d1/mode
 post-up /usr/sbin/ip link set ibp3s0d1 mtu 4092
 post-up echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
 post-up echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
 post-up echo 1 > /proc/sys/net/ipv4/conf/ibp3s0d1/arp_ignore

auto ibp4s0d1
iface ibp4s0d1 inet static
 address 10.40.40.100/24
 pre-up echo connected > /sys/class/net/ibp4s0d1/mode
 post-up /usr/sbin/ip link set ibp4s0d1 mtu 4092
 post-up echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
 post-up echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
 post-up echo 1 > /proc/sys/net/ipv4/conf/ibp4s0d1/arp_ignore

Einträge in /etc/hosts aller Cluster-Knoten, um unnötige DNS-Abfragen zu vermeiden:


127.0.0.1 localhost.localdomain localhost
10.40.2.100 pvecn0.pawott.de pvecn0
10.40.2.101 pvecn1.pawott.de pvecn1
10.40.2.102 pvecn2.pawott.de pvecn2
10.40.2.103 pvecn3.pawott.de pvecn3
10.40.2.104 pvecn4.pawott.de pvecn4
10.40.2.105 pvecn5.pawott.de pvecn5
10.40.2.106 pvecn6.pawott.de pvecn6
10.40.10.100 iscsi-portal.pawott.de iscsi-portal
10.40.20.100 iscsi-portal.pawott.de iscsi-portal

#10.40.30.100 iscsi-portal1.pawott.de iscsi-portal1
#10.40.20.100 iscsi-portal2.pawott.de iscsi-portal2

# The following lines are desirable for IPv6 capable hosts

::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Anlegen der /etc/modules-load.d/mellanox.conf zum Laden der Module:


mlx4_core
mlx4_ib
mlx4_en
ib_core
#ib_addr
#ib_sa
ib_cm
rdma_cm
rdma_ucm
ib_iser
#ib_isert
## IP over Infiniband
ib_ipoib
ib_umad
#ib_mad
rpcrdma
ib_srp
ib_isert
iw_cm
ib_uverbs
svcrdma
xprtrdma

Aktivierung von iSCSI über RDMA in /etc/rdma/modules/rdma.conf


# These modules are loaded by the system if any RDMA devices is installed
# iSCSI over RDMA client support
ib_iser

# iSCSI over RDMA target support
ib_isert

# User access to RDMA verbs (supports libibverbs)
ib_uverbs

# User access to RDMA connection management (supports librdmacm)
rdma_ucm

# RDS over RDMA support
# rds_rdma

# NFS over RDMA client support
xprtrdma

# NFS over RDMA server support
svcrdma

Port Typ Konfiguration:


for i in $(lspci | grep Mellanox | awk '{print $1}'); { echo "0000:$i ib ib" >>/etc/rdma/mlx4.conf; }

Deaktivierung von i40iw Devices in /etc/modprobe.d/mlx4.conf:


echo "blacklist i40iw" >> /etc/modprobe.d/mlx4.conf

Aktivieren der Exports des NFS-Server unter /etc/exports:


# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/hddpool/NFS/ISO-Images 10.40.2.0/24(rw,no_root_squash,no_all_squash,sync,no_subtree_check)
/hddpool/NFS/ISO-Images 10.40.2.50(rw,no_root_squash,no_all_squash,sync,no_subtree_check)
/hddpool/NFS/ISO-Images 10.40.10.0/24(rw,no_root_squash,no_all_squash,sync,no_subtree_check)
/hddpool/NFS/ISO-Images 10.40.20.0/24(rw,no_root_squash,no_all_squash,sync,no_subtree_check)
/hddpool/NFS/ISO-Images 10.40.30.0/24(rw,no_root_squash,no_all_squash,sync,no_subtree_check)
/hddpool/NFS/ISO-Images 10.40.40.0/24(rw,no_root_squash,no_all_squash,sync,no_subtree_check)

/hddpool/NFS/Snapshots 10.40.2.0/24(rw,no_root_squash,no_all_squash,sync,no_subtree_check)
/hddpool/NFS/Snapshots 10.40.2.50(rw,no_root_squash,no_all_squash,sync,no_subtree_check)
/hddpool/NFS/Snapshots 10.40.10.0/24(rw,no_root_squash,no_all_squash,sync,no_subtree_check)
/hddpool/NFS/Snapshots 10.40.20.0/24(rw,no_root_squash,no_all_squash,sync,no_subtree_check)
/hddpool/NFS/Snapshots 10.40.30.0/24(rw,no_root_squash,no_all_squash,sync,no_subtree_check)
/hddpool/NFS/Snapshots 10.40.40.0/24(rw,no_root_squash,no_all_squash,sync,no_subtree_check)

 

ZFS über iSCSI über Infiniband ConnectX-2 HCAs mit FreeNAS und Integration in Proxmox

ZFS über iSCSI über Infiniband ConnectX-2 HCAs mit FreeNAS und Integration in Proxmox

Wenn Proxmox im Cluster laufen soll, benötigt es ein shared storage. Das kann NFS sein oder besser iSCSI. Für Performance ist letztendlich entscheidend das Layout des Storage-Pools und eine möglichst latenzarme Anbindung. Fiberchannel oder Infiniband sind hier die Kandidaten der Wahl. Letzteres hat allerdings die Nase vorn, wenn es um Bandbreite geht und es ist ausgereift, da es im High-Perfomance-Computing schon sehr lange im Einsatz ist. Infiniband kennen wir zudem aus dem HP POD Supercomputing Projekt bei Airbus (damals die Nr.10 auf top500.org).

Da die Auswahl an Storage-Systemen mit Infiniband-Unterstützung dünn und im bezahlbaren Bereich quasi nicht vorhanden ist, haben wir beschlossen, selbst ein Storage zu entwickeln.

Als Hardware-Basis für Storage, Virtualisierungsplattform und Backup dienen unsere bewährten getcom Superserver Green-IT-Serie der Generation 7 & 8, Voltaire Infiniband Grid Director 4036E und Cisco Switche aus der SG550X Serie.

Alle Server (Storage und Cluster-Knoten) sind mit je zwei Intel XEONs 3,2GHz und 256GB ECC RAM bestückt und laufen auf aktuellen Supermicro Boards. Für den Netzwerkstack haben alle Server neben IPMI und Dual 10GbE je eine Dual Infiniband und eine Intel X710 SFP+ Karte mit an Bord. Die Betriebssysteme laufen auf gespiegelten Intel DC SSDs. Auf dem Storage-Server ist dazu auf der Rückseite ein hotplugfähiges 2,5″ Dual Bay integriert.

Das Herzstück des I/O-Systems für Storage- & Backup-Systeme, speziell geflashte HCAs, Dual SFP+ Ethernet 10GbE, Dual Infiniband 40Gbit mit gespiegelten PCIe NAND Flash Modulen, garantiert ordentlichen Durchsatz bei minimaler Latenz:

Die Frage nach dem Filesystem hat sich schnell beantwortet: ZFS soll es sein.
Die Vorteile sind:

  • schnelle Rebuildzeit (resilver), da nur die belegten Blöcke übertragen werden
  • schnelle Pool-Initialisierung, auch 140TB sind in wenigen Minuten initialisiert
  • die Datenintegrität ist bei ZFS immer garantiert, d.h. ein Block wird so ausgeliefert, wie er gespeichert wurde
  • einfache Poolerweiterung durch größere Ersatz-Platten
  • einfacher Pool-Import inklusive ACLs, Snaphots, etc., der Platten auf neuer Hardware, wenn ZFS Version gleich oder größer ist auf dem Zielsystem bei unrelevanter Plattenfolge

Aktuelle ZFS basierte Systeme, die geeignet sind, sind FreeNAS 11.2 oder OmniOSce in Verbindung mit Napp-IT.

OmniOSce/Napp-IT ist im Grunde ein Abkömmling von Solaris Version 10 => OpenSolaris => illumos / OpenIndiana und damit ein direkter Nachfahre vom Unix System V. Da es unter FreeNAS/FreeBSD einige Überraschungen in Verbindung mit HA, Infiniband und iSCSI gab, werden wir uns bei Gelegenheit OmniOSce und Napp-IT in einer eigenen Analyse näher ansehen. Die PoC-Hardware dazu steht schon bereit. Mehr dazu in einem der nächsten Blogs.

Da FreeNAS nun über OpenZFS und auch über Mellanox Infiniband Treiber verfügt, gehen wir es an.

FreeNAS Setup

Die Installation wird als erledigt vorausgesetzt. Wir haben lediglich die beiden Intel Datacenter SSDs als Spiegel für die Installation ausgewählt. Wichtig ist, dass im BIOS auf UEFI umgestellt ist vor der Installation. Anschließend ist der Hostname zu vergeben, die beiden SFP+ Ports zu lagg0 (LACP), die beiden internen 10GbE Ports zu lagg1 (LACP) zusammen zu schalten. Mehr ist hier erst einmal nicht zu tun. Auf Cisco-Seite müssen innerhalb des Stacks auf den Core und den Management Switchen ebenfalls die entsprechend verwendeten Ports unter Link Aggregation zu einem lagg zusammen geschaltet werden. Für die Stack-Implementierung ist je Switch die Cisco Tesla Hybrid Firmware in der aktuellen Version zu flashen, wenn sich verschiedene Typen im Stack befinden sollen.

ZFS

Ein Blick auf das OpenZFS, welches FreeNAS mitbringt, verrät uns, dass es nah dran ist am aktuellen Oracle ZFS, die fehlende Verschlüsselung fällt auf, womit wir aber erst mal leben können:

root@freenas1[~]# zpool upgrade -v
This system supports ZFS pool feature flags.

The following features are supported:

FEAT DESCRIPTION
-------------------------------------------------------------
async_destroy                         (read-only compatible)
     Destroy filesystems asynchronously.
empty_bpobj                           (read-only compatible)
     Snapshots use less space.
lz4_compress                         
     LZ4 compression algorithm support.
multi_vdev_crash_dump                
     Crash dumps to multiple vdev pools.
spacemap_histogram                    (read-only compatible)
     Spacemaps maintain space histograms.
enabled_txg                           (read-only compatible)
     Record txg at which a feature is enabled
hole_birth                           
     Retain hole birth txg for more precise zfs send
extensible_dataset                   
     Enhanced dataset functionality, used by other features.
embedded_data                        
     Blocks which compress very well use even less space.
bookmarks                             (read-only compatible)
     "zfs bookmark" command
filesystem_limits                     (read-only compatible)
     Filesystem and snapshot limits.
large_blocks                         
     Support for blocks larger than 128KB.
sha512                               
     SHA-512/256 hash algorithm.
skein                                
     Skein hash algorithm.
device_removal                       
     Top-level vdevs can be removed, reducing logical pool size.
obsolete_counts                       (read-only compatible)
     Reduce memory used by removed devices when their blocks are freed or remapped.
zpool_checkpoint                      (read-only compatible)
     Pool state can be checkpointed, allowing rewind later.

The following legacy versions are also supported:

VER  DESCRIPTION
---  --------------------------------------------------------
 1   Initial ZFS version
 2   Ditto blocks (replicated metadata)
 3   Hot spares and double parity RAID-Z
 4   zpool history
 5   Compression using the gzip algorithm
 6   bootfs pool property
 7   Separate intent log devices
 8   Delegated administration
 9   refquota and refreservation properties
 10  Cache devices
 11  Improved scrub performance
 12  Snapshot properties
 13  snapused property
 14  passthrough-x aclinherit
 15  user/group space accounting
 16  stmf property support
 17  Triple-parity RAID-Z
 18  Snapshot user holds
 19  Log device removal
 20  Compression using zle (zero-length encoding)
 21  Deduplication
 22  Received properties
 23  Slim ZIL
 24  System attributes
 25  Improved scrub stats
 26  Improved snapshot deletion performance
 27  Improved snapshot creation performance
 28  Multiple vdev replacements

For more information on a particular version, including supported releases,
see the ZFS Administration Guide.
root@freenas1[~]

Infiniband

Testweise manuelles Laden der Module für Infiniband unter FreeNAS/FreeBSD:

root@freenas1[~]# kldload mlx4   
kldload: can't load mlx4: module already loaded or in kernel
root@freenas1[~]# kldload mlx4ib
root@freenas1[~]# kldload ipoib
root@freenas1[~]

Das aktiviert schon einmal die Karten, die uns mit Aufleuchten der orangen und grünen LEDs signalisieren, dass die Treiber geladen und die Karten einsatzbereit sind.

Das permanente Laden erfolgt in FreeBSD über die /boot/loader.conf.local.
Anders als unter FreeBSD wird allerdings die local Datei bei Updates oder Änderungen in den Tuneables (loader) gnadenlos überschrieben. FreeNAS ist eine Appliance und somit muss man Änderungen immer über die GUI vornehmen. Das gilt für alle Appliances, nebenbei auch für pfSense. Die loader Config darf deshalb nicht manuell editiert werden, da sie vom System früher oder später überschrieben werden wird.
Die korrekte Vorgehensweise ist über die GUI => System => Tunables => Add zu gehen und die entsprechenden Werte für die beiden loader einzutragen.

Nach dem Speichern finden wir unsere loader an gewohnter Stelle wieder:

root@freenas1[~]# cat /boot/loader.conf.local   
mlx4ib_load="YES" # Be sure that Kernel modul Melloanox 4 Infiniband will be loaded
ipoib_load="YES" # Be sure that Kernel modul IP over Infiniband will be loaded
kernel="kernel"
module_path="/boot/kernel;/boot/modules;/usr/local/modules"
kern.cam.ctl.ha_id=0
root@freenas1[~]

Unter FreeBSD/FreeNAS kann für IP über Infiniband keine der bekannten Loadbalancer Methoden, wie Round Robin oder LACP verwendet werden. Da wir aber iSCSI für die Virtualisierungshosts, bzw. für das Proxmox-Cluster und den VMs einsetzen möchten, ist zwingend für die Erhöhung des Durchsatzes und für die Ausfallsicherheit zu sorgen.
Damit sind wir auch gleich schon beim Thema Multipath angelangt:

Multipath

Etwas Theorie dazu, wenn es lieber mehr sein darf:

Für Multipath ist je Netzwerk Gerät eine IP aus einem eigenen Subnet zu verwenden. Da wir die Infiniband-Netze weder routen, noch für andere Zwecke, außer latenzarm iSCSI zur Verfügung stellen wollen, verwenden wir neue Subnetze, außerhalb der bisher verwendeten.

In unserem Fall 10.20.24.0/24 für ib0 und 10.20.25.0/24 für ib1. Falls zwei HCAs mit je zwei Ports eingesetzt werden, werden analog vier eigene Subnetze benötigt.

Bei FreeBSD ist der Infiniband Treiber standardmäßig auf connected mode (CM) aktiv, was bedeutet, dass TCP/IP zum Einsatz kommt. Dafür ist normalerweise die MTU auf 65520 einzustellen auf Server- und Client-Seite (Proxmox), um den maximalen Durchsatz zu ermöglichen.

Mit diesen Werten hatten wir allerdings Probleme auf der Client-Seite mit SCSI-Kernel-Fehler-Meldungen. Durch heran tasten haben wir eine MTU von 40950 als zuverlässig ermittelt. Die Ursache ist aktuell nicht ganz klar. Wir vermuten Buffer-Probleme innerhalb der Treiber-Implementierung. Das könnte der Grund sein, weshalb Mellanox die ConnectX-2 Karten nicht für FreeBSD frei gegeben hatte. Wir wollen im Zuge des OmniOSce PoC-Projektes vorher auch noch ConnectX-3 Karten unter FreeBSD testen. Möglicherweise erledigt sich das damit auch schon. Mehr dazu, wenn wir die spezifischen Tests abgeschlossen haben. Aktuell genügt uns das Setup, wie es ist, da wir insgesamt mit vier virtuellen Testmaschinen beim Performance-Test auf einen Gesamtdurchsatz von über. 3.000 MB/s kommen, was dem ermittelten maximalen Wert von 3.134 MB/s der gespiegelten Intel Optane SSDs bereits sehr nahe kommt. Faktisch geht nicht mehr viel raus zu holen.

Das Setup der Infiniband-Karte ib0 sieht damit folgendermaßen aus:

Analog dazu ist ib1 einzurichten.

Pool Setup

Für Performance ist ein RAID-Z Pool ungeeignet. Zum einen wird bei einem Rebuild dann von allen Platten gelesen, was die Performance extrem nach unten zieht, zum anderen zum anderen sind die Schreib-/Lesewerte damit nicht befriedigent.

Es ist daher dringend empfohlen, VDEVs aus je zwei gespiegelten Platten (Mirroring) zu einem Pool zusammen zu schalten. In unserem Setup sind das 16 HGST 10TB HE2 SAS3 Platten, also 8 VDEVs mit je zwei Platten im Spiegelverbund plus die zwei Intel Optanes zu einem Spiegel verbundenen VDEV als SLOG.

Der Pool hat als Sync-Methode „Standard“, „lz4“ als Kompression, der Share Type ist „Unix“, Atime ist „off“, Deduplication ist „off“, der Rest bleibt Default:

Im Pool werden dann drei Datasets benötigt, wobei die ersten beiden via NFS frei gegeben werden:

  • Proxmox-ISO-Images
  • Proxmox-Snapshots
  • iSCSI

NFS Sharing

FreeNAS GUI => Sharing => Unix (NFS) Shares

Je Dataset Proxmox-* ist ein Share anzulegen mit aktiviertem All Dirs und mit den IPs der Proxmox-Cluster-Knoten aus dem SFP+ lagg0 Subnetz:

iSCSI Multipath Setup

Target Global Configuration

FreeNAS GUI => Sharing => Block (iSCSI) => Target Global Configuration:

Basename = iqn.2019-05.de.getcom.freenas1
Pool Availble Space Threshold (%) = 75

Portals

FreeNAS GUI => Sharing => Block (iSCSI) => Portals

Je Infiniband Subnet, bzw. IP, ist ein Portal zu erstellen.

Initiators

FreeNAS GUI => Sharing => Block (iSCSI) => Initiators

Es wird ein Initator benötigt, zuerst einmal ohne Einschränkung (ALL/ALL):

Authorized Access

FreeNAS GUI => Sharing => Block (iSCSI) => Authorized Access.

Keine Einschränkungen, das kann später geändert werden, wird aber nicht wirklich benötigt, da iSCSI nur auf den von Außen nicht erreichbaren Infiniband Subnetzen aktiv ist.

Targets

FreeNAS GUI => Sharing => Block (iSCSI) => Targets

Hier ist jetzt ein Target anzulegen. Der Name wird klein geschrieben und ist hier frei wählbar, kann also proxmox, proxmox0, iscsi oder wie in unserem Fall iscsi-target0 heißen. Dem Target sind beide Portal Group IDs „1“ + „2“ und die Initiator Group ID „1“ zuzuweisen:

Extents

FreeNAS GUI => Sharing => Block (iSCSI) => Extents

Wie im Screenshot ersichtlich, entsprechend die Werte auswählen:

Associated Targets

FreeNAS GUI => Sharing => Block (iSCSI) => Associated Targets

Wie im Screenshot ersichtlich, entsprechend auswählen:

Damit ist das iSCSI Setup abgeschlossen.

Aktivierung des iSCSI und NFS Services

FreeNAS GUI => Services => iSCSI

FreeNAS GUI => Services => NFS

Start Automatically muss ausgewählt werden und den Schalter dann nach rechts ziehen:

Damit ist das Setup auf der FreeNAS Seite abgeschlossen.

Proxmox Setup

iSCSI & FreeNAS: Verbindungsabbrüche und hängende VMs in Proxmox

Bei iSCSI konnten gelegentlich Verbindungsabbrüche in den Logs gesichtet werden.
Gleichzeitig hingen die betroffenen VMs auf Proxmox.

WARNING: 1.2.3.4 (iqn.2019-05.de.getcom.freenas1:97665f7s): no ping reply (NOP-Out) after 5 seconds; dropping connection
WARNING: 1.2.3.4 (iqn.2019-05.de.getcom.freenas1:97665f7s): no ping reply (NOP-Out) after 5 seconds; dropping connection		
WARNING: 1.2.3.4 (iqn.2019-05.ch.mydom.ctl:97665f7s): no ping reply (NOP-Out) after 5 seconds; dropping connection

Abhilfe:

System => Tunables => Add

Variable: kern.cam.ctl.iscsi.ping_timeout
Value: 0
Type: sysctl
Comment: Avoid iSCSI connection dropping
enabled: true

FreeNAS auf getcom Supermicro Hardware, Watchdog-Problem mit sporadischen Server-Reboots

Gelegentlich haben wir festgestellt, dass FreeNAS auf getcom Serverhardware mit Supermicro-Mainboards sporadisch durchstartet. Auf der Suche nach der Ursache sind wir dann fündig geworden beim FreeNAS watchdog.

Bisherige Hardware Kandidaten waren das Supermicro Board X10DRi mit Firmware Revision 03.58 und neuer.

root@freenas1[~]# ipmitool mc watchdog get
Watchdog Timer Use: SMS/OS (0x44)
Watchdog Timer Is: Started/Running
Watchdog Timer Actions: No action (0x00)
Pre-timeout interval: 0 seconds
Timer Expiration Flags: 0x00
Initial Countdown: 300 sec
Present Countdown: 290 sec

Prüfung bestehender Eventlogs:

root@freenas1[~]# ipmitool sel list   
SEL has no entries

Temporäre Abschaltung des Watchdog timeouts:

root@freenas1[~]# ipmitool mc watchdog off   
Watchdog Timer Shutoff successful -- timer stopped

Systemweite Abschaltung via GUI:

System => Tuneables => Add:

Variable: watchdogd_enable
Value: NO
Type: rc.conf
Comment: Disables IPMI Watchdog
enabled: true

Alternativ via Cronjob:

Tasks => Cron Jobs => Add

ipmitool mc watchdog off

run as: root

Hourly

Bareos @FreeBSD @Freenas 11.2

Verwendete Komponenten:

bareos-logo

Voraussetzung für dieses Setup:

  • FreeNAS 11.2-RELEASE-p6
  • Vollständige Basiskonfiguration inklusive Netzwerkdevices, Storage-Pool, etc.

Um Bareos Server und die WebUI auf einem FreeNAS 11.2 Storage Server zu installieren, muss man sich über folgendes im Klaren sein:

  • FreeNAS ist eine Appliance und somit ist per Design keine direkte Installation einer zusätzlichen Software vorgesehen und das muss auch so bleiben.
  • FreeNAS bietet ein Plugin für Bacula, nicht jedoch für Bareos.
  • Alle zusätzlichen Services, die nicht unter FreeNAS verfügbar sind, müssen daher in jeweils einem eigenen Jail laufen.

Vorgehensweise:

Wir erstellen ein Jail mit dem Namen „bareos-server“ innerhalb von FreeNAS, weisen ein Ethernet-Device zu und starten das Jail:

  • Jail Name: bareos-server
  • Template: FreeBSD
  • IPv4 address: <static_ip>
  • Autostart: Checked
  • VIMAGE: Checked
  • Alle anderen Optionen bleiben default (oder basierend auf einer eigenen Konfiguration)

Um Zugriff von Außen via SSH auf den neuen „bareos-server“ zu erhalten, sind folgende Schritte nötig:

Rechts am Ende des Jail-Eintrags befinden sich drei Punkte. Beim Klick darauf öffnet sich ein Kontextmenü. Hier eine Shell öffnen. (Jails > Jails > bareos-server > Shell)

Innerhalb der Shell des „bareos-server“ Jails folgende Änderungen vornehmen:

  • Änderung /etc/rc.conf:
    • echo 'sshd_enable="YES"' >>/etc/rc.conf
  • Erlaube root login. (alternativ kann man einen Benutzer anlegen und sudo verwenden)
    • vi /etc/ssh/sshd_config
      • PermitRootLogin YES
  • Start SSH service.
    • service sshd start
  • Ändere das root Passwort.
    • passwd
    • Folge dem Prompt, um das Passwort zu ändern.

Von nun an kann man sich direkt via SSH am bareos-server anmelden mit

  • ssh root@bareos-server

Anschließend sind folgende Vorbereitungen notwendig:

  • sed -i '' s/quarterly/latest/g /etc/pkg/FreeBSD.conf
  • pkg search bareos
  • pkg install bareos-client bareos-server bareos-webui postgresql95-server nginx php72 php72-xml php72-session php72-simplexml php72-gd php72-ctype php72-mbstring php72-zlib php72-tokenizer php72-iconv php72-pecl-mcrypt php72-pear-DB_ldap php72-zip php72-dom php72-sqlite3 php72-gettext php72-curl php72-json php72-opcache php72-wddx php72-hash php72-soap
  • echo 'bareos_sd_enable="YES"' >>/etc/rc.conf

Mit der zweiten Zeile wird der bareos_sd service beim Booten des Jails mit gestartet.

Nun ist noch eine Konfiguration notwendig, die alle bareos-sd.d/* Konfigurationen lädt:

  • echo '@/usr/local/etc/bareos/bareos-sd.d/*/*' >>/usr/local/etc/bareos/bareos-sd.conf

Nun benötigen wir einen pgsql login und setzen die Collation auf deutsch, da wir bei der Suche deutsche Umlaute erwarten:

  • cat >> /etc/login.conf << __EOF
    # PostgreSQL
    pgsql:\
    :lang=de_DE.UTF-8:\
    :setenv=LC_COLLATE=C:\
    :tc=default:
    __EOF

Neuladen der Login-Datenbank:

  • cap_mkdb /etc/login.conf

Nun initialisieren wir die Datenbanken:

  • /usr/local/etc/rc.d/postgresql initdb

Nun starten wir den PostgreSQL:

  • root@bareos-server:~ # /usr/local/etc/rc.d/postgresql start
    LOG: Logausgabe nach stderr endet
    TIPP: Die weitere Logausgabe geht an Logziel "syslog".

Wir kümmern uns nun um die Bareos Server Konfiguration. Die nicht benötigten*.sample Files werden gelöscht und die Permissions korrigiert:

  • chown -R bareos:bareos /usr/local/etc/bareos
  • find /usr/local/etc/bareos -type f -exec chmod 640 {} ';'
  • find /usr/local/etc/bareos -type d -exec chmod 750 {} ';'
  • find /usr/local/etc/bareos -name \*\.sample -delete

Für das „Tracking“ behalten wir eine Kopie der originalen Konfiguration:

  • cp -a /usr/local/etc/bareos /usr/local/etc/bareos.orig

Nun passen wie die Bareos Catalog Konfiguration an unter:
/usr/local/etc/bareos.ORG/bareos-dir.d/catalog/MyCatalog.conf
Nach der Anpassung sieht das so aus (das Passwort ist natürlich entsprechend anzupassen):

  • Catalog {
    Name = MyCatalog
    dbdriver = "postgresql"
    dbname = "bareos"
    dbuser = "bareos"
    dbpassword = "BAREOS-DATABASE-PASSWORD"
    }

Wir prüfen, ob beide Benutzer in der bareos-Gruppe sind:

  • root@bareos-server:~ # pw groupmod bareos -m pgsql
    root@bareos-server:~ # id pgsql
    uid=70(pgsql) gid=70(pgsql) groups=70(pgsql),997(bareos)
    root@bareos-server:~ # pw groupmod bareos -m www
    root@bareos-server:~ # id www
    uid=80(www) gid=80(www) groups=80(www),997(bareos)

Nun wird die PostgreSQL Datenbank für die Bareos Instanz vorbereitet. Dazu verwenden wir die Skripte aus dem Bareos Paket unter /usr/local/lib/bareos/scripts.

  • root@bareos-server:~ # su - pgsql
    $ whoami
    pgsql
    $ /usr/local/lib/bareos/scripts/create_bareos_database
    Creating postgresql database
    CREATE DATABASE
    ALTER DATABASE
    Database encoding OK
    Creating of bareos database succeeded.
    $ /usr/local/lib/bareos/scripts/make_bareos_tables
    Making postgresql tables
    CREATE TABLE
    ALTER TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE INDEX
    CREATE INDEX
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE INDEX
    CREATE INDEX
    CREATE TABLE
    CREATE TABLE
    CREATE TABLE
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE TABLE
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE INDEX
    CREATE TABLE
    CREATE TABLE
    CREATE TABLE
    CREATE TABLE
    CREATE TABLE
    CREATE TABLE
    CREATE TABLE
    CREATE TABLE
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    INSERT 0 1
    DELETE 0
    INSERT 0 1
    Creation of Bareos PostgreSQL tables succeeded.
    $ /usr/local/lib/bareos/scripts/grant_bareos_privileges
    Granting postgresql tables
    CREATE ROLE
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    GRANT
    Privileges for user bareos granted ON database bareos.
    $

Verfizierung, ob die benötigte DB vorhanden ist:

  • su -m bareos -c 'psql -l'
    List of databases
    Name       | Owner | Encoding  | Collate | Ctype       |Access privileges
    -----------+-------+-----------+---------+-------------+-----------------
    bareos     | pgsql | SQL_ASCII | C       | C           |
    postgres   | pgsql | UTF8      | C       | de_DE.UTF-8 |
    template0  | pgsql | UTF8      | C       | de_DE.UTF-8 | =c/pgsql +
    |          |       |           |         | pgsql=CTc/pgsql
    template1  | pgsql | UTF8      | C       | de_DE.UTF-8 | =c/pgsql +
    |          |       |           |         | pgsql=CTc/pgsql
    (4 rows)

Wir fügen die PostgreSQL Database Jobs ein in crontab(1):

  • root@bareos-server:~ # su - pgsql
    $ whoami
    pgsql
    $ cat >/usr/local/pgsql/vacuum.sh << __EOF
    #! /bin/sh
    /usr/local/bin/vacuumdb -a -z 1> /dev/null 2> /dev/null
    /usr/local/bin/reindexdb -a 1> /dev/null 2> /dev/null
    /usr/local/bin/reindexdb -s 1> /dev/null 2> /dev/null
    __EOF
    $ chmod +x /usr/local/pgsql/vacuum.sh
    $ cat /usr/local/pgsql/vacuum.sh
    #! /bin/sh
    /usr/local/bin/vacuumdb -a -z 1> /dev/null 2> /dev/null
    /usr/local/bin/reindexdb -a 1> /dev/null 2> /dev/null
    /usr/local/bin/reindexdb -s 1> /dev/null 2> /dev/null
    $ crontab -e
    crontab: no crontab for pgsql - using an empty one
    # DO NOT EDIT THIS FILE - edit the master and reinstall.
    # (/tmp/crontab.Be9j9VVCUa installed on Thu Apr 26 21:45:04 2018)
    # (Cron version -- $FreeBSD$)
    0 0 * * * /usr/local/pgsql/vacuum.sh
    /tmp/crontab.g8mCztyvSv: 5 lines, 191 characters.
    crontab: installing new crontab
    $ crontab -l
    # DO NOT EDIT THIS FILE - edit the master and reinstall.
    # (/tmp/crontab.Be9j9VVCUa installed on Thu Apr 26 21:45:04 2018)
    # (Cron version -- $FreeBSD$)
    0 0 * * * /usr/local/pgsql/vacuum.sh
    $ exit
    root@bareos-server:~ # cat /var/cron/tabs/pgsql
    # DO NOT EDIT THIS FILE - edit the master and reinstall.
    # (/tmp/crontab.g8mCztyvSv installed on Mon Dec 31 05:01:54 2018)
    # (Cron version -- $FreeBSD: releng/11.2/usr.sbin/cron/crontab/crontab.c 321241 2017-07-19 20:22:16Z ngie $)
    # DO NOT EDIT THIS FILE - edit the master and reinstall.
    # (/tmp/crontab.Be9j9VVCUa installed on Thu Apr 26 21:45:04 2018)
    # (Cron version -- $FreeBSD$)
    0 0 * * * /usr/local/pgsql/vacuum.sh
    root@bareos-server:~ # su -m pgsql -c 'crontab -l'
    # DO NOT EDIT THIS FILE - edit the master and reinstall.
    # (/tmp/crontab.Be9j9VVCUa installed on Thu Apr 26 21:45:04 2018)
    # (Cron version -- $FreeBSD$)
    0 0 * * * /usr/local/pgsql/vacuum.sh

Wir legen nun lokal die bareos-Verzeichnisse an, das /bareos-dr dient später als NFS mount point für ein weiteres DR-Storage:

  • root@bareos-server:~ # mkdir -p /bareos/bootstrap
    root@bareos-server:~ # mkdir -p /bareos/restore
    root@bareos-server:~ # mkdir -p /bareos/storage/FileStorage
    root@bareos-server:~ # mkdir -p /bareos/storage/FileStorage2
    root@bareos-server:~ # mkdir -p /bareos-dr/bootstrap
    root@bareos-server:~ # mkdir -p /bareos-dr/restore
    root@bareos-server:~ # mkdir -p /bareos-dr/storage/FileStorage
    root@bareos-server:~ # mkdir -p /bareos-dr/storage/FileStorage2
    root@bareos-server:~ # chown -R bareos:bareos /bareos /bareos-dr
    root@bareos-server:~ # find /bareos /bareos-dr -ls | column -t
    120761 1 drwxr-xr-x 5 bareos bareos 5 Dec 31 05:20 /bareos
    120774 1 drwxr-xr-x 3 bareos bareos 3 Dec 31 05:20 /bareos/storage
    120775 1 drwxr-xr-x 2 bareos bareos 2 Dec 31 05:20 /bareos/storage/FileStorage
    120786 1 drwxr-xr-x 2 bareos bareos 2 Dec 31 05:20 /bareos/storage/FileStorage2
    120768 1 drwxr-xr-x 2 bareos bareos 2 Dec 31 05:20 /bareos/restore
    120762 1 drwxr-xr-x 2 bareos bareos 2 Dec 31 05:20 /bareos/bootstrap
    120776 1 drwxr-xr-x 5 bareos bareos 5 Dec 31 05:21 /bareos-dr
    120777 1 drwxr-xr-x 2 bareos bareos 2 Dec 31 05:20 /bareos-dr/bootstrap
    120783 1 drwxr-xr-x 2 bareos bareos 2 Dec 31 05:20 /bareos-dr/restore
    120784 1 drwxr-xr-x 3 bareos bareos 3 Dec 31 05:21 /bareos-dr/storage
    120785 1 drwxr-xr-x 2 bareos bareos 2 Dec 31 05:21 /bareos-dr/storage/FileStorage
    120787 1 drwxr-xr-x 2 bareos bareos 2 Dec 31 05:21 /bareos-dr/storage/FileStorage2

Bareos

Im nächsten Schritt benötigen wir die Passwörter für die Bareos Subsysteme, wie wir das bereits analog für dasBAREOS-DATABASE-PASSWORD für den bareos User für die PostgreSQL Bareos Datenbank erstellt hatten:

  • BAREOS-DATABASE-PASSWORD
  • BAREOS-DIR-PASSWORD
  • BAREOS-SD-PASSWORD
  • BAREOS-FD-PASSWORD
  • BAREOS-MON-PASSWORD
  • ADMIN-PASSWORD

Wir verwenden dabei /dev/urandom zur Generierung der jeweiligen Passwörter, wie hier im Beispiel (je länger, je sicherer):

  • root@bareos-server:~ # cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 60 ; echo
    R32CERWerLmlHunzCfiTOEjhG2oo4oaWmTChzlQiuOEh50sSSwb7xKccOw8g

Wir haben bereits die MyCatalog.conf mit nachfolgendem Inhalt angelegt:

# cat /usr/local/etc/bareos/bareos-dir.d/catalog/MyCatalog.conf
Catalog {
  Name = MyCatalog
  dbdriver = "postgresql"
  dbname = "bareos"
  dbuser = "bareos"
  dbpassword = "BAREOS-DATABASE-PASSWORD"
}

Anlegen von /usr/local/etc/bareos/bconsole.d falls nicht vorhanden:

# test -d /usr/local/etc/bareos/bconsole.d/ || mkdir -p /usr/local/etc/bareos/bconsole.d/;\
chown bareos.bareos /usr/local/etc/bareos/bconsole.d

Symbolischen Link erstellen, falls notwendig:

# test -n /usr/local/etc/bareos/bconsole.d/bconsole.conf || \
ln -s /usr/local/etc/bareos/bconsole.conf /usr/local/etc/bareos/bconsole.d/

Inhalt von /usr/local/etc/bareos/bconsole.d/bconsole.conf nach der Anpassung:

# cat /usr/local/etc/bareos/bconsole.d/bconsole.conf
#
# Bareos User Agent (or Console) Configuration File
#

Director {
  Name = bareos-server.getcom.de
  address = localhost
  Password = "BAREOS-DIR-PASSWORD"
  Description = "Bareos Console credentials for local Director"
}

Inhalt von/usr/local/etc/bareos/bareos-dir.d/director/bareos-dir.conf nach der Anpassung:

# cat /usr/local/etc/bareos/bareos-dir.d/director/bareos-dir.conf
Director {
  Name = bareos-server.getcom.de
  QueryFile = "/usr/local/lib/bareos/scripts/query.sql"
  Maximum Concurrent Jobs = 100
  Password = "BAREOS-DIR-PASSWORD"
  Messages = Daemon
  Auditing = yes

  # Enable the Heartbeat if you experience connection losses
  # (eg. because of your router or firewall configuration).
  # Additionally the Heartbeat can be enabled in bareos-sd and bareos-fd.
  #
  # Heartbeat Interval = 1 min

  # remove comment in next line to load dynamic backends from specified directory
  # Backend Directory = /usr/local/lib

  # remove comment from "Plugin Directory" to load plugins from specified directory.
  # if "Plugin Names" is defined, only the specified plugins will be loaded,
  # otherwise all director plugins (*-dir.so) from the "Plugin Directory".
  #
  # Plugin Directory = /usr/local/lib/bareos/plugins
  # Plugin Names = ""
}

Inhalt von /usr/local/etc/bareos/bareos-dir.d/job/RestoreFiles.confnach der Anpassung:

# cat /usr/local/etc/bareos/bareos-dir.d/job/RestoreFiles.conf
Job {
  Name = "RestoreFiles"
  Description = "Standard Restore."
  Type = Restore
  Client = Default
  FileSet = "SelfTest"
  Storage = File
  Pool = BR-MO
  Messages = Standard
  Where = /bareos/restore
  Accurate = yes
}

Neues File /usr/local/etc/bareos/bareos-dir.d/client/Default.conf :

# cat /usr/local/etc/bareos/bareos-dir.d/client/Default.conf
Client {
  Name = Default
  address = bareos-server.getcom.de
  Password = "BAREOS-FD-PASSWORD"
}

Neues File /usr/local/etc/bareos/bareos-dir.d/client/bareos-server.getcom.de.conf :

# cat /usr/local/etc/bareos/bareos-dir.d/client/bareos-server.getcom.de.conf
Client {
  Name = bareos-server.getcom.de
  Description = "Client resource of the Director itself."
  address = bareos-server.getcom.de
  Password = "BAREOS-FD-PASSWORD"
}

Nachfolgendes File ist ohne Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/job/BackupCatalog.conf
Job {
  Name = "BackupCatalog"
  Description = "Backup the catalog database (after the nightly save)"
  JobDefs = "DefaultJob"
  Level = Full
  FileSet="Catalog"
  Schedule = "WeeklyCycleAfterBackup"

  # This creates an ASCII copy of the catalog
  # Arguments to make_catalog_backup.pl are:
  #  make_catalog_backup.pl 
  RunBeforeJob = "/usr/local/lib/bareos/scripts/make_catalog_backup.pl MyCatalog"

  # This deletes the copy of the catalog
  RunAfterJob  = "/usr/local/lib/bareos/scripts/delete_catalog_backup"

  # This sends the bootstrap via mail for disaster recovery.
  # Should be sent to another system, please change recipient accordingly
  Write Bootstrap = "|/usr/local/bin/bsmtp -h localhost -f \"\(Bareos\) \" -s \"Bootstrap for Job %j\" root@localhost" # (#01)
  Priority = 11                   # run after main backup
}

Nachfolgendes File ist ohne Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/messages/Standard.conf
Messages {
  Name = Standard
  Description = "Reasonable message delivery -- send most everything to email address and to the console."
  operatorcommand = "/usr/local/bin/bsmtp -h localhost -f \"\(Bareos\) \\" -s \"Bareos: Intervention needed for %j\" %r"
  mailcommand = "/usr/local/bin/bsmtp -h localhost -f \"\(Bareos\) \\" -s \"Bareos: %t %e of %c %l\" %r"
  operator = root@localhost = mount                                 # (#03)
  mail = root@localhost = all, !skipped, !saved, !audit             # (#02)
  console = all, !skipped, !saved, !audit
  append = "/var/log/bareos/bareos.log" = all, !skipped, !saved, !audit
  catalog = all, !skipped, !saved, !audit
}

Nachfolgendes File ist ohne Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/messages/Daemon.conf
Messages {
  Name = Daemon
  Description = "Message delivery for daemon messages (no job)."
  mailcommand = "/usr/local/bin/bsmtp -h localhost -f \"\(Bareos\) \\" -s \"Bareos daemon message\" %r"
  mail = root@localhost = all, !skipped, !audit # (#02)
  console = all, !skipped, !saved, !audit
  append = "/var/log/bareos/bareos.log" = all, !skipped, !audit
  append = "/var/log/bareos/bareos-audit.log" = audit
}

Pools

Per default hat Bareos vier Pools konfiguriert. Da wir sie nicht benutzen, löschen wir sie:

# ls -l /usr/local/etc/bareos/bareos-dir.d/pool
total 14
-rw-rw----  1 bareos  bareos  536 Apr 16 08:14 Differential.conf
-rw-rw----  1 bareos  bareos  512 Apr 16 08:14 Full.conf
-rw-rw----  1 bareos  bareos  534 Apr 16 08:14 Incremental.conf
-rw-rw----  1 bareos  bareos   48 Apr 16 08:14 Scratch.conf

# rm -f /usr/local/etc/bareos/bareos-dir.d/pool/*.conf

Wir legen nun zwei Pools für DAILY Backups und MONTHLY Backups an:

# cat /usr/local/etc/bareos/bareos-dir.d/pool/BRONZE-DAILY-POOL.conf
Pool {
  Name = BR-DA
  Pool Type = Backup
  Recycle = yes                       # Bareos can automatically recycle Volumes
  AutoPrune = yes                     # Prune expired volumes
  Volume Retention = 7 days           # How long should the Full Backups be kept? (#06)
  Maximum Volume Bytes = 2G           # Limit Volume size to something reasonable
  Maximum Volumes = 100000            # Limit number of Volumes in Pool
  Label Format = "BR-DA-"             # Volumes will be labeled "BR-DA-"
}

# cat /usr/local/etc/bareos/bareos-dir.d/pool/BRONZE-MONTHLY-POOL.conf
Pool {
  Name = BR-MO
  Pool Type = Backup
  Recycle = yes                       # Bareos can automatically recycle Volumes
  AutoPrune = yes                     # Prune expired volumes
  Volume Retention = 120 days         # How long should the Full Backups be kept? (#06)
  Maximum Volume Bytes = 2G           # Limit Volume size to something reasonable
  Maximum Volumes = 100000            # Limit number of Volumes in Pool
  Label Format = "BR-MO-"             # Volumes will be labeled "BR-MO-"
}

Nachfolgendes File ist ohne Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/schedule/WeeklyCycle.conf
Schedule {
  Name = "WeeklyCycle"
  Run = Full 1st sat at 21:00                   # (#04)
  Run = Differential 2nd-5th sat at 21:00       # (#07)
  Run = Incremental mon-fri at 21:00            # (#10)
}

Nachfolgendes File ist ohne Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/schedule/WeeklyCycle.conf
Schedule {
  Name = "WeeklyCycle"
  Run = Full 1st sat at 21:00                   # (#04)
  Run = Differential 2nd-5th sat at 21:00       # (#07)
  Run = Incremental mon-fri at 21:00            # (#10)
}

Inhalt von/usr/local/etc/bareos/bareos-dir.d/jobdefs/DefaultJob.conf nach der Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/jobdefs/DefaultJob.conf
JobDefs {
  Name = "DefaultJob"
  Type = Backup
  Level = Differential
  Client = Default
  FileSet = "SelfTest"
  Schedule = "WeeklyCycle"
  Storage = File
  Messages = Standard
  Pool = BR-DA
  Priority = 10
  Write Bootstrap = "/bareos/bootstrap/%c.bsr"
}

Inhalt von /usr/local/etc/bareos/bareos-dir.d/storage/File.conf
nach der Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/storage/File.conf
Storage {
  Name = File
  Address = bareos-server.getcom.de
  Password = "BAREOS-SD-PASSWORD"
  Device = FileStorage
  Media Type = File
}

Inhalt von /usr/local/etc/bareos/bareos-dir.d/console/bareos-mon.conf nach der Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/console/bareos-mon.conf
Console {
  Name = bareos-mon
  Description = "Restricted console used by tray-monitor to get the status of the director."
  Password = "BAREOS-MON-PASSWORD"
  CommandACL = status, .status
  JobACL = *all*
}

Inhalt von /usr/local/etc/bareos/bareos-dir.d/fileset/Catalog.conf nach der Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/fileset/Catalog.conf
FileSet {
  Name = "Catalog"
  Description = "Backup the catalog dump and Bareos configuration files."
  Include {
    Options {
      signature = MD5
      Compression = lzo
    }
    File = "/var/db/bareos"
    File = "/usr/local/etc/bareos"
  }
}

Inhalt von /usr/local/etc/bareos/bareos-dir.d/fileset/SelfTest.conf nach der Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/fileset/SelfTest.conf
FileSet {
  Name = "SelfTest"
  Description = "fileset just to backup some files for selftest"
  Include {
    Options {
      Signature   = MD5
      Compression = lzo
    }
    File = "/usr/local/sbin"
  }
}

Wir benötigen kein gebundeltes LinuxAll.conf und WindowsAllDrives.conf filesets, daher löschen wir das:

# ls -l /usr/local/etc/bareos/bareos-dir.d/fileset/
total 18
-rw-rw----  1 bareos  bareos  250 Apr 27 02:25 Catalog.conf
-rw-rw----  1 bareos  bareos  765 Apr 16 08:14 LinuxAll.conf
-rw-rw----  1 bareos  bareos  210 Apr 27 02:27 SelfTest.conf
-rw-rw----  1 bareos  bareos  362 Apr 16 08:14 WindowsAllDrives.conf

# rm -f /usr/local/etc/bareos/bareos-dir.d/fileset/LinuxAll.conf
# rm -f /usr/local/etc/bareos/bareos-dir.d/fileset/Windows*All*Drives.conf

Wir definieren nun zwei neue filesets Windows.conf und UNIX.conf :

Neue Datei /usr/local/etc/bareos/bareos-dir.d/fileset/Windows.conf :

# cat /usr/local/etc/bareos/bareos-dir.d/fileset/Windows.conf
FileSet {
  Name = Windows
  Enable VSS = yes
  Include {
    Options {
      Signature = MD5
      Drive Type = fixed
      IgnoreCase = yes
      WildFile = "[A-Z]:/pagefile.sys"
      WildDir  = "[A-Z]:/RECYCLER"
      WildDir  = "[A-Z]:/$RECYCLE.BIN"
      WildDir  = "[A-Z]:/System Volume Information"
      Exclude = yes
      Compression = lzo
    }
    File = /
  }

Neue Datei /usr/local/etc/bareos/bareos-dir.d/fileset/UNIX.conf :

# cat /usr/local/etc/bareos/bareos-dir.d/fileset/UNIX.conf
FileSet {
  Name = "UNIX"
  Include {
    Options {
      Signature = MD5 # calculate md5 checksum per file
      One FS = No     # change into other filessytems
      FS Type = ufs
      FS Type = btrfs
      FS Type = ext2  # filesystems of given types will be backed up
      FS Type = ext3  # others will be ignored
      FS Type = ext4
      FS Type = reiserfs
      FS Type = jfs
      FS Type = xfs
      FS Type = zfs
      noatime = yes
      Compression = lzo
    }
    File = /
  }
  # Things that usually have to be excluded
  # You have to exclude /tmp
  # on your bareos server
  Exclude {
    File = /var/db/bareos
    File = /tmp
    File = /proc
    File = /sys
    File = /var/tmp
    File = /.journal
    File = /.fsck
  }
}

Nachfolgendes File ist ohne Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/profile/operator.conf
Profile {
   Name = operator
   Description = "Profile allowing normal Bareos operations."

   Command ACL = !.bvfs_clear_cache, !.exit, !.sql
   Command ACL = !configure, !create, !delete, !purge, !sqlquery, !umount, !unmount
   Command ACL = *all*

   Catalog ACL = *all*
   Client ACL = *all*
   FileSet ACL = *all*
   Job ACL = *all*
   Plugin Options ACL = *all*
   Pool ACL = *all*
   Schedule ACL = *all*
   Storage ACL = *all*
   Where ACL = *all*
}

Inhalt von /usr/local/etc/bareos/bareos-sd.d/messages/Standard.conf nach der Änderung:

# cat /usr/local/etc/bareos/bareos-sd.d/messages/Standard.conf
Messages {
  Name = Standard
  Director = bareos-server.getcom.de = all
  Description = "Send all messages to the Director."
}

Wir fügen den Pfad /bareos/storage/FileStorage als unseren FileStorage Platz hinzu:

Inhalt von /usr/local/etc/bareos/bareos-sd.d/device/FileStorage.confnach der Änderung:

# cat /usr/local/etc/bareos/bareos-sd.d/device/FileStorage.conf
Device {
  Name = FileStorage
  Media Type = File
  Archive Device = /bareos/storage/FileStorage
  LabelMedia = yes;                   # lets Bareos label unlabeled media
  Random Access = yes;
  AutomaticMount = yes;               # when device opened, read it
  RemovableMedia = no;
  AlwaysOpen = no;
  Description = "File device. A connecting Director must have the same Name and MediaType."
}

Inhalt von /usr/local/etc/bareos/bareos-sd.d/storage/bareos-sd.confnach der Änderung:

# cat /usr/local/etc/bareos/bareos-sd.d/storage/bareos-sd.conf
Storage {
  Name = bareos-server.getcom.de
  Maximum Concurrent Jobs = 20

  # remove comment from "Plugin Directory" to load plugins from specified directory.
  # if "Plugin Names" is defined, only the specified plugins will be loaded,
  # otherwise all storage plugins (*-sd.so) from the "Plugin Directory".
  #
  # Plugin Directory = /usr/local/lib/bareos/plugins
  # Plugin Names = ""
}

Inhalt von /usr/local/etc/bareos/bareos-sd.d/director/bareos-mon.conf nach der Änderung:

# cat /usr/local/etc/bareos/bareos-sd.d/director/bareos-mon.conf
Director {
  Name = bareos-mon
  Password = "BAREOS-SD-PASSWORD"
  Monitor = yes
  Description = "Restricted Director, used by tray-monitor to get the status of this storage daemon."
}

Inhalt von /usr/local/etc/bareos/bareos-sd.d/director/bareos-dir.conf nach der Änderung:

# cat /usr/local/etc/bareos/bareos-sd.d/director/bareos-dir.conf
Director {
  Name = bareos-server.getcom.de
  Password = "BAREOS-SD-PASSWORD"
  Description = "Director, who is permitted to contact this storage daemon."
}

Inhalt von /usr/local/etc/bareos/bareos-fd.d/messages/Standard.conf nach der Änderung:

# cat /usr/local/etc/bareos/bareos-fd.d/messages/Standard.conf
Messages {
  Name = Standard
  Director = bareos-server.getcom.de = all, !skipped, !restored
  Description = "Send relevant messages to the Director."
}

Inhalt von /usr/local/etc/bareos/bareos-fd.d/director/bareos-dir.conf nach der Änderung:

# cat /usr/local/etc/bareos/bareos-fd.d/director/bareos-dir.conf
Director {
  Name = bareos-server.getcom.de
  Password = "BAREOS-FD-PASSWORD"
  Description = "Allow the configured Director to access this file daemon."
}

Inhalt von /usr/local/etc/bareos/bareos-fd.d/director/bareos-mon.confnach der Änderung:

# cat /usr/local/etc/bareos/bareos-fd.d/director/bareos-mon.conf
Director {
  Name = bareos-mon
  Password = "BAREOS-MON-PASSWORD"
  Monitor = yes
  Description = "Restricted Director, used by tray-monitor to get the status of this file daemon."
}

Inhalt von/usr/local/etc/bareos/bareos-fd.d/client/myself.confnach der Änderung:

# cat /usr/local/etc/bareos/bareos-fd.d/client/myself.conf
Client {
  Name = bareos-server.getcom.de
  Maximum Concurrent Jobs = 20

  # remove comment from "Plugin Directory" to load plugins from specified directory.
  # if "Plugin Names" is defined, only the specified plugins will be loaded,
  # otherwise all storage plugins (*-fd.so) from the "Plugin Directory".
  #
  # Plugin Directory = /usr/local/lib/bareos/plugins
  # Plugin Names = ""

  # if compatible is set to yes, we are compatible with bacula
  # if set to no, new bareos features are enabled which is the default
  # compatible = yes
}

Inhalt von /usr/local/etc/bareos/bareos-dir.d/client/bareos-fd.conf nach der Änderung:

# cat /usr/local/etc/bareos/bareos-dir.d/client/bareos-fd.conf
Client {
  Name = bareos-fd
  Description = "Client resource of the Director itself."
  Address = localhost
  Password = "BAREOS-FD-PASSWORD"
}

Wir prüfen, welches Passwort in welchem File gesetzt ist:

# pwd
/usr/local/etc/bareos

# grep -r Password . | sort -k 4 | column -t
./bareos-dir.d/director/bareos-dir.conf:        Password  =  "BAREOS-DIR-PASSWORD"
./bconsole.d/bconsole.conf:                     Password  =  "BAREOS-DIR-PASSWORD"
./bareos-dir.d/client/Default.conf:             Password  =  "BAREOS-FD-PASSWORD"
./bareos-dir.d/client/bareos-fd.conf:           Password  =  "BAREOS-FD-PASSWORD"
./bareos-dir.d/client/replica.backup.org.conf:  Password  =  "BAREOS-FD-PASSWORD"
./bareos-fd.d/director/bareos-dir.conf:         Password  =  "BAREOS-FD-PASSWORD"
./bareos-dir.d/console/bareos-mon.conf:         Password  =  "BAREOS-MON-PASSWORD"
./bareos-fd.d/director/bareos-mon.conf:         Password  =  "BAREOS-MON-PASSWORD"
./bareos-dir.d/storage/File.conf:               Password  =  "BAREOS-SD-PASSWORD"
./bareos-sd.d/director/bareos-dir.conf:         Password  =  "BAREOS-SD-PASSWORD"
./bareos-sd.d/director/bareos-mon.conf:         Password  =  "BAREOS-SD-PASSWORD"

Wir bereinigen die Berechtigungen:

# chown -R bareos:bareos /usr/local/etc/bareos
# find /usr/local/etc/bareos -type f -exec chmod 640 {} ';'
# find /usr/local/etc/bareos -type d -exec chmod 750 {} ';'

Bareos WebUI

Wir ergänzen oder ändern die Konfigurationen für das Bareos WebUI Interface.

Die Nginx Webserver Konfiguration Datei:

# cat /usr/local/etc/nginx/nginx.conf
user                 www;
worker_processes     4;
worker_rlimit_nofile 51200;
error_log            /var/log/nginx/error.log;

events {
  worker_connections 1024;
}

http {
  include           mime.types;
  default_type      application/octet-stream;
  log_format        main '$remote_addr - $remote_user [$time_local] "$request" ';
  access_log        /var/log/nginx/access.log main;
  sendfile          on;
  keepalive_timeout 65;

  server {
    listen       9100;
    server_name  replica.backup.org bareos;
    root         /usr/local/www/bareos-webui/public;

    location / {
      index index.php;
      try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ .php$ {
      fastcgi_pass 127.0.0.1:9000;
      fastcgi_param APPLICATION_ENV production;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      include fastcgi_params;
      try_files $uri =404;
    }
  }
}

Für PHP ändern wir die Konfigurationsdatei aus dem Paket /usr/local/etc/php.ini-production :

# cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini

# vi /usr/local/etc/php.ini

Wir fügen die Zeitzone Europe/Berlin hinzu:

# diff -u php.ini-production php.ini
--- php.ini-production  2019-02-13 03:23:36.000000000 +0200
+++ php.ini     2019-02-13 13:50:40.513138000 +0200
@@ -934,6 +934,7 @@
 ; Defines the default timezone used by the date functions
 ; http://php.net/date.timezone
-;date.timezone =
+date.timezone = Europe/Berlin

 ; http://php.net/date.default-latitude
 ;date.default_latitude = 31.7667

Inhalt der php-fpm daemon Konfiguration:

# cat /usr/local/etc/php-fpm.conf
[global]
pid = run/php-fpm.pid
log_level = notice

[www]
user = www
group = www
listen = 127.0.0.1:9000
listen.backlog = -1
listen.owner = www
listen.group = www
listen.mode = 0660
listen.allowed_clients = 127.0.0.1
pm = static
pm.max_children = 4
pm.start_servers = 1
pm.min_spare_servers = 0
pm.max_spare_servers = 4
pm.process_idle_timeout = 1000s;
pm.max_requests = 500
request_terminate_timeout = 0
rlimit_files = 51200
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

Der verbliebene Rest der Bareos WebUI Konfiguration:

Neue Datei /usr/local/etc/bareos/bareos-dir.d/console/admin.conf :

# cat /usr/local/etc/bareos/bareos-dir.d/console/admin.conf
Console {
  Name = admin
  Password = ADMIN-PASSWORD
  Profile = webui-admin
}

Neue Datei /usr/local/etc/bareos/bareos-dir.d/profile/webui-admin.conf :

# cat /usr/local/etc/bareos/bareos-dir.d/profile/webui-admin.conf
Profile {
  Name = webui-admin
  CommandACL = !.bvfs_clear_cache, !.exit, !.sql, !configure, !create, !delete, !purge, !sqlquery, !umount, !unmount, *all*
  Job ACL = *all*
  Schedule ACL = *all*
  Catalog ACL = *all*
  Pool ACL = *all*
  Storage ACL = *all*
  Client ACL = *all*
  FileSet ACL = *all*
  Where ACL = *all*
  Plugin Options ACL = *all*
}

Man kann hier durchaus auch weitere Bareos directors hinzu fügen:

Geänderte /usr/local/etc/bareos-webui/directors.ini :

#   test -d /usr/local/etc/bareos-webui || mkdir -p /usr/local/etc/bareos-webui
#   chown bareos.bareos /usr/local/etc/bareos-webui
# cat /usr/local/etc/bareos-webui/directors.ini
;------------------------------------------------------------------------------
; Section localhost-dir
;------------------------------------------------------------------------------
[bareos-server.getcom.de]
enabled = "yes"
diraddress = "bareos-server.getcom.de"
dirport = 9101
catalog = "MyCatalog"

Geänderte Datei /usr/local/etc/bareos-webui/configuration.ini :

# cat /usr/local/etc/bareos-webui/configuration.ini
;------------------------------------------------------------------------------
; SESSION SETTINGS
;------------------------------------------------------------------------------
[session]
timeout=3600

;------------------------------------------------------------------------------
; DASHBOARD SETTINGS
;------------------------------------------------------------------------------
[dashboard]
autorefresh_interval=60000

;------------------------------------------------------------------------------
; TABLE SETTINGS
;------------------------------------------------------------------------------
[tables]
pagination_values=10,25,50,100
pagination_default_value=25
save_previous_state=false

;------------------------------------------------------------------------------
; VARIOUS SETTINGS
;------------------------------------------------------------------------------
[autochanger]
labelpooltype=scratch

Zuletzt noch die Berechtigungen setzen für Bareos WebUI Konfigurations-Dateien:

# chown -R www:www /usr/local/etc/bareos-webui
# chown -R www:www /usr/local/www/bareos-webui

Logs

Erstellung der Log files, Verzeichnisse und Änderung der Berechtigungen:

# chown -R bareos:bareos /var/log/bareos
# :>               /var/log/php-fpm.log
# chown -R www:www /var/log/php-fpm.log
# chown -R www:www /var/log/nginx

Wir benötigen noch Regeln für den newsyslog(8) log rotate daemon, um zu verhindern, dass das Dateisystem früher oder später geflutet wird:

Für den newsyslog daemon verwenden wird die   *.conf.d Verzeichnisse, anstatt das File /etc/newsyslog.conf zu editieren:

# grep conf\\.d /etc/newsyslog.conf
 /etc/newsyslog.conf.d/*
 /usr/local/etc/newsyslog.conf.d/*
# mkdir -p /usr/local/etc/newsyslog.conf.d
# cat > /usr/local/etc/newsyslog.conf.d/bareos << __EOF
# BAREOS
/var/log/php-fpm.log             www:www       640  7     100    @T00  J
/var/log/nginx/access.log        www:www       640  7     100    @T00  J
/var/log/nginx/error.log         www:www       640  7     100    @T00  J
/var/log/bareos/bareos.log       bareos:bareos 640  7     100    @T00  J
/var/log/bareos/bareos-audit.log bareos:bareos 640  7     100    @T00  J
__EOF

Wir verifizieren, ob newsyslog(8) unsere Konfiguration versteht:

# newsyslog -v | tail -5
/var/log/php-fpm.log : --> will trim at Tue May  1 00:00:00 2019
/var/log/nginx/access.log : --> will trim at Tue May  1 00:00:00 2019
/var/log/nginx/error.log : --> will trim at Tue May  1 00:00:00 2019
/var/log/bareos/bareos.log : --> will trim at Tue May  1 00:00:00 2019
/var/log/bareos/bareos-audit.log : --> will trim at Tue May  1 00:00:00 2019

Skel

Wir legen nun die sogenannten Bareos skel files für das rc(8) Script an, um das komplette Setup über ein File zu triggern.

Wenn wir das nicht tun würden, würde der Bareos services nicht stoppen und folgender Fehler würde ausgegeben werden:

# /usr/local/etc/rc.d/bareos-sd onestart
Starting bareos_sd.
27-Apr 02:59 bareos-sd JobId 0: Error: parse_conf.c:580 Failed to read config file "/usr/local/etc/bareos/bareos-sd.conf"
bareos-sd ERROR TERMINATION
parse_conf.c:148 Failed to find config filename.
/usr/local/etc/rc.d/bareos-sd: WARNING: failed to start bareos_sd

Wir legen sie an:

# cat > /usr/local/etc/bareos/bareos-dir.conf << __EOF
 @/usr/local/etc/bareos/bareos-dir.d/*/*
__EOF

# cat > /usr/local/etc/bareos/bareos-fd.conf << __EOF
@/usr/local/etc/bareos/bareos-fd.d/*/*
__EOF

# cat > /usr/local/etc/bareos/bareos-sd.conf << __EOF
@/usr/local/etc/bareos/bareos-sd.d/*/*
__EOF

# cat > /usr/local/etc/bareos/bconsole.conf << __EOF
@/usr/local/etc/bareos/bconsole.d/*
__EOF

Die Verifizierung:

# cat /usr/local/etc/bareos/bareos-dir.conf
@/usr/local/etc/bareos/bareos-dir.d/*/*
# cat /usr/local/etc/bareos/bareos-fd.conf
@/usr/local/etc/bareos/bareos-fd.d/*/*

# cat /usr/local/etc/bareos/bareos-sd.conf
@/usr/local/etc/bareos/bareos-sd.d/*/*

# cat /usr/local/etc/bareos/bconsole.conf
@/usr/local/etc/bareos/bconsole.d/*

Nach all den Änderungen und Anlegen neuer Files, versichern wir uns, dass alle Files unterhalb von /usr/local/etc/bareos die richtigen Berechtigungen haben werden:

# chown -R bareos:bareos /usr/local/etc/bareos
# find /usr/local/etc/bareos -type f -exec chmod 640 {} ';'
# find /usr/local/etc/bareos -type d -exec chmod 750 {} ';'

Es ist soweit…

Der main FreeBSD Service Start /etc/rc.conf fehlt nur noch.

Nach den Änderungen der /etc/rc.conf sieht das so aus:

# cat /etc/rc.conf
# NETWORK
  hostname=bareos-server.getcom.de
  ifconfig_em0="inet 10.144.88.11/24 up"
  defaultrouter="10.144.88.1"

# DAEMONS
  zfs_enable=YES
  sshd_enable=YES
  nfs_client_enable=YES
  syslogd_flags="-ss"
  sendmail_enable=NONE

# OTHER
  clear_tmp_enable=YES
  dumpdev=NO

# BAREOS
  postgresql_enable=YES
  postgresql_class=pgsql
  bareos_dir_enable=YES
  bareos_sd_enable=YES
  bareos_fd_enable=YES
  php_fpm_enable=YES
  nginx_enable=YES

Der PostgreSQL läuft bereits:

# /usr/local/etc/rc.d/postgresql status
pg_ctl: server is running (PID: 28424)
/usr/local/bin/postgres "-D" "/usr/local/pgsql/data"

Wir starten nun den Rest von Bareos:

Zuerest den PHP php-fpm daemon:

# /usr/local/etc/rc.d/php-fpm start
Performing sanity check on php-fpm configuration:
[23-Feb-2019 02:57:09] NOTICE: configuration file /usr/local/etc/php-fpm.conf test is successful

Starting php_fpm.

Der Nginx webserver:

# /usr/local/etc/rc.d/nginx start
Performing sanity check on nginx configuration:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
Starting nginx.

Bareos Storage Daemon:

# /usr/local/etc/rc.d/bareos-sd start
Starting bareos_sd.

Bareos File Daemon, bekannt als Bareos Client:

# /usr/local/etc/rc.d/bareos-fd start
Starting bareos_f

… und zuletzt der wichtigste daemon, der Bareos Director:

# /usr/local/etc/rc.d/bareos-dir start
Starting bareos_dir.

Wir prüfen noch, auf welchen Ports die Daemons lauschen:

# sockstat -l4
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
bareos   bareos-dir 89823 4  tcp4   *:9101                *:*
root     bareos-fd  73066 3  tcp4   *:9102                *:*
www      nginx      33857 6  tcp4   *:9100                *:*
www      nginx      28675 6  tcp4   *:9100                *:*
www      nginx      20960 6  tcp4   *:9100                *:*
www      nginx      15881 6  tcp4   *:9100                *:*
root     nginx      14388 6  tcp4   *:9100                *:*
www      php-fpm    84047 0  tcp4   127.0.0.1:9000        *:*
www      php-fpm    82285 0  tcp4   127.0.0.1:9000        *:*
www      php-fpm    80688 0  tcp4   127.0.0.1:9000        *:*
www      php-fpm    74735 0  tcp4   127.0.0.1:9000        *:*
root     php-fpm    70518 8  tcp4   127.0.0.1:9000        *:*
bareos   bareos-sd  5151  3  tcp4   *:9103                *:*
pgsql    postgres   20009 4  tcp4   127.0.0.1:5432        *:*
root     sshd       49253 4  tcp4   *:22                  *:*

Um noch zu prüfen, in welcher Reihenfolge gestartet wurde, befragen wir das rc(8) Subsystem:

 # rcorder /etc/rc.d/* /usr/local/etc/rc.d/* | grep -E '(bareos|php-fpm|nginx|postgresql)'
/usr/local/etc/rc.d/postgresql
/usr/local/etc/rc.d/php-fpm
/usr/local/etc/rc.d/nginx
/usr/local/etc/rc.d/bareos-sd
/usr/local/etc/rc.d/bareos-fd
/usr/local/etc/rc.d/bareos-dir

Über die URL http://bareos-server.getcom.de:9100 erreichen wir den Webservice:

Wir können uns nun mit dem admin Benutzer und ADMIN-PASSWORD Anmelden.

Nach dem Login sehen wir ein leeres Bareos Dashboard.

Jobs

Hier kommt nun eine Skript-Sammlung, um Clients zum Bareos Server hinzu zu fügen.

Der BRONZE-job.sh und BRONZE-sched.sh generiert Bareos files für neue Jobs und Sicherungszeiten. Wir legen das nach /root/bin

# mkdir /root/bin

Die Basisskripte sind hier zu finden:

Nach dem Download benennen wir sie um:

# mv BRONZE-sched.sh.key BRONZE-sched.sh
# mv BRONZE-job.sh.key   BRONZE-job.sh

Wir machen das ausführbar:

# chmod +x /root/bin/BRONZE-sched.sh
# chmod +x /root/bin/BRONZE-job.sh

Die Hilfe:

# /root/bin/BRONZE-sched.sh 
usage: BRONZE-sched.sh GROUP TIME

example:
  BRONZE-sched.sh 01 21:00
# /root/bin/BRONZE-job.sh
usage: BRONZE-job.sh GROUP TIME CLIENT TYPE

  GROUP option: 01 | 02 | 03
   TIME option: 00:00 - 23:59
 CLIENT option: FQDN
   TYPE option: UNIX | Windows

example:
  BRONZE-job.sh 01 21:00 CLIENT.domain.com UNIX

 

Clients

Mögliche Firewall-Probleme auf Clients

Auf einem 3CX Server verhindert per default die Firewall einen Zugriff auf den Port 9002 (bacula-fd). Der entsprechende Job schlägt daher fehl mit einem timeout auf den bacula-fd service des zu sichernden Clients.

Abhilfe:

Identifizierung der iptables Regel-IDs der zuständigen Regeln:

  • iptables -L INPUT --line-numbers | grep -e 5060 -e 5090 | grep tcp
    2 ACCEPT tcp -- anywhere anywhere multiport dports http,https,sip,sip-tls,5090 tcp flags:FIN,SYN,RST,ACK/SYN ctstate NEW
    13 ACCEPT tcp -- anywhere anywhere multiport dports http,https,5000,5001,5015,sip,sip-tls,5090 tcp flags:FIN,SYN,RST,ACK/SYN ctstate NEW

Identifizierung der vollständigen Regeln:

  • iptables -S INPUT | grep -e 5060 -e 5090 | grep tcp
    -A INPUT -p tcp -m multiport --dports 80,443,5060,5061,5090,9101,9102,9103 -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
    -A INPUT -p tcp -m multiport --dports 80,443,5000,5001,5015,5060,5061,5090,9101,9102,9103 -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT

Änderungen einspielen mit Angabe der obigen Regel-IDs:

  • /sbin/iptables -R INPUT 2 -p tcp -m multiport --dports 80,443,5060,5061,5090,9102 -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
    /sbin/iptables -R INPUT 13 -p tcp -m multiport --dports 80,443,5000,5001,5015,5060,5061,5090,9102 -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT

Permanente Speicherung der Regelketten:

  • service netfilter-persistent save

 

Verwendete Quellen für diesen Beitrag: