#206 Docker 极速入门教程01 - 基本概念和操作

序言

为什么写这个系列

我加入了一家以 Docker 为技术栈核心的公司,如果走出去说自己不会 Docker,就显得有点不合适了。早在大三的时候就已经听说 Docker 技术的火爆,只是当时一心研究 iOS,并没有对此技术有太多在意,到了现在已经不得不研究了。

实习的这几个月,做的事情比较多,每周只能花很少的时间来了解 Docker 这一门技术,这也是我需要花很长时间才能完成这个系列的原因。网上关于 Docker 的资源、教程已经数不胜数,为什么我还要再写这样一个系列。这里面的原因有以下几点:

  1. 资源再多教程再多,也是别人的。别人写出来的东西是按照别人的思路进行,随着 Docker 技术的发展,我在学习 Docker 这门技术的过程中,发现了当下其实有更好更快捷的路径从新手直接入门整套技术;
  2. 自己写成了文章之后,才能够发现自己对这门技术究竟还有那些不懂不明白的地方;
  3. 装逼

为什么读这个系列

这个系列与其他网上的资源相比有以下几个特点:

  1. 只适用于有 Linux 基本基础的人,有很多教程都尝试向一些 Linux 基础薄弱的人由浅至深介绍 Docker,但实际上他们花了很大篇幅在介绍 Linux 本身上,却忽略了很多 Docker 的重要特性。
  2. 高速,无废话。Docker 的命令错综复杂,很多的书籍、教程反复针对同一个命令反复介绍,废话奇多。读者需要从中甄别这些无用信息,从而浪费大量时间。

好了,说了不废话还是废话了这么长,开始吧。

建立以 Docker 为核心的概念

容器技术与 Docker 架构

容器通过对操作系统的资源访问进行限制,构建成独立的资源池,让应用运行在一个相对隔离的空间里,同时容器间也可以进行通信。容器技术对比虚拟化技术,容器比虚拟化更轻量级,对资源的消耗小很多。容器操作也更快捷,启动和停止都要比虚拟机快。但Docker容器需要与主机共享操作系统内核,不能像虚拟机那样运行独立的内核。

Docker 则是一个基于 Linux 容器(LXC, Linux Container) 技术构建的容器引擎。Docker 支持将应用打包进一个可以移植的容器中,重新定义了应用开发,测试,部署上线的过程。

使用 Docker,可以快速构建一个应用程序服务器、一个消息总线、一个持续集成测试环境,升值为生产或开发快速复制一套复杂的应用程序栈,可以说是让开发者成为 DevOps 的必备技能之一。

Docker 是一个 C/S 架构的程序,Docker 客户端通过向守护进程发出请求,守护进程和 Docker 容器将请求处理完成后返回响应的结果。由于 Docker 是基于 LXC 产生的,因此在其他(Mac/Windows)上不具备这样的技术时,Docker 依然能够运行则是得益于一个虚拟的宿主机,因此整个 Docker 的架构在 Linux 和其他平台上的架构略有不同,但随着如今 Docker 技术的发展,作为 Docker 的用户,我们完全不需要操心这一切,只需心中有下图即可:

此外,Docker 提供了一个命令行工具及一整套 RESTful API 让用户与守护进程进行交互,也就是我常说的 Docker API,这使得我们能够基于 Docker 来开发 Docker 相关的应用。

学习 Docker 需要先在脑子里建立三大基本概念,分别是:仓库、镜像、容器。

仓库(Registry)

仓库的概念和 git 里的仓库几乎完全一样。一个 Docker 仓库就相当于一个 Git 的代码仓库。DockerHub 的地位就如同 GitHub,用于托管和保存用户的镜像,因此用户可以在 DockerHub 上注册账号,管理或开源自己的镜像。

镜像(Image)

镜像是构建 Docker 的基础,就如同操作系统安装的 .iso 镜像一样,Docker 镜像就是这种类似物。镜像通过 Union 文件系统产生了层式的结构,从最基础的镜像,像盖房子一样一层层堆叠,从而完成整个镜像的构建。

容器(Container)

容器是从 Docker 镜像创建运行出来的一个实例(Instance),可以理解为一个虚拟的 Linux 环境。Docker 容器如同虚拟机,支持启动、停止、删除。每个容器之间互相隔离,隔离性弱于虚拟机。

隔离的效果由 CGroupsNamespaces 实现,CGroups (Control Group, Linux 内核特性之一) 对 CPU、内存、磁盘资源等访问进行限制,而 Namespaces 提供了环境的隔离。

安装 Docker

安装 Docker 的方法在现在已经变得非常的简单了,这里不再叙述,下面是各个平台的安装方法:

值得一提的是,现在(Docker v1.12) Mac 上的 Docker 已经不再需要使用 Docker ToolBox 了,只需要下载 Docker for Mac,就能够在 命令行工具中使用了:

基本操作

首先要获得一个镜像,我们才能开始 Docker 的相关学习。

1
2
3
$ docker images           # 查看当前镜像
$ docker search ubuntu # 搜索镜像
$ docker pull ubuntu # 拉取一个镜像

拿到镜像后,我们可以开始进行一些基本的操作了。

1
2
3
4
5
6
7
8
$ # 运行 docker 容器
$ docker run ubuntu echo "hello docker"
$ # 查看运行的容器列表,
$ # docker 在执行完命令后会主动停止,
$ # 所以使用 -a 参数可以查看到已经停止的容器. 此外, -l 可以查看最后一次启动的容器, -q 只查看容器 ID
$ docker ps
$ # 对于 run 命令可以使用 -it 参数进入 bash 来保持容器运行
$ docker run -i -t ubuntu /bin/bash

docker run-i (interactive) 参数保证了容器中的 STDIN 开启,要让交互式 shell 长期运行,就必须要开启持久的标准输入;-t (tty) 指定让 Docker 创建一个伪 tty 终端。

在 Docker 中,涉及到磁盘、网络、设备等 Linux 特权命令都无法执行,因此我们不能够执行诸如 reboot 之类的命令,可以通过 exit 退出 bash。

如果希望退出后依然保持容器运行,可以使用 Ctrl+pCtrl+q 两组快捷键,然后使用 docker attach 能够再次进入 bash。

1
2
3
$ docker start <id>     # 根据 ID 启动一个容器
$ docker stop <id> # 根据 ID 停止一个容器
$ docker restart <id> # 根据 ID 重启一个容器
1
2
$ docker inspect <id>   # 查看容器或镜像内部信息
$ docker top <id> # 查看容器中运行进程等信息

1
2
$ docker rm  <id>        # 删除容器
$ docker rmi <id> # 删除镜像

初识 Dockerfile

Dockerfile 用于编写一个镜像,下面创建了一个新的 Docker 镜像:

1
2
from ubuntu:latest          # 基于 ubuntu:latest 
ENV HOSTNAME=changkun # 设置 HOSTNAME 环境变量

通过 docker build 构建新镜像:

1
$ docker build -t changkun .

其中 -t changkun 指定了镜像的名字, . 标志从当前目录查找 Dockerfile。

删除我们刚才创建的镜像:

注意: 删除 Docker 镜像时,尽管可以使用 -f 参数强制删除镜像,为了养成良好的运维习惯,应该先使用 docker rm 删除容器后,再删除镜像。

延伸阅读

如果我的文章对你起到了帮助,你可以选择金额不限的捐助,帮助我写出更多的文章。