Last active
November 14, 2018 14:50
-
-
Save mattlord/3afe25b23175df7791c4723be4f19ad4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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