Docker introduction

different with virtual machine

CONTAINERS

Containers are an abstraction at the app layer that packages code and dependencies together. Multiple containers can run on the same machine and share the OS kernel with other containers, each running as isolated processes in user space. Containers take up less space than VMs (container images are typically tens of MBs in size), and start almost instantly.

VIRTUAL MACHINES

Virtual machines (VMs) are an abstraction of physical hardware turning one server into many servers. The hypervisor allows multiple VMs to run on a single machine. Each VM includes a full copy of an operating system, one or more apps, necessary binaries and libraries - taking up tens of GBs. VMs can also be slow to boot.

image

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. Available for both Linux and Windows based apps, containerized software will always run the same, regardless of the environment. Containers isolate software from its surroundings, for example differences between development and staging environments and help reduce conflicts between teams running different software on the same infrastructure.

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

Container

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。

Repository

一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:< 标签 > 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

command

pull

docker pull [选项] [Docker Registry 地址 [: 端口号]/] 仓库名 [: 标签] example

docker pull ubuntu:16.04

run

docker run

show the images

docker image ls

delete local image

docker image rm [选项] < 镜像 1> [< 镜像 2> ...]

commit

docker commit [选项] < 容器 ID 或容器名 > [< 仓库名 >[:< 标签 >]]

container operation

下面的命令则启动一个 bash 终端,允许用户进行交互。

$ docker run -t -i ubuntu:14.04 /bin/bash

可以使用 docker container stop 来终止一个运行中的容器

docker container restart 命令会将一个运行态的容器终止,然后再重新启动它。

在使用 -d 参数时,容器启动后会进入后台。

某些时候需要进入容器进行操作,包括使用 docker attach 命令或 docker exec 命令,推荐大家使用 docker exec 命令,原因会在下面说明。

attach 命令 docker attach 是 Docker 自带的命令。下面示例如何使用该命令。

$ docker run -dit ubuntu 243c32535da7d142fb0e6df616a3c3ada0b8ab417937c853a9e1c251f499f550

$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 243c32535da7 ubuntu:latest “/bin/bash” 18 seconds ago Up 17 seconds nostalgic_hypatia

$ docker attach 243c root@243c32535da7:/# 注意: 如果从这个 stdin 中 exit,会导致容器的停止。

exec 命令 -i -t 参数 docker exec 后边可以跟多个参数,这里主要说明 -i -t 参数。

只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。

当 -i -t 参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。

$ docker run -dit ubuntu 69d137adef7a8a689cbcb059e94da5489d3cddd240ff675c640c8d96e84fe1f6

$ docker exec -it 69d1 bash root@69d137adef7a:/# 如果从这个 stdin 中 exit,不会导致容器的停止。这就是为什么推荐大家使用 docker exec 的原因。

导出容器 如果要导出本地某个容器,可以使用 docker export 命令。

$ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7691a814370e ubuntu:14.04 “/bin/bash” 36 hours ago Exited (0) 21 hours ago test $ docker export 7691a814370e > ubuntu.tar 这样将导出容器快照到本地文件。

导入容器快照 可以使用 docker import 从容器快照文件中再导入为镜像,例如

$ cat ubuntu.tar | docker import - test/ubuntu:v1.0 $ docker image ls REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE test/ubuntu v1.0 9d37a6082e97 About a minute ago 171.3 MB 此外,也可以通过指定 URL 或者某个目录来导入,例如

$ docker import http://example.com/exampleimage.tgz example/imagerepo

删除容器 可以使用 docker container rm 来删除一个处于终止状态的容器。例如

$ docker container rm trusting_newton trusting_newton 如果要删除一个运行中的容器,可以添加 -f 参数。Docker 会发送 SIGKILL 信号给容器。

清理所有处于终止状态的容器 用 docker container ls -a 命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。

$ docker container prune

How to use this image

Create a Dockerfile in your Python app project FROM python:3

WORKDIR /usr/src/app

COPY requirements.txt ./ RUN pip install –no-cache-dir -r requirements.txt

COPY . .

CMD [ “python”, “./your-daemon-or-script.py” ] or (if you need to use Python 2):

FROM python:2

WORKDIR /usr/src/app

COPY requirements.txt ./ RUN pip install –no-cache-dir -r requirements.txt

COPY . .

CMD [ “python”, “./your-daemon-or-script.py” ] You can then build and run the Docker image:

$ docker build -t my-python-app . $ docker run -it –rm –name my-running-app my-python-app

Run a single Python script

For many simple, single file projects, you may find it inconvenient to write a complete Dockerfile. In such cases, you can run a Python script by using the Python Docker image directly:

$ docker run -it –rm –name my-running-script -v “$PWD”:/usr/src/myapp -w /usr/src/myapp python:3 python your-daemon-or-script.py or (again, if you need to use Python 2):

$ docker run -it –rm –name my-running-script -v “$PWD”:/usr/src/myapp -w /usr/src/myapp python:2 python your-daemon-or-script.py

error explains

docker: Error response from daemon: Conflict. The container name “/server” is already in use by container “8a72052c5efbcfa5fd0fdef32ddd2413b9f09d3f6b318edb3d72fd76905c3691”. You have to remove (or rename) that container to be able to reuse that name.

That means you have already started a container in the past with the parameter docker run –name registry-v1 ….

You need to delete that first before you can re-create a container with the same name with docker rm registry-v1. When that container is sill running you need to stop it first before you can delete it with docker stop registry-v1. Or simply choose a different name for the new container.

To get a list of existing containers and their names simply invoke docker ps -a.