#作者:任少近
文章目錄
- 一、背景
- 二、部署etcd
- 1、etcd的svc部署yaml
- 2、Etcd 服務定義說明
- 3、etcd的statefulset部署yaml
- 4、Etcd 狀態集(StatefulSet)配置說明
- 5、查看集群狀態
- 三、部署apisix的deployment部署
- 1、apisix部署yaml文件
- 2、APISIX 部署配置說明
- 3、部署成功如下:
- 四、總結
一、背景
本方案旨在基于 APISIX 與 Etcd 的組合架構,探討如何構建具備高可用能力的 API 網關集群,為后續中間件統一接入與管理提供穩定可靠的基礎設施支持。
二、部署etcd
APISIX 的高效運行離不開可靠的數據存儲支持,官方推薦使用 Etcd 作為其數據存儲后端。為了確保 APISIX 在 Kubernetes 環境下的高可用性,提供以下基于容器化的 Etcd 高可用部署方案。此方案不僅適用于 APISIX 的數據存儲需求,也可為四共項目中的其他中間件提供穩定的數據層支持。
本節將詳細介紹如何在 Kubernetes 中實現 Etcd 的高可用部署,包括配置要點與最佳實踐,以供四共項目中 APISIX 所需的 Etcd 容器化高可用方案參考。
1、etcd的svc部署yaml
1.apiVersion: v1
2.kind: Service
3.metadata:
4. name: apisix-etcd-headless
5. namespace: apisix
6. labels:
7. app.kubernetes.io/instance: apisix-etcd
8. app.kubernetes.io/name: apisix-etcd
9.spec:
10. ports:
11. - name: client
12. port: 2379
13. protocol: TCP
14. targetPort: 2379
15. - name: peer
16. port: 2380
17. protocol: TCP
18. targetPort: 2380
19. clusterIP: None
20. selector:
21. app.kubernetes.io/instance: apisix-etcd
22. app.kubernetes.io/name: apisix-etcd
23. publishNotReadyAddresses: true
24.---
25.apiVersion: v1
26.kind: Service
27.metadata:
28. name: apisix-etcd
29. namespace: apisix
30. labels:
31. app.kubernetes.io/instance: apisix-etcd
32. app.kubernetes.io/name: apisix-etcd
33.spec:
34. ports:
35. - name: client
36. port: 2379
37. protocol: TCP
38. targetPort: 2379
39. - name: peer
40. port: 2380
41. protocol: TCP
42. targetPort: 2380
43. selector:
44. app.kubernetes.io/instance: apisix-etcd
45. app.kubernetes.io/name: apisix-etcd
2、Etcd 服務定義說明
-
Headless Service:apisix-etcd-headless
該 Service 主要用于 Etcd 成員之間的節點發現與集群內部通信。
作用:提供 DNS 解析支持,便于 Etcd 節點之間相互發現和建立集群。
配置特點:
clusterIP: None:表示這是一個 Headless Service,不分配 ClusterIP,直接通過 DNS 返回 Pod IP。
publishNotReadyAddresses: true:即使 Pod 尚未就緒,也允許其地址被發布,確保 Etcd 集群初始化階段能夠正常發現節點。
包含客戶端(2379)和服務端通信端口(2380)的映射。 -
普通 Service:apisix-etcd
該 Service 提供對外訪問 Etcd 的統一入口,供 APISIX 等外部組件使用。
作用:為 APISIX 提供穩定的訪問地址,指向后端 Etcd 集群。
配置特點:
包含標準的 Etcd 客戶端(2379)與節點通信端口(2380);
使用標簽選擇器關聯到 Etcd 實例,實現請求轉發。
這兩個 Service 共同構建了 Etcd 高可用集群所需的網絡通信基礎,一個服務于集群內部成員發現與通信,另一個則作為對外服務接口,支撐 APISIX 對 Etcd 的穩定訪問。
3、etcd的statefulset部署yaml
1.apiVersion: apps/v1
2.kind: StatefulSet
3.metadata:
4. name: apisix-etcd
5. namespace: apisix
6. labels:
7. app.kubernetes.io/instance: apisix-etcd
8. app.kubernetes.io/name: apisix-etcd
9.spec:
10. podManagementPolicy: Parallel
11. replicas: 3
12. serviceName: apisix-etcd-headless
13. selector:
14. matchLabels:
15. app.kubernetes.io/instance: apisix-etcd
16. app.kubernetes.io/name: apisix-etcd
17. template:
18. metadata:
19. labels:
20. app.kubernetes.io/instance: apisix-etcd
21. app.kubernetes.io/name: apisix-etcd
22. spec:
23. affinity:
24. podAntiAffinity:
25. preferredDuringSchedulingIgnoredDuringExecution:
26. - podAffinityTerm:
27. labelSelector:
28. matchLabels:
29. app.kubernetes.io/instance: apisix-etcd
30. app.kubernetes.io/name: apisix-etcd
31. topologyKey: kubernetes.io/hostname
32. weight: 1
33. containers:
34. - name: apisix-etcd-app
35. image: bitnami/etcd:3.5.4
36. imagePullPolicy: IfNotPresent
37. ports:
38. - containerPort: 2379
39. name: client
40. protocol: TCP
41. - containerPort: 2380
42. name: peer
43. protocol: TCP
44. env:
45. - name: BITNAMI_DEBUG
46. value: 'false'
47. - name: MY_POD_IP
48. valueFrom:
49. fieldRef:
50. apiVersion: v1
51. fieldPath: status.podIP
52. - name: MY_POD_NAME
53. valueFrom:
54. fieldRef:
55. apiVersion: v1
56. fieldPath: metadata.name
57. - name: MY_STS_NAME
58. value: apisix-etcd
59. - name: ETCDCTL_API
60. value: '3'
61. - name: ETCD_ON_K8S
62. value: 'yes'
63. - name: ETCD_START_FROM_SNAPSHOT
64. value: 'no'
65. - name: ETCD_DISASTER_RECOVERY
66. value: 'no'
67. - name: ETCD_NAME
68. value: $(MY_POD_NAME)
69. - name: ETCD_DATA_DIR
70. value: /bitnami/etcd/data
71. - name: ETCD_LOG_LEVEL
72. value: info
73. - name: ALLOW_NONE_AUTHENTICATION
74. value: 'yes'
75. - name: ETCD_ADVERTISE_CLIENT_URLS
76. value: http://$(MY_POD_NAME).apisix-etcd-headless.apisix.svc.cluster.local:2379
77. - name: ETCD_LISTEN_CLIENT_URLS
78. value: http://0.0.0.0:2379
79. - name: ETCD_INITIAL_ADVERTISE_PEER_URLS
80. value: http://$(MY_POD_NAME).apisix-etcd-headless.apisix.svc.cluster.local:2380
81. - name: ETCD_LISTEN_PEER_URLS
82. value: http://0.0.0.0:2380
83. - name: ETCD_INITIAL_CLUSTER_TOKEN
84. value: apisix-etcd-cluster-k8s
85. - name: ETCD_INITIAL_CLUSTER_STATE
86. value: new
87. - name: ETCD_INITIAL_CLUSTER
88. value: apisix-etcd-0=http://apisix-etcd-0.apisix-etcd-headless.apisix.svc.cluster.local:2380,apisix-etcd-1=http://apisix-etcd-1.apisix-etcd-headless.apisix.svc.cluster.local:2380,apisix-etcd-2=http://apisix-etcd-2.apisix-etcd-headless.apisix.svc.cluster.local:2380
89. - name: ETCD_CLUSTER_DOMAIN
90. value: apisix-etcd-headless.apisix.svc.cluster.local
91. volumeMounts:
92. - name: data
93. mountPath: /bitnami/etcd
94. lifecycle:
95. preStop:
96. exec:
97. command:
98. - /opt/bitnami/scripts/etcd/prestop.sh
99. livenessProbe:
100. exec:
101. command:
102. - /opt/bitnami/scripts/etcd/healthcheck.sh
103. initialDelaySeconds: 60
104. timeoutSeconds: 5
105. periodSeconds: 30
106. successThreshold: 1
107. failureThreshold: 5
108. readinessProbe:
109. exec:
110. command:
111. - /opt/bitnami/scripts/etcd/healthcheck.sh
112. initialDelaySeconds: 60
113. timeoutSeconds: 5
114. periodSeconds: 10
115. successThreshold: 1
116. failureThreshold: 5
117. securityContext:
118. fsGroup: 1001
119. volumeClaimTemplates:
120. - metadata:
121. name: data
122. spec:
123. accessModes:
124. - ReadWriteOnce
125. storageClassName: nfs-client
126. resources:
127. requests:
128. storage: 1Gi
4、Etcd 狀態集(StatefulSet)配置說明
為了在 Kubernetes 中部署高可用的 Etcd 集群,需使用 StatefulSet 控制器來管理 Etcd Pod。與無狀態應用不同,Etcd 作為分布式一致性存儲系統,要求每個節點具有穩定的網絡標識和持久化存儲。
-
基本定義
名稱:apisix-etcd
命名空間:apisix
副本數(replicas):3,表示部署一個三節點的 Etcd 高可用集群
關聯服務(serviceName):apisix-etcd-headless,通過 Headless Service 實現 Pod 的 DNS 解析與發現
標簽選擇器(selector):匹配標簽 app.kubernetes.io/name: apisix-etcd 和 app.kubernetes.io/instance: apisix-etcd -
Pod 管理策略
podManagementPolicy: Parallel
表示所有 Pod 可并行啟動或終止,提升部署效率(默認為 OrderedReady) -
反親和策略(Affinity)
podAntiAffinity
使用 preferredDuringSchedulingIgnoredDuringExecution 設置軟反親和規則:
同一宿主機上盡量避免調度多個 Etcd Pod;
提升集群容災能力,防止單節點故障影響整個 Etcd 集群。 -
容器配置
鏡像:bitnami/etcd:3.5.4
端口映射:
2379: 客戶端通信端口(client)
2380: 節點間通信端口(peer) -
探針配置(Probe)
livenessProbe(存活探針)
檢查腳本:/opt/bitnami/scripts/etcd/healthcheck.sh
初始延遲:60 秒
超時時間:5 秒
檢查周期:30 秒
失敗閾值:5 次失敗后重啟容器
readinessProbe(就緒探針)
檢查方式相同,但更頻繁地檢查以確保流量只轉發到健康節點
檢查周期:10 秒 -
生命周期鉤子(Lifecycle)
preStop
在容器停止前執行 /opt/bitnami/scripts/etcd/prestop.sh 腳本,進行優雅關閉,避免數據丟失或集群異常。 -
安全上下文(Security Context)
fsGroup: 1001
設置文件系統組 ID,確保容器對掛載卷有正確讀寫權限。 -
持久化存儲(Volume Claim Templates)
模板名稱:data
訪問模式:ReadWriteOnce,即每個 PVC 只能被一個節點掛載
存儲類:nfs-client,使用 NFS 作為共享存儲方案
存儲容量請求:每個 Pod 請求 1Gi 存儲空間
5、查看集群狀態
三、部署apisix的deployment部署
APISIX 作為一個動態、實時、高性能的 API 網關,為用戶提供了一系列強大的功能,如負載均衡、動態路由、限流限速、身份驗證等,極大地簡化了 API 的管理和保護工作。為了確保 APISIX 能夠在 Kubernetes 環境中實現高效、穩定運行,提供以下基于容器化的高可用部署方案。
1、apisix部署yaml文件
為了在 Kubernetes 環境下實現 APISIX 的高可用部署,需通過 ConfigMap、Deployment 和 Service 三類資源對象進行定義和管理。以下將逐一說明其作用與關鍵配置項。
1.apiVersion: v1
2.kind: ConfigMap
3.metadata:
4. name: apisix-conf
5. namespace: apisix
6. labels:
7. app: apisix
8.data:
9. config.yaml: |
10. etcd:
11. host:
12. - "http://apisix-etcd-0.apisix-etcd-headless.apisix.svc.cluster.local:2379"
13. - "http://apisix-etcd-1.apisix-etcd-headless.apisix.svc.cluster.local:2379"
14. - "http://apisix-etcd-2.apisix-etcd-headless.apisix.svc.cluster.local:2379"
15. prefix: "/apisix"
16. deployment:
17. role: data_plane
18. role_data_plane:
19. config_provider: etcd
20.---
21.apiVersion: apps/v1
22.kind: Deployment
23.metadata:
24. name: apisix
25. namespace: apisix
26. labels:
27. app: apisix
28.spec:
29. replicas: 3
30. selector:
31. matchLabels:
32. app: apisix
33. template:
34. metadata:
35. labels:
36. app: apisix
37. spec:
38. containers:
39. - name: apisix
40. image: registry.cn-hangzhou.aliyuncs.com/ali_cloud_images/apisix:latest
41. imagePullPolicy: IfNotPresent
42. env:
43. - name: APISIX_STAND_ALONE
44. value: "false" # 若使用 standalone 模式,改為 "true"
45. command: ["/bin/bash", "-c"]
46. args:
47. - |
48. set -eo pipefail
49. exec apisix start -c /usr/local/apisix/conf/config.yaml
50. # - name: APISIX_CONFIG_PATH
51. # value: "/usr/local/apisix/conf/config.yaml"
52. # command: ["/bin/bash", "-c"]
53. # args:
54. # - |
55. # set -eo pipefail
56. # /docker-entrypoint.sh docker-start
57. ports:
58. - containerPort: 9080 # HTTP
59. - containerPort: 9443 # HTTPS
60. - containerPort: 9091 # Prometheus
61. volumeMounts:
62. - name: apisix-conf
63. mountPath: /usr/local/apisix/conf/config.yaml
64. subPath: config.yaml
65. volumes:
66. - name: apisix-conf
67. configMap:
68. name: apisix-conf
69. items:
70. - key: config.yaml
71. path: config.yaml
72.---
73.apiVersion: v1
74.kind: Service
75.metadata:
76. name: apisix-service
77. namespace: apisix
78.spec:
79. type: NodePort
80. selector:
81. app: apisix
82. ports:
83. - name: http
84. port: 9080
85. targetPort: 9080
86. nodePort: 31080
2、APISIX 部署配置說明
- ConfigMap:apisix-conf
該 ConfigMap 定義了 APISIX 的核心配置文件 config.yaml,主要用于指定數據源(Etcd)、部署模式等運行時參數。
主要配置項說明:
87.etcd:
88. host:
89. - "http://apisix-etcd-0.apisix-etcd-headless.apisix.svc.cluster.local:2379"
90. - "http://apisix-etcd-1.apisix-etcd-headless.apisix.svc.cluster.local:2379"
91. - "http://apisix-etcd-2.apisix-etcd-headless.apisix.svc.cluster.local:2379"
92. prefix: "/apisix"
etcd.host:指向 Etcd 集群中的各個節點地址,確保 APISIX 可以連接到 Etcd 并獲取路由、插件等動態配置。
etcd.prefix:APISIX 在 Etcd 中使用的鍵前綴,避免與其他服務沖突。93. deployment:
94. role: data_plane
95. role_data_plane:
96. config_provider: etcd
role: 指定當前部署角色為 data_plane,即數據面網關節點;
config_provider: 表示使用 Etcd 作為配置中心,支持動態更新。
- Deployment:apisix
該 Deployment 控制器負責部署多個 APISIX 實例,確保其穩定運行并具備高可用性。
replicas: 設置副本數為 3,提升服務可用性和負載處理能力。
97. selector:
98. matchLabels:
99. app: apisix
100. template:
101. metadata:
102. labels:
103. app: apisix
通過標簽 app: apisix 匹配 Pod,用于后續 Service 路由轉發。
104. - name: APISIX_STAND_ALONE
105. value: "false" # 若使用 standalone 模式,改為 "true"
設置 APISIX 不使用 Standalone 模式(即非文件配置模式),而是通過 Etcd 獲取配置。
-
command: ["/bin/bash", "-c"]
-
args:
-
- |
-
set -eo pipefail
-
exec apisix start -c /usr/local/apisix/conf/config.yaml
自定義啟動命令,顯式指定加載掛載的 config.yaml 文件;
保證容器啟動時正確讀取自定義配置。
111. volumeMounts:
112. - name: apisix-conf
113. mountPath: /usr/local/apisix/conf/config.yaml
114. subPath: config.yaml
115. volumes:
116. - name: apisix-conf
117. configMap:
118. name: apisix-conf
將前面定義的 ConfigMap 掛載為 /usr/local/apisix/conf/config.yaml,實現配置注入;
使用 subPath 保證只掛載單個文件,不覆蓋整個目錄。
- Service:apisix-service
該 Service 提供對外訪問入口,允許外部流量訪問 APISIX 網關服務。
3、部署成功如下:
四、總結
以上資源配置完成了 APISIX 在 Kubernetes 環境下的高可用部署,具備以下特點:
**高可用性:**通過多副本部署結合 Kubernetes 的自動重啟、調度機制,保障服務持續可用;
**動態配置:**依賴 Etcd 提供實時配置同步能力,無需重啟即可生效變更;
**標準化部署:**通過 ConfigMap 統一管理配置,提升可維護性;
**可擴展性強:**可根據業務需求輕松擴展副本數量或接入 Ingress、監控系統等。