前言
此篇博文是笔者所总结的 Docker 系列之一;
本文为作者的原创作品,转载需注明出处;
安装
Ubuntu 上安装 Docker
从 Ubuntu 官方安装步骤上翻译;
前置条件
安装有两个重要的前提
- Docker 只能在 64 位 linux 操作系统上安装
- Docker 需要在 3.10 或者更高版本的内核版本上进行安装。如果内核版本低于 3.10,会丧失 Docker Container 的一些特性,并且会引入一些 bug,比如文件丢失等; 通过
uname -r
检查你的内核版本1
2mac@ubuntu:~$ uname -r
4.8.0-22-generic
更新你的 apt sources
更新 apt 包,保证 APT 能够使用 https
1
2$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates添加 PGP Key
1
2
3$ sudo apt-key adv \
--keyserver hkp://ha.pool.sks-keyservers.net:80 \
--recv-keys 58118E89F3A912897C070ADBF76221572C52609D参考如下的表格,查找于你的 Ubuntu 版本对应的 Repository,用来决定 APT 将会从哪个 Reposiroty 中查找 Docker 安装包;建议使用一个长期维护的 LTS 版本的 Reposiroty
Ubuntu Version | Repository |
---|---|
Precise 12.04 (LTS) | deb https://apt.dockerproject.org/repo ubuntu-precise main |
Trusty 14.04 (LTS) | deb https://apt.dockerproject.org/repo ubuntu-trusty main |
Wily 15.10 | deb https://apt.dockerproject.org/repo ubuntu-wily main |
Xenial 16.04 (LTS) | deb https://apt.dockerproject.org/repo ubuntu-xenial main |
将对应的源 repo 添加到 APT 中
1
$ echo "deb https://apt.dockerproject.org/repo ubuntu-xenial" | sudo tee /etc/apt/sources.list.d/docker.list
我的版本是 16.10,所以这里选择了一个最接近的
更新 APT index
1
sudo apt-get udpate
检查 APT 是否是从正确的 repository 中进行拉取的
1
2
3
4
5
6
7
8
9
10
11
12
13$ apt-cache policy docker-engine
docker-engine:
Installed: 1.12.2-0~trusty
Candidate: 1.12.2-0~trusty
Version table:
*** 1.12.2-0~trusty 0
500 https://apt.dockerproject.org/repo/ ubuntu-trusty/main amd64 Packages
100 /var/lib/dpkg/status
1.12.1-0~trusty 0
500 https://apt.dockerproject.org/repo/ ubuntu-trusty/main amd64 Packages
1.12.0-0~trusty 0
500 https://apt.dockerproject.org/repo/ ubuntu-trusty/main amd64 Packages*** 标志表示当前 repository 中所包含的 Docker 版本信息,这里显示的是1.12.0,且每一个路径中应当包含路径 https://apt.dockerproject.org/repo/,则表示 APT Repository 设置无误。
安装 linux-image-extra-* 内核
安装 linux-image-extra-* 内核,允许你使用 aufs 存储引擎,(只针对 Ubuntu Xenial 16.04 (LTS), Wily 15.10, Trusty 14.04 (LTS) 版本 )1
$ sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
安装最新版 Docker
更新 APT Package index1
$ sudo apt-get update
安装 Docker1
$ sudo apt-get install docker-engine
启动 Docker Daemon 守护进程1
$ sudo service docker start
通过运行 hello-world image 来检查是否安装成功1
2
3mac@ubuntu:~$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
用非 root 用户来管理 Docker
因为 docker 守护进程是绑定在 Unix socket 上而不是 TCP 端口上,默认情况下,Unix socket 是由 root 用户所拥有,其它的用户只能通过 sudo 进行访问;也正因如此,docker 的守护进程是运行在 root 用户上的。
如果,你不希望使用 sudo 来执行 docker 的命令,那么你需要创建一个名叫 docker 的 Unix 用户组然后将用户加入。当 docker 的守护进程启动以后,它将会把 Unix socket 绑定在 docker 用户组上。
注意,docker group 相当于 root 用户,要知道有什么安全隐患,查看
Dock Attack Surface
1 | $ sudo groupadd docker |
验证1
$ docker run hello-world
如果执行失败,你会看到如下的错误Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?
Check whether the DOCKER_HOST environment variable is set for your shell.1
$ env | grep DOCKER_HOST
If it is set, the above command will return a result. If so, unset it.1
$ unset DOCKER_HOST
You may need to edit your environment in files such as ~/.bashrc or ~/.profile to prevent the DOCKER_HOST variable from being set erroneously.
卸载
卸载 Docker 包
1
$ sudo apt-get purge docker-engine
卸载 Docker 包依赖
1
$ sudo apt-get autoremove --purge docker-engine
删除 Containers, Images 或者自定义的配置文件等
1
$ rm -rf /var/lib/docker
docker 日志输出
1 | Ubuntu (old using upstart ) - /var/log/upstart/docker.log |
Docker 容器状态机
Docker 容器状态
created:表示已经被创建的容器,但还没有启动(既是没有进入 running 状态)
docker ps -a
可以列出所有已经被创建的容器,Status 显示当前状态信息1
2
3
4
5
6mac@ubuntu:~$ docker ps -as
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE
fae5af17f0ba hello-world "/hello" 45 minutes ago Exited (0) 45 minutes ago romantic_noether 0 B (virtual 1.848 kB)
91d964aec9f7 hello-world "/hello" About an hour ago Exited (0) About an hour ago reverent_brattain 0 B (virtual 1.848 kB)
41d27e5b204f hello-world "/hello" About an hour ago Exited (0) About an hour ago distracted_tesla 0 B (virtual 1.848 kB)
2210b152b308 training/webapp "python app.py" 21 hours ago Created web31 0 B (virtual 348.8 MB)running:表示运行中的容器
docker ps
可以列出所有正在 running 状态的 Docker 容器。1
2mac@ubuntu:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES可以看到,当前没有任何正在运行的容器。
- paused:容器的进程被暂停了。
- restarting:容器的进程正在重启过程中。
- exited:上图中的 stopped 状态,表示容器之前运行过但是现在处于停止状态(要区别于
created 状态,它是指一个新创出的尚未运行过的容器)。可以通过 start 命令使其重新进入 running 状态 - destroyed:容器被删除了,再也不存在了
查看当前容器的状态
可以使用docker inspect ContainerID
查看当前容器的状态1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20mac@ubuntu:~$ docker inspect fae5af17f0ba
[
{
"Id": "fae5af17f0ba41248b99b08fa2ed6c38691201290218ae6b07d0ea4c0ccebb0e",
"Created": "2016-12-20T05:25:46.738194761Z",
"Path": "/hello",
"Args": [],
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 0,
"Error": "",
"StartedAt": "2016-12-20T05:25:47.760674803Z",
"FinishedAt": "2016-12-20T05:25:47.770661122Z"
},
Docker 的命令大全
Docker 命令分类
镜像操作
1 | build Build an image from a Dockerfile |
容器及其中应用的生命周期操作
1 | create Create a new container (创建一个容器) |
容器文件系统操作
1 | # 基本文件操作 |
Docker registry 操作
1 | login Log in to a Docker registry. |
Volume 操作
1 | volume Manage Docker volumes |
网络操作
1 | network Manage Docker networks |
Swarm 操作
1 | swarm Manage Docker Swarm |
系统操作
1 | version Show the Docker version information |
常用的命令
生命周期相关
创建一个容器
创建一个名为 web31 的容器1
2mac@devstack:/home/mac# docker create --name web31 training/webapp python app.py
7465f4cb7c49555af32929bd1bc4213f5e72643c0116450e495b71c7ec128502容器状态为
created
1
2root@devstack:/home/mac# docker inspect --format='{{.State.Status}}' web31
created启动容器
1
2root@devstack:/home/mac# docker start web31 #启动容器
web31容器的状态为
runnning
1
2root@devstack:/home/mac# docker inspect --format='{{.State.Status}}' web31
running暂停容器
1
2root@devstack:/home/mac# docker pause web31 #暂停容器
web31容器状态为
paused
1
2root@devstack:/home/mac# docker inspect --format='{{.State.Status}}' web31
paused继续容器
1
2root@devstack:/home/mac# docker unpause web31 #继续容器
web31容器状态为
runnning
1
2root@devstack:/home/mac# docker inspect --format='{{.State.Status}}' web31
running停止容器
1
2root@devstack:/home/mac# docker stop newweb31 #停止容器
newweb31容器状态为
exited
1
2root@devstack:/home/mac# docker inspect --format='{{.State.Status}}' newweb31
exited删除容器
1
2root@devstack:/home/mac# docker rm newweb31 #删除容器
newweb31容器状态为,错误,没有检查到该容器
1
2root@devstack:/home/mac# docker inspect --format='{{.State.Status}}' newweb31
Error: No such image, container or task: newweb31
重命名
1 | root@devstack:/home/mac# docker rename web31 newweb31 #重命名 |
查看容器中top
进程
1 | root@devstack:/home/mac# docker top newweb31 #在容器中运行 top 命令 |
获取容器的日志
1 | root@devstack:/home/mac# docker logs newweb31 #获取容器的日志 |
深入理解 docker stop 和 docker kill
在docker stop 命令执行的时候,会先向容器中PID为1的进程发送系统信号 SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间(默认为 10秒,用户可以指定特定超时时长),会继续发送SIGKILL的系统信号强行kill掉进程。在容器中的应用程序,可以选择忽略和不处理SIGTERM信号,不过一旦达到超时时间,程序就会被系统强行kill掉,因为SIGKILL信号是直接发往系统内核的,应用程序没有机会去处理它1
docker stop web5 -t 20 # 等待 20 秒,然后发送 kill 命令
查看容器 web5 的日志1
2
32016-09-16T16:01:18.206540853+08:00 container kill b3256ef1400a7f6a6f242e377a77af5e25d3b12237c4ee7c2e9b31a5f6437868 (image=training/webapp, name=web5, signal=15)
2016-09-16T16:01:38.212352224+08:00 container kill b3256ef1400a7f6a6f242e377a77af5e25d3b12237c4ee7c2e9b31a5f6437868 (image=training/webapp, name=web5, signal=9)
2016-09-16T16:01:38.235021315+08:00 container die b3256ef1400a7f6a6f242e377a77af5e25d3b12237c4ee7c2e9b31a5f6437868 (exitCode=137, image=training/webapp, name=web5)
能看到:
- 首先 docker 向容器发出 SIGTERM 信号(
signal=15
) - 等待20秒 (01:18 到 01:38)
- 再发送 SIGKILL 系统信号 (
signal = 9
) - 然后容器被杀掉了 (
die
)
在 host 与 container 之间相互拷贝文件或者目录
从 host 拷贝文件到 container 的 /webapp 目录中
1
2
3
4mac@ubuntu:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2210b152b308 training/webapp "python app.py" 22 hours ago Up 4 minutes 5000/tcp web31
mac@ubuntu:/home/mac# docker cp /home/mac/testfile web31:/webapp从 container 中拷贝文件到 host 中
1
2
3mac@ubuntu:~$ docker cp web31:/opt/webapp/tests.py /home/mac
mac@ubuntu:~$ ls /home/mac
tests.py
docker export 和 import
docker export
将一个容器整个文件系统打包成一个压缩文件,给容器备份、或者导出文件以便深度分析;1
2
3
4
5
6
7
8
9
10
11
12mac@ubuntu:~$ docker export web31 -o /home/mac/docker_web31_backup.tar
mac@ubuntu:~$ ls -shAl /home/mac
total 324M
4.0K -rw------- 1 mac mac 1.8K Dec 20 12:34 .bash_history
4.0K -rw-r--r-- 1 mac mac 220 Dec 18 16:29 .bash_logout
4.0K -rw-r--r-- 1 mac mac 3.7K Dec 18 16:29 .bashrc
4.0K drwx------ 2 mac mac 4.0K Dec 18 16:32 .cache
324M -rw------- 1 mac mac 324M Dec 20 15:11 .docker_web31_backup
4.0K -rw-r--r-- 1 mac mac 655 Dec 18 16:29 .profile
0 -rw-r--r-- 1 mac mac 0 Dec 18 16:33 .sudo_as_admin_successful
4.0K -rw-r--r-- 1 mac mac 285 May 16 2015 tests.py
4.0K -rw------- 1 root root 1.6K Dec 19 11:18 .viminfo可以直接使用 tar 命令解压压缩文件
1
mac@ubuntu:~$ tar -xvf docker_web31_backup.tar
docker import
从一个压缩包中创建一个镜像
1
2mac@ubuntu:/$ docker import /home/mac/docker_web31_backup.tar new_web31 -m "import a new image from the backup file"
sha256:81a66be74de5d63e3dd96d0e5e492cef14140ea9581a85662cfff19ceeb7c5c0可见,通过容器导出的备份文件,在本地新建了一个名为
new_web31
的 docker 镜像。1
2
3mac@ubuntu:/$ docker history new_web31
IMAGE CREATED CREATED BY SIZE COMMENT
81a66be74de5 11 seconds ago 323.7 MB import a new image from the compressed file1
2
3
4
5mac@ubuntu:/$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
new_web31 latest 81a66be74de5 32 seconds ago 323.7 MB
hello-world latest c54a2cc56cbb 5 months ago 1.848 kB
training/webapp latest 6fae60ef3446 19 months ago 348.8 MB
docker run
docker run 命令会创建一个容器并启动它,它也是包含很多的参数,按照用途将它们分类如下,
cgroups 和 namespace 相关
1 | --blkio-weight value Block IO (relative weight), between 10 and 1000 |
linux process capabilities 相关参数
1 | --cap-add value Add Linux capabilities (default []) |
容器运行模式和环境相关
1 | -d, --detach Run container in background and print container ID |
DNS 相关
1 | --dns value Set custom DNS servers (default []) |
健康检查相关
1 | --health-cmd string Command to run to check health |
IP 和端口
1 | --ip string Container IPv4 address (e.g. 172.30.100.104) |
Volume 相关
1 | -v, --volume value Bind mount a volume (default []) |
Network 有关
1 | --network string Connect a container to a network (default "default") |
日志有关
1 | --log-driver string Logging driver for the container |
交互性有关
1 | -a, --attach value Attach to STDIN, STDOUT or STDERR (default []) |
OOM 有关
1 | --oom-kill-disable Disable OOM Killer |
其它
1 | --detach-keys string Override the key sequence for detaching a container |