# 手摸手 Docker 从入门到实践

TIP

CentOS 版本:7.6

Nginx 版本:1.16.1

Docker 版本:19.03.12

# 安装 & 配置

  1. MAC 版本的 docker下载 (opens new window)
  2. 配置镜像加速,在 MacOS 的 Docker 配置 Perferences -> Docker Engine
{
  "experimental": false,
  "features": {
    "buildkit": true
  },
  "registry-mirrors": [
    "https://reg-mirror.qiniu.com/",
    "http://hub-mirror.c.163.com/",
    "https://registry.docker-cn.com/"
  ]
}
1
2
3
4
5
6
7
8
9
10
11
  1. 查看配置 docker info
....
 Registry Mirrors:
  https://reg-mirror.qiniu.com/
  http://hub-mirror.c.163.com/
  https://registry.docker-cn.com/
  ....
1
2
3
4
5
6
  1. 开启一个简单的docker服务

docker run hello-world

# 镜像 & 容器 & 仓库

镜像和容器的关系就像类和类的实例,一个镜像可以同时跑多个容器,单个容器实例又可以创建新的镜像。如下图:

performance

概念 说明
镜像Images 用于创建 Docker 容器的只读模板,比如 Ubuntu 16.04系统、Nginx 1.16.0 等,是一个特殊的文件系统,包括容器运行时需要的程序、库、资源、参数等,但不包含任何动态数据,内容在构建后也不会被改变,一个镜像可以创建多个容器
容器 Container 容器是独立运行、相互隔离的一个或一组应用,是镜像创建的运行实例,实质是进程,可以看作为一个简易版的 Linux 环境 + 运行在其中的应用程序
客户端 Client 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信
主机 Host 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器
仓库 Repository 集中存放镜像文件的地方,分为公有仓库和私有仓库。
注册服务器 Registry 是一个集中存储、分发镜像的服务,官方的叫 Docker Hub。一个 Docker Registry 中可包含多个仓库,每个仓库可以包含多个标签 Tag 的镜像,不同的标签对应不同的版本
Docker Machine Docker Machine 是一个简化 Docker 安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如 VirtualBox、 Digital Ocean、Microsoft Azure

# 容器的生命周期图示

容器的生命周期图示

容器的五个核心状态,也就是图中色块表示的:Created、Running、Paused、Stopped、Deleted:

  1. Created:容器已经被创建,容器所需的相关资源已经准备就绪,但容器中的程序还未处于运行状态。
  2. Running:容器正在运行,也就是容器中的应用正在运行。
  3. Paused:容器已暂停,表示容器中的所有程序都处于暂停 ( 不是停止 ) 状态。
  4. Stopped:容器处于停止状态,占用的资源和沙盒环境都依然存在,只是容器中的应用程序均已停止。
  5. Deleted:容器已删除,相关占用的资源及存储在 Docker 中的管理信息也都已释放和移除。

# 基本使用

# 操作命令

# 开启 Docker 开机自启动
$ sudo systemctl enable docke

# 关闭 Docker 开机自启动
$ sudo systemctl disable docke
1
2
3
4
5

# 镜像命令

# 去下载镜像,先从本地找,没有去镜像,最后没有去 hub,标签不写默认为 lastest
$ docker pull [镜像名]:[标签Tag]

# 列出本机的所有 image 文件,
-a 显示本地所有镜像(包括中间镜像), 镜像是可以分层的
-q 只显示镜像ID,
--digests 显示镜像的摘要信息
$ docker image ls
$ docker images

# 删除 image 文件, -f 强制删除镜像
$ docker rmi [镜像名][:标签Tag]
$ docker rmi [镜像名1][:标签Tag] [镜像名2][:标签Tag]    # 删多个
$ docker rmi $(docker ps -a -q)    # 删全部,后面是子命令

# 查询镜像名称
--no-trunc 显示完整的镜像描述
--filter=stars=30 列出star不少于指定值的镜像,
--filter=is-automated=true 列出自动构建类型的镜像
$ docker search [关键字]

# 下载镜像,标签 tag 不写默认为 lastest,也可以自己加比如 :3.2.0
$ docker pull [镜像名][:标签Tag]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 容器命令

# 列出本机正在运行的容器
-a 列出本机所有容器包括终止运行的容器
-q 静默模式只显示容器编号
-l 显示最近创建的容器
$ docker container ls     # 等价于下面这个命令
$ docker ps

# 新建并启动容器
$ docker run [option] [容器名]
--name 为容器指定一个名称;
-d 容器启动后进入后台,并返回容器 ID,即启动守护式容器;
-P 随机端口映射;
-p 80:8080 将本地 80 端口映射到容器的 8080 端口;
bash 容器启动以后,内部第一个执行的命令。这里启动 bash,保证用户可以使用 Shell;
-i 以交互模式运行容器,通常与 -t 同时使用;
-t 为容器重新分配一个伪输入终端,容器的 Shell 会映射到当前的 Shell,然后在本机窗口输入的命令,就会传入容器,通常与 -i  同时使用;
--rm 在容器终止运行后自动删除容器文件;
--restart=always 设置容器自启动;
-v /xxx:/yyy 映射命令,把本机的 xxx 目录映射到容器中的 yyy 目录,也就是说改变本机的 xxx 目录下的内容, 容器 yyy 目录中的内容也会改变;
docker run -it -name mycentos // 启动容器并以交互式进入容器
docker run -d -name mycentos // 以守护式启动容器. 由于docker机制,不可用docker ps查看


# 启动容器
$ docker start [容器ID]/[容器Names]

# 重启容器
$ docker restart [容器ID]/[容器Names]

# 终止容器运行
$ docker kill [容器ID]  # 强行终止,相当于向容器里面的主进程发出 SIGKILL 信号,那些正在进行中的操作会全部丢失
$ docker kill $(docker ps -a -q) # 强行终止所有容器
$ docker stop [容器ID]  # 从容终止,相当于向容器里面的主进程发出 SIGTERM 信号,然后过一段时间再发出 SIGKILL 信号
$ docker stop $(docker ps -a -q) # 终止所有容器

# 终止运行的容器文件,依然会占据硬盘空间,可以使用 docker container rm 命令删除,-f 强制删除可以删除正在运行的容器
$ docker rm [容器ID]
$ docker rm `docker ps -aq`    # 删除所有已经停止的容器,因为没停止的rm删不了需要加-f

# 查看容器的输出,-t加入时间戳,-f跟随最新日志打印,--tail数字显示最后多少条,如果docker run时,没有使用-it,就要用这个命令查看输出
$ docker logs [容器ID]

# 查看容器进程信息
$ docker top [容器ID]/[容器Names]
$ docker port [容器ID]/[容器Names]

# 退出容器
$ exit# 容器退出
ctrl + p + q     # 容器退出,快捷键

# 进入容器
$ docker attach [容器ID]      # 退出容器时会让容器停止,本机的输入直接输到容器中
$ docker exec -it [容器ID]    # 退出容器时不会让容器停止,在已运行的容器中执行命令,不创建和启动新的容器

# 设置容器在docker启动时自动启动
$ docker container update --restart=always [容器名字]
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
docker 容器内的应用进程之间运行于宿主的内核,容器内没有自己的内核,也没有进行硬件的虚拟
每个容器互相隔离,每个容器都有自己的文件系统,容器之间进行不互相影响

docker 是一个Client-Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,
守护进程从客户端接受命令并管理运作在主机上的容器。容器是一个运行时环境。

镜像是可以分层的

容器可以看做是简易 linux


容器停止了,里面的数据会丢失吗?
1
2
3
4
5
6
7
8
9
10
11
12