Apollo 配置中心學習筆記


前言

Apollo(阿波羅)是攜程框架部門研發的分布式配置中心,能夠集中化管理應用不同環境、不同集群的配置,配置修改后能夠實時推送到應用端,並且具備規范的權限、流程治理等特性,適用於微服務配置管理場景。

服務端基於Spring Boot和Spring Cloud開發,打包后可以直接運行,不需要額外安裝Tomcat等應用容器。

Java客戶端不依賴任何框架,能夠運行於所有Java運行時環境,同時對Spring/Spring Boot環境也有較好的支持。

強烈推薦參考官方文檔(中文):
https://www.apolloconfig.com/#/zh/README

本文着重記錄搭建及使用過程,分為以下三種部署方式:

  1. 本地快速部署
  2. 分布式部署
  3. 容器快速部署
  4. 基於 k8s 部署

本文所使用到的軟件包下載地址:
鏈接:https://pan.baidu.com/s/1Sa9XLGqIDTyTIwls_VaL4A
提取碼:hhhh

本地快速部署

准備工作

軟件名 版本
java 1.8.5
MySQL 8.0.25
apache-maven 3.8.1
apollo-quick-start 1.8.0

配置java 環境

# tar xf jdk-8u77-linux-x64.tar.gz  -C /usr/local/
# cat << EOF >> /etc/profile
JAVA_HOME=/usr/local/jdk1.8.0_77
JAVA_BIN=\$JAVA_HOME/bin
PATH=\$PATH:\$JAVA_BIN
CLASSPATH=\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar
export JAVA_HOME JAVA_BIN PATH CLASSPATH
EOF
# source  /etc/profile
# ln -vs  /usr/local/jdk1.8.0_77/bin/java /usr/bin/java
# java -version
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)

安裝並配置 MySQL

# tar xf mysql-server-8.0.25.tar.gz 
# yum localinstall mysql-server-8.0.25/*.rpm -y
# systemctl start mysqld
# egrep pass /var/log/mysqld.log 
2021-05-25T06:00:52.071719Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: ba6Q6s;RYbrs  # 這里獲取初始密碼。
# mysql -uroot -p'ba6Q6s;RYbrs'
 ### 注意密碼復雜度,MySQL8.0.x 以上默認要求密碼復雜度,否則無法更新密碼 ###
mysql> alter user 'root'@'localhost' identified by 'mysql@123.COM';
mysql> flush privileges;
mysql> exit
====== 使用修改后的密碼登錄 MySQL 獲取權限並設置遠程客戶端連接 ====== 
# mysql -uroot -pmysql@123.COM
mysql> use mysql
mysql> update user set host='%' where user ='root';
### 如果這里出現報錯信息,請再次執行一遍 ###
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'mysql@123.COM';
mysql> flush privileges;

使用 Navicat Premium 連接 MySQL
image

安裝並配置 Maven

# tar xf apache-maven-3.8.1-bin.tar.gz -C /usr/local/
# cat <<EOF>> /etc/profile.d/maven.sh
export PATH=\$PATH:/usr/local/apache-maven-3.8.1/bin/
EOF
# source /etc/profile.d/maven.sh
# mvn -v
Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d)
Maven home: /usr/local/apache-maven-3.8.1
Java version: 1.8.0_77, vendor: Oracle Corporation, runtime: /usr/local/jdk1.8.0_77/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1160.el7.x86_64", arch: "amd64", family: "unix"

配置並啟動 apollo

# mkdir apollo
# unzip apollo-quick-start-1.8.0.zip -d apollo/
  1. 首先導入 sql 數據庫信息
# ls
apolloconfigdb.sql  apolloportaldb.sql
# pwd
/root/apollo/sql

=== 登錄mysql,准備導入數據
# mysql -uroot -pmysql@123.COM
mysql> source /root/apollo/sql/apolloconfigdb.sql;
mysql> source /root/apollo/sql/apolloportaldb.sql;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| ApolloConfigDB     |
| ApolloPortalDB     |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

  1. 修改 demo.sh 數據庫信息
# vim demo.sh
...
# apollo config db info
apollo_config_db_url="jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8&serverTimezone=Asia/Shanghai"
apollo_config_db_username=root	# mysql 用戶名
apollo_config_db_password=mysql@123.COM # mysql 密碼

# apollo portal db info
apollo_portal_db_url="jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8&serverTimezone=Asia/Shanghai"
apollo_portal_db_username=root	# mysql 用戶名
apollo_portal_db_password=mysql@123.COM	# mysql 密碼
...
  1. 啟動 demo.sh
# ./demo.sh start
==== starting service ====
Service logging file is ./service/apollo-service.log
Application is running as root (UID 0). This is considered insecure.
Started [2143]
Waiting for config service startup...
Config service started. You may visit http://localhost:8080 for service status now!
Waiting for admin service startup
Admin service started
==== starting portal ====
Portal logging file is ./portal/apollo-portal.log
Application is running as root (UID 0). This is considered insecure.
Started [2343]
Waiting for portal startup...
Portal started. You can visit http://localhost:8070 now!

# netstat -ntplu | egrep java
tcp6       0      0 :::8090      :::*   LISTEN      2143/java
tcp6       0      0 :::8070      :::*   LISTEN      2343/java
tcp6       0      0 :::8080      :::*   LISTEN      2143/java
  1. 瀏覽器訪問

鏈接:http://10.0.30.101:8070 用戶名密碼:apollo/admin

image

配置 apollo 測試樣例

  1. maven 生成 jar 包
# vim /usr/local/apache-maven-3.8.1/conf/settings.xml

### 修改為國內源 ###
...
  <mirrors>
      <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>https://maven.aliyun.com/repository/public/</url>
      <mirrorOf>*</mirrorOf>
      </mirror>
  </mirrors>
...
# tar xf springboot-apollo-demo.tar.gz
# cd springboot-apollo-demo/
# tree -a 
.
├── deploy.yaml
├── Dockerfile
├── pom.xml
├── README.md
└── src
    └── main
        ├── java
        │   └── club
        │       └── mydlq
        │           └── demo
        │               ├── Application.java
        │               └── TestController.java
        └── resources
            └── application.yaml

### 修改配置如下 ###
# cat src/main/resources/application.yaml 
server:
  port: 7070
spring:
  application:
    name: apollo-test

app:
  id: apollo-test	# 應用ID 對應 apollo 項目中的AppId
apollo:
  cacheDir: /opt/data/	# 配置本地配置緩存目錄
  meta: http://localhost:8080	# 配置中心地址
  autoUpdateInjectedSpringProperties: true	# 是否開啟 Spring 參數自動更新
  bootstrap:
    enabled: true	# 是否開啟 Apollo
    eagerLoad:
      enabled: false # 將 Apollo 加載提到初始化日志系統之前

# mvn clean package
# cd target/
# java -jar apollo-demo-0.0.1.jar
  1. 通過 apollo 為程序添加變量

image

image

image

image

image

發布成功后,通過瀏覽器訪問:http://10.0.30.101:7070/test

image

程序中apollo 配置解讀

[root@apollo ~/springboot-apollo-demo]# tree -a 
.
├── deploy.yaml
├── Dockerfile
├── pom.xml
├── README.md
└── src
    └── main
        ├── java
        │   └── club
        │       └── mydlq
        │           └── demo
        │               ├── Application.java
        │               └── TestController.java
        └── resources
            └── application.yaml	# apollo 主配置文件

7 directories, 7 files

# cat src/main/resources/application.yaml 
server:
  port: 7070
spring:
  application:
    name: apollo-test

app:
  id: apollo-test	# 應用ID 對應 apollo 項目中的AppId
apollo:
  cacheDir: /opt/data/	# 配置本地配置緩存目錄
  meta: http://localhost:8080	# 配置中心地址
  autoUpdateInjectedSpringProperties: true	# 是否開啟 Spring 參數自動更新
  bootstrap:
    enabled: true	# 是否開啟 Apollo
    eagerLoad:
      enabled: false # 將 Apollo 加載提到初始化日志系統之前

測試 apollo

測試目標:測試當apollo中修改參數值后客戶端是否能及時刷新。

接下來,通過修改 test 的值來嘗試是否熱加載。

image

image

通過瀏覽器再次刷新:

image

測試當apollo執行配置回滾時客戶端是否能及時改變

image

回滾完成后狀態將變為未發布狀態,通過瀏覽器訪問程序接口:

image

結論:通過回滾,程序可獲取上一個版本參數的值。

測試當不能訪問 Apollo 時客戶端的變化

  1. 直接down掉 config-service
# ./demo.sh stop

關閉之后,通過瀏覽器刷新訪問:

image

可以發現顯示的值並不是定義的默認值,而是 Apollo 配置中心配置的 test 參數的值,查看本地的 緩存文件:

# cat /opt/data/apollo-test/config-cache/apollo-test+default+application.properties #Persisted by DefaultConfig#Tue May 25 15:27:50 CST 2021test=123456

結論:當客戶端不能連接到 Apollo 配置中心時候,默認使用本地緩存文件中的配置。

現在將緩存也進行清除嘗試:

# rm -rf /opt/data/=== 重新啟動 jar 程序 ===# java -jar apollo-demo-0.0.1.jar

通過瀏覽器訪問:

image

結論:刪除緩存配置文件后,輸出的值為程序定義的默認值。

測試當Apollo 中將參數刪除后客戶端的變化

進入到 apollo 配置中心,刪除之前創建的 test 參數,然后發布。

# ./demo.sh start# java -jar apollo-demo-0.0.1.jar

啟動后,訪問:

image

刪除參數配置:

image

刪除之后再次刷新瀏覽器:

image

結論:刪除參數配置后,輸出的值為程序定義的默認值。

測試程序切換 apollo 項目 實現參數變更

apollo-test 項目參數

image

apollo-test-1 項目參數

image

接下來通過,指定不同的啟動項來判斷 apollo項目的切換,從而獲取不同的參數。

默認啟動參數為:app.id=apollo-demoapp.meta=http://localhost:8080test 參數為 123456# java -jar apollo-demo-0.0.1.jar

瀏覽器訪問:

image

添加參數啟動:

# java -jar apollo-demo-0.0.1.jar --app.id=apollo-test-1 --apollo.meta=http://localhost:8080

image

結論:可通過指定不同的apollo 項目來實現多環境的切換。

分布式部署

部署架構

分布式部署需要確定部署環境及部署方式,Apollo目前支持以下環境:

  • DEV - 開發環境
  • FAT - 測試環境
  • UAT - 集成環境
  • PRO - 生產環境

規划如下:

  • 由於主機有限,本次只做 DEV,PRO 環境
  • Portal 部署在生產環境,通過它來直接管理多個環境(DEV,PRO)的配置
  • Config Service 和 Admin Service 在每個環境都單獨部署,使用獨立數據庫
  • Config Service 和 Admin Service 部署在同一台服務器。

環境

環境說明

  • apollo-portal是配置的管理端,可以統一管理多套環境的配置(apollo節點)。也可以每套環境獨立部署一個apollo-portal,只管理該環境的配置(apollo節點)。本次配置只配置一個 apollo-portal 節點。
  • 每個節點部署一個apollo-configservice和apollo-adminservice
  • 每套環境可以部署多個節點,建議生產環境部署兩個以上的節點。開發環境的節點個數可自行決定,可以只部署一個節點。
  • apollo-portal需要訪問ApolloPortalDB數據庫。
  • 每套環境需要有一個獨立的ApolloConfigDB數據庫,同一套環境的apollo-configservice和apollo-configservice訪問同一個ApolloConfigDB數據庫。

部署案例說明

以下部署將會演示:

  • 在 DEV , PRO 環境中各部署一套 apollo
  • 每套環境部署兩個apollo節點,每個節點包含一個apollo-configservice和一個apollo-adminservice。
  • 部署一個apollo-portal,管理多套環境。

軟件准備

軟件名 版本
java 1.8.5
MySQL 8.0.25
apache-maven 3.8.1
apollo-adminservice 1.8.1
apollo-configservice 1.8.1
apollo-portal 1.8.1

服務器准備

環境 服務器 服務 端口
/ 10.0.30.105 apollo-portal 8070
10.0.30.106 MySQL數據庫ApolloPortalDB 3306
DEV 10.0.30.101 apollo-configservice 8080
apollo-adminservice 8090
10.0.30.102 apollo-configservice 8080
apollo-adminservice 8090
10.0.30.103 MySQL數據庫ApolloPortalDB 3306
PRO 10.0.30.111 apollo-configservice 8080
apollo-adminservice 8090
10.0.30.112 apollo-configservice 8080
apollo-adminservice 8090
10.0.30.113 MySQL數據庫ApolloPortalDB 3306

數據庫

需要安裝並導入數據庫的主機如下:

主機 導入庫名
10.0.30.106 ApolloPortalDB.sql
10.0.30.103 ApolloConfigDB.sql
10.0.30.113 ApolloConfigDB.sql
  1. 安裝數據庫並導入:

【10.0.30.103、10.0.30.113】操作如下:

tar xf mysql-server-8.0.25.tar.gzcd mysql-server-8.0.25/yum localinstall *.rpm -ysystemctl start mysqldegrep pass /var/log/mysqld.log  # 獲取初始化密碼mysql -uroot -p'8A-Qkq8)./Ds'	# 通過初始化密碼登錄mysql> alter user 'root'@'localhost' identified by 'mysql@123.COM';	# 修改密碼mysql> flush privileges;mysql> exitmysql -uroot -pmysql@123.COM # 通過修改后的密碼登錄導入數據庫mysql> source /root/apollo/apolloconfigdb.sql;  # 注意導入數據庫的sql腳本=== 設置遠程連接 ===mysql> use mysql;## 執行報錯再次執行一次mysql> alter user 'root'@'%' identified with mysql_native_password by 'mysql@123.COM';mysql> alter user 'root'@'%' identified with mysql_native_password by 'mysql@123.COM';mysql> flush privileges;
  1. 調整 ApolloConfigDB.ServerConfig 表數據

如果當前環境只有一個節點時,則可以不用修改。如果有多個節點時,需要修改 eureka.serviceurl 的值為當前環境的 apollo-configservice 的地址和端口,多個地址之間用英文逗號隔開。

DEV 修改如下:http://10.0.30.101:8080/eureka/,http://10.0.30.102:8080/eureka/PRO 修改如下:http://10.0.30.111:8080/eureka/,http://10.0.30.112:8080/eureka/

image

【10.0.30.106】操作如下:

  1. 安裝數據庫並導入
tar xf mysql-server-8.0.25.tar.gzcd mysql-server-8.0.25/yum localinstall *.rpm -ysystemctl start mysqldegrep pass /var/log/mysqld.log  # 獲取初始化密碼mysql -uroot -p'8A-Qkq8)./Ds'	# 通過初始化密碼登錄mysql> alter user 'root'@'localhost' identified by 'mysql@123.COM';	# 修改密碼mysql> flush privileges;mysql> exitmysql -uroot -pmysql@123.COM # 通過修改后的密碼登錄導入數據庫mysql> source /root/apollo/apolloportaldb.sql;  # 注意導入數據庫的sql腳本=== 設置遠程連接 ===mysql> use mysql;## 執行報錯再次執行一次mysql> alter user 'root'@'%' identified with mysql_native_password by 'mysql@123.COM';mysql> alter user 'root'@'%' identified with mysql_native_password by 'mysql@123.COM';mysql> flush privileges;
  1. 調整 ApolloPortalDB.ServerConfig表的數據

portal默認支持的環境是DEV,若需要支持其它環境,需要修改apollo.portal.envs的值,默認值是DEV,修改為以下值,表示支持DEV、PRO兩個環境,注意每個環境值之間用英文逗號隔開:

DEV,PRO

image

部署 ConfigService 、AdminService

環境 服務 主機IP
DEV apollo-configService 10.0.30.101
10.0.30.102
apollo-adminService 10.0.30.101
10.0.30.102
PRO apollo-configService 10.0.30.111
10.0.30.112
apollo-adminService 10.0.30.111
10.0.30.112
  1. 部署 java
tar xf jdk-8u77-linux-x64.tar.gz  -C /usr/local/cat << EOF >> /etc/profileJAVA_HOME=/usr/local/jdk1.8.0_77JAVA_BIN=\$JAVA_HOME/binPATH=\$PATH:\$JAVA_BINCLASSPATH=\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jarexport JAVA_HOME JAVA_BIN PATH CLASSPATHEOFsource  /etc/profileln -vs  /usr/local/jdk1.8.0_77/bin/java /usr/bin/java
  1. 修改配置啟動apolloconfig、apolloadmin
yum install unzip -ymkdir -pv apollo/{adminservice,configservice}unzip apollo-configservice-1.8.1-github.zip -d apollo/configservice/unzip apollo-adminservice-1.8.1-github.zip -d apollo/adminservice/=== 修改如下 ===cat apollo/configservice/config/application-github.properties# DataSourcespring.datasource.url = jdbc:mysql://10.0.30.103:3306/ApolloConfigDB?characterEncoding=utf8	# mysql 地址【注意修改為對應集群的地址】spring.datasource.username = root	# 用戶名spring.datasource.password = mysql@123.COM	# 密碼cat apollo/adminservice/config/application-github.properties# DataSourcespring.datasource.url = jdbc:mysql://10.0.30.103:3306/ApolloConfigDB?characterEncoding=utf8spring.datasource.username = rootspring.datasource.password = mysql@123.COM

注意:這里修改mysql地址請對應集群,比如這里是 DEV 環境 對應的數據庫地址:10.0.30.103 。如果是PRO 環境,對應的數據庫地址:10.0.30.113

  1. 啟動服務:
# ./apollo/configservice/scripts/startup.sh 
Wed May 26 11:14:30 CST 2021 ==== Starting ==== 
Application is running as root (UID 0). This is considered insecure.
Started [1935]
Waiting for server startup...
Wed May 26 11:14:45 CST 2021 Server started in 15 seconds!
# ./apollo/adminservice/scripts/startup.sh 
Wed May 26 11:14:55 CST 2021 ==== Starting ==== 
Application is running as root (UID 0). This is considered insecure.
Started [2118]
Waiting for server startup..
Wed May 26 11:15:06 CST 2021 Server started in 10 seconds!

### 查看端口
# netstat -ntplu | egrep java
tcp6       0      0 :::8080   :::*   LISTEN 1935/java
tcp6       0      0 :::8090   :::*   LISTEN 2118/java

部署 apollo-portal

只部署了一個apollo-portal,用來管理所有環境的apollo節點。實際部署中,也可以每套環境都部署一個apollo-portal,管理各自環境的apollo-portal,下面也會有提示如何在每個環境單獨部署一個apollo-portal。

環境 服務器 服務 端口
/ 10.0.30.105 apollo-portal 8070
10.0.30.106 MySQL數據庫ApolloPortalDB 3306

【10.0.30.105】操作如下:

  1. java 環境
tar xf jdk-8u77-linux-x64.tar.gz  -C /usr/local/cat << EOF >> /etc/profileJAVA_HOME=/usr/local/jdk1.8.0_77JAVA_BIN=\$JAVA_HOME/binPATH=\$PATH:\$JAVA_BINCLASSPATH=\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jarexport JAVA_HOME JAVA_BIN PATH CLASSPATHEOFsource  /etc/profileln -vs  /usr/local/jdk1.8.0_77/bin/java /usr/bin/java
  1. 配置 apollo-portal
mkdir -pv apollo/portalyum install unzip -yunzip apollo-portal-1.8.1-github.zip -d apollo/portal/vim apollo/portal/config/application-github.properties# DataSourcespring.datasource.url = jdbc:mysql://10.0.30.106:3306/ApolloPortalDB?characterEncoding=utf8	# mysql 地址spring.datasource.username = root	# 用戶名spring.datasource.password = mysql@123.COM	# 密碼

注意:上面修改為對應數據庫的連接地址、用戶名、密碼

  1. 配置meta service信息。

meta service的地址和端口,默認就是apollo-configservice的地址和端口。修改config/apollo-env.properties,填寫當前的apollo-portal要管理的環境的apollo-configservice的地址和端口,多個地址之間用英文逗號隔開。修改完后的效果如下:

vim apollo/portal/config/apollo-env.propertiesdev.meta=http://10.0.30.101:8080,http://10.0.30.102:8080pro.meta=http://10.0.30.111:8080,http://10.0.30.112:8080

注意:上面的配置表示當前的apollo-portal要管理dev、pro兩套環境的apollo節點,每個環境的節點數是兩個。

啟動 apollo-portal

# ./apollo/portal/scripts/startup.shWed May 26 14:05:29 CST 2021 ==== Starting ====Application is running as root (UID 0). This is considered insecure.Started [13345]Waiting for server startup..Wed May 26 14:05:39 CST 2021 Server started in 10 seconds!
  1. 通過瀏覽器訪問

image

Docker 方式部署Quick Start

安裝docker-ce

curl http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repoyum install git docker-ce docker-compose -ymkdir -pv /etc/docker/cat << EOF >> /etc/docker/daemon.json{  "registry-mirrors": [    "https://hub-mirror.c.163.com",    "https://mirror.baidubce.com"  ]}EOFsystemctl start dockerdocker info 

下載 docker quick start 文件到本地

git clone https://github.com/ctripcorp/apollo.git

啟動 Apollo 配置中心

cd apollo/scripts/docker-quick-start/docker-compose up

報錯1:

ERROR: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on 223.6.6.6:53: server misbehaving

修改 dns ,不知道為什么 阿里的DNS 解析有問題,修改如下:

cat /etc/resolv.conf# Generated by NetworkManagernameserver 223.5.5.5nameserver 223.6.6.6sed -i 's@223.5.5.5@114.114.114.114@g' /etc/resolv.confcat /etc/resolv.conf# Generated by NetworkManagernameserver 114.114.114.114nameserver 223.6.6.6

出現如下信息,表示啟動成功。

image

查看本地端口:

# netstat -ntplu | egrep dockertcp        0  0 0.0.0.0:8080   0.0.0.0:*   LISTEN  3734/docker-proxy   tcp        0  0 0.0.0.0:8090   0.0.0.0:*   LISTEN  3710/docker-proxy   tcp        0  0 0.0.0.0:13306  0.0.0.0:*   LISTEN  3580/docker-proxy   tcp        0  0 0.0.0.0:8070   0.0.0.0:*   LISTEN  3754/docker-proxy   tcp6       0  0 :::8080        :::*        LISTEN  3740/docker-proxy   tcp6       0  0 :::8090        :::*        LISTEN  3719/docker-proxy   tcp6       0  0 :::13306       :::*        LISTEN  3586/docker-proxy   tcp6       0  0 :::8070        :::*        LISTEN  3761/docker-proxy

瀏覽器訪問本機 8070 端口即可。

連接數據庫的方法如下:

# 注意:這里必須寫 IP 地址,不能為 localhostmysql -uroot -p -h 127.0.0.1 -P 13306 # 密碼為空,直接回車

image



k8s+Apollo


主機規划

(網絡環境因素,主機配置雙網卡)

IP 主機用途
192.168.1.201/192.168.137.201 k8s-master
192.168.1.202/192.168.137.202 k8s-node1
192.168.1.203/192.168.137.203 k8s-node2
192.168.1.204/192.168.137.204 harbor倉庫
192.168.1.205/192.168.137.205 apollo-MySQL


部署k8s


k8s v1.8.6 離線部署:https://www.cnblogs.com/hukey/category/1858851.html


首先,部署 k8s+apollo 首先得有 k8s 環境。按照上面的文檔三台主機搭建 k8s 集群,搭建成功如下:

image-20210714100032953




部署Harbor倉庫


harbor 部署:https://www.cnblogs.com/hukey/p/14113396.html


部署好之后界面:


image-20210714100526701




部署Apollo到K8S



創建數據庫並導入數據


首先,需要為 apollo 創建數據庫,關系型數據庫最好的方式還是直接運行在物理機上。


  1. 安裝並配置數據庫

apollo-mysql 對應主機:192.168.1.201

[root@apollo-mysql(192.168.1.205) ~]#yum install -y mysql-server mysql
[root@apollo-mysql(192.168.1.205) ~]#systemctl start mysqld
[root@apollo-mysql(192.168.1.205) ~]#egrep -ri password /var/log/mysqld.log 
2021-07-13T03:04:01.331079Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: BYLmmLR29q&!

--- 通過初始化密碼連接mysql ---
[root@apollo-mysql(192.168.1.205) ~]#mysql -uroot -p'BYLmmLR29q&!'
mysql> alter user user() identified by 'mysql@123.COM';
mysql> flush privileges;

--- 修改完初始密碼后,用修改后的密碼登錄 ---
[root@apollo-mysql(192.168.1.205) ~]#mysql -uroot -pmysql@123.COM   
mysql> create user 'root'@'%' identified by 'mysql@123.COM';  // 創建用戶
mysql> grant all privileges on *.* to 'root'@'%';	// 賦予所有權限
mysql> flush privileges;
mysql> exit;

  1. 導入apollo 數據
root@apollo-mysql ~# unzip k8s-apollo.zip
root@apollo-mysql ~# cd k8s-apollo/db/config-db-prod/
root@apollo-mysql ~/k/d/config-db-prod# mysql -uroot -p'mysql@123.COM' < apolloconfigdb.sql
root@apollo-mysql ~/k/d/config-db-prod# cd ../portal-db/
root@apollo-mysql ~/k/d/portal-db# mysql -uroot -p'mysql@123.COM' < apolloportaldb.sql

--- 確認導入數據 ---
root@apollo-mysql ~/k/d/config-db-prod# mysql -uroot -p'mysql@123.COM'
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| ApolloPortalDB     |
| ProdApolloConfigDB |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)


生成鏡像並推送到 harbor倉庫


  1. 首先在 harbor 中新建一個倉庫

image-20210714102153889



  1. 上傳鏡像到倉庫

本步驟在 k8s-master 中操作

root@master ~#unzip k8s-apollo.zip  // 解壓上面從百度雲盤下載的包
root@master ~# cd k8s-apollo/k8s-apollo-images-v1.8.1/
root@master ~/k/k8s-apollo-images-v1.8.1# ls
k8s-apollo-docker-images-v1.8.1.tar.gz
root@master ~/k/k8s-apollo-images-v1.8.1# tar xf k8s-apollo-docker-images-v1.8.1.tar.gz
root@master ~/k/k8s-apollo-images-v1.8.1# docker load < k8s-apollo-docker-images-v1.8.1.tar

--- 打 tag 到對應的倉庫 ---
root@master ~/k/k8s-apollo-images-v1.8.1# docker tag alpine-bash:3.8 192.168.1.204:80/alpine-bash:3.8
root@master ~/k/k8s-apollo-images-v1.8.1# docker tag apollo-config-server:v1.8.1 192.168.1.204:80/apollo/apollo-config-server:v1.8.1
root@master ~/k/k8s-apollo-images-v1.8.1# docker tag apollo-admin-server:v1.8.1 192.168.1.204:80/apollo/apollo-admin-server:v1.8.1
root@master ~/k/k8s-apollo-images-v1.8.1# docker tag apollo-portal-server:v1.8.1 192.168.1.204:80/apollo/apollo-portal-server:v1.8.1

--- 上傳到 harbor ---

1. 修改 docker 配置
root@master ~/k/k8s-apollo-images-v1.8.1# vim /etc/docker/daemon.json   // 加入下面這一行
...
"insecure-registries": ["192.168.1.204:80"],
...

root@master ~/k/k8s-apollo-images-v1.8.1# systemctl restart docker  // 修改完成記得 restart docker

2. 登錄harbor 用戶名密碼就是頁面登錄所用的用戶名密碼
root@master ~/k/k8s-apollo-images-v1.8.1# docker login 192.168.1.204:80
Username: admin
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

3. 上傳鏡像到倉庫
root@master ~# docker push 192.168.1.204:80/apollo/alpine-bash:3.8
root@master ~# docker push 192.168.1.204:80/apollo/apollo-config-server
root@master ~# docker push 192.168.1.204:80/apollo/apollo-admin-server
root@master ~# docker push 192.168.1.204:80/apollo/apollo-portal-server

  1. 為每個k8s 節點配置可信倉庫

重點:非常容易遺漏的點,這里不做后面創建Pod是無法下載鏡像的!!!

# vim /etc/docker/daemon.json
...
"insecure-registries": ["192.168.1.204:80"],
...

# systemctl restart docker

通過 yaml 文件構建Pod及服務


本步驟在 k8s-master 中操作

root@master ~# cd k8s-apollo/kubernetes/apollo-env-prod/
root@master ~/k/k/apollo-env-prod# ll -tsh 
total 24K
8.0K -rwxr-xr-x 1 root root 4.1K Jul 14 10:08 service-apollo-admin-server-prod.yaml*	// apollo-admin-server
8.0K -rwxr-xr-x 1 root root 4.1K Jul 14 10:08 service-apollo-config-server-prod.yaml*	// apollo-config-server
4.0K -rwxr-xr-x 1 root root 1.1K Jul 14 10:08 service-mysql-for-apollo-prod-env.yaml*	// 將apollo外部mysql引入k8s內部調用

注意,執行順序如下:

  1. service-mysql-for-apollo-prod-env.yaml
  2. service-apollo-config-server-prod.yaml
  3. service-apollo-admin-server-prod.yaml

在執行之前需要為 apollo 創建專屬的命名空間:

root@master ~# kubectl create ns sre
namespace/sre created

為k8s 添加 harbor 登錄 secrets

在創建 docker-registry時候一定要指定 命名空間,切記!

[root@master(192.168.1.201) ~]#kubectl create secret docker-registry registry-harbor --namespace=sre --docker-server=192.168.1.204:80 --docker-username=admin --docker-password=123456 
secret/registry-harbor created

service-mysql-for-apollo-prod-env.yaml 執行

修改后的 service-mysql-for-apollo-dev-env.yaml 如下:

---
kind: Service
apiVersion: v1
metadata:
  namespace: sre
  name: service-mysql-for-apollo-prod-env
  labels:
    app: service-mysql-for-apollo-prod-env
spec:
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
  type: ClusterIP
  sessionAffinity: None

---
kind: Endpoints
apiVersion: v1
metadata:
  namespace: sre
  name: service-mysql-for-apollo-prod-env
subsets:
  - addresses:
      - ip: 192.168.1.205	// 這里需要修改為對應的apollo-mysql 主機地址
    ports:
      - protocol: TCP
        port: 3306

執行:

root@master ~/k/k/apollo-env-prod# kubectl apply -f service-mysql-for-apollo-prod-env.yaml
service/service-mysql-for-apollo-prod-env created
endpoints/service-mysql-for-apollo-prod-env created

--- 查看並嘗試連接 ---
root@master ~/k/k/apollo-env-prod# kubectl describe svc -n sre
Name:              service-mysql-for-apollo-prod-env
Namespace:         sre
Labels:            app=service-mysql-for-apollo-prod-env
Annotations:       Selector:  <none>
Type:              ClusterIP
IP:                10.111.52.129
Port:              <unset>  3306/TCP
TargetPort:        3306/TCP
Endpoints:         192.168.1.205:3306   // 確認這里是否是mysql主機
Session Affinity:  None
Events:            <none>


root@master ~/k/k/apollo-env-prod# yum install mysql -y
root@master ~/k/k/apollo-env-prod# mysql -uroot -pmysql@123.COM -h 10.111.52.129
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| ProdApolloConfigDB |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

確認mysql service 沒問題。

service-apollo-config-server-prod.yaml 執行

修改后的 service-apollo-config-server-prod.yaml 如下:

kind: ConfigMap
apiVersion: v1
metadata:
  namespace: sre
  name: configmap-apollo-config-server-prod
data:
  application-github.properties: |
    spring.datasource.url = jdbc:mysql://service-mysql-for-apollo-prod-env.sre:3306/ProdApolloConfigDB?characterEncoding=utf8
    spring.datasource.username = root			// 修改為數據庫的用戶名
    spring.datasource.password = mysql@123.COM	// 修改為數據庫的密碼
    eureka.service.url = http://statefulset-apollo-config-server-prod-0.service-apollo-meta-server-prod:8080/eureka/,http://statefulset-apollo-config-server-prod-1.service-apollo-meta-server-prod:8080/eureka/,http://statefulset-apollo-config-server-prod-2.service-apollo-meta-server-prod:8080/eureka/

---
kind: Service
apiVersion: v1
metadata:
  namespace: sre
  name: service-apollo-meta-server-prod
  labels:
    app: service-apollo-meta-server-prod
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  selector:
    app: pod-apollo-config-server-prod
  type: ClusterIP
  clusterIP: None
  sessionAffinity: ClientIP

---
kind: Service
apiVersion: v1
metadata:
  namespace: sre
  name: service-apollo-config-server-prod
  labels:
    app: service-apollo-config-server-prod
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
      nodePort: 30005
  selector:
    app: pod-apollo-config-server-prod
  type: NodePort
  sessionAffinity: ClientIP

---
kind: StatefulSet
apiVersion: apps/v1
metadata:
  namespace: sre
  name: statefulset-apollo-config-server-prod
  labels:
    app: statefulset-apollo-config-server-prod
spec:
  serviceName: service-apollo-meta-server-prod
  replicas: 1
  selector:
    matchLabels:
      app: pod-apollo-config-server-prod
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: pod-apollo-config-server-prod
    spec:
      imagePullSecrets:			// 添加倉庫secret
      - name: registry-harbor	// 添加倉庫secret
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - pod-apollo-config-server-prod
              topologyKey: kubernetes.io/hostname
      
      volumes:
        - name: volume-configmap-apollo-config-server-prod
          configMap:
            name: configmap-apollo-config-server-prod
            items:
              - key: application-github.properties
                path: application-github.properties
      
      containers:
        - image: 192.168.1.194:80/apollo/apollo-config-server:v1.8.1   // 修改為本地倉庫鏡像
          securityContext:
            privileged: true
          imagePullPolicy: IfNotPresent
          name: container-apollo-config-server-prod
          ports:
            - protocol: TCP
              containerPort: 8080

          volumeMounts:
            - name: volume-configmap-apollo-config-server-prod
              mountPath: /apollo-config-server/config/application-github.properties
              subPath: application-github.properties
          env:
            - name: APOLLO_CONFIG_SERVICE_NAME
              value: "service-apollo-config-server-prod.sre"
          
          readinessProbe:
            tcpSocket:
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 5
          
          livenessProbe:
            tcpSocket:
              port: 8080
            initialDelaySeconds: 120
            periodSeconds: 10
          
      dnsPolicy: ClusterFirst
      restartPolicy: Always

執行:

root@master ~/k/k/apollo-env-prod# kubectl apply -f service-apollo-config-server-prod.yaml 
configmap/configmap-apollo-config-server-prod created
service/service-apollo-meta-server-prod created
service/service-apollo-config-server-prod created
statefulset.apps/statefulset-apollo-config-server-prod created

等一段時間查看
root@master ~/k/k/apollo-env-prod# kubectl get pod,svc -n sre
NAME                                          READY   STATUS    RESTARTS   AGE
pod/statefulset-apollo-config-server-prod-0   1/1     Running   0          10m

NAME                                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/service-apollo-config-server-prod   NodePort    10.102.17.193   <none>        8080:30005/TCP   10m
service/service-apollo-meta-server-prod     ClusterIP   None            <none>        8080/TCP         10m
service/service-mysql-for-apollo-prod-env   ClusterIP   10.111.52.129   <none>        3306/TCP         26m


service-apollo-admin-server-prod.yaml 執行

修改后的 service-apollo-admin-server-prod.yaml 如下:

kind: ConfigMap
apiVersion: v1
metadata:
  namespace: sre
  name: configmap-apollo-admin-server-prod
data:
  application-github.properties: |
    spring.datasource.url = jdbc:mysql://service-mysql-for-apollo-prod-env.sre:3306/ProdApolloConfigDB?characterEncoding=utf8
    spring.datasource.username = root				// mysql用戶名
    spring.datasource.password = mysql@123.COM		// mysql密碼
    eureka.service.url = http://statefulset-apollo-config-server-prod-0.service-apollo-meta-server-prod:8080/eureka/,http://statefulset-apollo-config-server-prod-1.service-apollo-meta-server-prod:8080/eureka/,http://statefulset-apollo-config-server-prod-2.service-apollo-meta-server-prod:8080/eureka/

---
kind: Service
apiVersion: v1
metadata:
  namespace: sre
  name: service-apollo-admin-server-prod
  labels:
    app: service-apollo-admin-server-prod
spec:
  ports:
    - protocol: TCP
      port: 8090
      targetPort: 8090
  selector:
    app: pod-apollo-admin-server-prod  
  type: ClusterIP
  sessionAffinity: ClientIP

---
kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: sre
  name: deployment-apollo-admin-server-prod
  labels:
    app: deployment-apollo-admin-server-prod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: pod-apollo-admin-server-prod
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: pod-apollo-admin-server-prod
    spec:
      imagePullSecrets:
      - name: registry-harbor
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - pod-apollo-admin-server-prod
              topologyKey: kubernetes.io/hostname
      
      volumes:
        - name: volume-configmap-apollo-admin-server-prod
          configMap:
            name: configmap-apollo-admin-server-prod
            items:
              - key: application-github.properties
                path: application-github.properties
      
      initContainers:
        - image: 192.168.1.194:80/apollo/alpine-bash:3.8	// 修改鏡像地址
          name: check-service-apollo-config-server-prod
          command: ['bash', '-c', "curl --connect-timeout 2 --max-time 5 --retry 50 --retry-delay 1 --retry-max-time 120 service-apollo-config-server-prod.sre:8080"]
      
      containers:
        - image: 192.168.1.194:80/apollo/apollo-admin-server:v1.8.1	// 修改鏡像地址
          securityContext:
            privileged: true
          imagePullPolicy: IfNotPresent
          name: container-apollo-admin-server-prod
          ports:
            - protocol: TCP
              containerPort: 8090
          
          volumeMounts:
            - name: volume-configmap-apollo-admin-server-prod
              mountPath: /apollo-admin-server/config/application-github.properties
              subPath: application-github.properties
          
          env:
            - name: APOLLO_ADMIN_SERVICE_NAME
              value: "service-apollo-admin-server-prod.sre"
          
          readinessProbe:
            tcpSocket:
              port: 8090
            initialDelaySeconds: 10
            periodSeconds: 5
          
          livenessProbe:
            tcpSocket:
              port: 8090
            initialDelaySeconds: 120
            periodSeconds: 10

      dnsPolicy: ClusterFirst
      restartPolicy: Always

執行:

root@master ~/k/k/apollo-env-prod# kubectl apply -f service-apollo-admin-server-prod.yaml 
configmap/configmap-apollo-admin-server-prod created
service/service-apollo-admin-server-prod created
deployment.apps/deployment-apollo-admin-server-prod created

過2分鍾后查看:
root@master ~/k/k/apollo-env-prod# kubectl get pod,svc -n sre
NAME                                                       READY   STATUS    RESTARTS   AGE
pod/deployment-apollo-admin-server-prod-64c74bdcb9-2d74n   0/1     Running   0          19s
pod/statefulset-apollo-config-server-prod-0                1/1     Running   0          13m

NAME                                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/service-apollo-admin-server-prod    ClusterIP   10.100.33.188   <none>        8090/TCP         20s
service/service-apollo-config-server-prod   NodePort    10.102.17.193   <none>        8080:30005/TCP   13m
service/service-apollo-meta-server-prod     ClusterIP   None            <none>        8080/TCP         13m
service/service-mysql-for-apollo-prod-env   ClusterIP   10.111.52.129   <none>        3306/TCP         30m

最后,再來構建 service-apollo-portal-server.yaml

root@master ~/k/k/apollo-env-prod# cd ../
root@master ~/k/kubernetes# pwd
/root/k8s-apollo/kubernetes
root@master ~/k/kubernetes# ls service-apollo-portal-server.yaml 
service-apollo-portal-server.yaml*

service-apollo-portal-server.yaml 執行

修改后的 service-apollo-portal-server.yaml 如下:

# 為外部 mysql 服務設置 service
kind: Service
apiVersion: v1
metadata:
  namespace: sre
  name: service-mysql-for-portal-server
  labels:
    app: service-mysql-for-portal-server
spec:
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
  type: ClusterIP
  sessionAffinity: None
---
kind: Endpoints
apiVersion: v1
metadata:
  namespace: sre
  name: service-mysql-for-portal-server
subsets:
  - addresses:
      # 更改為你的 mysql addresses, 例如 1.1.1.1
      - ip: 192.168.1.205		// 修改為k8s集群外部訪問mysql的地址
    ports:
      - protocol: TCP
        port: 3306

---
# configmap for apollo-portal-server
kind: ConfigMap
apiVersion: v1
metadata:
  namespace: sre
  name: configmap-apollo-portal-server
data:
  application-github.properties: |
    spring.datasource.url = jdbc:mysql://service-mysql-for-portal-server.sre:3306/ApolloPortalDB?characterEncoding=utf8
    # mysql username
    spring.datasource.username = root	// mysql user
    # mysql password
    spring.datasource.password = mysql@123.COM // mysql password
  apollo-env.properties: |
    dev.meta=http://service-apollo-config-server-dev.sre:8080
    fat.meta=http://service-apollo-config-server-test-alpha.sre:8080
    uat.meta=http://service-apollo-config-server-test-beta.sre:8080
    pro.meta=http://service-apollo-config-server-prod.sre:8080

---
kind: Service
apiVersion: v1
metadata:
  namespace: sre
  name: service-apollo-portal-server
  labels:
    app: service-apollo-portal-server
spec:
  ports:
    - protocol: TCP
      port: 8070
      targetPort: 8070
      nodePort: 30001
  selector:
    app: pod-apollo-portal-server
  type: NodePort
  # portal session 保持
  sessionAffinity: ClientIP

---
kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: sre
  name: deployment-apollo-portal-server
  labels:
    app: deployment-apollo-portal-server
spec:
  # 3 個實例
  replicas: 3
  selector:
    matchLabels:
      app: pod-apollo-portal-server
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: pod-apollo-portal-server
    spec:
      imagePullSecrets:			// 添加 harbor secret
      - name: registry-harbor	// 添加 harbor secret
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - pod-apollo-portal-server
              topologyKey: kubernetes.io/hostname
      
      volumes:
        - name: volume-configmap-apollo-portal-server
          configMap:
            name: configmap-apollo-portal-server
            items:
              - key: application-github.properties
                path: application-github.properties
              - key: apollo-env.properties
                path: apollo-env.properties
      
      initContainers:
        # 確保 admin-service 正常提供服務
        - image: 192.168.1.204:80/apollo/alpine-bash:3.8	// 修改鏡像倉庫
          name: check-service-apollo-admin-server-prod
          command: ['bash', '-c', "curl --connect-timeout 2 --max-time 5 --retry 60 --retry-delay 1 --retry-max-time 120 service-apollo-admin-server-prod.sre:8090"]    
      
      containers:
        - image: 192.168.1.204:80/apollo/apollo-portal-server:v1.8.1   // 修改鏡像倉庫
          securityContext:
            privileged: true
          imagePullPolicy: IfNotPresent
          name: container-apollo-portal-server
          ports:
            - protocol: TCP
              containerPort: 8070
          
          volumeMounts:
            - name: volume-configmap-apollo-portal-server
              mountPath: /apollo-portal-server/config/application-github.properties
              subPath: application-github.properties
            - name: volume-configmap-apollo-portal-server
              mountPath: /apollo-portal-server/config/apollo-env.properties
              subPath: apollo-env.properties
          
          env:
            - name: APOLLO_PORTAL_SERVICE_NAME
              value: "service-apollo-portal-server.sre"
          
          readinessProbe:
            tcpSocket:
              port: 8070
            initialDelaySeconds: 10
            periodSeconds: 5
          
          livenessProbe:
            tcpSocket:
              port: 8070
            # 120s 內, server 未啟動則重啟 container
            initialDelaySeconds: 120
            periodSeconds: 15
          
      dnsPolicy: ClusterFirst
      restartPolicy: Always

執行:

root@master ~/k/kubernetes# kubectl apply -f service-apollo-portal-server.yaml 
service/service-mysql-for-portal-server created
endpoints/service-mysql-for-portal-server created
configmap/configmap-apollo-portal-server created
service/service-apollo-portal-server created
deployment.apps/deployment-apollo-portal-server created

查看:
root@master ~/k/kubernetes# kubectl get pod,svc -n sre
NAME                                                   READY   STATUS    RESTARTS   AGE
deployment-apollo-admin-server-prod-64c74bdcb9-2d74n   1/1     Running   0          26m
deployment-apollo-portal-server-f89ff96db-4bccn        1/1     Running   3          11m
deployment-apollo-portal-server-f89ff96db-hdnh8        1/1     Running   3          11m
deployment-apollo-portal-server-f89ff96db-xg2rs        1/1     Running   3          11m
statefulset-apollo-config-server-prod-0                1/1     Running   0          39m


NAME                                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service-apollo-admin-server-prod    ClusterIP   10.100.33.188   <none>        8090/TCP         26m
service-apollo-config-server-prod   NodePort    10.102.17.193   <none>        8080:30005/TCP   40m
service-apollo-meta-server-prod     ClusterIP   None            <none>        8080/TCP         40m
service-apollo-portal-server        NodePort    10.111.67.76    <none>        8070:30001/TCP   11m
service-mysql-for-apollo-prod-env   ClusterIP   10.111.52.129   <none>        3306/TCP         56m
service-mysql-for-portal-server     ClusterIP   10.107.60.175   <none>        3306/TCP         11m

通過瀏覽器訪問:

http://192.168.10.201:30001/

image-20210714114013615

--- EOF ---


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM