Part 5 of 5:
Running Docker on an Alpine VM
Intro
Meanwhile I have update my OpenBSD Server to version 6.6, so some commands look different from before (vmctl
uses a different ordering of arguments). All in all the whole vmd
interactions feel a lot more stable and mature than before.
Create an Alpine VM
Create the disk and start the installation
The procedure is similar to what I described in my other post about creating virtual machines, though as mentioned before the vmctl
has a slightly different syntax now.
Note also that the last command in the code-block below uses the virtual network called localnet
which I set up for the VM network in a previous post.
The vmctl start
command in the end means the following:
-c
: Connect to a virtual console after starting-B cdrom
: Boot from a supplied cdrom iso if exists-r alpine-virt-3.11.5-x86_64.iso
: Use the supplied iso as cdrom data-d alpine.drive
: Use the raw disk drive we created-m 2G
: With 2 Gigabyte of virtual ram-n localnet
: Connecting to the virtual bridge network calledlocalnet
alpine-vm
: Name the VM "alpine-vm"
# replace v3.11 with the latest version of alpine
doas ftp https://nl.alpinelinux.org/alpine/v3.11/releases/x86_64/alpine-virt-3.11.5-x86_64.iso
doas ftp https://nl.alpinelinux.org/alpine/v3.11/releases/x86_64/alpine-virt-3.11.5-x86_64.iso.sha256
# verify correct signature
diff <(sha256 -q alpine-virt-3.11.5-x86_64.iso) <(cat alpine-virt-3.11.5-x86_64.iso.sha256)
# create the raw disk file for alpine to install on
doas vmctl create -s 8G alpine.drive
# start the vm with boot rom
doas vmctl start -c -B cdrom -r alpine-virt-3.11.5-x86_64.iso -d alpine.drive -m 2G -n localnet alpine-vm
Installation of the alpine os inside the Alpine-VM
After the booting-process I logged into the VM as root
user (without any password), and set up the network interfaces, for accessing online package resources during the installation.
The setting of IP-Addresses, gateways, nameserver all is oriented at a previous post, in which I set up the VM-network that I use on my server.
# set up the network interfaces itself
localhost:~# setup-interfaces
Available interfaces are: eth0.
Enter '?' for help on bridges, bonding and vlans.
Which one do you want to initialize? (or '?' or 'done') [eth0]
Ip address for eth0? (or 'dhcp', 'none', '?') [dhcp] 192.168.30.6
Netmask? [255.255.255.0]
Gateway? (or 'none') [none] 192.168.30.1
Configuration for eth0:
type=static
address=192.168.30.6
netmask=255.255.255.0
gateway=192.168.30.1
Do you want to do any manual network configuration? [no]
# set up the nameserver
localhost:~# setup-dns
DNS domain name? (e.g 'bar.com') [] hermes-technology.de
DNS nameserver(s)? [] 192.168.30.1
After I was making sure that my networking was working (via a ping google.com
), I just started the installation choosing the commands shown below.
localhost:~# setup-alpine
Available keyboard layouts:
af be cn fi hu it lk mm pl sy uz
al bg cz fo id jp lt mt pt th vn
am br de fr ie ke lv my ro tj
ara brai dk gb il kg ma ng rs tm
at by dz ge in kr md nl ru tr
az ca ee gh iq kz me no se tw
ba ch epo gr ir la mk ph si ua
bd cm es hr is latam ml pk sk us
Select keyboard layout [none]: de
Available variants: de-T3 de-deadacute de-deadgraveacute de-deadtilde de-dsb de-dsb_qwertz de-dvorak de-mac de-mac_nodeadkeys de-neo de-nodeadkeys de-qwerty de-ro de-ro_nodeadkeys de-ru de-sundeadkeys de-tr de
Select variant []: de
* Caching service dependencies ...
[ ok ]
* Setting keymap ...
[ ok ]
Enter system hostname (short form, e.g. 'foo') [localhost]: services
Available interfaces are: eth0.
Enter '?' for help on bridges, bonding and vlans.
Which one do you want to initialize? (or '?' or 'done') [eth0]
Ip address for eth0? (or 'dhcp', 'none', '?') [192.168.30.6]
Netmask? [255.255.255.0]
Gateway? (or 'none') [192.168.30.1]
Configuration for eth0:
type=static
address=192.168.30.6
netmask=255.255.255.0
gateway=192.168.30.1
Do you want to do any manual network configuration? [no]
ifup: interface eth0 already configured
DNS domain name? (e.g 'bar.com') [] hermes-technology.de
DNS nameserver(s)? [192.168.30.1 ]
Changing password for root
New password:
Retype password:
passwd: password for root changed by root
Which timezone are you in? ('?' for list) [UTC] Europe/Berlin
* Starting busybox acpid ...
[ ok ]
* Starting busybox crond ...
[ ok ]
HTTP/FTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none]
Which NTP client to run? ('busybox', 'openntpd', 'chrony' or 'none') [chrony]
* service chronyd added to runlevel default
* Caching service dependencies ...
[ ok ]
* Starting chronyd ...
[ ok ]
Available mirrors:
1) dl-cdn.alpinelinux.org
2) uk.alpinelinux.org
3) dl-2.alpinelinux.org
4) dl-4.alpinelinux.org
5) dl-5.alpinelinux.org
6) dl-8.alpinelinux.org
7) mirror.yandex.ru
8) mirrors.gigenet.com
9) mirror1.hs-esslingen.de
10) mirror.leaseweb.com
11) mirror.fit.cvut.cz
12) alpine.mirror.far.fi
13) alpine.mirror.wearetriple.com
14) mirror.clarkson.edu
15) linorg.usp.br
16) ftp.yzu.edu.tw
17) mirror.aarnet.edu.au
18) speglar.siminn.is
19) mirrors.dotsrc.org
20) ftp.halifax.rwth-aachen.de
21) mirrors.tuna.tsinghua.edu.cn
22) mirrors.ustc.edu.cn
23) mirrors.xjtu.edu.cn
24) mirrors.nju.edu.cn
25) mirror.lzu.edu.cn
26) ftp.acc.umu.se
27) mirror.xtom.com.hk
28) mirror.csclub.uwaterloo.ca
29) alpinelinux.mirror.iweb.com
30) mirror.neostrada.nl
31) pkg.adfinis-sygroup.ch
32) mirror.ps.kz
33) mirror.rise.ph
34) mirror.operationtulip.com
35) mirrors.ircam.fr
36) alpine.42.fr
37) mirror.math.princeton.edu
38) mirrors.sjtug.sjtu.edu.cn
39) alpine.mirror.didstopia.com
40) ftp.icm.edu.pl
41) mirror.ungleich.ch
42) alpine.mirror.vexxhost.ca
43) sjc.edge.kernel.org
44) ewr.edge.kernel.org
45) ams.edge.kernel.org
46) download.nus.edu.sg
r) Add random from the above list
f) Detect and add fastest mirror from above list
e) Edit /etc/apk/repositories with text editor
Enter mirror number (1-46) or URL to add (or r/f/e/done) [1]:
Added mirror dl-cdn.alpinelinux.org
Updating repository indexes... done.
Which SSH server? ('openssh', 'dropbear' or 'none') [openssh]
* service sshd added to runlevel default
* Caching service dependencies ...
[ ok ]
ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519
* Starting sshd ...
[ ok ]
Available disks are:
vda (8.6 GB 0x0b5d )
Which disk(s) would you like to use? (or '?' for help or 'none') [none] vda
The following disk is selected:
vda (8.6 GB 0x0b5d )
How would you like to use it? ('sys', 'data', 'lvm' or '?' for help) [?] sys
WARNING: The following disk(s) will be erased:
vda (8.6 GB 0x0b5d )
WARNING: Erase the above disk(s) and continue? [y/N]: y
Creating file systems...
Installing system on /dev/vda3:
/mnt/boot is device /dev/vda1
100% ############################################==> initramfs: creating /boot/initramfs-virt
/boot is device /dev/vda1
Installation is complete. Please reboot.
Running poweroff
in the terminal should shutdown the vm and end the connection to the virtual terminal.
As an alternative you can run exit
and hit ~^D
to exit the virtual terminal, afterwards shutting down the vm via doas vmctl stop alpine-vm
.
Create separate data disk and Modify vm.conf and restart vmd
At first I created a 20 Gigabyte raw disk drive for system-independent data storage of the virtual machine.
doas vmctl create -s 20G /mnt/data/vm-drives/alpine-data.img
Afterwards I modified the /etc/vm.conf
to include the new virtual machine and feed the correct disk data to the alpine-vm
.
files= /home/web-spider/vm/
data= /mnt/data/vm-drives/
vm host-vm {
memory 2g
disk $files host.drive
interface tap { lladdr 00:00:00:00:00:02 switch localnet }
}
vm alpine-vm {
memory 2g
interface tap { lladdr 00:00:00:00:00:06 switch localnet }
disk "/mnt/data/vm-drives/alpine.drive" format raw
disk "/mnt/data/vm-drives/alpine-data.img" format raw
}
switch localnet {
interface bridge0
}
Restart vmd
for the changes to be effective.
doas rcctl restart vmd
Kernel booting modifications
For the virtual machine to work more stable and quick with vmd
, I did some recommended changes to the booting parameters.
- Connect to alpine-vm via
doas vmctl console alpine-vm
- Update config file
/boot/extlinux.conf
- Reboot and reconnect to vm
Important |
---|
<uuid> and <dist> must be substituted by your specific values, in mycase <dist> was virt and <uuid> was 001c5e4f-af70-4f6f-bdbc-ceff9d23c6f3 |
SERIAL 0 115200
DEFAULT <dist>
PROMPT 0
LABEL <dist>
MENU LABEL Linux <dist>
LINUX vmlinuz-<dist>
INITRD initramfs-<dist>
APPEND root=UUID=<uuid> modules=sd-mod,usb-storage,ext4 rootfstype=ext4 console=ttyS0,115200
My configuration looked like this in the end:
SERIAL 0 115200
DEFAULT virt
PROMPT 0
LABEL virt
MENU LABEL Linux virt
LINUX vmlinuz-virt
INITRD initramfs-virt
APPEND root=UUID=001c5e4f-af70-4f6f-bdbc-ceff9d23c6f3 modules=sd-mod,usb-storage,ext4 rootfstype=ext4 console=ttyS0,115200
Enable SSH-Access to the alpine-vm
For a more comfortable and generally better user experience, I enabled ssh access to the VM. To enable ssh access with the possibility to execute root commands, I installed sudo
, created a user and configured openssh
accordingly.
The procedure was as follows
- Add user and groups, configure
sudo
for groupwheel
- Modify
/etc/ssh/sshd_config
- Add the desired public-key from the workstation
- Restart
sshd
or reboot the VM - Connect to the vm via
ssh
# add some user e.g. named "general"
adduser general
# add a groups that will be gained ssh access privileges
addgroup ssh-user
# install sudo package
apk add sudo
# add user to groups
for u in $(ls /home); do for g in ssh-user disk lp floppy audio cdrom dialout video netdev games users wheel; do addgroup $u $g; done;done
# edit sudoers file to allow users of group wheel
sed -i 's/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g' /etc
/sudoers
My configuration file for the open ssh daemon looks like the one below, for a better security I also referred an earlier post on how to make ssh configuration more secure.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
|
add authorized keys from your workstation (e.g. copy and paste it)
echo "ssh-ed25519 SD323f928392i31sadfklsjdf37824 someone@some-workstation" > authorized_keys
# restart the sshd service
rc-service sshd restart
I logged in to the alpine machine from my workstation via ssh which was more comfortable. I did this by using my server as a jumphost into the vm. I covered the configuration of such an entry in a previous post.
Create a new filesystem and mount the data disk
Modify the repositories in /etc/apk/repositories
to include the community
packages and update them afterwards via apk update
. I used comminity
to check the available disks via lsblk
command.
#/etc/apk/repositories
#/media/cdrom/apks
http://dl-cdn.alpinelinux.org/alpine/v3.11/main
http://dl-cdn.alpinelinux.org/alpine/v3.11/community
#http://dl-cdn.alpinelinux.org/alpine/edge/main
#http://dl-cdn.alpinelinux.org/alpine/edge/community
#http://dl-cdn.alpinelinux.org/alpine/edge/testing
- update repos
# change to root
sudo -s
# install linux utils (for lsblk)
apk add util-linux
# check the disks
lsblk
# use parted, so install it
apk add parted
# execute parted (in my case with device vdb)
parted vdb
## now inside the parted-shell:
# configure new gpt label
(parted) mklabel gpt
# set unit size
(parted) unit MiB
# make new ext4 partition
(parted) mkpart 1 ext4 1 20479
# check optimal alignment
(parted) align-check opt
# name partition e.g. "data"
(parted) name 1 data
# quit
(parted) quit
# make new filesystem
mkfs.ext4 /dev/vdb1
# not the partition UUID that mkfs reports, copy it
DATA_UUID=<your partition uuid that you copied>
# create mount point directory
mkdir /data
# add mounting into fstab
echo "UUID=$DATA_UUID /data ext4 rw,relatime,user 0 0" >> /etc/fstab
# mount it
mount /data
Install Docker and make it use the data-disk
Install Docker
sudo apk add docker
sudo adduser general docker
Modify DOCKER_OPTS
in /etc/conf.d/docker
# any other random options you want to pass to docker
DOCKER_OPTS="--data-root /data/docker"
Restart Docker via rc-service docker restart