本讲是从Docker系列讲解课程,单独抽离出来的一个小节,主要介绍容器间内部相互访问和外部访问容器的一些方法,它和前面两篇:容器五种(3+2)网络模式、容器之间单/双向通信 |--link /自定义网络知识点互补。
通过对本文的学习,可以对docker run的-p -P两个参数,有个深入的了解,同时对容器间的访问也会有个深入的认识。这些基本功也会后期学好K8s做一些铺垫,从而打下一个坚实的基础。
-p(小写)常用方式,多用于生产环境,格式:主机端口:容器端口
-P(大写)随机分配端口映射,多用于测试,宿主机会随机映射一个 49000~49900 的端口到映射容器内部的端口。
注:-d 参数 是后台静默运行,及时当前窗口关闭了,服务不会停止;sleep参数 ,指定容器后台阻塞运行N秒后自动销毁,想了解更多点击进入,第二章节第3小节。
此处的所有端口,指的是自动匹配容器的内部端口。比如启动的是nginx自动匹配80,映射到80端口;容器是Tomcat,自动匹配8080端口,映射8080端口。
docker run -d --rm -P nginx:alpine sleep 30 #注意:这里是大写的P (30s后,容器通过--rm自行销毁)
docker ps -a #查看端口自动分配情况
docker run -d --rm -p 80 nginx:alpine sleep 30 #注意:这里是小写的p, 这个80是容器内的80端口
docker ps -a #查看端口自动分配情况
docker run -it -p 80:80 nginx /bin/bash
docker run -it -p 8080:80 nginx /bin/bash
docker run -it -p 443:443 nginx /bin/bash
docker run -it -p 80:80 -p 443:443 nginx /bin/bash #给一个容器指定多个端口映射
docker run -it -p 80:80 -p 443:443 --restart=always nginx #容器出现异常,自尝试重新启动
docker run -it -p 192.168.31.100:8080:80 nginx /bin/bash
docker run -it -p 192.168.31.100::80 nginx /bin/bash
访问原理:
需要把容器的内部端口,通过-p或-P做映射,从而把宿主机的端口暴露给外界,供外界访问,从而间接的访问到容器内部。
比如:docker run -p 8000:8080,后面的8080就是容器内部的端口,8000就是宿主机的端口,也是8080的映射端口,外界通过宿主机的8000端口来间接访问容器内部的8080端口。
理论总是有些绕口,看实战吧!
docker run -d -P --name mytomcat tomcat:8.5.46-jdk8-openjdk #通过-P,主机随机端口映射容器端口
docker ps #查看容器对外暴露端口和宿主机映射端口
在第一章节,已经提及,-P,宿主机会自动随机指定49000~49900内的一个端口,指向容器的内部端口,如下图所示:主机随机端口为49153,Tomcat容器内部的端口是8080。其中49153就是本实验要访问的宿主机端口。
宿主机IP是192.168.31.130,所以访问的地址应该是:192.168.31.130:49153
发现,在物理机直接访问 192.168.31.130:49153是可以访问容器内部的Tomcat的。
解析:表面访问的是 192.168.31.130:49153,实际访问的又是什么呢?实际访问的是虚拟机内部的tomcat容器内部的IP+容器内部的8080端口。
怎么查看容器的虚拟IP地址呢?通过docker inspect mytomcat就可以查看了。
docker inspect mytomcat #根据容器的别名,查看容器的详细信息,主要查看IP、端口
由此,可以获悉容器的虚拟IP地址是172.17.0.2,内部访问端口是8080。
也就是说我们访问的: 192.168.31.130:49153,实际上访问的是172.17.0.2:8080
docker run -d -p 5000:8080 --name cat tomcat:8.5.46-jdk8-openjdk #通过-p 指定主机端口映射容器指定端口
docker ps #查看容器对外暴露端口和宿主机映射端口
因为指定的宿主机端口是5000,所以下面用访问宿主机的IP+5000端口,访问容器内部的tomcat。
192.168.31.130:5000
上面介绍了-p和-P的常用的5种端口映射方式和外部浏览器访问容器的方法和步骤。下面一起来看一下,容器之间的相互访问吧!
访问原理:
同一宿主机的容器与容器之间除网络资源外(仅桥接模式和部分自定义网络模式下,网络互通),其他资源都是相互隔离。docker run 启动容器时,默认是使用的是桥接网络模式,在此模式下,在同一宿主机下的各容器可以通过对方容器的IP来进行访问。
如果使用自定义网络模式时-d bridge,容器之间可以通过别名相互访问。
docker rm -f $(docker ps -qa) #实验前,清空不相关容器,防止干扰下面的试验
docker images #查看镜像列表
docker run -d nginx:alpine #使用默认网络模式(bridge)启动nginx
docker run -d -p 8080:8080 tomcat:8.5.46-jdk8-openjdk #使用默认网络模式(bridge)启动tomcat
docker ps #查看已启动容器列表
docker inspect 26d018333e00 #根据容器id查看nginx的网络信息(主要查看IP)
docker inspect f0f47e02ea8f #根据容器id查看tomcat的网络信息(主要查看IP)
获悉nginx和tomcat的虚拟IP分别为172.17.0.2、172.17.0.3
进入nginx容器内部,访问tomcat虚拟IP,发现可以访问通
docker exec -it 26d018333e00 /bin/sh #进入nginx容器内部
ping -w 3 172.17.0.3 #尝试ping通tomcat服务器IP
进入tomcat容器内部,访问nginx虚拟IP,发现可以访问通
该章节的内容,在“容器之间单/双向通信”,一文中有详细介绍,可以点击进入了解一下。可以使用--link方式,也可以使用自定义网络模式,从而实现容器间通过别名相互访问。
下面就再简单介绍一下第二种方式(自定义网络模式)。
docker rm -f $(docker ps -qa) #清空无关容器
docker network ls #先查看已有的网络模式
docker network create -d bridge mynet #创建自定义网络,并指定为bridge桥接网络模式
docker network ls #查看自定义的网络模式,是否创建成功
注:如果你想了解更多的docker network命令的使用,点击进入点击进入,查看最后的第五章节。
docker images #查看已有镜像
docker run -d --name nginx --net=mynet nginx:alpine #指定网络为自定义网络mynet启动nginx
docker run -d --name tomcat --net=mynet -p 8080:8080 tomcat:8.5.46-jdk8-openjdk #指定网络为自定义网络mynet启动tomcat
docker inspect nginx
docker inspect tomcat
最终得知nginx和tomcat的虚拟ip分别是172.18.0.2 和 172.18.0.3
注:docker0虚拟网卡的默认网段是172.17,自定义网络mynet的网段和docker0的网段不能有重叠,默认是172.18。
在docker network create 时,可以通过--subnet指定网段(不使用默认的网段),感兴趣的话,点击进入,查看第三章节,当然,--subnet在docker run时也可以额外指定。
docker exec -it nginx sh #进入nginx容器内部
ping -w 3 172.18.0.3 #ping tomcat的虚拟IP
ping -w 3 tomcat #ping tomcat的别名
exit
docker exec -it tomcat bash #进入tomcat容器内部
ping -w 3 172.18.0.2 #ping nginx的虚拟IP
ping -w 3 nginx #ping nginx 的别名
exit
发现,通过自定义的网络模式(-d 指定为桥接)后,连接同一自定义网络的容器默认是可以通过别名相互访问的。
在容器内部访问同一宿主机的其他容器,默认只能通过其虚拟IP访问,是不识别对方容器的别名的。要想识别对方的别名,使用自定义网络模式,是不错的选择。
1、无论是外部浏览器访问容器,还是容器间相互访问,容器都需要有各自的独立/共享(虚拟)ip,才可以( 桥接网络模式默认会为每一个容器单独分配虚拟的ip,Host网络模式的容器默认会共享宿主机的网络资源,host模式下的容器没有自己独立的ip,想了解更多,点击进入)。
2、同一宿主机下的容器,在桥接模式下模式是可以通过各自的虚拟ip,相互在容器内部访问;要想通过容器的别名相互访问,各容器,需要连接同一指定的自定义网络,来实现,更多详情,见容器间通过别名单/双向通信。
本讲是从 Docker入门到进阶系列里面抽离出来的内容,因为它是一个庞大的知识体系,一篇文章难以讲述清楚,也为了让原文根据层次分明,同时也可以加深自己对该知识点的理解,在此汇总分享给大家,希望对大家有所帮助。
如果觉得还不错,欢迎点赞,留言!
最后,附注上你可能感兴趣的内容,送给爱学习的你,为你鼓掌、加油
1、Docker容器 | Dockerfile优化
2、Docker容器的生命周期 | kill和stop | pause 和 unpause
3、 Docker容器五种(3+2)网络模式 | bridge模式 | host模式 | none模式 | container 模式 | 自定义网络模式详解
4、容器之间单/双向通信 |--link /自定义网络实现互认容器别名
5、Docker核心命令 | 常用命令 | Docker build . 点的含义 | docker build和docker commit关系 | docker rm 与sleep用法_docker build --rm