Docker是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业务项目。它基于 Google 公司推出的 Go 语言实现。项目后来加入 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。
Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案,Docker 的基础是 Linux 容器 (LXC) 等技术。在 LCX 的基础上 Docker 进行了进一步的封装,让用户不需要关心容器的管理,使得操作更为简便,用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样。
以下为 Docker 的基本功能使用记录。
0x01 安装 Docker
1. 安装
在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Ubuntu 系统上可以使用这套脚本安装:
2. 镜像加速器
国内访问 Docker Hub 有时会遇到困难,此时可以配置镜像加速器。使用国内云服务商 DaoCloud 提供的加速器服务。
该脚本可以将 –registry-mirror 加入到 Docker 配置文件 /etc/docker/daemon.json 中。适用于 Ubuntu14.04、Debian、CentOS6 、CentOS7、Fedora、Arch Linux、openSUSE Leap 42.1,其他版本可能有细微不同。
重新启动服务。
配置完加速器需要检查是否生效,如果 Docker 版本大于 1.13 或 17.05.0-ce,可以使用以下命令检查。
0x02 镜像
对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:14.04 就包含了完整的一套 Ubuntu 14.04 最小系统的 root 文件系统。
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
1. 获取镜像
从 Docker Registry 获取镜像的命令是 docker pull。其命令格式为:
Docker Registry地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。
仓库名:仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。如:
上面的命令中没有给出 Docker Registry 地址,而镜像名称是 ubuntu:14.04,因此将会获取官方镜像 library/ubuntu 仓库中标签为 14.04 的镜像。
2. 运行容器
使用docker run
根据镜像新建并运行容器。
-it:这是两个参数,-i 是交互式操作,-t 为交互式终端。
–name: 指定新建容器的名称
ubuntu:14.04:指用 ubuntu:14.04 镜像为基础来启动容器。
bash:放在镜像名后的是命令,运行bash 返回交互式 Shell。
进入容器后,可以在 Shell 下操作,执行任何所需的命令。最后可以通过 exit 退出容器。
退出容器后可以使用 docker exec
命令进入容器。
3. 列出镜像
使用docker images
命令可以列出已经下载的镜像。
列表包含了仓库名、标签、镜像 ID、创建时间以及所占用的空间。
4. 保存镜像
当修改容器的文件后,可以使用命令docker diff
查看具体的改动。
在不使用卷的情况下运行一个容器时,任何文件修改都会被记录于容器存储层里。而 Docker 提供的 docker commit
命令可以将容器的存储层保存下来成为镜像,语法格式为:
用下面的命令将容器保存为镜像:
其中 –author 指定修改的作者,而 –message 记录本次修改的内容。
使用 docker commit
意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑箱镜像。在实际应用中使用 Dockerfile 来定制镜像。
5. 删除镜像
如果要删除本地的镜像,可以使用 docker rmi
命令。
0x03 容器
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
1. 启动容器
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
a. 新建并启动
如 0x02 中所示,使用 docker run
启动一个容器。利用这种方式来创建容器时,Docker 在后台运行的标准操作包括:
检查本地是否存在指定的镜像,不存在就从公有仓库下载
利用镜像创建并启动一个容器
分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
从地址池配置一个 ip 地址给容器
执行用户指定的应用程序
执行完毕后容器被终止
b. 启动已终止容器
可以利用docker start
命令,直接将一个已经终止的容器启动运行。
c. 守护态运行
更多的时候,需要让 Docker在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 -d 参数来实现。
2. 终止容器
可以使用 docker stop
来终止一个运行中的容器。
此外,当Docker容器中指定的应用终结时,容器也自动终止。 例如对于只启动了一个终端的容器,用户通过 exit 命令或 Ctrl+d 来退出终端时,所创建的容器立刻终止。
终止状态的容器可以用 docker ps -a 命令看到。
3. 进入容器
当需要进入在后台运行的容器时,可以使用docker attach
命令进行操作。
4. 导出和导入容器
使用 docker export
命令可以导出容器快照到本地文件。
使用docker import
可以将本地快照文件导入为镜像。
5. 删除容器
使用 docker rm
可以删除处于终止状态的容器。如果要删除一个运行中的容器,可以添加 -f 参数。
0x04 数据管理
在容器中管理数据主要有两种方式:数据卷(Data volumes)和数据卷容器(Data volume containers)。
1. 数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,有以下特性:
数据卷可以在容器之间共享和重用
对数据卷的修改会立马生效
对数据卷的更新,不会影响镜像
数据卷默认会一直存在,即使容器被删除
a. 创建数据卷
在用 docker run
命令时,使用 -v 选项可创建一个数据卷并挂载到容器里。下面创建一个名为 testVolume 的容器,并加载一个数据卷到容器的 /Volume 目录。
此外,可以指定挂载一个本地主机的目录到容器中去。本地目录的路径必须是绝对路径,如果目录不存在 Docker 会自动为你创建它。下面将本地主机的 localVolume 目录挂载到容器的 /testVolume 目录。
Docker 挂载数据卷的默认权限是读写,用户也可以通过 :ro 指定为只读。
b. 删除数据卷
数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。
在删除容器的时候使用 docker rm -v
命令可以在删除容器的同时移除数据卷。
|
|
c. 查看数据卷信息
使用docker inspect
命令可以查看容器的详细信息,找到其中有关数据卷的项:
2. 数据卷容器
如果一些持续更新的数据需要在容器之间共享,可以创建数据卷容器。数据卷容器是一个正常的容器,提供数据卷供其它容器挂载。
首先,创建一个名为 dbdata 的数据卷容器:
然后,在其他容器中使用 –volumes-from 来挂载 dbdata 容器中的数据卷。
0x05 网络配置
通过 -P 或 -p 参数进行端口映射可以在外部访问容器中的网络应用。当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。
-p 则可以指定要映射的端口,在一个指定端口上只可以绑定一个容器。
1. 端口映射
使用 hostPort:containerPort
将本地的 6666 端口映射到容器的 6666 端口。此时默认会绑定本地所有接口上的所有地址。
2. 查看映射端口
使用 docker port
可查看当前映射的端口配置,也可以查看绑定的地址。
0x06 其它
Docker守候进程绑定的是一个unix socket,而不是TCP端口。这个套接字默认的属主是root,其他是用户可以使用sudo命令来访问这个套接字文件。因为这个原因,docker服务进程都是以root帐号的身份运行的。
为了避免每次运行docker命令的时候都需要输入sudo,可以创建一个docker用户组,并把相应的用户添加到这个分组里面。当docker进程启动的时候,会设置该套接字可以被docker这个分组的用户读写。这样只要是在docker这个组里面的用户就可以直接执行docker命令了。
操作步骤:
- 使用有sudo权限的帐号登录系统。
创建docker分组,并将相应的用户添加到这个分组里面。
1sudo usermod -aG docker your_username退出,然后重新登录,以便让权限生效。
- 确认你可以直接运行docker命令。1$ docker run hello-world
References:
[1] Docker — 从入门到实践
[2] Docker 入门 & CI/CD实践