springcloud+vue docker部署记录—1
前言
项目是springcloud + vue架构。
如果采用传统的部署方式,我们需要部署安装:
- eureka:注册中心
- zuul:网关中心
- config:配置中心
- 若干子服务
- mysql
- nginx
- redis
而且为了搭建高可用的微服务体系,每个服务势必需要部署两个以上,因此传统的部署方式几乎无法完成这庞杂的部署任务,更别说频繁的改动与发布。采用docker部署是必须且必然的。
镜像与容器
镜像(image)
docker镜像:通俗的说在docker中比如mysql就是个镜像,镜像与容器的关系可以理解为镜像就是java的类,而容器就是类的对象
容器(container)
docker镜像,即上文提到的镜像的对象,实实在在运行在宿主机上的一个实例
阶段
该文档从第一阶段单机部署开始
假设所有的服务部署在一台服务器上,该场景模拟简单的开发环境,(实际生产基本不可能是这样),熟悉一下基本的docker部署方式
环境准备
虚拟机2台(centOS7)
安装docker
部署架构
主机 | ip | 部署服务 |
---|---|---|
hyper1 | 10.18.32.215 | 所有服务 |
hyper2 | 10.18.32.161 | mysql, redis, nginx |
部署数据库、中间件
部署mysql
- 拉取mysql镜像(以版本5.5为例)
docker pull mysql:5.5
- 启动mysql容器
docker run -d --name mysql -p 3306:3306 -v /home/docker/volumes/mysql/logs:/logs -v /home/docker/volumes/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.5 #--name 容器名称,同一网络下的其他容器可以直接通过该名称访问该容器 #-p 映射3306端口到宿主机,即访问宿主机ip:3306就可以访问到该mysql容器 #-v 挂载容器目录到宿主机下,数据文件必然需要持久化,因此需要挂载到主机下,避免容器重启导致数据丢失。此处挂载数据文件和日志到宿主机下,因为镜像功能最小化导致容器内并没有vi等命令,因此类似conf等配置文件可以在宿主机下配置好后挂载到容器内 #-e MYSQL_ROOT_PASSWORD=123456,即初始化root密码为123456
部署redis
- 拉取redis镜像
docker pull redis
- 在宿主机上准备配置文件redis.conf
- 启动master容器
docker run -d --name redis-master -v /home/docker/volumes/redis-master:/data -p 6379:6379 redis #-v 即把宿主机/home/docker/volumes/redis-master目录挂载到容器/data下,reids.conf就在该宿主机目录下,便于修改
- 启动服务
docker exec -it redis-master /bin/bash cp /data/redis.conf /usr/local/bin /usr/local/bin/redis-server redis.conf #进入容器,将配置文件复制到/usr/local/bin路径下,启动master
部署nginx(该阶段仅用于代理前端项目)
-
拉取nginx镜像
docker pull nginx
-
创建挂载目录,将前端项目和nginx.conf挂载到容器内
-
运行nginx容器
扫描二维码关注公众号,回复: 11328564 查看本文章docker run -d --name nginx -v /home/docker/volumes/nginx:/data -p 8080:8080 nginx
-
替换nginx配置
docker exec -it nginx /bin/bash cp /data/nginx/conf /etc/nginx
-
重启容器
docker restart nginx
服务部署
创建网络
因为所有微服务之间需要网络互通,需要创建网络并把相关的容器部署在指定网络下
docker network create -d bridge test-net
# -d bridge 即桥接网络,之后还会用到其他网络类型
# test-net 创建的网络名称
注册中心eureka
-
创建宿主机挂载目录
该目录维护部署脚本和jar包挂载到容器中,通过Dockfile指定脚本,脚本指定jar包的方式实现解耦,便于后期更新维护mkdir -p /home/eureka
-
编写部署脚本
cd /home/eureka vi deploy.sh #内容如下 java -jar /data/eureka.jar --xxx # /data即挂载的容器路径 # -xxx 自定义启动命令 chmod 777 deploy.sh # 脚本编写完成后授权可由容器启动
-
上传jar包到宿主机挂载的路径下
-
编写Dockerfile
# jdk8 FROM openjdk:8-jre-slim # 作者小水牛 MAINTAINER xsn #暴露端口(并非映射) EXPOSE 10100 #执行sh -c ENTRYPOINT ["sh", "-c"] #给entrypoint传参,即执行上个步骤定义的deploy.sh CMD ["/data/deploy.sh"]
-
制作镜像
docker build -t eureka:1.0 . #容器版本1.0 #在Dockerfile同级路径,且不要放其他文件 #注意最后还有一个.表示上下文路径
-
启动容器
docker run -d --name eureka -p 10100:10100 -v /home/eureka:/data --network test-net eureka:1.0 #--network 将容器连接到test-net网络下,则其他连接到test-net下的服务可以直接通过容器名注册,即服务配置eureka如下: eureka: client: service-url: defaultZone: http://eureka:10100/eureka #但是连接hyper2宿主机中的数据库,因为不是同一宿主机,暂时只能通过映射到宿主机下的端口来访问,即10.18.32.161:port
其他服务部署
其他服务的部署基本都和上述步骤如出一辙
后记
如此,我们在单宿主机上部署注册中心、配置中心、网关中心和子服务A、子服务B于同一网络下,它们之间通过容器名互联。我们再将注册中心、网关中心(如果有必要的也可以把子服务)映射到宿主机上,则可直接通过宿主机访问对应服务。
每个容器都有自己的ip,是宿主机docker0网桥的一个子网,该子网范围可以通过修改配置文件指定(centos下是/etc/docker/daemon.json,如果不存在可以自行创建)
{
"registry-mirrors": [
"https://jgrwc2yp.mirror.aliyuncs.com"
,"https://hub-mirror.c.163.com/"
,"https://reg-mirror.qiniu.com"],
"bip": "172.17.43.1/24"
}
#registry-mirrors 国内镜像地址
#bip 子网分配规则
如此容器间通过分配的子网ip也可以互联。
但是不同宿主机下的容器则无法互联(实际生产环境肯定是多宿主机),虽然我们可以通过映射端口的方式实现,但宿主机的端口毕竟有限,并且这样做并不符合容器的理念,因此容器跨主机互联是必须的,我们可以通过搭建docker swarm集群来实现。下一篇文章介绍docker swarm集群搭建