Skip to content

Instantly share code, notes, and snippets.

@mattlord
Last active November 14, 2018 14:50
Show Gist options
  • Save mattlord/3afe25b23175df7791c4723be4f19ad4 to your computer and use it in GitHub Desktop.
Save mattlord/3afe25b23175df7791c4723be4f19ad4 to your computer and use it in GitHub Desktop.
# This is the demo that I walked through in this talk: https://www.slideshare.net/mattalord/using-mysql-containers
Let's look at our current Docker environment:
docker version
docker info
docker system df
# as you play around, I would recommend you run this once in a while: docker system prune && docker volume prune
docker stats
docker ps -a
docker network ls
You can see the alpine linux VM setup by Docker which uses a native macOS hypervisor called xhyve:
ps aux | grep linux
# The native macOS docker CLI interacts with the docker engine running in that VM via /var/run/docker.sock
# From now on, let's just use the CLI directly in that VM using the psuedo tty provided
screen /Users/matt/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
# And let's make our console a bit easier to work with
PS1='\h:\W \u\$ '
stty columns 1000
cat /etc/issue
uname -a
cat /etc/os-release
# This is how we can run Linux containers on macOS
Let's create a network for our MySQL containers to work in:
docker network create mysqlnet
Let's create a MySQL 5.7 container:
docker run --net=mysqlnet --name=mysql1 --hostname=mysql1 -e MYSQL_ROOT_PASSWORD="root" -itd mysql/mysql-server
What just happened? Let's look at the image history and container definition to walk through it:
docker history mysql/mysql-server
#open https://github.com/mysql/mysql-docker/tree/mysql-server/5.7
cd ~/git/mysql-docker/5.7
We can see our new mysqld process running there, executing in the containerized environment created by containerd/runC:
docker ps -s
docker images
docker top mysql1
ps aux | grep mysql
ps aux | grep docker
# Notice the containerd/runC container runtime process that's managing our container ID
docker inspect mysql1
We can see the namespaces used with the containerized mysqld process with:
ls -l /proc/$(pidof mysqld)/ns
We can see the control group info with:
cat /proc/$(pidof mysqld)/cgroup
We can get the hash ID of our container in either of the following two ways:
docker inspect mysql1 | jq -r ".[0].Id"
docker ps -a --format "{{.ID}}" --no-trunc --filter "name=mysql1"
We can play with the container runtime, e.g. STDOUT:
echo "Hi There!" >> /var/run/docker/libcontainerd/$(docker inspect mysql1 | jq -r ".[0].Id")/init-stdout
docker logs mysql1
We can see the container files/diff that Docker placed on top of the base image/fs:
ls -l /var/lib/docker/containers/$(docker inspect mysql1 | jq -r ".[0].Id")
We can see the mysql datadir volume:
echo $(docker inspect mysql1 | jq -r ".[0].Mounts[0].Source")
ls -l $(docker inspect mysql1 | jq -r ".[0].Mounts[0].Source")
We can execute commands within the container...
# What happens is that containerd/runC executes our specified command in the same namespaces that containerd/runC has
# created for the mysqld process that's running
docker exec -it mysql1 bash
We can then see the files we created for this container (healthcheck.sh etc.):
ls -l /
We can see the PIDs running in this namespace/container:
ls -ld /proc/* | head -2
# One of which is mysqld, the other our shell
ls -ld /proc/* | head -2 | awk '{print $9"/comm"}' | xargs cat
# PID 1 will typically be the process running inside the container (this PID namespace), mysqld in our case.
# The other is our shell we're in now. So We can echo something to STDERR in our shell, e.g.:
echo "Hi" >> /proc/{PID}/fd/2
exit
And to demonstrate that our container is using a read-only COW base container image--remember it's using the OracleLinux7-slim
image, we can modify something that exists in the base image layer:
docker images
docker diff mysql1
docker exec -it mysql1 rm /etc/bashrc
# Notice that it's simply part of the diff in our container, we didn't change the base image at all
docker diff mysql1
Let's look at the namespaces again....
We can see the namespaces used with the containerized mysqld process with:
ls -l /proc/$(pidof mysqld)/ns
We can exec another shell in the same namespaces but let's detach this time so that it runs in the background
docker exec -d mysql1 bash
Now we can see both processes running in the same "container"
docker top mysql1
Now let's compare the namespaces used for both processes:
ls -l /proc/$(pidof mysqld)/ns
ls -l /proc/$(pidof bash)/ns
# They all match, which is why they're both in the same "container"! It's all an illusion setup by the container
# runtime, utilizing Linux namespaces
At various times a container may stop--the process ends/exits. You can then later restart it, and what happens is that
Docker executes the same entryfile/command again--in our case, because of how we defined the entryfile, skipping all of
the work initially done in the entryfile to initialize mysqld and its datadir--and re-uses the volumes it had in the
namespace. So in the end it's just like bouncing your MySQL service with systemd etc...
Let's send mysqld a SIGTERM to shut it down:
kill -15 $(pidof mysqld)
docker ps -a
It also terminated the shell that we had running "inside of the container" -- using the same namespaces managed by runC
Let's restart it:
docker restart mysql1
Now we have a new mysqld process executing inside of the same containerized environment created by runC (the old shell process is gone):
docker ps -a
docker top mysql1
But it is using the same namespaces from before, so we have the same view of the world, we're in "the same container":
ls -l /proc/$(pidof mysqld)/ns
Let's say that we want to add a file to our container... in our case a common example could be a file that we want to
use with LOAD DATA INFILE
We can see what files we've already added to the R/W layer of our container with:
docker diff mysql1
We can create a new file and copy it into the root directory in our container:
echo "Foo boo bar" > /tmp/test.txt
docker container cp /tmp/test.txt mysql1:/
docker diff mysql1 | grep test
docker exec -it mysql1 ls -l / | grep test
docker exec -it mysql1 cat /test.txt
-------------------------------------------------------------------------
If we want to play with Kubernetes a bit:
minikube start
kubectl get nodes
kubectl get pods
kubectl describe pods/hello-minikube-180744149-rwsm8
# https://github.com/mattlord/Docker-InnoDB-Cluster/blob/master/innodb-cluster.yml
kubectl create -f ./innodb-cluster.yml
kubectl get service innodb-cluster
kubectl get statefulset innodb-cluster
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment