Static DNS with DHCP on CoreOS
Published on 2015-06-24 10:39
Categories: coreos, infrastructure
TL;DR;
How to set static DNS servers while still getting IP and routes from the DHCP server in CoreOS.
Problem
I’ve setup two servers running CoreOS and SkyDNS to provide DNS resolution in my AWS VPC, creating a DHCP option set which used the two CoreOS instances as the DNS servers, which meant that the CoreOS instances got themselves as their DNS server. This meant that whenever the instances where unavailable they couldn’t resolve any names, which meant I couldn’t pull Docker images.
The solution
To fix this problem, I figured I wanted to set a static DNS, which is easy with the following commands:
# echo "nameserver 8.8.8.8" > /etc/resolv.conf
# echo "nameserver 8.8.4.4" >> /etc/resolv.conf
But this solution doesn’t persist between boots or whenever the network service
is restarted, since the dhcpclient will overwrite the /etc/resolv.conf
file. So, to have a permament solution I needed to add the configuration into
the cloud-config file. My initial cloud-config looked like this:
#cloud-config
coreos:
etcd:
discovery: https://discovery.etcd.io/2d8e9b50bc44d85d0e002767a86eff3a
addr: $private_ipv4:4001
peer-addr: $private_ipv4:7001
units:
- name: etcd.service
command: start
- name: fleet.service
command: start
- name: 00-eth0.network
runtime: true
content: |
[Match]
Name=eth0
[Network]
DHCP=yes
DNS=8.8.8.8
DNS=8.8.4.4
Which looked like it should work and it did work, but with the funny exception
that it used the DNS servers I had specified and also the one from DHCP. So my
/etc/resolv.conf
looked something like this:
nameserver 8.8.8.8
nameserver 10.0.0.10
nameserver 10.0.0.20
nameserver 8.8.4.4
So the /etc/resolv.conf
now contains two correct lines and two wrong
lines. The 10.0.0.{10,20} addresses are the addresses to the CoreOS instances.
So, after looking through the systemd.network documentation some more, I found that you should add the following lines to your cloud-config:
[DHCP]
UseDNS=false
This gave me the following final cloud-config:
#cloud-config
coreos:
etcd:
discovery: https://discovery.etcd.io/2d8e9b50bc44d85d0e002767a86eff3a
addr: $private_ipv4:4001
peer-addr: $private_ipv4:7001
units:
- name: etcd.service
command: start
- name: fleet.service
command: start
- name: 00-eth0.network
runtime: true
content: |
[Match]
Name=eth0
[Network]
DHCP=yes
DNS=8.8.8.8
DNS=8.8.4.4
[DHCP]
UseDNS=false
Which gave me the following /etc/resolv.conf
file:
nameserver 8.8.8.8
nameserver 8.8.4.4
Success! Now I have a CoreOS cluster with static DNS servers which persist between reboots and network restarts.
Warning
Do not copy and paste the cloud-config examples into your cloud-config before you edit the discovery token.