From 3a2f55fd3a03bab1241c275a04059986dabe99c0 Mon Sep 17 00:00:00 2001 From: Saar Shen Date: Fri, 7 Jun 2019 15:30:41 -0700 Subject: [PATCH] Dev/saars/no ilogger diagnostics docs (#185) * Update the main readme * Update BasicUsage_CLR21_RBAC * Update example of BasicUsage * Add a update version of the self diagnostics * Add an example for the console application * Fix the confused name of listner/observer * Update readme a bit for quick start * Troubleshooting is one word --- README.md | 96 +++++++++++++------ docs/SelfDiagnostics.MD | 68 +++++++++++++ examples/BasicConsoleApp/README.md | 6 ++ .../BasicConsoleAppILogger.csproj | 14 +++ examples/BasicConsoleAppILogger/Program.cs | 55 +++++++++++ examples/BasicConsoleAppILogger/README.md | 23 +++++ examples/BasicUsage/Program.cs | 1 - examples/BasicUsage/README.md | 56 +++++++---- examples/BasicUsage/Startup.cs | 1 + examples/BasicUsage_clr21_RBAC/README.MD | 75 +++++++++------ examples/BasicUsage_clr21_RBAC/app/Dockerfile | 4 +- examples/BasicUsage_clr21_RBAC/app/Program.cs | 1 - examples/BasicUsage_clr21_RBAC/app/Startup.cs | 2 +- examples/BasicUsage_clr21_RBAC/app/app.csproj | 4 +- examples/BasicUsage_clr21_RBAC/k8s/k8s.yaml | 2 +- examples/MultipleIKeys/README.md | 14 ++- examples/ZeroUserCodeLightup/README.md | 28 ++++-- 17 files changed, 353 insertions(+), 97 deletions(-) create mode 100644 docs/SelfDiagnostics.MD create mode 100644 examples/BasicConsoleAppILogger/BasicConsoleAppILogger.csproj create mode 100644 examples/BasicConsoleAppILogger/Program.cs create mode 100644 examples/BasicConsoleAppILogger/README.md diff --git a/README.md b/README.md index 4640c58..586def3 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,75 @@ -Microsoft Application Insights for Kubernetes -== +# Microsoft Application Insights for Kubernetes + This repository has code for Application Insights for Kubernetes, which works on .NET Core applications within the containers, managed by Kubernetes, on Azure Container Service. **Note:** `Microsoft Application Insights for Kubernetes` (this library) is an enhancement to the [Microsoft Application Insights](https://github.com/Microsoft/ApplicationInsights-aspnetcore). You can choose to run **Application Insights** without this library in Kubernetes cluster too. However, when using `Microsoft Application Insights for Kubernetes`, you will see Kubernetes related properties like *Pod-Name, Deployment ...* on all your telemetry entries. Proper values will also be set to make use of the rich features like enabling the Application Map to show the multiple micro services on the same map. -### Continous Integration Status -|Rolling Build | Nightly Build | -|---------------------------------|:-----------------------------| -|![Rolling-Build Status](https://devdiv.visualstudio.com/_apis/public/build/definitions/0bdbc590-a062-4c3f-b0f6-9383f67865ee/5974/badge) | ![Nightly-Build Status](https://devdiv.visualstudio.com/_apis/public/build/definitions/0bdbc590-a062-4c3f-b0f6-9383f67865ee/5976/badge) | +## Continuous Integration Status + +| Rolling Build | Nightly Build | +| --------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------- | +| ![Rolling-Build Status](https://devdiv.visualstudio.com/_apis/public/build/definitions/0bdbc590-a062-4c3f-b0f6-9383f67865ee/5974/badge) | ![Nightly-Build Status](https://devdiv.visualstudio.com/_apis/public/build/definitions/0bdbc590-a062-4c3f-b0f6-9383f67865ee/5976/badge) | ## Get Started + ### Prerequisite + * [Application Insights for ASP.NET Core](https://github.com/Microsoft/ApplicationInsights-aspnetcore) * [Docker Containers](https://www.docker.com/) * [Kubernetes](https://kubernetes.io/) -### Walkthrough -We support **ASP.NET Core** application as well as **.NET Core** application. +### Instrument an ASP.NET Core application -* For **ASP.NET Core** Application: Refer [Getting Started](https://github.com/Microsoft/ApplicationInsights-Kubernetes/wiki/Getting-Started-for-ASP.NET-Core-Applications) for a simple walkthrough. +These are the basic steps to instrument an ASP.NET Core application to enable Application Insights for Kubernetes. You will need to run the application in containers managed by Kubernetes to see the change. -* For **.NET Core** Application: Refer [Getting Started](https://github.com/Microsoft/ApplicationInsights-Kubernetes/wiki/Getting-Started-for-.NET-Core-Applications) for a simple walkthrough. +1. Add reference to **Application Insights SDK** and **Application Insights for Kubernetes**: -* Follow [this example](examples/BasicUsage_clr21_RBAC) for Role-based access control (RBAC) enabled Kubernetes clusters. + ```shell + dotnet add package Microsoft.ApplicationInsights.AspNetCore + dotnet add package Microsoft.ApplicationInsights.Kubernetes + ``` + +1. Enable **Application Insights** and **Application Insights for Kubernetes Enricher** in `Startup.cs`: + + ```csharp + public void ConfigureServices(IServiceCollection services) + { + ... + services.AddApplicationInsightsTelemetry("----Your Application Insights Instrumentation Key ----"); + services.AddApplicationInsightsKubernetesEnricher(); + services.AddMvc(); + ... + } + ``` + +1. Build the application in containers, then deploy the container with Kubernetes. + +**Notes:** Those steps are not considered the best practice to set the instrumentation key for application insights. Refer to [Enable Application Insights server-side telemetry](https://docs.microsoft.com/en-us/azure/azure-monitor/app/asp-net-core#enable-application-insights-server-side-telemetry-without-visual-studio) for various options. Also, consider deploy Kubernetes Secrets to secure it. + +### Walk-through + +Both **ASP.NET Core** and **.NET Core** applications are supported. + +* For **ASP.NET Core** Application: Refer to [Getting Started](https://github.com/Microsoft/ApplicationInsights-Kubernetes/wiki/Getting-Started-for-ASP.NET-Core-Applications) for a simple walk-through. + +* For **.NET Core** Application: Refer to [Getting Started](examples/BasicConsoleAppILogger/README.md) for a simple walk-through. + +* Follow [this example](examples/BasicUsage_clr21_RBAC) for **Role-based access control (RBAC)** enabled Kubernetes clusters. ### Configuration Details -Customize configurations are supported for `v1.0.2+`. There are several ways to customize the settings. For example: +Customize configurations are supported starting with version 1.0.2 of the ApplicationInsights.Kubernetes package. There are several ways to customize the settings. For example: + +1. Using code: -1. By the code: ```csharp services.AddApplicationInsightsKubernetesEnricher(option=> { option.InitializationTimeout = TimeSpan.FromSeconds(15); }); ``` -2. By `appsettings.json`: +2. Using `appsettings.json`: + ```jsonc { "Logging": { @@ -47,40 +81,48 @@ Customize configurations are supported for `v1.0.2+`. There are several ways to } } ``` -3. By environment varialbe: - ``` + +3. Using environment variables: + + ```shell AppInsightsForKubernetes__InitializationTimeout=3.1:12:15.34 ``` All the related configurations have to be put in a section named `AppInsightsForKubernetes`. The supported keys/values are listed below: - | Key | Value/Types | Default Value | Description | - |-----------------------|-------------|---------------|--------------------------------------------------------------------------------------------------------| - | InitializationTimeout | TimeSpan | 00:02:00 | Maximum time to wait for spinning up the container. Accepted format: [d.]hh:mm:ss[.fffffff]. | + | Key | Value/Types | Default Value | Description | + | --------------------- | ----------- | ------------- | -------------------------------------------------------------------------------------------- | + | InitializationTimeout | TimeSpan | 00:02:00 | Maximum time to wait for spinning up the container. Accepted format: [d.]hh:mm:ss[.fffffff]. | -The configuration uses with the conventions in ASP.NET Core. Refer [Configuration in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1) for more information. +The configuration uses the ASP.NET Core conventions. Refer to [Configuration in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1) for more information. + +### Verify the cluster configuration (Linux Container only) -### Verify the cluster configuration Use the [troubleshooting image](https://github.com/Microsoft/ApplicationInsights-Kubernetes/tree/develop/troubleshooting) to verify the cluster is properly configured. ### Learn more + * To build a container for Kubernetes that have Application Insights baked in for the existing applications, please refer the example of [Zero Code light up](https://github.com/Microsoft/ApplicationInsights-Kubernetes/tree/develop/examples/ZeroUserCodeLightup). -* To enable Application Insights for Kubernetes by environement variable instead of code, please refer [Hosting startup for ApplicationInsights.Kubernetes](https://github.com/Microsoft/ApplicationInsights-Kubernetes/wiki/Hosting-startup-for-ApplicationInsights.Kubernetes). +* To enable diagnostic logs when Application Insights for Kubernetes doesn't work as expected, reference [How to enable self diagnostics for ApplicationInsights.Kubernetes](docs/SelfDiagnostics.MD). * Still want more? Read the [Wikis](https://github.com/Microsoft/ApplicationInsights-Kubernetes/wiki). ### Next step + Profile your application for performance improvement using [Application Insights Profiler for Linux](https://github.com/Microsoft/ApplicationInsights-Profiler-AspNetCore). ## Contributing -### Report issues -Please file bug, discussion or any other interesting topics in [issues](https://github.com/Microsoft/ApplicationInsights-Kubernetes/issues) on github. -### Trouble Shooting -When Microsoft.ApplicationInsights.Kubernetes doesn't work properly, you can turn on self-diagnostics to see the traces in Kubernetes' logs. Refer [this wiki page](https://github.com/Microsoft/ApplicationInsights-Kubernetes/wiki/%5BAdvanced%5D-How-to-enable-self-diagnostics-for-ApplicationInsights.Kubernetes) for instructions to turn on trace. +### Report issues + +Please file bug, discussion or any other interesting topics in [issues](https://github.com/Microsoft/ApplicationInsights-Kubernetes/issues) on GitHub. + +### Troubleshooting + +When Microsoft.ApplicationInsights.Kubernetes doesn't work properly, you can turn on self-diagnostics to see the traces in Kubernetes' logs. Refer to [How to enable self diagnostics for ApplicationInsights.Kubernetes](./docs/SelfDiagnostics.md) for instructions. ### Developing -Please refer the [Develop Guide](https://github.com/Microsoft/ApplicationInsights-Kubernetes/wiki/Development-Guide). +Please refer the [Develop Guide](https://github.com/Microsoft/ApplicationInsights-Kubernetes/wiki/Development-Guide). --- This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/docs/SelfDiagnostics.MD b/docs/SelfDiagnostics.MD new file mode 100644 index 0000000..0b581de --- /dev/null +++ b/docs/SelfDiagnostics.MD @@ -0,0 +1,68 @@ +# [Advanced] How to enable self diagnostics for ApplicationInsights.Kubernetes + +## Enable self-diagnostics + +Enabling self-diagnostics helps troubleshoot issues and determine whether the problem is with service code/configuration, or with the `ApplicationInsights.Kubernetes` package itself. + +If problem with ApplicationInsights.Kubernetes package is suspected, please open an [issues](https://github.com/microsoft/ApplicationInsights-Kubernetes/issues) and we will look into it. + +Application Insights for Kubernetes is instrumented with DiagnosticsSource. To see the logs, create a diagnostic source observer that subscribe to `Microsoft.ApplicationInsights.Kubernetes.Debugging.ApplicationInsightsKubernetesDiagnosticSource.Observable`. The observable(DiagnosticSource) will emits logs in different levels. + +To make diagnostic easier, a default observer that outputs logs into the console is provided and and could be enabled like it below before `AddApplicationInsightsKubernetesEnricher` is called: + +```csharp +using Microsoft.ApplicationInsights.Kubernetes.Debugging; +... +var observer = new ApplicationInsightsKubernetesDiagnosticObserver(DiagnosticLogLevel.Trace); +ApplicationInsightsKubernetesDiagnosticSource.Instance.Observable.SubscribeWithAdapter(observer); +``` + +When the observer above is enabled, you will see diagnostic logs like this in the console: + +```shell +... +[Debug] Application Insights Kubernetes injected the service successfully. +[Debug] Initialize Application Insights for Kubernetes telemetry initializer with Options: +{"InitializationTimeout":"00:02:00"} +[Debug] Application Insights for Kubernetes environment initialized. +[Trace] Inject into telemetry configuration: 60695621 +[Information] KubernetesTelemetryInitializer is injected. +... +``` + +Or you can fetch the log by calling kubectl logs [ContainerName]. For example: + +```shell +kubectl logs x-u-service-20450933-b61w2 x-webapi +``` + +A similar log will be output to the terminal. + +## Logging Levels + +There are 5 levels of the events, each is assigned with a number like: + +* Critical - 5 +* Error - 4 +* Warning - 3 +* Information - 2 +* Debug - 1 +* Trace - 0 + +When minimum level is set at the creation of the observer, issues that has a number greater or equal to it will be printed. For example, if the minimum level is set to `Error`(4) like this: + +```csharp +var observer = new ApplicationInsightsKubernetesDiagnosticObserver(DiagnosticLogLevel.Error); // Set the minimum level to Error 4. +``` + +Logs with the level of critical or error will be printed to the console. + +## About the Diagnostic Source + +To find out more about the [DiagnosticSource], refer to [DiagnosticSource Users Guide](https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/DiagnosticSourceUsersGuide.md#diagnosticsource-users-guide). + +If you want to write another diagnostic source observer, here's the basic information: + +The DiagnosticSource used in Application Insights is named `ApplicationInsightsKubernetesDiagnosticSource`. + +There happen to be 5 predefined events, named after the levels - "Critical", "Error", "Warning", "Information", "Debug" and "Trace". diff --git a/examples/BasicConsoleApp/README.md b/examples/BasicConsoleApp/README.md index 5d3b5b1..31c837c 100644 --- a/examples/BasicConsoleApp/README.md +++ b/examples/BasicConsoleApp/README.md @@ -1,5 +1,11 @@ # Enable Application Insights for Kubernetes in .NET Core Console Application +## Deprecated + +This example is deprecated and will not be updated. Please reference [Enable Application Insights for Kubernetes in .NET Core Console Application](../BasicConsoleAppILogger/README.md) for the latest instructions. + +## Description + When running a Console Application inside a Kubernetes managed container, and if you have chosen Application Insights as your telemetry solution, you might want to enrich the telemetry with Kubernetes related information. This is an example of how to do it. _Note: This is an example that does not follow all best practices, including security-related best practices. E.g. Application Insights instrumentation key is not adequately protected (it should be deployed as a secret)._ diff --git a/examples/BasicConsoleAppILogger/BasicConsoleAppILogger.csproj b/examples/BasicConsoleAppILogger/BasicConsoleAppILogger.csproj new file mode 100644 index 0000000..86f3d41 --- /dev/null +++ b/examples/BasicConsoleAppILogger/BasicConsoleAppILogger.csproj @@ -0,0 +1,14 @@ + + + + Exe + netcoreapp2.2 + + + + + + + + + diff --git a/examples/BasicConsoleAppILogger/Program.cs b/examples/BasicConsoleAppILogger/Program.cs new file mode 100644 index 0000000..62a52d2 --- /dev/null +++ b/examples/BasicConsoleAppILogger/Program.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using Microsoft.ApplicationInsights.Channel; +using Microsoft.ApplicationInsights.Extensibility; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace BasicConsoleAppILogger +{ + class Program + { + static void Main(string[] args) + { + // Create the DI container. + IServiceCollection services = new ServiceCollection(); + + // Channel is explicitly configured to do flush on it later. + var channel = new InMemoryChannel(); + services.Configure( + (config) => + { + config.TelemetryChannel = channel; + } + ); + + // Add the logging pipelines to use. We are using Application Insights only here. + services.AddLogging(builder => + { + // Optional: Apply filters to configure LogLevel Trace or above is sent to + // Application Insights for all categories. + builder.AddFilter("", LogLevel.Trace); + builder.AddApplicationInsights("---Your AI instrumentation key---"); + }); + + // Add application insights for Kubernetes. + services.AddApplicationInsightsKubernetesEnricher(); + + // Build ServiceProvider. + IServiceProvider serviceProvider = services.BuildServiceProvider(); + ILogger logger = serviceProvider.GetRequiredService>(); + + // Begin a new scope. This is optional. + using (logger.BeginScope(new Dictionary { { "Method", nameof(Main) } })) + { + logger.LogInformation("Logger is working"); // this will be captured by Application Insights. + } + + // Explicitly call Flush() followed by sleep is required in Console Apps. + // This is to ensure that even if application terminates, telemetry is sent to the back-end. + channel.Flush(); + Thread.Sleep(1000); + } + } +} diff --git a/examples/BasicConsoleAppILogger/README.md b/examples/BasicConsoleAppILogger/README.md new file mode 100644 index 0000000..e24240e --- /dev/null +++ b/examples/BasicConsoleAppILogger/README.md @@ -0,0 +1,23 @@ +# Enable Application Insights for Kubernetes in .NET Core Console Application + +The following code shows a sample console application that's configured to send ILogger traces to Application Insights with Kubernetes enricher. + +* Create a console application + + ```shell + dotnet new console + ``` + +* Add packages + + ```shell + dotnet add package Microsoft.Extensions.DependencyInjection + dotnet add package Microsoft.Extensions.Logging.ApplicationInsights + dotnet add package Microsoft.ApplicationInsights.Kubernetes + ``` + +* Replace the code in [Program.cs](Program.cs). + +## References + +* [ApplicationInsightsLoggerProvider](https://docs.microsoft.com/en-us/azure/azure-monitor/app/ilogger). diff --git a/examples/BasicUsage/Program.cs b/examples/BasicUsage/Program.cs index 7ee78ab..49a8dcd 100644 --- a/examples/BasicUsage/Program.cs +++ b/examples/BasicUsage/Program.cs @@ -19,7 +19,6 @@ namespace BasicUsage public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) - .UseApplicationInsights() .UseStartup() .Build(); } diff --git a/examples/BasicUsage/README.md b/examples/BasicUsage/README.md index e7f3043..164403d 100644 --- a/examples/BasicUsage/README.md +++ b/examples/BasicUsage/README.md @@ -1,52 +1,66 @@ -# Walkthrough -This example walks through the necessary steps to deploy an ASP.NET Core 2.0 MVC application to Kubernets cluster with `Application Insights for Kubernetes` on. +# Walk-through -_Note: This is a simple example that does not follow all best practices, including security-related best practices. E.g. Application Insights instrumentation key is not adequately protected (it should be deployed as a secret)_ +## Deprecated -* Let's start by creating an ASP.NET Core MVC applicaiton: -``` +This example is deprecated and won't be updated anymore. Please refer the [walk-through for ASP.NET Core 2.1](../BasicUsage_clr21_RBAC/Readme.md) instead. + +## Description + +This example walks through the necessary steps to deploy an ASP.NET Core 2.0 MVC application to Kubernetes cluster with `Application Insights for Kubernetes` on. + +_Note:_ This is a simple example that does not follow all best practices, including security-related best practices. E.g. Application Insights instrumentation key is not adequately protected (it should be deployed as a secret). + +* Let's start by creating an ASP.NET Core MVC application: + +```shell dotnet new mvc ``` + * Add the NuGet Packages: -``` + +```shell dotnet add package Microsoft.ApplicationInsights.AspNetCore dotnet add package Microsoft.ApplicationInsights.Kubernetes ``` * Edit the project file, add the following property: -``` + +```xml false ``` + Reference [ASP.NET Core implicit store](https://docs.microsoft.com/en-us/dotnet/core/deploying/runtime-store#aspnet-core-implicit-store) for more details with regarding this property. -* Enable Application Insights in Program.cs by calling UseApplicaitonInsights() on WebHostBuilder: -``` -public static IWebHost BuildWebHost(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseApplicationInsights() - .UseStartup() - .Build(); -``` * Enable Application Insights for Kubernetes in Startup.cs: -``` + +```csharp public void ConfigureServices(IServiceCollection services) { + ... + services.AddApplicationInsightsTelemetry(); services.AddApplicationInsightsKubernetesEnricher(); - services.AddMvc(); + ... } ``` + * Optionally, update the base images: -``` + +```shell docker pull microsoft/aspnetcore-build:2.0 docker pull microsoft/aspnetcore:2.0 ``` + * Add [Dockerfile](Dockerfile) to the project folder. Build the docker container (dockeraccount/aik8sbasic, for example) using [Dockerfile](Dockerfile) and upload it to an image registry. -``` + +```shell docker build . -t dockeraccount/aik8sbasic:latest docker push dockeraccount/aik8sbasic:latest ``` -* Create the Kubernetes spec for the deployment and the service. Referencing [k8s.yaml](k8s.yaml). Please update the variable of `APPINSIGHTS_INSTRUMENTATIONKEY` to your own application insights instrumentation key. + +* Create the Kubernetes spec for the deployment and the service. Referencing [k8s.yaml](k8s.yaml). Please update the variable of `APPINSIGHTS_INSTRUMENTATIONKEY` to your own application insights instrumentation key. + Deploy it: -``` + +```shell kubectl create -f k8s.yaml ``` diff --git a/examples/BasicUsage/Startup.cs b/examples/BasicUsage/Startup.cs index 22702bb..8f7be44 100644 --- a/examples/BasicUsage/Startup.cs +++ b/examples/BasicUsage/Startup.cs @@ -21,6 +21,7 @@ namespace BasicUsage // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { + services.AddApplicationInsightsTelemetry(); services.AddApplicationInsightsKubernetesEnricher(); services.AddMvc(); } diff --git a/examples/BasicUsage_clr21_RBAC/README.MD b/examples/BasicUsage_clr21_RBAC/README.MD index f6a7b0c..677fcd7 100644 --- a/examples/BasicUsage_clr21_RBAC/README.MD +++ b/examples/BasicUsage_clr21_RBAC/README.MD @@ -1,23 +1,28 @@ -# Walkthrough -This example walks through the steps to deploy an ASP.NET Core 2.1 MVC application to a Kubernets cluster with `Application Insights for Kubernetes` on. +# Walk-through + +This example walks through the steps to deploy an ASP.NET Core 2.1 MVC application to a Kubernetes cluster with `Application Insights for Kubernetes` on. The steps also applies for ASP.NET Core 2.2 applications. A simple cluster role sample yaml is also included to describe how to make it work in a Role-based access control(RBAC) enabled clusters. _Tip: [Read this for more information about RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)._ -_Note: This is an example that does not follow all best practices, including security-related best practices. E.g. Application Insights instrumentation key is not adequately protected (it should be deployed as a secret)._ +_Note: This is an example that does NOT follow all best practices, including security-related best practices. E.g. Application Insights instrumentation key is not adequately protected (it should be deployed as a secret)._ ## Prerequisite + * .NETCore SDK 2.1.300 or above * .NET Core SDK is required in this example. Go to [https://dot.net](https://dot.net) to download the latest SDK. Make sure you have `2.1.300` or `above`: - ```bash + + ```shell dotnet --version 2.1.301 ``` + * A Kubernetes Cluster that you can manage with kubectl. - * If you don't have any, an easy way is to go to [Azure AKS](https://docs.microsoft.com/en-us/azure/aks/) to get a managed cluster. Verify that the credential is properly set for kubctl to work: - ```bash + * If you don't have any, an easy way is to go to [Azure AKS](https://docs.microsoft.com/en-us/azure/aks/) to get a managed cluster. Verify that the credential is properly set for kubectl to work: + + ```shell user@user-pc:~$ kubectl get nodes NAME STATUS ROLES AGE VERSION aks-nodepool1-10984277-0 Ready agent 17d v1.9.9 @@ -25,68 +30,80 @@ _Note: This is an example that does not follow all best practices, including sec aks-nodepool1-10984277-2 Ready agent 17d v1.9.9 user@user-pc:~$ ``` + * A container image repository * The image built will be pushed into an image repository. Dockerhub is used in this example. ## Create the project + * Let's start by creating an ASP.NET Core MVC applicaiton: -``` + +```shell dotnet new mvc ``` + * Add the NuGet Packages: -``` + +```shell dotnet add package Microsoft.ApplicationInsights.AspNetCore dotnet add package Microsoft.ApplicationInsights.Kubernetes ``` -* Enable Application Insights in Program.cs by calling UseApplicaitonInsights() on WebHostBuilder: -```csharp -public static IWebHost BuildWebHost(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseApplicationInsights() // Add this line of code - .UseStartup() - .Build(); -``` -* Enable Application Insights for Kubernetes in Startup.cs: +* Enable **Application Insights** and **Application Insights for Kubernetes** in [Startup.cs](app/Startup.cs): + ```csharp public void ConfigureServices(IServiceCollection services) { - services.AddApplicationInsightsKubernetesEnricher(); // Add this line of code - services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); + ... + services.AddApplicationInsightsTelemetry(); // Enables Application Insights + services.AddApplicationInsightsKubernetesEnricher(); // Enables Application Insights for Kubernetes. + ... } ``` ## Prepare the container -* It is always recommended to update the base images: -``` -docker pull microsoft/dotnet:2.1-sdk -docker pull microsoft/dotnet:2.1-aspnetcore-runtime + +* It is optional but recommended to update the base images: + +```shell +docker pull mcr.microsoft.com/dotnet/core/sdk:2.1 +docker pull mcr.microsoft.com/dotnet/core/aspnet:2.1 ``` + * Add [Dockerfile](app/Dockerfile) to the project folder. Build the docker container (dockeraccount/aik8sbasic_rbac, for example) using [Dockerfile](app/Dockerfile) and upload it to an image registry. -``` + +```shell docker build . -t dockeraccount/aik8sbasic_rbac:latest docker push dockeraccount/aik8sbasic_rbac:latest ``` + ## Setup the default Service Account for RBAC enabled cluster + * If the cluster is RBAC enabled, the service account used will need to bind to proper cluster role so that the application can fetch Kubernetes related properties. + In [saRole.yaml](k8s/saRole.yaml), a cluster role named `appinsights-k8s-property-reader` is created and then bind to the default service account. Permissions needed are listed in the resources property. To deploy it, update the value for the `namespace` and then: -``` + +```shell kubectl create -f k8s/saRole.yaml ``` ## Deploy the application -* Create the Kubernetes spec for the deployment and the service. Referencing [k8s.yaml](k8s/k8s.yaml). Please update the variable of `APPINSIGHTS_INSTRUMENTATIONKEY` to your own application insights instrumentation key. + +* Create the Kubernetes spec for the deployment and the service. Referencing [k8s.yaml](k8s/k8s.yaml). Please update the variable of `APPINSIGHTS_INSTRUMENTATIONKEY` to your own application insights instrumentation key. + Deploy it: -``` + +```shell kubectl create -f k8s/k8s.yaml ``` ## Verification -Once properly set up, your telemetry data will all be decorated with Kubernetes properties on it: - +Once properly set up, your telemetry data will all be decorated with Kubernetes properties on it: +![Result](media/Result.png) ## Next step + * [Troubleshoot Application Insights for Kubernetes](https://github.com/Microsoft/ApplicationInsights-Kubernetes/wiki/%5BAdvanced%5D-How-to-enable-self-diagnostics-for-ApplicationInsights.Kubernetes) * [Enable Application Insights Profiler](https://github.com/Microsoft/ApplicationInsights-Profiler-AspNetCore) to optimize the performance for your application. diff --git a/examples/BasicUsage_clr21_RBAC/app/Dockerfile b/examples/BasicUsage_clr21_RBAC/app/Dockerfile index a9d50ef..c4a6d6f 100644 --- a/examples/BasicUsage_clr21_RBAC/app/Dockerfile +++ b/examples/BasicUsage_clr21_RBAC/app/Dockerfile @@ -1,4 +1,4 @@ -FROM microsoft/dotnet:2.1-sdk AS build-env +FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build-env WORKDIR /app # Copy csproj and restore as distinct layers @@ -10,7 +10,7 @@ COPY . ./ RUN dotnet publish -c Release -o out # Build runtime image -FROM microsoft/dotnet:2.1-aspnetcore-runtime +FROM mcr.microsoft.com/dotnet/core/aspnet:2.1 WORKDIR /app COPY --from=build-env /app/out . ENTRYPOINT ["dotnet", "app.dll"] \ No newline at end of file diff --git a/examples/BasicUsage_clr21_RBAC/app/Program.cs b/examples/BasicUsage_clr21_RBAC/app/Program.cs index 5d261a4..f6aaf8f 100644 --- a/examples/BasicUsage_clr21_RBAC/app/Program.cs +++ b/examples/BasicUsage_clr21_RBAC/app/Program.cs @@ -19,7 +19,6 @@ namespace app public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) - .UseApplicationInsights() .UseStartup(); } } diff --git a/examples/BasicUsage_clr21_RBAC/app/Startup.cs b/examples/BasicUsage_clr21_RBAC/app/Startup.cs index e1e2196..26d79f9 100644 --- a/examples/BasicUsage_clr21_RBAC/app/Startup.cs +++ b/examples/BasicUsage_clr21_RBAC/app/Startup.cs @@ -31,7 +31,7 @@ namespace app options.MinimumSameSitePolicy = SameSiteMode.None; }); - + services.AddApplicationInsightsTelemetry(); services.AddApplicationInsightsKubernetesEnricher(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); } diff --git a/examples/BasicUsage_clr21_RBAC/app/app.csproj b/examples/BasicUsage_clr21_RBAC/app/app.csproj index 7c0bfda..08bb1ad 100644 --- a/examples/BasicUsage_clr21_RBAC/app/app.csproj +++ b/examples/BasicUsage_clr21_RBAC/app/app.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/examples/BasicUsage_clr21_RBAC/k8s/k8s.yaml b/examples/BasicUsage_clr21_RBAC/k8s/k8s.yaml index a8a9b1a..9362db7 100644 --- a/examples/BasicUsage_clr21_RBAC/k8s/k8s.yaml +++ b/examples/BasicUsage_clr21_RBAC/k8s/k8s.yaml @@ -11,7 +11,7 @@ spec: spec: containers: - name: ai-k8s-basic-container - image: saars/aik8sbasic_rbac:latest + image: dockeraccount/aik8sbasic_rbac:latest ports: - containerPort: 80 env: diff --git a/examples/MultipleIKeys/README.md b/examples/MultipleIKeys/README.md index 7add9ee..3fa6532 100644 --- a/examples/MultipleIKeys/README.md +++ b/examples/MultipleIKeys/README.md @@ -1,9 +1,11 @@ # Multiple Application Insights Instrumentation Key Example ## Assumption + If you are reading this example, we assume you are familiar with deploy Application Insights Kubernetes with your application in Kubernetes. Refer the basic examples if you do not know how to do that. ## Scenarios + Sometimes, you might have one application sending to different application insight backends. There are several ways to reach the goal. It could be done by using multiple channels ([Reference 1](https://github.com/Microsoft/ApplicationInsights-dotnet/blob/e544ffae4f3188bde01a367364ea3e36f2bf03a9/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/TelemetryConfigurationFactoryTest.cs), [Reference 2](https://github.com/Microsoft/ApplicationInsights-dotnet/blob/e544ffae4f3188bde01a367364ea3e36f2bf03a9/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/TelemetrySinkTests.cs)) or by building multiple `TelemetryConfiguration` instances to hold multiple iKeys. This example is going to focus on the multiple-iKey scenario, which will be supported from Application Insights Kubernetes 1.0.0-beta8. Different than single Application Insights Instrumentation Key (iKey), in which case, you are suggested to use the TelemetryClient by ASP.NET Dependency Injection, for multiple-iKey scenario, you will need to build your own Telemetry Clients. The telemetry clients accept a telemetry configuration object, which contains the iKey property. Supporting of calling `AddApplicationInsightsKubernetesEnricher()` on various `TelemetryConfiguration` is added. @@ -11,9 +13,10 @@ Different than single Application Insights Instrumentation Key (iKey), in which ## Key code Let's talk in code: + ```csharp // Build a TelemetryClient with iKey1 - TelemetryConfiguration aiConfig = new TelemetryConfiguration("ikey 1", app.ApplicationServices.GetService()); + TelemetryConfiguration aiConfig = new TelemetryConfiguration("iKey 1", app.ApplicationServices.GetService()); aiConfig.AddApplicationInsightsKubernetesEnricher(); TelemetryClient client = new TelemetryClient(aiConfig); // Invoking the constructor for the TelemetryInitializer @@ -24,9 +27,11 @@ Let's talk in code: aiConfig2.AddApplicationInsightsKubernetesEnricher(); TelemetryClient client2 = new TelemetryClient(aiConfig2); ``` -Now you can have telemetry clients sending to different application insight backends. Refer [Startup.cs](./Startup.cs) for the full code. + +Now you can have telemetry clients sending to different application insight backends. Refer to [Startup.cs](./Startup.cs) for the full code. There are some points worth to mention: + * In this example, we are getting the ITelemetryChannel object from the service provider because * It is a `ServerTelemetryChannel` than a, by default, `InMemory` channel. * It is reusable for various telemetry configurations. @@ -38,9 +43,8 @@ There are some points worth to mention: * This is sort of obvious, but since this is the Application Insights Kubernetes example, I have to mention: please do not forget to call `.AddApplicationInsightsKubernetesEnricher()` on the configuration object to inject Kubernetes information to the telemetry data. -``` -Side note: You might notice the very first TrackEvent doesn't come with the Kubernetes info. That is by design because the TelemetryInitializer is non-blocking but it will take an async call to fetch the Kubernetes info. -``` +_Side note: You might notice the very first TrackEvent doesn't come with the Kubernetes info. That is by design because the TelemetryInitializer is non-blocking but it will take an async call to fetch the Kubernetes info._ + This is how it looks like in two different application insights backend: ![Result Example](./Media/screenshot1.png) diff --git a/examples/ZeroUserCodeLightup/README.md b/examples/ZeroUserCodeLightup/README.md index aa6cee9..23a7db9 100644 --- a/examples/ZeroUserCodeLightup/README.md +++ b/examples/ZeroUserCodeLightup/README.md @@ -1,4 +1,5 @@ # Zero Code light up Example + This walkthrough shows how to enable application insights for Kubernetes for ASP.NET Core 2.0 Web App without code change for the existing project. ## Add Dockerfile @@ -15,6 +16,7 @@ ENV APPINSIGHTS_INSTRUMENTATIONKEY $APPINSIGHTS_KEY ENV ASPNETCORE_HOSTINGSTARTUPASSEMBLIES Microsoft.ApplicationInsights.Kubernetes.HostingStartup ... ``` + Reference the full [Dockerfile](./Dockerfile). *Note: This applies to **1.0.6-beta1** and above.* @@ -22,25 +24,32 @@ Reference the full [Dockerfile](./Dockerfile). *Note: To make your build context as small as possible add a [.dockerignore](./.dockerignore) file to your project folder.* ## Build and run the Docker image + 1. Open a command prompt and navigate to your project folder. 2. Use the following commands to build and run your Docker image: -``` -$ docker build -t ai-k8s-app --build-arg APPINSIGHTS_KEY=YOUR_APPLICATION_INSIGHTS_KEY . -$ docker run -p 8080:80 --name test-ai-k8s-app ai-k8s-app + +```shell +docker build -t ai-k8s-app --build-arg APPINSIGHTS_KEY=YOUR_APPLICATION_INSIGHTS_KEY . +docker run -p 8080:80 --name test-ai-k8s-app ai-k8s-app ``` ## Expect the error + If you follow the steps above, you shall see the following error in the beginning of the log: -``` + +```shell fail: Microsoft.ApplicationInsights.Kubernetes.KubernetesModule[0] System.IO.FileNotFoundException: File contains namespace does not exist. File name: '/var/run/secrets/kubernetes.io/serviceaccount/namespace' ``` + Congratulations, your image is ready to run inside the Kubernetes! The failure, as a matter of fact, is a good sign that Application Insights for Kubernetes is injected and is trying to get the Kubernetes related data. It failed only because it is running outside of the Kubernetes. ## Upload the image to the DockerHub + Once verified, the image is ready to be uploaded. For example: -``` + +```shell docker tag ai-k8s-app:latest dockeraccount/ai-k8s-app:0.0.1 docker push dockeraccount/ai-k8s-app:0.0.1 ``` @@ -48,9 +57,11 @@ docker push dockeraccount/ai-k8s-app:0.0.1 **Note:** Change the tag properly. For more details, please reference the docker document: [Push images to Docker Cloud](https://docs.docker.com/docker-cloud/builds/push-images/). ## Deploy the application in Kubernetes + Now that the image is in the container registry, it is time to deploy it to Kubernetes. Create a Kubernets deployment file. Reference [deployment.yaml](./k8s/deployment.yaml) as an example. Some key lines: + ```yaml apiVersion: extensions/v1beta1 kind: Deployment @@ -74,20 +85,23 @@ spec: - name: ASPNETCORE_HOSTINGSTARTUPASSEMBLIES value: Microsoft.ApplicationInsights.Kubernetes.HostingStartup ``` + **Note:** There is yet another chance to overwrite the environment variable of the application insights key. [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) are recommended to protect the key in the production environment. Then run the following kubectl command to deploy the app: + ```bash # kubectl create -f deployment.yaml ``` -To learn more about Kubernetes deployment, please refer [Deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/). +To learn more about Kubernetes deployment, please refer to [Deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/). Generate some traffic to your application. After a while (around 2 minutes), you shall see Application Insights data coming with Kubernetes properties on it. ![Application Insights Events with Kubernetes Properties](./.media/AI_K8s_Properties.png) -## Summary +## Summary + In this example, we modified the Dockerfile a bit to add the required NuGet packages into the project, then we used the environment variables to enable the feature. The environment variable could also be managed by Kubernetes in the deployment spec.