第一本Docker书
1. 简介
1.1 Docker简介
- 提供一个简单、轻量的建模方式
- 职责的逻辑分离:开发人员只关心容器运行中的应用程序,运维人员只关心如何管理容器。
- 快速、高效的开发生命周期
- 鼓励面向服务的架构
1.2 Docker组件
核心组件:
- Docker客户端和服务端
- Docker是一个客户-服务器(C/S)架构的程序
- Docker镜像: 基于Union文件系统的一种层式结构,由一系列指令一步一步构建出来。
- Docker容器:基于镜像启动起来的。可以认为,镜像是Docker生命周期中的构建或打包阶段,而容器则是启动或执行阶段。
- Registry:用来保存用户构建的镜像。
1.3 Docker技术组件
包括以下几个部分:
- 一个原生的Linux容器格式,称为libcontainer。libcontainer格式现在是Docker容器的默认格式。
- Linux内核的命名空间(namespace),用于隔离文件系统、进程和网络。
- 文件系统隔离:每个容器有自己的root文件系统。
- 进程隔离:每个容器都运行在自己的进程环境中。
- 网络隔离:容器间的虚拟网络接口和IP地址都是分开的。
- 资源隔离和分组:使用cgroups将CPU和内存之类的资源独立分配给每个Docker容器。
- 写时复制:文件系统分层。
- 日志。
- 交互式shell。
2. 安装Docker
2.1 检查前提条件
- 运行64位CPU架构的计算机,目前Docker不支持32位CPU
- Linux 3.8或更高版本内核
- 内核必须支持一种适合的存储驱动
- Device Manager
- AUFS
- vfs
- btrfs
- 默认存储驱动通常是Device Mapper
ls -l /sys/class/misc/device-mapper
sudo grep device-mapper /proc/devices
- 如果没有device-mapper相关信息,可以尝试加载dm_mod,
sudo modprobe dm_mod
- 内核必须支持并开启
cgroup
和命名空间功能。
2.2 Docker守护进程
安装完Docker后,Docker以root权限运行它的守护进程,来处理普通用户无法完成的操作。docker程序是Docker守护程序的客户端程序,同时需要以root身份运行。
当Docker软件包安装完毕后,默认会立即启动Docker守护进程。守护进程监听 /var/run/docker.sock
这个Unix套接字文件,来获取来自客户端的Docker请求。
如果系统中存在名为docker
的用户组的话,Docker则会将该套接字文件的所有者设置为该用户组。这样,docker
用户组的所有用户都可以直接运行Docker,而无需使用sudo
命令。
3. Docker入门
3.1 确保Docker已经就绪
容器的典型声明周期:创建、管理到停止,直到最终删除。
- 查看docker程序是否存在,功能是否正常:
$ sudo docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 18.05.0-ce
Storage Driver: aufs
Root Dir: /mnt/sda1/var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 0
Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
...
docker info
命令会返回所有容器和镜像的数量、Docker使用的执行驱动和存储驱动以及Docker的基本配置。
3.2 运行第一个容器
使用docker run
命令创建容器,该命令提供了Docker容器的创建到启动的功能。-i
标志保证容器中STDIN是开启的,-t
告诉Docker为要创建的容器分配一个伪tty终端。
$ sudo docker run -i -t ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
a48c500ed24e: Pull complete
1e1de00ff7e1: Pull complete
0330ca45a200: Pull complete
471db38bcfbf: Pull complete
0b4aba487617: Pull complete
Digest: sha256:c8c275751219dadad8fa56b3ac41ca6cb22219ff117ca98fe82b42f24e1ba64e
Status: Downloaded newer image for ubuntu:latest
root@a3865ae60bd6:/#
3.3 容器命名
--name
参数。比如,下面示例命令会创建一个名为test的容器,在很多Docker命令中,我们可以使用容器的名称来替代容器ID,容器名称有助于分辨容器。
容器命名必须是唯一的,如果试图创建两个名称相同的容器,则命令会失败。
$ sudo docker run --name test -i -t ubuntu /bin/bash
3.4 常用命令
- 重新启动已经停止的容器
$ sudo docker start test
- 附着到容器上
$ sudo docker attach test
- 创建守护式容器:守护式容器没有交互式会话,非常适合运行应用程序和服务。
$ sudo docker run --name daemon -d ubuntu /bin/bash -c "while true; do echo hello world; sleep 1; done"
-d
参数表面Docker会将容器放在后台运行。
可以用docker logs
命令获取容器日志:
$ sudo docker logs daemon
$ sudo docker logs -f daemon # 与tail -f命令相似
$ sudo docker logs -ft daemon # 为每条日志加时间戳
$ sudo docker logs --tail 10 daemon # 获取日志的最后10行内容
3.5 查看容器内的进程
$ sudo docker top daemon
该命令执行后,可以看到容器内的所有进程、运行进程的用户及进程ID。
3.6 在容器内部运行进程
可以通过docker exec
命令在容器内部额外启动新进程。
两种进程:
- 后台进程
- 交互进程
3.7 停止守护式容器等
$ sudo docker inspect daemon # 获取更多的容器信息,会对容器进行详细的检查,然后返回配置信息
$ sudo docker stop daemon # 停止容器
$ sudo docker run --restart=always --name daemon -d ubuntu /bin/bash -c "while true; do echo hello world; sleep 1; done" #restart标志会检查容器的退出代码,以决定是否重启容器
$ sudo docker rm daemon # 删除容器,运行中的容器无法删除
运行中的容器无法删除,需要先stop再删除。