Docker Learn

参考文档:什么是 Docker - Docker — 从入门到实践

Docker是什么?

Docker可以类比虚拟机软件,不过Docker实现了进程层面的封装隔离,是一种轻量级的虚拟化技术。

传统虚拟机技术:先虚拟出一套硬件系统、再其上运行一个完整操作系统、最后在操作系统上运行应用。

Docker的的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟

Docker的原理

熟悉Docker的原理就需要了解三个基本概念:镜像、容器、仓库。

镜像

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。

我们都知道,操作系统分为 内核用户空间。对于 Linux 而言,内核启动后,会挂载 root文件系统为其提供用户空间支持。Docker 镜像Image),就相当于是一个 root文件系统。

镜像 不包含 任何动态数据,其内容在构建之后也不会被改变。

容器

容器是镜像创建的运行实例,Docker利用容器来运行应用。每个容器都是相互隔离的、保证安全的平台。我们可以把容器看做是一个轻量级的Linux运行环境。

容器是镜像运行时的实体,容器可以被创建、启动、停止、删除、暂停等。

镜像仓库

镜像仓库就是集中存放镜像文件的地方。

用户创建完镜像后,可以将其上传到公共仓库或者私有仓库,需要在另一台主机上使用该镜像时,只需要从仓库上下载即可。

Ubuntu 镜像 为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如,16.04, 18.04

我们可以通过 ubuntu:16.04,或者 ubuntu:18.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 ubuntu,那将视为 ubuntu:latest

数据卷

每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层。容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。

所以,容器要进行文件读取的话,必须挂载数据卷或者主机目录

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UnionFS,可以提供很多有用的特性:

  • 数据卷 可以在容器之间共享和重用
  • 数据卷 的修改会立马生效
  • 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除

Docker使用

安装

安装之后会碰到一个小问题:

1
2
3
4
Got permission denied while trying to connect to the Docker 
daemon socket at unix:///var/run/docker.sock: Get
"http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/json": dial unix
/var/run/docker.sock: connect: permission denied

docker进程使用Unix Socket而不是TCP端口,而默认情况下,Unix socket属于root用户,需要root权限。

解决方法:

  • 在每条docker命令前加sudo获取root权限
  • 将用户添加到docker的用户组
1
2
3
sudo groupadd docker 					#添加docker用户组
sudo gpasswd -a $USER docker #将登陆用户加入到docker用户组中
newgrp docker #更新用户组

docker images #测试docker命令是否可以使用sudo正常使用

docker守护进程启动的时候,会默认赋予名字为docker的用户组读写Unix socket的权限,因此只要创建docker用户组,并将当前用户加入到docker用户组中,那么当前用户就有权限访问Unix socket了,进而也就可以执行docker相关命令。

镜像操作

拉取镜像

1
docker pull 仓库名:版本标签

默认从docker.io获取镜像,比如:

1
2
3
4
5
6
7
8
$ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
92dc2a97ff99: Pull complete
be13a9d27eb8: Pull complete
c8299583700a: Pull complete
Digest: sha256:4bc3ae6596938cb0d9e5ac51a1152ec9dcac2a1c50829c74abd9c4361e321b26
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04

查看镜像

1
2
3
docker image ls #列出已经下载的镜像
docker images # 等同于上条命令
docker image rm 镜像名 # 删除镜像

使用镜像启动容器

使用镜像,实际就是以某个镜像为基础,启动容器,运行相应的命令。

1
$ docker run -it ubuntu:18.04 /bin/bash
  • -it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。
  • ubuntu:18.04:这是指用 ubuntu:18.04 镜像为基础来启动容器。
  • /bin/bash:放在镜像名后的是 命令,这里我们希望有个交互式 Shell,因此用的是 bash

这将启动一个临时容器,运行交互式shell bash,推出shell后,这个容器就进入终止状态。

容器操作

查看容器

1
docker container ls [options]

Options:

  • -a, --all: 列出所有容器 (包括停止的容器)。
  • -q, --quiet: 只显示容器 ID。
  • -s, --size: 显示每个容器所占用的磁盘空间大小。

启动容器

启动容器有两种方式:

  • 一种是基于镜像新建一个容器并启动;
  • 另一种是将在终止状态(exited)的容器重新启动。

(1)新建容器并启动

1
docker run 镜像名 执行的命令 --name 容器名

(2)启动终止容器

1
docker start 容器名

其他操作

1
2
docker stop	容器名 # 停止容器
docker container rm 容器名 # 删除容器

数据卷操作

数据卷操作

(1)创建

1
docker volume create 卷名

默认情况下,Docker 会将数据卷存储在 /var/lib/docker/volumes 目录下。

(2)查看数据卷

1
docker volume ls

(3)查看数据卷具体信息

1
docker volume inspect 卷名

比如

1
2
3
4
5
6
7
8
9
10
11
$ docker volume inspect my-vol
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]

就能看到my-vol在主机中存数据的具体路径了。

(4)查看数据卷挂载情况

1
$ docker inspect 容器名

数据卷 信息在 “Mounts” Key 下面

1
2
3
4
5
6
7
8
9
10
11
12
"Mounts": [
{
"Type": "volume",
"Name": "my-vol",
"Source": "/var/lib/docker/volumes/my-vol/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],

(5)删除数据卷

1
docker volume rm 卷名

数据卷挂载【目录映射】

-v 选项和 --mount 选项都可以在 Docker 中用于挂载数据卷。

使用 -v 参数时,如果本地目录不存在 Docker 会自动为你创建一个文件夹。

使用 --mount 参数时,如果本地目录不存在,Docker 会报错。

注意:本地目录的路径必须是绝对路径

v选项

-v 选项是 Docker 较早版本中的选项,主要用于简单的数据卷挂载。它的语法为:

1
docker run -v /host/path:/container/path image

/host/path 是主机上要挂载的文件夹路径,

/container/path 是容器内要挂载到的路径。

mount选项

--mount 选项是 Docker 较新版本的选项,可以提供更细粒度的控制,支持更丰富的数据卷挂载方式。它的语法为:

1
docker run --mount type=bind,source=/host/path,target=/container/path image

type=bind 表示使用主机目录,

source=/host/path 表示主机上要挂载的文件夹路径,

target=/container/path 表示容器内要挂载到的路径。

作者

Desirer

发布于

2023-05-18

更新于

2025-07-27

许可协议