个人docker部署springcloud微服务到两个云服务器:一个阿里云,一个抖音的火山引擎
启动必要服务
先docker上运行mysql,nacos,es,mq等,pull超时考虑docker换源,
docker run --name mysql -e MYSQL_ROOT_PASSWORD=124578 -p3306:3306 -d mysql
本地打包
本地打包各个微服务jar包,注意要在pom.xml中添加spring boot maven插件,先clean,再package,生成的jar包再target目录下,先在本地运行看jar包是否能正常运行。common包不需要打包,
java -jar xxx.jar
上传到云服务器中,我是为每个微服务新建单独文件夹,用于存放jar包和Dockerfile
构建容器运行
为每个微服务编写Dockerfile,放在jar包同一目录下
比如网关微服务:
FROM openjdk:8
ENV APP_HOME=/apps
WORKDIR $APP_HOME
COPY ./sgateway-1.0-SNAPSHOT.jar ./gateway.jar
EXPOSE 3000
ENTRYPOINT ["java","-jar"]
CMD ["gateway.jar"]
再运行build为镜像
docker build -t s-gateway:1.0 .
运行容器:
docker run -d --name s-gateway -p 3000:3000 s-gateway:1.0
则对应微服务启动成功。如法炮制启动其他微服务。注意修改镜像名和容器名
至此如果全部微服务都部署在同一个云服务器下,它们的互相调用服务不会出错,可以正常使用。
nacos注册中心注册的是docker内网IP问题
但我的项目一共9个微服务,预想的是在阿里云上部署网关微服务和另一个小微服务,其他7个部署在火山云,以上面的方式构建的镜像运行后,发现网关无法转发任务到对应服务,查看发现nacos注册中心注册的默认是容器内网ip,即172.x.x.x,而网关拿着容器内部ip显然访问不到火山云上的服务,一直显示remote不可达什么。
查找资料有三种解决方法:
1.搭建overlay集群,利用docker swarm,不太熟,没尝试
2.配置容器网络模式为host(默认的是桥接),
即运行容器时使用
docker run -d --name s-gateway --network host s-gateway:1.0
但是我试了还是无法跨主机调用,nacos中注册的服务地址还是内网地址
3.注册公网IP,强制固定nacos中注册服务公网ip地址,在dockerfile中加上"-Dspring.cloud.nacos.discovery.ip=14.103.55.240"
FROM openjdk:8
ENV APP_HOME=/apps
WORKDIR $APP_HOME
COPY ./sgateway-1.0-SNAPSHOT.jar ./gateway.jar
EXPOSE 3000
ENTRYPOINT ["java","-jar","-Dspring.cloud.nacos.discovery.ip=服务器公网ip"]
CMD ["gateway.jar"]
再重新build,run。
这下成功注册成公网IP
利用apipost测试,阿里云上的网关也成功将请求转发到对应服务。
可优化点
1.手动一个一个服务run,可以使用docker compose批量启动
2.部署前端vue到nginx后,访问服务返回405,估计是nginx哪里没配置好,看看后面能不能解决一下,但本地运行前端,调用云服务器上后端接口没问题的
3.每次修改都要重新上传jar,重新生成镜像,微服务多的时候很麻烦