文章目录
- 环境
- 准备
- 1.1 源码
- 1.2 环境
- 1.3 数据库
- 修改源码
- 2.1 解决Eureka注册ip错误问题
- 2.1.1 修改yml文件
- 2.1.2 修改启动脚本文件
- 2.2 解决数据库适配的问题
- 2.3 修改启动脚本
- 修改汇总
- 3.1 Dockerfile
- 3.2 启动脚本
- build
- Rancher部署
- 5.1 configservice
- 5.1 adminservice
- 5.2 portal
- 5.1.1 meta-service-url配置
- 微服务使用Apollo
- 6.1 apollo portal管理并发布配置
- 6.2 pom依赖
- 6.3 yml配置
- 6.4 添加注解
- 6.5 本地启动
- 6.6 微服务部署注意事项
项目上微服务,需要使用配置中心。技术选型选择了携程的Apollo配置中心,并且基于Rancher部署,所以需要把Apollo打包成Docker部署。Apollo提供了完善的文档说明,提供了QuickStart,只需要导入mysql数据库,配置数据库信息,本地运行启动脚本即可。
强大的懒惰基因驱使自己使用把QuickStart的jar包和脚本build成docker的方法(原QuickStart里有docker-coompose,但是因为需要部署到不同环境,而且项目本身已经有数据库,所以没有使用)。然后踩坑,Apollo的meta-server注册在Eureka的ip是docker镜像自身的ip,如果是Rancher集群内部的项目可以访问,但是如果想用本地开发就无法使用。所以,使用了分布式部署方式,给Apollo的三个组件打成不同的Docker镜像在Rancher部署。下面文档结合官方文档和Issue问答后的实践。
记录如下:
环境
环境 | 版本 |
Apollo | v1.4.0 |
Rancher | v2.2.4 |
Docker | 18.09.6 |
Java | 1.8.0_151 |
准备
1.1 源码
去Github,选择tag为1.4.0的branch,下载源码。家里有矿的用Git clone吧。
1.2 环境
准备Java&Docker环境,编译代码和打包Docker镜像用。
1.3 数据库
导入Apollo需要的数据库,可以在QuickStart的sql文件夹中找到。
修改源码
修改源码的目的是什么?
- 适配数据库,让数据库信息在Rancher启动时就可以指定。
- 修改ConfigService的Eureka注册信息,不能注册成Docker镜像的本地ip。
Dockerfile不需要自己编写,使用Apollo自带的即可。Dockerfile在下载源码的apollo-configservice,adminservice和apollo-portal的docker文件夹。
2.1 解决Eureka注册ip错误问题
方案文档:
网络策略issue 1303
2.1.1 修改yml文件
这里先采用网络策略文档中的修改yml文件配置方法。
修改apollo-configservice/src/main/resources/application.yml和apollo-adminservice/src/main/resources/application.yml文件,添加:
spring:
cloud:
inetutils:
ignoredInterfaces:
- docker0
- veth.*
实际build Docker镜像后发现eureka注册的还是镜像自身ip!后续操作也没有删除这个配置。
2.1.2 修改启动脚本文件
修改源码configservice和adminservice模块的启动脚本(start.sh),export JAVA_OPTS命令中添加
-Deureka.instance.ip-address={EUREKA_HOME_PAGE_IP}?{EUREKA_HOME_PAGE_PORT}
把指定要注册的eureka ip放到JAVA_OPT中:
export JAVA_OPTS="$JAVA_OPTS -Dspring.datasource.url=$APOLLO_PORTAL_DB_URL -Dspring.datasource.username=$APOLLO_PORTAL_DB_USER
-Dspring.datasource.password=$APOLLO_PORTAL_DB_PWD -Dserver.port=$SERVER_PORT
-Dlogging.file=$LOG_DIR/$SERVICE_NAME.log -XX:HeapDumpPath=$LOG_DIR/HeapDumpOnOutOfMemoryError/"
这个方法可以指定注册的ip。打包成dockerfile后运行时指定env参数即可。这里采用的是–env-file传入
docker run -d -p 8080:8080 --name configservice --env-file=test.env 192.168.6.96:8098/third-party/apollo-configservice:1.4.0
test.env:
EUREKA_IP_ADDRESS=192.168.126.100
EUREKA_HOME_PAGE_IP=192.168.126.100
EUREKA_HOME_PAGE_PORT=8080
运行后注册的ip正确,程序也可以连接meta-server。
注意: admin的eureka连接需要在ApolloPortalDB数据库的ServerConfig表中配置。配置eureka.service.url的value为部署的configservice docker的访问url!
2.2 解决数据库适配的问题
同样使用修改启动脚本文件的方法
2.3 修改启动脚本
给configservice,adminservice模块的启动脚本添加数据库启动配置:
-Dspring.datasource.url=APOLLO_CONF_DB_USER -Dspring.datasource.password=$APOLLO_CONF_DB_PWD
给portal模块的启动脚本添加数据库启动配置:
-Dspring.datasource.url=APOLLO_PORT_DB_USER -Dspring.datasource.password=$APOLLO_PORT_DB_PWD
** 启动同2.1.2,在docker启动时把数据库相关的env配置好。**
修改汇总
3.1 Dockerfile
给configservice,adminservice和portal模块的Dockerfile添加一条给启动脚本赋权的命令:
&& chmod +x /apollo-adminservice/scripts/startup.sh \
修改后:
adminservice Dockerfile
# Dockerfile for apollo-adminservice
# 1. Copy apollo-adminservice-${VERSION}-github.zip to current directory
# 2. Build with: docker build -t apollo-adminservice .
# 3. Run with: docker run -p 8090:8090 -d -v /tmp/logs:/opt/logs --name apollo-adminservice apollo-adminservice
FROM openjdk:8-jre-alpine
MAINTAINER ameizi <sxyx2008@163.com>
ENV VERSION 1.4.0
RUN echo "http://mirrors.aliyun.com/alpine/v3.8/main" > /etc/apk/repositories \
&& echo "http://mirrors.aliyun.com/alpine/v3.8/community" >> /etc/apk/repositories \
&& apk update upgrade \
&& apk add --no-cache procps unzip curl bash tzdata \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
ADD apollo-adminservice-${VERSION}-github.zip /apollo-adminservice/apollo-adminservice-${VERSION}-github.zip
RUN unzip /apollo-adminservice/apollo-adminservice-${VERSION}-github.zip -d /apollo-adminservice \
&& rm -rf /apollo-adminservice/apollo-adminservice-${VERSION}-github.zip \
&& sed -i '$d' /apollo-adminservice/scripts/startup.sh \
&& chmod +x /apollo-adminservice/scripts/startup.sh \
&& echo "tail -f /dev/null" >> /apollo-adminservice/scripts/startup.sh
EXPOSE 8090
CMD ["/apollo-adminservice/scripts/startup.sh"]
configservice Dockerfile
# Dockerfile for apollo-configservice
# 1. Copy apollo-configservice-${VERSION}-github.zip to current directory
# 2. Build with: docker build -t apollo-configservice .
# 3. Run with: docker run -p 8080:8080 -d -v /tmp/logs:/opt/logs --name apollo-configservice apollo-configservice
FROM openjdk:8-jre-alpine
MAINTAINER ameizi <sxyx2008@163.com>
ENV VERSION 1.4.0
RUN echo "http://mirrors.aliyun.com/alpine/v3.8/main" > /etc/apk/repositories \
&& echo "http://mirrors.aliyun.com/alpine/v3.8/community" >> /etc/apk/repositories \
&& apk update upgrade \
&& apk add --no-cache procps unzip curl bash tzdata \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
ADD apollo-configservice-${VERSION}-github.zip /apollo-configservice/apollo-configservice-${VERSION}-github.zip
RUN unzip /apollo-configservice/apollo-configservice-${VERSION}-github.zip -d /apollo-configservice \
&& rm -rf /apollo-configservice/apollo-configservice-${VERSION}-github.zip \
&& sed -i '$d' /apollo-configservice/scripts/startup.sh \
&& chmod +x /apollo-configservice/scripts/startup.sh \
&& echo "tail -f /dev/null" >> /apollo-configservice/scripts/startup.sh
EXPOSE 8080
CMD ["/apollo-configservice/scripts/startup.sh"]
portal Dockerfile
# Dockerfile for apollo-portal
# 1. Copy apollo-portal-${VERSION}-github.zip to current directory
# 2. Build with: docker build -t apollo-portal .
# 3. Run with: docker run -p 8070:8070 -d -v /tmp/logs:/opt/logs --name apollo-portal apollo-portal
FROM openjdk:8-jre-alpine
MAINTAINER ameizi <sxyx2008@163.com>
ENV VERSION 1.4.0
RUN echo "http://mirrors.aliyun.com/alpine/v3.8/main" > /etc/apk/repositories \
&& echo "http://mirrors.aliyun.com/alpine/v3.8/community" >> /etc/apk/repositories \
&& apk update upgrade \
&& apk add --no-cache procps unzip curl bash tzdata \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
ADD apollo-portal-${VERSION}-github.zip /apollo-portal/apollo-portal-${VERSION}-github.zip
RUN unzip /apollo-portal/apollo-portal-${VERSION}-github.zip -d /apollo-portal \
&& rm -rf /apollo-portal/apollo-portal-${VERSION}-github.zip \
&& sed -i '$d' /apollo-portal/scripts/startup.sh \
&& chmod +x /apollo-portal/scripts/startup.sh \
&& echo "tail -f /dev/null" >> /apollo-portal/scripts/startup.sh
EXPOSE 8070
CMD ["/apollo-portal/scripts/startup.sh"]
3.2 启动脚本
三个模块的启动脚本只是添加了export java_opt部分。
configservice 启动脚本修改部分:
export JAVA_OPTS="$JAVA_OPTS -Dspring.datasource.url=$APOLLO_CONF_DB_URL -Dspring.datasource.username=$APOLLO_CONF_DB_USER -Dspring.datasource.password=$APOLLO_CONF_DB_PWD -Deureka.instance.ip-address=$EUREKA_IP_ADDRESS -Deureka.instance.homePageUrl=http://${EUREKA_HOME_PAGE_IP}:${EUREKA_HOME_PAGE_PORT} -Dserver.port=$SERVER_PORT -Dlogging.file=$LOG_DIR/$SERVICE_NAME.log -XX:HeapDumpPath=$LOG_DIR/HeapDumpOnOutOfMemoryError/"
adminservice 启动脚本修改部分:
export JAVA_OPTS="$JAVA_OPTS -Dspring.datasource.url=$APOLLO_CONF_DB_URL -Dspring.datasource.username=$APOLLO_CONF_DB_USER -Dspring.datasource.password=$APOLLO_CONF_DB_PWD -Deureka.instance.ip-address=$EUREKA_IP_ADDRESS -Deureka.instance.homePageUrl=http://${EUREKA_HOME_PAGE_IP}:${EUREKA_HOME_PAGE_PORT} -Dserver.port=$SERVER_PORT -Dlogging.file=$LOG_DIR/$SERVICE_NAME.log -XX:HeapDumpPath=$LOG_DIR/HeapDumpOnOutOfMemoryError/"
portal 启动脚本部分:
export JAVA_OPTS="$JAVA_OPTS -Dspring.datasource.url=$APOLLO_PORTAL_DB_URL -Dspring.datasource.username=$APOLLO_PORTAL_DB_USER -Dspring.datasource.password=$APOLLO_PORTAL_DB_PWD -Dserver.port=$SERVER_PORT -Dlogging.file=$LOG_DIR/$SERVICE_NAME.log -XX:HeapDumpPath=$LOG_DIR/HeapDumpOnOutOfMemoryError/"
启动时,给对应的docker镜像添加需要的ENV参数即可。adminservice的eureka url需要在数据库中配置。portal不需要注册eureka,但是需要配置apollo-env.properties
build
使用源码scripts文件夹下的build.sh脚本build。然后把三个模块下target文件夹下的压缩包和对应的Dockerfile放在一起,执行Docker build,push到nexus。
Rancher部署
5.1 configservice
docker镜像名称:192.168.6.96:8098/third-party/apollo-configservice:1.4.0
端口配置:
环境变量
5.1 adminservice
端口配置
环境变量
5.2 portal
端口配置
环境变量
持久卷
5.1.1 meta-service-url配置
启动docker后,去到容器的/apollo-portal/config/目录,把apollo-portal-1.4.0-github.zip压缩包中的config文件均复制到此文件夹中,修改apollo-env.properties:
dev.meta=http://192.168.108.3:31080
微服务使用Apollo
6.1 apollo portal管理并发布配置
** 新建项目 **
登录apollo portal管理界面:http://192.168.108.3:31070,点击创建项目
填写信息:
应用id为此项目的id。新建的项目默认会有一个application.properteis的namespace(apollo的称呼,理解为配置文件就行)。可以添加配置,发布。** 添加namespace **
添加namespace
选择类型
编写配置
完成后点击发布上线
6.2 pom依赖
<!-- https://mvnrepository.com/artifact/com.ctrip.framework.apollo/apollo-client -->
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.4.0</version>
</dependency>
6.3 yml配置
添加新的yml配置文件application-dev.yml,添加配置如下:
app.id: 应用id
apollo:
meta: http://192.168.108.3:31080
bootstrap:
enabled: true
namespaces: application.yml
6.4 添加注解
SpringBoot启动函数添加注解:
@EnableApolloConfig({"application.yml"})
完成上述步骤后,修改spring.profiles.active=dev。启动项目,使用的就是apollo的配置文件了。
6.5 本地启动
本地启动添加参数:
-Denv = LOCAL
6.6 微服务部署注意事项
- 其他微服务使用apollo配置中心提供配置文件时会在本地缓存最新的配置文件,路径在/opt/data目录下,所以建议做持久化,以免apollo服务挂掉后,镜像重启后无法获取配置文件。
- Apollo的app.id和apollo.meta可以通过Docker的环境变量传入,以便在不同环境下部署同一个微服务的Docker镜像。