Containers 101

Fırat KÜÇÜK

agenda

  • Show me a container, now!
  • Emulation
  • Virtualization
  • Docker Registry
  • docker compose
  • hello nodejs container
  • docker swarm mode
  • Fundamentals
    • cgroups
    • namespaces
    • union filesystem

A container image is a lightweight, stand-alone, executable package of a piece of software that includes everything needed to run it: code, runtime, system tools, system libraries, settings.

  • Single Process
  • Immutable
  • Access via network

helps us to build

  • microservices
  • CI/CD and DevOps magic
  • easy legacy code migration
  • PaaS
  • serverless

Show me a container, now!

docker run httpd

# finding internal IP address
docker inspect

docker run -d -p 9191:80 httpd

docker stop <container name>
docker rm <container name>

 

docker run -d --name myweb -p 9191:80 httpd

emulation

emulation

emulation

emulation

emulation

emulation

Most Known Emulator: Qemu

https://www.qemu.org/

 

- BIOS

- Network

- Disk

- Display

- Graphic Card

- USB Controller

virtualization

virtualization

Most Known Hypervisors:

- VMWare

- Microsoft HyperV

- Oracle Virtualbox

- Linux KVM

- Xen

virtualization

- Intel VT-X

- AMD-V

virtualization

Type 1 Hypervisor

VMWare ESX

virtualization

Type 1 Hypervisor

Oracle Virtualbox

containers

containers

Most Known Container Engines

- docker

- CRI-O

- podman

- CoreOS rkt

containers

In 2016 container space boomed up. Docker decided to create an API facade called container.d for standardization

docker registry

hub.docker.com

 

for private usage:

gitlab and github have a docker registry

container demo

docker run -d --name my-mysql-5.7 -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql:5.7

 

docker run -d --name my-mysql-5.6 -e MYSQL_ROOT_PASSWORD=my-secret-pw mysql:5.6

Running multiple versions of same applications

container demo

docker run -it --rm --name nyancat 06kellyjac/nyancat

container demo

docker run -d \
  -it \
  --name volume-test \
  -v $HOME/Volumes/nginx:/usr/share/nginx/html \
  -p 80:80 \
  nginx

Persisting the data / Breaking the immutable nature

container demo

docker run --name wordpress-mysql \
    -e MYSQL_ROOT_PASSWORD=abc123 \
    -e MYSQL_USER=wordpress \
    -e MYSQL_PASSWORD=wp123 \
    -e MYSQL_DATABASE=wpdb \
    -d mysql:5.7

Linking containers / DNS Service Discovery

docker run --name wordpress \
    --link wordpress-mysql:mysql \
    -e WORDPRESS_DB_HOST=mysql \
    -e WORDPRESS_DB_USER=wordpress \
    -e WORDPRESS_DB_PASSWORD=wp123 \
    -e WORDPRESS_DB_NAME=wpdb \
    -p 80:80 \
    -d wordpress

creating a container

var http = require('http');

// Create a server object:
http.createServer(function (req, res) {
  res.write('Hello World!'); // Write a response to the client
  res.end(); // End the response
}).listen(8080); // Server listens on port 8080

server.js

Dockerfile

FROM node:10

 

ADD server.js server.js

EXPOSE 8080

 

CMD [ "node", "server.js" ]

Pushing to registry

docker build -t firatkucuk/demo .
docker run -it --rm -p 8080:8080  firatkucuk/demo
docker login
docker push firatkucuk/demo

Inheritance

FROM alpine:3.15

ENV NODE_VERSION 16.14.0

RUN addgroup -g 1000 node \
    && adduser -u 1000 -G node -s /bin/sh -D node \
    && apk add --no-cache \
        libstdc++ \
    && apk add --no-cache --virtual .build-deps \
        curl \

....

docker-compose

docker-compose.yml

Docker swarm

docker-machine create manager
docker-machine create worker1
docker-machine create worker2

docker-machine ssh manager

$ ifconfig
$ docker swarm init --advertise-addr 192.168.99.105
docker-machine ssh worker1
$ docker swarm join ..
docker-machine ssh worker2
$ docker swarm join ..

docker node ls

Creating Services

docker service create --replicas 1 --name demo -p 80:8080 firatkucuk/demo
docker service ls

docker service inspect --pretty demo
docker service ps demo

docker service scale demo=5
docker service ps demo
docker service rm demo

Service Discovery

docker network create --driver overlay --subnet=10.0.9.0/24 my-net


docker service create --network my-net --name wp-mysql -e MYSQL_ROOT_PASSWORD=abc123 -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wordpress -e MYSQL_DATABASE=wordpress -d mysql:5.7

 

docker service create --network my-net --name wordpress -p 80:80 -d wordpress

Reverse Proxy

docker network create --driver overlay --subnet=10.0.10.0/24 --attachable proxy-net

docker service create \
    --name traefik \
    --constraint=node.role==manager \
    --publish 80:80 --publish 8080:8080 \
    --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
    --network proxy-net \
    traefik \
    --docker \
    --docker.swarmmode \
    --docker.domain=traefik \
    --docker.watch \
    --api

Reverse Proxy

docker service create \
    --name test \
    --network proxy-net \
    --label traefik.frontend.rule=Host:temp.domain.com \
    --label traefik.enable=true \
    --label traefik.port=80 \
    nginx

underlying tech

  • cgroups
  • namespaces
  • union file system

cgroups

let evens = [];

for (let i = 0; i < 10000000; i++) {
    if (i % 2 == 0) {
        console.log(i);
        evens.push(i);
    }
}

evennumbers.js

cgroups

sudo cgcreate -a firat:firat -t firat:firat -g memory:evennumbers

sudo cgset -r memory.limit_in_bytes=$((50*1024*1024)) evennumbers
swapoff -a
cgexec -g memory:evennumbers node evennumbers.js

 

# examine via top / turnoff swap

cgroups

ls -al /sys/fs/cgroup/

namespaces

docker run -d --name pid-ns-test --rm busybox sleep 180

docker exec -it pid-ns-test ps

namespaces

docker run -d --name mount-ns-test --rm busybox sleep 180

docker exec -it mount-ns-test ls -al /

namespaces

ip netns add ns1 # Create new namespace

ip netns list # List namespaces

ip link # List physical network devices

 

ip link add veth0 type veth peer name veth1 # creating a virtual p2p network
ip link # List physical network devices

namespaces

ip link set veth1 netns ns1
# assign network device to ns1
ip netns exec ns1 ip link list
# exec physical network list
ifconfig veth0 192.168.5.5/24
# assign IP address to veth0

ip netns exec ns1 ifconfig veth1 192.168.5.10/24 up
# assign IP address to other pair

ping 192.168.5.10

 

namespaces

# p2p communication
ip netns exec ns1 nc -l -p 2000

nc 192.168.5.10 2000

union file system

mkdir fruits
touch fruits/apple
touch fruits/orange
mkdir vegetables
touch vegetables/tomato
mkdir healthy

mount -t aufs -o dirs=fruits/:vegetables/ none healthy/

union file system

docker layered architecture



FROM alpine

 

RUN a && b && c

RUN d

 

Future Topics

  • Advanced Service Discovery
    • consul
    • etcd
  • snapcraft
  • podman / cri-o
  • Kubernetes
  • LXC
  • CoreOS / rancheros

Thank you
Dankuwel

Danke schön

Teşekkürler

Containers 101

By Fırat KÜÇÜK

Containers 101

  • 145