From 23248b080eff80f2e3d65d8543e90c51aae22efe Mon Sep 17 00:00:00 2001 From: geffzhang Date: Sat, 19 Jan 2019 17:16:24 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E5=86=99k8s=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E4=BE=8B=E5=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- samples/OelotKube/.dockerignore | 9 ++++ .../OelotKube/ApiGateway/ApiGateway.csproj | 21 ++++++++ samples/OelotKube/ApiGateway/Dockerfile | 19 +++++++ samples/OelotKube/ApiGateway/Program.cs | 33 +++++++++++++ .../ApiGateway/Properties/launchSettings.json | 32 ++++++++++++ samples/OelotKube/ApiGateway/Startup.cs | 38 ++++++++++++++ .../ApiGateway/appsettings.Development.json | 9 ++++ samples/OelotKube/ApiGateway/appsettings.json | 8 +++ samples/OelotKube/ApiGateway/ocelot.json | 27 ++++++++++ .../Controllers/ValuesController.cs | 45 +++++++++++++++++ .../OelotKube/DownstreamService/Dockerfile | 19 +++++++ .../DownstreamService.csproj | 15 ++++++ .../OelotKube/DownstreamService/Program.cs | 24 +++++++++ .../Properties/launchSettings.json | 35 +++++++++++++ .../OelotKube/DownstreamService/Startup.cs | 41 ++++++++++++++++ .../appsettings.Development.json | 9 ++++ .../DownstreamService/appsettings.json | 8 +++ samples/OelotKube/OelotKube.sln | 49 +++++++++++++++++++ .../KubernetesProviderFactory.cs | 16 ++++-- 19 files changed, 453 insertions(+), 4 deletions(-) create mode 100644 samples/OelotKube/.dockerignore create mode 100644 samples/OelotKube/ApiGateway/ApiGateway.csproj create mode 100644 samples/OelotKube/ApiGateway/Dockerfile create mode 100644 samples/OelotKube/ApiGateway/Program.cs create mode 100644 samples/OelotKube/ApiGateway/Properties/launchSettings.json create mode 100644 samples/OelotKube/ApiGateway/Startup.cs create mode 100644 samples/OelotKube/ApiGateway/appsettings.Development.json create mode 100644 samples/OelotKube/ApiGateway/appsettings.json create mode 100644 samples/OelotKube/ApiGateway/ocelot.json create mode 100644 samples/OelotKube/DownstreamService/Controllers/ValuesController.cs create mode 100644 samples/OelotKube/DownstreamService/Dockerfile create mode 100644 samples/OelotKube/DownstreamService/DownstreamService.csproj create mode 100644 samples/OelotKube/DownstreamService/Program.cs create mode 100644 samples/OelotKube/DownstreamService/Properties/launchSettings.json create mode 100644 samples/OelotKube/DownstreamService/Startup.cs create mode 100644 samples/OelotKube/DownstreamService/appsettings.Development.json create mode 100644 samples/OelotKube/DownstreamService/appsettings.json create mode 100644 samples/OelotKube/OelotKube.sln diff --git a/samples/OelotKube/.dockerignore b/samples/OelotKube/.dockerignore new file mode 100644 index 00000000..df2e0fe5 --- /dev/null +++ b/samples/OelotKube/.dockerignore @@ -0,0 +1,9 @@ +.dockerignore +.env +.git +.gitignore +.vs +.vscode +*/bin +*/obj +**/.toolstarget \ No newline at end of file diff --git a/samples/OelotKube/ApiGateway/ApiGateway.csproj b/samples/OelotKube/ApiGateway/ApiGateway.csproj new file mode 100644 index 00000000..ab5b5e80 --- /dev/null +++ b/samples/OelotKube/ApiGateway/ApiGateway.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp2.1 + InProcess + Linux + + + + + + + + + + + + + + + diff --git a/samples/OelotKube/ApiGateway/Dockerfile b/samples/OelotKube/ApiGateway/Dockerfile new file mode 100644 index 00000000..5abcd05a --- /dev/null +++ b/samples/OelotKube/ApiGateway/Dockerfile @@ -0,0 +1,19 @@ +FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base +WORKDIR /app +EXPOSE 80 + +FROM microsoft/dotnet:2.2-sdk AS build +WORKDIR /src +COPY ["ApiGateway/ApiGateway.csproj", "ApiGateway/"] +RUN dotnet restore "ApiGateway/ApiGateway.csproj" +COPY . . +WORKDIR "/src/ApiGateway" +RUN dotnet build "ApiGateway.csproj" -c Release -o /app + +FROM build AS publish +RUN dotnet publish "ApiGateway.csproj" -c Release -o /app + +FROM base AS final +WORKDIR /app +COPY --from=publish /app . +ENTRYPOINT ["dotnet", "ApiGateway.dll"] \ No newline at end of file diff --git a/samples/OelotKube/ApiGateway/Program.cs b/samples/OelotKube/ApiGateway/Program.cs new file mode 100644 index 00000000..0b55041c --- /dev/null +++ b/samples/OelotKube/ApiGateway/Program.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Ocelot.DependencyInjection; +using Ocelot.Middleware; +using Ocelot.Provider.Kubernetes; + +namespace ApiGateway +{ + public class Program + { + public static void Main(string[] args) + { + BuildWebHost(args).Run(); + } + + public static IWebHost BuildWebHost(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseUrls("http://localhost:5000") + .ConfigureAppConfiguration((hostingContext, config) => + { + config + .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath) + .AddJsonFile("appsettings.json", true, true) + .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true) + .AddJsonFile("ocelot.json", false, false) + .AddEnvironmentVariables(); + }) + .UseStartup() + .Build(); + } +} + diff --git a/samples/OelotKube/ApiGateway/Properties/launchSettings.json b/samples/OelotKube/ApiGateway/Properties/launchSettings.json new file mode 100644 index 00000000..5315ab2c --- /dev/null +++ b/samples/OelotKube/ApiGateway/Properties/launchSettings.json @@ -0,0 +1,32 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:52363", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "ApiGateway": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:5000" + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://localhost:{ServicePort}" + } + } +} \ No newline at end of file diff --git a/samples/OelotKube/ApiGateway/Startup.cs b/samples/OelotKube/ApiGateway/Startup.cs new file mode 100644 index 00000000..6b7b68f2 --- /dev/null +++ b/samples/OelotKube/ApiGateway/Startup.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Ocelot.DependencyInjection; +using Ocelot.Middleware; +using Ocelot.Provider.Kubernetes; +using Ocelot.Provider.Polly; + +namespace ApiGateway +{ + public class Startup + { + // This method gets called by the runtime. Use this method to add services to the container. + // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 + public void ConfigureServices(IServiceCollection services) + { + services.AddOcelot() + .AddPolly() + .AddKubernetes(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseOcelot().Wait(); + } + } +} diff --git a/samples/OelotKube/ApiGateway/appsettings.Development.json b/samples/OelotKube/ApiGateway/appsettings.Development.json new file mode 100644 index 00000000..e203e940 --- /dev/null +++ b/samples/OelotKube/ApiGateway/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/samples/OelotKube/ApiGateway/appsettings.json b/samples/OelotKube/ApiGateway/appsettings.json new file mode 100644 index 00000000..def9159a --- /dev/null +++ b/samples/OelotKube/ApiGateway/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/samples/OelotKube/ApiGateway/ocelot.json b/samples/OelotKube/ApiGateway/ocelot.json new file mode 100644 index 00000000..7099261c --- /dev/null +++ b/samples/OelotKube/ApiGateway/ocelot.json @@ -0,0 +1,27 @@ +{ + "ReRoutes": [ + { + "DownstreamPathTemplate": "/api/Category", + "DownstreamScheme": "http", + "UpstreamPathTemplate": "/Category", + "ServiceName": "DownstreamService", + "UpstreamHttpMethod": [ "Get" ], + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10000, + "TimeoutValue": 5000 + }, + "FileCacheOptions": { "TtlSeconds": 15 } + } + ], + "GlobalConfiguration": { + "RequestIdKey": "OcRequestId", + "AdministrationPath": "/administration", + "ServiceDiscoveryProvider": { + "Host": "localhost", + "Port": 8001, + "Namesapce": "dev", + "Type": "k8s" + } + } +} diff --git a/samples/OelotKube/DownstreamService/Controllers/ValuesController.cs b/samples/OelotKube/DownstreamService/Controllers/ValuesController.cs new file mode 100644 index 00000000..425cf18d --- /dev/null +++ b/samples/OelotKube/DownstreamService/Controllers/ValuesController.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace DownstreamService.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class ValuesController : ControllerBase + { + // GET api/values + [HttpGet] + public ActionResult> Get() + { + return new string[] { "value1", "value2" }; + } + + // GET api/values/5 + [HttpGet("{id}")] + public ActionResult Get(int id) + { + return "value"; + } + + // POST api/values + [HttpPost] + public void Post([FromBody] string value) + { + } + + // PUT api/values/5 + [HttpPut("{id}")] + public void Put(int id, [FromBody] string value) + { + } + + // DELETE api/values/5 + [HttpDelete("{id}")] + public void Delete(int id) + { + } + } +} diff --git a/samples/OelotKube/DownstreamService/Dockerfile b/samples/OelotKube/DownstreamService/Dockerfile new file mode 100644 index 00000000..baa13993 --- /dev/null +++ b/samples/OelotKube/DownstreamService/Dockerfile @@ -0,0 +1,19 @@ +FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base +WORKDIR /app +EXPOSE 80 + +FROM microsoft/dotnet:2.2-sdk AS build +WORKDIR /src +COPY ["DownstreamService/DownstreamService.csproj", "DownstreamService/"] +RUN dotnet restore "DownstreamService/DownstreamService.csproj" +COPY . . +WORKDIR "/src/DownstreamService" +RUN dotnet build "DownstreamService.csproj" -c Release -o /app + +FROM build AS publish +RUN dotnet publish "DownstreamService.csproj" -c Release -o /app + +FROM base AS final +WORKDIR /app +COPY --from=publish /app . +ENTRYPOINT ["dotnet", "DownstreamService.dll"] \ No newline at end of file diff --git a/samples/OelotKube/DownstreamService/DownstreamService.csproj b/samples/OelotKube/DownstreamService/DownstreamService.csproj new file mode 100644 index 00000000..c32dd048 --- /dev/null +++ b/samples/OelotKube/DownstreamService/DownstreamService.csproj @@ -0,0 +1,15 @@ + + + + netcoreapp2.1 + InProcess + Linux + + + + + + + + + diff --git a/samples/OelotKube/DownstreamService/Program.cs b/samples/OelotKube/DownstreamService/Program.cs new file mode 100644 index 00000000..03e1b8ae --- /dev/null +++ b/samples/OelotKube/DownstreamService/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace DownstreamService +{ + public class Program + { + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + } + + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup(); + } +} diff --git a/samples/OelotKube/DownstreamService/Properties/launchSettings.json b/samples/OelotKube/DownstreamService/Properties/launchSettings.json new file mode 100644 index 00000000..30d6118c --- /dev/null +++ b/samples/OelotKube/DownstreamService/Properties/launchSettings.json @@ -0,0 +1,35 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:56411", + "sslPort": 0 + } + }, + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "api/values", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "DownstreamService": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "api/values", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:5000" + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/api/values" + } + } +} \ No newline at end of file diff --git a/samples/OelotKube/DownstreamService/Startup.cs b/samples/OelotKube/DownstreamService/Startup.cs new file mode 100644 index 00000000..9a927a37 --- /dev/null +++ b/samples/OelotKube/DownstreamService/Startup.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace DownstreamService +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseMvc(); + } + } +} diff --git a/samples/OelotKube/DownstreamService/appsettings.Development.json b/samples/OelotKube/DownstreamService/appsettings.Development.json new file mode 100644 index 00000000..e203e940 --- /dev/null +++ b/samples/OelotKube/DownstreamService/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/samples/OelotKube/DownstreamService/appsettings.json b/samples/OelotKube/DownstreamService/appsettings.json new file mode 100644 index 00000000..def9159a --- /dev/null +++ b/samples/OelotKube/DownstreamService/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/samples/OelotKube/OelotKube.sln b/samples/OelotKube/OelotKube.sln new file mode 100644 index 00000000..ed31dc9d --- /dev/null +++ b/samples/OelotKube/OelotKube.sln @@ -0,0 +1,49 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2048 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApiGateway", "ApiGateway\ApiGateway.csproj", "{E9AFBFD7-EF20-48E5-BB30-5C63C59D7C1C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ocelot", "..\..\src\Ocelot\Ocelot.csproj", "{E8551073-622E-45FA-AD09-038EB8AAFFBC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ocelot.Provider.Kubernetes", "..\..\src\Ocelot.Provider.Kubernetes\Ocelot.Provider.Kubernetes.csproj", "{EF973868-98A6-4864-BF66-65B5A8C123FE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ocelot.Provider.Polly", "..\..\src\Ocelot.Provider.Polly\Ocelot.Provider.Polly.csproj", "{323055CB-BF62-4A31-A619-A4444B633CDB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DownstreamService", "DownstreamService\DownstreamService.csproj", "{86FFAE3C-648F-4CDE-A260-37C8EBFBF4F2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E9AFBFD7-EF20-48E5-BB30-5C63C59D7C1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9AFBFD7-EF20-48E5-BB30-5C63C59D7C1C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9AFBFD7-EF20-48E5-BB30-5C63C59D7C1C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9AFBFD7-EF20-48E5-BB30-5C63C59D7C1C}.Release|Any CPU.Build.0 = Release|Any CPU + {E8551073-622E-45FA-AD09-038EB8AAFFBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E8551073-622E-45FA-AD09-038EB8AAFFBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E8551073-622E-45FA-AD09-038EB8AAFFBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E8551073-622E-45FA-AD09-038EB8AAFFBC}.Release|Any CPU.Build.0 = Release|Any CPU + {EF973868-98A6-4864-BF66-65B5A8C123FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF973868-98A6-4864-BF66-65B5A8C123FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF973868-98A6-4864-BF66-65B5A8C123FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF973868-98A6-4864-BF66-65B5A8C123FE}.Release|Any CPU.Build.0 = Release|Any CPU + {323055CB-BF62-4A31-A619-A4444B633CDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {323055CB-BF62-4A31-A619-A4444B633CDB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {323055CB-BF62-4A31-A619-A4444B633CDB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {323055CB-BF62-4A31-A619-A4444B633CDB}.Release|Any CPU.Build.0 = Release|Any CPU + {86FFAE3C-648F-4CDE-A260-37C8EBFBF4F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86FFAE3C-648F-4CDE-A260-37C8EBFBF4F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86FFAE3C-648F-4CDE-A260-37C8EBFBF4F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86FFAE3C-648F-4CDE-A260-37C8EBFBF4F2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D29790E8-4BA9-4E60-8D7D-327E21320CC9} + EndGlobalSection +EndGlobal diff --git a/src/Ocelot.Provider.Kubernetes/KubernetesProviderFactory.cs b/src/Ocelot.Provider.Kubernetes/KubernetesProviderFactory.cs index 528a9115..074e926d 100644 --- a/src/Ocelot.Provider.Kubernetes/KubernetesProviderFactory.cs +++ b/src/Ocelot.Provider.Kubernetes/KubernetesProviderFactory.cs @@ -11,10 +11,18 @@ namespace Ocelot.Provider.Kubernetes public static ServiceDiscoveryFinderDelegate Get = (provider, config, name) => { var factory = provider.GetService(); - - var kubeClientFactory = provider.GetService(); + if (config.Type?.ToLower() == "k8s") + { + return GetkubeProvider(provider, config, name, factory); + } + return null; + }; - var k8sRegistryConfiguration = new KubeRegistryConfiguration() { + private static ServiceDiscovery.Providers.IServiceDiscoveryProvider GetkubeProvider(IServiceProvider provider, Configuration.ServiceProviderConfiguration config, string name, IOcelotLoggerFactory factory) + { + var kubeClientFactory = provider.GetService(); + var k8sRegistryConfiguration = new KubeRegistryConfiguration() + { ApiEndPoint = new Uri($"http://{config.Host}:{config.Port}"), KeyOfServiceInK8s = name, KubeNamespace = config.Namesapce, @@ -26,6 +34,6 @@ namespace Ocelot.Provider.Kubernetes var k8sServiceDiscoveryProvider = new KubeProvider(k8sRegistryConfiguration, factory, kubeClientFactory); return k8sServiceDiscoveryProvider; - }; + } } }