Docker学习笔记---day011(微服务实战)
文章目录
一、Docker微服务实战
1.1、构建一个简单的微服务项目

1.2、通过maven将项目打成jar包
powershell
mvn clean package

1.3、通过dockerfile发布微服务部署到docker容器
1.3.1、编写Dockerfile
powershell
# 基础镜像使用java
FROM openjdk:8
# 作者
MAINTAINER radan
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为radan_docker.jar
ADD DockerSpringBoot-0.0.1-SNAPSHOT.jar radan_docker.jar
# 运行jar包
RUN bash -c 'touch /radan_docker.jar'
ENTRYPOINT ["java", "-jar", "/radan_docker.jar"]
# 暴露6001端口作为微服务
EXPOSE 6001
1.3.2、构建镜像
powershell
docker build -t radan_docker .
1.3.3、运行容器
powershell
docker run -d -p 6001:6001 镜像ID/镜像名
1.3.4、访问测试
powershell
curl 127.0.0.1:6001/order/docker
curl 127.0.0.1:6001/order/index


遇到的问题:jar包中没有主清单属性
当在 pom.xml中将 Spring Boot Maven 插件的 参数设置为 true时,执行 mvn package进行打包,这个插件会完全被跳过。

解决办法修改pom.xml文件(也可参考这个博主)

二、Docker网络
2.1、Docker网络结果是什么
2.1.1、Docker不启动默认的网络结构
当docker未启动的时候,只有一些常用的网络选项。
- ens33:
- IO:
- virbr0:
2.1.2、Docker启动后,网络情况
docker启动后会产生一个名为docker0的虚拟网桥
2.2、查看Docker的网络模式命令
安装完docker后,会默认的创建3大网络模式
powershell
docker network connect # 将容器链接到网络
docker network create # 创建一个网络
docker network disconnect # 将容器断开到网络
docker network inspect # 展示一个网络的细节信息
docker network ls # 查看docker的网络模式
docker network prune # 移除所有未使用的网络
docker network rm # 移除一个或多个网络
累出当前网络模式

查看具体网络的具体信息

2.3、Docker网络有什么用
- 容器间的互联和通信以及端口映射
- 容器IP变动时候可以通过服务名直接网络通信而不受影响
2.4、Docker的网络模式
| 4种网络模式 | 简介 |
|---|---|
| bridge | 为每一个容器、设置IP等,并将容器连接到docker0上 (虚拟网桥,默认是该模式) |
| host | 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口号 |
| none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配 veth pair和网桥连接,IP等 |
| container | 新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个制定的容器共享IP和端口范围 |
- bridge模式:使用 --network bridge指定,默认使用docker0
- host模式:使用--network host指定
- none模式:使用--network none指定
- container模式 :使用--network container:容器名或容器ID
2.5、容器实例内默认
docker 容器内部的IP是有可能会发生改变的
所以我们要利用网络规划好各种服务,通过服务名来获取ID
2.6、Dockernet之bridge模式
Docker服务默认会创建一个docker0网桥 (其上有一个docker0的内部接口),该桥接网络的名称为docker0,它在内核层连通了其它的物理或虚拟网卡,这就将所有容器和主机都放到同一个物理网络中 。
Docker默认制定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网络相互通信。
- 1、整个宿主机的网桥模式都是docker0 ,类似于一个交换机有一堆接口,每个接口叫veth ,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一堆接口叫veth pair)
- 2、每个容器实例内部也有一块网卡 ,,每个接口叫eth0
- 3、docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
因此,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一网络下,会从这个网关下各自拿到分配的IP,此时两个容器的网络是互通的。(容器互相是没办法通信的,只有通过网桥才能实现互连互通)

案例
新建两台tomcat实例容器
powershell
docker run -d -p 8081:8080 --name tomcat81 tomcat:8
docker run -d -p 8082:8080 --name tomcat82 tomcat:8
主机内网络信息:

在容器内部的网络信息

注意:主机内部的veth和容器内部的网络接口eth0两者是一一匹配的关系。
2.7、Dockernet之host模式
直接使用宿主机的IP地址和外界进行通信,不在需要额外进行NAT转换
容器将不会获得一个独立的Network Namesoace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,而是使用宿主机的IP+端口号

案例
powershell
docker run -d -p 8083:8080 --network host --name tomcat83 tomcat:8
docker run -d --network host --name tomcat83 tomcat:8
启动实例容器遇到的问题:docker启动时总是遇见标题中的警告信息

原因:Docker启动时指定--network=host或-net=host,如果还指定了-p映射端口,此时就会出现这样的警告信息,并且通过-p设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增。
解决:使用docker的其它网络模式,例如--network=bridge,这样可以解决,或者忽略此警告信息。
host模式下,容器没有自己的网关和IP

进入容器内部,发现网络配置和宿主机的网络配置是一样的

重点问题:现在host模式下启动了tomcat没有指定端口,我们如何才能访问到tomcat的首页呢?
现在相当于就是在主机上装了一个tomcat,所以只需要使用主机IP+8080端口号进行访问即可
2.8、Dockernet之none模式
容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配 veth pair和网桥连接,IP等
禁用了网络功能。
在None模式下,并不为Docker容器进行任何网络设置(这个Docker容器没有网卡、IP。路由等信息)--- 需要我们自己为Docker容器添加网卡、配置IP等
案例
powershell
docker run -d -p 8084:8080 --network none --name tomcat84 tomcat:8
docker inspect tomcat84|tail -n 20

2.9、Dockernet之Container模式
新建的容器和已经存在的一个容器共享一个网络IP配置而不是和宿主机刚性。
新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个制定的容器共享IP、端口范围。
两个容器除了网络方面,其它的如文件系统、进程列表等都还是隔离的

案列1
powershell
docker run -d -p 8085:8080 --name tomcat85 镜像ID
docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 镜像ID
遇到的问题

问题原因:相当于tomcat86和tomcat85共用同一个IP+端口号,导致端口冲突(本案例不适合显示)
案列2
本案例使用Alpine Linux是一款独立的、非商业的通用Linux发行版本。(作为基础镜像非常好的选择)
powershell
docker pull alpine
docker run -it --name alpine1 alpine /bin/sh
docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh

假如我们把alpine1容器停了,又会造成什么影响?
ehth0@if9:消失了!

2.10、自定义网络模式
自定义网络主要解决的问题:容器IP变动时候可以通过服务名直接网络通信而不受影响
案例1
powershell
# 启动两个tomcat实例容器
docker run -d -p 8081:8080 --name tomcat81 tomcat
docker run -d -p 8082:8080 --name tomcat82 tomcat
# 使用exec进入各个容器内部
docker exec -it tomcat81 bnash
docker exec -it tomcat82 bnash
tomcat81的IP172.17.0.2

tomcat82的IP172.17.0.3

- 首先看按照IP地址是否可以Ping通
powershell
ping 172.17.0.3

- 按照服务名可否ping通
由于容器的Ip地址是变换的,为了防止变动,我们必须用服务名去动态的获取指定IP。
直接使用服务名去ping看是否能够ping通呢?

可以看出,直接使用服务名两个容器是ping不通的
案例2:容器是如何通过服务名进行网络的互联互通的
- 新建自定义网络
powershell
docker network create radan_network
- 新建容器加入上一步新建的自定义网络
powershell
docker run -d -p 8081:8080 --network radan_network --name tomcat81 tomcat
docker run -d -p 8082:8080 --network radan_network --name tomcat82 tomcat
- 互相ping测试
powershell
ping tomcat82

自定义网络本身就维护好了主机名和ip的对应关系(ip和服务名都是可以ping通的)
