Implementation
Step-by-step guide to enable Container Insights with ContainerLogV2 on an AKS cluster.
Environment Variables
Set these before running the commands below:
export SUBSCRIPTION_ID=<subscription id>
export RESOURCE_GROUP=<resource group name>
export CLUSTER_NAME=<aks cluster name>
export LOCATION=<azure region, e.g. eastus>
export LAW_NAME=<log analytics workspace name>
Install Required CLI Extensions
az extension add --name aks-preview --upgrade
az provider register --namespace Microsoft.Monitor
az provider register --namespace Microsoft.Insights
Step 1 — Create a Log Analytics Workspace
A Log Analytics Workspace is the destination for all container logs. Skip this step if you already have one.
# Create the workspace
az monitor log-analytics workspace create \
--resource-group $RESOURCE_GROUP \
--workspace-name $LAW_NAME \
--location $LOCATION \
--subscription $SUBSCRIPTION_ID
# Save the workspace resource ID for later steps
export LAW_RESOURCE_ID=$(az monitor log-analytics workspace show \
--resource-group $RESOURCE_GROUP \
--workspace-name $LAW_NAME \
--subscription $SUBSCRIPTION_ID \
--query id -o tsv)
echo "Workspace ID: $LAW_RESOURCE_ID"
Step 2 — Get AKS Cluster Credentials
az aks get-credentials \
-g $RESOURCE_GROUP \
-n $CLUSTER_NAME \
-a --overwrite-existing \
--subscription $SUBSCRIPTION_ID
Step 3 — Enable Container Insights with ContainerLogV2
This single command enables the Azure Monitor Agent on your AKS cluster:
az aks enable-addons \
--addon monitoring \
--name $CLUSTER_NAME \
--resource-group $RESOURCE_GROUP \
--workspace-resource-id $LAW_RESOURCE_ID \
--subscription $SUBSCRIPTION_ID
What this does:
- Deploys the
ama-logsDaemonSet intokube-systemnamespace - Creates a Data Collection Rule (DCR) linked to the cluster
- Starts collecting container stdout/stderr, Kubernetes events, and performance metrics
- Sends logs to the Log Analytics Workspace in ContainerLogV2 format
Step 4 — Configure Log Filtering (ConfigMap)
Create `container-logs-configmap.yaml` to control which namespaces are collected and enable metadata enrichment:
apiVersion: v1
kind: ConfigMap
metadata:
name: container-azm-ms-agentconfig
namespace: kube-system
data:
schema-version: v1
config-version: ver1
log-data-collection-settings: |-
[log_collection_settings]
[log_collection_settings.stdout]
enabled = true
exclude_namespaces = ["kube-system", "gatekeeper-system"]
[log_collection_settings.stderr]
enabled = true
exclude_namespaces = ["kube-system", "gatekeeper-system"]
[log_collection_settings.env_var]
enabled = true
[log_collection_settings.enrich_container_logs]
enabled = true
[log_collection_settings.collect_all_kube_events]
enabled = true
Apply it:
kubectl apply -f container-logs-configmap.yaml
Note: After updating the ConfigMap, AMA pods automatically pick up changes within ~5 minutes. To force an immediate reload:
kubectl rollout restart daemonset ama-logs -n kube-system
Step 5 — Configure Data Collection Rule (DCR) for Namespace Filtering
The DCR controls what data gets collected at the platform level. You can scope collection to specific namespaces.
Create `container-logs-dcr.json`:
{
"properties": {
"dataSources": {
"extensions": [
{
"name": "ContainerInsightsExtension",
"streams": ["Microsoft-ContainerLogV2"],
"extensionSettings": {
"dataCollectionSettings": {
"interval": "1m",
"namespaceFilteringMode": "Include",
"namespaces": ["default", "app", "production"],
"enableContainerLogV2": true
}
},
"extensionName": "ContainerInsights"
}
]
},
"destinations": {
"logAnalytics": [
{
"workspaceResourceId": "<LAW_RESOURCE_ID>",
"name": "ciworkspace"
}
]
},
"dataFlows": [
{
"streams": ["Microsoft-ContainerLogV2"],
"destinations": ["ciworkspace"]
}
]
}
}
Find and inspect the DCR created by the addon:
az monitor data-collection rule list \
--resource-group $RESOURCE_GROUP \
--subscription $SUBSCRIPTION_ID \
--query "[?contains(name,'MSCI')].{name:name, id:id}" -o table
Step 6 — (Optional) Export Logs to Event Hub
If you need logs forwarded to an Event Hub, set up a Diagnostic Setting:
# Get Event Hub Authorization Rule ID
export EVENTHUB_RULE_ID=$(az eventhubs namespace authorization-rule show \
--resource-group $RESOURCE_GROUP \
--namespace-name $EVENTHUB_NAMESPACE \
--name RootManageSharedAccessKey \
--subscription $SUBSCRIPTION_ID \
--query id -o tsv)
# Get AKS cluster resource ID
export AKS_RESOURCE_ID=$(az aks show \
--name $CLUSTER_NAME \
--resource-group $RESOURCE_GROUP \
--subscription $SUBSCRIPTION_ID \
--query id -o tsv)
# Create diagnostic setting to export logs to Event Hub
az monitor diagnostic-settings create \
--name "aks-logs-to-eventhub" \
--resource $AKS_RESOURCE_ID \
--event-hub $EVENTHUB_INSTANCE_NAME \
--event-hub-rule $EVENTHUB_RULE_ID \
--logs '[{"categoryGroup":"allLogs","enabled":true}]' \
--subscription $SUBSCRIPTION_ID
Verification
Check AMA Agent Pods
kubectl get pods -n kube-system -l component=ama-logs -o wide
Expected output — one pod per node, all `Running` with `1/1` READY:
NAME READY STATUS RESTARTS AGE
ama-logs-xxxxx 1/1 Running 0 5m
ama-logs-rs-xxxx 1/1 Running 0 5m
Check Agent Logs
kubectl logs -n kube-system -l component=ama-logs --tail=50
kubectl logs -n kube-system -l component=ama-logs | grep -i "started\|success\|heartbeat"
Verify Addon Is Enabled
az aks show -g $RESOURCE_GROUP -n $CLUSTER_NAME \
--subscription $SUBSCRIPTION_ID \
--query "addonProfiles.omsagent.enabled"
Verify Logs in Log Analytics
Allow 5–10 minutes after enabling, then run in Log Analytics:
ContainerLogV2
| where TimeGenerated > ago(30m)
| summarize Count = count() by PodNamespace
| order by Count desc
Troubleshooting
| Symptom | Fix |
|---|---|
No ama-logs pods found |
Run az aks enable-addons --addon monitoring ... again |
Pods in CrashLoopBackOff |
Check pod logs: kubectl logs -n kube-system -l component=ama-logs |
| 0 rows in ContainerLogV2 | Verify addon enabled (az aks show ... --query "addonProfiles.omsagent.enabled"), check workspace ID is correct, ensure workspace is in same or peered region |
| Logs missing for a namespace | Update ConfigMap exclude_namespaces and restart: kubectl rollout restart daemonset ama-logs -n kube-system |
| High log volume / cost | Switch to Basic tier or add namespace filtering in DCR |
| ConfigMap changes not applied | Wait 5 min or force: kubectl rollout restart daemonset ama-logs -n kube-system |
Quick Deploy Script
#!/bin/bash
# container-insights-deploy.sh
# Usage: sh ./container-insights-deploy.sh <SUBSCRIPTION_ID> <RESOURCE_GROUP> <CLUSTER_NAME> <LAW_NAME> <LOCATION>
set -e
SUBSCRIPTION_ID=$1
RESOURCE_GROUP=$2
CLUSTER_NAME=$3
LAW_NAME=$4
LOCATION=$5
echo "=== Container Insights Deployment ==="
echo "Subscription: $SUBSCRIPTION_ID"
echo "Cluster: $CLUSTER_NAME"
echo "Workspace: $LAW_NAME"
# Step 1: Create Log Analytics Workspace (idempotent)
echo "[1/3] Creating Log Analytics Workspace..."
az monitor log-analytics workspace create \
--resource-group $RESOURCE_GROUP \
--workspace-name $LAW_NAME \
--location $LOCATION \
--subscription $SUBSCRIPTION_ID \
--only-show-errors 2>/dev/null || true
LAW_RESOURCE_ID=$(az monitor log-analytics workspace show \
--resource-group $RESOURCE_GROUP \
--workspace-name $LAW_NAME \
--subscription $SUBSCRIPTION_ID \
--query id -o tsv)
# Step 2: Get AKS credentials
echo "[2/3] Getting AKS credentials..."
az aks get-credentials -g $RESOURCE_GROUP -n $CLUSTER_NAME -a \
--overwrite-existing --subscription $SUBSCRIPTION_ID
# Step 3: Enable Container Insights
echo "[3/3] Enabling Container Insights..."
az aks enable-addons \
--addon monitoring \
--name $CLUSTER_NAME \
--resource-group $RESOURCE_GROUP \
--workspace-resource-id $LAW_RESOURCE_ID \
--subscription $SUBSCRIPTION_ID
echo ""
echo "=== Deployment Complete ==="
echo "Verify: kubectl get pods -n kube-system -l component=ama-logs"
echo "Query: Go to Log Analytics → ContainerLogV2 table"
Usage:
sh ./container-insights-deploy.sh $SUBSCRIPTION_ID $RESOURCE_GROUP $CLUSTER_NAME $LAW_NAME $LOCATION
Terraform Alternative
# Log Analytics Workspace
resource "azurerm_log_analytics_workspace" "law" {
name = var.law_name
location = var.location
resource_group_name = var.resource_group_name
sku = "PerGB2018"
retention_in_days = 30
}
# Log Analytics Solution for Container Insights
resource "azurerm_log_analytics_solution" "container_insights" {
solution_name = "ContainerInsights"
location = var.location
resource_group_name = var.resource_group_name
workspace_resource_id = azurerm_log_analytics_workspace.law.id
workspace_name = azurerm_log_analytics_workspace.law.name
plan {
publisher = "Microsoft"
product = "OMSGallery/ContainerInsights"
}
}
# AKS Cluster with Container Insights enabled
resource "azurerm_kubernetes_cluster" "aks" {
name = var.cluster_name
location = var.location
resource_group_name = var.resource_group_name
dns_prefix = var.cluster_name
default_node_pool {
name = "default"
node_count = 3
vm_size = "Standard_DS2_v2"
}
identity {
type = "SystemAssigned"
}
oms_agent {
log_analytics_workspace_id = azurerm_log_analytics_workspace.law.id
}
}