本文部分摘自书籍《Docker技术入门与实战》
互联网应用服务包括多个服务组件,往往需要多个容器之间通过网络通信进行配合,docker提供了映射容器端口到宿主机和容器互联网机制来为容器提供网络服务。
端口映射实现访问容器
在启动容器的时候,如果不指定对应参数,在容器外部是无法通过网络来访问容器内的网络应用和服务的。 当容器中运行一些网络应用,要让外部访问这些应用时,可以通过-P或-p参数来指定端口映射。当使用-P标记时,Docker会随机映射一个端口至容器内部开放的网络端口:
docker run -d -p 8000 tomcat
查看容器:
docker ps
输出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c9261fae0b8 tomcat "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:32770->8000/tcp agitated_euler
本地主机的32770端口被映射到了容器的端口8000上,此时访问主机的32770端口即可访问应用,但是此时却不能访问tomcat,接下来进行分析:
首先查看容器log:
docker logs 1c9261fae0b8
输出:
...
可以看出输出即tomcat的启动日志,那么仔细观察或考虑一下即可发现,
tomcat默认情况下是绑定在8080端口,而tomcat在容器内启动,那么显
然,tomcat正确的端口绑定应该是容器的8080端口。
首先新启动tomcat使得绑定容器8080端口:
docker run -d -p 5555:8080 tomcat
查看容器信息:
docker ps
输出:
...
可以看出主机端口5555被映射到了容器8080端口
查看容器log:
docker log <CONTAINER ID>
直到输出日志表示tomcat启动完毕,访问tomcat:
127.0.0.1:5555
到此,我们已经使用了指定的主机端口与容器端口的映射,接下来是-p支持的所有规则:
ip:hostPort:containerPort
hostPort:containerPort
ip::containerPort
hostPort:主机端口
containerPort:容器端口
容器互联实现容器间通信
容器链接系统是除了端口映射外另一种可以与容器中应用进行交互的方式。它会在源和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信息。
自定义容器命名(命名不允许重复)
连接系统依据容器的名称来执行、因此首先需要自定义一个适宜的容器命名。创建容器时,系统会默认给容器分配名字,但不适宜我们进行方便的操作。
使用–name标记自定义命名:
docker run -d -p --name webA tomcat
查看是否设置成功:
docker ps
或
docker inspect -f "{{.Name}}" <CONTAINER ID>
容器互联
使用link参数使得容器间进行安全的交互,首先创建一个名为database的容器:
docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name -v /usr/local/data/mysql:/usr/lib/mysql database mysql
创建一个新的名为app的容器链接到database容器:
docker run -d -p 80:8080 --name app --link database:db tomcat
--link参数格式为:--link name:alias
name:要链接的容器名
alias:链接的别名
app访问数据库:jdbc_url=jdbc:mysql://<name>或<alias>:3306/<databaseName>?useUnicode=true&characterEncoding=utf8
关于上面-v参数挂载数据卷请点击链接。
注意:上面的例子中我们的mysql并没有映射到宿主机端口3306上,但是在web中却使用3306来链接,说明docker容器间的链接不用映射到宿主机店口上,而是在容器间创建了安全隧道。
使用env命令来查看tomcat环境变量
docker run --rm --name app1 --link database:db tomcat env
--rm:当退出时自动删除容器。
输出:
PATH=/usr/local/tomcat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=48b716f32fcd
DATABASE_PORT=tcp://172.17.0.2:3306
DATABASE_PORT_3306_TCP=tcp://172.17.0.2:3306
DATABASE_PORT_3306_TCP_ADDR=172.17.0.2
DATABASE_PORT_3306_TCP_PORT=3306
DATABASE_PORT_3306_TCP_PROTO=tcp
DATABASE_NAME=/app1/database
DATABASE_ENV_MYSQL_ROOT_PASSWORD=123456
DATABASE_ENV_GOSU_VERSION=1.7
DATABASE_ENV_MYSQL_MAJOR=5.7
.......