前文讲解了Docker镜像的原理和常用命令,本文继续通过官方的Apache镜像演示Docker容器相关的常用操作及命令。
我之前的Linux入门系列文章中“linux入门系列18–web服务之apache服务1”,演示了在CentOS7下安装和使用Apache服务,本次我们仍然采用官方的Apache镜像来进行演示,通过这个案例,大家自行对比这两种方式的不同,从而更加深刻理解Docke能干什么,以及Docker带来的好处。
接下来我们就来演示下容器如何创建、如何停止、如何删除等操作。
一、Docker容器简介
容器是Docker中的另外一个核心概念,容器是镜像的一个运行实例。
Docker镜像是静态的,只有从Docker镜像创建容器并运行起来,容器内的程序会运行,从而完成特定的功能。
我们要完成业务功能的程序就是在容器中运行。镜像本身是静态的只读文件,而容器带有运行时所需的可写文件层,同时容器内的应用进程处于运行状态。
通过下边的演示,将会理解的更加深刻。
二、Docker容器常用命令
2.1 apache镜像准备
我们后续的演示是基于Docker Hub上官方提供的apache镜像进行。
镜像名称为httpd,该镜像并不包含php的环境只能运行静态的HTML页面,因此如果你是想运行php的动态网站则需要选择PHP镜像,而本文只是为了演示容器的相关操作,因此采用静态页面即可。
[root@docker ~]# docker pull httpd:2.4
2.4: Pulling from library/httpd
68ced04f60ab: Pull complete
35d35f1e0dc9: Pull complete
8a918bf0ae55: Pull complete
d7b9f2dbc195: Pull complete
d56c468bde81: Pull complete
Digest: sha256:946c54069130dbf136903fe658fe7d113bd8db8004de31282e20b262a3e106fb
Status: Downloaded newer image for httpd:2.4
docker.io/library/httpd:2.4
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd 2.4 c5a012f9cf45 2 days ago 165MB
下载完成后我们可以看到httpd镜像大小为165M,里边究竟包含了什么内容呢?文章最后我们再来仔细分析一下。
2.2 创建容器并后台运行
镜像下载完成后,就需要通过docker run命令创建容器。
语法:
docker run [选项] 镜像名称 [命令] [参数]
选项很多,可以执行通过帮助命令进行查看,以下列出最常用的几个选项
选项 | 作用 |
---|---|
–name | 指定容器的名称 |
-d | 容器后台运行,不在控制台打印消息 |
-i | 即–interactive,交互式运行 |
-t | 分配伪终端 |
-p | 指定宿主机与容器端口的映射,宿主机端口:容器内端口 |
-P | 指定宿主机与容器端口映射,宿主机端口随机指定 |
其中-it参数和-d参数一般不同时使用,并且代表了两种启动容器的不同方式:交互式启动容器***和***守护式启动容器。
***所谓交互式启动***就是在容器启动后直接进入容器,并会自动分配一个伪终端,可以在容器内执行各种命令;而***守护式启动容器***则是容器启动后无需进入容器,容器在后台运行,默默的提供服务。
至于如何选择使用哪一种方式就看是否需要进入容器,如果要进入就选择交互式,如果只是希望容器后台运行提供服务那就选择守护式。
接下来***通过-d参数,以守护进程方式***创建基于httpd镜像的容器并后台运行
[root@docker ~]# docker run -d --name mywebsit -p 8888:80 httpd:2.4
783b46f5cddcc3ea919329a99f83a783da98bce4abce05ccc9b3f27fda859b09
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
783b46f5cddc httpd:2.4 "httpd-foreground" 6 seconds ago Up 4 seconds 0.0.0.0:8888->80/tcp mywebsit
[root@docker ~]
只需要做这一步操作,基于Apache的web环境就搭建好了,此时在CentOS7上就可以通过浏览器访问刚才搭建的基于apahce的网站了。
如果配置了防火墙,也可以在宿主机进行访问。
接下来就可以修改容器内网站目录里的数据,替换为自己的web页面即可。轻轻松松就搭建了一个apache的web静态网站,这是不是很方便呢?甚至都无须配置任何环境。迁移也非常方便,比如想换到另外一台主机运行该网站,也只需要下载该镜像,然后run起来即可。
这就是docker的强大之处,还有很多更强大的功能,后续慢慢演示。
说明一下我本地的环境,大家一定要理清楚物理机、虚拟机、容器之间的关系。我本地物理机系统是win10,在其上装了VMware虚拟机,在虚拟机中创建了一个Centos7的实例,然后在其中安装Docker,并运行mywebsite容器。因为我本地没有装Centos7,所以在虚拟机中虚拟一个来进行演示,当然你也可以直接在windows上装docker或直接在本地的centos上安装docker。
外部访问是访问在run容器是指定映射到的Centos7的宿主机端口8888,而非mywebsite容器的80端口。
特别注意:此处之所以采用-d在后台以守护进程的方式运行容器,原因就是当一个容器没有前台进程执行的时候,创建容器后立马就会停止。所以你可以用交互式的方式创建一个容器试试,docker run -it --name mywebsit1 -p 8888:80 httpd:2.4 ,创建后你用docker ps命令查看根本看不到容器,用docker ps -a命令查看,你就会发现容器创建后,短暂启动后立马就停止了,就是这个原因。
2.3 查看容器命令
查看本地有哪些正在运行的容器,或者是曾经创建过的容器可以通过docker ps命令
语法
docker ps [选项]
常用参数
参数 | 作用 |
---|---|
-a | –all,查看所有容器,默认情况下只显示正在运行的容器 |
-l | –latest,查看最近创建的容器 |
-n | 显示最后创建的n个容器 |
–no-trunc | 不截断显示 |
案例:
(1)查看正在运行的容器
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
783b46f5cddc httpd:2.4 "httpd-foreground" 4 hours ago Up 4 hours 0.0.0.0:8888->80/tcp mywebsit
[root@docker ~]#
可以看到只有刚才创建的mywebsit容器在运行。
2.4 在容器外部查看容器信息
2.4.1 查看容器日志命令
语法
docker logs [选项] 容器名或id
常用参数
参数 | 作用 |
---|---|
-f | 动态跟踪打印日志信息,一旦有新日志会继续打印 |
-t | 在每行日志前面打印出时间 |
–tail | 指定显示的行数 |
案例
(1)查看mywebsit的日志,只显示2行
[root@docker ~]# docker logs -t --tail 2 mywebsit
2020-02-29T03:09:57.654372509Z 192.168.78.1 - - [29/Feb/2020:03:09:57 +0000] "-" 408 -
2020-02-29T03:09:57.854284777Z 192.168.78.1 - - [29/Feb/2020:03:09:57 +0000] "-" 408 -
[root@docker ~]#
2.4.2 查看容器内进程命令
语法
docker top
案例
(1)查看mywebsit内部的进程
[root@docker ~]# docker top mywebsit
UID PID PPID C STIME TTY TIME CMD
root 3673 3655 0 10:29 pts/0 00:00:01 httpd -DFOREGROUND
bin 3708 3673 0 10:29 pts/0 00:00:00 httpd -DFOREGROUND
...省略部分输出
此命令类似于Linux下的top命令。
2.4.3 查看容器内部细节
语法
docker inspect 容器名称或id
案例
(1)查看mywebsit容器内部信息
[root@docker ~]# docker inspect mywebsit
...省略输出
由于输出内容太多就不粘贴了。
执行命令后将得到一个详细描述容器信息的JSON字符串对象,该对象中包含了容器的详细信息,包含容器端口映射、挂载信息、卷信息、网络ip等信息。
2.5 退出容器命令
如果进入了容器,退出方式有如下两种:
exit命令
或
按快捷键:ctrl+p+q
2.6 进入容器内部与之交互
进入正在运行的容器并以命令行交互
2.6.1 docker exec命令
采用docker exec命令可以进入容器或不进入容器直接执行命令
语法
docker exec [选项] 容器名或id 命令 [参数…]
选项与docker run命令类似,也有-itd等参数。
用此命令进入容器后,用exit命令或快捷键退出容器后,容器不会停止。
案例
(1)不进入容器直接执行命令
[root@docker ~]# docker exec -it mywebsit pwd
/usr/local/apache2
[root@docker ~]#
该命令的含义查看mywebsit容器内的当前目录,可以看到命令执行结束后我们没没有进入到容器内部。
pwd是linux的命令,但此处为何能执行呢?原因是httpd镜像是由debian基镜像继承而来,大家知道debian也是linux的一个发行版本,因此该容器就有debian的功能。简单说就是你可以认为mywebsit容器就是跑在docker上的一个小linux系统。
(2)进入容器执行命令
[root@docker ~]# docker exec -it mywebsit /bin/bash
root@783b46f5cddc:/usr/local/apache2# pwd
/usr/local/apache2
root@783b46f5cddc:/usr/local/apache2# exit
exit
[root@docker ~]#
这个过程的作用给前面的案例是一样的,只不过这里是进入到容器内部,然后打印当前目录,然后在退出容器,返回到centos7宿主机。
通过这两个案例的对比,应该很清楚他们的区别了吧。
2.6.2 docker attach命令
语法
docker attach [选项] 容器名或id
用此命令重新进入容器,进入容器后如果用exit命令退出,则容器会停止。
2.7 容器与宿主机之间数据拷贝
docker cp命令可以实现宿主机与主机之间的数据拷贝,即使是容器停止的情况下也可以执行拷贝操作。
语法
docker cp 容器id:容器内路径 宿主机路径
案例
(1)修改容器内的首页内容
首先:httpd镜像网站的目录为:/usr/local/apache2/htdocs/index.html
其次:由于httpd镜像基于debian制作,内部并没有包含vi/vim等工具。
再次:正好可以用docker cp演示宿主机与容器之间文件的相互拷贝。
因此我们将网页文件拷贝到宿主机然后修改后在拷贝回容器网站目录下,已达到修改首页的目的。(在后续的讲解中也可以通过数据卷的方式将网站目录映射到宿主机上实现共享和修改)
[root@docker ~]# docker cp mywebsit:/usr/local/apache2/htdocs/index.html /
[root@docker ~]# ll /index.html
-rw-r--r-- 1 root root 45 Jun 12 2007 /index.html
[root@docker ~]# echo "my websit is updating">/index.html
[root@docker ~]# cat /index.html
my websit is updating
[root@docker ~]# docker cp /index.html mywebsit:/usr/local/apache2/htdocs/index.html
[root@docker ~]#
再次在浏览器中查看网页,就会发现已经被修改过了。
2.8 停止容器命令
停止容器可以通过stop和kill两个命令
kill是强制停止容器,stop会稍微过一小会停止容器,二者都可以指定容器停止前等待的时间。
docker stop|kill 容器id或容器名
案例
(1)停止容器
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
783b46f5cddc httpd:2.4 "httpd-foreground" 6 hours ago Up 21 minutes 0.0.0.0:8888->80/tcp mywebsit
[root@docker ~]# docker stop mywebsit
mywebsit
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]#
2.9 启动容器命令
可以通过start或restart启动或重启容器
语法
docker start|restart 容器id或容器名
案例
(1)启动停止的容器
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
783b46f5cddc httpd:2.4 "httpd-foreground" 6 hours ago Exited (0) 2 minutes ago mywebsit
[root@docker ~]# docker start mywebsit
mywebsit
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
783b46f5cddc httpd:2.4 "httpd-foreground" 6 hours ago Up 1 second 0.0.0.0:8888->80/tcp mywebsit
[root@docker ~]#
可以看到刚停止的mywebsit容器为exited状态,重启后又重新运行起来。
2.10 删除容器命令
语法
docker rm [选项] 容器名或id
常用选项
选项 | 作用 |
---|---|
-f | –forece,强制删除,当容器在运行时只能强制删除 |
-v | –vomumes,删除数据卷 |
案例
(1)删除正在运行容器
[root@docker ~]# docker rm mywebsit
Error response from daemon: You cannot remove a running container 783b46f5cddcc3ea919329a99f83a783da98bce4abce05ccc9b3f27fda859b09. Stop the container before attempting removal or force remove
[root@docker ~]# docker rm -f mywebsit
mywebsit
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]#
可以看到当容器运行时不能删除,需要添加-f参数强制删除。
(2)强制删除所有容器
慎用,仅供演示,他会删除所有的容器,包括正在运行的和已经停止的。
[root@docker ~]# docker rm -f $(docker ps -aq)
3d228a470c53
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]#
上边这个删除语句也可以写为:docker ps -a -q | xargs docker rm
三、容器内部窥探
以上基于httpd镜像创建了容器进行各种容器操作的演示,接下来我们在通过centos镜像,研究下镜像内部的结构和原理
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 470671670cac 6 weeks ago 237MB
如果你本地还没有centos进行,先用docker pull命令下载到本地,接下来我们用它来创建一个名为mycentos的容器,然后进入容器查看结构
[root@docker ~]# docker run -it --name mycentos centos
[root@bda9ff3abfd9 /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@bda9ff3abfd9 /]# pwd
/
[root@bda9ff3abfd9 /]# cat /etc/redhat-release
CentOS Linux release 8.1.1911 (Core)
[root@bda9ff3abfd9 /]#
进入容器后,我们可以看到,其实它就是运行着的一个centos系统,里边可以执行各种centos命令,也可以查看到内核版本。
如果你想象力在扩展一下,那很容易想到,镜像其实就是把各种操作系统环境以及我们运行所需要的软件包打包在一起,然后上传到仓库中,需要的时候直接pull下来,在运行run命令创建容器即可。这也正是我们前二篇文章反复提到的内容,如果现在在返回去看之前的文章,应该会有更深刻的理解。
本文演示完容器相关操作命令后,docker三要素就还差仓库了,下一篇讲解仓库相关理论和操作,敬请期待。