diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..8525b1c4
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,261 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# Local global.json
+global.json
+
+# Anything that is local
+local.*
+
+# BenchmarkDotNet Results
+BenchmarkDotNet.Artifacts/
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c6e9905a..82c9355b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -26,7 +26,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v2
with:
- dotnet-version: 6.x
+ dotnet-version: 8.x
- name: Restore dependencies
run: dotnet restore ApplicationInsights.Kubernetes.sln
diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml
new file mode 100644
index 00000000..ac030f27
--- /dev/null
+++ b/.github/workflows/image.yml
@@ -0,0 +1,73 @@
+
+name: Push Docker Image
+run-name: PushI Docker Image by @${{ github.actor }}
+
+on:
+ workflow_dispatch:
+
+ release:
+ types:
+ - published
+
+permissions:
+ packages: write
+
+# ------------------------------------------------------------------------------------------------------------------------
+env:
+ ACR_NAME: 'ghcr.io'
+ ACR_APP_NAME: 'aik8s_troubleshoot'
+
+# ------------------------------------------------------------------------------------------------------------------------
+jobs:
+ build-and-push-image:
+ runs-on: ubuntu-latest
+ permissions:
+ packages: write
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4.1.1
+
+ - name: Get repo name
+ id: set-repo
+ run: echo "REPO_NAME=$(basename ${{ github.repository }})" >> $GITHUB_OUTPUT
+
+ # Uses the `docker/login-action` action to log in to the Container registry using the account and password that
+ # will publish the packages. Once published, the packages are scoped to the account defined here.
+ - name: Log in to the Container registry
+ uses: docker/login-action@327cd5a69de6c009b9ce71bce8395f28e651bf99
+ with:
+ registry: ${{ env.ACR_NAME }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Set image name
+ id: image-name
+ run: |
+ echo "IMAGE_NAME_NO_TAG=${{ github.repository_owner }}/${{ steps.set-repo.outputs.REPO_NAME }}/${{ env.ACR_APP_NAME }}" >> $GITHUB_OUTPUT
+
+ - name: Extract metadata (tags, labels) for Docker
+ id: meta
+ uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
+ with:
+ images: ${{ env.ACR_NAME }}/${{ steps.image-name.outputs.IMAGE_NAME_NO_TAG }}
+ labels: |
+ org.opencontainers.image.title=aik8s_troubleshoot
+ org.opencontainers.image.description=Troubleshooting image for Microsoft Application Insights for Kubernetes
+ org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/${{ steps.set-repo.outputs.REPO_NAME }}
+ tags: |
+ type=raw,value=latest,enable={{is_default_branch}}
+ type=ref,event=branch
+ type=ref,event=pr
+ type=semver,pattern={{version}}
+ type=semver,pattern={{major}}.{{minor}}
+
+ - name: Build Docker image
+ run: docker build -t ${{ env.ACR_APP_NAME }} .
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v6
+ with:
+ push: true
+ labels: ${{ steps.meta.outputs.labels }}
+ tags: ${{ steps.meta.outputs.tags }}
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..f7d9c8ae
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,22 @@
+FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build-env
+WORKDIR /app
+
+# Copy csproj and restore as distinct layers
+COPY troubleshooting/AIK8sTroubleShooting/*.csproj /app/troubleshooting/AIK8sTroubleShooting/
+COPY src/ApplicationInsights.Kubernetes/*.csproj /app/src/ApplicationInsights.Kubernetes/
+
+WORKDIR /app/troubleshooting/AIK8sTroubleShooting
+RUN dotnet restore
+
+# Copy everything else and build
+COPY troubleshooting/AIK8sTroubleShooting /app/troubleshooting/AIK8sTroubleShooting
+COPY src /app/src
+COPY LICENSE /app/LICENSE
+COPY README.md /app/README.md
+RUN dotnet publish -c Release -o out
+
+# Build runtime image
+FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
+WORKDIR /app
+COPY --from=build-env /app/troubleshooting/AIK8sTroubleShooting/out .
+ENTRYPOINT ["dotnet", "AIK8sTroubleShooting.dll"]
\ No newline at end of file
diff --git a/src/ApplicationInsights.Kubernetes.HostingStartup/ApplicationInsights.Kubernetes.HostingStartup.csproj b/src/ApplicationInsights.Kubernetes.HostingStartup/ApplicationInsights.Kubernetes.HostingStartup.csproj
index 7a16f5aa..b1fc7a6e 100644
--- a/src/ApplicationInsights.Kubernetes.HostingStartup/ApplicationInsights.Kubernetes.HostingStartup.csproj
+++ b/src/ApplicationInsights.Kubernetes.HostingStartup/ApplicationInsights.Kubernetes.HostingStartup.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
Microsoft.ApplicationInsights.Kubernetes.HostingStartup
true
diff --git a/src/ApplicationInsights.Kubernetes/ApplicationInsights.Kubernetes.csproj b/src/ApplicationInsights.Kubernetes/ApplicationInsights.Kubernetes.csproj
index ed59da84..eb1fcd6b 100644
--- a/src/ApplicationInsights.Kubernetes/ApplicationInsights.Kubernetes.csproj
+++ b/src/ApplicationInsights.Kubernetes/ApplicationInsights.Kubernetes.csproj
@@ -3,7 +3,7 @@
IOperation
- net6.0
+ net8.0
Microsoft.ApplicationInsights.Kubernetes
Microsoft.ApplicationInsights.Kubernetes
true
diff --git a/src/ApplicationInsights.Kubernetes/K8sClientService.cs b/src/ApplicationInsights.Kubernetes/K8sClientService.cs
index b5c570bd..b6028bc2 100644
--- a/src/ApplicationInsights.Kubernetes/K8sClientService.cs
+++ b/src/ApplicationInsights.Kubernetes/K8sClientService.cs
@@ -1,92 +1,92 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Threading;
-using System.Threading.Tasks;
-using k8s;
-using k8s.Autorest;
-using k8s.Models;
-using Microsoft.ApplicationInsights.Kubernetes.Debugging;
-using Microsoft.ApplicationInsights.Kubernetes.Utilities;
-using K8s = k8s.Kubernetes;
-
-namespace Microsoft.ApplicationInsights.Kubernetes;
-
-///
-/// A thin wrapper for Kubernetes client to use inside K8s cluster
-///
-internal sealed class K8sClientService : IDisposable, IK8sClientService
-{
- private readonly ApplicationInsightsKubernetesDiagnosticSource _logger = ApplicationInsightsKubernetesDiagnosticSource.Instance;
-
- private bool _isDisposeCalled = false;
- private readonly string _namespace;
-
- private readonly KubernetesClientConfiguration _configuration;
-
- private readonly IKubernetes _kubernetesClient;
-
- private K8sClientService()
- {
- _configuration = KubernetesClientConfiguration.InClusterConfig();
- _namespace = _configuration.Namespace;
- _kubernetesClient = new K8s(_configuration);
- }
-
- public static K8sClientService Instance { get; } = new K8sClientService();
-
- public void Dispose()
- {
- if (_isDisposeCalled)
- {
- return;
- }
- _isDisposeCalled = true;
-
- _kubernetesClient.Dispose();
- }
-
- public async Task> GetPodsAsync(CancellationToken cancellationToken)
- {
- V1PodList? list = await _kubernetesClient.CoreV1.ListNamespacedPodAsync(_namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
- return list.AsEnumerable();
- }
-
- public Task GetPodByNameAsync(string podName, CancellationToken cancellationToken)
- => _kubernetesClient.CoreV1.ReadNamespacedPodAsync(podName, _namespace, cancellationToken: cancellationToken);
-
- public async Task> GetReplicaSetsAsync(CancellationToken cancellationToken)
- {
- V1ReplicaSetList? replicaSetList = await _kubernetesClient.AppsV1.ListNamespacedReplicaSetAsync(_namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
- return replicaSetList.AsEnumerable();
- }
-
- public async Task> GetDeploymentsAsync(CancellationToken cancellationToken)
- {
- V1DeploymentList? deploymentList = await _kubernetesClient.AppsV1.ListNamespacedDeploymentAsync(_namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
- return deploymentList.AsEnumerable();
- }
-
- public async Task> GetNodesAsync(bool ignoreForbiddenException, CancellationToken cancellationToken)
- {
- try
- {
- V1NodeList? nodeList = await _kubernetesClient.CoreV1.ListNodeAsync().ConfigureAwait(false);
- return nodeList.AsEnumerable();
- }
- catch (HttpOperationException ex) when (ex.Response.StatusCode == HttpStatusCode.Forbidden)
- {
- // Choose to ignore forbidden exception
- if (ignoreForbiddenException)
- {
- _logger.LogDebug(ex.Message);
- _logger.LogTrace(ex.ToString());
- return Enumerable.Empty();
- }
-
- // Otherwise
- throw;
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using k8s;
+using k8s.Autorest;
+using k8s.Models;
+using Microsoft.ApplicationInsights.Kubernetes.Debugging;
+using Microsoft.ApplicationInsights.Kubernetes.Utilities;
+using K8s = k8s.Kubernetes;
+
+namespace Microsoft.ApplicationInsights.Kubernetes;
+
+///
+/// A thin wrapper for Kubernetes client to use inside K8s cluster
+///
+internal sealed class K8sClientService : IDisposable, IK8sClientService
+{
+ private readonly ApplicationInsightsKubernetesDiagnosticSource _logger = ApplicationInsightsKubernetesDiagnosticSource.Instance;
+
+ private bool _isDisposeCalled = false;
+ private readonly string _namespace;
+
+ private readonly KubernetesClientConfiguration _configuration;
+
+ private readonly IKubernetes _kubernetesClient;
+
+ private K8sClientService()
+ {
+ _configuration = KubernetesClientConfiguration.InClusterConfig();
+ _namespace = _configuration.Namespace;
+ _kubernetesClient = new K8s(_configuration);
+ }
+
+ public static K8sClientService Instance { get; } = new K8sClientService();
+
+ public void Dispose()
+ {
+ if (_isDisposeCalled)
+ {
+ return;
+ }
+ _isDisposeCalled = true;
+
+ _kubernetesClient.Dispose();
+ }
+
+ public async Task> GetPodsAsync(CancellationToken cancellationToken)
+ {
+ V1PodList? list = await _kubernetesClient.CoreV1.ListNamespacedPodAsync(_namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
+ return list.AsEnumerable();
+ }
+
+ public Task GetPodByNameAsync(string podName, CancellationToken cancellationToken)
+ => _kubernetesClient.CoreV1.ReadNamespacedPodAsync(podName, _namespace, cancellationToken: cancellationToken);
+
+ public async Task> GetReplicaSetsAsync(CancellationToken cancellationToken)
+ {
+ V1ReplicaSetList? replicaSetList = await _kubernetesClient.AppsV1.ListNamespacedReplicaSetAsync(_namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
+ return replicaSetList.AsEnumerable();
+ }
+
+ public async Task> GetDeploymentsAsync(CancellationToken cancellationToken)
+ {
+ V1DeploymentList? deploymentList = await _kubernetesClient.AppsV1.ListNamespacedDeploymentAsync(_namespace, cancellationToken: cancellationToken).ConfigureAwait(false);
+ return deploymentList.AsEnumerable();
+ }
+
+ public async Task> GetNodesAsync(bool ignoreForbiddenException, CancellationToken cancellationToken)
+ {
+ try
+ {
+ V1NodeList? nodeList = await _kubernetesClient.CoreV1.ListNodeAsync().ConfigureAwait(false);
+ return nodeList.AsEnumerable();
+ }
+ catch (HttpOperationException ex) when (ex.Response.StatusCode == HttpStatusCode.Forbidden)
+ {
+ // Choose to ignore forbidden exception
+ if (ignoreForbiddenException)
+ {
+ _logger.LogDebug(ex.Message);
+ _logger.LogTrace(ex.ToString());
+ return Enumerable.Empty();
+ }
+
+ // Otherwise
+ throw;
+ }
+ }
+}
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index ac66a7b2..3febf715 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -2,7 +2,7 @@
- 10.0
+ 12.0
enable
@@ -19,8 +19,8 @@
$(MSBuildThisFileDirectory)PublicKey.snk
$([System.DateTime]::Now.ToString(yyyyMMddHHmm))
- 7.0.0-private-$(VersionSuffix)
- 7.0.0.0
+ 8.0.0-private-$(VersionSuffix)
+ 8.0.0.0
Microsoft
Microsoft
True
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index c779d44f..7f66ecf8 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -4,16 +4,16 @@
true
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
diff --git a/tests/UnitTests/UnitTests.csproj b/tests/UnitTests/UnitTests.csproj
index a9c95ae5..484c8f45 100644
--- a/tests/UnitTests/UnitTests.csproj
+++ b/tests/UnitTests/UnitTests.csproj
@@ -1,7 +1,7 @@
- net6
+ net8
Microsoft.ApplicationInsights.Kubernetes.UnitTests
Microsoft.ApplicationInsights.Kubernetes
True
@@ -13,8 +13,8 @@
-
-
+
+
diff --git a/troubleshooting/AIK8sTroubleShooting/AIK8sTroubleShooting.csproj b/troubleshooting/AIK8sTroubleShooting/AIK8sTroubleShooting.csproj
index fb348f2b..054f4999 100644
--- a/troubleshooting/AIK8sTroubleShooting/AIK8sTroubleShooting.csproj
+++ b/troubleshooting/AIK8sTroubleShooting/AIK8sTroubleShooting.csproj
@@ -1,16 +1,19 @@
- net6.0
+ net8.0
enable
enable
-
+
-
-
+
+
+
+
\ No newline at end of file
diff --git a/troubleshooting/AIK8sTroubleShooting/Dockerfile b/troubleshooting/AIK8sTroubleShooting/Dockerfile
index 80c2d3ca..c276be95 100644
--- a/troubleshooting/AIK8sTroubleShooting/Dockerfile
+++ b/troubleshooting/AIK8sTroubleShooting/Dockerfile
@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build-env
+FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine 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 mcr.microsoft.com/dotnet/aspnet:6.0-alpine
+FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "AIK8sTroubleShooting.dll"]
\ No newline at end of file
diff --git a/troubleshooting/AIK8sTroubleShooting/k8s/k8s.yaml b/troubleshooting/AIK8sTroubleShooting/k8s/k8s.yaml
index 7ea75000..1ec3b70d 100644
--- a/troubleshooting/AIK8sTroubleShooting/k8s/k8s.yaml
+++ b/troubleshooting/AIK8sTroubleShooting/k8s/k8s.yaml
@@ -16,7 +16,7 @@ spec:
spec:
containers:
- name: ai-k8s-troubleshooting-container
- image: saars/aik8s_troubleshoot:latest
+ image: ghcr.io/microsoft/applicationinsights-kubernetes:latest
ports:
- containerPort: 80
env: