Docker 简介

docker 三大基本概念

docker仓库(Registry):用来保存各种打包好的软件镜像,仓库分为公有仓库和私有仓库(类似maven)
docker镜像(Images):软件打包好的镜像,放在docker仓库中
docker容器(Container):镜像启动后的实例称为一个容器,容器是独立运行的一个或一组应用

Docker 安装

菜鸟教程-docker

CentOS 安装

安装命令如下:

1
curl -fsSL https://get.docker.com | bash -s docker --mirror aliyun

也可以使用国内 daocloud 一键安装命令:

1
curl -sSL https://get.daocloud.io/docker | sh

Docker 命令

常用命令

基础命令

  • 启动docker: systemctl start docker
  • 停止docker: systemctl stop docker
  • 重启docker: systemctl restart docker
  • 查看docker状态: systemctl status docker
  • 开机启动: systemctl enable docker
  • 查看docker概要信息: docker info
  • 查看docker总体帮助文档: docker --help
  • 查看docker命令帮助文档: docker 具体命令 --help

镜像常用命令

这里只列举一些常用的,详细的操作请访问 https://docs.docker.com/engine/reference/commandline/docker/

docker images

docker images [OPTIONS] [REPOSITORY[:TAG]]

OPTIONS说明:

1
2
-a:  列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层)
-q: 只显示镜像ID

e.g.

1
2
3
4
5
6
[root@localhost ~]# docker images 
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 2a0961b7de03 5 weeks ago 462MB
rabbitmq management 1bfc98e879d5 3 months ago 257MB
mongo latest 0bcbeb494bed 10 months ago 684MB
nginx v3 2c139dd2d638 10 months ago 133MB

说明:
REPOSITORY:镜像的仓库源,TAG:镜像的标签版本号,IMAGE ID:镜像ID,CREATED:镜像创建时间,SIZE:镜像大小

docker pull

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

下载镜像的命令。镜像从远程镜像仓库服务的仓库中下载。默认情况下,镜像会从 Docker Hub 的仓库中拉取。通过下载过程,可以看到,一个镜像一般是由多个层组成,类似 2a0961b7de03 这样的串表示层的唯一 ID。

OPTIONS说明:

1
2
-a, --all-tags=true|false: 是否获取仓库中所有镜像,默认为否;
--disable-content-trust: 跳过镜像内容的校验,默认为 true;

e.g.

1
2
3
4
5
6
7
8
9
[root@localhost ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
b85a868b505f: Pull complete
b09642bd3b88: Pull complete
e0678a951c8d: Pull complete
Digest: sha256:d581aded52343c461f32e4a48125879ed2596291f4ea4baa7e3af0ad1e56feed
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
问题:
  • 如果多个不同的镜像中,同时包含了同一个层,这样重复下载,岂不是导致了存储空间的浪费么?

实际上,Docker 并不会去下载重复的层,Docker 在下载之前,会去检测本地是否会有同样 ID的层,如果本地已经存在了,就直接使用本地的就好了。

  • 不同仓库中,可能也会存在镜像重名的情况发生,这种情况咋办?

从严格意义上讲,在使用 pull命令时,还需要在镜像前面指定仓库地址(Registry),如果不指定,则Docker 会使用您默认配置的仓库地址。例如本机docker配置的是国内 docker.io的仓库地址,我在pull 的时候,docker 会默认加上 docker.io/library 的前缀。
例如:当我执行 docker pull nginx命令时,实际上相当于 docker pull docker.io/nginx,如果未自定义配置仓库,则默认在下载的时候,会在镜像前面加上
DockerHub 的地址。Docker 通过前缀地址的不同,来保证不同仓库中,重名镜像的唯一性。

docker search [OPTIONS] TERM

不推荐,建议直接上仓库网站找

OPTIONS说明:

1
2
3
-f, --filter filter: 过滤输出的内容
--limit int:指定搜索内容展示个数
--no-trunc:不截断输出内容

e.g.

1
2
3
4
5
6
[root@localhost ~]# docker search --limit 4 redis
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
redis Redis is an open source key-value store that… 11101 [OK]
bitnami/redis Bitnami Redis Docker Image 225 [OK]
bitnami/redis-sentinel Bitnami Docker Image for Redis Sentinel 39 [OK]
circleci/redis CircleCI images for Redis 14 [OK]

docker rmi

docker rmi [OPTIONS] IMAGE [IMAGE…]

删除本地一个或多个镜像。

OPTIONS说明:

1
2
-f:	强制删除
--no-prune: 不移除该镜像的过程镜像,默认移除

e.g.

1
2
3
4
5
6
# 删除单个
docker rmi -f 镜像ID
# 删除多个
docker rmi -f 镜像名1:TAG 镜像名2:TAG
# 删除全部
docker rmi -f $(docker images -qa)

容器常用命令

docker run

docker run [OPTIONS] IMAGE [COMMAND] [ARG…]

创建一个新的容器并运行一个命令。更全docker run 参数请移步

OPTIONS说明:

1
2
3
4
5
6
7
8
9
10
11
--name="容器新名字"为容器指定一个名称
-d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行)
-i:以交互模式运行容器,通常与 -t 同时使用
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用, 也即启动交互式容器(前台有伪终端,等待交互)
-P: 随机端口映射,大写P
-p: 指定端口映射,小写p
-v: 挂载一个卷
--restart=no:指定容器停止后的重启策略
no:容器退出时不重启
on-failure:容器故障退出(返回值非零)时重启
always:容器退出时总是重启,推荐使用

e.g.

1
2
3
4
5
[root@localhost opt]# docker run -p 80:80 -v /opt/data:/data --name nginx01 -d nginx:latest
93d5f26ba7538aef84a74ed22d0f7dc844693d33a2767599baeccd14b3fdcedc
[root@localhost opt]# docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Ports}}"
CONTAINER ID IMAGE NAMES PORTS
93d5f26ba753 nginx:latest nginx01 0.0.0.0:80->80/tcp, :::80->80/tcp

docker ps

docker ps [OPTIONS]

列出容器

OPTIONS说明:

1
2
3
4
5
-a :列出当前所有正在运行的容器+历史上运行过的
-l :显示最近创建的容器
-n:显示最近n个创建的容器
-q :静默模式,只显示容器编号
--format :指定返回值的模板文件。

e.g.

1
2
3
[root@localhost opt]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5994c6ac58ba nginx:stable-alpine "/docker-entrypoint.…" 21 hours ago Up 21 hours 0.0.0.0:80->80/tcp

说明:

CONTAINER ID: 容器 ID,IMAGE: 使用的镜像,COMMAND: 启动容器时运行的命令,CREATED: 容器的创建时间,STATUS: 容器状态。

容器状态有7种:

  • created(已创建)
  • restarting(重启中)
  • running(运行中)
  • removing(迁移中)
  • paused(暂停)
  • exited(停止)
  • dead(死亡)
显示指定列

docker ps 默认的显示内容过多,当值过长时就会导致折行,可读性很差,所以希望只显示自己关心的某些列

可用的占位符

名称 含义
.ID 容器ID
.Image 镜像ID
.Command 执行的命令
.CreatedAt 容器创建时间
.RunningFor 运行时长
.Ports 暴露的端口
.Status 容器状态
.Names 容器名称
.Label 分配给容器的所有标签
.Mounts 容器挂载的卷
.Networks 容器所用的网络名称

e.g.

table - 表示显示表头列名

1
2
3
[root@localhost opt]# docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Ports}}"
CONTAINER ID IMAGE NAMES PORTS
93d5f26ba753 nginx:latest nginx01 0.0.0.0:80->80/tcp, :::80->80/tcp

docker rm

删除一个或多个容器(docker rm命令只能删除处于终止或退出状态的容器,并不能删除还处于运行状态的容器)

1
2
3
4
5
6
# 删除单个
docker rm 容器ID
# 一次性删除多个容器实例
docker rm -f $(docker ps -a -q)

docker ps -a -q | xargs docker rm

docker exec

docker exec [OPTIONS] CONTAINER COMMAND [ARG…]

在运行的容器中执行命令。早期有attach命令,对于阻塞命令会等待,所以不方便。在Docker 1.3.0后提供了exec 可以在容器内直接执行任意命令。

推荐使用 docker exec 命令,因为其退出容器终端,不会导致容器的停止

OPTIONS说明:

1
2
-i:	即使没有附加也保持STDIN 打开
-t: 分配一个伪终端

e.g.

1
2
3
4
# 有bash命令的linux系统:例如centos 
[root@localhost opt]# docker run -it --name tomcat9.1 -p 8080:8080 tomcat:9.0.20-jre8-slim docker exec -it tomcat9.1 /bin/bash
# 没有bash命令的linux系统:例如alpine系统
[root@localhost opt]# docker run -it --name tomcat9.2 -p 8081:8080 tomcat:9.0.20-jre8-alpine docker exec -it tomcat9.2 sh

docker attac(不推荐使用)

docker attach [OPTIONS] CONTAINER

连接到正在运行中的容器

docker attac 和 docker exec 的区别

attach 直接进入容器启动命令的终端,不会启动新的进程 用exit退出,会导致容器的停止exec 是在容器中打开新的终端,并且可以启动新的进程 用exit退出,不会导致容器的停止

e.g.

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
# 使用exec,不会导致容器的停止
[root@localhost ~]# docker run --name debian01 -d -it debian
dea96e62d3d673f0b5d0cde9cd39a06ec34de1a6c951aa504da9523cfc714c4a
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dea96e62d3d6 debian "bash" 4 seconds ago Up 2 seconds debian01
[root@localhost ~]# docker exec -it debian01 /bin/bash
root@dea96e62d3d6:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@dea96e62d3d6:/# exit
exit
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dea96e62d3d6 debian "bash" 4 seconds ago Up 2 seconds debian01

# 使用attach,会导致容器的停止
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dea96e62d3d6 debian "bash" 4 seconds ago Up 2 seconds debian01
[root@localhost ~]# docker attach debian01
root@dea96e62d3d6:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@dea96e62d3d6:/# exit
exit
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

启动、重启、停止、强制停止

  • docker start :启动一个或多个已经被停止的容器

  • docker stop :停止一个运行中的容器

  • docker restart :重启容器

  • docker kill:强制停止容器

语法:

1
2
3
4
docker start [OPTIONS] CONTAINER [CONTAINER...] 
docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker restart [OPTIONS] CONTAINER [CONTAINER...]
docker kill [OPTIONS] CONTAINER [CONTAINER...]

e.g.

1
2
3
4
docker start nginx 
docker stop nginx
docker restart nginx
docker kill nginx

退出容器

exit: run进去容器,exit退出,容器停止

ctrl+p+q: run进去容器,ctrl+p+q退出,容器不停止

docker logs

docker logs [OPTIONS] CONTAINER

获取容器的日志

OPTIONS说明:

1
2
3
-f: 跟踪日志输出
--tail: 仅列出最新N条容器日志
--since: 显示某个开始时间的所有日志

e.g.

1
[root@localhost opt]#  docker logs --since="2022-05-06" --tail=10 nginx

docker inspect(了解)

docker inspect [OPTIONS] NAME|ID [NAME|ID…]

通过 docker inspect 命令,我们可以获取镜像的详细信息,其中,包括创建者,各层的数字摘要等。

docker inspect 返回的是 JSON格式的信息,如果您想获取其中指定的一项内容,可以通过 -f 来指定,如获取镜像大小

OPTIONS说明:

1
2
-f:	指定返回值的模板文件
-s: 显示总的文件大小。

e.g.

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
[root@localhost ~]# docker inspect mysql:5.7
[
{
"Id": "sha256:2a0961b7de03c7b1xxx13fec09d0d30992b6e0b4f94xxxba4273723778ed95",
"RepoTags": [
"mysql:5.7"
],
"RepoDigests": [
"mysql@sha256:7e99b2b8d5bca914ef31059858210xxxb009c40375d647f0xxx65ecd01d6b1d5"
],
"Parent": "",
"Comment": "",
"Created": "2022-05-04T05:34:18.063275284Z",
"Container": "73465fb1cd38xd599a4f8e75650xxx918f599262f1d1e995717df42ade0cdb",
"ContainerConfig": {
"Hostname": "73465fb1cd38",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"3306/tcp": {},
"33060/tcp": {}
},
"Tty": false,
.....

[root@localhost ~]# docker inspect -f {{".ContainerConfig.Hostname"}} mysql:5.7
73465fb1cd38

容器rootfs命令

**docker cp **

用于容器与主机之间的数据拷贝

1
2
3
4
# 宿主机文件复制到容器内 
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH
# 容器内文件复制到宿主机
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH

OPTIONS说明:

1
-L: 保持源目标中的链接

e.g.

  • 宿主机文件拷贝至容器内

    将宿主机的index.html页面覆盖容器内的index.html页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost ~]# docker run -itd --name nginx -p 80:80 nginx:1.19.3-alpine 
Unable to find image 'nginx:1.19.3-alpine' locally
1.19.3-alpine: Pulling from library/nginx
188c0c94c7c5: Pull complete
61c2c0635c35: Pull complete
378d0a9d4d5f: Pull complete
2fe865f77305: Pull complete
b92535839843: Pull complete
Digest: sha256:5aa44b407756b274a600cxxx418bdfb1d02c33317ae27fd5e8a333afb115db1
Status: Downloaded newer image for nginx:1.19.3-alpine
docker: Error response from daemon: Conflict. The container name "/nginx" is already in use by container "ff968fb18a4c364f5334930eb192657e09763f4". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.
[root@localhost ~]# cd /opt/data && echo "hello nginx" > /opt/data/index.html
[root@localhost data]# docker cp /opt/data/index.html nginx:/usr/share/nginx/html/index.html