Difference between revisions of "Arch VServer"
Delerious010 (talk | contribs) |
Delerious010 (talk | contribs) |
||
Line 107: | Line 107: | ||
fi | fi | ||
− | ====/etc/rc. | + | ====/etc/rc.sysinit==== |
#!/bin/bash | #!/bin/bash | ||
# | # | ||
Line 205: | Line 205: | ||
# Flush old locale settings | # Flush old locale settings | ||
: >/etc/profile.d/locale.sh | : >/etc/profile.d/locale.sh | ||
− | /bin/chmod 755 /etc/profile.d/locale.sh | + | /bin/chmod 755 /etc/profile.d/locale.sh |
# Set user defined locale | # Set user defined locale | ||
[ -z "$LOCALE" ] && LOCALE="en_US" | [ -z "$LOCALE" ] && LOCALE="en_US" | ||
stat_busy "Setting Locale: $LOCALE" | stat_busy "Setting Locale: $LOCALE" | ||
echo "export LANG=$LOCALE" >>/etc/profile.d/locale.sh | echo "export LANG=$LOCALE" >>/etc/profile.d/locale.sh | ||
− | stat_done | + | stat_done |
− | # Adding persistent network/cdrom generated rules | + | # Adding persistent network/cdrom generated rules |
− | if [ -f "/dev/.udev/tmp-rules--70-persistent-cd.rules" ]; then | + | if [ -f "/dev/.udev/tmp-rules--70-persistent-cd.rules" ]; then |
− | + | stat_busy "Adding persistent cdrom udev rules" | |
− | + | /bin/cat /dev/.udev/tmp-rules--70-persistent-cd.rules >> /etc/udev/rules.d/70-persistent-cd.rules | |
− | + | stat_done | |
− | fi | + | fi |
− | if [ -f "/dev/.udev/tmp-rules--70-persistent-net.rules" ]; then | + | if [ -f "/dev/.udev/tmp-rules--70-persistent-net.rules" ]; then |
− | + | stat_busy "Adding persistent network udev rules" | |
− | + | /bin/cat /dev/.udev/tmp-rules--70-persistent-net.rules >> /etc/udev/rules.d /70-persistent-net.rules | |
− | + | stat_done | |
− | fi | + | fi |
− | + | ||
− | /bin/dmesg >| /var/log/dmesg.log | + | /bin/dmesg >| /var/log/dmesg.log |
− | + | ||
− | # End of file | + | # End of file |
− | # vim: set ts=2 noet: | + | # vim: set ts=2 noet: |
====/etc/rc.shutdown==== | ====/etc/rc.shutdown==== | ||
− | #!/bin/bash | + | #!/bin/bash |
− | # | + | # |
− | # /etc/rc.shutdown | + | # /etc/rc.shutdown |
− | # | + | # |
+ | |||
+ | . /etc/rc.conf | ||
+ | . /etc/rc.d/functions | ||
+ | |||
+ | # avoid staircase effect | ||
+ | /bin/stty onlcr | ||
+ | |||
+ | echo " " | ||
+ | printhl "Initiating Shutdown..." | ||
+ | echo " " | ||
+ | |||
+ | # avoid NIS hanging syslog-ng on shutdown by unsetting the domainname | ||
+ | if [ -x /bin/domainname ]; then | ||
+ | /bin/domainname "" | ||
+ | fi | ||
+ | |||
+ | if [ -x /etc/rc.local.shutdown ]; then | ||
+ | /etc/rc.local.shutdown | ||
+ | fi | ||
+ | |||
+ | if [ "$PREVLEVEL" = "3" -o "$PREVLEVEL" = "5" ]; then | ||
+ | # Find daemons NOT in the DAEMONS array. Shut these down first | ||
+ | if [ -d /var/run/daemons ]; then | ||
+ | for daemon in $(/bin/ls -1t /var/run/daemons); do | ||
+ | if ! in_array $daemon ${DAEMONS[@]}; then | ||
+ | stop_daemon $daemon | ||
+ | fi | ||
+ | done | ||
+ | fi | ||
+ | # Shutdown daemons in reverse order | ||
+ | let i=${#DAEMONS[@]}-1 | ||
+ | while [ $i -ge 0 ]; do | ||
+ | if [ "${DAEMONS[$i]:0:1}" != '!' ]; then | ||
+ | ck_daemon ${DAEMONS[$i]#@} || stop_daemon ${DAEMONS[$i]#@} | ||
+ | fi | ||
+ | let i=i-1 | ||
+ | done | ||
+ | fi | ||
+ | |||
+ | # Terminate all processes | ||
+ | stat_busy "Sending SIGTERM To Processes" | ||
+ | /sbin/killall5 -15 &> /dev/null | ||
+ | /bin/sleep 5 | ||
+ | stat_done | ||
− | + | stat_busy "Sending SIGKILL To Processes" | |
− | + | /sbin/killall5 -9 &> /dev/null | |
+ | /bin/sleep 1 | ||
+ | stat_done | ||
− | # | + | # Write to wtmp file before unmounting |
− | / | + | /sbin/halt -w |
− | + | # Power off or reboot | |
− | printhl " | + | if [ "$RUNLEVEL" = "0" ]; then |
− | + | printsep | |
+ | printhl "${C_H2}POWER OFF" | ||
+ | /sbin/poweroff -d -f -h -i | ||
+ | else | ||
+ | printsep | ||
+ | printhl "${C_H2}REBOOTING" | ||
+ | # if kexec is installed and a kernel is loaded, use it | ||
+ | [ -x /sbin/kexec ] && /sbin/kexec -e > /dev/null 2>&1 | ||
+ | /sbin/reboot -d -f -i | ||
+ | fi | ||
+ | |||
+ | # End of file | ||
+ | # vim: set ts=2 sw=2 noet: | ||
− | + | =Troubleshooting= | |
− | + | ==Viewing output from vserver $GuestName start / stop== | |
− | |||
− | |||
− | + | '''NOTE : ''' For me, this only worked in the actual consoles, not in X. | |
− | |||
− | |||
− | + | # Make sure that the device /dev/console exists in the guest | |
− | + | ## If it does not, cp -a /dev/console $GuestRoot/dev/ | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | ==SSH will not start== | |
− | + | I noticed that /dev/null did not always get created properly in my first experimentations. Therefore I did a quick : | |
− | / | + | # cp -a /dev/null $GuestRoot/dev |
− | / | + | # cp -a /dev/zero $GuestRoot/dev |
− | |||
− | + | Furthermore, if you're not using the dummy network driver and are attaching to the host's network interface, you'll want to configure the ListenAddress statement of /etc/ssh/sshd_config so that it binds only to the guest's IP address as opposed to 127.0.0.1. | |
− | / | ||
− | |||
− | |||
− | |||
− | |||
− | + | =Tips & Trick= | |
− | + | ==Network via dummy adapters== | |
− | + | Here, you're either using the dummy module to create virtual network adapters or created interface aliases via /usr/sbin/ip or /usr/sbin/ifconfig. I went for the former and configured the host as such : | |
− | + | # ''/etc/sysctl.conf'' : net.ipv4.ip_forward=1<br> | |
− | + | Modify or add that statement to enable routing on the host | |
− | + | # ''/etc/rc.local''<br> | |
− | + | modprobe dummy numdummies=$NumberOfGuests<br> | |
− | + | ip link set dev dummy$GuestContext name $GuestName | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | # | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | This provides me with dummy interfaces that I can route / firewall that are all named the same as my guests... yay. | |
=More Resources= | =More Resources= | ||
− | [http://linux-vserver.org/Problematic_Programs Problematic Programs] | + | [http://linux-vserver.org/Problematic_Programs Problematic Programs]<br> |
− | [http://linux-vserver.org/Howto_make_bsd-style_init_sysv-compatible Make BSD style init SYSV compatible] | + | [http://linux-vserver.org/Howto_make_bsd-style_init_sysv-compatible Make BSD style init SYSV compatible]<br> |
− | [http://www.cedarcreeksoftware.com/an-even-easier-linux-vserver-tutorial.html Vserver tutorial] | + | [http://www.cedarcreeksoftware.com/an-even-easier-linux-vserver-tutorial.html Vserver tutorial]<br> |
− | [http://linux-vserver.org/Installation_on_ArchLinux linux-vserver.org's Installation on ArchLinux] | + | [http://linux-vserver.org/Installation_on_ArchLinux linux-vserver.org's Installation on ArchLinux]<br> |
− | [http://wiki.linux-vserver.org/Networking_vserver_guests linux-verserver.org's networking tutorial] | + | [http://wiki.linux-vserver.org/Networking_vserver_guests linux-verserver.org's networking tutorial]<br> |
<!-- vim: set ft=Wikipedia: --> | <!-- vim: set ft=Wikipedia: --> |
Revision as of 23:35, 19 November 2009
Contents
- 1 Introduction
- 2 Preparing the Host
- 3 Paths of Interest
- 4 Preparing the Guests
- 4.1 Preparing the guest installation media
- 5 Troubleshooting
- 6 Tips & Trick
- 7 More Resources
Introduction
This article aims to provide all necessary information regarding the creation of a vserver host as well as vserver guests running ArchLinux. Tis will enable you to setup virtual servers that provide different services as if they were on different machines, with a very little overhead. You can get more information about virtual servers here.
[disclaimer] I've just started playing around with vserver and am finding the documentation regarding this project lacking. As such, the way I'm doing this below may not be optimal.[/disclaimer]
Preparing the Host
To prepare the vserver host environment, you will need to install both a vserver patched kernel and the vserver utilities which are located in AUR. In the following steps, the instructions are provided using yaourt to fetch them automatically. This has the aded benefit of pulling down the required dependencies ( dietlibc and beecrypt ) automagically :
- yaourt -S kernel26-vserver util-vserver
Paths of Interest
/etc/vservers : configuration root ( reference )
- /etc/vservers/.defaults : configuration skeleton used when building new guests
- /etc/vservers/.defaults/vdirbase : symlink to the folder containing vserver guests. This defaults to /vservers.
- /etc/vservers/<guest name> : guest specific configurations
Preparing the Guests
Vserver will launch guests from subfolders of /etc/vservers/.defaults/vdirbase. As such, creating a new guest system is as simple as installing the required packages in a folder of the host. Furthermore, there's nothing stopping you ( and quite a few things encouraging you ) to mount filesystems to the subfolders of vdirbase and installing your guest in there.
If you plan on doing this often, I highly recommend that you write yourself a little batch script since most of these steps can be automated quite easily.
'NOTE' : Next step is going to be writing scripts in /usr/lib/util-vservers to integrate pacman into the mix to automagically get everything built up and installed.
Preparing the guest installation media
'NOTE' : This is all heavily inspired from wiki:Install From Existing Linux and will therefore be quite brief when not mentioning Vserver specific steps.
Optional: Base variables to follow along with the steps
GuestName= # Name of the guest GuestRoot=/etc/vservers/.defaults/vdirbase/$GuestName GuestPackages= # Listing of packages to install via pacman GuestDisk= # Installation target device GuestNetDevice= # ex.: eth0, dummy0, etc... GuestIP= # I think you get it GuestContext= # Unique identifier for the guest, I go with the last part of the IP
Optional: Preparing the guest disk
- Create a LVM Physical Volume, a Volume Group and a Logical Volume ( wiki:LVM )
- Create a filesystem on the lvm volume
- mkdir $GuestRoot
- mount /dev/$GuestDisk $GuestRoot
Optional: Link the host and guest pacman cache
- mkdir $GuestRoot/var/cache/pacman/pkg
- mount -o bind /var/cache/pacman/pkg $GuestRoot/var/cache/pacman/pkg
Prepare Vserver
- vserver $GuestName -m skeleton --context $GuestContext --interface $GuestNetDevice:$GuestIP --flags lock,virt_mem,virt_uptime,virt_cpu,virt_load,sched_hard,hide_netif --initstyle plain
- (optional) cd /etc/vservers/$GuestName/interfaces
- (optional) cp -r 0 1
- (optional) echo 'lo' > dev
- (optional) echo '127.0.0.$GuestContext' > ip
Prepare the guest's filesystem
- Prepare guest filesystem for the pacman db
- mkdir -p /newarch/var/lib/pacman
Install the base system
NOTE : To save some time, it's probably a good idea to create a text file containing all the packages to install and call it via "pacman -Sy `cat $GuestPackages` -r $GuestRoot" instead of the following :
- pacman -Sy base -r $GuestRoot
- Optional: If you want to chroot into the newly created guest so as to install new packages, it might be a good idea to mount a few filesystems required by some packages.
- Bind /dev, /proc, /sys to the corresponding directories in $GuestRoot
- Modify guest configuration files to enable a smoother boot process
- Modify /etc/inittab by deleting all lines that create the consoles ( agetty )
- Modify /etc/rc.shutdown by removing anything hardware/clock/mount related. This
includes most everything under Saving Random Seed'.
- Modify /etc/rc.sysinit by anything hardware/clock/mount related.
- Create /etc/init.d/rc
- Modify /etc/syslog-ng.conf by removing file("/proc/kmsg")
- Modify /etc/rc.conf by removing the networks Daemon.
Annexe : Configuration files modified
/etc/init.d/rc
if [ $1 -eq 3 ]; then echo "entering runlevel 3:multi"; /etc/rc.multi fi if [ $1 -eq 6 ]; then echo "entering runlevel 6:reboot"; /etc/rc.shutdown fi if [ $1 -eq 0 ]; then echo "entering runlevel 0: shutdown"; /etc/rc.shutdown fi if [ $1 -eq 4 ]; then echo "entering runlevel 4"; fi if [ $1 -eq 5 ]; then echo "entering runlevel 5"; fi if [ $1 -eq 1 ]; then echo "entering runlevel 1:single"; /etc/rc.single fi if [ $1 -eq 2 ]; then echo "entering runlevel 2:multi"; /etc/rc.multi fi
/etc/rc.sysinit
#!/bin/bash # # /etc/rc.sysinit # . /etc/rc.conf . /etc/rc.d/functions echo " " printhl "Arch Linux\n" printhl "${C_H2}http://www.archlinux.org" printhl "Copyright 2002-2007 Judd Vinet" printhl "Copyright 2007-2009 Aaron Griffin" printhl "Distributed under the GNU General Public License (GPL)" printsep # start up our mini logger until syslog takes over /sbin/minilogd if [ -x /sbin/udevadm ]; then stat_busy "Starting UDev Daemon" /sbin/udevd --daemon stat_done else # Static /dev, our last resort status "Using static /dev filesystem" true fi # Trigger udev uevents if /bin/pidof -o %PPID /sbin/udevd >/dev/null; then stat_busy "Triggering UDev uevents" /sbin/udevadm trigger stat_done fi NETFS="nonfs,nonfs4,nosmbfs,nocifs,nocodafs,noncpfs,nosysfs,noshfs,nofuse,nofuseblk,noglusterfs" stat_busy "Mounting Local Filesystems" /bin/rm -f /etc/mtab* # Write /proc, /sys and /dev to /etc/mtab if [ -e /proc/mounts ]; then /bin/grep -e "rootfs" -e "/proc " -e "/sys " -e "/dev " /proc/mounts >> /etc/mtab fi stat_done stat_busy "Configuring System Clock" if [ ! -f /var/lib/hwclock/adjtime ]; then echo "0.0 0 0.0" > /var/lib/hwclock/adjtime fi if [ "$TIMEZONE" != "" -a -e "/usr/share/zoneinfo/$TIMEZONE" ]; then /bin/rm -f /etc/localtime /bin/cp "/usr/share/zoneinfo/$TIMEZONE" /etc/localtime fi if [ -n "$HWCLOCK_PARAMS" ]; then /sbin/hwclock --adjust #Adjust for system drift /sbin/hwclock $HWCLOCK_PARAMS fi stat_done RANDOM_SEED=/var/lib/misc/random-seed if [ -f $RANDOM_SEED ]; then stat_busy "Initializing Random Seed" /bin/cat $RANDOM_SEED > /dev/urandom stat_done fi stat_busy "Removing Leftover Files" /bin/rm -f /etc/nologin &>/dev/null /bin/rm -f /etc/shutdownpid &>/dev/null /bin/rm -f /var/lock/* &>/dev/null /bin/rm -rf /tmp/* /tmp/.* &>/dev/null /bin/rm -f /forcefsck &>/dev/null (cd /var/run && /usr/bin/find . ! -type d -exec /bin/rm -f -- {} \; ) : > /var/run/utmp /bin/chmod 0664 /var/run/utmp # Keep {x,k,g}dm happy with xorg /bin/mkdir /tmp/.ICE-unix && /bin/chmod 1777 /tmp/.ICE-unix /bin/mkdir /tmp/.X11-unix && /bin/chmod 1777 /tmp/.X11-unix stat_done #status "Updating Shared Library Links" /sbin/ldconfig if [ "$HOSTNAME" != "" ]; then status "Setting Hostname: $HOSTNAME" /bin/hostname $HOSTNAME fi # Set the NIS domain name, if necessary [ -f /etc/conf.d/nisdomainname ] && . /etc/conf.d/nisdomainname if [ "$NISDOMAINNAME" != "" ]; then status "Setting NIS Domain Name: $NISDOMAINNAME" /bin/nisdomainname $NISDOMAINNAME fi status "Updating Module Dependencies" /sbin/depmod -A # Flush old locale settings : >/etc/profile.d/locale.sh /bin/chmod 755 /etc/profile.d/locale.sh # Set user defined locale [ -z "$LOCALE" ] && LOCALE="en_US" stat_busy "Setting Locale: $LOCALE" echo "export LANG=$LOCALE" >>/etc/profile.d/locale.sh stat_done
# Adding persistent network/cdrom generated rules if [ -f "/dev/.udev/tmp-rules--70-persistent-cd.rules" ]; then stat_busy "Adding persistent cdrom udev rules" /bin/cat /dev/.udev/tmp-rules--70-persistent-cd.rules >> /etc/udev/rules.d/70-persistent-cd.rules stat_done fi if [ -f "/dev/.udev/tmp-rules--70-persistent-net.rules" ]; then stat_busy "Adding persistent network udev rules" /bin/cat /dev/.udev/tmp-rules--70-persistent-net.rules >> /etc/udev/rules.d /70-persistent-net.rules stat_done fi /bin/dmesg >| /var/log/dmesg.log # End of file # vim: set ts=2 noet:
/etc/rc.shutdown
#!/bin/bash # # /etc/rc.shutdown # . /etc/rc.conf . /etc/rc.d/functions # avoid staircase effect /bin/stty onlcr echo " " printhl "Initiating Shutdown..." echo " " # avoid NIS hanging syslog-ng on shutdown by unsetting the domainname if [ -x /bin/domainname ]; then /bin/domainname "" fi if [ -x /etc/rc.local.shutdown ]; then /etc/rc.local.shutdown fi if [ "$PREVLEVEL" = "3" -o "$PREVLEVEL" = "5" ]; then # Find daemons NOT in the DAEMONS array. Shut these down first if [ -d /var/run/daemons ]; then for daemon in $(/bin/ls -1t /var/run/daemons); do if ! in_array $daemon ${DAEMONS[@]}; then stop_daemon $daemon fi done fi # Shutdown daemons in reverse order let i=${#DAEMONS[@]}-1 while [ $i -ge 0 ]; do if [ "${DAEMONS[$i]:0:1}" != '!' ]; then ck_daemon ${DAEMONS[$i]#@} || stop_daemon ${DAEMONS[$i]#@} fi let i=i-1 done fi # Terminate all processes stat_busy "Sending SIGTERM To Processes" /sbin/killall5 -15 &> /dev/null /bin/sleep 5 stat_done
stat_busy "Sending SIGKILL To Processes" /sbin/killall5 -9 &> /dev/null /bin/sleep 1 stat_done
# Write to wtmp file before unmounting /sbin/halt -w
# Power off or reboot if [ "$RUNLEVEL" = "0" ]; then printsep printhl "${C_H2}POWER OFF" /sbin/poweroff -d -f -h -i else printsep printhl "${C_H2}REBOOTING" # if kexec is installed and a kernel is loaded, use it [ -x /sbin/kexec ] && /sbin/kexec -e > /dev/null 2>&1 /sbin/reboot -d -f -i fi # End of file # vim: set ts=2 sw=2 noet:
Troubleshooting
Viewing output from vserver $GuestName start / stop
NOTE : For me, this only worked in the actual consoles, not in X.
- Make sure that the device /dev/console exists in the guest
- If it does not, cp -a /dev/console $GuestRoot/dev/
SSH will not start
I noticed that /dev/null did not always get created properly in my first experimentations. Therefore I did a quick :
- cp -a /dev/null $GuestRoot/dev
- cp -a /dev/zero $GuestRoot/dev
Furthermore, if you're not using the dummy network driver and are attaching to the host's network interface, you'll want to configure the ListenAddress statement of /etc/ssh/sshd_config so that it binds only to the guest's IP address as opposed to 127.0.0.1.
Tips & Trick
Network via dummy adapters
Here, you're either using the dummy module to create virtual network adapters or created interface aliases via /usr/sbin/ip or /usr/sbin/ifconfig. I went for the former and configured the host as such :
- /etc/sysctl.conf : net.ipv4.ip_forward=1
Modify or add that statement to enable routing on the host
- /etc/rc.local
modprobe dummy numdummies=$NumberOfGuests
ip link set dev dummy$GuestContext name $GuestName
This provides me with dummy interfaces that I can route / firewall that are all named the same as my guests... yay.
More Resources
Problematic Programs
Make BSD style init SYSV compatible
Vserver tutorial
linux-vserver.org's Installation on ArchLinux
linux-verserver.org's networking tutorial