Introduction
I’ve been a fan of immutable infrastructure ever since I used tools like Terraform and Packer. I wouldn’t say I understood the pros of it right away, but with time spent managing deployment of services in high traffic environments, one sort of understands the importance of being able to have an infrastructure which is scalable, predictable and can be recovered automatically. Who better to explain what immutable infrastructure is than Armon Dadgar himself?
Image layering
If you go through Section 2.3 of the book container best practices, they have a good section on various types of images. This brought back few of the steps I used to use previously on maintaining and building container images.
Poor quick drawing credits: sketchpad.io
Base Layer
This base layer contains the operating system, core system tools, (eg: such as vim, bash, software-properties-common, curl, vim etc) and tools necessary to install packages and make updates to the image over time. The best example of such base layers are the alpine images.
FROM alpine:3.7 | |
RUN apk update && \ | |
apk add --no-cache xorriso git xz curl tar iptables cpio bash && \ | |
rm -rf /var/cache/apk/* | |
RUN apk add -U --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing aufs-util | |
RUN addgroup -g 2999 docker |
Dependency layer
Dependency image layers are where you would install the platform related dependencies (eg: such as Java runtime, mysql, Go, Erlang etc)
FROM mockingbird/base-image | |
ENV MYSQL_MAJOR 5.6 | |
ENV MYSQL_VERSION 5.6.44-1debian9 | |
RUN echo "deb http://repo.mysql.com/apt/debian/ stretch mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list | |
# the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql) | |
# also, we set debconf keys to make APT a little quieter | |
RUN { \ | |
echo mysql-community-server mysql-community-server/data-dir select ''; \ | |
echo mysql-community-server mysql-community-server/root-pass password ''; \ | |
echo mysql-community-server mysql-community-server/re-root-pass password ''; \ | |
echo mysql-community-server mysql-community-server/remove-test-db select false; \ | |
} | debconf-set-selections \ | |
&& apt-get update && apt-get install -y mysql-server="${MYSQL_VERSION}" && rm -rf /var/lib/apt/lists/* \ | |
&& rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \ | |
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \ | |
# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime | |
&& chmod 777 /var/run/mysqld \ | |
# comment out a few problematic configuration values | |
&& find /etc/mysql/ -name '*.cnf' -print0 \ | |
| xargs -0 grep -lZE '^(bind-address|log)' \ | |
| xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/' \ | |
# don't reverse lookup hostnames, they are usually another container | |
&& echo '[mysqld]\nskip-host-cache\nskip-name-resolve' > /etc/mysql/conf.d/docker.cnf |
FROM mockingbird/base-image | |
ENV LANG=C.UTF-8 | |
RUN curl -LO https://dl.google.com/go/go1.12.2.linux-amd64.tar.gz \ | |
&& chown root:root go1.12.2.linux-amd64.tar.gz \ | |
&& tar -xzf go1.12.2.linux-amd64.tar.gz \ | |
&& rm go1.12.2.linux-amd64.tar.gz \ | |
&& mv go /usr/local | |
WORKDIR /usr/local/lib/jre1.8.0_131 | |
ENV GOROOT=/usr/local/go | |
ENV GOPATH="/Users/farhankh/go-workspace/src" | |
ENV PATH=$PATH:$GOPATH/bin |
Application layer
Application layer is where the dependencies specific to the container would go (eg: Database configurations, Go application code etc)
FROM mockingbird/application-go-image | |
RUN git clone https://github.com/dgraph-io/badger | |
WORKDIR /badger | |
WORKDIR /badger | |
RUN make VERBOSE=1 && make install |
One can add the application specific endpoints here or add something like dumb-init.
What this helps us do is to reuse the layers at one specific stage and to use it for multiple purposes. Images being layered in this fashion will help break down large sized images into smaller images with well defined layers. It will help in faster builds, maintenance and also for reusing them as components.
References
Please follow TechLog for more.
Top comments (0)