1. 程式人生 > >攜程 Apollo 配置中心分散式部署(Docker)

攜程 Apollo 配置中心分散式部署(Docker)

Spring Boot 2.0 整合攜程Apollo配置中心一文中,我們在本地快速部署試用了Apollo。本文將介紹如何按照分散式部署(採用Docker部署)的方式編譯、打包、部署Apollo配置中心,從而可以在開發、測試、生產等環境分別部署執行。

一、準備工作

本文將在CentOS 7.x上部署Apollo配置中心服務端。

1.1 Java和MySQ

對於Java和MySQL的要求可以參考Spring Boot 2.0 整合攜程Apollo配置中心準備工作的部分。

1.2 Docker環境安裝

對於Docker環境的安裝可以參考CentOS 7.x 安裝Docker

1.3 Docker Compose安裝

對於Docker Compose的安裝可以參考Docker Compose編排微服務

1.4 部署策略(來自官網)

分散式部署需要事先確定部署的環境以及部署方式。Apollo目前支援以下環境:

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

  • Portal部署在生產環境的機房,通過它來直接管理FAT、UAT、PRO等環境的配置
  • Meta Server、Config Service和Admin Service在每個環境都單獨部署,使用獨立的資料庫
  • Meta Server、Config Service和Admin Service在生產環境部署在兩個機房,實現雙活
  • Meta Server和Config Service部署在同一個JVM程序內,Admin Service部署在同一臺伺服器的另一個JVM程序內

另外可以參考下面的樣例部署圖:
樣例部署圖

為了演示方便,本文將Apollo-portal,Apollo-adminservice和Apollo-configservice部署在一臺機器上

伺服器 服務 環境
192.168.10.138 apollo-portal 8070 UAT
192.168.10.138 apollo-adminservice 8080 UAT
192.168.10.138 apollo-configservice 8090 UAT

1.5 網路策略(來自官網)

分散式部署的時候,apollo-configservice和apollo-adminservice需要把自己的IP和埠註冊到Meta Server(apollo-configservice本身)。

Apollo客戶端和Portal會從Meta Server獲取服務的地址(IP+埠),然後通過服務地址直接訪問。

所以如果實際部署的機器有多塊網絡卡(如docker),或者存在某些網絡卡的IP是Apollo客戶端和Portal無法訪問的(如網路安全限制),那麼我們就需要在apollo-configservice和apollo-adminservice中做相關限制以避免Eureka將這些網絡卡的IP註冊到Meta Server。

如下面這個例子就是對於apollo-configservice,把docker0和veth.* 的網絡卡在註冊到Eureka時忽略掉。

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

另外一種方式是直接指定要註冊的IP,可以修改startup.sh,通過JVM System Property在執行時傳入,如-Deureka.instance.ip-address=${指定的IP},或者也可以修改apollo-adminservice或apollo-configservice 的bootstrap.yml檔案,加入以下配置

eureka:
  instance:
    ip-address: ${指定的IP}

最後一種方式是直接指定要註冊的IP+PORT,可以修改startup.sh,通過JVM System Property在執行時傳入,如-Deureka.instance.homePageUrl=http://${指定的IP}:${指定的Port},或者也可以修改apollo-adminservice或apollo-configservice 的bootstrap.yml檔案,加入以下配置

eureka:
  instance:
    homePageUrl: http://${指定的IP}:${指定的Port}
    preferIpAddress: false

如果Apollo部署在公有云上,本地開發環境無法連線,但又需要做開發測試的話,客戶端可以升級到0.11.0版本及以上,然後通過-Dapollo.configService=http://config-service的公網IP:埠來跳過meta service的服務發現

二、部署步驟

部署步驟共三步:

  1. 建立資料庫:Apollo服務端依賴於MySQL資料庫,所以需要事先建立並完成初始化
  2. 獲取安裝包:通過原始碼構建
  3. 構建docker映象:為apollo-configservice, apollo-adminservice, apollo-portal構建Docker映象
  4. 部署Apollo服務端:構建映象後通過docker compose就可以部署到公司的測試和生產環境了

2.1 建立資料庫

Apollo服務端共需要兩個資料庫:ApolloPortalDB和ApolloConfigDB,官網把資料庫、表的建立和樣例資料都分別準備了sql檔案(在下載的原始碼/scripts/sql目錄下),只需要匯入資料庫即可。

由於我只在一臺伺服器上做演示,所以ApolloPortalDBApolloConfigDB在UAT環境部署一套就可以了

伺服器 資料庫 環境
192.168.10.58 ApolloPortalDB 3306 UAT
192.168.10.58 ApolloConfigDB 3306 UAT

2.1.1 建立ApolloPortalDB

通過各種Mysql客戶端(Navicat,DataGrip等)匯入sql/apolloportaldb.sql即可
下面以MySQL原生客戶端為例:

source /your_local_path/sql/apolloportaldb.sql

匯入成功後,可以通過執行以下sql語句來驗證:

select `Id`, `AppId`, `Name` from ApolloPortalDB.App;
Id AppId Name
1 SampleApp Sample App

2.1.2 建立ApolloConfigDB

通過各種Mysql客戶端(Navicat,DataGrip等)匯入sql/apolloconfigdb.sql即可
下面以MySQL原生客戶端為例:

source /your_local_path/sql/apolloconfigdb.sql

匯入成功後,可以通過執行以下sql語句來驗證:

select `NamespaceId`, `Key`, `Value`, `Comment` from ApolloConfigDB.Item;
NamespaceId Key Value Comment
1 timeout 100 sample
2.1.2.1 從別的環境匯入ApolloConfigDB的專案資料

如果是全新部署的Apollo配置中心,請忽略此步。

如果不是全新部署的Apollo配置中心,比如已經使用了一段時間,這時在Apollo配置中心已經建立了不少專案以及namespace等,那麼在新環境中的ApolloConfigDB中需要從其它正常執行的環境中匯入必要的專案資料。

主要涉及ApolloConfigDB的下面4張表,下面同時附上需要匯入的資料查詢語句:

  1. App
    • 匯入全部的App
    • 如:insert into 新環境的ApolloConfigDB.App select * from 其它環境的ApolloConfigDB.App where IsDeleted = 0;
  2. AppNamespace
    • 匯入全部的AppNamespace
    • 如:insert into 新環境的ApolloConfigDB.AppNamespace select * from 其它環境的ApolloConfigDB.AppNamespace where IsDeleted = 0;
  3. Cluster
    • 匯入預設的default叢集
    • 如:insert into 新環境的ApolloConfigDB.Cluster select * from 其它環境的ApolloConfigDB.Cluster where Name = ‘default’ and IsDeleted = 0;
  4. Namespace
    • 匯入預設的default叢集中的namespace
    • 如:insert into 新環境的ApolloConfigDB.Namespace select * from 其它環境的ApolloConfigDB.Namespace where ClusterName = ‘default’ and IsDeleted = 0;

同時也別忘了通知使用者在新的環境給自己的專案設定正確的配置資訊,尤其是一些影響面比較大的公共namespace配置。

2.1.3 調整服務端配置

Apollo自身的一些配置是放在資料庫裡面的,所以需要針對實際情況做一些調整。

2.1.3.1 調整ApolloPortalDB配置

配置項統一儲存在ApolloPortalDB.ServerConfig表中,也可以通過管理員工具 - 系統引數頁面進行配置。

  1. apollo.portal.envs - 可支援的環境列表
    預設值是dev,如果portal需要管理多個環境的話,以逗號分隔即可(大小寫不敏感),如:DEV,FAT,UAT,PRO,我這裡設定為UAT1.1.0版本增加了系統資訊頁面(管理員工具 -> 系統資訊),可以通過該頁面檢查配置是否正確
2.1.3.2 調整ApolloConfigDB配置

配置項統一儲存在ApolloConfigDB.ServerConfig表中,需要注意每個環境的ApolloConfigDB.ServerConfig都需要單獨配置。

  1. eureka.service.url - Eureka服務Url
    不管是apollo-configservice還是apollo-adminservice都需要向eureka服務註冊,所以需要配置eureka服務地址。 按照目前的實現,apollo-configservice本身就是一個eureka服務,所以只需要填入apollo-configservice的地址即可,如有多個,用逗號分隔(注意不要忘了/eureka/字尾)。這裡我填寫http://192.168.10.138:8080/eureka。後續文章我會單獨介紹如何將Config Service和Admin Service註冊到公司統一的Eureka上

2.2 獲取安裝包

可以通過兩種方式獲取安裝包:

  1. 直接下載安裝包
    • 從GitHub Release頁面下載預先打好的安裝包
    • 如果對Apollo的程式碼沒有定製需求,建議使用這種方式,可以省去本地打包的過程
  2. 通過原始碼構建
    • 從GitHub Release頁面下載Source code包或直接clone原始碼後在本地構建
    • 如果需要對Apollo的做定製開發,需要使用這種方式

這裡我是通過原始碼構建的

2.2.1 通過原始碼構建

到github上進行原始碼下載

2.2.1.1 配置資料庫連線資訊

Apollo服務端需要知道如何連線到你前面建立的資料庫,所以需要編輯scripts/build.sh,修改ApolloPortalDB和ApolloConfigDB相關的資料庫連線串資訊。

# apollo config db info
apollo_config_db_url=jdbc:mysql://192.168.10.58:3306/ApolloConfigDB?characterEncoding=utf8
apollo_config_db_username=root
apollo_config_db_password=Ibase2016

# apollo portal db info
apollo_portal_db_url=jdbc:mysql://192.168.10.58:3306/ApolloPortalDB?characterEncoding=utf8
apollo_portal_db_username=root
apollo_portal_db_password=Ibase2016
2.2.1.2 配置各環境meta service地址

Apollo Portal需要在不同的環境訪問不同的meta service(apollo-configservice)地址,所以需要在打包時提供這些資訊。我這裡只部署UAT環境,配置修改如下:

# meta server url, different environments should have different meta server addresses
#dev_meta=http://192.168.10.58:8080
#fat_meta=http://192.168.10.58:8080
uat_meta=http://192.168.10.138:8080
#pro_meta=http://192.168.10.58:8080

#META_SERVERS_OPTS="-Ddev_meta=$dev_meta -Dfat_meta=$fat_meta -Duat_meta=$uat_meta -Dpro_meta=$pro_meta"
META_SERVERS_OPTS="-Duat_meta=$uat_meta"
2.2.1.3 執行編譯、打包

做完上述配置後,就可以執行編譯和打包了。執行/scripts目錄下build.sh指令碼,該指令碼會依次打包apollo-configservice, apollo-adminservice, apollo-portal。

2.2.1.4 獲取安裝包和Dockerfile檔案
  1. 獲取apollo-configservice安裝包:安裝包在位於apollo-configservice/target/目錄下的apollo-configservice-x.x.x-github.zip,Dockerfile在apollo-configservice/src/main/docker/目錄下
  2. 獲取apollo-adminservice安裝包:安裝包位於apollo-adminservice/target/目錄下的apollo-adminservice-x.x.x-github.zip,Dockerfile在apollo-adminservice/src/main/docker/目錄下
  3. 獲取apollo-portal安裝包:安裝包位於apollo-portal/target/目錄下的apollo-portal-x.x.x-github.zip,Dockerfile在apollo-portal/src/main/docker/目錄下

分別將上面的安裝包和Dockerfile檔案上傳至伺服器(已安裝Docker)上

2.3 構建docker映象

上傳到伺服器上的安胡子那個包和Dockerfile檔案目錄結構如下:

apollo_portal
      - Dokerfile
      - apollo-portal-x.x.x-github.zip
apollo_config
      - Dokerfile
      - apollo-configservice-x.x.x-github.zip      
apollo_admin
      - Dokerfile
      - apollo-adminservice-x.x.x-github.zip
  1. 構建simon/apollo-portal映象
    進入apollo_portal目錄執行如下命令docker build -t simon/apollo_portal .
  2. 構建simon/apollo-portal映象
    進入apollo_config目錄執行如下命令docker build -t simon/apollo_configservice .
  3. 構建simon/apollo-portal映象
    進入apollo_admin目錄執行如下命令docker build -t simon/apollo_adminservice .

2.4 部署Apollo服務端

我們通過docker compose部署Apollo服務端,部署的配置檔案如下:

version: "3"

services:
  apollo-configservice:                                         ##容器服務名
    container_name: apollo-configservice                        ##容器名
    #build: apollo-configservice/src/main/docker/                ##Dockerfile路徑
    image: simon/apollo-configservice                           ##映象名
    ports:
      - "8080:8080"    
    volumes:
      - "/opt/logs/100003171:/opt/logs/100003171"    ##將/opt/logs/100003171目錄掛載到宿主機的/opt/logs/100003171方便在宿主機上檢視日誌
  apollo-adminservice:
    container_name: apollo-adminservice
    #build: apollo-adminservice/src/main/docker/
    image: simon/apollo-adminservice
    ports:
      - "8090:8090"
    depends_on:
      - apollo-configservice
    volumes:
      - "/opt/logs/100003172:/opt/logs/100003172"
  apollo-portal:
    container_name: apollo-portal
    #build: apollo-portal/src/main/docker/
    image: simon/apollo-portal
    ports:
      - "8070:8070"
    depends_on:
      - apollo-adminservice
    volumes:
      - "/opt/logs/100003173:/opt/logs/100003173"

在配置檔案目錄執行如下命令啟動服務:

docker-compose up

這樣整個部署過程就結束了。