Apollo分布式Docker部署
# 一、前置准备
# 1.1 数据库脚本准备
数据库这里直接使用外部准备好的,如果没有数据库则需要先部署数据库,然后把数据库脚本导入。
apolloportaldb地址:
https://github.com/apolloconfig/apollo/tree/1.9.1/scripts/sql/apolloportaldb.sql
apolloconfigdb地址:
https://github.com/apolloconfig/apollo/tree/1.9.1/scripts/sql/apolloconfigdb.sql
关于数据库我们也可以在下载源码之后,在apollo/scripts/sql
目录下查看,Apollo服务共需要两个数据库:ApolloPortalDB
和ApolloConfigDB
,ApolloPortalDB
只需要在生产环境部署一个即可,而ApolloConfigDB
需要在每个环境部署一套,如dev、test、和pro分别部署3套ApolloConfigDB
。
# 1.2 环境准备
这里环境指的是apollo分布式部署需要事先确定部署的环境,Apollo目前支持以下环境:
- DEV
- 开发环境
- FAT、FWS
- 测试环境,相当于alpha环境(功能测试)
- UAT
- 集成环境,相当于beta环境(回归测试)
- LPT
- 灰度环境
- PRO
- 生产环境
上面,四个环境基本可以满足我们企业使用,然而对于测试环境FAT
,可能有些企业使用TEST
、SIT
等表示,然后内置环境并不支持我们这样,因此如果想要新增这种自定义的环境,则需要我们进一步修改源代码,这里我们以新增TEST
为例:
d第一步: 修改com.ctrip.framework.apollo.core.enums.Env (opens new window)类,在其中加入
TEST
枚举,类路径: apollo-core/src/main/java/com/ctrip/framework/apollo/core/enums/Env.java
public enum Env{
LOCAL, DEV, TEST,FWS, FAT, UAT, LPT, PRO, TOOLS, UNKNOWN;
public static Env fromString(String env) {
Env environment = EnvUtils.transformEnv(env);
Preconditions.checkArgument(environment != UNKNOWN, String.format("Env %s is invalid", env));
return environment;
}
}
2
3
4
5
6
7
8
9
第二步: 修改com.ctrip.framework.apollo.core.enums.EnvUtils (opens new window)类,在其中加入
TEST
枚举的转换逻辑,类路径: apollo-core/src/main/java/com/ctrip/framework/apollo/core/enums/EnvUtils.java
public final class EnvUtils {
public static Env transformEnv(String envName) {
if (StringUtils.isBlank(envName)) {
return Env.UNKNOWN;
}
switch (envName.trim().toUpperCase()) {
case "LPT":
return Env.LPT;
case "FAT":
case "FWS":
return Env.FAT;
case "UAT":
return Env.UAT;
case "PRO":
case "PROD": //just in case
return Env.PRO;
case "DEV":
return Env.DEV;
case "TEST":
return Env.TEST;
case "LOCAL":
return Env.LOCAL;
case "TOOLS":
return Env.TOOLS;
default:
return Env.UNKNOWN;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
第三步: 修改com.ctrip.framework.apollo.core.internals.LegacyMetaServerProvider (opens new window)类,增加读取
TEST
环境的meta server
地址逻辑,类路径: apollo-core/src/main/java/com/ctrip/framework/apollo/core/internals/LegacyMetaServerProvider.java
private void initialize() {
Properties prop = new Properties();
prop = ResourceUtils.readConfigFile("apollo-env.properties", prop);
domains.put(Env.LOCAL, getMetaServerAddress(prop, "local_meta", "local.meta"));
domains.put(Env.DEV, getMetaServerAddress(prop, "dev_meta", "dev.meta"));
domains.put(Env.TEST, getMetaServerAddress(prop, "test_meta", "test.meta"));
domains.put(Env.FAT, getMetaServerAddress(prop, "fat_meta", "fat.meta"));
domains.put(Env.UAT, getMetaServerAddress(prop, "uat_meta", "uat.meta"));
domains.put(Env.LPT, getMetaServerAddress(prop, "lpt_meta", "lpt.meta"));
domains.put(Env.PRO, getMetaServerAddress(prop, "pro_meta", "pro.meta"));
}
2
3
4
5
6
7
8
9
10
11
12
第四步: 修改apollo-env.properties (opens new window),增加
test.meta
占位符,这里直接修改脚本即可:scripts/build.sh
# meta server url, different environments should have different meta server addresses
dev_meta=http://fill-in-dev-meta-server:8080
test_meta=http://fill-in-test-meta-server:8080
fat_meta=http://fill-in-fat-meta-server:8080
uat_meta=http://fill-in-uat-meta-server:8080
pro_meta=http://fill-in-pro-meta-server:8080
2
3
4
5
6
# 二、构建镜像
Apollo 1.7.0版本开始会默认上传Docker镜像到Docker Hub (opens new window),这里因为需要自定义环境修改了服务端源码,因此需要自定义构建镜像部署,后面会单独介绍下如果直接使用官方镜像直接部署。
# 2.1 构建脚本配置文件修改
官方把一些公共配置都集成到构建脚本中,我们修改下即可 脚本路径: apollo/scripts/build.sh
1) 修改数据库连接
# ##修改数据库连接信息
# apollo config db info
apollo_config_db_url='jdbc:mysql://{prodMYSQL}:3306/apolloconfigdb?characterEncoding=utf8'
apollo_config_db_username='apollo'
apollo_config_db_password='*******'
# apollo portal db info
apollo_portal_db_url='jdbc:mysql://{prodMYSQL}:3306/apolloportaldb?characterEncoding=utf8'
apollo_portal_db_username='apollo'
apollo_portal_db_password='******'
2) 修改各环境meta server参数配置
# 这里我们先部署pro环境为例 注意端口号
dev_meta=http://fill-in-dev-meta-server:8080
test_meta=http://fill-in-test-meta-server:8080
fat_meta=http://fill-in-fat-meta-server:8080
uat_meta=http://fill-in-uat-meta-server:8080
pro_meta=http://172.16.10.76:8080
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 2.2 修改应用配置
- apollo-adminservice配置文件
路径: apollo/apollo-adminservice/src/main/resources/application.yml
spring:
application:
name: apollo-adminservice
profiles:
active: ${apollo_profile}
cloud:
inetutils:
ignoredInterfaces:
- docker0
- eth1
ctrip:
appid: 100003172
server:
port: 8090
logging:
file:
name: /opt/logs/100003172/apollo-adminservice.log
eureka:
instance:
ip-address: 172.16.10.76
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- apollo-configservice配置文件
路径: apollo/apollo-configservice/src/main/resources/application.yml
spring:
application:
name: apollo-configservice
profiles:
active: ${apollo_profile}
cloud:
inetutils:
ignoredInterfaces:
- docker0
- eth1
server:
port: 8080
logging:
file:
name: /opt/logs/100003171/apollo-configservice.log
eureka:
instance:
ip-address: 172.16.10.76
ctrip:
appid: 100003171
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- apollo-portal配置
路径: apollo/apollo-portal/src/main/resources/application.yml
spring:
application:
name: apollo-portal
profiles:
active: ${apollo_profile}
jpa:
properties:
hibernate:
query:
plan_cache_max_size: 192 # limit query plan cache max size
server:
port: 8070
compression:
enabled: true
tomcat:
use-relative-redirects: true
logging:
file: /opt/logs/100003173/apollo-portal.log
management:
health:
status:
order: DOWN, OUT_OF_SERVICE, UNKNOWN, UP
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
配置说明
- ignoredInterfaces: 忽略某些网卡,主机多网卡时,我们可以忽略通信有问题的网卡,根据需要配置,也可以在启动到时候指定
- eureka.instance.ip-address: 指定注册IP,也可以使用
homePageUrl
参数指定注册的url - server.port: 服务端口,如果想要修改应用端口,则需要修改下启动脚本中的
SERVER_PORT
变量,路径:apollo-adminservice/src/main/scripts/startup.sh
更多用法参考配置: https://www.apolloconfig.com/#/zh/deployment/distributed-deployment-guide?id=_14-%e7%bd%91%e7%bb%9c%e7%ad%96%e7%95%a5
# 2.3 制作镜像
- 代码打包
镜像制作之前,我们需要先把代码构建打包,依赖java、mvn环境,需要提前安装
# 打包直接执行
./scripts/build.sh
2
- 方式一: 镜像构建
默认配置,方便快捷
# 1) 第一种 代码打包成功后,可以使用mvn命令进行镜像制作:
mvn docker:build -pl apollo-configservice,apollo-adminservice,apollo-portal
2
- 方式二: 镜像构建
可以自定义一些配置参数
# 2) 第二种 使用官方提供的Dockerfile构建 apollo/apollo-${service}/src/main/docker 目录下
这里以apollo-adminservice为例
cd apollo/apollo-adminservice/target/docker
cp apollo/apollo-adminservice/src/main/docker/Dockerfile .
docker build -t registry.cn-hangzhou.aliyuncs.com/tfgol-dev/apollo-adminservice:prod .
2
3
4
5
- 镜像上传【可选】
其实这里我们只需要使用portal的镜像即可,其他都可以直接使用官方的镜像直接配置相关参数启动即可
这里是因为镜像是在本地机器构建,因此上传至镜像仓库,方便在其他机器拉取启动。
# 2.4 配置校验
这一步是可选步骤,当我们上面打包应用之后,可以看下,脚本中的配置是否正确的配置,如果修改是需要在应用构建打包之前修改。
- 数据库配置校验
文件路径: apollo-adminservice/target/classes/application-github.properties
- portal环境参数
文件路径: apollo-portal/target/classes/apollo-env.properties
- 关于启动脚本
这里的启动脚本,是镜像中应用的启动脚本,针对我们自定义的时候,可以修改的一些配置,脚本位置: apollo/apollo-portal/src/main/scripts
,比如我们上面配置文件中指定的,可以在启动时指定:
**忽略网卡配置: **
# 在启动参数JAVA_OPTS变量中添加
-Dspring.cloud.inetutils.ignoredInterfaces[0]=docker0
-Dspring.cloud.inetutils.ignoredInterfaces[1]=veth.*
2
3
指定注册IP:
# 在启动参数JAVA_OPTS变量中添加
-Deureka.instance.ip-address=172.16.10.76
2
指定注册URL:
# 在启动参数JAVA_OPTS变量中添加
-Deureka.instance.homePageUrl=http://172.16.10.76:8080
-Deureka.instance.preferIpAddress=false
2
3
# 三、启动运行
启动如果有报错,一般是因为无法连接对应的 config 或者admin服务,可以先不用管,把下面的配置完善之后再进行排查
# apollo-configservice、apollo-adminservice
docker run -p 8080:8080 -d -v /store/logs:/opt/logs --name apollo-configservice registry.cn-hangzhou.aliyuncs.com/tfgol-dev/apollo-configservice
docker run -p 8090:8090 -d -v /store/logs:/opt/logs --name apollo-adminservice registry.cn-hangzhou.aliyuncs.com/tfgol-dev/apollo-adminservice
# apollo-portal
docker run -p 8070:8070 -d -v /store/logs:/opt/logs --name apollo-portal registry.cn-hangzhou.aliyuncs.com/tfgol-dev/apollo-portal
2
3
4
5
6
7
# 四、配置调整
以下调整均为对应数据库字段数据修改
# 4.1 ApolloPortalDB库
apolloportaldb.ServerConfig字段,配置项统一存储在ApolloPortalDB.ServerConfig表中,也可以通过管理员工具 - 系统参数页面进行配置,无特殊说明则修改完一分钟实时生效。
# 4.1.1 可支持的环境列表
字段: pollo.portal.envs - 默认是dev,如果需要多环境的话,直接配置以下参数:
PRO
2
# 4.1.2 Meta Service列表
apollo-configservice服务的IP+端口
字段: apollo.portal.meta.servers - 该配置优先级高于其它方式设置的Meta Service地址
{
"PRO":"http://172.16.10.76:8080"
}
2
3
4
# 4.1.3 部门列表
字段: apolloportaldb.organizations
# 默认配置
[{"orgId":"TEST1","orgName":"样例部门1"},{"orgId":"TEST2","orgName":"样例部门2"}]
# 自定义
[{"orgId":"SH","orgName":"wms技术部"},]
2
3
4
5
# 4.1.4 环境权限
只对项目成员显示配置信息的环境列表,这里如果没有特殊要求,建议所有环境均对外开放
字段: configView.memberOnly.envs
pro
注意: 对设定了只对项目成员显示配置信息的环境,只有该项目的管理员或拥有该namespace的编辑或发布权限的用户才能看到该私有namespace的配置信息和发布历史。公共namespace始终对所有用户可见。
2
3
4
官方参考文档:
https://www.apolloconfig.com/#/zh/deployment/distributed-deployment-guide?id=%e4%b8%89%e3%80%81%e6%9c%8d%e5%8a%a1%e7%ab%af%e9%85%8d%e7%bd%ae%e8%af%b4%e6%98%8e
# 4.2 ApolloConfigDB库
apolloconfigdb.ServerConfig 表
# 配置当前环境eureka服务地址
字段: eureka.service.url
http://172.16.10.76:18080/eureka/
2
3
参考文档:
https://ctripcorp.github.io/apollo/#/zh/deployment/distributed-deployment-guide?id=_321-eurekaserviceurl-eureka%e6%9c%8d%e5%8a%a1url
# 4.3 访问
上面配置完成之后,一般都是实时生效,也可以手动重启下三个服务,然后访问http://${IP}:8070/,默认用户名密码apollo/admin
# 五、新增环境
以上仅仅是配置了生产环境,如果有新增环境的话,需要进行以下步骤:
1、ApolloPortalDB调整
2、Apollo Config Service、Apollo Admin Service应用部署
3、创建ApolloConfigDB库并调整
2
3
4
# 5.1 添加预设DEV
环境
上面我们知道,默认有DEV
、UAT
、FAT
等默认环境,其实上面部署的PRO
也属于内置环境之一。我们知道对于apollo来说,portal作为管理端部署一个即可,而不同的环境 Config
和Admin
需要部署至对应环境中,因此,新增环境我们仅部署这2个应用即可。
# 5.1.1 portal服务端配置
apolloportaldb
.ServerConfig 修改新增dev环境列表,需要注意portal要能够访问新增dev
环境8080端口
# apollo.portal.envs
DEV,PRO
# apollo.portal.meta.servers
{
"DEV":"http://172.16.11.160:8080",
"PRO":"http://172.16.10.76:8080"
}
2
3
4
5
6
7
# 5.1.2 ApolloConfigDB库准备
数据库,只需要新建apolloconfigdb
,然后导入对应数据就行,然后调整环境参数:
# 调整 eureka.service.url字段(ApolloConfigDB.ServerConfig表),添加dev环境注册地址
http://172.16.11.160:8080/eureka/
2
# 5.1.3 镜像准备
镜像,我们在部署pro
环境时,都是自定义构建镜像,上面我们也知道,操作修改的时候相对来说还是比较繁琐,上面我们说过从Apollo 1.7.0版本开始会默认上传Docker镜像到Docker Hub (opens new window),我们直接拉取即可,需要注意,尽量跟自定义的保持版本一致
docker pull apolloconfig/apollo-configservice:1.9.1
docker pull apolloconfig/apollo-adminservice:1.9.1
2
# 5.1.4 应用启动
这里因为,镜像不是我们自定义构建,因此启动的时候需要指定数据库等参数配置,
&serverTimezone=UTC
新增该链接参数
- Apollo Config Service
docker run -p 8080:8080 -d -v /store/logs:/opt/logs \
-e SPRING_DATASOURCE_URL="jdbc:mysql://{devMYSQL}:3306/ApolloConfigDB?characterEncoding=utf8&serverTimezone=UTC" \
-e SPRING_DATASOURCE_USERNAME=root -e SPRING_DATASOURCE_PASSWORD=**** \
--name apollo-configservice apolloconfig/apollo-configservice:1.9.1
2
3
4
- Apollo Admin Service
docker run -p 8090:8090 -d -v /store/logs:/opt/logs \
-e SPRING_DATASOURCE_URL="jdbc:mysql://{devMYSQL}:3306/ApolloConfigDB?characterEncoding=utf8&serverTimezone=UTC" \
-e SPRING_DATASOURCE_USERNAME=root -e SPRING_DATASOURCE_PASSWORD=**** \
--name apollo-adminservice apolloconfig/apollo-adminservice:1.9.1
2
3
4
# 5.1.5 查看新环境注册
如果一直没有注册进来,各个应用也没有报错,那么重启下apollo-portal即可
说明
如果想要Home Page Url
注册地址为宿主机指定的IP地址,我们也可以在容器启动的时候,像在启动脚本中传递参数一样,apollo的各个应用也支持系统变量的方式传递,因此上面启动时候,我们也可以像MySQL那样,使用-e
把需要的配置传递给容器:
- 忽略网卡
SPRING_CLOUD_INETUTILS_IGNORED_INTERFACES[0]=docker0
SPRING_CLOUD_INETUTILS_IGNORED_INTERFACES[1]=veth.*
2
- 指定注册IP
EUREKA_INSTANCE_IP_ADDRESS=172.16.11.160
- 指定注册URL
EUREKA_INSTANCE_HOME_PAGE_URL=http://172.16.11.160:8080
EUREKA_INSTANCE_PREFER_IP_ADDRESS=false
2
# 5.2 新增自定义TEST
环境
新增自定义环境,是指前面我们所说,内置环境标签并没有我们所需要的,添加test环境,步骤与新增内置环境一样,唯一需要注意的就是,如果想要新增自定义环境,那么portal服务端源码处必须修改,新增相关的环境配置,这里我们新增TEST
环境,因为前面部署portal时,我们已经修改新增该环境相关源码。
# 5.2.1 portal调整
apolloportaldb
.ServerConfig 修改新增dev环境列表,需要注意portal要能够访问新增test
环境8080端口
# apollo.portal.envs
DEV,TEST,PRO
# apollo.portal.meta.servers
{
"DEV":"http://172.16.11.160:8080",
"TEST":"http://172.16.11.161:8080",
"PRO":"http://172.16.10.76:8080"
}
2
3
4
5
6
7
8
# 5.2.2 ApolloConfigDB库准备
数据库,只需要新建
apolloconfigdb
,然后导入对应数据就行,然后调整环境参数:
# 调整 eureka.service.url字段(ApolloConfigDB.ServerConfig表),添加dev环境注册地址
http://172.16.11.161:8080/eureka/
2
# 5.2.3 镜像准备
镜像这里我们同样直接使用官方的镜像,省去自己构建的步骤
docker pull apolloconfig/apollo-configservice:1.9.1
docker pull apolloconfig/apollo-adminservice:1.9.1
2
# 5.2.4 启动
- Apollo Config Service
docker run -p 8080:8080 -d -v /store/logs:/opt/logs \
-e SPRING_DATASOURCE_URL="jdbc:mysql://{testMYSQL}:3306/apolloconfigdb?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=root -e SPRING_DATASOURCE_PASSWORD=***** \
--name apollo-configservice apolloconfig/apollo-configservice:1.9.1
2
3
4
- Apollo Admin Service
docker run -p 8090:8090 -d -v /store/logs:/opt/logs \
-e SPRING_DATASOURCE_URL="jdbc:mysql://{testMYSQL}:3306/apolloconfigdb_test?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=root -e SPRING_DATASOURCE_PASSWORD=******* \
--name apollo-adminservice apolloconfig/apollo-adminservice:1.9.1
2
3
4
# 5.2.5 查看环境注册
# 六、环境高可用
生产环境中,程序客户端与apollo的交换,其实是跟config应用的交互,因此为了保证该服务的高可用,我们可以针对某一个环境部署多套应用,这样不仅达到高可用的状态,也可以起到一个分流的作用,比如,我们生产有多个vpc或者机房网络环境,vpc1的应用如果访问vpc2的apollo-configservice服务,就需要使用外网映射,如果我们在vpc2中也部署一套生产环境的apollo每个网络环境只连接该环境的服务,这样就实现了分流的操作,当然,该方案也可以在同一个网络环境中,不同业务连不同的apollo-configservice,这里需要保证,所有的生产服务,所连的apolloconfigdb
是一致的。
# 6.1 生产镜像准备
docker pull apolloconfig/apollo-configservice:1.9.1
docker pull apolloconfig/apollo-adminservice:1.9.1
2
# 6.2 ApolloConfigDB参数修改
这里只需要修改生产环境的参数即可,不用再配置多套数据库
http://172.16.10.76:8080/eureka/,http://172.29.126.159:8080/eureka/
# 6.3 应用启动
- Apollo Config Service
docker run -p 8080:8080 -d -v /store/logs:/opt/logs \
-e SPRING_DATASOURCE_URL="jdbc:mysql://{prodMYSQL}:3306/apolloconfigdb?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=root -e SPRING_DATASOURCE_PASSWORD=**** \
--name apollo-configservice apolloconfig/apollo-configservice:1.9.1
2
3
4
- Apollo Admin Service
docker run -p 8090:8090 -d -v /store/logs:/opt/logs \
-e SPRING_DATASOURCE_URL="jdbc:mysql://{prodMYSQL}:3306/apolloconfigdb?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=root -e SPRING_DATASOURCE_PASSWORD=**** \
--name apollo-adminservice apolloconfig/apollo-adminservice:1.9.1
2
3
4
# 6.4 查看环境注册
说明
①:这里地址虽然看到的还是之前的环境,是因为我们的portaldb中的配置是这一个地址,但是这并不影响客户端直接使用新的configservice地址: http://172.29.126.159:8080
进行连接访问
②③: 生产环境两套应用可以不用互相访问,也就是说,两套环境网络可以完全隔离,我们只需要保证所连的数据库是一个即可。
# 6.5 完整环境注册情况