Docker常用命令

前言

什么是Docker?
Docker就是一个容器,但是这个容器里什么都没有,所以我们根据需求不同就要不同的环境,这些环境就是镜像,我们可以用一个镜像生成多个容器,每个容器都有它的IDNAME

所以对于Docker的操作命令就可以分为三类:Docker命令 镜像命令容器命令

Docker信息

查看docker版本

1
docker version

显示docker系统的信息

1
docker info

批量删除

删除容器

Linux

删除所有容器

1
docker rm `docker ps -a -q`

获取退出的容器

1
docker ps -a --filter "status=exited" --format "{{.ID}}: {{.Names}} ({{.Status}})"

删除退出的容器

1
docker ps -a --filter "status=exited" --format "{{.ID}}" | xargs docker rm

Windows上

删除未运行的容器

1
docker container prune

删除镜像

获取悬空镜像

1
docker images -f "dangling=true"

上述命令中的-f参数是过滤器,dangling=true表示只显示悬空镜像,即没有被任何容器使用且没有标签的镜像。

删除悬空镜像

悬空镜像指的是没有标签且未被任何容器使用的镜像。

可使用以下命令将其删除:

1
docker image prune -f

这里的 -f 选项是为了避免需要手动确认操作。

删除所有未被使用的镜像

若你想删除所有未被任何容器引用的镜像,不管它是否有标签,可使用以下命令:

1
docker image prune -a -f

其中,-a 选项意味着删除所有未被使用的镜像,而 -f 选项则用于避免手动确认。

删除所有的镜像

1
docker rmi `docker images -q`

强制删除

1
docker rmi --force `docker images -q`

删除所有没有tag的镜像

1
docker rmi `docker images|grep none|awk '{print $3 }'|xargs`

镜像命令

常用命令

检索镜像

1
docker search image_name

下载镜像

1
docker pull image_name

列出镜像列表

1
docker images

删除一个或者多个镜像

1
docker rmi image_name

显示一个镜像的历史

1
docker history image_name

添加镜像的名字和tag

1
docker tag imageid name:tag

镜像导出导入

保存和加载镜像(save、load)

当需要把一台机器上的镜像迁移到另一台机器的时候,需要保存镜像与加载镜像。

1
2
3
4
5
6
7
8
9
# 保存镜像到一个tar包  
docker save image_name -o file_path
# 加载一个tar包格式的镜像
docker load -i file_path

# 机器a导出tar包
docker save image_name > /home/save.tar
# 使用scp将save.tar拷到机器b上,然后:
docker load < /home/save.tar

容器命令

启动容器

1
2
3
4
5
6
7
8
# 在容器中运行"echo"命令,输出"hello word"  
docker run image_name echo "hello word"

# 交互式进入容器中
docker run -i -t image_name /bin/bash

# 在容器(ubuntu)中安装新的程序
docker run image_name apt-get install -y app_name

举例

1
2
3
docker run -i -t -v /root/software/:/mnt/software/ 25c5298b1a36 /bin/bash

docker run -d -p 58080:8080 --name javaweb huangyong/javaweb:0.1 /root/run.sh

这条命令比较长,我们稍微分解一下,其实包含以下三个部分:

1
docker run <相关参数> <镜像 ID> <初始命令>

其中,相关参数包括:

  • -i:表示以“交互模式”运行容器
  • -t:表示容器启动后会进入其命令行
  • -v:表示需要将本地哪个目录挂载到容器中,格式:-v <宿主机目录>:<容器目录>.
    假设我们的所有安装程序都放在了宿主机的/root/software/目录下,现在需要将其挂载到容器的/mnt/software/目录下。
    
  • -d:表示以守护模式执行/bin/bash脚本,此时 Tomcat 控制台不会出现在输出终端上。
  • -p:表示宿主机与容器的端口映射,此时将容器内部的 8080 端口映射为宿主机的 58080 端口,这样就向外界暴露了 58080 端口,可通过 Docker 网桥来访问容器内部的 8080 端口了。
  • –name:表示容器名称,用一个有意义的名称命名即可。
    使用在Docker run的时候使用`--restart`参数来设置。    
    `no-container`:不重启.   
    `on-failure-container`:退出状态非0时重启.    
    `always`:始终重启. 
    
    需要说明的是,不一定要使用“镜像 ID”,也可以使用“仓库名:标签名”,例如:docker.cn/docker/centos:centos6。

查看容器

1
2
3
4
5
6
# 列出当前所有正在运行的container  
docker ps
# 列出所有的container
docker ps -a
# 列出最近一次启动的container
docker ps -l

docker ps 命令用于列出容器,默认情况下它会显示容器的基本信息,比如容器 ID、镜像名称、创建时间、状态和端口等。不过,你可以通过 --filter 选项对输出进行过滤,并通过 --format 选项自定义显示的属性。

添加属性过滤

docker ps 支持使用 --format 选项来控制输出格式。你可以使用 Go 模板语法来指定要显示的字段。

以下是 docker ps 可以使用的完整字段列表:

  • .ID: 容器 ID
  • .Image: 镜像名称
  • .Command: 启动命令
  • .CreatedAt: 创建时间
  • .RunningFor: 运行时间
  • .Ports: 端口映射
  • .Status: 容器状态
  • .Size: 容器大小
  • .Names: 容器名称
  • .Labels: 容器标签
  • .Networks: 容器网络
  • .Mounts: 挂载点

示例

显示容器名称、镜像和状态:

1
docker ps -a --format "{{.Names}}: {{.Image}} [{{.Status}}]" | column -t

状态列只取状态

1
docker ps -a --format "{{.Names}}: {{.Image}} {{.Ports}} [{{.Status}}]" | sed 's/\([^[]*\[[^ ]*\).*/\1]/' | column -t

显示容器名称、镜像和状态:

1
docker ps -a --format "{{.Names}}: {{.Image}} [{{.Status}}]" | column -t

显示容器名称、镜像、状态和端口:

1
docker ps -a --format "{{.Names}} ({{.Image}}) [{{.Status}}] {{.Ports}}"

显示容器 ID 和名称:

1
docker ps -a --format "{{.ID}}: {{.Names}}"

显示容器镜像和状态:

1
docker ps -a --format "{{.Image}}: {{.Status}}"

显示容器名称、镜像和运行时间:

1
docker ps -a --format "{{.Names}} [{{.Status}}]: {{.Image}} ({{.RunningFor}})" | column -t

显示容器端口映射:

1
docker ps -a --format "{{.Names}}: {{.Ports}}"

显示容器标签:

1
docker ps -a --format "{{.Names}}: {{.Labels}}"

显示容器网络:

1
docker ps -a --format "{{.Names}}: {{.Networks}}"

结合过滤器

你还可以结合 --filter 选项来过滤容器,然后使用 --format 选项自定义显示属性。

例如,只显示运行中的容器并显示其名称和镜像:

1
docker ps -f "status=running" --format "{{.Names}}: {{.Image}}"

退出的列表

1
docker ps -a -f "status=exited" --format "{{.Names}}\t{{.Command}}\t{{.Status}}"

保存自定义格式

如果你经常使用某个自定义格式,可以将它保存为环境变量的别名。例如:

1
alias dps='docker ps -a --format "{{.ID}}: {{.Names}} ({{.Status}})"'

这样你可以通过简单的命令 dps 来查看自定义格式的容器信息。

希望这些信息能帮助你更好地管理和查看 Docker 容器!如有其他问题,欢迎随时询问。

导入导出

导出 Docker 容器

要把一个正在运行或者已经停止的 Docker 容器导出成一个文件,可以使用 docker export 命令。

以下是具体命令示例:

1
docker export -o <导出文件名.tar> <容器 ID 或名称>
  • -o:指定导出文件的路径和文件名。
  • <导出文件名.tar>:你要导出的文件名,通常以 .tar 结尾。
  • <容器 ID 或名称>:你想要导出的 Docker 容器的 ID 或者名称。

例如,要将名为 my_container 的容器导出为 my_container_export.tar 文件,可以使用以下命令:

1
docker export -o my_container_export.tar my_container

导入 Docker 容器

当你有了导出的容器文件后,就可以使用 docker import 命令将其导入到 Docker 中。

以下是具体命令示例:

1
docker import <导出文件名.tar> <仓库名称:标签>
  • <导出文件名.tar>:你之前导出的容器文件的名称。
  • <仓库名称:标签>:导入后的镜像的名称和标签。

例如,将 my_container_export.tar 文件导入为名为 my_imported_image:latest 的镜像,可以使用以下命令:

1
docker import my_container_export.tar my_imported_image:latest

容器操作

对容器的操作(rm、stop、start、kill、logs、diff、top、cp、restart、attach)

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
# 删除所有容器  
docker rm `docker ps -a -q`

# 删除单个容器
docker rm Name/ID

# 停止、启动、杀死一个容器
docker stop Name/ID
docker start Name/ID
docker kill Name/ID

# 从一个容器中取日志; -t 显示时间
docker logs Name/ID

# 列出一个容器里面被改变的文件或者目录,list列表会显示出三种事件,A 增加的,D 删除的,C 被改变的
docker diff Name/ID

# 显示一个运行的容器里面的进程信息
docker top Name/ID

# 从容器里面拷贝文件/目录到本地一个路径
docker cp Name:/container_path local_path
docker cp ID:/container_path local_path

# 从本地路径拷贝文件/目录到容器内
docker cp local_path Name:/container_path
docker cp local_path ID:/container_path

# 重启一个正在运行的容器;
docker restart Name/ID

# 运行已运行容器的命令
docker attach ID

# 退出attach
Ctrl+P+Q

# 在运行中的容器里运行命令
docker exec -t -i Name/ID /bin/bash

导出日志

1
docker logs mydocker>mydocker.log

查看容器IP

查询单个容器 IP 地址:

使用下面命令可以查看容器详细信息,里面包含 IP 地址信息:

1
docker inspect <container id>

或者使用下面命令直接输出 IP 地址信息:

1
docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container id>

或者:

1
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container id>

查询全部容器 IP 地址:

任选其一即可:

1
docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}' $(docker ps -aq)

或者:

1
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

其中

-f--format的简写

查看容器内网络

在docker中,为了尽可能缩减镜像大小,常常不会包含一些常用的工具,类似ping,curl,tcpdump

很多时候我们需要知道容器内部解析的域名ip信息,如果没有这些工具,本来很简单的事就变得很麻烦,通过以下步骤就可以通过nsenter解决以上问题

如果我们想利用主机上的工具,能够实现这种需求的工具就是我们今天要介绍的nsenter

工具安装

1
yum install util-linux -y

参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
nsenter [options] [program [arguments]]

options:
-t, --target pid:指定被进入命名空间的目标进程的pid
-m, --mount[=file]:进入mount命令空间。如果指定了file,则进入file的命令空间
-u, --uts[=file]:进入uts命令空间。如果指定了file,则进入file的命令空间
-i, --ipc[=file]:进入ipc命令空间。如果指定了file,则进入file的命令空间
-n, --net[=file]:进入net命令空间。如果指定了file,则进入file的命令空间
-p, --pid[=file]:进入pid命令空间。如果指定了file,则进入file的命令空间
-U, --user[=file]:进入user命令空间。如果指定了file,则进入file的命令空间
-G, --setgid gid:设置运行程序的gid
-S, --setuid uid:设置运行程序的uid
-r, --root[=directory]:设置根目录
-w, --wd[=directory]:设置工作目录

如果没有给出program,则默认执行$SHELL

获取容器pid

1
docker inspect taier_taier_1 -f '{{.State.Pid}}'

结果为

15728

执行nsenter命令

1
2
nsenter -n -t 15728
ifconfig

注意

这个命令没有任何输出,通过ifconfig命令查看当前ip可以确定我们已经进入了容器的网络空间

这时候主机上的命令都可以使用

1
2
3
ping 192.168.7.101
ping hadoop01
ping hadoop02

如果想退出当前网络空间,返回系统网络空间,输入exit就行

1
exit

如果内部无法访问外部网络

安装brctl

1
yum install -y bridge-utils

重建docker0网桥

1
2
3
4
5
6
sudo service docker stop
sudo pkill docker
sudo iptables -t nat -F
sudo ifconfig docker0 down
sudo brctl delbr docker0
sudo service docker start

实际操作

下载Tomcat8镜像(操作方式见自定义Dockerfile构建镜像)

1
docker pull registry.cn-hangzhou.aliyuncs.com/psvmc/oraclejdk-tomcat8

查看镜像ID

1
docker images

运行镜像

1
docker run -d -p 8081:8080 --name tomcat01 -v /data/wwwroot/tomcat01/:/opt/tomcat8/webapps/  -v /data/wwwroot/tomcat01_log/:/opt/tomcat8/logs/ --restart=always 71dc929e155c

查看容器运行状态

1
docker ps -a

查看tomcat启动日志

1
docker logs tomcat01

我们运行了tomcat 那么怎样进入tomcat运行的环境呢

1
2
3
4
# docker exec意思是:在`tomcat01`下面运行一个命令,在这里,运行的是/bin/bash
# -t 表示分配一个pseudo-TTY,-i 表示可交互
# tomcat这个image的默认工作目录是/usr/local/tomcat
docker exec -t -i tomcat01 /bin/bash

接下来 我们退出tomcat的运行环境(Ctrl+P+Q)

把文件拷贝到容器中

1
docker cp /root/test.war tomcat01:/usr/local/tomcat/webapps/test.war

重启容器

1
docker restart tomcat01

常见问题

1) 怎样在一运行的容器中添加端口映射?
不能直接添加端口映射。只能先保存(commit)为镜像 再重新运行(run)

  1. import/export 与 save/load 的区别?
    import应用于容器 save应用于镜像

自动启动容器内服务

Docker 容器运行后 自动启动服务
docker中的容器运行后 里面的服务就算设置了开机启动也不会启动。
解决方式是建一个文件/home/auto_service.sh

1
2
3
4
5
#!/bin/sh
service nginx start
service mysqld start
service tomcat7 start
/bin/bash

第一行不能少 来标示文件的类型 最后一行也不能少 否则会在服务启动后自动退出容器

运行命令

1
docker run -i -t --name javaweb -p 80:80 -p 8080:8080  fec9183579a7 /home/auto_service.sh

4) 无法ping容器的IP地址 无法用容器的ip ssh登录

I cannot ping my containers。
Unfortunately, due to limitations in macOS, we’re unable to route traffic to containers, and from containers back to the host.

这是官网给的解释 由于macOS的限制
所以在mac上只能把内部的22端口映射到外部 直接通过映射出来的端口访问

镜像无法删除

1
docker images

假如

image-20210301124946140

进入文件目录

1
2
cd /var/lib/docker/image/overlay2/imagedb/content/sha256
ls

找到如下的文件(前12位和前面的IMAGE ID 一致 )

f6d0b4767a6c466c178bf718f99bea0d3742b26679081e52dbf8e0c7c4c42d74

直接删除即可

1
rm -rf f6d0b4767a6c466c178bf718f99bea0d3742b26679081e52dbf8e0c7c4c42d74

这时再查看镜像就没有了