文章目录

  • 环境
  • 准备
  • 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官方文档 Github

环境

环境

版本

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文件夹中找到。

修改源码

修改源码的目的是什么?

  1. 适配数据库,让数据库信息在Rancher启动时就可以指定。
  2. 修改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=apollo的docker部署 apollo docker_Docker{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的docker部署 apollo docker_Apollo  Config_02APOLLO_CONF_DB_USER -Dspring.datasource.password=$APOLLO_CONF_DB_PWD

给portal模块的启动脚本添加数据库启动配置:

-Dspring.datasource.url=apollo的docker部署 apollo docker_Spring Cloud_03APOLLO_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

端口配置:

apollo的docker部署 apollo docker_Docker_04

环境变量

apollo的docker部署 apollo docker_apollo的docker部署_05

5.1 adminservice

端口配置

apollo的docker部署 apollo docker_Docker_06

环境变量

apollo的docker部署 apollo docker_Spring Cloud_07

5.2 portal

端口配置

apollo的docker部署 apollo docker_Rancher_08

环境变量

apollo的docker部署 apollo docker_Spring Cloud_09

持久卷

apollo的docker部署 apollo docker_Rancher_10

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,点击创建项目

apollo的docker部署 apollo docker_Spring Cloud_11


填写信息:

apollo的docker部署 apollo docker_Rancher_12


应用id为此项目的id。新建的项目默认会有一个application.properteis的namespace(apollo的称呼,理解为配置文件就行)。可以添加配置,发布。** 添加namespace **

添加namespace

apollo的docker部署 apollo docker_apollo的docker部署_13


选择类型

apollo的docker部署 apollo docker_Docker_14


编写配置

apollo的docker部署 apollo docker_Apollo  Config_15


完成后点击发布上线

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 微服务部署注意事项

  1. 其他微服务使用apollo配置中心提供配置文件时会在本地缓存最新的配置文件,路径在/opt/data目录下,所以建议做持久化,以免apollo服务挂掉后,镜像重启后无法获取配置文件。
  2. Apollo的app.id和apollo.meta可以通过Docker的环境变量传入,以便在不同环境下部署同一个微服务的Docker镜像。