Apollo学习(五):docker容器化分布式部署

说明

在之前的文章《Apollo学习(三): 分布式部署》中,我简单介绍了在Windows环境下,实现Apollo配置中心的分布式部署。本篇博文我将对如何实现Apollo的docker容器化分布式部署的步骤进行记录总结。

正文

目的

  1. 根据源码定制安装包,修改默认端口,日志输出地址、等级,jvm等参数的默认值
  2. 使用独立的docker部署的注册中心集群
  3. 使用容器化部署的MySQL数据库
  4. 容器化部署Apollo并使用docker compose实现容器编排

要达到以上的目的,我们需要根据官方的分布式部署指南对Apollo的启动脚本,配置文件等进行修改,获取安装包。同时,因为使用了docker部署,在与MySQL数据库和Eureka注册中心的通信,涉及到了容器间的通信问题。最后,要使用docker compose对容器进行编排,需要编写docker-compose.yml文件。


步骤

1. 获取源码

根据需求从GitHub Release页面下载所需版本的source code包或者直接clone源码。

2. 自定义配置

如果需要项目的默认端口,日志输出路径、等级等配置信息,需要对apllo-configservice, apollo-adminservice, apollo-portal三个项目进行修改。

修改端口:原来默认端口分别是8070 8080 8090,若需修改监听端口,可直接修改三个项目的scripts/startup.sh中的SERVER_PORT。
注意,由于采用的是docker部署,可以不修改原有端口,可采用端口映射来实现默认值的修改。此时,要注意docker-compose.yml文件中各服务的端口映射ports的值。

修改日志配置:
调整日志输出路径可分别修改三个项目scripts/startup.sh文件和apollo-{project}.conf文件中LOG_DIR的值。为方便查询日志,可在docker-compose.yml文件中,使用volumes进行文件的挂载。
调整日志等级分别修改三个项目的logback.yml配置文件。

修改JVM参数:可以修改scripts/startup.sh的JAVA_OPTS参数值

3. 禁用自带配置中心

由于Apollo的apollo-configservice项目本身就是配置中心,要使用独立的配置中心,需要禁止自带的配置中心。修改apollo-configsevice项目的bootstrap.yml文件,添加以下配置:

apollo:
  eureka:
    server:
      enabled: false

4. 调整网络策略

分布式部署时,apollo-configsevice和apollo-adminservice需要把直接的ip和port注册到注册中心,再由Meta Server返回给客户端和apollo-portal。

在docker部署时,如果没有使用独立的容器化部署的注册中心,不需进行这样的容器间通信。这里注意,需要避免将某些客户端和Portal无法访问的网卡IP注册到eureka,因此要在apollo-configservice和apollo-adminservice中做先关的限制。

修改两个项目的application.yml文件,把要忽略的网卡加进去,如:docker0,这个是docker默认的bridge network,当创建容器时,没有特别指network,则会默认加入到此bridge network中。

spring:
  application:
      name: apollo-configservice
  profiles:
    active: ${apollo_profile}
  cloud:
    inetutils:
      ignoredInterfaces:
        - docker0
        - veth.*

如果是使用单独容器化部署的注册中心,则容器间需要进行通信(这里指的都是同一个docker daemon进程下的容器通信)。需要使用特定的bridge network。注意,因为容器间的通信,所以apollo-configservice和apollo-adminservice在注册时会将特定的网卡ip注册到注册中心,这样会导致客户端和Portal无法访问。这里,就需要指定要注册的IP,由于apollo-configservice和apollo-adminservice是基于内网可信的网络设计的,我们可以直接指定内网机器的内网ip,此时访问时就需要内网IP:映射的Port, 而不是通过expose暴露的端口

指定注册的IP,修改apollo-configsevice和apollo-adminservice项目的bootstrap.yml文件。其他方式详见wiki。

eureka:
  instance:
    ip-address: 内网ip

5. 修改配置中心的地址

这里我使用的是独立的容器化部署的eureka集群,需要修改ApolloConfigDB数据库中ServerConfig表的eureka.service.url字段的值。容器间的通信,直接指定container_name:port,多个地址用逗号分隔:

http://eureka-server1:3030/eureka/,http://eureka-server2:3031/eureka/

6. 配置数据库的连接信息

这里我同样使用的是容器化部署的MySQL数据库,ip也为container_name。直接编辑项目中的scripts/build.sh文件,配置ApolloConfigDB和ApolloPortalDB的连接信息:

# apollo config db info
apollo_config_db_url=jdbc:mysql://mysql5.7:3306/ApolloConfigDB?characterEncoding=utf8
apollo_config_db_username=root
apollo_config_db_password=

# apollo portal db info
apollo_portal_db_url=jdbc:mysql://mysql5.7:3306/ApolloPortalDB?characterEncoding=utf8
apollo_portal_db_username=root
apollo_portal_db_password=

7. 配置Meta Server的地址

由于meta service和config service是在同一个jvm部署的,所以这个地址就是apollo-configservice项目的地址,又因为apollo-portal项目同为docker部署,这里要进行容器间的通信。ip即为apollo-configservice的容器名称,若之前修改了项目的监听端口,这里的端口也要与其一致
注意,在实际使用中,在不同环境中,apollo-configservice和apollo-adminservice要重新部署,而apollo-portal只要部署一套就可管理各个环境,不同的环境中可能并不需要容器间的通信。要依据实际来配置meta service的地址。

编辑scripts/build.sh文件

dev_meta=http://apollo-configservice:9003

8. 编译打包

根据需求修改后,进行编译打包,执行项目的build.sh脚本,该脚本会重新打包项目的安装包。

由于不同环境所用的数据库信息不同,所以针对不同的环境apollo-configservice和apollo-adminservice要重新打包,apollo-portal只需要打包一次。

9. 构建镜像

在脚本执行完成后,分别在三个项目的target文件夹下获取安装包,名称分别为apollo-configservice-x.x.x-github.zip, apollo-adminservice-x.x.x-githup.zip, apollo-portal-x.x.x-github.zip。
官方已经在源码中提供了Dockerfile,注意文件中的版本号要与安装包的版本号一致

这里我使用的是云服务器,将Dockerfile和安装包上传到服务器后,执行docker build -t container_name . 构建镜像。

10. 编写docker-compose文件

注意,这里连接MySQL,Eureka以及Portal需要从meta service获取服务地址信息都涉及到了容器间的通信,又因为这些容器我都部署在了同一个docker daemon进程下,所以使用 User-defined bridge network

这里我使用了两个bridge network,分别为mysql_net,eureka_net。

eureka_net为eureka容器化部署集群时创建,apollo-configservice和apollo-adminservice需要与eureka进行通信,需要加入到此网络中,又因为apollo-portal需要从meta service中获取服务地址,即需要和apollo-configservice通信,也需要加入到此网络中。

mysql_net为单独创建,为了与MySQL通信,apollo-configservice,apollo-adminservice和apollo-portal都需要进入到此网络中

创建bridge network可使用以下命令:

docker network create [network_name]

连接正在运行的容器到network中可使用以下命令:

dockcer network connect [network_name] [container_name]

注意,这里的bridge network都是提前创建的,在docker-compose.yml文件中需要将networks的external参数值设置为true

version: '3'
services:
  apolloconfigservice:
    image: apollo-configservice
    container_name: apollo-configservice
    networks:
      - mysql
      - eureka-net
    volumes:
      - /opt/docker/apollo/logs/config:/opt/logs/configservice
    ports:
      - 9003:9003
  
  apolloadminservice:
    image: apollo-adminservice
    container_name: apollo-adminservice
    depends_on: 
      - apolloconfigservice
    networks:
      - mysql
      - eureka-net
    volumes:
      - /opt/docker/apollo/logs/admin:/opt/logs/adminservice  
    ports:
      - 9004:9004

  apolloportalservice:
    image: apollo-portal
    container_name: apollo-portal
    depends_on: 
      - apolloconfigservice
      - apolloadminservice
    networks:
      - mysql
      - eureka-net
    volumes:
      - /opt/docker/apollo/logs/portal:/opt/logs/apolloportal   
    ports:
      - 9005:9005

networks:
  eureka-net:
    external: true
  mysql:
    external: true

11. 启动服务

将docker-compose.yml上传到服务器,使用命令docker-compose up -d 启动服务。

注意,在文件中使用depends_on来确定容器的启动顺序,确保apollo-configservice和apollo-adminservice服务在apollo-portal服务前启动。

问题

我在实际操作时,使用的是个人云服务器,由于服务器的限制,无法同时启动三个服务,我将apollo-configservice和apollo-adminservice使用一个docker-compose.yml文件管理,apollo-portal单独使用一个docker-compose.yml文件管理。
但是在服务启动后发现,apollo-portal服务对apollo-adminservice 和 apollo-configservice的某个http请求一直会出现connection refused错误,但是这些容器都运行正常。
在刚开始时,以为是端口的问题,换了多次端口,通过docker-compose重启多次,但依然存在http connection refused的问题。查了很多资料,都很确定容器内监听的端口设置没有问题,如果正常监听的话,不会出现connection refused的问题。那么问题就在 容器是否正常监听了设置的端口??
通过命令 docker exec -it container_name /bin/sh 进入到无法连接的服务容器中,再通过命令 netstat -tunlp 查看端口占用的情况。果然,端口没有正常监听,导致apollo-portal的http请求一直connection refused,整个Apollo配置服务一直异常。
通过命令 docker restart container_name 重启容器后,容器监听端口正常,服务恢复正常。


源码地址:
https://github.com/Edenwds/apollo_docker
参考资料:
https://github.com/idoop/docker-apollo
https://docs.docker.com/network/bridge/
https://github.com/moby/moby/issues/23849
https://blog.csdn.net/Third_Week/article/details/89145583

你可能感兴趣的:(Apollo,Apollo配置中心,分布式部署,docker容器化)