Debian 10, Cloud-init and static IP addresses
In the last two days, I was preparing a virtual environment for some tests
about MariaDB replication. I was determined to use the same identical
settings of the production machine I was simulating: Debian 10, Docker,
MariaDB 10.4. I use terraform for these tests, which works pretty well
with the libvirt provider.
Usually, I do some testing using the Ubuntu LTS cloud image (even if I’m using Debian everywhere) due to the easiness of setup. However, in this test, I want to use Debian because I want to be sure about the accuracy of this test.
Yesterday morning I discovered that even Debian has some official cloud-ready
images. A quick look on internet
and I discovered that genericcloud is what I need.
Long story short, I was using Cloud-init to setup static IP addresses on Debian Buster images. However, the image was still trying the DHCP, and no DNS.
Stable is… too stable?
Digging inside the image, I discovered that Cloud-init was too old (version
18.something), while in the backport repo there was an updated 20. By looking
at the behavior of the old and new version, I discovered that the 18 version
is creating a file inside the /run/cloud/interfaces.d/ens3 with the correct
configuration, which is however ignored, and a similar file is created inside
/etc/network/interfaces.d/ens3 with the wrong configuration (eg. DHCP). The
updated version instead is writing the latter file correctly (eg. same content
of the former), still ignoring the one in /run.
Because there is no cloud-ready version for buster-backports, I decided to
compile one on my own, updating cloud-init in order to fix the issue with
the network configuration.
I cloned the Debian Cloud images
repository and I downloaded the cloud-init deb package inside localdebs/,
so the fai-based installer can use that version (as it’s new). Then:
user@debian: ~/debian-cloud-images/localdebs$ apt-ftparchive packages . > Packages
This command is used to generate a valid Packages file for the “local repo”.
What about the DNS?
The fix above is not sufficient to resolve for the DNS. In fact, no
/etc/resolv.conf is ever created, neither by cloud-init (with any
possible configuration…) or the system itself (which is normal as, by
default, it’s missing resolvconf package or any other package which
generates that file).
Using runcmd in cloud-init was not an option for me as I was trying
to install packages and do other things using cloud-init, so before the
runcmd part.
I tried different things:
- Install
resolvconfpackage in the base image during the build (result: the file is not generated for some reason) - Create this file manually bu putting it in
config_spaces/files/etc(result: the file will not survive, and the reason is that the script that I found for the “resolution” is removing it on image cleanup) - Create this file manually using a shell script (result: for some reason, that also was not working, even if the script is after the cleanup)
I ended up editing config_spaces/scripts/LAST/10-cleanup, which is the script
that has the duty of cleaning up the image. At the end of the rm command set
I wrote something like echo "nameserver 192.0.2.1" > $target/etc/resolv.conf
where 192.0.2.1 is your preferred DNS server.
Unfortunately this is not a definitive solution, as DNS servers specified
in the cloud-init still gets ignored (at least up until the cloud-init
preparation ends). However is a workaround which might be usable. I really
hope that these things will be fixed in the next Debian major release.
Build the image
Ah, of course the command for building the image is:
$ make image_buster-backports_genericcloud_amd64
Note: by default these images have no root password in console, and
no remote root login capability except for public key auth.
Addendum: download pre-built image
This pre-built image uses 1.1.1.1 DNS and an updated version of cloud-init:
https://drive.google.com/file/d/1GeeFgJwny478c1VCEnKf1Tsba3WUhyr2/view?usp=sharing