Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaomi7732 committed Aug 29, 2022
2 parents 07c6684 + 1486c2e commit 864affb
Show file tree
Hide file tree
Showing 18 changed files with 491 additions and 6 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This repository has code for Application Insights for Kubernetes, which works on

![Screenshot for Application Insights for Kubernetes enhanced telemetry](./docs/TelemetryEnhancement.png)

**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.
**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 a Kubernetes cluster. 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 microservices on the same map.

## Continuous Integration Status

Expand All @@ -17,21 +17,24 @@ This repository has code for Application Insights for Kubernetes, which works on

## Get Started

This is a quick guide for ASP.NET Core project. For [Worker Services in .NET](https://docs.microsoft.com/en-us/dotnet/core/extensions/workers), refer to [Application Insights Kubernetes Example (Worker)](./examples/WorkerExample/Readme.md).
This is a quick guide for ASP.NET Core project.

* For [Worker Services in .NET](https://docs.microsoft.com/en-us/dotnet/core/extensions/workers), refer to the [Application Insights Kubernetes worker example](./examples/WorkerExample/Readme.md).
* For ASP.NET Core WebAPI or ASP.NET Minimal Web API, refer to the [Application Insights for Kubernetes on WebAPI example](./examples/WebAPI.Net6/).

### Prerequisite

* [Application Insights for ASP.NET Core](https://github.com/Microsoft/ApplicationInsights-aspnetcore)
* [Docker Containers](https://www.docker.com/)
* [Kubernetes](https://kubernetes.io/)

* For RBAC enabled Kubernetes, making sure [permissions are configured](./docs/configure-rbac-permissions.md).
* For RBAC-enabled Kubernetes, make sure [permissions are configured](./docs/configure-rbac-permissions.md).

### Instrument an ASP.NET Core application

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.

1. Add reference to **Application Insights SDK** and **Application Insights for Kubernetes**:
1. Add references to **Application Insights SDK** and **Application Insights for Kubernetes**:

```shell
dotnet add package Microsoft.ApplicationInsights.AspNetCore
Expand All @@ -53,7 +56,8 @@ These are the basic steps to instrument an ASP.NET Core application to enable Ap

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.
**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 deploying [Kubernetes Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) to secure it. Refer to [Deploy the application in Kubernetes
](examples/ZeroUserCodeLightup.Net6/README.md#deploy-the-application-in-kubernetes) for an example.

### Walk-through

Expand Down Expand Up @@ -112,7 +116,7 @@ Use the [troubleshooting image](https://github.com/Microsoft/ApplicationInsights

### 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 build a container for Kubernetes that have Application Insights baked in for the existing applications, please refer to the example of [Zero Code light up](https://github.com/Microsoft/ApplicationInsights-Kubernetes/tree/develop/examples/ZeroUserCodeLightup).
* 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).
Expand Down
6 changes: 6 additions & 0 deletions examples/WebAPI.Net6/MinimalAPI/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
obj
bin
Readme.md
k8s.yaml
k8s*.yaml
secrets.*
14 changes: 14 additions & 0 deletions examples/WebAPI.Net6/MinimalAPI/MinimalAPI.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.21.0" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="2.0.5-beta1" />
</ItemGroup>

</Project>
13 changes: 13 additions & 0 deletions examples/WebAPI.Net6/MinimalAPI/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var builder = WebApplication.CreateBuilder(args);

// Enable application insights
builder.Services.AddApplicationInsightsTelemetry();

// Enable application insights for Kubernetes
builder.Services.AddApplicationInsightsKubernetesEnricher(diagnosticLogLevel: LogLevel.Information);

var app = builder.Build();

app.MapGet("/", () => "Hello Minimal API!");

app.Run();
31 changes: 31 additions & 0 deletions examples/WebAPI.Net6/MinimalAPI/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:10058",
"sslPort": 44320
}
},
"profiles": {
"MinimalAPI": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7224;http://localhost:5015",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
5 changes: 5 additions & 0 deletions examples/WebAPI.Net6/MinimalAPI/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"ApplicationInsights": {
"ConnectionString": "Your Application Insights ConnectionString"
}
}
17 changes: 17 additions & 0 deletions examples/WebAPI.Net6/MinimalAPI/dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "MinimalAPI.dll"]
22 changes: 22 additions & 0 deletions examples/WebAPI.Net6/MinimalAPI/k8s.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-k8s-minimal-api-deployment
namespace: ai-k8s-demo
labels:
app: ai-k8s-minimal-api
spec:
replicas: 1
selector:
matchLabels:
app: ai-k8s-minimal-api
template:
metadata:
labels:
app: ai-k8s-minimal-api
spec:
containers:
- name: ai-k8s-minimal-api-container
image: dockeraccount/ai-k8s-minimal-api:1.0.0
ports:
- containerPort: 80
196 changes: 196 additions & 0 deletions examples/WebAPI.Net6/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
# Application Insights for Kubernetes on WebAPI

This page is a walk-through to enable `Application Insights for Kubernetes` in WebAPI projects, including traditional WebAPI (controller-based) and minimal WebAPIs. The example code is separated in [WebAPI](./WebAPI/) and [MinimalAPI](./MinimalAPI/) respectively.

_To learn more about minimal API, please refer to the [Minimal APIs overview](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-6.0)._

## Prerequisite

* .NET 6 SDK - <https://dot.net>
* Verify dotnet version. For example:
```shell
dotnet --version
6.0.302
```
_You might have a slightly different patch version and that should be fine._

* A Kubernetes Cluster that you can manage with `kubectl`.
* If you don't have any, there are several options:
* [Azure AKS](https://docs.microsoft.com/en-us/azure/aks/)
* [Docker Desktop](https://www.docker.com/products/docker-desktop/)
* [MiniKube](https://minikube.sigs.k8s.io/docs/start/)
* ...
* Verify that the credential is properly set up for `kubectl`, for example:

```shell
kubectl get nodes
NAME STATUS ROLES AGE VERSION
aks-nodepool1-10984277-0 Ready agent 5d8h v1.24.1
```

* A container image registry
* The image built will be pushed into an image registry. Dockerhub is used in this example. It should work with any image registry.

## Prepare the project

1. Create the project from templates

* For Control-Based WebAPI:

```shell
dotnet new webapi # Create a control-based webapi from the template
```

* For Minimal WebAPI

```shell
dotnet new web # Create a minimal webapi from the template
```

2. Add NuGet packages

```shell
dotnet add package Microsoft.ApplicationInsights.AspNetCore
dotnet add package Microsoft.ApplicationInsights.Kubernetes --prerelease
```

## Enable Application Insights for Kubernetes

To enable Application Insights for Kubernetes, the services need to be registered:

```csharp
...
// Enable application insights
builder.Services.AddApplicationInsightsTelemetry();
// Enable application insights for Kubernetes
builder.Services.AddApplicationInsightsKubernetesEnricher(diagnosticLogLevel: LogLevel.Information);
...
```

See a full example for [WebAPI](./WebAPI/Program.cs) or [Minimal WebAPI](./MinimalAPI/Program.cs).

## Prepare the image

1. Get the **dockerfile** ready. For example, refer to [this](./WebAPI/dockerfile) for WebAPI or [this](./MinimalAPI/dockerfile) for Minimal Web API, remember to update the `ENTRYPOINT` to align with your assembly name. For more about containerizing an ASP.NET application, refer to [Dockerize an ASP.NET Core application](https://docs.docker.com/samples/dotnetcore/).

1. Setup some variables for the convenience

```shell
$imageName='ai-k8s-web-api' # Choose your own tag name
$imageVersion='1.0.0' # Update the version of the container accordingly
$testAppName='test-ai-k8s-web-api' # Used as the container instance name for local testing
$imageRegistryAccount='your-registry-account' # Used to push the image
```
_Note: In this example, we use PowerShell. Tweak it accordingly in other shells. Also, you don't have to have those variables if you prefer to use the value directly below._
1. Build the image
```shell
docker build -t "$imageName`:$imageVersion" . # For PowerShell, you need to escape the colon(:) with (`).
docker container rm $testAppName -f # Making sure any existing container with the same name is deleted
docker run -d -p 8080:80 --name $testAppName "$imageName`:$imageVersion"
```
1. Check the logs
```shell
docker logs $testAppName
```
When you see this error at the beginning of the logs, it means the container is ready to be put into a Kubernetes cluster:
```log
[Error] [2022-08-12T23:56:08.9973664Z] Application is not running inside a Kubernetes cluster.
```
1. Remove the running container
```shell
docker container rm $testAppName -f
```
1. Tag and push the image
```shell
docker tag "$imageName`:$imageVersion" "$imageRegistryAccount/$imageName`:$imageVersion"
docker push "$imageRegistryAccount/$imageName`:$imageVersion"
```
## Deploy to Kubernetes Cluster
Now that the image is in the container registry, it is time to deploy it to Kubernetes.
1. Deploy to a dedicated namespace
You could use the default namespace, but it is recommended to put the test application in a dedicated one, for example, 'ai-k8s-demo'. To deploy a namespace, use content in [k8s-namespace.yaml](../k8s-namespace.yaml):
```shell
kubectl create -f ..\k8s-namespace.yaml # tweak the path accordingly
```
1. Setup proper role binding for RBAC-enabled clusters
If you have RBAC enabled for your cluster, permissions need to be granted to the service account to access the cluster info for telemetries. Refer to [Configure RBAC permissions](../../docs/configure-rbac-permissions.md) for details.
For example, deploy a role assignment in the namespace of `ai-k8s-demo` by using [sa-role.yaml](../../docs/sa-role.yaml):
```shell
kubectl create -f ..\..\docs\sa-role.yaml # tweak the path accordingly
```
_Notes: Check the namespace for the service account in the yaml file._
1. Deploy the application
Create a Kubernetes deployment file. Reference [k8s.yaml](./k8s.yaml) as an example, pay attention to **namespace**, **image**, and **environment variables**, making sure they are properly set up.
Then run the following command to deploy the app:
```shell
kubectl create -f k8s.yaml
```
To learn more about Kubernetes deployment, please refer to [Deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/).
1. Check out the pod deployed:
```shell
kubectl get pods --namespace ai-k8s-demo # Or whatever your namespace of choice.
```
And you will see something like this:
```
PS > kubectl get pods --namespace ai-k8s-demo
NAME READY STATUS RESTARTS AGE
some-other-pod-that-has-run-for-10-days-pmfdc 1/1 Running 0 10d
ai-k8s-web-api-deployment-97d688b46-7cxs5 1/1 Running 0 2m58s <==== created ~3 minutes ago
```
Check out the logs, for example:
```shell
PS > kubectl logs ai-k8s-web-api-deployment-97d688b46-7cxs5 --namespace ai-k8s-demo
[Information] [2022-08-23T21:32:01.0135029Z] [CGroupContainerIdProvider] Got container id: 41a149977b4ea424947d54c59e7f63d32664e19503adda762004250f72db7687
[Information] [2022-08-23T21:32:01.2737318Z] Found pod by name providers: ai-k8s-web-api-deployment-97d688b46-7cxs5
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: /app/
```
1. Test the endpoint
One way to hit the endpoint is by port forwarding. Check out the example in [Deploy the application in Kubernetes](../ZeroUserCodeLightup.Net6/README.md#deploy-the-application-in-kubernetes), looking for "Port forward for testing" section specifically.
2. Delete the cluster after the test
```
PS > kubectl delete -f k8s.yaml
deployment.apps "ai-k8s-web-api-deployment" deleted
```
Loading

0 comments on commit 864affb

Please sign in to comment.