一旦你学会了如何在Docker中启动和运行一个容器,你就可以继续在同一docker引擎中为你的环境运行和管理多个容器。和其他事情一样,练习设置容器,与它们互动,并在完成后拆除它们,将使你适应管理容器的过程和工作流程。在本教程中,我们将通过设置3个单独的容器进行练习。一个是[MySQL],另一个是[Nginx],最后一个是[Apache]。
MySQL容器
首先,我们可以在Docker中启动一个MySQL容器。
docker container run -d -p 3306:3306 --name db -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql
Unable to find image 'mysql:latest' locally
latest: Pulling from library/mysql
d121f8d1c412: Pull complete
f3cebc0b4691: Pull complete
1862755a0b37: Pull complete
489b44f3dbb4: Pull complete
690874f836db: Pull complete
baa8be383ffb: Pull complete
55356608b4ac: Pull complete
dd35ceccb6eb: Pull complete
162d8291095c: Pull complete
5e500ef7181b: Pull complete
af7528e958b6: Pull complete
Digest: sha256:e1bfe11693ed2052cb3b4e5fa356c65381129e87e38551c6cd6ec532ebe0e808
1309c4b670f02dfffe5ef3ae0c405867fdad81b61bb3a60f08018273d035830b
Apache容器
现在MySQL已经启动并运行了,让我们来启动Apache webserver。
docker container run -d -p 8080:80 --name webserver httpd
Unable to find image 'httpd:latest' locally latest: Pulling from library/httpd d121f8d1c412: Already exists
9cd35c2006cf: Pull complete
b6b9dec6e0f8: Pull complete
fc3f9b55fcc2: Pull complete
802357647f64: Pull complete
Digest: sha256:5ce7c20e45b407607f30b8f8ba435671c2ff80440d12645527be670eb8ce1961
Status: Downloaded newer image for httpd:latest
d2659ccf4b39ad461b0352af1b096f5835726c8042f32916febd948e0c819482
Nginx容器
我们要启动的最后一个容器是一个[Nginx容器]。
docker container run -d -p 80:80 --name proxy nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
d121f8d1c412: Already exists
ebd81fc8c071: Pull complete
655316c160af: Pull complete
d15953c0e0f8: Pull complete
2ee525c5c3cc: Pull complete
Digest: sha256:c628b67d21744fce822d22fdcc0389f6bd763daac23a6b77147d0712ea7102d0
Status: Downloaded newer image for nginx:latest
5f65da618b6aae8e9cd223f7bba046c2efaf9573753fd9c40cdabca12593adfe
列出容器
好了,之前的那些步骤都很顺利。让我们用docker container ls命令查看正在运行的容器。
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5f65da618b6a nginx "/docker-entrypoint.…" 11 seconds ago Up 10 seconds 0.0.0.0:80->80/tcp proxy
d2659ccf4b39 httpd "httpd-foreground" 27 seconds ago Up 26 seconds 0.0.0.0:8080->80/tcp webserver
1309c4b670f0 mysql "docker-entrypoint.s…" 40 seconds ago Up 37 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp db
测试端口80
我们可以用命令行中的curl和网络浏览器来测试Nginx容器所运行的80端口。看起来不错
curl http://localhost
StatusCode : 200
StatusDescription : OK
Content : <!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
} </style> <... RawContent : HTTP/1.1 200 OK Connection: keep-alive
Accept-Ranges: bytes
Content-Length: 612
Content-Type: text/html
Date: Wed, 30 Sep 2020 20:58:08 GMT
ETag: "5f32b03b-264"
Last-Modified: Tue, 11 Aug 2020 ...
Forms : {}
Headers : {[Connection, keep-alive], [Accept-Ranges, bytes], [Content-Length, 612], [Content-Type, text/html]...}
Images : {}
InputFields : {}
Links : {@{innerHTML=nginx.org; innerText=nginx.org; outerHTML=<A href="http://nginx.org/">nginx.org</A>; outerText=nginx.org; tagName=A;
href=http://nginx.org/}, @{innerHTML=nginx.com; innerText=nginx.com; outerHTML=<A href="http://nginx.com/">nginx.com</A>;
outerText=nginx.com; tagName=A; href=http://nginx.com/}}
ParsedHtml : System.__ComObject
RawContentLength : 612

测试8080端口
测试Apache服务器的8080端口,无论是用curl还是用浏览器,都遵循同样的过程。Apache的回答是:"它能工作!"
curl http://localhost:8080
StatusCode : 200
StatusDescription : OK
Content : <html><body><h1>It works!</h1></body></html>
RawContent : HTTP/1.1 200 OK
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Accept-Ranges: bytes
Content-Length: 45
Content-Type: text/html
Date: Wed, 30 Sep 2020 21:03:11 GMT
ETag: "2d-432a5e4a73a80...
Forms : {}
Headers : {[Keep-Alive, timeout=5, max=100], [Connection, Keep-Alive], [Accept-Ranges, bytes], [Content-Length, 45]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : System.__ComObject
RawContentLength : 45

停止所有的容器
我们想清理我们的Docker环境,所以让我们停止所有正在运行的容器的名字。
docker container stop db webserver proxy
db
webserver
proxy
确认容器已退出
状态显示为exited,所以我们知道这些容器没有在运行。
docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5f65da618b6a nginx "/docker-entrypoint.…" 11 minutes ago Exited (0) 59 seconds ago proxy
d2659ccf4b39 httpd "httpd-foreground" 12 minutes ago Exited (0) 58 seconds ago webserver
1309c4b670f0 mysql "docker-entrypoint.s…" 12 minutes ago Exited (0) 58 seconds ago db
移除这些容器
如果我们已经完成了练习,就没有必要再保留这些容器了,所以让我们继续删除它们吧。
docker container rm db webserver proxy
db
webserver
proxy
容器已经消失了
确认运行和不运行的容器都已经消失了。
docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
删除图像
当我们在清理东西的时候,我们也可以删除我们用来驱动容器的图像。
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 417af7dc28bc 2 weeks ago 138MB
nginx latest 7e4d58f0e5f3 2 weeks ago 133MB
mysql latest e1d7dc9731da 2 weeks ago 544MB
docker image rm httpd nginx mysql
Deleted: sha256:ba0c2ff8d3620c0910832424efef02787214013b1c5b1d9dc9d87d638e2ceb71
Deleted: sha256:db9c97c9ad968b91c4499e5cca7435a155bfef6f5fb9c6cd5543481e47ff4f71
Deleted: sha256:8cdd4c6014e71c2f6ff38dadcaec2003b955230d38831e85db5a44fa38320e6b
图像消失了
最后,我们检查一下我们的Docker环境中是否有任何镜像,当然,没有了。我们又有了一个干净的环境来工作了。
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
总结
我们可以看到,启动一个以上的容器并不是那么困难。在上面的例子中,我们能够让几个容器启动并运行,测试它们的服务,然后停止并从Docker中删除它们。一些经验包括。
- docker container ls -a和docker ps -a做同样的事情。两者都显示所有的容器,不管是运行还是停止。
- 当在docker run中添加-d时,你告诉容器以分离模式运行。换句话说,就是在后台运行。以这种方式配置时,没有日志显示在主机终端上。
- docker container run -p 80:80 -d nginx和docker container run -p 8080:80 -d nginx将启动两个Nginx容器。即使两者都在容器中监听80端口,也没有冲突。左边的数字是主机端口,是不同的(80 vs 8080)。