DHCP


Rough notes on setting up an Ubuntu 22.04LTS server with docker and snap 1

IP allocations

First, we set up a static IP on the network device that would handle all external traffic and a DHCP on the network device that would access the management network, which is connected for maintenance.

To do so, we created the following file:

/etc/netplan/01-netcfg.yaml

using the following command:

sudo nano /etc/netplan/01-netcfg.yaml;

and added the following content to it:

# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      addresses: [192.168.45.13/24]
      gateway4: 192.168.45.1
      nameservers:
          addresses: [1.1.1.1,8.8.8.8]
    eth1:
      dhcp4: yes

To apply the changes, we executed the following:

sudo netplan apply;

Update everything (the operating system and all packages)

Usually, it is a good idea to update your system before making significant changes to it:

sudo apt update -y; sudo apt upgrade -y; sudo apt autoremove -y;

Install docker via snap

In this setup, we did not use the docker version available on the Ubuntu repositories, we went for the ones from the snap. To install it, we used the following commands:

sudo apt install snapd;
sudo snap install docker;

Increase network pool for docker daemon

To handle the following problem:

ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

We modified the following file

/var/snap/docker/current/config/daemon.json

using the command:

sudo nano /var/snap/docker/current/config/daemon.json;

and set the content to be as follows:

{
    "log-level":        "error",
    "storage-driver":   "overlay2",
    "default-address-pools": [
        {
            "base": "172.80.0.0/16",
            "size": 24
        },
        {
            "base": "172.90.0.0/16",
            "size": 24
        }
    ]
}

We executed the following command to restart the docker daemon and get the network changes applied:

sudo snap disable docker;
sudo snap enable docker;

Gave access to our user to manage the docker

We added our user to the docker group so that we could manage the docker daemon without sudo rights.

sudo addgroup --system docker;
sudo adduser $USER docker;
newgrp docker;
sudo snap disable docker;
sudo snap enable docker;

After that, we made sure that the access rights to the volumes were correct:

sudo chown -R www-data:www-data /volumes/*
sudo chown -R tux:tux /volumes/letsencrypt/ /volumes/reverse/private/

Deploying

After we copied everything in place, we executed the following command to create our containers and start them with the appropriate networks and volumes:

export COMPOSE_HTTP_TIMEOUT=600;
docker-compose up -d --remove-orphans;

We had to increase the timeout as we were getting the following error:

ERROR: for container_a  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.
If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value (current value: 60).

Updating the databases and performing any repairs

First, we connected to a terminal of the database container using the following command:

docker exec -it mariadb_c1 /bin/bash;

From there, we executed the following commands:

mysql_upgrade --user=root --password;
mysqlcheck -p -o --all-databases;

Bulk / Batch stopping docker containers

The following commands will help you stop many docker containers simultaneously. Of course, you can change the command stop to another, for example rm or whatever suits your needs.

You need to keep in mind that if you have dependencies between containers, you might need to execute the commands below more than once.

Stop all docker containers.

docker container stop $(docker container ls -q);
#This command creates a list of all containers.
#Using the -q parameter, we only get back the container ID and not all information about them.
#Then it will stop each container one by one.

Stop specific docker containers using a filter on their name.

docker container stop $(docker container ls -q --filter name=_web);
#This command finds all containers that their name contains _web.
#Using the -q parameter, we only get back the container ID and not all information about them.
#Then it will stop each container one by one.

A personal note

Check the system for things you might need to configure, like a crontab or other services.

A script that handles privileges on the docker volumes

To avoid access problems with the various external volumes we created the mysql user and group on the host machine as follows:

sudo groupadd -g 999 mysql;
sudo useradd -u 999 mysql -g mysql;

Then we execute the following to repair ownership issues with our containers. Please note that this script is custom to a particular installation and might not meet your needs.

#!/bin/bash

sudo chown -R www-data:www-data ~/volumes/*;
sudo chown -R bob:bob ~/volumes/letsencrypt/ ~/volumes/reverse/private/;
find ~/volumes/ -maxdepth 2 -type d -name mysql -exec sudo chown -R mysql:mysql '{}' \;;

A simple way to find which DHCP server gave you an IP

Recently, we were trying to find which DHCP server was responding to the messages on the network. Using a DHCP-enabled client on a Fedora 26 GNU/Linux we grepped the contents of journalctl to find the DHCP acknowledgment messages (DHCPACK) and figure out the IP of the DHCP server.

The command we used was the following:

sudo journalctl | grep DHCPACK;

And it gave us results such as the ones below:

[user@sys-net ~]$ sudo journalctl | grep DHCPACK
Nov 12 13:08:28 sys-net dhclient[578]: DHCPACK from 10.1.101.252 (xid=0x80ec760c)
Nov 12 13:08:34 sys-net dhclient[720]: DHCPACK from 10.1.101.252 (xid=0x2ed6486f)
Nov 12 11:51:19 sys-net dhclient[1248]: DHCPACK from 10.1.101.252 (xid=0xe3dd491c)
Nov 12 12:02:09 sys-net dhclient[1407]: DHCPACK from 10.1.101.252 (xid=0x1fa42c2d)
Nov 12 12:11:03 sys-net dhclient[1508]: DHCPACK from 10.1.101.252 (xid=0x91c3990a)
Nov 12 12:14:06 sys-net dhclient[1607]: DHCPACK from 10.1.101.252 (xid=0x57ebb515)
Nov 12 12:19:27 sys-net dhclient[1710]: DHCPACK from 10.1.101.252 (xid=0x5450c250)
Nov 12 12:19:39 sys-net dhclient[1776]: DHCPACK from 10.1.101.252 (xid=0x2c38d517)
Nov 12 12:39:53 sys-net dhclient[1837]: DHCPACK from 192.168.1.1 (xid=0xe7a1182d)
Nov 12 12:40:51 sys-net dhclient[1837]: DHCPACK from 192.168.1.1 (xid=0xe7a1182d)
Nov 12 12:41:51 sys-net dhclient[1837]: DHCPACK from 192.168.1.1 (xid=0xe7a1182d)
Nov 12 12:42:44 sys-net dhclient[1837]: DHCPACK from 192.168.1.1 (xid=0xe7a1182d)
Nov 12 12:43:33 sys-net dhclient[1837]: DHCPACK from 192.168.1.1 (xid=0xe7a1182d)
Nov 12 12:44:31 sys-net dhclient[1837]: DHCPACK from 192.168.1.1 (xid=0xe7a1182d)
Nov 12 12:46:20 sys-net dhclient[2053]: DHCPACK from 192.168.1.1 (xid=0xbb006001)

It is important to use sudo or else you will not be seeing messages from other users and the system. As, only users in groups ‘adm’, ‘systemd-journal’, ‘wheel’ can see all messages.


CentOS 7: Setup a DHCP server and provide specific IP based on MAC address

Step 1: Install DHCP service

We installed the Dynamic host configuration protocol software (DHCP service) using the command:

yum install dhcp;

The dhcp package provides the ISC DHCP service and relay agent.

Step 2: Configure the DHCP service

Afterwards, we created the file /etc/dhcp/dhcpd.conf using the following content:

subnet 192.168.0.0 netmask 255.255.255.0 {
 option routers                  192.168.0.254;
 option subnet-mask              255.255.255.0;
 option domain-name              "bytefreaks.net";
 option domain-name-servers       192.168.0.1;
 option time-offset              -18000;     # Eastern Standard Time
 range 192.168.0.90 192.168.0.99;
}

host coolServer {
 hardware ethernet 0e:e0:4b:b4:28:82;
 fixed-address 192.168.0.80;
}

This configuration allowed us to provide a DHCP service to the network for the subdomain 192.168.0.x with the range [90,99].
Also, we statically defined the IP for our coolServer using a filter based on the MAC address of the machine.
If you do not want to provide any range, only static IPs, then comment out (#) the line that starts with the word range .

Step 3: Start DHCP service

systemctl start dhcpd.service;

Step 4: Check the status of DHCP service

systemctl status dhcpd.service;

It is a good idea to verify that there are no errors, so be sure to check the status of the service.
You can ignore the error that says “you did not define a subnet declaration for all devices” if you do not really need to do it.

Step 5: Permanently enable the DHCP service

systemctl enable dhcpd.service;

Additional:

Disable the DHCP service

systemctl disable dhcpd.service;

Stop the DHCP service

systemctl stop dhcpd.service;


How to setup DNS service for DHCP-enabled KVM guests

So you’ve set up KVM on your machine and you have installed a few guests to run on top, now it’s the time to access them.

Since KVM can run without a GUI, you might want to control these guests from the command line. But, how can you do it if you do not know the IP of the guests?

You can either connect to the guest using virt-viewer:

virt-viewer -c qemu:///system $MACHINE &

which requires more bandwidth since it will open up a VNC session.

Or, use ssh to connect using the guest’s name, like this:

ssh $MACHINE

which doesn’t require that you know the IP beforehand.

To achieve this, access guest machines using their hostname only, you can do the following: Edit /etc/resolv.conf and add the line nameserver 192.168.122.1 right after the search entries .

Your file should look something like this afterwards:
domain in.bytefreaks.net
search in.bytefreaks.net
nameserver 192.168.122.1
nameserver 194.44.13.20
nameserver 194.44.13.58
nameserver 194.44.13.11

Then you are ready to go! No restarts needed no extra steps.

NOTES:

  • After restarting (and some times periodically), the /etc/resolv.conf file will return to its original form because it is updating each time you restart the host machine from data it gets via the network DHCP server.
  • For this tutorial to work as is, your host machine needs to have the virtual IP 192.168.122.1 (the default IP of your host in libvirt — NOT THE IP of eth0, it’s a totally different thing). If you have a different libvirt IP use that one in the /etc/resolv.conf file.
  • Use your host’s IP as your first nameserver in /etc/resolv.conf to achieve name resolution for your guests.