6,534
edits
Changes
created (mostly stolen from Ubuntu Hardy template creation)
[[Category: HOWTO]]
[[Category: Templates]]
[[Category: Ubuntu]]
This article summarizes the experience of creating Ubunty Hardy Heron (a.k.a. 8.04) template for OpenVZ.
Template creation is based on debootstrap, and the procedure is similar to [[Ubuntu Gutsy template creation]], but it differs in some subtle details.
== Prerequisites ==
=== debootstrap ===
You have to have a <code>debootstrap</code> working for Hardy, i.e. you should have
* <code>debootstrap</code> and its dependencies
* <code>/usr/lib/debootstrap/scripts/hardy</code> file
The simplest way to have it all is to work on an Ubuntu Hardy system (be it on a real machine or inside a container). If you don't have <code>debootstrap</code> installed, this is the command to install it:
# apt-get install debootstrap
On a Gentoo Linux, <code>debootstrap</code> is also available, this is how you can install it:
# emerge \>=debootstrap-1.0.0
Note you need at least version 1.0.0, since earlier versions do not have Ubuntu scripts. So, possible you will first need to add it to package.keywords, like this:
# echo dev-util/debootstrap >> /etc/portage.package.keywords
On a Fedora system (at least Fedora 8, not sure about earlier versions):
# yum install debootstrap
=== vzctl ===
You need vzctl-3.0.22 or later to work with Ubuntu Hardy Heron. If vzctl-3.0.18 or earlier is used, you will not be able to run your Ubuntu Hardy container. See {{bug|662}} for details.
Note: Older versions of vzctl are working if you install <code>sysvinit</code> (which will remove <code>upstart</code>). The only problem I had was the network did not start, so I added "/etc/init.d/networking restart" to /etc/re.local.
== Creating template ==
=== Running debootstrap ===
Create a working directory:
[HW]# mkdir hardy-chroot
Run debootstrap to install a minimal Ubunty Hardy system into that directory:
[HW]# debootstrap [--arch ''ARCH''] hardy hardy-chroot
If ARCH of CT0 is equal to container, you can skip the <code>--arch</code> option, but if you need to build an OS template for another ''ARCH'', specify it explicitly:
* for AMD64/x86_64, use <code>amd64</code>
* for IA64, use <code>ia64</code>
* for i386 <code>i386</code>
=== Preparing/starting a container ===
Now then you have an installation created by <code>debootstrap</code>, you can run it as a container. In the example below CT ID of 777 is used; of course you can use any other non-allocated ID.
{{Note|an alternative way is using <code>chroot</code> instead of running a container. This is not recommended because of security concerns.}}
==== Moving installation to container private area ====
You should move the contents of <code>hardy-chroot</code> directory into new container private area, like this:
# mv hardy-chroot /vz/private/777
==== Setting container config ====
An initial config for the [[container]] is needed:
# vzctl set 777 --applyconfig vps.basic --save
==== Setting container OSTEMPLATE ====
Also, we need <code>OSTEMPLATE</code> to be set in container configuration file, for the [[vzctl]] to work properly.
# echo "OSTEMPLATE=ubuntu-8.04" >> /etc/vz/conf/777.conf
==== Setting container IP address ====
For the [[container]] to be able to download updates from the Internet, we need a valid IP address for it:
# vzctl set 777 --ipadd x.x.x.x --save
{{Note|if you use private IP for the container, you have to set up NAT as described in [[Using NAT for container with private IPs]].}}
==== Setting DNS server for the container ====
For the [[container]] to be able to download updates from the Internet, we also need to specify a DNS for it:
# vzctl set 777 --nameserver x.x.x.x --save
Instead of <code>x.x.x.x</code>, specify the same IP that you have in your <code>/etc/resolv.conf</code>.
==== Starting container ====
Now start the container:
# vzctl start 777
=== Modify the installation ===
You have to do some things in order to modify the installation to better suit the environment it will be run in (i.e. a container).
First, enter a container:
# vzctl enter 777
{{Warning|Do not run the commands below on the hardware node, they are only to be run within the container!}}
==== Remove unneeded packages ====
Some packages does not make sense in a container, or are really optional. Remove those:
[container]# dpkg -P ubuntu-minimal wpasupplicant wireless-tools \
udev pcmciautils initramfs-tools console-setup \
xkb-data usbutils mii-diag ethtool \
module-init-tools console-tools \
console-terminus busybox-initramfs libvolume-id0 \
ntpdate eject pciutils tasksel tasksel-data \
laptop-detect
{{Note|On removing the deb-package "module-init-tools", a fake-modprobe is needed for IPv6 addresses, see below!}}
Note that the above list of packages may be too extensive. Say, if you want to use <code>tasksel</code> tool, do not remove it — but then you have to let laptop-detect stay.
Clean up after udev:
[container]# rm -fr /lib/udev
==== Disable getty ====
On a usual Linux system, <code>getty</code> is running on a virtual terminals, which a container does not have. So, having <code>getty</code> running doesn't make sense; more to say, it complains it can not open terminal device and this clutters the logs.
So, first of all we stop all the <code>getty</code> processes:
[container]# initctl stop tty{1,2,3,4,5,6}
Next, we disable running <code>getty</code>. This can be done in two ways:
First way:
[container]# rm /etc/event.d/tty*
Second way:
[container]# dpkg -P system-services
Second way can be dangerous for future versions of system-services, but it's OK for now since the only service they carry is running <code>getty</code>s.
==== Set sane permissions for /root directory ====
[container]# chmod 700 /root
==== Disable root login ====
[container]# usermod -L root
==== "fake-modprobe" needed for IPv6 addresses ====
[container]# ln -s /bin/true /sbin/modprobe
<small>On setup IPv6, the command "modprobe -Q IPv6" is called, which fails without the "fake-modprobe"</small>
==== Get new security updates ====
[container]# apt-get update && apt-get upgrade
<small>This didn't show anything for me, but might do something in the future.</small>
==== Install some more packages ====
[container]# apt-get install ssh quota
Feel free to add packages which you want to have in a default template to this command.
==== Fix SSH host keys ====
This is only useful if you installed SSH above. Each individual [[container]] should have its own pair of SSH host keys. The code below will wipe out the existing SSH keys and instruct the newly-created [[container]] to create new SSH keys on first boot.
<!-- please DO NOT remove <pre>...</pre> pair of tags below,
otherwise quotes after -N (-N '') are not visible -->
<pre>
rm -f /etc/ssh/ssh_host_*
cat << EOF > /etc/rc2.d/S15ssh_gen_host_keys
#!/bin/sh
ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -N ''
ssh-keygen -f /etc/ssh/ssh_host_dsa_key -t dsa -N ''
rm -f \$0
EOF
chmod a+x /etc/rc2.d/S15ssh_gen_host_keys
</pre>
==== Disable <code>sync()</code> for syslog ====
Turn off doing <tt>sync()</tt> on every write for <code>syslog</code>'s log files, to improve overall I/O performance.
In Ubuntu this is already done for most log files and levels, so you can omit this step if you know what you are doing.
<!-- DO NOT remove <pre> here, it's useful -->
<pre>[container]# sed -i -e 's@\([[:space:]]\)\(/var/log/\)@\1-\2@' /etc/syslog.conf</pre>
==== Fix <code>/etc/mtab</code> ====
Link <code>/etc/mtab</code> to <code>/proc/mounts</code>, so <code>df</code> and friends will work:
[container]# rm -f /etc/mtab
[container]# ln -s /proc/mounts /etc/mtab
After that, it would make sense to disable <code>mtab.sh</code> script which messes with <code>/etc/mtab</code>:
[container]# update-rc.d -f mtab.sh remove
==== Disable some services ====
In most of the cases you don't want klogd to run -- the only exception is if you configure iptables to log some events -- so you can disable it:
[container]# update-rc.d -f klogd remove
==== Hostname ====
Set proper hostname:
[container]# echo "localhost" > /etc/hostname
==== Set /etc/hosts ====
[container]# echo "127.0.0.1 localhost.localdomain localhost" > /etc/hosts
==== Add ptys to /dev ====
This is needed in case /dev/pts will not me mounted after container start. In case /dev/ttyp* and /dev/ptyp* files are present, and LEGACY_PTYS support is enabled in the kernel, vzctl will still be able to enter container.
[container]# cd /dev && /sbin/MAKEDEV ptyp
<small>'''Note:''' the warning "/sbin/MAKEDEV: warning: can't read /proc/devices" is safe to ignore.</small>
==== Remove nameserver(s) ====
Remove DNS entries:
[container]# > /etc/resolv.conf
==== Clean packages ====
After installing packages, you'll have some junk packages laying around in your cache. Since you don't want your template to have those, this command will wipe them out.
[container]# apt-get clean
==== Cleaning up log files ====
[container]# cd /var/log
[container]# > messages; > auth.log; > kern.log; > bootstrap.log
[container]# > dpkg.log; > syslog; > daemon.log; > apt/term.log
[container]# rm -f *.0 *.1
==== Anything else? ====
Think of what else could be done to better suit your needs.
==== Exit from the container ====
Now everything is done. Exit from the template and go back to the hardware node.
[container]# exit
== Preparing for and packing template cache ==
The following commands are to be run in the host system (i.e. not inside a container).
We don't need an IP for the container anymore, and we definitely do not need it in template cache, so remove it:
[HW]# vzctl set 777 --ipdel all --save
Stop the container:
[HW]# vzctl stop 777
Change dir to the container private:
[HW]# cd /vz/private/777
Now create a cached OS tarball. In the command below, you'll want to replace <arch> with your architecture (i386, amd64, ia64, etc). '''Note the space and the dot at the end of the command'''.
[HW]# tar czf /vz/template/cache/ubuntu-8.04-<arch>-minimal.tar.gz .
Look at the resulting tarball to see its size is sane (i.e. tens of megabytes):
# ls -lh /vz/template/cache/ubuntu-8*
-rw-r--r-- 1 root root 46M May 13 12:20 /vz/template/cache/ubuntu-8.04-i386-minimal.tar.gz
== Testing template cache ==
We can now create a container based on the just-created template cache. Be sure to change <tt>i386</tt> to your architecture just like you did when you named the tarball above.
[HW]# vzctl create 123456 --ostemplate ubuntu-8.04-<arch>-minimal
Now make sure that your new container it works:
[HW]# vzctl start 123456
[HW]# vzctl exec 123456 ps axf
You should see that a few processes are running.
Other tests that could be done are:
[HW]# vzctl enter 123456
[container]# ps axf
[container]# mount
[container]# dpkg -l
[container]# logout
[HW]#
Feel free to do more tests.
== Final cleanup ==
Stop and remove the test container you just created:
[HW]# vzctl stop 123456
[HW]# vzctl destroy 123456
[HW]# rm -f /etc/vz/conf/123456.conf.destroyed
Finally, let's remove the container we used for OS template cache creation:
[HW]# vzctl destroy 777
[HW]# rm -f /etc/vz/conf/777.conf.destroyed
== Updating the template cache ==
See [[Updating Ubuntu template]]
[[Category: Templates]]
[[Category: Ubuntu]]
This article summarizes the experience of creating Ubunty Hardy Heron (a.k.a. 8.04) template for OpenVZ.
Template creation is based on debootstrap, and the procedure is similar to [[Ubuntu Gutsy template creation]], but it differs in some subtle details.
== Prerequisites ==
=== debootstrap ===
You have to have a <code>debootstrap</code> working for Hardy, i.e. you should have
* <code>debootstrap</code> and its dependencies
* <code>/usr/lib/debootstrap/scripts/hardy</code> file
The simplest way to have it all is to work on an Ubuntu Hardy system (be it on a real machine or inside a container). If you don't have <code>debootstrap</code> installed, this is the command to install it:
# apt-get install debootstrap
On a Gentoo Linux, <code>debootstrap</code> is also available, this is how you can install it:
# emerge \>=debootstrap-1.0.0
Note you need at least version 1.0.0, since earlier versions do not have Ubuntu scripts. So, possible you will first need to add it to package.keywords, like this:
# echo dev-util/debootstrap >> /etc/portage.package.keywords
On a Fedora system (at least Fedora 8, not sure about earlier versions):
# yum install debootstrap
=== vzctl ===
You need vzctl-3.0.22 or later to work with Ubuntu Hardy Heron. If vzctl-3.0.18 or earlier is used, you will not be able to run your Ubuntu Hardy container. See {{bug|662}} for details.
Note: Older versions of vzctl are working if you install <code>sysvinit</code> (which will remove <code>upstart</code>). The only problem I had was the network did not start, so I added "/etc/init.d/networking restart" to /etc/re.local.
== Creating template ==
=== Running debootstrap ===
Create a working directory:
[HW]# mkdir hardy-chroot
Run debootstrap to install a minimal Ubunty Hardy system into that directory:
[HW]# debootstrap [--arch ''ARCH''] hardy hardy-chroot
If ARCH of CT0 is equal to container, you can skip the <code>--arch</code> option, but if you need to build an OS template for another ''ARCH'', specify it explicitly:
* for AMD64/x86_64, use <code>amd64</code>
* for IA64, use <code>ia64</code>
* for i386 <code>i386</code>
=== Preparing/starting a container ===
Now then you have an installation created by <code>debootstrap</code>, you can run it as a container. In the example below CT ID of 777 is used; of course you can use any other non-allocated ID.
{{Note|an alternative way is using <code>chroot</code> instead of running a container. This is not recommended because of security concerns.}}
==== Moving installation to container private area ====
You should move the contents of <code>hardy-chroot</code> directory into new container private area, like this:
# mv hardy-chroot /vz/private/777
==== Setting container config ====
An initial config for the [[container]] is needed:
# vzctl set 777 --applyconfig vps.basic --save
==== Setting container OSTEMPLATE ====
Also, we need <code>OSTEMPLATE</code> to be set in container configuration file, for the [[vzctl]] to work properly.
# echo "OSTEMPLATE=ubuntu-8.04" >> /etc/vz/conf/777.conf
==== Setting container IP address ====
For the [[container]] to be able to download updates from the Internet, we need a valid IP address for it:
# vzctl set 777 --ipadd x.x.x.x --save
{{Note|if you use private IP for the container, you have to set up NAT as described in [[Using NAT for container with private IPs]].}}
==== Setting DNS server for the container ====
For the [[container]] to be able to download updates from the Internet, we also need to specify a DNS for it:
# vzctl set 777 --nameserver x.x.x.x --save
Instead of <code>x.x.x.x</code>, specify the same IP that you have in your <code>/etc/resolv.conf</code>.
==== Starting container ====
Now start the container:
# vzctl start 777
=== Modify the installation ===
You have to do some things in order to modify the installation to better suit the environment it will be run in (i.e. a container).
First, enter a container:
# vzctl enter 777
{{Warning|Do not run the commands below on the hardware node, they are only to be run within the container!}}
==== Remove unneeded packages ====
Some packages does not make sense in a container, or are really optional. Remove those:
[container]# dpkg -P ubuntu-minimal wpasupplicant wireless-tools \
udev pcmciautils initramfs-tools console-setup \
xkb-data usbutils mii-diag ethtool \
module-init-tools console-tools \
console-terminus busybox-initramfs libvolume-id0 \
ntpdate eject pciutils tasksel tasksel-data \
laptop-detect
{{Note|On removing the deb-package "module-init-tools", a fake-modprobe is needed for IPv6 addresses, see below!}}
Note that the above list of packages may be too extensive. Say, if you want to use <code>tasksel</code> tool, do not remove it — but then you have to let laptop-detect stay.
Clean up after udev:
[container]# rm -fr /lib/udev
==== Disable getty ====
On a usual Linux system, <code>getty</code> is running on a virtual terminals, which a container does not have. So, having <code>getty</code> running doesn't make sense; more to say, it complains it can not open terminal device and this clutters the logs.
So, first of all we stop all the <code>getty</code> processes:
[container]# initctl stop tty{1,2,3,4,5,6}
Next, we disable running <code>getty</code>. This can be done in two ways:
First way:
[container]# rm /etc/event.d/tty*
Second way:
[container]# dpkg -P system-services
Second way can be dangerous for future versions of system-services, but it's OK for now since the only service they carry is running <code>getty</code>s.
==== Set sane permissions for /root directory ====
[container]# chmod 700 /root
==== Disable root login ====
[container]# usermod -L root
==== "fake-modprobe" needed for IPv6 addresses ====
[container]# ln -s /bin/true /sbin/modprobe
<small>On setup IPv6, the command "modprobe -Q IPv6" is called, which fails without the "fake-modprobe"</small>
==== Get new security updates ====
[container]# apt-get update && apt-get upgrade
<small>This didn't show anything for me, but might do something in the future.</small>
==== Install some more packages ====
[container]# apt-get install ssh quota
Feel free to add packages which you want to have in a default template to this command.
==== Fix SSH host keys ====
This is only useful if you installed SSH above. Each individual [[container]] should have its own pair of SSH host keys. The code below will wipe out the existing SSH keys and instruct the newly-created [[container]] to create new SSH keys on first boot.
<!-- please DO NOT remove <pre>...</pre> pair of tags below,
otherwise quotes after -N (-N '') are not visible -->
<pre>
rm -f /etc/ssh/ssh_host_*
cat << EOF > /etc/rc2.d/S15ssh_gen_host_keys
#!/bin/sh
ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -N ''
ssh-keygen -f /etc/ssh/ssh_host_dsa_key -t dsa -N ''
rm -f \$0
EOF
chmod a+x /etc/rc2.d/S15ssh_gen_host_keys
</pre>
==== Disable <code>sync()</code> for syslog ====
Turn off doing <tt>sync()</tt> on every write for <code>syslog</code>'s log files, to improve overall I/O performance.
In Ubuntu this is already done for most log files and levels, so you can omit this step if you know what you are doing.
<!-- DO NOT remove <pre> here, it's useful -->
<pre>[container]# sed -i -e 's@\([[:space:]]\)\(/var/log/\)@\1-\2@' /etc/syslog.conf</pre>
==== Fix <code>/etc/mtab</code> ====
Link <code>/etc/mtab</code> to <code>/proc/mounts</code>, so <code>df</code> and friends will work:
[container]# rm -f /etc/mtab
[container]# ln -s /proc/mounts /etc/mtab
After that, it would make sense to disable <code>mtab.sh</code> script which messes with <code>/etc/mtab</code>:
[container]# update-rc.d -f mtab.sh remove
==== Disable some services ====
In most of the cases you don't want klogd to run -- the only exception is if you configure iptables to log some events -- so you can disable it:
[container]# update-rc.d -f klogd remove
==== Hostname ====
Set proper hostname:
[container]# echo "localhost" > /etc/hostname
==== Set /etc/hosts ====
[container]# echo "127.0.0.1 localhost.localdomain localhost" > /etc/hosts
==== Add ptys to /dev ====
This is needed in case /dev/pts will not me mounted after container start. In case /dev/ttyp* and /dev/ptyp* files are present, and LEGACY_PTYS support is enabled in the kernel, vzctl will still be able to enter container.
[container]# cd /dev && /sbin/MAKEDEV ptyp
<small>'''Note:''' the warning "/sbin/MAKEDEV: warning: can't read /proc/devices" is safe to ignore.</small>
==== Remove nameserver(s) ====
Remove DNS entries:
[container]# > /etc/resolv.conf
==== Clean packages ====
After installing packages, you'll have some junk packages laying around in your cache. Since you don't want your template to have those, this command will wipe them out.
[container]# apt-get clean
==== Cleaning up log files ====
[container]# cd /var/log
[container]# > messages; > auth.log; > kern.log; > bootstrap.log
[container]# > dpkg.log; > syslog; > daemon.log; > apt/term.log
[container]# rm -f *.0 *.1
==== Anything else? ====
Think of what else could be done to better suit your needs.
==== Exit from the container ====
Now everything is done. Exit from the template and go back to the hardware node.
[container]# exit
== Preparing for and packing template cache ==
The following commands are to be run in the host system (i.e. not inside a container).
We don't need an IP for the container anymore, and we definitely do not need it in template cache, so remove it:
[HW]# vzctl set 777 --ipdel all --save
Stop the container:
[HW]# vzctl stop 777
Change dir to the container private:
[HW]# cd /vz/private/777
Now create a cached OS tarball. In the command below, you'll want to replace <arch> with your architecture (i386, amd64, ia64, etc). '''Note the space and the dot at the end of the command'''.
[HW]# tar czf /vz/template/cache/ubuntu-8.04-<arch>-minimal.tar.gz .
Look at the resulting tarball to see its size is sane (i.e. tens of megabytes):
# ls -lh /vz/template/cache/ubuntu-8*
-rw-r--r-- 1 root root 46M May 13 12:20 /vz/template/cache/ubuntu-8.04-i386-minimal.tar.gz
== Testing template cache ==
We can now create a container based on the just-created template cache. Be sure to change <tt>i386</tt> to your architecture just like you did when you named the tarball above.
[HW]# vzctl create 123456 --ostemplate ubuntu-8.04-<arch>-minimal
Now make sure that your new container it works:
[HW]# vzctl start 123456
[HW]# vzctl exec 123456 ps axf
You should see that a few processes are running.
Other tests that could be done are:
[HW]# vzctl enter 123456
[container]# ps axf
[container]# mount
[container]# dpkg -l
[container]# logout
[HW]#
Feel free to do more tests.
== Final cleanup ==
Stop and remove the test container you just created:
[HW]# vzctl stop 123456
[HW]# vzctl destroy 123456
[HW]# rm -f /etc/vz/conf/123456.conf.destroyed
Finally, let's remove the container we used for OS template cache creation:
[HW]# vzctl destroy 777
[HW]# rm -f /etc/vz/conf/777.conf.destroyed
== Updating the template cache ==
See [[Updating Ubuntu template]]