mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 20:50:49 +08:00 
			
		
		
		
	Updated KubeProvider to use pod endpoints instead of service
This commit is contained in:
		@@ -0,0 +1,41 @@
 | 
			
		||||
using HTTPlease;
 | 
			
		||||
using KubeClient;
 | 
			
		||||
using KubeClient.Models;
 | 
			
		||||
using KubeClient.ResourceClients;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Provider.Kubernetes.KubeApiClientExtensions
 | 
			
		||||
{
 | 
			
		||||
    public class EndPointClientV1 : KubeResourceClient
 | 
			
		||||
    {
 | 
			
		||||
        public EndPointClientV1(IKubeApiClient client) : base(client)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<EndpointsV1> Get(string serviceName, string kubeNamespace = null, CancellationToken cancellationToken = default)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(serviceName)) throw new ArgumentNullException(nameof(serviceName));
 | 
			
		||||
 | 
			
		||||
            var response = await Http.GetAsync(
 | 
			
		||||
                Requests.Collection.WithTemplateParameters(new
 | 
			
		||||
                {
 | 
			
		||||
                    Namespace = kubeNamespace ?? KubeClient.DefaultNamespace,
 | 
			
		||||
                    ServiceName = serviceName
 | 
			
		||||
                }),
 | 
			
		||||
                cancellationToken: cancellationToken
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            if (response.IsSuccessStatusCode)
 | 
			
		||||
                return await response.ReadContentAsAsync<EndpointsV1>();
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static class Requests
 | 
			
		||||
        {
 | 
			
		||||
            public static readonly HttpRequest Collection = KubeRequest.Create("api/v1/namespaces/{Namespace}/endpoints/{ServiceName}");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
using KubeClient;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Provider.Kubernetes.KubeApiClientExtensions
 | 
			
		||||
{
 | 
			
		||||
    public static class KubeClientExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static EndPointClientV1 EndPointsV1(this IKubeApiClient kubeClient)
 | 
			
		||||
        {
 | 
			
		||||
            return kubeClient.ResourceClient(client => new EndPointClientV1(client));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,14 +6,15 @@ using Ocelot.Values;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Ocelot.Provider.Kubernetes.KubeApiClientExtensions;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Provider.Kubernetes
 | 
			
		||||
{
 | 
			
		||||
    public class Kube : IServiceDiscoveryProvider
 | 
			
		||||
    {
 | 
			
		||||
        private KubeRegistryConfiguration kubeRegistryConfiguration;
 | 
			
		||||
        private IOcelotLogger logger;
 | 
			
		||||
        private IKubeApiClient kubeApi;
 | 
			
		||||
        private readonly IOcelotLogger logger;
 | 
			
		||||
        private readonly IKubeApiClient kubeApi;
 | 
			
		||||
 | 
			
		||||
        public Kube(KubeRegistryConfiguration kubeRegistryConfiguration, IOcelotLoggerFactory factory, IKubeApiClient kubeApi)
 | 
			
		||||
        {
 | 
			
		||||
@@ -22,14 +23,13 @@ namespace Ocelot.Provider.Kubernetes
 | 
			
		||||
            this.kubeApi = kubeApi;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public async Task<List<Service>> Get()
 | 
			
		||||
        {
 | 
			
		||||
            var service = await kubeApi.ServicesV1().Get(kubeRegistryConfiguration.KeyOfServiceInK8s, kubeRegistryConfiguration.KubeNamespace);
 | 
			
		||||
            var endpoint = await kubeApi.EndPointsV1().Get(kubeRegistryConfiguration.KeyOfServiceInK8s, kubeRegistryConfiguration.KubeNamespace);
 | 
			
		||||
            var services = new List<Service>();
 | 
			
		||||
            if (IsValid(service))
 | 
			
		||||
            if (endpoint != null && endpoint.Subsets.Any())
 | 
			
		||||
            {
 | 
			
		||||
                services.Add(BuildService(service));
 | 
			
		||||
                services.AddRange(BuildServices(endpoint));
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
@@ -38,25 +38,17 @@ namespace Ocelot.Provider.Kubernetes
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool IsValid(ServiceV1 service)
 | 
			
		||||
        private List<Service> BuildServices(EndpointsV1 endpoint)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrEmpty(service.Spec.ClusterIP) || service.Spec.Ports.Count <= 0)
 | 
			
		||||
            var services = new List<Service>();
 | 
			
		||||
 | 
			
		||||
            foreach (var subset in endpoint.Subsets)
 | 
			
		||||
            {
 | 
			
		||||
                return false;
 | 
			
		||||
                services.AddRange(subset.Addresses.Select(address => new Service(endpoint.Metadata.Name,
 | 
			
		||||
                    new ServiceHostAndPort(address.Ip, subset.Ports.First().Port),
 | 
			
		||||
                    endpoint.Metadata.Uid, string.Empty, Enumerable.Empty<string>())));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Service BuildService(ServiceV1 serviceEntry)
 | 
			
		||||
        {
 | 
			
		||||
            var servicePort = serviceEntry.Spec.Ports.FirstOrDefault();
 | 
			
		||||
            return new Service(
 | 
			
		||||
                serviceEntry.Metadata.Name,
 | 
			
		||||
                new ServiceHostAndPort(serviceEntry.Spec.ClusterIP, servicePort.Port),
 | 
			
		||||
                serviceEntry.Metadata.Uid,
 | 
			
		||||
                string.Empty,
 | 
			
		||||
                Enumerable.Empty<string>());
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,8 +28,8 @@
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="KubeClient" Version="2.3.4" />
 | 
			
		||||
    <PackageReference Include="KubeClient.Extensions.DependencyInjection" Version="2.3.4" />
 | 
			
		||||
    <PackageReference Include="KubeClient" Version="2.3.11" />
 | 
			
		||||
    <PackageReference Include="KubeClient.Extensions.DependencyInjection" Version="2.3.11" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user