基础 3 —— Docker 的常用命令

基础 3 —— Docker 的常用命令
3.1 帮助启动类命令启动 Docker[rootshjava101 ~]# systemctl start docker # 启动docker[rootshjava101 ~]# systemctl status docker # 查看docker的运行状态[rootshjava101 ~]# systemctl restart docker # 重启docker服务[rootshjava101 ~]# systemctl stop docker # 停止docker服务[rootshjava101 ~]# docker --help # 查看docker帮助文档如果我们想查看指定某条 Docker 命令的帮助信息呢语法格式是:docker 具体命令 --help。 比如我们现在想查看 Docker 的 cp 命令详细信息。[rootshjava101 ~]# docker cp --help3.2 Docker 的镜像命令Docker images 列出本地主机上的镜像[rootshjava101 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest feb5d9fea6a515months ago13.3kB上图中展示镜像列表的各个选项信息是什么意思REPOSITORY表示镜像的仓库源TAG镜像的标签版本号。在下载镜像的时候如果默认不加版本号就会下载默认最新版本的镜像。如果加上指定版本号的镜像下载的就是对应版本的镜像。IMAGE ID镜像 IDCREATED镜像创建时间SIZE镜像大小注意同一仓库源可以有多个 TAG 版本代表这个仓库源的不同个版本我们使用 REPOSITORY:TAG 来定义不同的镜像。如果我们想深入学习 docker images 的命令我们可以使用 help 指令查看关于 docker images 的帮助文档。[rootshjava101 ~]# docker images --helpUsage:dockerimages[OPTIONS][REPOSITORY[:TAG]]List images Options: - a, --all. Show all images(default hides intermediate images)--digests. Show digests - f,--filterfilter Filter output based on conditions provided--formatstring Pretty-print images using a Go template --no-trunc Dont truncate output - q,--quietOnly show image IDs[rootshjava101 ~]# docker images -aREPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest feb5d9fea6a515months ago13.3kB[rootshjava101 ~]# docker images -qfeb5d9fea6a5-a :列出本地所有的镜像含历史映像层-q :只显示镜像ID。docker search 某个XXX镜像名字指定搜索某个镜像的名称。[rootshjava101 ~]# docker search redis搜索镜像出现的选项是什么意思呢我们也可以携带一些参数比如--limit。--limit: 只列出 N 个镜像默认 25 个[rootshjava101 ~]# docker search --limit 5 redisdocker pull 某个 XXX 镜像名字拉取指定的镜像到本地(下载镜像)语法docker pull 镜像名字 [:TAG][rootshjava101 ~]# docker pull mysql # 没有带标签就下载的是最新版本的 mysql 镜像[rootshjava101 ~]# docker pull redis:6.0.8 # 下载指定标签的 redis 镜像比如我们给大家演示下载 ubuntu 镜像[rootshjava101 ~]# docker pull ubuntu # 默认下载最新版本的镜像Using default tag: latest latest: Pulling from library/ubuntu 7b1a6ab2e44d: Pull complete Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322 Status: Downloaded newer imageforubuntu:latest docker.io/library/ubuntu:latest[rootshjava101 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest ba6acccedd2914months ago72.8MB hello-world latest feb5d9fea6a515months ago13.3kB redis6.0.8 16ecd27729342years ago 104MB在 Linux 里面我们如何插件硬盘的使用情况是不是可以使用df -h命令。在 Docker 里面我们也想查看镜像 / 容器的占用空间我们应该如何使用呢语法格式:docker system df查看镜像 / 容器 / 数据卷所占的空间docker rmi 某个 XXX 镜像名字 ID删除某个镜像注意不能删除正在运行容器的镜像[rootshjava101 ~]# docker rmi hello-world # 可以根据镜像名称删除Error response from daemon: conflict: unable to remove repository referencehello-world(must force)- container eec46ce5392d is using its referenced image feb5d9fea6a5[rootshjava101 ~]# docker rmi feb5d9fea6a5 # 也可以根据镜像 id 删除因为镜像 id 是唯一的。Error response from daemon: conflict: unable to delete feb5d9fea6a5(must be forced)- image is being used by stopped container eec46ce5392d但是此时删除报错为什么因为删除的时候当前镜像存在正在运行的容器。我们可以使用-f参数来指定强制删除但是强制删除的话正在运行的容器也就不复存在了。[rootshjava101 ~]# docker rmi -f feb5d9fea6a5docker rmi -f 镜像名1: TAG 镜像名2: TAG删除多镜像可以使用这个命令[rootshjava101 ~]# docker rmi -f ubuntu:latest redis:6.0.8也可以直接删除全部镜像慎用[rootshjava101 ~]# docker rmi -f $(docker images -qa)这里有个面试题大家需要留意一下什么是虚悬镜像仓库名、标签都是none的镜像俗称虚悬镜像。这种经常一般没啥用我们直接删除即可。3.3 Docker 的容器命令Docker 的容器命令我们用 Ubuntu 演示。首先我们使用docker pull ubuntu下载 ubuntu 镜像。[rootshjava101 ~]# docker pull ubuntu3.3.1 容器的基本命令启动容器启动容器命令的语法格式是:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]OPTIONS 参数说明 (有些是一个减号有些是两个减号):–name“容器新名字” 为容器指定一个名称-d: 后台运行容器并返回容器ID也即启动守护式容器(后台运行)-i以交互模式运行容器通常与 -t 同时使用-t为容器重新分配一个伪输入终端通常与 -i 同时使用也即启动交互式容器(前台有伪终端等待交互)-P: 随机端口映射大写P-p: 指定端口映射小写p现在我们如何启动一个 Ubuntu 容器呢使用docker run ubuntu吗我们可以试一下[rootshjava101 ~]# docker run ubuntu[rootshjava101 ~]#我们发现启动之后没有任何反应因为我们希望启动的是一个交互式的容器也就是用户可以在终端输入命令的容器。那如何启动一个交互式的容器呢根据上面的语法规则我们可以这样启动[rootshjava101 ~]# docker run -it ubuntu /bin/bashrootf6d5e6eb2c5c:/#参数说明-i: 交互式操作。-t: 终端。ubuntu: ubuntu镜像。/bin/bash放在镜像名后的是命令这里我们希望有个交互式 Shell用来解释执行 Linux指令。因此用的是 /bin/bash。要退出终端直接输入 exit。docker ps 列出正在运行的容器我们另起一个终端运行docker ps命令。[rootshjava101 /]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f05e76e5e32c ubuntu/bin/bash11seconds ago Up10seconds optimistic_swirlesNAMES指定启动的容器名字如果你不指定系统就会给你随机指的一个名字。如何在启动容器的时候也指定容器的名字呢我们可以使用--name参数指定。[rootshjava101 /]# docker run -it --nameu1 ubuntu /bin/bash我们再次查看正在运行的容器。[rootshjava101 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6d2d86512480 ubuntu/bin/bash11seconds ago Up10seconds u1我们发现正在运行的容器的名字就是我们自己定义的了。这个命令还可以携带一些常用的参数-a: 列出当前所有正在运行的容器 历史上运行过的-l: 显示最近创建的容器。-n: 显示最近n个创建的容器。-q: 只显示正在运行的容器编号。下面我们来具体演示[rootshjava101 ~]# docker ps -a # 列出所有容器(正在运行的以及历史运行的)CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6d2d86512480 ubuntu/bin/bash5minutes ago Up5minutes u1 2377079e316a ubuntu/bin/bash5minutes ago Exited(0)5minutes ago[rootshjava101 ~]# docker ps -l #罗列最近运行的容器CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6d2d86512480 ubuntu/bin/bash6minutes ago Up6minutes u1[rootshjava101 ~]# docker ps -n 2 # 罗列最近运行的2个容器CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6d2d86512480 ubuntu/bin/bash6minutes ago Up6minutes u1 2377079e316a ubuntu/bin/bash7minutes ago Exited(0)7minutes ago hopeful_davinci[rootshjava101 ~]# docker ps -q # 只显示最近运行的容器的id6d2d86512480退出容器的命令上面提到要退出容器终端可以使用exit命令但是使用exit命令退出会导致容器终止执行如果退出容器终端不影响容器正在运行可以吗答案是可以的。这个也是退出容器的两种机制。exit run 进去容器exit 退出容器停止ctrlpq run 进去容器ctrlpq 退出容器不停止启动已停止运行的容器语法格式docker start 容器 ID 或者容器名[rootshjava101 /]# docker start 2377079e316a 2377079e316a [rootshjava101 /]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6d2d86512480 ubuntu /bin/bash 22 minutes ago Up 22 minutes u1 2377079e316a ubuntu /bin/bash 22 minutes ago Up 17 seconds hopeful_davinci我们发现之前已经停止的容器也运行起来了。重启容器语法格式:docker restart 容器ID或者容器名[rootshjava101 /]# docker restart 2377079e316a停止容器语法格式:docker stop 容器ID或者容器名[rootshjava101 /]# docker stop 2377079e316a强制停止容器语法格式:docker kill 容器ID或容器名[rootshjava101 /]# docker kill 2377079e316a删除已停止的容器语法格式:docker rm 容器ID[rootshjava101 /]# docker rm 2377079e316a如果我们要删除正在运行的容器呢此时需要加上一个-f参数[rootshjava101 /]# docker rm -f 2377079e316a我们也可以一次性删除多个容器实例但是一般不建议大家这么使用[rootshjava101 /]# docker rm -f $(docker ps -a -q)或者[rootshjava101 /]# docker ps -a -q | xargs docker rm # xargs 是linux里的一个显式参数现在我们思考几个问题上面我们启动了前台交互式的容器如果我们想以后台守护式的方式启动容器应该怎么做?还有我们从一个正在运行中的容器退出来了以后我们又如何进入这个容器呢接下来我们就来解决这几个问题。3.3.2 启动守护式容器与进入容器这里我们用 Redis6.0.8 镜像演示。各位同学首先请确保你本机里面下载有 Redis 镜像。在大部分的场景下我们希望 Docker 的服务是在后台运行的我们可以过-d指定容器的后台运行模式。为了显示区别我们先用前台交互的方式启动容器:[rootshjava101 /]# docker run -it redis:6.0.8此时会以前台运行redis的方式显示但是这种启动方式会霸占我们整个 Linux 终端导致我们不能做其他的事情。所以我们应该以后台的形式启动守护式容器。如何启动我们可以使用docker run -d 容器名这个命令。[rootshjava101 /]# docker run -d redis:6.0.838b51ae774dd345fef245de93d2285987831c9119da93421c6a4304e89447ec5我们查看容器是否启动[rootshjava101 /]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 38b51ae774dd redis:6.0.8docker-entrypoint.s…4seconds ago Up3seconds6379/tcp boring_poitras 6d2d86512480 ubuntu/bin/bashAbout an hour ago Up About an hour u1我们如何进入到 Redis 容器的内部我们马上说到。现在我们再看几个和容器相关的其他命令。查看容器日志的命令 docker logs 容器id[rootshjava101 /]# docker logs 38b51ae774dd我们发现容器启动的日志信息全部被封装起来了。查看容器内运行的进程docker top 容器ID在 Linux 里面我们可以使用 top 命令动态查看进程信息在 docker 里面我们可以使用docker top 命令查看指定容器的进程信息。[rootshjava101 /]# docker top 38b51ae774dd查看容器内部具体细节命令 docker inspect 容器ID[rootshjava101 /]# docker inspect 38b51ae774dd接下来我们讨论如何进入正在运行的容器并以命令行交互。我们先以前面运行的 Ubuntu 容器为例我们可以通过 docker exec 命令进入容器内部[rootshjava101 /]# docker exec -it 6d2d86512480 /bin/bashroot6d2d86512480:/# lsbin boot dev etc home lib lib32 lib64 libx32 media mnt opt proc root run sbin srv sys tmp usr var此时我们使用 exit 命令退出容器。root6d2d86512480:/# exitexit[rootshjava101 /]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 38b51ae774dd redis:6.0.8docker-entrypoint.s…17minutes ago Up17minutes6379/tcp boring_poitras 6d2d86512480 ubuntu我们发现当我们退出容器之后容器依然在运行。我们还可以使用docker attach 容器id的命令进入容器但是用 exit 命令退出会导致容器停止。[rootshjava101 /]# docker attach 6d2d86512480root6d2d86512480:/# exitexit[rootshjava101 /]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 38b51ae774dd redis:6.0.8docker-entrypoint.s…22minutes ago Up22minutes6379/tcp boring_poitras我们发现 ubuntu 运行的容器已经停止了。所以推荐大家使用 docker exec 命令因为退出容器终端不会导致容器的停止。我们现在如何进入到 Redis 容器的内部呢[rootshjava101 /]# docker exec -it 38b51ae774dd /bin/bashroot38b51ae774dd:/data# redis-cli127.0.0.1:6379setusername eric OK127.0.0.1:6379get usernameeric127.0.0.1:63793.3.3 备份容器(1) 从容器内拷贝文件到主机上语法格式: docker cp 容器ID:容器内路径 目的主机路径需求我们先启动 Ubuntu 容器然后在容器的 tmp 目录创建一个文件。然后把这个文件拷贝至宿主机中。[rootshjava101 /]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest ba6acccedd2914months ago72.8MB redis6.0.8 16ecd27729342years ago 104MB[rootshjava101 /]# docker run -it ubuntu /bin/bashroot608d2057e7e5:/# cd /tmproot608d2057e7e5:/tmp# touch a.txtroot608d2057e7e5:/tmp# lsa.txt我们使用命令尝试拷贝[rootshjava101 /]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 608d2057e7e5 ubuntu/bin/bash13minutes ago Up13minutes reverent_stonebraker 38b51ae774dd redis:6.0.8docker-entrypoint.s…About an hour ago Up About an hour6379/tcp boring_poitras[rootshjava101 /]# docker cp 608d2057e7e5:/tmp/a.txt /tmp/a.txt[rootshjava101 /]# cd /tmp[rootshjava101 tmp]# lltotal1504-rw-r--r--.1root root0Dec2221:17 a.txt我们发现可以成功将容器内部的文件拷贝出来。(2) 导入和导出容器上面是将文件中的某个内容导出来我们也可以将整个容器导出来以 tar.gz 的文件保存。我们可以使用 export 命令实现。语法格式docker export 容器ID 文件名.tar[rootshjava101 tmp]# docker export 608d2057e7e5 ubuntu.tar.gz[rootshjava101 tmp]# ll-rw-r--r--.1root root75158016Dec2221:47 ubuntu.tar.gz我们发现容器成功备份。接下来我们分别删除运行的 Ubuntu 镜像和运行的 Ubuntu 容器。现在我们通过 ubuntu.tar.gz 来导入一个新镜像语法格式cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号[rootshjava101 tmp]# cat ubuntu.tar.gz | docker import - wen/ubuntu:1.0sha256:575629a1394b19d888621928a842b706a385fe1d3d862d85f6be3f765d88656c[rootshjava101 tmp]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE wen/ubuntu1.0575629a1394b16seconds ago72.8MB redis6.0.8 16ecd27729342years ago 104MB我们发现镜像成功导入。接下来我们启动容器[rootshjava101 tmp]# docker run -it 575629a1394b /bin/bash # 启动容器roote53f29855791:/# cd /tmproote53f29855791:/tmp# lltotal0drwxrwxrwt.2root root19Dec2213:17 ./ drwxr-xr-x.1root root6Dec2213:55../ -rw-r--r--.1root root0Dec2213:17 a.txt我们发现容器成功启动并且之前创建的文件也存在。说明我们导入成功