#This repository is archived and will no longer receive updates.
Docker Day II - April 15, 2015
- Chris Collins
- christopher.collins@duke.edu
https://github.com/clcollins/DockerDay2
Majority of Docker use by sysadmins (at least at first):
Replicating Servers inside of a Container
Super Docker Wizards (10th Level or above) replicate services instead
Super Docker Wizards (10th Level or above) replicate services instead
(...with linked containers)
Super Docker Wizards (10th Level or above) replicate services instead
(...with linked containers)
(...and a bit of style)
Developers, I think, use Docker in a similar manner:
Developers, I think, use Docker in a similar manner
Example:
Web server + Language packages for easy testing
Developers, I think, use Docker in a similar manner
Example:
Web server + Language packages for easy testing
(...but it's still a server)
(Earn Your Docker-ate Degree)
(Abara-ka-
-Dockera!)
\\ ,/ *
\ _,'/_ |
`(")' ,'/
_ _,-H-./ /
\_\_\. /
)" | (
__/ H \__
\ /|\ /
`--'|||`--'
==^==
(Earn Your Docker-ate Degree)
Docker containers can be used in other ways.
(Earn Your Docker-ate Degree)
Docker containers can be used in other ways.
Tangential to, or even unrelated to Servers and Services
Docker Container as a Binary
Basic concept:
Small, Single-purpose Docker container used to accomplish one task on linked containers
Docker Container as a Binary
Examples:
- Backups
- Migrations
- Monitoring
- Maintenance
Docker Container as a Binary
*Consider this:
FROM centos:centos7
MAINTAINER Chris Collins <collins.christopher@gmail.com>
RUN yum install -y mariadb && yum clean all
RUN echo -e '\n\
#!/bin/bash\n\
set -x \n\
USER=$(awk -F: "/USER/ {print $2}" /secret/dbcreds.yml)\n\
PASS=$(awk -F: "/PASS/ {print $2}" /secret/dbcreds.yml)\n\
HOST=$DATABASE_PORT_3306_TCP_ADDR\n\
\n\
mysqldump --all-databases -u${USER} -p{$PASS} -h${HOST}> /backup/$(date "+%Y%m%d")\n\
' >> /backup.sh
ENTRYPOINT [ "bash", "/backup.sh" ]
Docker Container as a Binary
Run with:
docker run --link datbase:database -v /srv/backups:/backups --rm -it do_backups
- dumps a mysql backup to /srv/backups on the host
- can be run linked to dozens, hundreds of MySQL containers
- removes the need for cron, backup scripts, mounted volumes, etc from MySQL container
Docker Container as a Binary
Consider this:
FROM centos:centos7
MAINTAINER Chris Collins <collins.christopher@gmail.com>
RUN yum install -y logrotate
RUN echo -e "\
/var/log/*/*log {\n\
rotate 7\n\
daily\n\
compress\n\
delaycompress\n\
copytruncate\n\
}\n\
" >> /logrotate.conf
ENTRYPOINT ["logrotate", "-f", "/logrotate.conf"]
Docker Container as a Binary
Run with:
docker run --volumes-from web --rm -it logrotate
- connects to "web"; rotates all logs
- as before, is generic; can run on any linked container
- removes the need for cron, logrotate on any linked containers
Helper Containers
Basic concept:
Reduce complexity of Server (or Service) containers by pre-configuring them!
Helper Containers
Consider this:
FROM centos:centos7
MAINTAINER Chris Collins <collins.christopher@gmail.com>
RUN yum install -y mariadb-server && yum clean all
EXPOSE 3306
ENTRYPOINT ["/usr/bin/mysqld_safe"]
A super-simple MySQL container. Easy to maintain. Single job.
Question:
What would happen if you ran this container?
Helper Containers
Answer:
Nothing. Nada. Zilch.
MySQL is not configured, no users, no initialized databases. It runs, and dies.
Helper Containers
Answer:
Nothing. Nada. Zilch.
MySQL is not configured, no users, no initialized databases. It runs, and dies.
(...like a sad little mayfly)
Helper Containers
But link a data container and run a helper container first (and just once!):
/usr/bin/mysql_install_db --datadir=${DATADIR} --user=mysql | tee $MYSQL_LOGFILE
chown -R mysql:mysql "${DATADIR}"
chmod 0755 "${DATADIR}"
/usr/bin/mysqld_safe |tee $MYSQL_LOGFILE &
sleep 5s && \
mysql -u root -e "CREATE DATABASE ${DB_NAME};" \
|| f_err "Unable to create database"
mysql -u root -e "GRANT ALL PRIVILEGES on *.* to 'backup'@'%' IDENTIFIED BY \"${BACKUP_PASS}\";" \
|| f_err "Unable to setup backup user"
mysql -u root -e "GRANT ALL PRIVILEGES on ${DB_NAME}.* to 'root'@'%' IDENTIFIED BY \"${ROOT_PASS}\";" \
|| f_err "Unable to setup root user"
# MAKE SURE THIS ONE IS LAST, OR WE'LL HAVE TO PASS THE ROOT PW EVERY TIME
mysql -u root -e "UPDATE mysql.user SET Password=PASSWORD(\"${ROOT_PASS}\") WHERE User='root'; FLUSH PRIVILEGES" \
|| f_err "Unable to set root user password"
Helper Containers
New answer:
Fully functioning MySQL database container
- lightweight
- easy to maintain
- instant startup
- no extra files or pre-configuration
- no need for "has this been done yet" checks
- no complicated bash startup scripts, etc.
- can be started, restarted, built, rebuilt
Multi-run Images
Basic concept:
Build an image twice - once to configure, and once to finalize
Multi-run Images
Real World (gasp!) example:
Fail-over DNS server in a Docker container
- requires up-to-date named.conf
- named.conf generated by ruby script that queries DNS servers
- updates take 15+ minutes, so use as a rapid fail-over not so helpful
Multi-run Images
Solution:
Build the Docker image every 4 hours
Multi-run Images
Solution:
Build the Docker image every 4 hours
New Problem:
Build server doesn't have Ruby version/gems required to run named.conf gen. script
Multi-run Images
Solution:
Build the Docker image every 4 hours
New Problem:
Build server doesn't have Ruby version/gems required to run named.conf gen. script
(...and I don't want it to)
Multi-run Images
New Solution:
Build the Docker image every 4 hours & let if configure ITSELF
Multi-run Images
Consider this:
FROM centos:7
MAINTAINER Drew Stinnett <drews@duke.edu>
ENV BINDPKGS bind bind-utils
ENV DEBUGPKGS net-tools
ENV RUBYPKGS rubygems ruby-devel gcc zlib-devel libxml2-devel tar patch
ENV GEMS netaddr cog-dukereg bundler
RUN yum -y install $BINDPKGS $DEBUGPKGS $RUBYPKGS
RUN yum -y groupinstall "Development Tools" ; yum clean all
RUN gem sources -a https://gems-internal.oit.duke.edu/
RUN gem install $GEMS
ADD named.conf /etc/named.conf ### DUMMY NAMED FILE ###
RUN chown named /etc/named.conf
RUN mkdir -p /zones/data/{internal,external}
RUN mkdir -p /var/log/named
RUN chown -R named /var/named /zones /var/log/named
EXPOSE 53
CMD ["/usr/sbin/named","-u", "named", "-g"]
Multi-run Images
Build the image then run with:
docker run -v $(pwd):/srv -it dns-auth /srv/generate_named.rb > /srv/named.conf
- $pwd has the generate_named.rb script
- generate_named.rb script generates real named.conf file and dumps it back out to $pwd
Then, build the image again.
This time the real named.conf is copied into the image, and it can be launched wherever with the latest version.
Build and Install
Basic concept:
Docker as a build environment
(You're already doing this - esp. Developers.)
Build and Install
Basic concept:
Docker as a build environment
(You're already doing this - esp. Developers.)
Docker is wonderful for building code and testing in a self-contained environment.
Build and Install
Basic concept:
Docker as a build environment
You're already doing this - esp. Developers.
Docker is wonderful for building code and testing in a self-contained environment.
But...
Build and Install
What if it isn't self-contained?
Build and Install
Consider this:
FROM ubuntu:14.10
MAINTAINER Chris Collins <collins.christopher@gmail.com>
ENV DT https://github.com/splintermind/Dwarf-Therapist/archive/v31.0.0.tar.gz
RUN apt-get update && apt-get install -y curl tar gzip \
make g++ qt5-qmake qtbase5-dev qtbase5-dev-tools qtdeclarative5-dev \
texlive-full
RUN mkdir /dt
WORKDIR /dt
RUN curl -L -O $DT
RUN tar -xzf v31.0.0.tar.gz --strip-components=1
RUN qmake -qt=5
RUN make -j1
VOLUME ['/mnt']
["/bin/cp", "-r", "/dt", "/mnt"]
Run with:
docker run -v /usr/sbin:/mnt -it dwarf_therapist
Build and Install
Question:
What did that do?
Build and Install
Answer:
Scary right?
Build and Install
Answer:
But cool!
Build and Install
Question:
Guess who does this?
Build and Install
Answer:
DOCKER!
Build and Install
Answer:
DOCKER!
The Docker folks have a pre-made development environment inside of a Docker image.
The resulting Docker binary is dropped into a directory on the host system for use.
Docker-ception!
Basic concept:
Build a Docker image inside a Docker container
Docker-ception!
Question:
OH DEAR GOD WHY!?
Docker-ception!
Answer:
Because I could.
(Non, Je ne regrette rien)
Docker-ception!
The long Answer:
Working with a Developer -
- had static code that would live inside the image, from Github
- had dynamic content that would live in mounted volumes, from users
- Dev needed to rapidly build and deploy when needed
- I wanted this to work on any server; did not want a registry involved
Docker-ception!
How:
Docker Inside Docker (DIND)
Docker-ception! (DIND)
Docker Inside Docker
...by, SURPRISE!, Jerome Petazzoni ('nsenter' fame, among other stuff)
Docker-ception! (DIND)
Docker Inside Docker
...by, SURPRISE!, Jerome Petazzoni (nsenter fame, among other stuff)
Taken and modified like so:
FROM ubuntu:14.10
MAINTAINER Chris Collins <christopher.collins@duke.edu>
ENV TERM=xterm
ENV DEBIAN_FRONTEND noninteractive
ENV PKGS git docker curl apt-transport-https ca-certificates curl lxc iptables
ENV REPO <url_to_devs_code>
ENV DOCKERFILE <url_to_sub-dockerfile>
RUN apt-get update -qq && apt-get install -qqy $PKGS \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
RUN curl -sSL -o /usr/bin/docker https://get.docker.com/builds/Linux/x86_64/docker-latest
ADD ./wrapdocker /usr/local/bin/wrapdocker
RUN chmod +x /usr/bin/docker
RUN chmod +x /usr/local/bin/wrapdocker
VOLUME /var/lib/docker
VOLUME /tmp
WORKDIR /srv
RUN echo -e '\n\
#!/bin/bash\n\
git clone $DOCKERFILE /srv
git archive --format tar --remote $REPO | tar xz -C /srv --strip-components=1
cd /srv
docker build -t my_image .\n\
docker save myimage > /tmp/myimage.tar\n\
' >> /build_it.sh
ENTRYPOINT ["/usr/local/bin/wrapdocker"]
Docker-ception!
And run:
docker run --privileged -v ~/images:/tmp --rm -it docker_build
root@885ad1955fbf:/build_it.sh
Docker-ception!
- runs Docker inside a container configured with build tools and Dev's code
- builds another image (the real image)
Docker save
's it to the host disk for load
Using Containers to Manage their Hosts
Basic concept:
Provide a container mount points and/or privileged access to manage its host
Using Containers to Manage their Hosts
Consider this:
docker run -it centos:centos7 sh -c "cat /proc/sys/vm/swappiness"
60
docker run --privileged -it centos:centos7 sysctl -w vm.swappiness=65
Swappiness of the host is adjusted inside a container.
Question:
But why?
Using Containers to Manage their Hosts
Answer:
AUTOMATION! THE CLOUD! And, ...stuff!
You don't need to have direct access to the host to manage it.
- cloud hosts w/remote Docker API (--tlsverify, etc)
- hosts are throwaway, ephemeral
- need to make a change? Fire up your Docker management tool (docker-compose, fig, etc) and do it!
Using Containers to Manage their Hosts
Consider this:
docker run --privileged -v /proc/mounts:/srv/mounts:ro -it centos:centos7 sh -c "cat /srv/mounts"
The host's mount points are exposed to the container.
Question:
But why?
Using Containers to Manage their Hosts
Answer:
Remote monitoring!
- Nagios
- Cacti
- Logstash Forwarder
- Your own scripts
- etc..
Attach one to every host for instant monitoring/trending - no need to install or configure any packages on the host.
Using Containers to Manage their Hosts
Example of this in the wild:
Google CAdvisor (https://github.com/google/cadvisor)
Monitors the host and container usage, and provides a web UI and API for extracting the data.
sudo docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
google/cadvisor:latest
Containers as a Binary:
Docker Development Environment:
Docker In Docker:
More with Privileged Containers:
- https://jpetazzo.github.io/2014/06/23/docker-ssh-considered-evil/
- https://developerblog.redhat.com/2014/11/06/introducing-a-super-privileged-container-concept/
Awesome Wizard Ascii Art:
( Docker, Docker,
No toil, no trouble. )
\
\ ( Man Chris is bad at rhyming...sheesh.)
\ /
\ / .
\ /^\ .
\ /\ "V"
/__\ I O o
//..\\ I .
\].`[/ I
/l\/j\ (] . O
/. ~~ ,\/I .
\\L__j^\/I o
\/--v} I o .
| | I _________
| | I c(` ')o
| l I \. ,/
_/j L l\_! _//^---^\\_
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~