1919package apigateway
2020
2121import (
22+ "context"
2223 "fmt"
2324 "net/http"
2425 "strings"
@@ -38,6 +39,56 @@ import (
3839 "k8s.io/apimachinery/pkg/util/intstr"
3940)
4041
42+ // getNodeIPs 获取集群节点的IP地址列表
43+ func getNodeIPs (k8sComponent * k8s.Component ) ([]string , error ) {
44+ nodeList , err := k8sComponent .Clientset .CoreV1 ().Nodes ().List (context .TODO (), v1.ListOptions {})
45+ if err != nil {
46+ return nil , err
47+ }
48+
49+ var nodeIPs []string
50+ for _ , node := range nodeList .Items {
51+ // 优先使用外网IP,如果没有则使用内网IP
52+ var nodeIP string
53+ for _ , address := range node .Status .Addresses {
54+ if address .Type == corev1 .NodeExternalIP && address .Address != "" {
55+ nodeIP = address .Address
56+ break
57+ }
58+ }
59+ if nodeIP == "" {
60+ for _ , address := range node .Status .Addresses {
61+ if address .Type == corev1 .NodeInternalIP && address .Address != "" {
62+ nodeIP = address .Address
63+ break
64+ }
65+ }
66+ }
67+ if nodeIP != "" {
68+ nodeIPs = append (nodeIPs , nodeIP )
69+ }
70+ }
71+ return nodeIPs , nil
72+ }
73+
74+ // generateAccessURLs 生成访问地址列表
75+ func generateAccessURLs (nodeIPs []string , ports []model.LoadBalancerPort ) []string {
76+ var accessURLs []string
77+ for _ , nodeIP := range nodeIPs {
78+ for _ , port := range ports {
79+ if port .NodePort > 0 {
80+ protocol := "http"
81+ if strings .ToUpper (port .Protocol ) == "UDP" {
82+ protocol = "udp"
83+ }
84+ url := fmt .Sprintf ("%s://%s:%d" , protocol , nodeIP , port .NodePort )
85+ accessURLs = append (accessURLs , url )
86+ }
87+ }
88+ }
89+ return accessURLs
90+ }
91+
4192// CreateLoadBalancer 创建LoadBalancer服务
4293func (g Struct ) CreateLoadBalancer (w http.ResponseWriter , r * http.Request ) {
4394 tenant := r .Context ().Value (ctxutil .ContextKey ("tenant" )).(* dbmodel.Tenants )
@@ -117,12 +168,12 @@ func (g Struct) CreateLoadBalancer(w http.ResponseWriter, r *http.Request) {
117168 labels ["service_id" ] = serviceID
118169 }
119170 labels ["service_alias" ] = createLBReq .ServiceName
120- // 记录端口信息(多个端口用逗号分隔 )
121- var ports []string
171+ // 记录端口信息(多个端口用下划线分隔,符合K8s标签规范 )
172+ var portStrings []string
122173 for _ , port := range createLBReq .Ports {
123- ports = append (ports , fmt .Sprintf ("%d" , port .Port ))
174+ portStrings = append (portStrings , fmt .Sprintf ("%d" , port .Port ))
124175 }
125- labels ["ports" ] = strings .Join (ports , ", " )
176+ labels ["ports" ] = strings .Join (portStrings , "_ " )
126177
127178 // 创建注解
128179 annotations := make (map [string ]string )
@@ -149,13 +200,39 @@ func (g Struct) CreateLoadBalancer(w http.ResponseWriter, r *http.Request) {
149200 return
150201 }
151202
203+ // 转换端口信息,包含NodePort
204+ var responsePorts []model.LoadBalancerPort
205+ for _ , port := range createdService .Spec .Ports {
206+ responsePorts = append (responsePorts , model.LoadBalancerPort {
207+ Port : int (port .Port ),
208+ TargetPort : port .TargetPort .IntValue (),
209+ Protocol : string (port .Protocol ),
210+ Name : port .Name ,
211+ NodePort : port .NodePort ,
212+ })
213+ }
214+
215+ // 获取节点IP列表
216+ nodeIPs , err := getNodeIPs (k8s .Default ())
217+ if err != nil {
218+ logrus .Warnf ("get node IPs error %s" , err .Error ())
219+ // 不影响主要功能,继续执行
220+ }
221+
222+ // 生成访问地址
223+ var accessURLs []string
224+ if len (nodeIPs ) > 0 {
225+ accessURLs = generateAccessURLs (nodeIPs , responsePorts )
226+ }
227+
152228 // 构造响应
153229 response := & model.LoadBalancerResponse {
154230 Name : createdService .Name ,
155231 Namespace : createdService .Namespace ,
156232 ServiceName : createLBReq .ServiceName ,
157- Ports : createLBReq . Ports ,
233+ Ports : responsePorts ,
158234 ExternalIPs : createdService .Spec .ExternalIPs ,
235+ AccessURLs : accessURLs ,
159236 Annotations : createdService .Annotations ,
160237 Status : "Creating" ,
161238 CreatedAt : createdService .CreationTimestamp .Format (time .RFC3339 ),
@@ -208,29 +285,43 @@ func (g Struct) GetLoadBalancer(w http.ResponseWriter, r *http.Request) {
208285 return
209286 }
210287
288+ // 获取节点IP列表(只获取一次,避免重复调用)
289+ nodeIPs , err := getNodeIPs (k8s .Default ())
290+ if err != nil {
291+ logrus .Warnf ("get node IPs error %s" , err .Error ())
292+ }
293+
211294 var responses []* model.LoadBalancerResponse
212295 for _ , service := range list .Items {
213296 if service .Spec .Type != corev1 .ServiceTypeLoadBalancer {
214297 continue
215298 }
216299
217- // 转换端口信息
218- var ports []model.LoadBalancerPort
300+ // 转换端口信息,包含NodePort
301+ var servicePorts []model.LoadBalancerPort
219302 for _ , port := range service .Spec .Ports {
220- ports = append (ports , model.LoadBalancerPort {
303+ servicePorts = append (servicePorts , model.LoadBalancerPort {
221304 Port : int (port .Port ),
222305 TargetPort : port .TargetPort .IntValue (),
223306 Protocol : string (port .Protocol ),
224307 Name : port .Name ,
308+ NodePort : port .NodePort ,
225309 })
226310 }
227311
312+ // 生成访问地址
313+ var accessURLs []string
314+ if len (nodeIPs ) > 0 {
315+ accessURLs = generateAccessURLs (nodeIPs , servicePorts )
316+ }
317+
228318 response := & model.LoadBalancerResponse {
229319 Name : service .Name ,
230320 Namespace : service .Namespace ,
231321 ServiceName : service .Labels ["service_alias" ],
232- Ports : ports ,
322+ Ports : servicePorts ,
233323 ExternalIPs : service .Spec .ExternalIPs ,
324+ AccessURLs : accessURLs ,
234325 Annotations : service .Annotations ,
235326 Status : "Creating" ,
236327 CreatedAt : service .CreationTimestamp .Format (time .RFC3339 ),
@@ -384,12 +475,12 @@ func (g Struct) UpdateLoadBalancer(w http.ResponseWriter, r *http.Request) {
384475 }
385476 service .Spec .Ports = servicePorts
386477
387- // 更新标签中的端口信息
388- var ports []string
478+ // 更新标签中的端口信息(多个端口用下划线分隔,符合K8s标签规范)
479+ var updatePortStrings []string
389480 for _ , port := range updateLBReq .Ports {
390- ports = append (ports , fmt .Sprintf ("%d" , port .Port ))
481+ updatePortStrings = append (updatePortStrings , fmt .Sprintf ("%d" , port .Port ))
391482 }
392- service .Labels ["ports" ] = strings .Join (ports , ", " )
483+ service .Labels ["ports" ] = strings .Join (updatePortStrings , "_ " )
393484 }
394485
395486 // 更新注解
@@ -410,24 +501,38 @@ func (g Struct) UpdateLoadBalancer(w http.ResponseWriter, r *http.Request) {
410501 return
411502 }
412503
413- // 转换端口信息
414- var ports []model.LoadBalancerPort
504+ // 转换端口信息,包含NodePort
505+ var updatedPorts []model.LoadBalancerPort
415506 for _ , port := range updatedService .Spec .Ports {
416- ports = append (ports , model.LoadBalancerPort {
507+ updatedPorts = append (updatedPorts , model.LoadBalancerPort {
417508 Port : int (port .Port ),
418509 TargetPort : port .TargetPort .IntValue (),
419510 Protocol : string (port .Protocol ),
420511 Name : port .Name ,
512+ NodePort : port .NodePort ,
421513 })
422514 }
423515
516+ // 获取节点IP列表
517+ nodeIPs , err := getNodeIPs (k8s .Default ())
518+ if err != nil {
519+ logrus .Warnf ("get node IPs error %s" , err .Error ())
520+ }
521+
522+ // 生成访问地址
523+ var accessURLs []string
524+ if len (nodeIPs ) > 0 {
525+ accessURLs = generateAccessURLs (nodeIPs , updatedPorts )
526+ }
527+
424528 // 构造响应
425529 response := & model.LoadBalancerResponse {
426530 Name : updatedService .Name ,
427531 Namespace : updatedService .Namespace ,
428532 ServiceName : updatedService .Labels ["service_alias" ],
429- Ports : ports ,
533+ Ports : updatedPorts ,
430534 ExternalIPs : updatedService .Spec .ExternalIPs ,
535+ AccessURLs : accessURLs ,
431536 Annotations : updatedService .Annotations ,
432537 Status : "Creating" ,
433538 CreatedAt : updatedService .CreationTimestamp .Format (time .RFC3339 ),
0 commit comments