1、镜像加速
开始基本操作之前我们先配置一下Docker镜像加速、设置国内源:
在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件):
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://reg-mirror.qiniu.com",
"https://registry.docker-cn.com"
]
}
通过systemctl restart docker命令重启Docker即可体验加速啦。
2、镜像获取
Docker 官方提供了一个公共的镜像仓库:Docker Hub,我们就可以从这上面获取镜像,获取镜像的命令:docker pull,格式为:
docker pull [选项] [Docker Registry 地址[:端口]/]仓库名[:标签]
- Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号],默认地址是 Docker Hub。
- 仓库名:这里的仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。
例如我们通过下面的命令拉取镜像:
上面的命令中没有给出 Docker 镜像仓库地址,因此将会从默认 Docker Hub 获取镜像。而镜像名称是 ubuntu:16.04,因此将会获取官方镜像 library/ubuntu 仓库中标签为 16.04 的镜像。
从下载过程中可以看到Docker分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。下载过程中给出了每一层 ID 的前 12 位。并且下载结束后,给出该镜像完整的 sha256 摘要,以确保下载一致性。
3、运行容器
有了镜像后,我们就能够以这个镜像为基础启动并运行一个容器。以上面的 ubuntu:16.04 为例,如果我们打算启动里面的 bash 并且进行交互式操作的话,可以执行下面的命令。
docker run 就是运行容器的命令,这里我们简要的说明一下上面用到的参数。
-it:这是两个参数,一个是 -i:交互式操作;一个是 -t :终端。这里我们进入 bash 执行一些命令并查看返回结果,因此需要交互式终端。
–rm:这个参数表示容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm 进行删除。这里我们可以使用 –rm 可以避免浪费空间。
ubuntu:16.04:表示以 ubuntu:16.04 镜像为基础来启动容器。
bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。
进入容器后,我可以在 Shell 下操作,执行任何所需的命令。这里,我们执行了 cat /etc/os-release,这是 Linux 常用的查看当前系统版本的命令,从返回的结果可以看到容器内是 Ubuntu 16.04.4 LTS 系统。 最后我们通过 exit 退出了这个容器。
4、列出镜像
列表包含了 仓库名、标签、镜像 ID、创建时间 以及 所占用的空间。镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个标签。
5、镜像大小
如果仔细观察,会注意到,这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不同。比如,ubuntu:16.04 镜像大小,在这里是 127 MB,但是在 Docker Hub 显示的却是 43 MB。这是因为 Docker Hub 中显示的体积是压缩后的体积。在镜像下载和上传过程中镜像是保持着压缩状态的,因此 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而 docker image ls 显示的是镜像下载到本地后,展开的大小,准确说,是展开后的各层所占空间的总和,因为镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。
另外一个需要注意的问题是,docker image ls 列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于 Docker 使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。
我们可以通过以下命令来便捷的查看镜像、容器、数据卷所占用的空间
docker system df
6、新建并启动容器
新建并启动一个容器,我们可以使用的命令主要为 docker run。 例如,下面的命令输出一个 “Hello World”,之后终止容器。
docker run ubuntu:16.04 /bin/echo ‘Hello world’
这跟在本地直接执行 /bin/echo ‘hello world’ 几乎感觉不出任何区别。下面我们可以通过一个命令来启动一个 bash 终端,允许用户进行交互。 其中,-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开。 在交互模式下,用户可以通过所创建的终端来输入命令,例如:
当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
7、启动已终止容器
我们可以利用 docker container start 命令,直接将一个已经终止的容器启动运行。 容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。可以在伪终端中利用 ps 或 top 来查看进程信息。
可见,容器中仅运行了指定的 bash 应用。这种特点使得 Docker 对资源的利用率极高,是货真价实的轻量级虚拟化。
8、后台运行
更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加 -d 参数来实现。 例如:
容器会把输出的结果 (STDOUT) 打印到宿主机上面。
如果使用了 -d 参数运行容器、例如:
此时容器会在后台运行并不会把输出的结果 (STDOUT) 打印到宿主机上面(输出结果可以用 docker logs 查看)。 注: 容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关。 使用 -d 参数启动后会返回一个唯一的 id,也可以通过 docker container ls 命令来查看容器信息。
要获取容器的输出信息,可以通过 docker container logs 命令(参考上图)。
9、终止容器
我们可以使用 docker container stop 来终止一个运行中的容器。 此外,当 Docker 容器中指定的应用终结时,容器也自动终止。终止状态的容器可以用 docker container ls -a 命令看到。例如:
处于终止状态的容器,可以通过 docker container start 命令来重新启动。 此外,docker container restart 命令会将一个运行态的容器终止,然后再重新启动它。
10、进入容器
在使用 -d 参数时,容器启动后会进入后台。某些时候需要进入容器进行操作
exec 命令
-i -t 参数
docker exec 后边可以跟多个参数,这里主要说明 -i -t 参数。 只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。
当 -i -t 参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。
注:这里我们通过docker exec -i 2339 bash进入该容器一直无效(有知道的可以私信我一下)
如果从这个 stdin 中 exit,不会导致容器的停止。这就是为什么推荐大家使用 docker exec 的原因。 更多参数说明请使用 docker exec –help 查看。
11、删除容器
我们可以使用 docker container rm 来删除一个处于终止状态的容器。例如:
当然、也可用使用 docker rm 容器名来删除,如果要删除一个运行中的容器,可以添加 -f 参数。Docker 会发送 SIGKILL 信号给容器。
清理所有处于终止状态的容器。用 docker container ls -a (或者docker ps -a)命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。
docker container prune 或者 docker ps -aq
12、删除本地镜像
如果要删除本地的镜像,可以使用 docker image rm 命令,其格式为:
docker image rm [选项] <镜像1> [<镜像2> …]
或者 docker rmi 镜像名
用 ID、镜像名、摘要删除镜像
其中,<镜像> 可以是 镜像短 ID、镜像长 ID、镜像名 或者 镜像摘要。比如我们有下面这些镜像:
我们可以用镜像的完整 ID,也称为长 ID来删除镜像。使用脚本的时候可能会用长ID,但是人工输入就太累了,所以更多的时候是用短 ID 来删除镜像。docker image ls 默认列出的就已经是短 ID 了,一般取前3个字符以上,只要足够区分于别的镜像就可以了。 当然、我们也可以用镜像名,也就是 <仓库名>:<标签>,来删除镜像。