From defd1263bbc1cbf9762ea1badb90681ecf403195 Mon Sep 17 00:00:00 2001 From: Michael Marsh <mmarsh@cs.umd.edu> Date: Wed, 17 Jan 2018 13:58:40 -0500 Subject: [PATCH] more docker tutorial work I'm not sure if I want to get into Dockerfiles. There's already a lot here. --- README | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 161 insertions(+), 9 deletions(-) diff --git a/README b/README index 363f37a..6d05ff2 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ with it. What is docker? You can think of it like a lightweight VM. It's really considerably different, because it uses the host processor, -memory, network stack, etc., without creating virutal hardware. We +memory, network stack, etc., without creating virtual hardware. We can throw around terms like user-level filesystems, process groups, and network namespaces, but the important part is that you can run a self-contained guest Linux OS within another host Linux OS, with @@ -14,8 +14,8 @@ the resources given to it by the host, so it provides some (minimal) level of security. It also means we can start a process from a known-clean state, so we have repeatability. -Exercise 1: Docker Images -========================= +Docker Images +============= Let's start with the concept of an *image*. This is the self-contained guest Linux OS, which is configured to automatically run some process @@ -38,7 +38,7 @@ docker we only want one image, and it's the one with the *tag* When the command completes, try running - docker image list + docker images You should see something like: @@ -54,7 +54,7 @@ We can do a few things with this image, aside from running it. Try the following: docker tag ubuntu:16.04 my_ubuntu - docker image list + docker images Note that we now see the same image ID twice, but with different names. By default, a repository (the tagless part of an image name) @@ -62,7 +62,7 @@ is tagged as "latest" if you don't specify one. Let's try specifying a tag, though: docker tag ubuntu:16.04 foo:bar - docker image list + docker images The results should not be surprising. @@ -71,7 +71,7 @@ it's good to know how to clean these up. Let's get rid of our new tagged images: docker rmi my_ubuntu:latest foo:bar - docker image list + docker images A common problem is that we'll end up reusing an old tag, leaving an image with no repository:tag name. These show up as "<none>:<none>". @@ -83,7 +83,159 @@ For the curious, feel free to read the man pages for awk and xargs. This is not going to be essential information for this course, though. +The commands here are largely from an older version of docker. Now they're +aliases to new-style commands. Here's the mapping: -Exercise 2: Running an Image in a Container -=========================================== +| Old Command | New Command | +| ------------- | ----------------- | +| docker images | docker image list | +| docker pull | docker image pull | +| docker rmi | docker image rm | +| docker tag | docker image tag | + +Running an Image in a Container +=============================== + +Images are all fine and good, but we actually want to use docker to *do* +something, which means we have to run these images. An image runs in a +*container*. The container has system resources allocated to it, and runs +a program or programs that exist in the image. A container runs a single +image, but an image may be running in multiple containers. + +Containers can also be started with various options, such as elevated +privileges, mounted volumes, environment variables, and so on. The most +basic invocation is + + docker run ubuntu:16.04 + +If you run this, you'll find that it pauses for a second or so, and then +returns to the command line. If you want to see running containers, run + + docker ps + +You see headings, but probably no actual containers. Now, try + + docker ps -a + +Now we have something! Here's an example of what you might see: + + CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES + 1b937126d5bc ubuntu:16.04 "/bin/bash" About a minute ago Exited (0) About a minute ago upbeat_archimedes + +Let's parse this out: + + - The container ID is a unique ID, like the image ID we saw before + - The image should be self-explanatory + - The command is what the container ran. In this case, it's just bash + - The created time is when the container was started + - The status tells us that this container exited, and is no longer running + - We have no ports bound, but if we did these would map from local + network ports to network ports on the container + - The names are symbolic names used to refer to this container, and are + synonyms for the container ID + +By default, names are assigned randomly according to the pattern +<adjective>_<scientist> + +We can assign a name to the container, which is often useful: + + docker run --name=bash_test ubuntu:16.04 + +This will behave similarly to the previous command, but if we run + + docker ps -a + +We'll now see our container named "bash_test" along with whatever random name +our first container was assigned. + +Usually, an image is defined to do something useful when run non-interactively. +We can get interactive access to the container, though, as follows: + + docker run -ti ubuntu:16.04 + +We've passed two new options to docker run. The "-t" option allocates a +pseudo-TTY, and the "-i" option makes the container interactive. You should +now have a shell on the container running as root! If you run "docker ps" in +another terminal, you will see that the container status is +"Up <length of time>" + +When you're done playing around in this shell, exit to stop the container. + +At this point, you probably want to get rid of these stopped containers. Run: + + docker rm bash_test + docker ps -a + +You'll still have the two randomly-named containers, but the one named +"bash_test" should no longer be present. Remove the other two, as well. + +We don't have to run the configured program in a container; we can run any +command that's present on the image. Let's see this in action: + + docker run ubuntu:16.04 /bin/date + +That should print the date in the container. It's probably in UTC, while running +/bin/date on your VM should print the date in Eastern US time (EST or EDT). You +can also specify options: + + docker run ubuntu:16.04 ls /var + +Another very useful option is "--rm", which will get rid of the container once +it stops: + + docker run --rm --name="rm_test" ubuntu:16.04 ls /var + +We've once again been using old-style commands, which are aliases: + +| Old Command | New Command | +| ----------- | -------------------- | +| docker run | docker container run | +| docker ps | docker container ls | + + +Stopping a Running Container +============================ + +A container might become unresponsive, or it might be a long-running service +that you want to terminate. You can do this with either of the following: + + docker kill <container> + docker stop <container> + +"stop" is more graceful, trying SIGTERM first, and then SIGKILL. "kill" sends +SIGKILL by default, but this can be overridden on the command line. + +| Old Command | New Command | +| ----------- | --------------------- | +| docker kill | docker container kill | +| docker stop | docker container stop | + + +Removing Stopped Containers +=========================== + +As with images, you'll tend to accumulate lots of stopped containers, unless +you've run them all with the "--rm" option. Fortunately, we can get rid of +these with + + docker rm <container> + +which is now an alias for + + docker container rm <container> + + +Other Options for Running Containers +==================================== + +Here are some useful options you might want to use: + +| Option | Argument | Effect | +| ------ | --------------- | ----------------------------------------- | +| --rm | | removes container after exit | +| -ti | | run interactively with a pTTY | +| -e | <vars> | set environment variables | +| -h | <hostname> | set the container's hostname | +| -p | <hport>:<cport> | map host's <hport> to container's <cport> | +| -v | <hdir>:<cdir> | mount host's <hdir> on <cdir> | -- GitLab