参考:https://yeasy.gitbook.io/docker_practicehttps://www.bilibili.com/video/BV1YRWse1ESD/?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click

# 一、Docker 简介

# 1.1 什么是 docker

Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

# 1.2 为什么要用 docker

作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。

  • 更高效的利用系统资源

由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。

  • 更快速的启动时间

传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。

  • 一致的运行环境

开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。

  • 持续交付和部署

对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成 (Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署 (Continuous Delivery/Deployment) 系统进行自动部署。

而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。

  • 更轻松的迁移

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。

  • 更轻松的维护和扩展

Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

  • 对比传统虚拟机总结
特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个

# 二、基本概念

# 2.1 镜像

我们都知道,操作系统分为内核用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 Ubuntu:18.04 就包含了完整的一套 Ubuntu 18.04 最小系统的 root 文件系统。Docker 镜像不包含任何动态数据,其内容在构建之后也不会被改变

# 2.2 容器

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

容器的实质是进程,但与直接在宿主执行的进程不同,容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。

# 2.3 仓库

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

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

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

最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并拥有大量的高质量的 官方镜像。

除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。

# 三、使用镜像

# 3.1 获取镜像

从 Docker 镜像仓库获取镜像的命令是 docker pull。其命令格式为:

$ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
  • 具体的选项可以通过 docker pull --help 命令看到

  • Docker 镜像仓库地址:地址的格式一般是 <域名 / IP>[: 端口号]。默认地址是 Docker Hub (docker.io)。

  • 仓库名:仓库名是两段式名称,即 <用户名>/< 软件名 >。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。

(base) ember@ember-Victus-by-HP-Laptop:~$ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
7c457f213c76: Pull complete 
Digest: sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04

# 3.2 列出镜像

要想列出已经下载下来的镜像,可以使用 docker image ls 或者 docker images 命令。

(base) ember@ember-Victus-by-HP-Laptop:~$ docker images
REPOSITORY        TAG       IMAGE ID       CREATED         SIZE
pytorch/pytorch   latest    bbb948040751   8 months ago    7.6GB
ubuntu            18.04     f9a80a55f492   16 months ago   63.2MB
hello-world       latest    d2c94e258dcb   17 months ago   13.3kB
(base) ember@ember-Victus-by-HP-Laptop:~$ docker image ls
REPOSITORY        TAG       IMAGE ID       CREATED         SIZE
pytorch/pytorch   latest    bbb948040751   8 months ago    7.6GB
ubuntu            18.04     f9a80a55f492   16 months ago   63.2MB
hello-world       latest    d2c94e258dcb   17 months ago   13.3kB
(base) ember@ember-Victus-by-HP-Laptop:~$

列表包含了 仓库名、标签、镜像 ID、创建时间 以及 所占用的空间。

其他显示 docker 镜像的命令:

docker system df # 查看镜像、容器、数据卷所占用的空间
docker image ls ubuntu # 根据仓库名列出镜像
docker image ls ubuntu:18.04 #列出特定的某个镜像

# 3.3 运行镜像

有了镜像后,我们就能够以这个镜像为基础启动并运行一个容器。以上面的 ubuntu:18.04 为例,如果我们打算启动里面的 bash 并且进行交互式操作的话,可以执行下面的命令。

(base) ember@ember-Victus-by-HP-Laptop:~$ docker run -it --rm ubuntu:18.04 bash
root@e9a46d9a85a7:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.6 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.6 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
root@e9a46d9a85a7:/# exit
exit
(base) ember@ember-Victus-by-HP-Laptop:~$

docker run 就是运行容器的命令,主要使用到的参数如下

  • -it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。

  • –rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 --rm 可以避免浪费空间。

  • ubuntu:18.04:这是指用 ubuntu:18.04 镜像为基础来启动容器。

  • bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。

进入容器后,我们可以在 Shell 下操作,执行任何所需的命令。这里,我们执行了 cat /etc/os-release,这是 Linux 常用的查看当前系统版本的命令,从返回的结果可以看到容器内是 Ubuntu 18.04.1 LTS 系统。

最后我们通过 exit 退出了这个容器。

# 3.4 删除镜像

如果要删除本地的镜像,可以使用 docker image rm 命令,其格式为:

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

其中,<镜像> 可以是 镜像短 ID、镜像长 ID、镜像名 或者 镜像摘要。我们可以用镜像的完整 ID,也称为长 ID,来删除镜像。使用脚本的时候可能会用长 ID,但是人工输入就太累了,所以更多的时候是用短 ID 来删除镜像。docker image ls 默认列出的就已经是短 ID 了,一般取前 3 个字符以上,只要足够区分于别的镜像就可以了。

docker image rm 501 # 使用短 ID 来删除镜像
docker image rm centos # 使用镜像名 & lt; 仓库名 >:< 标签 > 来删除镜像

# 3.5 制作镜像

(1) docker commit

todo

(2) Dockerfile

todo

# 四、操作容器

# 4.1 启动容器

启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(exited)的容器重新启动。

(1)新建并启动

所需要的命令主要为 docker run

例如,下面的命令输出一个 “Hello World”,之后终止容器。

(base) ember@ember-Victus-by-HP-Laptop:~$ docker run ubuntu:18.04 /bin/echo 'Hello world'
Hello world

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

(base) ember@ember-Victus-by-HP-Laptop:~$ docker run ubuntu:18.04 /bin/echo 'Hello world'
Hello world
(base) ember@ember-Victus-by-HP-Laptop:~$ docker run -it ubuntu:18.04 bash
root@c28d053628f4:/# pwd
/
root@c28d053628f4:/# ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:

  • 检查本地是否存在指定的镜像,不存在就从 registry 下载

  • 利用镜像创建并启动一个容器

  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层

  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去

  • 从地址池配置一个 ip 地址给容器

  • 执行用户指定的应用程序

  • 执行完毕后容器被终止

(2)启动已终止的容器

可以利用 docker container start 命令,直接将一个已经终止(exited)的容器启动运行。

# 4.2 查看正在运行中的容器

可以通过 docker container ls 或者 docker ps 命令来查看容器信息。不添加 -a 参数表示仅查询正在运行的容器,添加 -a 参数表示查询所有容器。

(base) ember@ember-Victus-by-HP-Laptop:~$ docker container ls
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
f46a0966d2f0   ubuntu    "/bin/bash"   2 minutes ago   Up 2 minutes             pedantic_ride
(base) ember@ember-Victus-by-HP-Laptop:~$ docker container ls -a
CONTAINER ID   IMAGE                    COMMAND                   CREATED              STATUS                          PORTS     NAMES
f46a0966d2f0   ubuntu                   "/bin/bash"               35 seconds ago       Up 34 seconds                             pedantic_ride
2017ea1579ba   ubuntu                   "bash"                    About a minute ago   Exited (0) About a minute ago             heuristic_ritchie
a6ebe91f0963   ubuntu                   "bash"                    About a minute ago   Exited (0) About a minute ago             funny_ganguly
1ea1d2fdc98f   ubuntu                   "/bin/bash"               About a minute ago   Exited (0) About a minute ago             fervent_antonelli
8a22936923b9   ubuntu                   "/bin/bash"               3 minutes ago        Exited (0) 2 minutes ago                  keen_galois
42ef1554542d   ubuntu                   "bash"                    4 minutes ago        Exited (0) 4 minutes ago                  affectionate_torvalds
af4b52cb7f4d   ubuntu                   "/bin/bash"               4 minutes ago        Exited (0) 4 minutes ago                  modest_ritchie
9004e2682944   ubuntu                   "/bin/bash"               29 minutes ago       Exited (0) 25 minutes ago                 suspicious_shockley
f2ee1fb9dbd3   ubuntu:18.04             "/bin/echo 'Hello wo…"   36 minutes ago       Exited (0) 36 minutes ago                 focused_ride
9de4edc03c66   ubuntu:18.04             "/bin/echo 'Hello wo…"   37 minutes ago       Exited (0) 37 minutes ago                 loving_poincare
c28d053628f4   ubuntu:18.04             "bash"                    40 minutes ago       Exited (0) 37 minutes ago                 nifty_diffie
482b8943345d   ubuntu:18.04             "/bin/echo 'Hello wo…"   41 minutes ago       Exited (0) 41 minutes ago                 agitated_galois
e56c41136583   hello-world              "/hello"                  2 hours ago          Exited (0) 2 hours ago                    vibrant_carver
066f72347a3b   pytorch/pytorch          "bash"                    3 days ago           Exited (0) 3 days ago                     dazzling_poitras
a1d4426c8152   bbb948040751             "/bin/bash"               11 days ago          Exited (137) 11 days ago                  confident_edison
51dd9da96e61   bbb948040751             "/bin/bash"               11 days ago          Exited (0) 11 days ago                    nervous_williamson
9c03918a1e27   pytorch/pytorch:latest   "/bin/bash"               12 days ago          Exited (0) 12 days ago                    test

# 4.3 守护态运行

更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 -d 参数来实现。下面举两个例子来说明一下。

如果不使用 -d 参数运行容器。

(base) ember@ember-Victus-by-HP-Laptop:~$ docker run ubuntu:18.04 /bin/echo 'Hello world'
Hello world

容器会把输出的结果 (STDOUT) 打印到宿主机上面。如果使用了 -d 参数运行容器。

(base) ember@ember-Victus-by-HP-Laptop:~$ docker run -d ubuntu:18.04 /bin/echo 'Hello world'
f2ee1fb9dbd3936b7cdc2e7dac5a53e86e5e8122acb0dcef43ba4fc47ea6ccb6
(base) ember@ember-Victus-by-HP-Laptop:~$ docker logs f2ee1fb9dbd3936b7cdc2e7dac5a53e86e5e8122acb0dcef43ba4fc47ea6ccb6
Hello world

此时容器会在后台运行并不会把输出的结果 (STDOUT) 打印到宿主机上面 (输出结果可以用 docker logs 查看)。

# 4.4 进入容器

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

某些时候需要进入容器进行操作,包括使用 docker attach 命令或 docker exec 命令,推荐使用 docker exec 命令。

(1) attach 命令

(base) ember@ember-Victus-by-HP-Laptop:~$ docker run -dit ubuntu
9004e2682944ba4750772867e417a04348f1ff8b4bd8f83e629ef2052bf66844
(base) ember@ember-Victus-by-HP-Laptop:~$ docker container ls
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
9004e2682944   ubuntu    "/bin/bash"   49 seconds ago   Up 48 seconds             suspicious_shockley
(base) ember@ember-Victus-by-HP-Laptop:~$ docker attach 9004
root@9004e2682944:/# exit
exit
(base) ember@ember-Victus-by-HP-Laptop:~$ docker container ls
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

注意: 如果从这个 stdin 中 exit ,会导致容器的停止。

注:标准输入文件(stdin),通常对应终端的键盘;标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应终端的屏幕。

(2) exec 命令

(base) ember@ember-Victus-by-HP-Laptop:~$ docker run -dit ubuntu
7d49eb33ae2cca32be243690101b7640b312dee06f76f7fb083970410ccb0c76
(base) ember@ember-Victus-by-HP-Laptop:~$ docker container ls
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
7d49eb33ae2c   ubuntu    "/bin/bash"   7 seconds ago   Up 7 seconds             modest_saha
(base) ember@ember-Victus-by-HP-Laptop:~$ docker exec -it 7d49 bash
root@7d49eb33ae2c:/# exit
exit
(base) ember@ember-Victus-by-HP-Laptop:~$ docker container ls 
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
7d49eb33ae2c   ubuntu    "/bin/bash"   3 minutes ago   Up 3 minutes             modest_saha

如果从这个 stdin 中 exit ,不会导致容器的停止。这就是为什么推荐使用 docker exec 的原因。

# 4.5 停止容器

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

此外,当 Docker 容器中指定的应用终结时,容器也自动终止。

例如对于上一章节中只启动了一个终端的容器,用户通过 exit 命令或 Ctrl+d 来退出终端时,所创建的容器立刻终止。

终止状态的容器可以用 docker container ls -a 命令看到。例如

(base) ember@ember-Victus-by-HP-Laptop:~$ docker container ls -a
CONTAINER ID   IMAGE                    COMMAND                   CREATED             STATUS                         PORTS     NAMES
f2ee1fb9dbd3   ubuntu:18.04             "/bin/echo 'Hello wo…"   3 minutes ago       Exited (0) 3 minutes ago                 focused_ride
9de4edc03c66   ubuntu:18.04             "/bin/echo 'Hello wo…"   4 minutes ago       Exited (0) 4 minutes ago                 loving_poincare
c28d053628f4   ubuntu:18.04             "bash"                    8 minutes ago       Exited (0) 4 minutes ago                 nifty_diffie
482b8943345d   ubuntu:18.04             "/bin/echo 'Hello wo…"   9 minutes ago       Exited (0) 9 minutes ago                 agitated_galois
e56c41136583   hello-world              "/hello"                  About an hour ago   Exited (0) About an hour ago             vibrant_carver
066f72347a3b   pytorch/pytorch          "bash"                    3 days ago          Exited (0) 3 days ago                    dazzling_poitras
a1d4426c8152   bbb948040751             "/bin/bash"               11 days ago         Exited (137) 11 days ago                 confident_edison
51dd9da96e61   bbb948040751             "/bin/bash"               11 days ago         Exited (0) 11 days ago                   nervous_williamson
9c03918a1e27   pytorch/pytorch:latest   "/bin/bash"               12 days ago         Exited (0) 12 days ago                   test

处于终止状态的容器,可以通过 docker container start 命令来重新启动。

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

# 4.6 导出和导入

(1)导出容器

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

(base) ember@ember-Victus-by-HP-Laptop:~$ docker container ls 
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
7d49eb33ae2c   ubuntu    "/bin/bash"   3 minutes ago   Up 3 minutes             modest_saha
(base) ember@ember-Victus-by-HP-Laptop:~$ docker export 7d49 > /home/ember/project/docker/test/ubuntu.tar

这样将导出容器快照到本地文件。

(2)导入容器快照

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

(base) ember@ember-Victus-by-HP-Laptop:~$ cat /home/ember/project/docker/test/ubuntu.tar | docker import - test/ubuntu:v1.0
sha256:819f39358ac6614e347c95e5ab2f948fae449b11e12c045a429a4ff0ad3c2c89
(base) ember@ember-Victus-by-HP-Laptop:~$ docker images
REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
test/ubuntu       v1.0      819f39358ac6   23 seconds ago   78.1MB
ubuntu            latest    59ab366372d5   9 days ago       78.1MB
pytorch/pytorch   latest    bbb948040751   8 months ago     7.6GB
ubuntu            18.04     f9a80a55f492   16 months ago    63.2MB
hello-world       latest    d2c94e258dcb   17 months ago    13.3kB

# 4.7 删除容器

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

(base) ember@ember-Victus-by-HP-Laptop:~$ docker container ls -a
CONTAINER ID   IMAGE                    COMMAND                   CREATED          STATUS                        PORTS     NAMES
7d49eb33ae2c   ubuntu                   "/bin/bash"               12 minutes ago   Exited (137) 11 seconds ago             modest_saha
(base) ember@ember-Victus-by-HP-Laptop:~$ docker container rm 7d49
7d49
(base) ember@ember-Victus-by-HP-Laptop:~$ docker container ls -a
CONTAINER ID   IMAGE                    COMMAND                   CREATED          STATUS                      PORTS     NAMES

# 五、访问仓库

docker search # 查找官方仓库中的镜像
docker pull # 拉取官方镜像
docker push # 将镜像推送到仓库

私有仓库:todo

更新于 阅读次数