Docker常用命令

前言

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

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

Docker信息

查看docker版本

1
docker version

显示docker系统的信息

1
docker info

批量删除

删除容器

删除所有容器

1
docker rm `docker ps -a -q`

删除镜像

删除所有的镜像

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

保存和加载镜像(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

添加镜像的名字和tag

1
docker tag imageid name:tag

容器命令

启动容器

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

容器保存为镜像(commit)

1
docker commit ID new_image_name

如:

1
docker commit 57c312bbaad1 psvmc/javaweb:0.1

该容器的 ID 是57c312bbaad1,所创建的镜像名是psvmc/javaweb:0.1,随后可使用镜像来启动 Java Web 容器。

导入导出

1
2
3
4
5
#可以使用 docker export 命令,导出容器快照到本地文件。
sudo docker export 7691a814370e > ubuntu.tar

#可以使用 docker import 从容器快照文件中再导入为镜像
sudo docker import - test/ubuntu:v1.0

对容器的操作(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

这时再查看镜像就没有了