-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/develop'
- Loading branch information
Showing
18 changed files
with
491 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
obj | ||
bin | ||
Readme.md | ||
k8s.yaml | ||
k8s*.yaml | ||
secrets.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
31
examples/WebAPI.Net6/MinimalAPI/Properties/launchSettings.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"ApplicationInsights": { | ||
"ConnectionString": "Your Application Insights ConnectionString" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
Oops, something went wrong.