Docker 学习笔记

容器是一种历史悠久的虚拟化技术。Linux 的 LXC、Solaris 上的 Zones等,都是容器的不同实现方式。

一个容器实质上就是运行在宿主机上的一个进程。只不过在启动进程之前,进行了一些特殊处理,让这个进程进入了一个全新的虚拟环境,与宿主机环境分开。所以这个进程以及它的子进程认为自己运行在一个独立的世界里面。

简介

Docker 是一个能够把开发的应用程序自动部署到容器的轻量级的容器管理引擎。

  • 提供一个简单、轻量的建模方式。大多数 Docker 应用程序只需要不到 1 秒钟即可启动。
  • 职责的逻辑分离。使用 Docker,开发人员只需要关心容器中运行的应用程序,而运维人员只需要关心如何管理容器。
  • 快速、高效的开发生命周期。Docker 的目标之一就是缩短代码从开发、测试到部署、上线运行的周期,让你的应用程序具备可移植性,易于构建,并易于协作。
  • 鼓励使用面向服务的架构和微服务架构

核心组件

  • Docker 的客户端和服务端,也称为 Docker 引擎
  • Docker 镜像
  • Registry
  • Docker 容器

镜像和仓库

什么是 Docker 镜像?

Docker 镜像是由文件系统叠加而成。最低端是一个引导文件系统,即 bootfs,这很像典型的 Linux/Unix 的引导文件系统。Docker 用户几乎永远不会和引导文件系统有什么交互。实际上,当一个容器启动后,它将会被移到内存中,而引导文件系统则会被写在(unmount),以留出更多的内存供 initrd 磁盘镜像使用。

到目前为止,Docker 看起来还很像一个典型的 Linux 虚拟化栈。实际上,Docker 镜像的第二层是 root 文件系统 rootfs,它位于引导文件系统之上。rootfs 可以是一种或多种操作系统。

为了区分一个仓库中的不同镜像,Docker 提供了一种称为标签(tag)的功能。

构建镜像

有两种方式:

  1. 使用 docker commit 命令
  2. 使用 docker build 命令和 Dockerfile 文件

后者更灵活、更强大。

一般来说,我们不是真正的创建新镜像,而是基于一个已有的基础镜像,如 Ubuntu 或 fedora 等,构建新镜像而已。


常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# Docker 相关的信息
docker info

# 查看帮助文档
docker help

# 查看某个命令的使用文档
docker COMMAND --help

# 创建并运行新容器
# -i 保证容器中 STDIN 是开启的
# -t 告诉 Docker 为要创建的容器分配一个伪 tty 终端,这样新创建的容器才能提供一个交互式 shell
# eg. docker run -i -t ubuntu /bin/bash
# --name 为容器指定一个名词
# eg. docker run --name try_name_ubuntu -i -t ubuntu /bin/bash
# --restart 让 Docker 自动重新启动该容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

# 查看运行中的容器
# -a 查看所有状态下的容器列表
# -l 查看最后一个运行的容器
docker ps

# 查看容器的详细信息
docker inspect [OPTIONS] NAME|ID [NAME|ID...]

# 重新启动已经停止的容器
docker start NAME|ID

# 附着到容器上
docker attach [OPTIONS] CONTAINER

# 创建一个容器
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]

# 获取守护式容器的日志
# 可通过 Ctrl + C 退出日志跟踪
docker logs [OPTIONS] CONTAINER

# 查看容器内的进程
docker top CONTAINER [ps OPTIONS]

# 在容器内额外启动新进程
# 可以在容器内运行的进程有两种类型:后台任务和交互式任务。
# 后台任务在容器内运行且没有交互需求,而交互式任务则保持在前台运行。
# 对于需要在容器内打开 shell 的任务,交互式任务是很实用的。
# -d 表明需要运行一个后台进程
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

# 查看 Docker 统计信息
docker stats

# 停止守护式容器
docker stop [OPTIONS] CONTAINER [CONTAINER...]

# 删除容器
docker rm [OPTIONS] CONTAINER [CONTAINER...]

# 删除镜像
docker rmi [OPTIONS] IMAGE [IMAGE...]

# 删除所有容器
docker rm `docker ps -a -q`

# 列出本机已有的 Docker 镜像
docker images

# 拉取镜像
docker pull [OPTIONS] NAME[:TAG|@DIGEST]

# 查找镜像
docker search [OPTIONS] TERM

# 从 PATH 中的源码构建镜像
# 通常会使用 -t 参数。eg. docker build -t="lizy/static_web:v1.0.0" .
# --no-cache 用来指定构建的时候不使用缓存
docker build [OPTIONS] PATH | URL | -

# 查看容器端口映射情况
docker port CONTAINER [PRIVATE_PORT[/PROTO]]

Dockerfile

简介

Dockerfile 使用基本的基于 DSL(Domain Specific Language)语法的指令来构建一个 Docker 镜像。
Dockerfile 由一系列指令和参数组成。每条指令都必须为大写字母,且后面要跟随一个参数。Dockerfile 中的指令会按顺序从上到下执行,所以应该根据需要合理的安排指令的顺序。

每个 Dockerfile 的第一条指令必须是 FROM。FROM 指令指定一个已经存在的镜像,后续指令都将基于该镜像进行,FROM 指令指定的镜像被称为基础镜像(base image)。

Dockerfile 中指令执行流程

每条指令都会创建一个新的镜像并对新的镜像进行提交。大体流程如下:

  1. Docker 从基础镜像运行一个容器
  2. 执行一条指令,对容器做出修改
  3. 执行类似 docker commit 的操作,提交一个新的镜像
  4. Docker 再基于刚提交的镜像运行一个容器
  5. 执行 Dockerfile 中的下一条指令,直到所有指令都执行完毕

Dockerfile 指令

FROM

指定一个已经存在的镜像

MAINTAINER

告诉 Docker 该镜像的作者是谁,以及作者的电子邮件地址。

ENV

在镜像中设置环境变量。

RUN

在当前镜像中运行指定的命令。

EXPOSE

告诉 Docker 该容器内的应用将会使用容器的指定端口。

这并不意味着可以自动访问任意容器运行中服务的端口。处于安全的考虑,Docker 并不会自动打开该端口,而是用户在使用 docker run 运行容器是来指定需要打开哪些端口。

可以指定多个 EXPOSE 指令来向外部公开多个端口。

构建上下文

我们会创建一个目录来保存 Dockerfile,这个目录是我们的构建环境(build environment),Docker 则称此环节为上下文(content)或者构建上下文(build content)。

.dockerignore

用来设置那些文件不会被当做构建上下文的一部分。


docker run -d -p 80 –name static_web lizy/static_web:v1 nginx -g “daemon off;”

实践

在宿主机上启用 Nginx

1
docker pull nginx
志遥 wechat
微信扫一扫,我在丁香园记公众号等你