至今入IT的6年小跑中,学过见过的很多,但记住的不多。记忆犹新的是《代码大全》作者“Steve McConnell”说的一句话“应当对所有重复事情零容忍”,而Docker来的时间刚刚好,给我带来了全方面的效率提升。
Docker作为新时代的产物拥有许多靓丽的地方,很多人对Docker应该还是很迷茫,除了觉得使用它去部署程序或则环境简单外并没有其他的认知或者应用。
Docker可以从以下几个方面提供帮助:
对个人使用来说,集群服务暂且用不到,因此主要应用的是“修仙炉”和“Compose”。“修仙炉”是对多语言傍身或者多项目开发者来说的利器法宝,而Compose则是主机运维工作的利器法宝。
此次进阶过程我们从几个维度展开:
在开始前需要先简单了解下容器状态变迁过程:
图中所示的动作都是docker命令。即:
docker create
命令创建容器,容器的初始状态为“停止”。docker start
命令用于启动容器,使容器进入“运行”状态。docker pause
命令将容器中的所有进程暂停,使容器进入“暂停”状态。docker unpause
命令恢复容器中被暂停的进程,使容器重新进入“运行”状态。docker stop
命令用来停止容器,使容器进入“停止”状态。docker rm
命令用来删除容器。docker create
的时候,给了--restart
参数,且容器在“运行”时抛出了异常,这时候容器会自动重启。因此,容器的生命周期从docker create
开始,直至docker rm
后消亡。
从上文我们了解到了docker create
和docker start
两个命令分别用于“创建”和“运行”容器。而在实际使用中却很少见,那是因为还有一个更便利的命令docker run
,该命令能自动完成创建和运行两个动作,除此之外,如果本地没有存在所需的镜像的话,它还能自动从Registry拉取镜像:
$ docker run -d --name http homqyy/example_http
-d
:daemon,后台运行的意思。--name
:设置容器名称,比如这里设置容器名称为http
。homqyy/example_http
:用来运行容器的镜像,homqyy
是作者,example_http
是镜像名称。通过docker ps
命令,可以查看当前正在运行的容器:
NAMES
)为http
的容器正在运行,其运行了两分钟(STATUS: Up 2 minutes
),它是通过镜像(IMAGE
)homqyy/example_http
创建的,且创建于2分钟前(CREATE: 2 minutes ago
)。既然运行了容器,那么我们肯定有操作容器内部进程或文件的需求,就像我们通过操作虚拟机一样。docker也同样支持,只需要使用docker exec
命令即可,该命令时可以实现:在目标容器中执行特定命令:
$ docker exec -it http bash
-i
:interactive,交互的意思,它将目标容器的STDIN
映射到当前终端。-t
:tty,伪终端的意思,它将为目标容器创建一个伪终端(这里不详细展开,它超过了本文章的陈述范围),配合-i
就起到了跟虚拟机一样的效果,即:打开一个终端(输出),并将输入映射到此容器中。http
:目标容器的名称,这里也可以用容器的ID,即在本示例中的 2d9afdd06269
。bash
:要在容器中运行的命令,这里是bash
,因此相当于在目标容器中运行一个shell程序,同时由于我们创建了终端并映射了输入,从而达到了跟虚拟机一样的效果。这时候用ls
命令看一下目录情况,可以明显的看出我们已经进入到容器内部中了。我们尝试修改下容器中的nginx
配置文件/etc/nginx/nginx.conf
,并通过命令/usr/sbin/nginx -t
测试一下配置文件是否有误:
$ sed -i 's/listen 8080/listen 8081/g' /etc/nginx/nginx.conf
$ /usr/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
sed
工具来修改配置文件:将listen 8080
改为listen 8081
。reload
重载配置了。由于容器默认情况下是不允许直接被访问的,因此我们此时打开浏览器访问:”http://localhost:8080″是无法访问成功的:
为了能够在宿主机中访问容器的服务,需要开放端口,方法是在docker run
命令中追加-p
参数来指定端口的映射关系,例如这里再新起一个http服务:
$ docker run -d --name http2 -p 50000:8080 homqyy/example_http
-p <host_port:container_port/protocol>
:此参数可以指定端口映射关系,此样例的意思是将主机的50000
端口映射到容器的8080
端口,这意味着可以访问主机的50000
端口来访问容器中的8080
端口,即:在主机的浏览器中访问http://localhost:50000
就相当于访问容器中的8080
端口的服务。host_port
:宿主机的端口container_port
:容器中的端口protocol
:协议,值可以是udp
或tcp
http://localhost:50000
,将得到正确的返回。这里需要注意,至此总共运行了http
和http2
两个容器,且是由相同的镜像homqyy/example_http
产生的,这里表明了镜像与容器的关系是“1对n”的。这是查看一下两个容器,看一下彼此间的区别,可以观察到PORTS
列有明显区别:
$ docker ps |grep homqyy/example_http
... PORTS NAMES
... 80/tcp, 0.0.0.0:50000->8080/tcp, :::50000->8080/tcp http2
... 80/tcp, 8080/tcp http
http2
体现出了主机和容器的映射关系,这也说明我们可以通过此来查看容器与主机的映射关系。在运行完样例后可以开始清除容器和镜像了:
$ docker stop http
$ docker rm http
$ docker stop http2
$ docker rm http
$ docker rmi homqyy/example_http