03-Introduction-to-Docker
03-Introduction-to-Docker
Docker
CSCI-GA 2820, Graduate Division, Computer Science
Instructor:
John J Rofrano
Senior Technical Staff Member | DevOps Champion
IBM T.J. Watson Research Center
[email protected] (@JohnRofrano)
1
Introduction to Docker
Cultural Change
Loose Coupling/Binding
Automated Pipeline
RESTful APIs
Everything as Code
Designed to resist failures
Immutable Infrastructure
Test by break / fail fast
DevOps Microservices
AGILITY
Containers Portability
Developer Centric
Ecosystem enabler
Fast startup
@JohnRofrano 2
Introduction to Docker
Cultural Change
Loose Coupling/Binding
Automated Pipeline
RESTful APIs
Everything as Code
Designed to resist failures
Immutable Infrastructure
Test by break / fail fast
DevOps Microservices
Containers Portability
Developer Centric
Ecosystem enabler
Fast startup
@JohnRofrano 3
Introduction to Docker
@JohnRofrano 4
fi
Introduction to Docker
@JohnRofrano 5
Introduction to Docker
The Lure of
Containers
@JohnRofrano
Introduction to Docker
@JohnRofrano 7
Introduction to Docker
+ +
kubernetes
@JohnRofrano 8
Introduction to Docker
Docker Containers
• Docker is a light-weight container service that runs on Linux
• File system overlay
• One Process Space
• One Network Interface
• Shares the Linux kernel with other containers and processes
• Containers encapsulate a run-time environment
• Almost no overhead
• Containers spin up in seconds not minutes like VMs
• Native performance because there is no emulation
• Package only what you need
@JohnRofrano 9
Introduction to Docker
Docker Concepts
@JohnRofrano 10
Introduction to Docker
Benefits of Containers
• Great isolation
• Great manageability
• Container encapsulates implementation
technology
• Efficient resource utilization
• Fast deployment
@JohnRofrano 11
Introduction to Docker
@JohnRofrano 12
Introduction to Docker
Containers
Docker made containers easily
consumable
are not
new
@JohnRofrano 13
Introduction to Docker
• Containers are:
- Linux® processes
- with isolation and resource
confinement cpu cpu cpu cpu
cgroups
memory memory memory memory
- that enable you to run processes processes processes processes
sandboxed applications mounts mounts mounts mounts namespaces
networking networking networking networking
- on a shared host kernel
root filesystem root filesystem root filesystem root filesystem chroot
- using cgroups, namespaces, and
chroot Docker Daemon
OS Kernel
@JohnRofrano 14
Introduction to Docker
• cgroups - Control Groups allow you to control how much resources are allocated to a
process (e.g., memory, cpu. etc.)
• namespaces - control access to what you can see (e.g., processes, mounts, networking, etc.).
What you can't see, you can't access!
• chroot - Allows you to change the root lesystem. This allows the apparent root to be any
linux lesystem whether it be ubuntu, opensuse, redhat or otherwise (i.e., overlay lesystem)
@JohnRofrano 15
fi
fi
fi
Introduction to Docker
@JohnRofrano 16
fi
Introduction to Docker
• A container runs natively on Linux and shares the kernel of the host machine with other
containers
- It runs a discrete process, taking no more memory than any other executable, making it
lightweight
• By contrast, a virtual machine (VM) runs a full-blown “guest” operating system with virtual
access to host resources through a hypervisor
- In general, VMs provide an environment with more resources than most applications need
@JohnRofrano 17
Introduction to Docker
@JohnRofrano 18
Introduction to Docker
Container
Adoption
19
@JohnRofrano
Introduction to Docker
Container
Adoption
has Grown
75% in 2018
@JohnRofrano 20
Introduction to Docker
Container
Adoption
Continues
to Grow
@JohnRofrano 21
Introduction to Docker
Host Density
is 3x Higher
(16 pods vs 5 tasks)
@JohnRofrano 22
Introduction to Docker
Large
Enterprises
are Leading
the Way
@JohnRofrano 23
Introduction to Docker
90% of
Containers are
using
Orchestration
OpenShift
Adoption
Grew 28%
@JohnRofrano 25
Introduction to Docker
The
average
Container
lives for 2
days!
@JohnRofrano 26
Introduction to Docker
@JohnRofrano 27
Introduction to Docker
@JohnRofrano 28
Introduction to Docker
Containers are:
@JohnRofrano 29 https://docs.docker.com/get-started/#images-and-containers
fl
Introduction to Docker
Horizontal Scaling →
@JohnRofrano
30
Introduction to Docker
A B
A B A A A … B
@JohnRofrano 31
Introduction to Docker
Containers in
Practice
32
@JohnRofrano
Introduction to Docker
33
@JohnRofrano
Introduction to Docker
https://docs.docker.com/get-started/#images-and-containers
@JohnRofrano 34
fi
fi
Introduction to Docker
http://hub.docker.com
• Contains 13 million+ Docker images
with almost every software you can
imagine
• Usually “official” images come from
the creator of the software
• Most have documentation on how
to best use them
@JohnRofrano 35
Introduction to Docker
Documentation
• Each image has documentation on
how to use it
• From simply running the container
• To forwarding ports, mapping
storage, etc.
@JohnRofrano 36
Introduction to Docker
@JohnRofrano 37
Introduction to Docker
@JohnRofrano 38
Introduction to Docker Steps for a Fresh Installation of MySQL
1.Adding the MySQL APT Repository
Wordpress First, add the MySQL APT repository to your system's software repository list. Follow these steps:
• Go to the download page for the MySQL APT repository at https://dev.mysql.com/downloads/repo/apt/.
and MySQL
• Select and download the release package for your Linux distribution.
• Install the downloaded release package with the following command, replacing version-specific-package-
name with the name of the downloaded package (preceded by its path, if you are not running the command
inside the folder where the package is):
Installation
For example, for version w.x.y-z of the package, the command is:
Wordpress
and MySQL
with
Docker
40
@JohnRofrano
Introduction to Docker
Docker Compose
WordPress
@JohnRofrano 41
Introduction to Docker
@JohnRofrano 42
Introduction to Docker
version: '3'
Wordpress services:
wordpress:
Example image: wordpress
ports:
- "8080:80"
environment:
- WORDPRESS_DB_HOST=db
networks:
- overlay
depends_on:
- db
db:
image: mysql
volumes:
- wordpress-data:/var/lib/mysql/data
networks:
- overlay
volumes:
wordpress-data:
networks:
overlay:
@JohnRofrano 43
Introduction to Docker
@JohnRofrano 44
Introduction to Docker
@JohnRofrano 45
Introduction to Docker
This is a
Very • Significant time is spent trying to
Powerful make development, test, and
Concept production environments the same
• Docker allow the same container
that is built and tested in
development to run unchanged in
production
• You can literally deploy an entire
environment with a single command
46
@JohnRofrano
Introduction to Docker
Creating Your
Own Docker
Images
47
@JohnRofrano
Introduction to Docker
@JohnRofrano 48
Introduction to Docker $ docker build -t hitcounter:1.0 .
Sending build context to Docker daemon 343kB
Step 1/12 : FROM python:3.11-slim
• The docker build command is used to build an image Step 4/12 : RUN pip install --no-cache-dir -r requirements.txt
---> Running in dfed65002625
@JohnRofrano 50
fi
Introduction to Docker
Base Image
Docker container
(AUFS storage-driver demonstrating whiteout le)
@JohnRofrano 52
fi
Introduction to Docker
• Files from the read-only layers below are visible to the top layer
Docker container
(AUFS storage-driver demonstrating whiteout le)
@JohnRofrano 53
fi
Introduction to Docker
• As you add layers more les become visible at the top layer
Docker container
(AUFS storage-driver demonstrating whiteout le)
@JohnRofrano 54
fi
fi
Introduction to Docker
New Versions
• A new version of file1 is added and it hides the old file1 version
Docker container
(AUFS storage-driver demonstrating whiteout le)
@JohnRofrano 55
fi
Introduction to Docker
White-out Files
• Special les called "white-out" les are used to make les appear to be deleted
X
Image layer 2 file1 file4
Docker container
(AUFS storage-driver demonstrating whiteout le)
@JohnRofrano 56
fi
fi
fi
fi
Introduction to Docker
• Note when you provision with Vagrant how Redis:Alpine reuses Alpine layer:
==> default: Running provisioner: docker...
default: Installing Docker onto machine...
==> default: Pulling Docker images...
==> default: -- Image: alpine:latest
==> default: stdin: is not a tty
==> default: latest: Pulling from library/alpine Alpine layer is being reused
==> default: 3690ec4760f9: Pulling fs layer by Redis:Alpine
==> default: 3690ec4760f9: Verifying Checksum
==> default: 3690ec4760f9: Download complete
==> default: 3690ec4760f9: Pull complete
==> default: Digest: sha256:1354db23ff5478120c980eca1611a51c9f2b88b61f24283ee8200bf9a54f2e5c
==> default: Status: Downloaded newer image for alpine:latest
==> default: -- Image: redis:alpine
==> default: stdin: is not a tty
==> default: alpine: Pulling from library/redis
==> default: 3690ec4760f9: Already exists
==> default: 5e231f7bdf9d: Pulling fs layer
==> default: 5a74fb2950f8: Pulling fs layer
. . .
@JohnRofrano 57
Introduction to Docker
Docker Volumes
@JohnRofrano 58
Introduction to Docker
######################################################################
# Add Redis docker container
######################################################################
config.vm.provision "shell", inline: <<-SHELL
# Prepare Redis data share
sudo mkdir -p /var/lib/redis/data
sudo chown vagrant:vagrant /var/lib/redis/data
SHELL
Volume in container
# Add Redis docker container volume on the host
config.vm.provision "docker" do |d|
d.pull_images "redis:alpine"
d.run "redis:alpine",
args: "--restart=always -d --name redis -h redis -p 6379:6379 -v /var/lib/redis/data:/data"
end
@JohnRofrano 59
Introduction to Docker
Volume in container
@JohnRofrano 60
Introduction to Docker
Docker volume ls
Docker Images
• Minimal images are more secure because they REPOSITORY TAG SIZE
have a smaller attack surface centos latest 202MB
debian stretch-slim 55.3MB
• Don't load anything into an image that you don't debian latest 101MB
need ubuntu
ubuntu
16.04
latest
117MB
86.7MB
• Minimal images load faster python 2-alpine 58.3MB
python 2.7-slim 120MB
• Alpine is only 4.4MB compared to Ubuntu 16.04 python 3.7-alpine 78.2MB
python 3.7-slim 143MB
at 117MB! bitnami/minideb latest 53.7MB
• PostgreSQL Alpine is 71MB vs 228MB alpine
alpine
latest
3.7
4.41MB
4.21MB
postgres alpine 71.6MB
postgres latest 228MB
@JohnRofrano 62
Introduction to Docker
Containers
should be... • Stateless
- All state should be maintained in a Database, Object Store, or
Persistent Volume
• Light Weight
- Only one process per container i.e., Container dies when
process dies
• Immutable
- Do not install an ssh daemon or any other means of entering
the container!
@JohnRofrano 64
Introduction to Docker
@JohnRofrano 65
Introduction to Docker
• You can run Containers from the Images in the Docker Registry (e.g., Docker Hub)
• You can build Docker Images that hold your applications and their dependancies
• You can create Docker Containers from those Docker images to run your applications
• You can share those Docker images via Docker Hub or your own Docker registry
• You can pull those images from the Docker registry to deploy them as Containers on a
server running Docker Engine
• You can even deploy those containers in the IBM Cloud Kubernetes Cloud!
@JohnRofrano 66
Hands-On
@JohnRofrano 67
Introduction to Docker
@JohnRofrano 68
fi
fi
Introduction to Docker
@JohnRofrano 69
Introduction to Docker
@JohnRofrano 70
Introduction to Docker
• Using Visual Studio Code and Docker is the easiest way to prepare for this lab
• Make sure Docker Desktop or Rancher Desktop is running
• Just issue the following commands:
@JohnRofrano 71
Introduction to Docker
@JohnRofrano 72
Introduction to Docker
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
• It checked the local Docker Image cache to see if hello-world was there
@JohnRofrano 74
Introduction to Docker
Docker Images
@JohnRofrano 75
Introduction to Docker
@JohnRofrano 76
Introduction to Docker
• We can use the -a switch to see all containers, even stopped ones
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9a25d7302cf0 hello-world "/hello" 17 minutes ago Exited (0) 17 minutes ago silly_boyd
ab46390b31b7 redis:6-alpine "docker-entrypoint.sh" 29 minutes ago Up 29 minutes 0.0.0.0:6379->6379/tcp redis
@JohnRofrano 77
Introduction to Docker
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9a25d7302cf0 hello-world "/hello" 17 minutes ago Exited (0) 17 minutes ago silly_boyd
ab46390b31b7 redis:alpine "docker-entrypoint.sh" 29 minutes ago Up 29 minutes 0.0.0.0:6379->6379/tcp redis
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ab46390b31b7 redis:alpine "docker-entrypoint.sh" 29 minutes ago Up 29 minutes 0.0.0.0:6379->6379/tcp redis
@JohnRofrano 78
Introduction to Docker
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis alpine 906fffc0e2f4 35 hours ago 20.38 MB
alpine latest baa5d63471ea 39 hours ago 4.803 MB
hello-world latest c54a2cc56cbb 3 months ago 1.848 kB
$ docker rmi c54a2cc56cbb
Untagged: hello-world:latest Remove the image with id “c54a2cc56cbb”
Untagged: hello-world@sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Deleted: sha256:c54a2cc56cbb2f04003c1cd4507e118af7c0d340fe7e2720f70976c4b75237dc
Deleted: sha256:a02596fdd012f22b03af6ad7d11fa590c57507558357b079c3e8cebceb4262d7
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis alpine 906fffc0e2f4 35 hours ago 20.38 MB
alpine latest baa5d63471ea 39 hours ago 4.803 MB
@JohnRofrano 79
Introduction to Docker
Creating
Containers
from Images
80
@JohnRofrano
Introduction to Docker
@JohnRofrano 81
Introduction to Docker
• Docker Hub
• Contains 1000’s of Docker
images with almost every Let’s use nginx to create a web site
software you can imagine
• Usually “of cial” images come
from the creator of the software
• Most have documentation on
how to best use them
@JohnRofrano 82
fi
Introduction to Docker
@JohnRofrano 83
Introduction to Docker
Run as a Daemon
Map port 80 in container Run nginx from local cache or Docker Hub
to 8080 on the Host
@JohnRofrano 84
Introduction to Docker
• Since we don’t have a local nginx image it will be pulled from Docker hub the rst time
@JohnRofrano 85
fi
Introduction to Docker
In A Web browser
Goto http://localhost:8080/
@JohnRofrano 86
Introduction to Docker
Stop a Container
$ docker rm stoic_shaw
stoic_shaw
Remove container “stoic_shaw”
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ab46390b31b7 redis:alpine "docker-entrypoint.sh" 52 minutes ago Up 52 minutes 0.0.0.0:6379->6379/tcp redis
@JohnRofrano 87
Introduction to Docker
@JohnRofrano 88
fi
Introduction to Docker
Goto http://localhost:8080/
@JohnRofrano 89
Introduction to Docker
Dynamic Development
• You can now change the les in that folder and the changes will be re ected in the web
browser
• Try it and see...
• Then stop the container with:
$ docker rm nginx
@JohnRofrano 90
fi
fl
Introduction to Docker
Creating
Containers
from
Dockerfiles
91
@JohnRofrano
Introduction to Docker
Using A Dockerfile
@JohnRofrano 92
fi
Introduction to Docker
FROM nginx:alpine
COPY content /usr/share/nginx/html
@JohnRofrano 93
fi
fi
Introduction to Docker
What is /usr/share/nginx/html?
@JohnRofrano 94
Introduction to Docker
fi
Introduction to Docker
Goto http://localhost:8080/
@JohnRofrano 96
Introduction to Docker
$ docker rm nginx
@JohnRofrano 97
Introduction to Docker
@JohnRofrano 98
Introduction to Docker FROM python:3.11-slim
$ cd /app
$ honcho start
@JohnRofrano 100
Introduction to Docker
Goto http://localhost:8080
@JohnRofrano 101
Introduction to Docker
No counters yet
@JohnRofrano 102
Introduction to Docker
Create a counter
{
"counter": 0,
"name": "foo"
}
@JohnRofrano 103
Introduction to Docker
@JohnRofrano 104
Introduction to Docker
@JohnRofrano 105
Introduction to Docker
$ Ctrl+C
@JohnRofrano 106
Introduction to Docker
@JohnRofrano 107
$ cd /app
Introduction to Docker $ docker build -t hitcounter:1.0 .
• docker images
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hitcounter 1.0 8ac3c707ab08 2 minutes ago 239MB
python 3.9-slim 07ee12a5eb2a 4 days ago 179MB
nginx alpine b6753551581f 4 weeks ago 21.4MB
redis alpine 6f63d037b592 4 weeks ago 29.3MB
alpine latest 965ea09ff2eb 4 weeks ago 5.55MB
$
This is the new hit counter:1.0 image that you just built
@JohnRofrano 109
Introduction to Docker
@JohnRofrano 110
Introduction to Docker
Goto http://localhost:8080
@JohnRofrano 111
Introduction to Docker
What Happened?
@JohnRofrano 112
Introduction to Docker
Where is Redis?
@JohnRofrano 113
Introduction to Docker
Running in a VM
Redis Container
localhost:6379
@JohnRofrano 114
Introduction to Docker
Running in a Container
localhost:6379
local host
@JohnRofrano 115
Introduction to Docker
Solution
localhost:6379
Linkage is performed by name
local host
@JohnRofrano 116
Introduction to Docker
• We can use the --link command to tell lab-docker where redis is:
• We use an environment variable to give our app the new DATABASE_URI
@JohnRofrano 117
Introduction to Docker
Linking Containers
@JohnRofrano 118
Introduction to Docker
Try Again
Goto http://localhost:8080/counters
@JohnRofrano 119
Introduction to Docker
Running Commands
@JohnRofrano 120
Introduction to Docker
Multi-stage Builds
WORKDIR /install
COPY requirements.txt /requirements.txt
RUN pip install --install-option="--prefix=/install" -r /requirements.txt
FROM python:3.11-slim
COPY --from=builder /install /usr/local
WORKDIR /app
COPY src .
Docker Compose
@JohnRofrano 122
Introduction to Docker
docker-compose.yml
version: "3"
services:
web:
build: .
ports:
- "8080:8080"
db:
image: postgres
ports:
- "5432:5432"
@JohnRofrano 123
Introduction to Docker version: '3'
Wordpress services:
wordpress:
Example image: wordpress
ports:
- "8080:80"
networks:
- overlay
restart: always
mysql:
image: mysql
volumes:
- wordpress-data:/var/lib/mysql/data
networks:
- overlay
restart: always
volumes:
wordpress-data:
networks:
@JohnRofrano overlay: 124
version: "3"
Introduction to Docker
services:
app:
Compose build: .
image: hitcounter:1.0
redis:
image: redis:alpine
restart: always
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- web
volumes:
redis-data:
networks:
@JohnRofrano web: 125
Introduction to Docker
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
@JohnRofrano 126
Introduction to Docker
compose Creating
Creating
network "vagrant_web" with the default driver
volume "vagrant_redis-data" with default driver
Creating vagrant_redis_1 ... done
Creating hitcounter ... done
$ docker compose ps
• We can bring
up both Name Command State Ports
---------------------------------------------------------------------------------
containers hitcounter gunicorn --log-level=info ... Up 0.0.0.0:8080->8080/tcp
together: vagrant_redis_1 docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp
@JohnRofrano 127
Introduction to Docker
• docker compose up
• docker compose build
• docker compose start | stop
• docker compose ps
• …and more
@JohnRofrano 128
Introduction to Docker
• If you want to see the commands that create the layers in your docker image you can
docker use the history option
@JohnRofrano 129
Introduction to Docker
@JohnRofrano 132
Introduction to Docker
• We can automatically remove all dangling images with the following command:
Deleted: sha256:3f7a53d3c3a3a64ec79fea01747b97556c276bc851b65b8e24cfb1c2082d5cff
Deleted: sha256:d76a50fd288ec67ec7699bbb4f5b65b9f40b68790d1fb6c96ac39f60dddc146a
Deleted: sha256:56ee01767abea97505cef0646e4172cb18a36f06c4eff070ef09caa47be63564
@JohnRofrano 133
Introduction to Docker
@JohnRofrano 134
Introduction to Docker
• Here are two commands to quickly kill and remove all containers
(remember: "with great power comes great responsibility!)
@JohnRofrano 135
Introduction to Docker
Summary
@JohnRofrano 136
fi
fi