% vim: spelllang=nl:
\PassOptionsToPackage{dvipsnames}{xcolor}
\documentclass{beamer}

\usetheme{Dresden}
\usecolortheme{whale}

\usepackage{hyperref}
\usepackage[dutch]{babel}
\usepackage{graphicx}
\usepackage{subcaption}

\usepackage{tikz}
\usetikzlibrary{positioning}

\usepackage{minted}
\setminted{fontsize=\scriptsize,tabsize=0,breaklines}
\setmintedinline{fontsize=\small,style=bw}

\title{Docker}
\subtitle{Uit gebruikersperspectief\\\vspace{1cm}\includegraphics[width=.3\linewidth]{moby}}
\author[Camil Staps]{
	Camil Staps\\
	{\footnotesize\href{mailto:info@camilstaps.nl}{info@camilstaps.nl}}
}
\date{11 oktober 2016}

\AtBeginSection[]{
	\begin{frame}{Inhoudsopgave}
		\tableofcontents[currentsection]
	\end{frame}
}

\begin{document}

\pdfinfo{
	/Title (Docker)
	/Author (Camil Staps)
	/Subject (Docker)
	/Keywords (docker, containers, linux)}

\begin{frame}[plain]
	\maketitle
\end{frame}

\begin{frame}{Inhoudsopgave}
	\tableofcontents
\end{frame}

\section{Introductie}
\begin{frame}{Wat is Docker}
	\begin{itemize}
		\item Virtualisatie
		\item Lightweight
		\item Compleet besturingssysteem in \'e\'en bestand beschrijven
		\item Secure by default
	\end{itemize}
\end{frame}

\begin{frame}{Containers vs. Virtual Machines}
	\tikzset{rm/.style={draw=red,text=red}}
	\tikzset{ad/.style={draw=Green,text=Green}}
	\begin{minipage}[b]{.49\linewidth}
		\begin{figure}
			\scriptsize
			\begin{tikzpicture}[
					node distance=2pt,
					every node/.style={rectangle,draw,minimum width=5em}]
				\node                    (app1)  {App 1};
				\node[below=of app1]     (bins1) {Bins/libs};
				\node[rm,below=of bins1] (os1)   {Guest OS};

				\node[right=5pt of app1] (app2)  {App 2};
				\node[below=of app2]     (bins2) {Bins/libs};
				\node[rm,below=of bins2] (os2)   {Guest OS};

				\node[right=5pt of app2] (app3)  {App 3};
				\node[below=of app3]     (bins3) {Bins/libs};
				\node[rm,below=of bins3] (os3)   {Guest OS};

				\node[rm,below=of os2,minimum width=15em+11pt] (hyp) {Hypervisor};
				\node[below=of hyp,minimum width=15em+11pt] (hos) {Host OS};
				\node[below=of hos,minimum width=15em+11pt] (inf) {Infrastructure};
			\end{tikzpicture}
			\caption*{Virtual machines}
		\end{figure}
	\end{minipage}
	\begin{minipage}[b]{.49\linewidth}
		\begin{figure}
			\scriptsize
			\begin{tikzpicture}[node distance=2pt,every node/.style={rectangle,draw,minimum width=5em}]
				\node                    (app1)  {App 1};
				\node[below=of app1]     (bins1) {Bins/libs};

				\node[right=5pt of app1] (app2)  {App 2};
				\node[below=of app2]     (bins2) {Bins/libs};

				\node[right=5pt of app2] (app3)  {App 3};
				\node[below=of app3]     (bins3) {Bins/libs};

				\node[ad,below=of bins2,minimum width=15em+11pt] (eng) {(Docker) engine};
				\node[below=of eng,minimum width=15em+11pt] (hos) {Host OS};
				\node[below=of hos,minimum width=15em+11pt] (inf) {Infrastructure};
			\end{tikzpicture}
			\caption*{Containers}
		\end{figure}
	\end{minipage}
\end{frame}

\begin{frame}{Terminologie}
	\begin{description}
		\item[Dockerfile]
			Een bestand dat de omgeving van een app beschrijft.
		\item[Image]
			Een gebouwde \texttt{Dockerfile}.
		\item[Container]
			Een instantie van een image.
	\end{description}
\end{frame}

\section{Dockerfiles}
\begin{frame}[fragile]{Dockerfiles}
	\inputminted{docker}{examples/fortune/Dockerfile}
\end{frame}

\begin{frame}[fragile]{Bouwen}
	\begin{minted}{console}
$ docker build -t fortune .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM debian:jessie
 ---> 1b088884749b
Step 2 : MAINTAINER Camil Staps <info@camilstaps.nl>
 ---> Using cache
 ---> 4311919afa35
Step 3 : RUN apt-get update -qq && apt-get install -qq -y fortune
 ---> Running in 646d62983d27
...
Processing triggers for libc-bin (2.19-18+deb8u4) ...
 ---> 7243ea8162ab
Removing intermediate container 646d62983d27
Step 4 : ENTRYPOINT /usr/games/fortune -s
 ---> Running in 420b0415e53b
 ---> 2d29f9fe8488
Removing intermediate container 420b0415e53b
Successfully built 2d29f9fe8488
	\end{minted}
\end{frame}

\begin{frame}[fragile]{Draaien}
	\begin{minted}{console}
$ docker images
REPOSITORY  TAG     IMAGE ID      CREATED        SIZE
fortune     latest  2d29f9fe8488  5 minutes ago  137.3 MB
<none>      <none>  e466c9f6b26f  6 minutes ago  137.3 MB
<none>      <none>  e3a1930e7832  6 minutes ago  125.1 MB
debian      jessie  1b088884749b  3 months ago   125.1 MB
	\end{minted}
	\pause
	\begin{minted}{console}
$ docker run --name fortune_container fortune
Q:      Why was Stonehenge abandoned?
A:      It wasn't IBM compatible.
	\end{minted}
	\pause
	\begin{minted}{console}
$ docker ps --all
CONTAINER ID  IMAGE    CREATED        STATUS      NAMES
4f496eb1518c  fortune  4 minutes ago  Exited (0)  fortune_container
	\end{minted}
	\pause
	\begin{minted}{console}
$ docker start -a fortune_container
Tonight's the night: Sleep in a eucalyptus tree.
	\end{minted}
\end{frame}

\begin{frame}[fragile]{Daemons}{Dockerfile}
	\begin{minted}{docker}
# Basis: Node.js
FROM node:argon

RUN mkdir -p /usr/src/cloogle-stats
WORKDIR /usr/src/cloogle-stats

# Dependencies
COPY package.json /usr/src/cloogle-stats
RUN npm install

# Eigen code
COPY server.js /usr/src/cloogle-stats
COPY entrypoint.sh /usr/src/cloogle-stats

EXPOSE 31216

ENTRYPOINT ["./entrypoint.sh"]
	\end{minted}
\end{frame}

\begin{frame}[fragile]{Daemons}{entrypoint.sh}
	\begin{minted}{bash}
		#!/bin/bash
		if [[ -f "/srv/ssl/cert.pem" ]] && [[ -f "/srv/ssl/key.pem" ]]; then
		    node server.js \
		        /var/log/cloogle.log \
		        /srv/ssl/cert.pem /srv/ssl/key.pem
		else
		    node server.js \
		        /var/log/cloogle.log
		fi
	\end{minted}
\end{frame}

\begin{frame}[fragile]{Daemons}{Gebruik}
	\begin{minted}{console}
		$ docker build -t stats .
		...
	\end{minted}
	\pause
	\begin{minted}{console}
		$ docker run \
		    --detach \
		    --volume=/local/path/to/cloogle.log:/var/log/cloogle.log \
		    --net=host \
		    --name stats-1 \
		    stats
		a0546b4e0b95e509b412a044a3b1d719a5638d6aad40e11246dac14c6a503e01
	\end{minted}
	\pause
	\begin{minted}{console}
		$ docker ps
		CONTAINER ID  IMAGE  COMMAND            CREATED      STATUS      NAMES
		29a21ce90a8c  stats  "./entrypoint.sh"  5 hours ago  Up 5 hours  stats-1
	\end{minted}

	\vfill
	{\scriptsize\color{gray}
		(Dit voorbeeld kwam uit Cloogle,
		\href{https://github.com/dopefishh/cloogle}{https://github.com/dopefishh/cloogle}.)}
\end{frame}

\section{Toepassingen}
\begin{frame}[fragile]{Compileren in verschillende omgevingen}
	\begin{minted}{console}
		$ docker run --rm -v "$PWD":/usr/src/app -w /usr/src/app gcc:4.9 make
		cc -c -o fuspel.o fuspel.c -Werror -Wall -Wextra -O3 -g
		cc -c -o lex.o lex.c -Werror -Wall -Wextra -O3 -g
		...
		cc -o fuspel fuspel.o ... -Werror -Wall -Wextra -O3 -g
	\end{minted}
	\pause
	\begin{minted}[breaklines]{console}
		$ docker run --rm -v "$PWD":/usr/src/app -w /usr/src/app gcc:5.4 make
		cc -c -o fuspel.o fuspel.c -Werror -Wall -Wextra -O3 -g
		...
		cc -c -o print.o print.c -Werror -Wall -Wextra -O3 -g
		print.c: In function 'print_token':
		print.c:12:11: error: initialization makes integer from pointer without a cast [-Werror=int-conversion]
		  char c = NULL;
	\end{minted}
\end{frame}

\begin{frame}{Continuous Integration}{Idee}
	\begin{itemize}
		\item
			Code onder versiebeheer
		\item
			Draai \mintinline{bash}{make test} op iedere commit
		\item
			Doe dat op allerlei verschillende omgevingen
	\end{itemize}
\end{frame}
\begin{frame}[fragile]{Continuous Integration}{Configuratie - GitLab (\href{https://gitlab.com}{https://gitlab.com})}
	\begin{minted}{yaml}
test:
    image: "camilstaps/clean:2.4-itasks"
    before_script:
        - apt-get update -qq && apt-get install -qq build-essential
    script:
        - make test
	\end{minted}
\end{frame}

\section{Beveiliging}
\begin{frame}{Beveiliging}
	\begin{itemize}
		\item
			Voorbeeld: \mintinline{bash}{--net=host}

			\begin{itemize}
				\item
					Geeft de guest toegang tot de network stack van de host
				\item
					Beter: \emph{expose} poorten
				\item
					Routing regels met iptables
			\end{itemize}

		\item
			Te veel voor nu, zie \href{https://docs.docker.com/engine/security/security/}{https://docs.docker.com/engine/security/security/}
	\end{itemize}
\end{frame}

\section{En verder\dots}
\begin{frame}{Docker Hub}
	\begin{itemize}
		\item
			Heel veel applicaties zijn al \emph{dockerized}
		\item
			Dockerfiles worden gedeeld op de Docker Hub
		\item
			\href{https://hub.docker.com/explore}{https://hub.docker.com/explore}
	\end{itemize}
\end{frame}

\begin{frame}{Docker Compose}
	\begin{itemize}
		\item
			Docker-filosofie: \'e\'en proces per container
		\item
			Probleem: webserver met database?
		\item
			Beschrijf hoe containers van elkaar afhankelijk zijn
		\item
			\href{https://docs.docker.com/compose/}{https://docs.docker.com/compose/}
	\end{itemize}
\end{frame}

\begin{frame}{Swarm}
	\begin{itemize}
		\item
			Maak een netwerk van Docker hosts
		\item
			Verdeel workload over al die hosts
		\item
			Hele netwerk toegankelijk als \'e\'en Docker host
		\item
			\href{https://www.docker.com/products/docker-swarm}{https://www.docker.com/products/docker-swarm}
	\end{itemize}
	\begin{center}
		\includegraphics[width=.3\linewidth]{swarm}
	\end{center}
\end{frame}

\section*{Einde}
\begin{frame}{Einde}
	\begin{itemize}
		\item
			Vragen?

		\vfill
		\item Deze presentatie en voorbeelden:
			\begin{itemize}
				\item \href{https://git.camilstaps.nl/LUGN-Docker.git}{https://git.camilstaps.nl/LUGN-Docker.git}
				\item \href{https://files.camilstaps.nl/LUGN-Docker/docker.pdf}{https://files.camilstaps.nl/LUGN-Docker/docker.pdf}
			\end{itemize}

		\item Meer informatie:
			\begin{itemize}
				\item \href{https://docker.io}{https://docker.io}
				\item \href{https://stackoverflow.com/questions/tagged/docker}{https://stackoverflow.com/questions/tagged/docker}
			\end{itemize}
	\end{itemize}
\end{frame}

\end{document}
