环境:centos7.9 docker version 20.10.14
本篇我们来介绍docker的常用命令。
docker镜像都是只读的。当容器启动后,一个新的可写的镜像被加载到镜像层的顶部,这一层通常被叫做容器层,容器层之下的都叫镜像层。
我们平时执行命令 docker pull ubuntu:12.04 ,并没有严格区分镜像名和镜像仓库的意思;
安装好的docker后台守护进程之后,此时默认镜像仓库是Docker Hub 公共注册服务器中的仓库。
当使用docker的默认仓库时,docker pull ubuntu:12.04 这条命令实际上相当于 docker pull registry.hub.docker.com/ubuntu:12.04 命令,即从注册服务器 registry.hub.docker.com 中的 ubuntu 仓库来下载标记为 12.04 的镜像。
一般的,我们可能习惯了直接说拉取一个ubuntu 12.04的镜像,在不太严格的说法下,我们会认为ubuntu 是镜像的名字,严格得讲ubuntu 其实是镜像仓库名。
同理,docker pull nginx:1.18,nginx是镜像仓库名字,当然,再不严格区分的情况下,我们还是习惯叫做镜像名字。
[root@docker ~]# systemctl start docker #启动docker
[root@docker ~]# systemctl status docker #查看docker状态
[root@docker ~]# systemctl restart docker #重启docker状态
[root@docker ~]# systemctl stop docker #停止docker状态
Docker daemon运行在docker host上,负责创建、运行、监控容器,构建、存储镜像,默认情况下,docker daemon只响应来之本地host的客户端请求,如果要允许允许客户端请求,需要在配置文件中打开tcp监听,步骤如下:
1、编辑配置文件
vim /usr/lib/systemd/system/docker.service
#在下面这句后面加上 -H tcp://0.0.0.0 表示允许来自任意IP客户端链接
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0
2、重启Docker daemon
systemctl daemon-reload
3、远程客户端连接docker daemon,使用-H参数
docker -H 192.168.118.128 info
[root@docker ~]# which docker #这是docker的客户端命令行工具
/usr/bin/docker
[root@docker ~]# docker version #查看docker的版,包含客户端版本和服务端版本
[root@docker ~]# docker -h #查看docker帮助文档
[root@docker ~]# docker info #显示docker系统的信息
Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]
常用参数:
--all :列出全部镜像,默认值
-q :列出镜像的id
[root@docker ~]# docker images #列出本地的所有镜像
[root@docker ~]# docker images hello-world #列出指定的镜像
[root@docker ~]# docker images -q hello-world #列出指定镜像的ID
[root@docker image]# docker images -aq #列出全部镜像的ID
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
ubuntu 12.04 74fe38d11401 4 weeks ago 209.6 MB
nginx 1.24 54fe38d11201 3 weeks ago 149.6 MB
在列出信息中,可以看到几个字段信息
来自于哪个仓库,比如 ubuntu
镜像的标记,比如 12.04
镜像ID号(唯一)
创建时间
镜像大小
[root@docker ~]# docker info | grep 'Docker Root Dir' #查看docker数据存储位置
Docker Root Dir: /var/lib/docker
[root@docker ~]#
[root@docker ~]# ll -th /var/lib/docker/image/overlay2/imagedb/content/sha256/ #查看镜像存放位置
total 8.0K
-rw------- 1 root root 7.5K Jul 23 18:55 605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85 #这就是镜像的文件,但是这个文件只是一个JSON格式文件,作用是记录镜像和容器的配置关系
[root@docker ~]# docker images #查看镜像id,这镜像id其实就是简写
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 6 months ago 141MB
[root@docker ~]#
[root@docker ~]# docker search nginx #从镜像仓库中搜索镜像
docker [image] pull NAME[:TAG]
其中:NAME是镜像仓库名称,TAG是镜像的标签。
对于docker镜像来说,如果不显示指定 TAG,则默认会选择latest标签,这样会下载仓库中最新版本的镜像。
[root@docker ~]# docker pull hello-world:1.0.0 #从默认仓库拉取一个指定版本的镜像
[root@docker ~]# docker pull hello-world #拉取一个指定版本的镜像,不加tag标签号默认pull最新的镜像
docker ps [option]:查看当前宿主机上容器列表。默认只查看runing中的容器。
[option]主要有:
-a :相当于all,查看所有的容器列表。
-q : 只显示容器ID,如docker ps -aq docker images -q
docker run是创建并启动容器,其是docker create 和docker start的结合,docker run的使用语法如下:
语法:docker run [options] image [command] [arg...]
option说明:有些是单个-符号,有些是两个-符号
--name :为容器指定一个名字,如果不为容器指定名称,则docker自动分配一个名称
-d :后台运行容器,并返回容器ID,也即启动守护式容器
-i :以交互式运行容器,通常与-t同时使用
-t :为容器重新分配一个伪输入终端,通常与-i同时使用
-P :随机端口映射,系统随机分配一个空闲端口
-p :指定端口映射,如,-p 8089:80 其中前面8089是暴露在外部的端口,后面那个80是容器内部端口,我们知道docker是沙箱机制,想要外部程序能访问docker就必须暴露一个端口让外部访问;-p可以指定多个,支持的格式有ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
--restart :重启策略,当容器退出时执行何种重启策略,Docker容器的重启策略如下:
no,默认策略,在容器退出时不重启容器
on-failure,在容器非正常退出时(退出状态非0),才会重启容器
on-failure:3,在容器非正常退出时重启容器,最多重启3次
always,在容器退出时总是重启容器
unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
--rm : 当容器退出时自动删除容器
-v : 挂载宿主机目录到容器目录以实现容器数据持久化(目录或文件都可以)
演示范例:
[root@docker ~]# docker run -it -d -p 8089:8080 tomcat /bin/bash
[root@docker ~]# docker run -d --name dev-nginx --restart=on-failure:3 nginx:latest
#使用hostPort:containerPort格式将本地的5000端口映射到容器的5000端口,此时默认所有网卡IP地址都监听5000端口
[root@docker ~]# docker run -d -p 5000:5000 training/webapp python app.py
#使用ip:hostPort:containerPort 格式指定要绑定的IP地址+端口
docker run -d -p 192.168.158.130:5000:5000 training/webapp python app.py
#使用 ip::containerPort 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口供外部访问容器
docker run -d -p 192.168.158.130::5000 training/webapp python app.py
#可以使用 udp 标记来指定 udp 端口
docker run -d -p 192.168.158.130:5000:5000/udp training/webapp python app.py
当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
检查本地是否存在指定的镜像,不存在就从公有仓库下载
利用镜像创建并启动一个容器
分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
从地址池配置一个 ip 地址给容器
执行用户指定的应用程序
语法:
Usage: docker port CONTAINER [PRIVATE_PORT[/PROTO]]
List port mappings or a specific mapping for the container
[root@docker ~]# docker run -d -p 8777:80 --name nginx nginx:1.17
a366d85fdf64
[root@docker ~]# docker port a366d85fdf64
80/tcp -> 0.0.0.0:8777
80/tcp -> :::8777
#其实这样也能看的出来映射的端口
root@ccw3 ~]# docker ps | grep a366d85fdf64
a366d85fdf64 nginx:1.17 "nginx -g 'daemon of…" 5 minutes ago Up 5 minutes 0.0.0.0:8777->80/tcp, :::8777->80/tcp nginx
[root@ccw3 ~]#
容器有一共有7种状态:cerated(已创建)、restarting(重启中)、running(运行中)、removing(迁移中)、paused(暂停)、exited(已停止)、dead(死亡)。
可以使用docker create 先创建容器,此时容器处于Created状态,处于created状态的容器可以使用docker start 启动容器,如下:
[root@docker ~]# docker create --name dev1-nginx nginx:latest #创建容器
44494bfa4e8ab0f4b906d7f437a9c21f0e309d6fc292aac4ce56905cac6e3160
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44494bfa4e8a nginx:latest "/docker-entrypoint.…" 5 seconds ago Created dev1-nginx
[root@docker ~]# docker start 44494bfa4e8a #启动容器
44494bfa4e8a
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44494bfa4e8a nginx:latest "/docker-entrypoint.…" About a minute ago Up 4 seconds 80/tcp dev1-nginx
当一个容器被停止之后(状态是exit),可使用docker start 命令重新启动容器,如下:
[root@docker ~]# docker start nginx #重启启动被停止的容器,既可以使用name来指定容器,也可以使用容器id来指定容器
[root@docker ~]# docker restart nginx #重启容器,既可以使用name来指定容器,也可以使用容器id来指定容器
docker stop命令表示停止某个容器,容器被停止了并不是表示该容器就消失了(容器状态为Exited),停止容器只是表示该容器不再运行,可以使用docker start重新启动容器的。
[root@docker ~]# docker stop 65d86177eb63 #既可以使用容器nginx也可以使用容器id
发送信号给容器,默认发送的是强制停止信号,当需要强制停止容器的时候,可以使用该命令替代docker stop命令,如下:
[root@docker ~]# docker kill b8eac755926d #停止后的容器其实还在,只是状态变成Exited
可以通过 docker pause命令来暂停某个容器的运行,如下:
[root@docker ~]# docker pause 65d86177eb63
处于暂停的容器不会占用CPU,可以通过docker unpause 命令恢复暂停的容器,如下:
[root@docker ~]# docker unpause 65d86177eb63
我们知道,当使用docker stop 命令或docker kill 命令停止容器后,容器的状态就会变成Exited退出状态,此时这些容器仍占用host上的资源,如果你想重启这些容器,可以通过docker start命令来重启它们,如果确定不在需要这些容器,那么可以使用docker rm命令删除容器,如下:
[root@docker ~]# docker rm 65d86177eb63 #删除一个已经停止的容器,如果容器正在运行,则报错
[root@docker ~]# docker rm -f dev-nginx #-f表示强制删除,即使容器正在运行也要强制删除
[root@docker ~]# docker rm -v $(docker ps -aq -f status=exited) #删除状态是exited的容器
docker容器后台运行就必须有一个前台进程,容器的命令如果不是那些一直挂起的命令(如top,tail)就会自动闪退,因为他觉得没事做了就会自动自杀,这是docker的机制问题。
[root@docker ~]# docker rmi `docker images -qa` #删除全部的镜像,危险命令,慎用
[root@docker ~]# docker rmi -f nginx:1.0.0 #强制删除nginx:1.0.0镜像
docker logs [option] container_ID:查看指定容器的日志信息
option参数如下:
-n 行数: 查看日志末尾指定行数,不加n表示显示全部行(-n等价于下面的--tail参数)
--tail 行数 :查看日志末尾指定行数,不加n表示显示全部行
-t:显示时间戳
-f :持续追踪日志
[root@docker ~]# docker logs -f 2c627df4 #-f追踪日志
[root@docker ~]# docker logs -n 22 -f 2c627df4 #-f追踪日志,-n指定输入日志行数
进入容器有两种方法:
方式1:docker exec -it container_id /bin/bash
方式2:docker attach container_id
两种方式的区别:exec -it 表示在容器打开新的终端并开启新进程,这样即使exit也只是退出自己的终端。attach则是直接进入容器终端,不会启动新的进程。
语法: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
参数:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
--env-file list Read in a file of environment variables
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the container
[root@docker ~]#
[root@docker ~]# docker exec -it 2c627df4531d bash #进入到容器内,可以指定容器ID和容器名字
[root@docker ~]# docker top 4bfc8c2b9777
UID PID PPID C STIME TTY TIME CMD
1000 34023 3969 0 07:28 ? 00:00:04 elasticsearch_exporter --es.uri=http://det-es-7-master:9200
[root@docker ~]#
docker inspect 命令用于查案docker对象信息,docker对象包括镜像、容器等,语法如下:
docker inspect container_ID #查看容器信息,json格式显示(信息很全)
docker inspect image_ID #查看镜像信息,json格式显示(信息很全)
docker container 命令用于管理容器,有很多子命令,其中 docker container inspect 命令也能用于查看容器详细信息,如下:
[root@docker ~]# docker container inspect nginx #查看nginx容器的详细信息
#docker container top 命令用于查看容器运行的进程
#当容器里面没有ps -ef命令时,使用docker container top 命令可以方便的查看容器运行的进程
#语法,
[root@rancher _data]# docker container top --help
Usage: docker container top CONTAINER [ps OPTIONS]
Display the running processes of a container
[root@rancher _data]# docker container top nginx1 #可以接ps的参数,如docker container top nginx1 -ef
UID PID PPID C STIME TTY TIME CMD
root 9513 9483 0 00:12 ? 00:00:00 nginx: master process nginx -g daemon off;
101 9580 9513 0 00:12 ? 00:00:00 nginx: worker process
101 9581 9513 0 00:12 ? 00:00:00 nginx: worker process
101 9582 9513 0 00:12 ? 00:00:00 nginx: worker process
101 9583 9513 0 00:12 ? 00:00:00 nginx: worker process
#容器里面没有ps命令
[root@rancher _data]# docker exec -it nginx1 bash
root@e88229ce4a8a:/# ps -ef
bash: ps: command not found
语法:
docker port CONTAINER [PRIVATE_PORT[/PROTO]]
[root@docker ~]# docker port nginx #查看容器端口映射
80/tcp -> 0.0.0.0:8080
80/tcp -> :::8080
[root@docker ~]# docker port 2c627df4531d #查看容器端口映射
80/tcp -> 0.0.0.0:8080
80/tcp -> :::8080
[root@docker ~]#
docker的commit操作:当镜像运行之后可以修改容器里面的内容,在提交成一个新的镜像。
语法:docker commit -m "新镜像描述信息" -a "作者" container_ID 新镜像名:[标签]
注意:要加双引号(这里称之为镜像名,严格意义上叫做仓库名,REPOSITORY就是仓库的意思)
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
[root@docker ~]# docker commit 2c627df4531d nginx_install_vim:1.7 #从容器中创建一个新的镜像
sha256:adabed2f4b8eeb4e3c0ad5491053d888ac2075957a9ae9f02c9f32a6104947cc
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx_install_vim 1.7 adabed2f4b8e 5 seconds ago 141MB #已经生成新的镜像了
nginx latest 605c77e624dd 6 months ago 141MB
[root@docker ~]#
语法:docker save [OPTIONS] IMAGE [IMAGE...] #可以同时指定多个镜像,表示多个镜像都报错导出到同一个文件
-o 参数指定输出到文件
[root@docker ~]# docker save -o centos.tar centos:latest #导出centos:latest为一个tar包
[root@docker ~]# docker save -o many-images.tar centos:latest nginx:1.18 tmocat:7.7 #同时到处多个镜像为一个tar包
docker image save跟上面的docker save功能一模一样,docker image 命令是用于镜像管理的。
语法:docker image save [OPTIONS] IMAGE [IMAGE...]
-o 参数指定输出到tar文件,文件也可以是tar.gz格式
[root@docker ~]# docker image save -o centos.tar centos:latest #导出centos:latest为一个tar包
使用docker save命令导出镜像后可以使用docker load 导入镜像,如下:
语法:docker load [OPTIONS]
-i, --input string Read from tar archive file, instead of STDIN #-i指定tar文件
-q, --quiet Suppress the load output #-q表示静默方式
[root@docker ~]# docker load -i centos.tar #导入镜像
docker image load 命令与 docker load 都是导入镜像,docker image load 命令是专门用于管理镜像的。
[root@docker ~]# docker image load -i nginx.tar.gz #docker image load导入镜像
docker export [OPTIONS] CONTAINER
-o, --output string Write to a file, instead of STDOUT
[root@docker ~]# docker export -o mysql5.7_test.tar mysql5.7 #将一个容器导出为一个tar文件
Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
Import the contents from a tarball to create a filesystem image
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Set commit message for imported image
[root@docker ~]# docker import mysql5.7_test.tar mysql5.7:v1 #导入镜像,指定镜像名称和版本号
[root@docker ~]# cat mysql5.7_test.tar | sudo docker import - mysql5.7:v1 #等价上面一条
save与load是一对,export与import是一对,它们的区别:
1、docker sava 保存的是镜像(image),docker export 保存的是容器(container);
2、docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;
3、docker load不能对载入的镜像重命名,而docker import可以为载入的镜像重命名。
• 注意: save导出的是镜像打包的tar文件,此类文件只能用load进行导入。
• import只能导入export生成的容器镜像tar文件或基于本地的镜像模板;import通常和cat命令搭配使用。
镜像访问地址形式registry.devops.com/demo/hello:latest,若没有前面的url地址,则默认寻找docker hub中的镜像,如果没有tag,则默认使用latest作为标签,比如,docker pull nginx,会被解析成docker.io/library/nginx:latest。一般的,在企业中会使用私有镜像仓库,而仓库一般使用域名,这样整个镜像就会是这样:wuhukd.com/dev/nginx:1.0.0,其中wuhukd.com域名,dev是仓库名称,nginx:1.0.0是镜像。
Usage: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
[root@docker ~]# docker tag nginx:1.7.9 xiaoming.com/my_harbor/nginx:1.0.0
docker cp 复制命令,从容器复制文件到物理主机或从主机复制文件到容器。
语法:
docker cp container_ID:file_path host_filesystem_path
docker cp host_filesystem_path container_ID:file_path
[root@docker ~]# docker cp 15d0def0fd10:/usr/local/tomcat/webapps/ /home/guo/Test #从容器中复制文件到宿主机
[root@docker ~]# docker cp /home/guo/Test 31812cb98a0c:/usr/local/tomcat #复制文件到容器中
[root@docker ~]# docker volume --help
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
#列出全部的volume
docker volume ls
#查看指定名字的volume的详细信息
docker volume inspect a0dc63aae530f4070bb34e1c5331319c93a97f3727e6cf60415b7847010dcaf8
#移除全部未使用的本地volume
docker volume prune
#删除指定的volume
docker volume rm a0dc63aae530f4070bb34e1c5331319c93a97f3727e6cf60415b7847010dcaf8
示例:
#创建一个数据卷,名称叫做nginx
[root@docker ~]# docker volume create nginx
nginx
[root@docker ~]# docker volume ls | grep nginx
local nginx
[root@docker ~]# docker volume inspect nginx
[
{
"CreatedAt": "2023-08-27T14:40:43+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nginx/_data",
"Name": "nginx",
"Options": {},
"Scope": "local"
}
]
#容器使用数据卷,-v参数时加上卷名即可
[root@docker ~]# docker run -d --name nginx -p 8081:80 -v nginx:/usr/share/nginx/html nginx:latest
57022b423ec03bdb1a7a178544d422b262daa1b2861ba8a509a20962ed3051cf
[root@docker ~]# docker inspect nginx
"Mounts": [ #查看挂载信息
{
"Type": "volume", #类型是数据卷
"Name": "nginx",
"Source": "/var/lib/docker/volumes/nginx/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
#可以看到,nginx已经使用了nginx数据卷
#注意
#使用数据卷 bind mount ,-v参数,不会产生volume,如下:
docker run -d --name nginx -p 8081:80 -v /root/nginx/html:/usr/share/nginx/html nginx:latest
docker inspect nginx
"Mounts": [
{
"Type": "bind", #可以看到类型是bind,所以没有产生volume
"Source": "/root/nginx/html",
"Destination": "/usr/share/nginx/html",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
#编写好Dockerfile文件之后就可以使用docker build命令构建镜像了
#Dockerfile编写参考:https://blog.csdn.net/MssGuo/article/details/126001887
[root@docker dockerfile]# docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--force-rm Always remove intermediate containers
--network string Set the networking mode for the RUN instructions during build (default "default")
--no-cache Do not use cache when building the image
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
-t, --tag list Name and optionally a tag in the 'name:tag' format
.........................
#基本的格式为 docker build [选项] 路径 ,该命令将读取指定路径下(包括子目录)的 Dockerfile,并将
#该路径下所有内容发送给 Docker 服务端,由服务端来创建镜像。因此一般建议放置 Dockerfile 的目录为空
#目录。也可以通过 .dockerignore 文件(每一行添加一条匹配模式)来让 Docker 忽略路径下的目录和文件。
#构建镜像,--no-cache表示不缓存,镜像是分层的,如果已经构建过了则docker会使用缓存,这里使用--no-cache表示不使用缓存
# -t 指定镜像名称和版本,如果不指定-t ,则构建出来的镜像没有名称和版本号
# 最后一个点.表示当前目录,docker build指令会默认寻找当前目录下名叫Dockerfile的文件进行构建镜像
# -f指定Dockerfile文件,不指定时默认寻找当前目录下的名称叫做Dockerfile的文件
[root@docker dockerfile]# docker build --no-cache -t my_website:1.1.1 .
docker system df
docker system prune
docker system prune -a
docker images -f dangling=true