1. 概述
Docker 命令有点借鉴 git 命令的意思,有 docker pull,docker push 等。

2. 镜像相关
2.1. 查找镜像
默认的镜像仓库都在国外:hub.docker.com,可以改成阿里云的镜像仓库,可以见安装教程文章。
通过 search 命令,可以搜索一些镜像信息,例如搜索 redis 镜像
docker search redis

2.2. 镜像拉取
拉取最新版本的镜像
# 要跟上完整的名称,默认拉取的是最新的版本
docker pull supermanito/helloworld
如下图所示,这个镜像分成了 2 层,所以拉取的时候看到了 2 个

关于镜像分层存储,主要是为了节省存储空间,例如:

拉取指定版本的镜像,例如 v3 版本的 redis
docker pull redis:3
2.3. 查看本地镜像
docker images

2.4. 删除镜像
Rm 默认是删除容器,rmi 表示删除镜像
docker rmi 镜像的ImageId

有时候一个镜像 id 对应多个容器,这个时候删除要通过镜像仓库名称的方式删除,不然会报错,因为同一个镜像 id 有多个
如果镜像已经创建容器了,可以强制删除,连容器一块删除
docker rmi -f 镜像id
3. 容器
3.1. 创建并且运行一个镜像
首先查找本地的 nginx 镜像,如果本地没有 nginx 镜像,则会从远程拉取。使用 run 命令,加上镜像名称,即可运行起来
docker run nginx
用上述这个命令直接运行的话,有几个问题:
- nginx 容器会前台运行
- 宿主机的网络和 nginx 容器时候隔离开的,宿主机无法访问到容器里的网络
端口映射和后台启动
为了解决上面两个问题,可以使用-d 后台运行,-p 将主机的端口:映射到容器的端口里,docker 使用的是 iptables 防火墙路由映射的功能
docker run -d -p 80:80 nginx
查看端口映射信息
docker ps

如果说,容器内有多个端口,想要一次性暴露出来,这些端口绑定到宿主机的随机端口上,可以用-P 参数
docker run -d -P nginx
下图中的 32768 是随机端口。

设置容器名称
因为容器 id 比较不好记住,操作的时候不方便,所以启动的时候,可以指定名称,这样对容器的操作比较方便
docker run -d -p 81:80 --name nginxName nginx

然后,就可以通过名字来操作了
docker stop nginxName
容器退出时候自动删除容器
有时候,容器依赖一些配置,如果没有配置的话,就启动不起来,但是即使启动失败了,执行 docker run 命令后,容器还是会创建了,这个时候产生的容器没啥用,还得手动去删除。所以这个时候可以使用--rm 参数,容器退出后自动删除,对于测试的时候可以用,但是 redis,mysql 这种存储数据的最好不要用

docker run --rm supermanito/helloworld
容器因为一些原因,关闭了,需要重启
指定容器关闭时的重启策略,有三种可选策略,通过--restart 参数设置
- no(默认):表示不重启
- on-failure:当失败时重启,还可以加上 3 指定最多重启 3 次,如果 3 次都失败就不再重启了,这种是针对异常关闭,如果是 docker stop 命令,不会重启
- always:只要已关闭就自动重启,服务器重启后也能自动启动
# 容器关闭后,重启三次
docker run -d --name nginx01 -P --restart on-failure:3 nginx
# docker一旦启动,容器就自动起来,不然的话默认是关闭的,需要手动启动各个容器
docker run -d --name nginx01 -P --restart always nginx
设置容器里的环境变量
有时候,我们需要通过环境变量判断一些程序逻辑,这个时候在 docker 启动的时候,通过-e 参数(也可以--env 来指定)进行指定就好了
# 设置了两个环境变量,多个环境变量,需要多个-e指定
docker run -d -P --name nginx_env -e JAVA_ENV=dev -e JAVA_VM=G1 nginx
查看容器的一些基础信息,包括环境变量:
docker inspect nginx_env

我们还可以通过 docker exec 命令,把命令发送给容器执行,-it 表示让容器启动一个终端来执行命令,要执行的 env 命令放在最后
[root@localhost ~]# docker exec -it nginx_env env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=9689859c69d1
TERM=xterm
JAVA_ENV=dev
JAVA_VM=G1
NGINX_VERSION=1.21.5
NJS_VERSION=0.7.1
PKG_RELEASE=1~bullseye
HOME=/root
限制容器的资源限制
可以限制的内容很多,可以通过 docker run --help查看 run 的一些参数信息
# -m 限制内存为8m,单位还可以是k,g,cpu设置为1个
docker run -d -rm -m 8m --cpus 1 nginx
那我们怎么知道,容器有没被限制呢,可以通过查看容器的实时状态查看
docker stats 容器id

执行 docker run 的时候报错
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: unable to retrieve OCI runtime error (open /run/containerd/io.containerd.runtime.v2.task/moby/9a0ed943a4f075981caaa8d059831515447adcf322294ab208badc6fee297c3c/log.json: no such file or directory): runc did not terminate successfully: exit status 127: unknown.
你的服务器(宿主机)上的 libseccomp 库版本过低,导致 Docker 的底层运行时工具 runc 无法正常工作。这在使用较新版本的 Docker 但操作系统较老(特别是 CentOS 7)时非常常见,只需要更新下库就行
yum update -y libseccomp
systemctl restart docker
3.2. 查看运行中的容器
查看正在运行中的所有容器
docker ps
查看所有状态的容器
docker ps -a
3.3. 删除容器
这个容器 id,可以是完整的容器 id,也可以是前缀好,只要能唯一定位到容器即可
docker rm 容器id
# 一次删除多个
docker rm 74350eb761cc c7353a2bf490
强行删除进行中的容器
运行中的容器可以删除吗?正常是不要这么操作,正常要先停止容器,然后再删除就好了。如果非要删除进行中的,可以-f 参数
docker rm -f 74350eb761cc
3.4. 停止容器
docker stop 容器id
3.5. 启动容器
docker start 容器id
4. 查看容器日志
以下就可以输出容器的日志信息,比如 nginx 容器的信息,以下命令一次性输出所有
docker logs 容器id
docker logs c1bd1b7f7f9a
如果想要实时查看最近的 20 条,可以用-f,是 flow 的简写
docker logs -f -n 20 ngix01
5. 进入容器内部
因为容器相当于一个小虚拟机,容器内和容器外,文件系统是隔离开的,可以进入容器内部
docker exec -it nginx01 /bin/bash
如果要退出的话,只需要输入 exit就好。
容器内和容器外的文件隔离方式其实也很简单,就从宿主机上专门申请一块磁盘目录,用于容器的存储
