:octocat: Alpine Linux base image with support for DNS service discovery in Docker clusters
Clone or download

README.md

Deprecated: This image is no longer maintained as Alpine Linux 3.4+ supports search domains in resolv.conf.

Alpine-Kubernetes base image

CircleCI ImageLayers Size Docker Pulls License

The Alpine-Kubernetes base image enables deployment of Alpine Linux micro-service containers in Kubernetes, Consul, Tutum or other Docker cluster environments that use DNS-based service discovery and rely on the containers ability to qualify service names using the search domains from resolv.conf.

Supported tags and respective Dockerfile links

Trusted builds are available on Docker Hub.

About

Alpine-Kubernetes is derived from the official Docker Alpine image adding the s6 supervisor for containers and a lightweight DNS resolver with minimal runtime and filesystem overhead.

Motivation

Alpine Linux does not support the search keyword in resolv.conf. This breaks many tools that rely on DNS service discovery (e.g. Kubernetes, Tutum.co, Consul).

Additionally Alpine Linux deviates from the established concept of primary and secondary nameservers. This leads to problems in cases where the container is configured with multiple nameserver with inconsistent records (e.g. one Consul server and one recursing server).

To overcome these issues the Alpine-Kubernetes base image includes a lightweight (1.2 MB) container-only DNS server that replicates the behavior of GNU libc's stub-resolver.

How it works

On container start the DNS resolver parses the nameserver and search entries from resolv.conf and configures itself as nameserver for the container. DNS queries from local processes are handled following these conventions:

  • The nameserver listed first in resolv.conf is always queried first. Additional nameservers are treated as fallbacks.
  • Hostnames are qualified by appending the domains configured with the search keyword in resolv.conf
  • Single-label hostnames (e.g.: "redis-master") are always qualified with search domains
  • Multi-label hostnames are first tried as absolute names and only then qualified with search domains

Usage

Building your own image based on Alpine-Kubernetes is as easy as typing FROM janeczku/alpine-kubernetes.
The official Alpine Docker image is well documented, so check out their documentation to learn more about building micro Docker images with Alpine Linux.

The small print:
Do NOT redeclare the ENTRYPOINT in your Dockerfile as this is reserved for the supervisor init script.

Example Alpine Redis image

FROM janeczku/alpine-kubernetes:3.3
RUN apk-install redis
CMD ["redis-server"]

Caveats

Kubernetes multi-container pods

All containers within a pod behave as if they are on the same host with regard to networking. They can all reach each other’s ports on localhost.

(Source: Kubernetes Networking)

This means there can be only one container per pod running a DNS server on localhost. If your pod spec contains more than one containers based on the Alpine-Kubernetes base image, you need to disable the local DNS server for all but one of them. This can be achieved by setting the environment variable ALPINE_NO_RESOLVER. Any container set to this env var will use an existing DNS service on localhost as it's nameserver.

apiVersion: v1
kind: Pod
metadata:
  name: redis_django
  labels:
    app: web
spec:
  containers:
    - name: key-value-store           # On this container the DNS server will bind to localhost as usual
      image: alpine-kubernetes-redis
      ports:
        - containerPort: 6379
    - name: frontend                  # This container will just have it's nameserver set to localhost
      image: alpine-kubernetes-django
      ports:
        - containerPort: 8000
      env:
        - name: ALPINE_NO_RESOLVER
          value: True

Multiple processes in a single container (optional)

You can leverage s6 supervised services to run multiple processes in a single container. Instructions can be found here. Since the container DNS server itself is a service, any additional services need to be configured to start after the DNS service. This is accomplished by adding the following line to the service script:

if { s6-svwait -t 5000 -u /var/run/s6/services/resolver }

Example service script

#!/usr/bin/execlineb -P
if { s6-svwait -t 5000 -u /var/run/s6/services/resolver }
with-contenv
nginx

Docker Hub image tags

Alpine-Kubernetes image tags follow the official Alpine Linux image. See the top of this page for the currently available versions.

DNS resolver configuration (optional)

The configuration of the included go-dnsmasq DNS server can be changed by setting environment variables either at runtime with docker run -e ... or in the Dockerfile. Check out the documentation for the available configuration options.

Acknowledgement