在docker swarm集群部署apollo(可用于生产环境)

写在前面

  最近在工作中需要使用到apollo配置中心来简化微服务开发,在部署时使用docker的方式部署到线上到docker swarm集群。在网上翻了很多人的博文,有些由于时间久远很多东西都发生来变化,而有些对一些坑的细节没有做详细说明,最后还是我在官方文档中扒到了解决方法。
  因此在踩完了所有坑后,详细的记录一便流程,方便大家有相同的需求时可以按图索骥,也作为备忘录方便以后回顾。

一、准备工作

1.1 docker环境安装

  由于针对生产环境部署情景,需要在本地环境及服务器都准备好docker环境,如果只是本机玩玩的话,只需准备本地docker环境。至于docker的安装网上有很多方法,在Mac和windows中都有安装包进行一键安装即可,在此就不多加赘述了。

1.2 源码获取

  首先我们去github上apollo的官方仓库中获取部署需要的文件,注意除了使用git获取到源码,还需要在Releases页面中获取以下三个服务的最新稳定版本压缩包,用于后续的镜像构建。

  • apollo-configservice
  • apollo-adminservice
  • apollo-portal

1.3 Mysql数据库

  Apollo服务端共需要两个数据库:ApolloPortalDB和ApolloConfigDB,官网把数据库、表的创建和样例数据都分别准备了sql文件(在下载的源码包的script/sql目录下),只需要导入数据库即可。

  建议后续使用已有的mysql进行部署不要将mysql不要和apollo的三个服务放在一个docker compose进行编排。因为我们要部署的服务在启动时需要依赖数据库中的配置,如果在一起编排服务,第一次启动会直接挂掉,mysql启动后还需要初始化才能正常使用,大家如果没有现成的mysql要使用docker构建,也建议部署好mysql导入sql文件后再启动apollo的服务。

1.4 部署策略

分布式部署需要事先确定部署的环境以及部署方式。Apollo目前支持以下环境:

  • DEV 开发环境
  • FAT 测试环境,相当于alpha环境(功能测试)
  • UAT 集成环境,相当于beta环境(回归测试)
  • PRO 生产环境

以ctrip为例,其部署策略如下:


ctrip部署策略.png
  • Portal部署在生产环境的机房,通过它来直接管理FAT、UAT、PRO等环境的配置
  • Meta Server、Config Service和Admin Service在每个环境都单独部署,使用独立的数据库
  • Meta Server、Config Service和Admin Service在生产环境部署在两个机房,实现双活
  • Meta Server和Config Service部署在同一个JVM进程内,Admin Service部署在同一台服务器的另一个JVM进程内


    样例部署图.png

为了演示方便,本文将Apollo-portal,Apollo-adminservice和Apollo-configservice部署在一台机器上

服务器 服务 端口 环境
192.168.20.198 apollo-portal 8070 UAT
192.168.20.198 apollo-adminservice 8080 UAT
192.168.20.198 apollo-configservice 8090 UAT

二、构建镜像

  首先创建一个apollo目录用于后续统一管理我们的资源文件,并创建apollo-configservice、apollo-adminservice、apollo-portal三个子目录。
  打开之前下载源码,分别找出apollo-configservice/src/main/docker/Dockerfile、apollo-adminservice/src/main/docker/Dockerfile、apollo-portal/src/main/docker/Dockerfile三个文件并移动到之前创建的三个对应子目录下,将下载好的apollo-configservice-x.x.x-github.zip、apollo-adminservice-x.x.x-github.zip、apollo-portal-x.x.x-github.zip也一并移动到对应的子目录。

  此处有了源码后如果有需求的话其实是可以自己进行打包的,但由于在本文中没有特殊需求,并且我自己在尝试打包中出现了各种依赖问题所以就放弃,如果各位有兴趣可以自行尝试。

准备好的目录结构如下:


apollo.jpg

  部署时使用的是官方最新的1.7.1 release版本,中间出现了些状况为了看里面的源码所以我解压了压缩包,各位如果没有必要可以不解压。

以apollo-configservice为例,首先我们来看一下官方提供的Dockerfile:


Dockerfile.jpg

  可以看出在Dockerfile里就是一个标准的jar包部署内容,值得注意的是需要所需的jar包是从.zip压缩包解压出来的,这里直接使用之前下载的压缩包,但需要将Dockerfile中的${VERSION}改为实际下载的压缩包版本号

一切准本就绪后就可以进行镜像构建了:

cd apollo-configservice
docker build -t myhub/apollo-configservice .

cd apollo-adminservice
docker build -t myhub/apollo-adminservice .

cd apollo-portal
docker build -t myhub/apollo-portal .

将镜像推送至dockerHub:

#登录到dockerhub,首先得注册自己得账号
docker login -u yourname -p yourpassword docker.io
docker push myhub/apollo-configservice
docker push myhub/apollo-adminservice
docker push myhub/apollo-portal

  至此准备工作就差不多了,接下来可以直接去要部署服务的目标服务器进行部署操作了

三、服务部署

首先编辑我们的docker-stack.yml文件,用于描述我们用docker stack部署服务的细节:

version: "3.7"

services:
  apollo-configservice:
    image: myhub/apollo-configservice:latest
    ports:
      - target: 8080
        published: 8080
        mode: host
    environment:
      - spring_datasource_url=jdbc:mysql://{mysqlurl}/ApolloConfigDB?characterEncoding=utf8
      - spring_datasource_username={username}
      - spring_datasource_password={password}
      - eureka.instance.ip-address=192.168.20.198
    deploy:
      placement:
        constraints:
          - 'node.hostname == 192-168-20-198'
      replicas: 1
      update_config:
        parallelism: 1
        delay: 5s
        failure_action: rollback
        monitor: 60s
        order: start-first
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 60s
      rollback_config:
        parallelism: 1
        delay: 5s
        failure_action: continue
        monitor: 60s
        order: start-first
  apollo-adminservice:
    image: myhub/gapi/apollo-adminservice:latest
    ports:
      - target: 8090
        published: 8090
        mode: host
    environment:
      - spring_datasource_url=jdbc:mysql://{mysqlurl}/ApolloConfigDB?characterEncoding=utf8
      - spring_datasource_username={username}
      - spring_datasource_password={password}
    deploy:
      placement:
        constraints:
          - 'node.hostname == 192-168-20-198'
      replicas: 1
      update_config:
        parallelism: 1
        delay: 5s
        failure_action: rollback
        monitor: 60s
        order: start-first
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 60s
      rollback_config:
        parallelism: 1
        delay: 5s
        failure_action: continue
        monitor: 60s
        order: start-first
  apollo-portal:
    image: myhub/gapi/apollo-portal:latest
    ports:
      - target: 8070
        published: 8070
        mode: host
    environment:
      - DEV_META=http://192.168.20.198:8080
      - spring_datasource_url=jdbc:mysql://{mysqlurl}/ApolloConfigDB?characterEncoding=utf8
      - spring_datasource_username={username}
      - spring_datasource_password={password}
    deploy:
      placement:
        constraints:
          - 'node.hostname == 192-168-20-198'
      replicas: 1
      update_config:
        parallelism: 1
        delay: 5s
        failure_action: rollback
        monitor: 60s
        order: start-first
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 60s
      rollback_config:
        parallelism: 1
        delay: 5s
        failure_action: continue
        monitor: 60s
        order: start-first

  需要注意的是,由于我们需要将三个服务都部署到192.168.20.198机器上,所以在deploy.placement.constraints中添加node.hostname == 192-168-20-198将服务都指定部署到192.168.20.198上。
  之后由于客户端服务需要通过注册中心调用apollo-configservice服务拉去配置,所以在apollo-configservice中需要
添加环境变量- eureka.instance.ip-address=192.168.20.198将自己实际IP注册到eureka中,否则注册信息是docker内部网桥的虚拟地址,会导致我们拉去配置失败。
  另外在apollo-portal需要添加环境变量- DEV_META=http://192.168.20.198:8080指定dev环境的configservice地址,官方提供的sql环境只开启了dev环境,开启其他环境在自后续进行说明

  准备完成后就可以进行使用docker stack deploy命令部署服务了,但在此之前还需要到去ApolloConfigDB.ServerConfig表中将Key为eureka.service.url的Value由http://localhost:8080/eureka/改为http://192.168.20.198:8080/eureka/,因为apollo-configservice和apollo-adminservice服务都是通过此配置的地址注册到eureka中,configservice和注册中心在同一进程中没什么问题,但adminservice在其他容器中通过localhost:8080并不能找到configservice中但注册中心。

修改完成后运行命令以一键部署服务:

docker stack deploy -c docker-stack.yml apollo

完成后可以使用docker stack ps命令查看详情:

docker stack ps apollo

四、注意事项及后续升级

  进行到这里我们的服务部署就基本完成了,为了便于演示暂时只是支持了官方开箱自带的dev环境,接下来演示如何增加新的环境。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容