基于Docker 5分钟搭建携程Apollo分布式配置中心

  |   0 评论   |   浏览

前言

由于一开始对Apollo的架构方式了解的不够深入,同时为了能够使得安装过程更加的简单,做到一条指令实现Apollo环境的搭建,经历了比较多的测试;本文基于apollo 1.6.0的版本进行编译打包的,后面会将整个镜像的创建过程逐一的列举出来,避免想了解的朋友再次花时间去研究;

什么是Apollo

携程官方Apollo仓库对该分布式配置中心做了详细的说明,这里就不再对起解析过多的解释,官方文档永远是最新、最全、最权威的介绍,下面只引用官方的一张图来简单说明一下;

总体设计

file

上图简要描述了Apollo的总体设计,我们可以从下往上看:

  • Config Service
    提供配置的读取、推送等功能,服务对象是Apollo客户端
  • Admin Service
    提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面)
  • Config ServiceAdmin Service都是多实例无状态部署,所以需要将自己注册到Eureka中并保持心跳
  • 在Eureka之上我们架了一层Meta Server用于封装Eureka的服务发现接口
  • Client通过域名访问Meta Server获取Config Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Client侧会做load balance、错误重试
  • Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做load balance、错误重试
  • 为了简化部署,我们实际上会把Config Service、Eureka和Meta Server三个逻辑角色部署在同一个JVM进程中

修改流程图

file

更多详细的介绍,请通读官方,读官方,官方,方的文档,读完之后,详细你会对Apollo有一个全面及系统的认识;这里主要是想如何以最快的方式将环境搭建起来。

Docker 安装apollo

Docker安装及基础操作

参考此:CentOS 7下安装Docker及基础操作 博客,docker的安装不是这里的重点,所以也就不做过多的说明及解释;上面的博客有详细的介绍。

镜像介绍

下面都是我准备好的镜像,真接使用就好了;

  • apollo-portal

    docker pull pengfeilu/apollo-portal:1.6.0
    
  • apollo-configservice

    docker pull pengfeilu/apollo-configservice:1.6.0
    
  • apollo-adminservice

    docker pull pengfeilu/apollo-adminservice:1.6.0
    
  • apollo-mysql

    // 该镜像基于mysql 5.7.22版本运行时自动执行了apollo 1.6.0版本中相关的sql
    // 通俗一点说就是镜像启动之后数据库里面就包含apollo默认的相关数据库
    docker pull pengfeilu/apollo-mysql:5.7.22_1.6.0
    

安装Apollo

  • 创建一个apollo环境管理的配置文件

    // 这个文件是用于配置apollo-portal管理的各个环境的Eureka地址
    vim apollo-env.properties
    // 创建好之后添加以下配置
    
    #本地默认环境配置,没啥用
    local.meta=http://localhost:8080
    #下面的环境,你有几个就添加几个,没有的或者不需要的可以直接删掉
    #将以下各环境的ip更换为自己对应的服务器ip
    dev.meta=http://fill-in-dev-meta-server:8080
    fat.meta=http://fill-in-fat-meta-server:8080
    uat.meta=http://fill-in-uat-meta-server:8080
    lpt.meta=http://fill-in-lpt-meta-server:8080
    pro.meta=http://fill-in-pro-meta-server:8080
    
  • 创建docker-conpose.yml文件

    // 任意目录下创建docker-compose.yml
    vim docker-compose.yml
    // 并在文件中添加一下内容
    
    version: "3"
    
    services:
      apollo-mysql:
        container_name: apollo-mysql
        image: pengfeilu/apollo/apollo-mysql:5.7.22_1.6.0
        ports:
          - "13306:3306"
        volumes:
          - "$PWD/mysql/data:/var/lib/mysql"
          - "$PWD/mysql/logs:/logs"
          - "/etc/localtime:/etc/localtime:ro"
        environment:
          - MYSQL_ROOT_PASSWORD=你的数据库密码
          - UPDATE_EUREKA_URL_SQL=update ApolloConfigDB.ServerConfig set `Value`="http://部署环境的主机IP:8080/eureka/" where `Key`="eureka.service.url"
          - TZ=Asia/Shanghai
      apollo-configservice:
        container_name: apollo-configservice
        image: pengfeilu/apollo-configservice:1.6.0
        ports:
          - "8080:8080"
        depends_on:
          - apollo-mysql
        volumes:
          - "$PWD/logs/100003171:/opt/logs/100003171"
        environment:
          - spring_datasource_url=jdbc:mysql://数据库的主机IP:13306/ApolloConfigDB?characterEncoding=utf8
          - spring_datasource_username=数据库名称
          - spring_datasource_password=数据库密码
          - host_ip=这个是我自己加的Eureka上服务的IP地址(部署服务的宿主机IP)
      apollo-adminservice:
        container_name: apollo-adminservice
        image: pengfeilu/apollo-adminservice:1.6.0
        ports:
          - "8090:8090"
        depends_on:
          - apollo-mysql
          - apollo-configservice
        links:
          - apollo-configservice
        volumes:
          - "$PWD/logs/100003172:/opt/logs/100003172"
        environment:
          - spring_datasource_url=jdbc:mysql://数据库的主机IP:13306/ApolloConfigDB?characterEncoding=utf8
          - spring_datasource_username=数据库的用户名
          - spring_datasource_password=数据库密码
          - host_ip=这个是我自己加的Eureka上服务的IP地址(部署服务的宿主机IP)
      apolo-portal:
        container_name: apollo-portal
        image: pengfeilu/apollo-portal:1.6.0
        ports:
          - "8070:8070"
        volumes:
          - "$PWD/logs/100003173:/opt/logs/100003173"
          - "$PWD/apollo-env.properties:/apollo-portal/config/apollo-env.properties"
        environment:
          - spring_datasource_url=jdbc:mysql://数据库的主机IP:13306/ApolloPortalDB?characterEncoding=utf8
          - spring_datasource_username=数据库的用户名
          - spring_datasource_password=数据库密码
        depends_on:
          - apollo-mysql
    

    好!到此,所有的配置项都已经完成了;务必要注意上面涉及到的 IP端口用户密码等信息;下面对上面核心的部分进行一些简单的说明

    • UPDATE_EUREKA_URL_SQL

      这个变量在基础的Mysql镜像中是不存在的,是我自定义的镜像加的,用来修改adminservice和configservice连接的Eureka地址的sql,它会在数据库创建成功之后执行;如果你使用的基础的Mysql镜像,可以优先启动Mysql的服务,启动之后手动运行官方提供的apolloportaldb.sql和apolloconfigdb.sql脚本,成功后去修改 ApolloConfigDB.ServerConfig表中的eureka.service.url列,值为当前环境要注册的Eureka的服务地址;

    • host_ip

      这也是自定义的一个变量,用于admin和config服务注册到Eureka的时候,指明自己服务所处的IP地址,由于使用Docker安装,如果不指定服务注册到eureka上的地址就是容器内部的IP,从而导致客户端访问配置的时候失败;官方在分布式部署中的1.4中有介绍网络策略,这里使用的是其中的第二种。

    • apolo-portal

      该服务是管理服务,所以他只需要部署一份,对应的数据库为 ApolloPortalDB;一般其部署在正式环境,确保其可用性;

    • apolo-portal环境配置文件挂载

      "$PWD/apollo-env.properties:/apollo-portal/config/apollo-env.properties"
      

      该配置文件是用于配置各个环境的metaSeever服务的地址,文件放置在宿主机上并挂载的容器对应的路径,目的是为了,环境的增加及移除只需要修改对应的文件,并将apollo-portal容器重启一下即可,方便!

    • configservice和adminservice

      各个环境服务,每个环境需要单独部署;同时每个环境各自关联着各自的 ApolloConfigDB数据库,互不干扰,互不影响;

  • 启动服务

    // 首次启动会下载镜像,会比较的慢
    // 如果存在镜像启动失败,请往下看。
    docker-compose up -d
    

    file

  • 重启容器 (着重关注)

    docker-compose restart
    

    在docker-compose.yml中虽然指定了容器之间的关联关系,Mysql的优先级最高,最先启动,但是Mysql在首次启动的时候会比较慢一点,从而会导致admin、config或者portal在启动的时候,mysql服务还没有准备好,导致服务启动失败;这个时候我们只需要等mysql初始化好之后再把所有的服务重新启动一遍就好了。

    file


测试


添加环境

上面默认我们创建了一个Dev的环境,但是实际的使用过程中并不是只有一个环境,可能还有 测试环境预发布环境正式环境;那我们如何来添加一个环境呢?有了上面的基础镜像,这个事情就变的非常的简单了;一句话,将上面的docker-compose.yml配置文件的apollo-portal相关的服务去掉并启动即可

  • 第一步:准备docker-compose.yml

    // 任意目录下创建docker-compose.yml
    vim docker-compose.yml
    // 并在文件中添加一下内容
    
    version: "3"
    
    services:
      apollo-mysql:
        container_name: apollo-mysql
        image: pengfeilu/apollo/apollo-mysql:5.7.22_1.6.0
        ports:
          - "13306:3306"
        volumes:
          - "$PWD/mysql/data:/var/lib/mysql"
          - "$PWD/mysql/logs:/logs"
          - "/etc/localtime:/etc/localtime:ro"
        environment:
          - MYSQL_ROOT_PASSWORD=你的数据库密码
          - UPDATE_EUREKA_URL_SQL=update ApolloConfigDB.ServerConfig set `Value`="http://部署环境的主机IP:8080/eureka/" where `Key`="eureka.service.url"
          - TZ=Asia/Shanghai
      apollo-configservice:
        container_name: apollo-configservice
        image: pengfeilu/apollo-configservice:1.6.0
        ports:
          - "8080:8080"
        depends_on:
          - apollo-mysql
        volumes:
          - "$PWD/logs/100003171:/opt/logs/100003171"
        environment:
          - spring_datasource_url=jdbc:mysql://数据库的主机IP:13306/ApolloConfigDB?characterEncoding=utf8
          - spring_datasource_username=数据库名称
          - spring_datasource_password=数据库密码
          - host_ip=这个是我自己加的Eureka上服务的IP地址(部署服务的宿主机IP)
      apollo-adminservice:
        container_name: apollo-adminservice
        image: pengfeilu/apollo-adminservice:1.6.0
        ports:
          - "8090:8090"
        depends_on:
          - apollo-mysql
          - apollo-configservice
        links:
          - apollo-configservice
        volumes:
          - "$PWD/logs/100003172:/opt/logs/100003172"
        environment:
          - spring_datasource_url=jdbc:mysql://数据库的主机IP:13306/ApolloConfigDB?characterEncoding=utf8
          - spring_datasource_username=数据库的用户名
          - spring_datasource_password=数据库密码
          - host_ip=这个是我自己加的Eureka上服务的IP地址(部署服务的宿主机IP)
    

    除了把apollo-portal相关的去掉了,其他的没有任何变得;同是把ip、数据库等相关环境个性化的东西做一下修改就好了;

  • 第二步:启动并二次重启服务

    docker-compose up -d
    // 重启的原因和上面说的一样
    docker-compose restart
    // 查看服务
    docker ps -a | grep apollo
    // 如果出现下图切Eureka上面正常注册了,说明环境相关的服务以及启动正常了
    

    file
    file

  • 第三步,修改环境配置文件apollo-env.properties
    file

  • 第四步,修改ApolloPortalDB.ServerConfig表中的envs字段

    找到 系统参数配置并查找 apollo.portal.envs配置,并将其修改为你需要支持的多个环境,记得用英文的逗号隔开

    file

  • 第五步,重启apollo-portal服务

    docker restart apollo-portal
    

    file
    file

到此,分布式的apollo环境搭建就完成了;集群就在以上环境下做相关配置即可。


镜像创建过程

apollo-mysql镜像

  • 获取sql脚本,下载

  • 配置文件

    vim mysql.cnf
    
    [mysql]
    default-character-set = utf8
    [mysql.server]
    default-character-set = utf8
    [mysqld_safe]
    default-character-set = utf8
    [client]
    default-character-set = utf8
    [mysqld]
    character_set_server=utf8
    init_connect='SET NAMES utf8'
    
  • 添加初始化数据库脚本

    vim init_db.sh
    
    mysql -uroot -p$MYSQL_ROOT_PASSWORD <<EOF
    source $WORK_PATH/apolloconfigdb.sql;
    source $WORK_PATH/apolloportaldb.sql;
    EOF
    mysql -uroot -p$MYSQL_ROOT_PASSWORD <<EOF
    $UPDATE_EUREKA_URL_SQL;
    EOF
    
  • 创建Dockerfile

    # mysql 官方镜像
    FROM mysql:5.7.22
    # 作者
    MAINTAINER lupf <397729842@qq.com>
    # 定义会被容器自动执行的目录
    ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d
    # 定义工作目录
    ENV WORK_PATH /usr/local/work
    # 将要执行的sql脚本拷贝至工作目录
    COPY ./*.sql $WORK_PATH/
    # 将执行sql的shell脚本拷贝至docker-entrypoint-initdb.d,这个目录会在容器启动的时候自动执行下面的指令
    COPY ./init_db.sh $AUTO_RUN_DIR/
    # 将配置文件拷贝到对应的目录
    #COPY ./mysql.cnf /etc/mysql/mysql.conf.d/
    # 给执行文件增加可执行权限
    RUN chmod a+x $AUTO_RUN_DIR/*
    
  • 构建镜像即可

    docker build -t pengfeilu/apollo-mysql:5.7.22_1.6.0
    

adminservice、configservice和portal镜像构建

  • 下载官方代码

    // github 地址
    git clone https://github.com/ctripcorp/apollo.git
    // 如果github下载慢,也可以去码云下
    git clone https://gitee.com/nobodyiam/apollo.git
    
  • 微调一点Eureka配置

    //进入apollo-adminservice和apollo-configservice
    cd apollo-adminservice/src/main/resources/
    // 以及
    cd apollo-configservice/src/main/resources/
    

    分别在application.yml添加以下配置

    spring:
      cloud:
        inetutils:
          ignoredInterfaces:
            - docker0
            - veth.*
    

    亲测上面这种忽略网卡的做法貌似不会生效,因此,这里再添加下面的一行配置
    分别在bootstrap.yml添加以下配置

    eureka:
      instance:
        ip-address: ${host_ip}
    
  • Maven编译

    // 进入项目的根目录,apollo目录,允许以下指令
    sh scripts/build.sh
    // 如果是windows,允许build.bat即可
    
  • 使用各个项目的Docker脚本将打好的包打成镜像

    • 找到Dockerfile

      将apollo-configservice、apollo-adminservice和apollo-portal下,target目录中的apollo-*-1.6.0-SNAPSHOT-github.zip文件分别拷贝到各自项目的src/main/docker/目录下

    • 生成镜像

      // 在各自的src/main/docker/ 分别执行以下各自的指令编译成对于的镜像
      cd apollo-configservice/src/main/docker/
      docker build -t pengfeilu/apollo-configservice:1.6.0 .
      
      cd apollo-adminservice/src/main/docker/
      docker build -t pengfeilu/apollo-adminservice:1.6.0 .
      
      cd apollo-portal/src/main/docker/
      docker build -t pengfeilu/apollo-portal:1.6.0 .
      

      file

到此,所有的镜像即创建完成!



标题:基于Docker 5分钟搭建携程Apollo分布式配置中心
作者:码霸霸
地址:https://lupf.cn/articles/2019/11/16/1573908705297.html