华为云 CCE 快速部署 Apollo 配置中心:单 YAML 一站式实现
在云原生环境中,配置中心是微服务架构的核心组件之一,而 Apollo(阿波罗)作为携程开源的分布式配置中心,以其易用性、高可用性和强大的配置管理能力被广泛采用。本文将详细介绍如何在华为云容器服务 CCE 中,通过单 YAML 文件快速部署 Apollo 配置中心(包含 Config Service、Admin Service、Portal 全组件),适配华为云 RDS 数据库、ELB 负载均衡等特性,实现一站式部署与运维。
一、部署前提说明
在开始部署前,需确保以下环境和资源已准备就绪:
华为云 CCE 集群:已创建 Kubernetes 集群(支持 K8s 1.19 + 版本),并通过 kubectl 客户端成功连接集群(配置参考:华为云 CCE kubectl 配置文档)。
华为云 RDS 数据库:已创建 MySQL 实例(5.7 + 版本),并开放 3306 端口供 CCE 集群访问(配置 RDS 安全组,允许集群节点 IP 段接入)。
Apollo 数据库初始化:在 RDS 中创建两个数据库(apolloconfigdb和apolloportaldb),并执行官方初始化脚本:
apolloconfigdb脚本:点击下载
apolloportaldb脚本:点击下载
镜像访问权限:确保 CCE 集群能拉取 Apollo 官方镜像(或华为云 SWR 私有镜像,需配置镜像拉取密钥)。
二、核心架构与配置解析
Apollo 配置中心由三大核心组件构成,本次部署采用无状态负载(Deployment)模式,通过 ConfigMap 统一管理配置,Service 暴露服务,架构如下:
Config Service:配置服务,内置 Eureka 实现服务注册发现,负责配置的读取与推送。
Admin Service:管理服务,负责配置的修改、发布等操作,依赖 Config Service 注册到 Eureka。
Portal:Web 管理界面,提供可视化配置操作,对接 Admin Service 和 Config Service。
关键配置说明
ConfigMap 统一配置:将数据库连接、服务地址、JVM 参数等抽离到 ConfigMap,避免硬编码,便于维护。
华为云 ELB 适配:Portal 通过公网 ELB 暴露(LoadBalancer类型),供外部访问;Config Service 和 Admin Service 通过内网 ClusterIP 暴露,仅集群内通信。
健康检查配置:通过存活探针(livenessProbe)和就绪探针(readinessProbe)确保服务可用性,异常时自动重启。
资源限制:合理配置 CPU 和内存资源,避免服务占用过多集群资源或因资源不足导致异常。
三、完整部署 YAML 文件
以下是整合后的单 YAML 文件,包含 Apollo 全组件的部署配置,直接替换占位符即可使用:
1. ConfigMap:统一管理Apollo数据库和服务配置
apiVersion: v1
kind: ConfigMap
metadata:
name: apollo-config
namespace: default
data:
MySQL数据库配置(替换为华为云RDS实际信息)
SPRING_DATASOURCE_URL_CONFIG: "jdbc:mysql://云RDS地址>:3306/apolloconfigdb?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai"
SPRING_DATASOURCE_URL_PORTAL: "jdbc:mysql://<华为云RDS地址>:3306/apolloportaldb?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai"
SPRING_DATASOURCE_USERNAME: " SPRING_DATASOURCE_PASSWORD: "
Apollo服务地址配置
EUREKA_INSTANCE_HOSTNAME: "apollo-configservice"
APOLLO_CONFIG_SERVICE_URL: "http://apollo-configservice-service:8080"
APOLLO_ADMIN_SERVICE_URL: "http://apollo-adminservice-service:8090"
JVM参数(根据集群资源调整)
JAVA_OPTS_CONFIG: "-Xms512m -Xmx512m"
JAVA_OPTS_ADMIN: "-Xms512m -Xmx512m"
JAVA_OPTS_PORTAL: "-Xms512m -Xmx512m"
2. Deployment:Apollo ConfigService(内置Eureka)
apiVersion: apps/v1
kind: Deployment
metadata:
name: apollo-configservice
namespace: default
labels:
app: apollo-configservice
spec:
replicas: 1 # 生产环境需多实例部署Eureka集群
selector:
matchLabels:
app: apollo-configservice
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: apollo-configservice
spec:
containers:
- name: apollo-configservice
image: apolloconfig/apollo-configservice:2.0.0 # 稳定版镜像,可替换为最新版
ports: - containerPort: 8080
env: - name: SPRING_DATASOURCE_URL
valueFrom:
configMapKeyRef:
name: apollo-config
key: SPRING_DATASOURCE_URL_CONFIG - name: SPRING_DATASOURCE_USERNAME
valueFrom:
configMapKeyRef:
name: apollo-config
key: SPRING_DATASOURCE_USERNAME - name: SPRING_DATASOURCE_PASSWORD
valueFrom:
configMapKeyRef:
name: apollo-config
key: SPRING_DATASOURCE_PASSWORD - name: EUREKA_INSTANCE_HOSTNAME
valueFrom:
configMapKeyRef:
name: apollo-config
key: EUREKA_INSTANCE_HOSTNAME - name: JAVA_OPTS
valueFrom:
configMapKeyRef:
name: apollo-config
key: JAVA_OPTS_CONFIG
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
imagePullPolicy: IfNotPresent
restartPolicy: Always
3. Service:暴露Apollo ConfigService(集群内访问)
apiVersion: v1
kind: Service
metadata:
name: apollo-configservice-service
namespace: default
annotations:
kubernetes.io/elb.class: inner # 华为云内网ELB标识
spec:
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http
selector:
app: apollo-configservice
4. Deployment:Apollo AdminService
apiVersion: apps/v1
kind: Deployment
metadata:
name: apollo-adminservice
namespace: default
labels:
app: apollo-adminservice
spec:
replicas: 1
selector:
matchLabels:
app: apollo-adminservice
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: apollo-adminservice
spec:
containers:
- name: apollo-adminservice
image: apolloconfig/apollo-adminservice:2.0.0
ports: - containerPort: 8090
env: - name: SPRING_DATASOURCE_URL
valueFrom:
configMapKeyRef:
name: apollo-config
key: SPRING_DATASOURCE_URL_CONFIG - name: SPRING_DATASOURCE_USERNAME
valueFrom:
configMapKeyRef:
name: apollo-config
key: SPRING_DATASOURCE_USERNAME - name: SPRING_DATASOURCE_PASSWORD
valueFrom:
configMapKeyRef:
name: apollo-config
key: SPRING_DATASOURCE_PASSWORD - name: EUREKA_CLIENT_SERVICEURL_DEFAULTZONE
value: "http://apollo-configservice-service:8080/eureka/" # 注册到Eureka - name: JAVA_OPTS
valueFrom:
configMapKeyRef:
name: apollo-config
key: JAVA_OPTS_ADMIN
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 8090
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 8090
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
imagePullPolicy: IfNotPresent
restartPolicy: Always
5. Service:暴露Apollo AdminService(集群内访问)
apiVersion: v1
kind: Service
metadata:
name: apollo-adminservice-service
namespace: default
annotations:
kubernetes.io/elb.class: inner
spec:
type: ClusterIP
ports:
- port: 8090
targetPort: 8090
protocol: TCP
name: http
selector:
app: apollo-adminservice
6. Deployment:Apollo Portal(管理界面)
apiVersion: apps/v1
kind: Deployment
metadata:
name: apollo-portal
namespace: default
labels:
app: apollo-portal
spec:
replicas: 1
selector:
matchLabels:
app: apollo-portal
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: apollo-portal
spec:
containers:
- name: apollo-portal
image: apolloconfig/apollo-portal:2.0.0
ports: - containerPort: 8070
env: - name: SPRING_DATASOURCE_URL
valueFrom:
configMapKeyRef:
name: apollo-config
key: SPRING_DATASOURCE_URL_PORTAL - name: SPRING_DATASOURCE_USERNAME
valueFrom:
configMapKeyRef:
name: apollo-config
key: SPRING_DATASOURCE_USERNAME - name: SPRING_DATASOURCE_PASSWORD
valueFrom:
configMapKeyRef:
name: apollo-config
key: SPRING_DATASOURCE_PASSWORD - name: APOLLO_PORTAL_ENVS
value: "dev" # 支持多环境,如dev,test,prod - name: DEV_META
valueFrom:
configMapKeyRef:
name: apollo-config
key: APOLLO_CONFIG_SERVICE_URL - name: JAVA_OPTS
valueFrom:
configMapKeyRef:
name: apollo-config
key: JAVA_OPTS_PORTAL
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 8070
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 8070
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
imagePullPolicy: IfNotPresent
restartPolicy: Always
7. Service:暴露Apollo Portal(公网访问)
apiVersion: v1
kind: Service
metadata:
name: apollo-portal-service
namespace: default
annotations:
kubernetes.io/elb.class: union # 华为云公网ELB标识
kubernetes.io/elb.name: apollo-portal-elb # 自定义ELB名称(可选)
spec:
type: LoadBalancer
ports:
- port: 8070
targetPort: 8070
protocol: TCP
name: http
selector:
app: apollo-portal
必替换占位符
部署前需将以下参数替换为华为云实际资源信息:
:RDS MySQL 的内网地址(推荐使用内网,降低网络延迟)。
:RDS 数据库的登录账号(需拥有apolloconfigdb和apolloportaldb的读写权限)。
密码>:RDS 数据库的登录密码。
四、部署与验证步骤
-
部署执行
将上述 YAML 文件保存为apollo-full-deploy.yaml,执行以下命令部署:
kubectl apply -f apollo-full-deploy.yaml
-
状态验证
部署完成后,通过以下命令检查资源状态:
查看 ConfigMap、Deployment、Service 状态:
kubectl get configmap,deployment,service -n default | grep apollo
查看 Pod 运行状态(确保所有 Pod 均为Running状态):
kubectl get pods -n default | grep apollo
查看 Portal 的公网访问地址(EXTERNAL-IP列即为 ELB 公网 IP):
kubectl get svc apollo-portal-service -n default
-
访问 Apollo Portal
通过浏览器访问 http://<ELB公网IP>:8070,使用默认账号登录:
用户名:apollo
密码:admin
登录后,在「管理中心」可看到已配置的dev环境,「配置中心」可创建应用并管理配置,说明部署成功。
五、华为云 CCE 特有优化建议
-
使用华为云 SWR 私有镜像
若需使用自定义 Apollo 镜像(如集成插件、修改配置),可将镜像推送到华为云 SWR 私有仓库,在 Deployment 中添加镜像拉取密钥:
spec:
template:
spec:
imagePullSecrets:
- name: swr-secret # 已创建的SWR镜像拉取密钥(参考华为云SWR文档创建)
-
日志持久化(挂载 EVS 存储)
Apollo 默认日志存储在容器内,重启后日志丢失,可挂载华为云 EVS 存储持久化日志:
在Deployment的spec.template.spec中添加volumes和volumeMounts
volumes:
- name: apollo-log-volume
persistentVolumeClaim:
claimName: evs-pvc # 已创建的EVS PVC(需提前创建)
containers: - name: apollo-configservice # 对ConfigService、AdminService、Portal分别配置
volumeMounts:- name: apollo-log-volume
mountPath: /opt/logs # Apollo日志默认存储路径
- name: apollo-log-volume
- 多环境配置扩展
若需支持test、prod等多环境,需:
在 RDS 中为每个环境创建apolloconfigdb(如apolloconfigdb-test)。
在 ConfigMap 中添加对应环境的数据库配置和 Meta 地址:
ConfigMap中新增
SPRING_DATASOURCE_URL_CONFIG_TEST: "jdbc:mysql://3306/apolloconfigdb-test?.."
TEST_META: "http://apollo-configservice-test:8080"
在 Portal 的 env 中添加环境配置:
env:
- name: APOLLO_PORTAL_ENVS
value: "dev,test,prod" - name: TEST_META
valueFrom:
configMapKeyRef:
name: apollo-config
key: TEST_META
- 高可用部署(生产环境必备)
ConfigService 集群:部署多个 ConfigService 实例,配置 Eureka 集群(修改EUREKA_CLIENT_SERVICEURL_DEFAULTZONE为多个节点地址)。
AdminService 集群:多实例部署,通过 Eureka 实现负载均衡。
RDS 高可用:开启华为云 RDS 的主从复制功能,避免数据库单点故障。
六、常见问题排查
Pod 启动失败(数据库连接超时):
检查 RDS 安全组是否放行 CCE 集群节点 IP 的 3306 端口。
验证 ConfigMap 中的数据库地址、用户名、密码是否正确。
Portal 无法访问:
检查apollo-portal-service的EXTERNAL-IP是否已分配(ELB 创建需要几分钟)。
查看 Pod 日志:kubectl logs -n default。
配置发布后不生效:
检查 ConfigService 和 AdminService 是否注册到 Eureka(访问http://>:8080/eureka/apps查看)。
确保应用已正确配置 Apollo Meta 地址(指向 ConfigService 的 Service 地址)。
总结
本文通过单 YAML 文件实现了 Apollo 配置中心在华为云 CCE 的快速部署,整合了 ConfigMap 配置管理、ELB 服务暴露、健康检查等核心特性,同时提供了华为云专属优化方案。该方案无需复杂的分步配置,适合快速落地,同时支持灵活扩展(多环境、高可用、私有镜像等),可满足开发、测试和生产环境的需求。
如果需要进一步定制(如集成华为云监控、配置 HTTPS、自动扩缩容等),可根据实际业务场景调整 YAML 配置,充分利用华为云 CCE 的云原生能力。