apolloconfig / apollo

Apollo is a reliable configuration management system suitable for microservice configuration management scenarios.
https://www.apolloconfig.com
Apache License 2.0
29.07k stars 10.2k forks source link

如何简化Apollo的分布式部署流程? #1424

Open nobodyiam opened 6 years ago

nobodyiam commented 6 years ago

目前Apollo的一个痛点就是分布式部署有点太复杂了,虽然文档写得很细,不过乍看一下,细节非常多,如果用户没有耐心读完文档就开始部署的话,一般都会遇到这样那样的问题,影响体验。

所以还想请大家一起看看是否有啥办法能够简化Apollo的分布式部署流程,欢迎大家献计献策!

oooooooz commented 6 years ago

在目前的架构下,我们先来看单机布署一个环境要做哪些事情:

1,构建后发布。构建时选自己的 profile 加上 github 即可,原封不动官方配置。我们是自己拉代码下来自己构建的,所以有构建这一步。

2,修改配置。

为了方便修改,数据库配置我们写到 config/application-github.properteis,portal 的注册中心配到 config/apollo-env.properteis

3,客户端 配置好 -Denv,注册中心地址配置到 apollo-env.properties

一个环境差不多要做就是这些。大家一般都是下载 release 版不用自己构建。配置部分的细节确实有点繁琐。对于 config 和 admin 服务,我的理解是配置文件类其实仅修改日志路径,和数据库配置即可,其他可以不改。portal 服务配一个好记的 http 访问端口。


好,以上说完单机单环境,现在看分布式或集群下的部署有没有优化空间。

分布式部署的话,portal 的话一般一个即可,但我觉得大部分公司还是要求生产和开发、测试分离的 ,image

所以上面的步骤好像免不了都要走一遍:

1,构建看不同公司的需求,一般可以省略,直接发布应用即可。我们是因为增加了导出,所以合并做了构建,不知是否可以提个 PR ? image

2,configdb,不同环境肯定是要新建立的。portaldb 要增加 env meta(这里假设 portal 不用重新部署) 3,admin 和 config 的应用要重新部署,然后和上面一样去修改应用配置,修改数据库配置 4,客户端。增加对应环境的注册中心地址。

总体下来感觉要优化的话可以从怎么优化 修改配置和数据库的细节入手。我觉得可以优化几点,总体的思路是配置集中化管理,可以配到数据库就配到数据库(这样方便扩展去界面管理):

1,portal 应用,把 portal 连注册中心的地址配到 portaldb。这个时候对于 env 可以根据注册中心来增加,比如 dev.meta 就增加 dev,fat.meta 就增加 fat 2,数据库脚本还是要人工去执行,执行后修改配置 3,部分配置由 portal 去管理,比如 portaldb 增加一个表,专门用来维护 config 和 admin 的配置,portal 起来后,将配置推送到 config 和 admin 的配置路径。 4、portal 的相关配置还要老样去改

这样的化 config 和 admin 的配置就简化了。

以上抛砖引玉,欢迎讨论。顺便感谢宋大侠对社区的时刻关心,及时雨啊。感谢 @nobodyiam

jiangshubian commented 6 years ago

单机版: ./demo.sh start,portal一直无法执行到,是不是有bug? 把脚步portal启动部分独立开来就可以启动。 Quick Start:https://github.com/ctripcorp/apollo/wiki/Quick-Start中的安装包

nobodyiam commented 6 years ago

@jiangshubian 开个新的issue描述你的问题吧,估计是下载的时候少了conf文件?比如apollo-service.conf

dypublic commented 6 years ago

@nobodyiam 宋大神,想请教一下,Eureka和Meta server引入的目的是做config/admin server的服务发现吗?既然SLB(nginx)可以找到Meta server, 为什么不直接用域名绑SLB,SLB去LB config server,client 直接访问SLB->config server?这样就可以取消Eureka和Meta server的必要性了。

nobodyiam commented 6 years ago

client需要长连config service的(http long polling),如果走slb的话,对slb的压力太大。

dypublic commented 6 years ago

@nobodyiam 谢谢。那如果域名绑定多个SLB,即SLB集群,是不是就可以了呢?我们自己使用AWS环境,有NLB组件,单个NLB的性能就相当不错,可以认为是网络设备而不是SLB(nginx)。

nobodyiam commented 6 years ago

如果性能OK的话,倒也无所谓的,不过走LB也是有点浪费,因为内网其实完全可以直连的。

另外,直连规模也要考虑一下的,比如如果内网有6位数的机器,就会有6位数的长连,势必会增加不少LB的成本吧。。

另外一点就是走LB的话,需要在LB上调整超时时间的,目前apollo的http long polling最长会保持60秒。

dypublic commented 6 years ago

@nobodyiam 明白这个考量点了,谢谢 。对于6位数的时候,config server的节点经验上需要部署多少个呢?假设4核16G的机器。

nobodyiam commented 6 years ago

一台4核8G的config service服务10000以内的节点数是没问题的,留一些余量的话,建议一台服务6000 - 7000个节点吧

nolan4954 commented 6 years ago

个人感觉,可以将config service和admin service集成在一起;即作为各个env下的client服务,又为总的管理后台portal服务

hupuxiaojun commented 5 years ago

我看到文档中写到如果需要使用单独的eureka注册中心的话,除了修改数据库中的url外,还需要修改源码将@EnableEurekaServer改成@EnableEurekaClient,然后重新打包编译源码。 感觉可以用@Profile的方式来控制是否要自启动eureka server,然后在启动时传入spring profile来控制,这样应该可以不用修改源代码,使用起来更友好一些,类似如下代码:

//@EnableEurekaServer
//@EnableEurekaClient
@EnableAspectJAutoProxy
@EnableAutoConfiguration // (exclude = EurekaClientConfigBean.class)
@Configuration
@EnableTransactionManagement
@PropertySource(value = {"classpath:configservice.properties"})
@ComponentScan(basePackageClasses = {ApolloCommonConfig.class,
    ApolloBizConfig.class,
    ConfigServiceApplication.class,
    ApolloMetaServiceConfig.class})
public class ConfigServiceApplication {

  public static void main(String[] args) throws Exception {
    SpringApplication.run(ConfigServiceApplication.class, args);
  }

  @Profile("EurekaServer")
  @Configuration
  @EnableEurekaServer
  public class EurekaServerConfig {

  }

  @Profile("EurekaClient")
  @Configuration
  @EnableEurekaClient
  public class EurekaClientConfig {

  }
}

打包的时候-Dapollo_profile=github,EurekaClient来激活配置

lawrencewu commented 5 years ago

部署文档可以以三台机器模拟的三个不同的环境为例,一步步写下如何部署的以便参考.与部署不相关的"注1" "注2" 等信息可以另写一篇参考文档, 分布式部署文档内容分支太多, 也繁琐, 不干净不流畅.

nobodyiam commented 5 years ago

@lawrencewu 很好的建议,后续分布式部署文档增加一个实际部署案例

jimmy401 commented 5 years ago

linux suse 版本下会报错start-stop-daemon unrecognized option '--chuid' 建议支持多个linux发行版, 或者明确指出只支持centos系统。

nobodyiam commented 5 years ago

@jimmy401 这个貌似是spring boot脚本的问题,详见 #https://github.com/spring-projects/spring-boot/issues/4772Customizing the Start Script when It Is Written,可以试一下,如果OK的话,后续我们在文档中更新一下~

YoungHu commented 5 years ago

视频为主,文档为辅,事半功倍。

LittleYellowMonster commented 5 years ago

当前项目是使用springCloud+docker+k8s技术,生产环境和预生产环境是的各自独立k8s集群,开发测试是在单个服务器通过docker部署springCloud,当前项目架构下,打算接入apollo,遇到一些问题想请教一下 1.是否有apollo官方镜像,方便直接跑容器。 2.如果使用apollo的eureka作为注册中心怎么解决高可用,项目之前是部署三个eureka服务互相注册。

nobodyiam commented 5 years ago

@LittleYellowMonster

  1. docker/k8s部署可以参考分布式部署的文档,目前没有上传官方镜像,不过项目的zip包,dockerfile等都是有的

  2. 高可用是一样的,部署多个,然后互相注册,地址配置在ApolloConfigDB.ServerConfig中,详见eureka.service.url - Eureka服务Url文档

yinl825 commented 5 years ago

关于服务端口和日志路径的修改,在dubbo项目中有这样一段脚本内容: image 通过读取和脚本所在目录的同级目录conf下的属性文件,解析出属性值,我觉得可以用这种方式将服务端口和日志路径的修改迁移出来,这样日志路径的修改只需要改动一个地方就可以了,而且避免运维操作复杂的sh脚本,而是编辑简单易读的属性文件

thinkerFenglm commented 5 years ago

1、通过修改启动脚本 startup.sh 增加 JAVA_OPTIONS 部署

Portal 启动脚本

#!/bin/bash
SERVICE_NAME=apollo-portal
## Adjust log dir if necessary
LOG_DIR=/home/souche/projects/apollo-portal/logs
## Adjust server port if necessary
SERVER_PORT=8070

################add
export JAVA_HOME=/opt/souche/java

apollo_portal_db_url=
apollo_portal_db_username=
apollo_portal_db_password=

# meta server url
dev_config_server_url=http://config.dev-apollo.net
pro_config_server_url=http://config.pro-apollo.net

BASE_JAVA_OPTS="-Ddev_meta=$dev_config_server_url -Dpro_meta=$pro_config_server_url"
PORTAL_JAVA_OPTS="$BASE_JAVA_OPTS -Dspring.profiles.active=github"
JAVA_OPTS="$PORTAL_JAVA_OPTS -Dspring.datasource.url=$apollo_portal_db_url -Dspring.datasource.username=$apollo_portal_db_username -Dspring.datasource.password=$apollo_portal_db_password"

ConfigService 启动脚本

/startup.sh 
#!/bin/bash
SERVICE_NAME=apollo-configservice
## Adjust log dir if necessary
LOG_DIR=/home/souche/projects/apollo-configservice-pro/logs
## Adjust server port if necessary
SERVER_PORT=8080

###############add
export JAVA_HOME=/opt/souche/java

apollo_config_db_url=
apollo_config_db_username=
apollo_config_db_password=

# meta server url
config_server_url=http://172.16.33.*:8080
admin_server_url=http://172.16.33.*:8090
eureka_service_url=$config_server_url/eureka/

#JAVA OPTS
BASE_JAVA_OPTS="-Denv=pro -Dpro_meta=$config_server_url"
ADMIN_JAVA_OPTS="$BASE_JAVA_OPTS -Dspring.profiles.active=github -Deureka.service.url=$eureka_service_url -Deureka.instance.homePageUrl=$config_server_url"
JAVA_OPTS="$ADMIN_JAVA_OPTS -Dspring.datasource.url=$apollo_config_db_url -Dspring.datasource.username=$apollo_config_db_username -Dspring.datasource.password=$apollo_config_db_password"

AdminService 启动脚本

startup.sh 
#!/bin/bash
SERVICE_NAME=apollo-adminservice
## Adjust log dir if necessary
LOG_DIR=/home/souche/projects/apollo-adminservice-pro/logs/
## Adjust server port if necessary
SERVER_PORT=8090

###############new add
export JAVA_HOME=/opt/souche/java

apollo_config_db_url=
apollo_config_db_username=
apollo_config_db_password=

# meta server url
config_server_url=http://172.16.33.*:8080
admin_server_url=http://172.16.33.*:8090
eureka_service_url=$config_server_url/eureka/

#JAVA OPTS
BASE_JAVA_OPTS="-Denv=pro -Dpro_meta=$config_server_url"
ADMIN_JAVA_OPTS="$BASE_JAVA_OPTS -Dspring.profiles.active=github -Deureka.service.url=$eureka_service_url -Deureka.instance.homePageUrl=$admin_server_url"
JAVA_OPTS="$ADMIN_JAVA_OPTS -Dspring.datasource.url=$apollo_config_db_url -Dspring.datasource.username=$apollo_config_db_username -Dspring.datasource.password=$apollo_config_db_password"

⚠️注意:portal 一般部署两个实例,主备就行,configservice、adminservice 根据自己需要的环境部署,脚本改动参数都是以上的换成对应环境的即可

nobodyiam commented 5 years ago

@thinkerFenglm 现在分布式部署方案是通过修改config目录下的application-github.properties和apollo-env.properties来实现的,你的建议是都放在JAVA_OPTS里面?

thinkerFenglm commented 5 years ago

@nobodyiam 是的,读取配置的是有优先级的,通过在启动脚本里设置 JAVA_OPTS 可以最简单的解决需要打不同包的,而且易于一些配置的修改,只用修改完重启就行不用打包重新部署。

YoungHu commented 5 years ago

@nobodyiam 是的,读取配置的是有优先级的,通过在启动脚本里设置 JAVA_OPTS 可以最简单的解决需要打不同包的,而且易于一些配置的修改,只用修改完重启就行不用打包重新部署。

现在都不用打包的,下载官网上打好的包,修改配置的文件中内容就可以了。你说的这个只是在哪里配置的问题,从配置文件转移到脚本文件了而已。

boluoboluomi commented 5 years ago

我看数据库和负载均衡都是单点,就想问问如果数据库挂了,负载均衡挂了,貌似没办法高可用了吧。 携程流量这么大,我想应该碰到过负载均衡挂的情况吧。

nobodyiam commented 5 years ago

数据库挂了,需要切库,负载均衡挂了,也是需要切的,都有成熟方案的。

tianmingxing commented 5 years ago

如果性能OK的话,倒也无所谓的,不过走LB也是有点浪费,因为内网其实完全可以直连的。

另外,直连规模也要考虑一下的,比如如果内网有6位数的机器,就会有6位数的长连,势必会增加不少LB的成本吧。。

另外一点就是走LB的话,需要在LB上调整超时时间的,目前apollo的http long polling最长会保持60秒。

疑问:为什么会采用http长轮询?tcp通讯是否可以?

nobodyiam commented 5 years ago

@xiaoxing598

用http长轮询的原因是简单、可靠、够用,用tcp当然也是可以的,只是在配置下发的场景没有很大的必要性,而且对多语言接入会增加门槛。

tianmingxing commented 5 years ago

@xiaoxing598

用http长轮询的原因是简单、可靠、够用,用tcp当然也是可以的,只是在配置下发的场景没有很大的必要性,而且对多语言接入会增加门槛。

ok,了解。

happymatt commented 5 years ago

之前用过spring cloud config,它的所有环境的配置都是在一起管理的,也不需要针对不同环境不同部署,所有环境都从同一个集中的服务拉取配置,当然它的功能其实是很简单,没有apollo这样丰富的功能,但是如果appolo部署方式也能做到很简单那就更好了。

iluoxuan commented 5 years ago

搞成springboot jar 我们可以引用jar 最好,类似springboot config 升级也方便!现在部署麻烦,升级更加!

lepdou commented 5 years ago

还有一个地方可以入手,就像前面 @happymatt 提到的 spring cloud config 模式,支持“多租户”模式。 简单的讲,部署的时候,可以让用户选择是“单租户”还是“多租户”模式,如果是“多租户”模式,用户只需要部署一套环境,Portal 层面可以任意创建环境,环境变成逻辑隔离而不是现在强物理隔离。也就是把现在的 cluster 封装成 env。

xuqiming commented 5 years ago

我给的建议是: 配置尽可能的简单,portaldb,在首次访问portal时填入数据连接字符串、用户、密码然后自动导入初始数据库,这样Portal的部署就会变得非常简单了,就只是一个下载启动就搞定了。同理,config-service和admin-service也是,也把部署简化成一个下载启动的过程,通过portl去管理每个环境的config-service和admin-service的数据连接字符串、用户、密码,这样也可以省去apollo-env.properties的mateserver配置, 这样应该把部署难度降低挺多的了,甚至可以给portl和(admin/config)写一个部署脚本,更过分的就portal和(admin/config)进行免密登录,只需要部署portal,用portal去部署所有的环境里的所有的admin/config。

上面纯属我自己的意淫,如果觉得不对,尽管拍砖把我拍醒。

kaelzhang commented 5 years ago

宋老板早点出一个官方的 helm-chart 吧

jssngz commented 4 years ago

上面纯属我自己的意淫,如果觉得不对,尽管拍砖把我拍醒。

这个有点像wordpress初始化

bruse-peng commented 4 years ago

1.6.1版本启用了秘钥后直接curl访问的时候报401,启用秘钥的要怎么使用了?我是运维(看源码有点困难)需要curl访问获取配置,怎么秘钥curl访问

nobodyiam commented 4 years ago

3055 尝试使用原生的k8s服务发现来简化部署和运维的复杂度,同时支持了 helm chart 部署,大家可以体验一下

zoulux commented 4 years ago

3055 尝试使用原生的k8s服务发现来简化部署和运维的复杂度,同时支持了 helm chart 部署,大家可以体验一下

我通过文档部署了,反馈几点意见

总体还算流畅 👍👍

nobodyiam commented 4 years ago

@zoulux

  1. portal 可以配置下session affinity,参见以Ingress配置session affinity形式暴露服务

  2. 很多配置都支持放到数据库的,不过也支持在 values.yaml 中配置

  3. $HOST/config-svc 的 ingress 是指 configservice 的 ingress 吗?

zoulux commented 4 years ago

@zoulux

  1. portal 可以配置下session affinity,参见以Ingress配置session affinity形式暴露服务
  2. 很多配置都支持放到数据库的,不过也支持在 values.yaml 中配置
  3. $HOST/config-svc 的 ingress 是指 configservice 的 ingress 吗?

多谢,

  1. session affinity 这样应该可以
  2. 我觉得统一一个地方比较好管理,否则要照顾数据库和配置文件两个地方
  3. 对的之前我想的是缺少一个 configservice 的 ingress,但是后来想到这个生产环境应该是用内网环境更安全,用 portal 管理就可以了,是我对 Apollo 理解不到位
pllsxyc commented 3 years ago

这两天尝试写一个ansible playbook来部署

hulucc commented 3 years ago

3055 尝试使用原生的k8s服务发现来简化部署和运维的复杂度,同时支持了 helm chart 部署,大家可以体验一下

https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments configmap 变化 deployment 不会 rollout

nobodyiam commented 3 years ago

@hulucc good idea,是否能提交个 PR?

sorakylin commented 3 years ago

这个分布式部署指南感觉写的太杂乱了。 一个部署流程, 导入SQL就提出几种分支。 2.1.3 调整服务端配置 更是直接列出了一大堆参数, 直接阻碍了为了部署的读者的思维。
整个文档基本都是这种形式,就不继续举例了, 看的真是挺难受的。

实际上能够直接用命令 + 步骤说明的方式 让刚接触的人部署完毕、成功跑起来就够了。 至于参数解释、以及更进阶的说明完全可以放入其他的文档。 可以学习一个 Nacos 的运维指南

doudouliyougangbeng commented 3 years ago

数据库挂了,需要切库,负载均衡挂了,也是需要切的,都有成熟方案的。

宋老师,我想知道你说的切库是设么概念,数据库挂了,切库只能修改配置重启服务,这算是高可用吗?(可能我理解的比较浅薄,多谢指正)

nobodyiam commented 3 years ago

数据库挂了,需要切库,负载均衡挂了,也是需要切的,都有成熟方案的。

宋老师,我想知道你说的切库是设么概念,数据库挂了,切库只能修改配置重启服务,这算是高可用吗?(可能我理解的比较浅薄,多谢指正)

@doudouliyougangbeng

  1. 简单的切库是指连接的数据库 IP 是一个 vip,当数据库出问题后可以切换 vip 到新的数据库上
  2. 复杂的切库是切换应用中的 datasource,可以参考 dynamic-datasource
souselesslove commented 2 years ago

请问参照Docker部署,如何替换默认的“eureka”为“Consul”?

nobodyiam commented 2 years ago

@souselesslove

Docker 部署简而言之就是把配置参数通过 -e 传入即可。 根据consul 配置说明,应该是额外增加以下 -e 参数:

-e SPRING_PROFILES_ACTIVE=github,consul-discovery -e SPRING_CLOUD_CONSUL_HOST=127.0.0.1 -e SPRING_CLOUD_CONSUL_PORT=8500

Alceatraz commented 2 years ago

看到了文档里的“注5”,谢邀:)

非技术向: 我个人觉的是因为文档过长,Markdown形式的文档在这么深的层级下,很容易看串行。

技术向: 实际使用中我相信应该是一个Portal连接多个admin/config服务器作为对多个环境的统一管理,也许可以参考kubeadm那样的工具,在指定服务器直接部署portal+mysql或者admin/config+mysql。比如


// 10.0.3.10是config的SLB
apollo-adm create config-service --bind 10.0.3.11:8080 --jdbc apollo:apollo@config-service.local:3306
apollo-adm create config-service --bind 10.0.3.12:8080 --jdbc apollo:apollo@config-service.local:3306

// 10.0.2.10是admin的SLB
// 创建admin-service,并指向config-service的SLB
apollo-adm create admin-service --bind 10.0.2.11:8090 --config-service 10.0.3.10:8080 --jdbc apollo:apollo@admin-service.local:3306
apollo-adm create admin-service --bind 10.0.2.12:8090 --config-service 10.0.3.10:8080 --jdbc apollo:apollo@admin-service.local:3306

// 10.0.1.10是portal的SLB
// 创建potal,并指向admin-service的SLB
apollo-adm create portal-service --bind 10.0.1.11:8080 --admin-service 10.0.2.10:8090 --jdbc apollo:apollo@portal-service.local:3306
apollo-adm create portal-service --bind 10.0.1.12:8080 --admin-service 10.0.2.10:8090 --jdbc apollo:apollo@portal-service.local:3306
nobodyiam commented 2 years ago

@Alceatraz 感谢建议,通过声明式的方式来部署确实能极大地简化部署的难度。目前 Apollo 是提供了 Helm Chart 部署方式,可以看下是否达到了类似的效果~

liangkiller commented 1 year ago

文档显得乱,是因为 重复的太多了,细节也很多,像是想在一篇文档里写完所有的步骤。 细节的配置项,在第一次部署时是不会考虑,只想按最简的默认值启动服务。 所以 可以把java_opts 这类的配置项 放在“高级配置” 的文档里。 可以写一个脚本,只要修改 数据库的 信息, 就可以自动用默认值 安装启动3个服务。 其他细节,等启动成功后,才有兴趣去了解。 也可以使用 ansible 部署,不过也有门槛。