前言  

本讲是从Docker系列讲解课程,单独抽离出来的一个小节,重点介绍八大核心命令和一些常用的辅助命令,比如inspect、logs、push、commit等。如果你想,通过部署Tomcat容器(从查找镜像、到拉取、到运行、最后到移除)来熟悉这些命令的使用,点击进入。 

一、服务启动相关命令

1.docker 服务启动停止命令(linux基础)            

service docker start #启动docker 
service docker restart #重启docker 
service docker status #查看运行状态
service docker stop #停掉服务
systemctl start docker  #启动docker
systemctl restart docker  #重启docker
systemctl status docker  #查看运行状态
systemctl enable docker #设置开机自动启动

2.docker 容器启动停止命令

docker ps #查看正在运行的容器
docker run -d --name nginx-v1 nginx:latest #启动容器
docker start redis #启动一个或多个已经被停止的容器
docker restart redis  #重启容器
docker stop nginx-v1 #根据容器名称停掉指定容器
docker kill redis  #杀掉一个运行中的容器

温馨提示:

对于初学者而言、不知道什么时候用docker start 、什么时候用docker run ,总之需要运行容器时,不管三七二十一,就直接docker run -d

引发的问题:docker ps -a ,会发现同一个镜像竟然后台有多个容器多个副本,其中大部分的状态是Exited,可能只有一个状态是Up上线。

此时是不是很懵逼,恨不得用docker rm $(docker ps -qa)移除掉全部容器,然后再重新docker run ,你当然可以这么做,但是,怎么避免该问题再次出现?

最好的办法,当你每次想docker run -d 时,先用命令docker ps -a 来查看一下后台的容器,是不是已经有你需要的容器,并且它的状态是Exited,如果有,你仅仅需要通过docker start 命令,启动它就可以了。如果你想了解更多的Docker容器的各种状态,点击这里,带你飞。

小技巧:

docker [stop | start |restart ] 容器ID时,如果容器的前缀唯一,容器ID可以写前两个字母/数字,不必写全。

docker build 后如何使用 docker build . -t_docker build 后如何使用

二、八大核心命令

1.docker pull 从远程仓库抽取镜像

语法:docker pull 镜像名<:tags>

tags是标签的意思,如果不添加该参数,就会默认拉取最新版本。

docker pull tomcat  #默认就是获取latest最新版
docker pull tomcat:latest  #明确指定获取最新版
docker pull tomcat:8.5.46-jdk8-openjdk   #拉取指定版本镜像

2.docker images 查看本地已下载镜像

查看已下载的本机镜像列表

docker images #列出本地镜像
docker images -a  #列出本地镜像(含中间映像层)
docker images -q  #只显示镜像ID
docker images -qa #只显示镜像ID(含中间映像层)
docker images --digests #显示镜像摘要信息(DIGEST列)
docker images --no-trunc  #显示镜像完整信息

3.docker run 启动容器

语法:docker run镜像名<:tags> 

如果没有运行docker pull 命令,而直接运行docker run命令,则该run命令会自动运行pull从远程仓库抽取镜像,然后自动运行容器。

--name 为容器指定一个名称

-e 设置环境变量,该环境变量看覆盖Dockerfile中的ENV环境变量

-p

-P

-it 其中,-i以交互模式运行容器 ;-t为容器重新分配一个伪输入终端

-d 后台运行容器,并返回容器ID (没有此参数,容器在前台窗口运行,窗口关,随之关)

#docker run -d --name nginx-v2 nginx:latest  后台运行容器

-v 将宿主机目录挂载到容器内  ;格式:宿主机目录:容器目录

注:前后两个目录路径,除了用:冒号外,也可以使用空格代替。

docker run -it -v /suzhu_data:/contain_data nginx:1.12 /bin/bash  #启动容器时,直接指定挂载映射目录,并进入容器内部
exit #退出容器

宿主机本地路径suzhu_data目录和容器内contain_data路径做映射(可以粗略的认为容器内的contain_data是宿主机suzhu_data目录的硬链接,注意:真实情况,是不允许给目录创建硬链接的);通常情况下,宿主目录存放的是经常需要变动的文件。

挂载的好处:多个容器,都映射同一个宿主目录,便于统一管理(类似于Tomcat集群,所有的Tomcat的Webapps目录指向同一个web工程目录,每次部署,只需要部署一份)。

-v参数引申用法:

挂载时,可以指定挂载的可读方式,如果不希望在容器内部修改挂载目录(中的文件),可以写作:-v /suzhu_data:/contain_data:ro,其中ro-read only的意思。

注:默认在容器内部是可以修改宿主的源挂载目录内容的(它们之间类似于硬链接的关系)。 

--rm 容器退出时自动清理容器内部的文件系统(常用于一次性的测试环境),同时会清理容器的匿名data volumes。

所以,执行docker run命令带--rm命令选项,等价于在容器退出后,执行docker rm -v (该-v与docker run -v是相互呼应的)。

docker run --rm nginx:test
#等价于
docker run --rm=true nginx:test

-rm参数引申用法:它经常和sleep配合使用,意味着多少秒后容器自我销毁(灰飞烟灭)。

sleep命令单独使用的场景:当容器启动失败(时dock exec命令,无法进入容器内部排错),但我们又想进去容器排错的时候,就可以在dock run时配合sleep命令,从而让我们在容器启动失败前有足够时间进入容器内部。

docker run -d --rm nginx:alpine  sleep 10 #容器后台阻塞运行10秒后自动销毁,可以不停的用docker ps -a 来查看验证
docker run -d --name mybox busybox  sleep 10  
docker run -d --name mybox busybox /bin/sh -c "while true; do sleep 10; done" #容器后台阻塞运行10秒后自动销毁,-c是-command的意思,后面跟cmd命令(while true是一个死循环,10秒后自动结束)

--restart=always  启动过程如果出现问题,一直尝试重启 

docker pull registry  #拉取精简版本地仓库
docker images  #查看镜像
docker run -d -p 5000:5000 --restart=always --name registry registry:latest #启动镜像

-it 开启新的终端,以交互方式进入容器内部(尾部要指定/bin/bash方式);和-d一起使用后,将不会进入容器内部。

注:该写法相当于把docker run命令和docker exec -it

区别是:前者docker run的同时,又进入了容器内部,如果exit命令退出容器,容器状态(通过docker ps -a查看)立马会变成Exited状态后者docker exec -it就不一样了,以此方式进入容器,然后exit退出容器,不会主动影响容器的原有状态。

docker run  -it --name mytomcat -p 8080:8080 tomcat:8.5.46-jdk8-openjdk  /bin/bash

docker build 后如何使用 docker build . -t_Dockerfile_02

4.docker ps 查看正在运行中的镜像列表

不带参数,默认只显示正在运行中的容器(状态为UP上线状态)

-a 列出所有容器 ;-n 显示最近创建指定个数的容器; --no-trunc 不截断输出

docker ps -l #显示最近创建容器 
docker ps -n 3 #显示最近创建的3个容器 
docker ps --no-trunc  #不截断输出

5.docker rm 容器id  删除容器

-f 代表要强制删除,移除容器时,可以不写全名,可以是前两个字符(如果前两个字符互不重复的话),正在情况需要用docker stop 容器ID,先停掉容器,再rm移除容器。

docker ps -a     #查看需要被删除的容器
docker rm -f 9c  #容器名称首字母
docker rm -f eb  #容器名称首字母
docker rm -f 31  #容器名称首字母
docker rm -f tomcat7 #强制删除容器
docker rmi -f redis tomcat nginx #一次删除多个容器

删除所有容器的3种写法

docker rm $(docker ps -a -q)
docker rm -f $(docker ps -aq)  
docker ps -a -q | xargs docker rm  #通过管道,把前面的命令交给后面

引申:批量创建测试目录(和上面用法异曲同工)的2种写法 

#mkdir $(seq -f 'test%02g' 1 5)     seq命令详解 #seq -f "test%03g" 1 5 | xargs mkdir 

-v  删除与容器关联的volumes卷和它在主机的映射目录  

注:该-v 与docker run -v的参数相互呼应,删除的也是run -v时指定的映射目录

可以通过:docker inspect 命令,查看“Mounts”挂载部分,得知:容器内部挂载数据目录,默认是 "Source": "/var/lib/docker/volumes***“

docker rm -f   tomcat7 #仅删除容器本身
docker rm -fv  tomcat7 #彻底级联删除

6.docker rmi   删除镜像

语法:docker rmi <-f>镜像名:<tags>

docker images #查看所有镜像
docker rmi -f  tomcat:latest #-f强制删除指定版本的tomcat镜像

7.docker exec -it 从宿主机,进入容器内部 

docker ps  #查看正在运行的容器
docker exec -it mynginx /bin/bash 
docker exec -it mynginx /bin/sh /root/runoob.sh  #进入容器的同时,运行runoob.sh脚本
exit #退出容器,退出后不影响该容器的正常运行(如果是通过dock run直接进入的容器,会影响)

./bin/bash 与/bin/sh (引申:两者的区别和联系,点击进入

两脚本的使用权限是不一样的;/bin/sh 相当于 /bin/bash --posix;两者区别,是bash没有开启posix便携模式。

POSIX规范:“当某行代码出错时,不继续往下解释”。bash 就算出错,也会继续向下执行。

#ll /bin/sh
lrwxrwxrwx. 1 root root 4 Jan 7 2022 /bin/sh -> bash
#ll /bin/bash
-rwxr-xr-x. 1 root root 938768 Jan 7 2022 /bin/bash

8.docker build 使用Dockerfile构建镜像

该命令的运行,一般情况下,需要先切换到Dockerfile所在目录,然后运行docker build,当然,如果Dockerfile在其他目录,也可以使用docker build -f 指定Dockerfile的位置(可以是远程地址)。

--file,-f 指定Dockerfile脚本路径(该文件是镜像构建脚本的合集,类似于xx.sh

docker build -f /path/to/a/Dockerfile .  #明确指定Dockerfile的路径
docker build github.com/creack/docker-firefox #也可以使用URL github.com/creack/docker-firefox 的 Dockerfile 创建镜像

--build-arg 设置一些创建镜像时的参数,可以指定环境常量,会覆盖Dockerfile的同名常量

示例:假如Dockerfile中,有如下环境常量

ENV http_proxy ""
ENV https_proxy ""

 那么在docker build命令运行时,依然可以使用 --build-arg 来覆盖该常量在Dockerfile中的值

docker build
--build-arg http_proxy=http://10.188.61.2:8118
--build-arg https_proxy=https://10.188.61.2:8118
-f Dockerfile . -t imagename:tag

--tag, -t 镜像的名字及标签,通常 name:tag 或者 name ;可以在一次构建中为一个镜像设置多个标签。

docker images #查看镜像列表
docker build -t nginx:env . 
docker build  .  -t nginx:env #两种写法均可,前面是容器名称,后面是标签
docker build -t coonote/ubuntu:v1 .  
docker build -t test/myapp .

注:这些命令,如果没有通过-f指定Dockfile的位置,默认会在当前目录寻找Dockfile,通过当前的Dockfile来build自定义的镜像。 

三、docker build .点的扩展说明

它是指镜像构建时,需要打包上传到Docker server 引擎中文件的目录,以供Dockerfile中的COPY或ADD命令自动关联并使用这些文件。

当前目录可以用.表示,非当前目录,需手动指定上下文目录,不要迷迷糊糊的也写个.(该目录一般是构建docker镜像项目的根目录,但最好不要是在/root根目录,会造成不必要的资源浪费,本来几十M的镜像,可能会被你搞成10几个G)。

所以,一般:我们会单读在一个比较清爽,没有闲杂文件的(测试)目录来构建镜像。

注:build过程中,首先会将整个构建镜像上下文文件(递归)发送到Docker守护进程(服务器),以供Dockerfile内部的ADD、COPY命令使用。build构建成功后,会返回新镜像的ID,同时Docker守护进程会自动清理发送的构建镜像上下文。

结论:它不是指 Dockerfile所在的目录,它代表的是(宿主)当前所在的目录,只是Dockerfile恰好有可能在当前目录而已,如果Dockerfile不是在当前目录,需要用-f去手动指定Dockerfile的位置。

.点,它是指build构建上下文,需要上传Dockerfile中ADD、COPY命令所需文件的上下文目录(便于这两个命令使用上下文中的文件,就好比使用自己本地的文件一样),build结束后,上下文文件会被自动清理。

注:该点的作用在网络中诸多地方,说的闪烁其词、模弄两可,本讲把它揉碎了,分享给你。

四、常用命令

1.docker search 搜索镜像

docker search helloword
docker search ubuntu
docker search nginx

docker build 后如何使用 docker build . -t_linux_03

 2.docker inspect 镜像/容器 获取容器/镜像的元数据详细信息

docker inspect nginx

-f ,--format : 返回指定值的模板文件
语法:docker inspect -f ${format} ID|NAME 

-s ,--size 如果是容器,则显示文件总的大小 
语法:docker inspect -s ID|NAME

--type 为指定类型返回JSON  语法:docker inspect --type JSON ID|NAME

3.docker tag 给镜像自定义标签

作用:
它类似于虚拟机中的快照,添加标签后不仅能保存最新版本的镜像,也能保存历史版本的镜像,方便新版本镜像出问题时进行版本回溯。
注意:在实际工作中,需要修改镜像名称,否则无法上传(push)到本地仓库(上传时,需要指定 repository,如果repository名称一致,可以:tag版本号即可)。 

docker images #查看镜像列表
docker tag ubuntu:latest aliyun/ubuntu:v1  #给镜像打标签
docker images #可以看到两个镜像的名称不同,镜像ID相同

此时会有一个问题,直接通过镜像ID,系统会提示:image is referenced in multiple repositories。
镜像在多个仓库中被使用,不知道要删除哪一个。
所以要根据镜像名称+版本号删除

#docker rmi ubuntu:latest

4.docker login /logout 登录/退出官方仓库

#docker login
#password:
Login Succeeded

注:如果没有账号可以到https://hub.docker.com注册一下

docker build 后如何使用 docker build . -t_docker_04

push

docker pull nginx
docker images
docker tag nginx:latest xxxx_login_name/nginx:v1 #给镜像打标签
docker images
docker push xxxx_login_name/nginx:v1

注:xxxx_login_name是你登录github的登录名  

docker build 后如何使用 docker build . -t_容器_05

 登录Docker账号后,可以看到刚才上传的镜像。

history 查看指定镜像的创建历史

参数:-H 显示镜像的大小和日期;--no-trunc 显示完整的提交记录;-q 仅列出提交记录ID

#docker history -H redis
#docker history runoob/ubuntu:v3

7.docker save将指定镜像保存成 tar 归档文件

#docker save -o my_ubuntu_v3.tar runoob/ubuntu:v3

8.docker load导入使用 docker save命令导出的镜像

#docker load -i my_ubuntu_v3.tar

9.docker info 显示 Docker 系统信息,包括镜像和容器数

#docker info

10.docker version显示 Docker 版本信息

#docker version

11.docker cp 宿主机、容器内之间文件(夹)相互复制

参数-r 是递归复制

1.宿主机拷文件到容器里面

命令需要用docker exec -it 进入容器内部执行,前面绝对路径是宿主机的,后面路径是容器内部的路径(可以是相对路径)

#docker cp -r /root/doc/htmls /usr/local/tomcat/webapps  从宿主机向容器复制文件

2.容器拷文件到宿主机

命令直接在宿主机内执行就可以,前面要指明容器的名称(通过docker ps -a

#docker cp  container_name:/var/logs /host/path   从容器向宿主机复制文件

注意:容器启动与否,拷贝命令都会生效。被拷贝内容如有重复,会直接覆盖,不会询问。

12.docker top显示容器正在运行的进程

语法:docker top CONTAINER [ps OPTIONS]

#docker top redis 列出redis容器中运行进程
#docker top gitlab  列出所有正在运行的进程
#docker top gitlab | grep redis  过滤出redis相关进程

13.docker port 查看容器对外暴露的端口

#docker ps 获取容器id
#docker port e93e695d65

docker build 后如何使用 docker build . -t_Dockerfile_06

14.docker logs 查看容器日志

参数:-f 跟踪日志输出(实时刷新);-t 显示时间戳;--tail 仅列出最新N条容器日志;   

#docker logs rabbitmq
docker logs -f -t --tail=20 redis
docker logs --since="2022-05-21" --tail=10 redis  查看自2022-05-21后最新的10条日志

15.docker commi 提交镜像到仓库

语法:docker commit -a="作者" -m="描述信息" -c  容器id 目标镜像名:[TAG]

参数:-a 提交的镜像作者;-c 使用Dockerfile指令来创建镜像;-m 提交时的说明文字;-p

注:Docker容器运行期间会产生数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器被(rm命令)删除后,这些数据就没有了。

点击这里了解容器和镜像的关系。 

docker commit -a="myredis test" -m="my redis" [redis容器ID]  myredis:v1.1

实战演练

#1、随意拉取一个Tomcat镜像,乐观的认为能正常访问
docker pull tomcat 
#2、很激动的启动默认的tomcat,发现这个默认的tomcat页面来了个大大的404惊喜。原因是:官方的镜像默认webapps下面是没有文件
docker run -d -p 8080:8080 tomcat
#3、进入容器内部
docker exec -it 64357165e00e
#4、同cp命令拷贝文件进去(从宿主机向容器复制文件)
cp -r webapps.dist/* webapps
#5、将操作过的容器通过commit提交为一个镜像。我们以后就使用我们修改过的镜像即可
docker commit -a="succ" -m="add webapps app" 64357165e00e mytomcat:v1 
sha256:37af1236adef1544e8886be23010b66577647a40bc02c0885a6600b33ee28057
#6、查看自己创建的镜像
docker images mytomcat:v1
EPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mytomcat           v1                  37af1236adef        15 seconds ago      329 MB

五、docker build 和 docker commit的关系

区别与联系:两者都是构建自定义的镜像,然而他们构建方式不同。

通过以上的内容,可以了解到docker build 它有个隐藏的参数是-f,此种方式构建自定义镜像时,需要指定Dockerfile,以Dockerfile为依托。

docker commit就不同了,它不依托于任何Dockerfile,你可以随时在宿主的任意目录,执行该操作,比如你在某个容器内部,添加了一个配置或者yum 安装了什么软件后,需要把这些配置持久化到镜像中,此时你就可以用docker commit操作。

六、总结

以上内容,比较重要,重点介绍了Docker的核心命令,以及周边常用命令。

如果你是初学者,可以通过浏览Tomcat镜像从下载到部署到移除,从而对Docker命令的运用有个初步认识与了解。进阶课程在请查看↓↓↓↓下方附注↓中的6、7两个章节。

尾言

本讲内容是从 Docker入门到进阶里面抽离出来的内容,从而使原文更加有序、重点突出。它是docker使用前的必须要掌握和了解的一些知识点,希望对大家有所帮助。