Support #683
Updated by Daniel Curtis about 10 years ago
{{>toc}}
This is a simple guide for setting up and using Linux Containers on Arch Linux.
h2. Prepare the Environment
* Make sure the system is up to date:
<pre>
pacman -Syu
</pre>
* Install the base-devel and wget packages:
<pre>
pacman -S base-devel wget rsync
</pre>
* Download the packages for yaourt:
<pre>
cd /tmp
wget https://aur.archlinux.org/cgit/aur.git/snapshot/package-query.tar.gz && wget https://aur.archlinux.org/cgit/aur.git/snapshot/yaourt.tar.gz
tar xzf package-query.tar.gz
tar xzf yaourt.tar.gz
</pre>
#* Install package-query:
<pre>
cd package-query
makepkg -csi
</pre>
#* Install yaourt
<pre>
cd ../yaourt
makepkg -csi
</pre>
h2. Set Up The Network
* Install netctl:
<pre>
pacman -S netctl
</pre>
h3. Bridged Wired Connection
* Bridge Internet-shared - This example will bridge network interface eth0 and configure a static IP for the bridge:
<pre>
nano /etc/netctl/lxcbridge
</pre>
#* And add/modify the following:
<pre>
Description="LXC Bridge"
Interface=br0
Connection=bridge
BindsToInterfaces=(eth0)
IP=dhcp
SkipForwardingDelay=yes
</pre>
* After changes are made, make sure to re-enable and restart the bridge:
<pre>
netctl enable lxcbridge
netctl start lxcbridge
</pre>
* Enable IP Forwarding persist at boot:
<pre>
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/40-ip-forward.conf
</pre>
* And also apply this iptables rule:
<pre>
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
</pre>
#* To make changes persist upon reboot:
<pre>
iptables-save > /etc/iptables/iptables.rules
systemctl enable iptables
systemctl start iptables
</pre>
h3. NAT Wireless Connection (Optional)
* Make sure that forwarding is turned on to support NAT:
<pre>
echo 1 > /proc/sys/net/ipv4/ip_forward
</pre>
* Make the previous change persistent after a reboot:
<pre>
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.d/30-ipforward.conf
echo 'net.ipv6.conf.default.forwarding=1' >> /etc/sysctl.d/30-ipforward.conf
echo 'net.ipv6.conf.all.forwarding=1' >> /etc/sysctl.d/30-ipforward.conf
</pre>
Now create the bridge:
* NAT Internet-shared - This example will bridge network interface eth0 and configure a static IP for the bridge:
<pre>
nano /etc/netctl/lxcnatbridge
</pre>
#* And add/modify the following:
<pre>
Description="LXC NAT Bridge"
Interface=natbr0
Connection=bridge
IP=static
Address=192.168.10.200/24
DNS=192.168.1.1
SkipForwardingDelay=yes
ExecUpPost="/usr/local/bin/natbr0-up"
</pre>
Create the nat script:
<pre>
nano /usr/local/bin/natbr0-up
</pre>
#* And add the following:
<pre>
#!/bin/sh
# Script to setup NAT iptables masquerade rules; and dnsmasq for DHCP and DNS.
# This is the address assigned to the bridge at boot
BRADDR=192.168.10.200
# DHCP IP address range for containers
BRRANGE=192.168.10.201,192.168.10.250
# Configure iptables rules for NAT
iptables -A FORWARD -i natbr0 -s ${BRADDR}/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A POSTROUTING -t nat -j MASQUERADE
# (Optional) Forward port 2222 to host behind NAT bridge
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to 192.168.10.200:22
# Start dnsmasq DNS/DHCP server for the network attached to the NAT interface.
dnsmasq --bind-interfaces --conf-file= --listen-address $BRADDR --except-interface lo --dhcp-range $BRRANGE --dhcp-lease-max=253 --dhcp-no-override
</pre>
* Make sure it is executable by doing
<pre>
chmod +x /usr/local/bin/natbr0-up
</pre>
* Start and enable the NAT bridge at boot:
<pre>
netctl enable lxcnatbridge
netctl start lxcnatbridge
</pre>
* Now a container lxc.conf should read:
<pre>
lxc.network.type=veth
lxc.network.link=natbr0
lxc.network.flags=up
</pre>
h2. Install LXC
* Install lxc, bridge-utils, and arch-install-scripts:
<pre>
pacman -S lxc bridge-utils arch-install-scripts dnsmasq
</pre>
#* (Optional) Install extra packages for lxc:
<pre>
pacman -S lua lua-filesystem lua-alt-getopt
</pre>
* Test that the system is correctly configured
<pre>
lxc-checkconfig
</pre>
#* The output should be similar to:
<pre>
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: missing
Network namespace: enabled
Multiple /dev/pts instances: enabled
--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled
--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
File capabilities: enabled
</pre>
h2. Container setup
To find all available templates that come with LXC, look in @/usr/share/lxc/templates@ directory:
<pre>
ls /usr/share/lxc/templates
</pre>
#* _Example output:_
<pre>
lxc-alpine lxc-altlinux lxc-archlinux lxc-busybox lxc-centos lxc-cirros lxc-debian lxc-download lxc-fedora lxc-gentoo lxc-openmandriva lxc-opensuse lxc-oracle lxc-plamo lxc-sshd lxc-ubuntu lxc-ubuntu-cloud
</pre>
h3. Arch Container
* Create the container:
<pre>
lxc-create -n arch.example.com -t archlinux
</pre>
* Edit the Arch Linux container config file:
<pre>
nano /var/lib/lxc/arch.example.com/config
</pre>
#* And add/modify the following:
<pre>
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
#lxc.network.hwaddr =
lxc.network.ipv4 = 192.168.1.52
lxc.network.ipv4.gateway = 192.168.1.1
lxc.network.name = eth0
lxc.autodev = 1
lxc.pts = 1024
lxc.kmsg = 0
lxc.rootfs = /var/lib/lxc/arch.example.com/rootfs
lxc.utsname = arch.example.com
lxc.arch = armv7l
</pre>
* Start the Arch container:
<pre>
lxc-start -n arch.example.com
</pre>
* Open a console:
<pre>
lxc-attach -n arch.example.com
</pre>
#* And change the password:
<pre>
passwd
</pre>
* Create a wired connection:
<pre>
cp /etc/netctl/examples/ethernet-static /etc/netctl/wired
</pre>
* Edit the /etc/netctl/wired to match your needs.
<pre>
nano /etc/netctl/wired
</pre>
#* Add/modify the following:
<pre>
Description='Ethernet Connection'
Interface=eth0
Connection=ethernet
IP=static
Address=('192.168.1.101/24')
Gateway=('192.168.1.1')
DNS=('192.168.1.1')
# Required to start a network connection in a container
ForceConnection=yes
</pre>
* Start and enable the wired connection at boot:
<pre>
netctl enable wired
</pre>
* *NOTE*: I needed to edit /etc/systemd/system/netctl\@wired.service and comment out the following in order for the netctl command to start:
<pre>
#BindsTo=sys-subsystem-net-devices-eth0.device
#After=sys-subsystem-net-devices-eth0.device
</pre>
#* Then reload the systemd units:
<pre>
systemctl daemon-reload
</pre>
* While the console to the container is open, install openssh
<pre>
pacman -S openssh
</pre>
#* Start and enable openssh at boot:
<pre>
systemctl enable sshd.service
systemctl start sshd.service
</pre>
h3. Debian Container
* Install debootstrap from AUR:
<pre>
yaourt debootstrap
</pre>
#* Install gnupg1 for keyring verification; make sure to +edit the PKGBUILD+ and add *armv7h* to the arch parameter:
<pre>
gpg --keyserver pgpkeys.mit.edu --recv-keys 2071B08A33BD3F06
yaourt gnupg1
</pre>
#* Install debian-archive-keyring:
<pre>
yaourt debian-archive-keyring
</pre>
* Edit the Debian Raspbian LXC template:
<pre>
nano /usr/share/lxc/templates/lxc-debian /usr/share/lxc/templates/lxc-raspbian
</pre>
#* And modify the following parameters:
<pre>
debootstrap --verbose --variant=minbase --arch=$arch --no-check-gpg
#...
download_debian()
{
packages=\
ifupdown,\
locales,\
libui-dialog-perl,\
dialog,\
isc-dhcp-client,\
netbase,\
net-tools,\
iproute,\
apt-utils,\
openssh-server
#...
</pre>
#* *NOTE*: The debootstrap command has the added *@--no-check-gpg argument@*
#* *NOTE*: Make sure to add the *apt-utils,\* line above openssh-server
* Create the container:
<pre>
lxc-create -n debian.example.com raspbian.example.com -t debian raspbian -- -r jessie
</pre>
* Edit the Debian Raspbian container config file:
<pre>
nano /var/lib/lxc/debian.example.com/config /var/lib/lxc/raspbian.example.com/config
</pre>
#* And add/modify the following:
<pre>
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.1.53
lxc.network.ipv4.gateway = 192.168.1.1
lxc.network.name = eth0
lxc.autodev = 1
lxc.pts = 1024
lxc.rootfs = /var/lib/lxc/debian.example.com/rootfs /var/lib/lxc/raspbian.example.com/rootfs
lxc.utsname = debian.example.com raspbian.example.com
lxc.arch = armvhf
</pre>
* Start the containter:
<pre>
lxc-start -n debian.example.com raspbian.example.com
</pre>
* Then attach to the container:
<pre>
lxc-attach -n debian.example.com raspbian.example.com
</pre>
#* And install the debian-keyring package:
<pre>
apt-get install debian-keyring
</pre>
h3. Ubuntu Container
* Install debootstrap from AUR:
<pre>
yaourt debootstrap
</pre>
#* Install ubuntu-keyring:
<pre>
yaourt ubuntu-keyring
</pre>
* Create the container:
<pre>
lxc-create -n ubuntu.example.com -t ubuntu -- -r trusty
</pre>
* Edit the Ubuntu container config file:
<pre>
nano /var/lib/lxc/ubuntu.example.com/config
</pre>
#* And add/modify the following:
<pre>
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.1.54
lxc.network.ipv4.gateway = 192.168.1.1
lxc.network.name = eth0
lxc.autodev = 1
lxc.pts = 1024
lxc.rootfs = /var/lib/lxc/ubuntu.example.com/rootfs
lxc.utsname = ubuntu.example.com
lxc.arch = armvhf
</pre>
* Start the containter:
<pre>
lxc-start -n ubuntu.example.com
</pre>
h3. Fedora Container
* Create the container:
<pre>
lxc-create -n fedora.example.com -t fedora -- -R 23
</pre>
* Edit the Fedora container config file:
<pre>
nano /var/lib/lxc/fedora.example.com/config
</pre>
#* And add/modify the following:
<pre>
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.ipv4 = 192.168.1.55
lxc.network.ipv4.gateway = 192.168.1.1
lxc.network.name = eth0
lxc.autodev = 1
lxc.pts = 1024
lxc.rootfs = /var/lib/lxc/fedora.example.com/rootfs
lxc.utsname = fedora.example.com
lxc.arch = armvhf
</pre>
* Start the containter:
<pre>
lxc-start -n fedora.example.com
</pre>
h2. Autostart Containers
* Enable the lxc service at boot:
<pre>
systemctl enable lxc.service
</pre>
* Then add the autostart line to the containers config file:
<pre>
echo 'lxc.start.auto = 1' >> /var/lib/lxc/arch.example.com/config
</pre>
* Start the lxc service:
<pre>
systemctl start lxc.service
</pre>
h2. Resources
* https://s3hh.wordpress.com/2011/05/17/lxc-containers-on-a-host-with-wireless/
* https://wiki.archlinux.org/index.php?title=Linux_Containers&redirect=no