Unlocking AI with AKS MCP Integration

In 2026, MCP (Model Context Protocol) has become the primary bridge between AI assistants and your infrastructure. Integrating MCP with AKS allows AI agents (like GitHub Copilot, Claude, or custom LLMs) to “talk” to your cluster safely to perform tasks like troubleshooting, deployment, and status checks.

Here is a breakdown of how this integration works and why it’s a powerful addition to your support proposal.


1. The Core Concept: The “AI Translator”

Think of the AKS MCP Server as a specialized API translator.

  • The Agent: An AI assistant sends a natural language request (e.g., “Why is the payment-service pod crashing?”).
  • The MCP Server: Receives the request and translates it into specific kubectl or Azure SDK commands.
  • The Response: It retrieves the logs and events, summarizes the issue, and suggests a fix back to the agent.

2. How the Integration is Structured

You typically deploy the MCP server in one of two ways:

A. Local Mode (Developer/Admin Support)

You run the MCP binary on your local machine or within VS Code.

  • Setup: Install the AKS Extension for VS Code.
  • Authentication: It inherits your existing az login credentials.
  • Benefit: You can use Copilot Chat as a “Junior SRE” to help you debug your Linux nodes or Docker containers in real-time.

B. Remote/Cluster Mode (Automated Support)

The MCP server is deployed directly into your AKS cluster as a pod.

  • Setup: Deployed via Helm chart.
  • Authentication: Uses Entra Workload Identity. The pod has a Managed Identity with specific RBAC roles (e.g., Azure Kubernetes Service RBAC Reader).
  • Benefit: Allows external AI agents or automated “healing” bots to interact with the cluster without needing human intervention.

3. Security & Governance (The “Guardrails”)

This is the most important part to explain to your client. Integrating AI with AKS is not a “free-for-all.”

  • RBAC Enforcement: The MCP server is strictly bound by the same Azure RBAC and Kubernetes RBAC rules you’ve already set up. If the AI doesn’t have “Write” access, it cannot delete or change anything.
  • Permission Tiers: You can configure the MCP server in three modes:
    • Read-Only (Default): AI can see logs and status but can’t change anything.
    • Read-Write: AI can deploy pods or restart services.
    • Admin: Full control for advanced automation.

4. Practical Use Cases for Your Support Role

By proposing MCP integration, you are essentially providing the company with an “AI-Powered Operations Center.”

  • Instant Root Cause Analysis: “MCP, find all OOMKilled pods in the production namespace and show me their last 50 lines of logs.”
  • Security Auditing: “MCP, list all images running in the cluster that haven’t been updated in 30 days.”
  • Infrastructure Queries: “MCP, what is the current CPU utilization across all Linux nodes in the ‘West US’ pool?”

How to Propose This

In your proposal, call this “Next-Gen Observability with AI-Context.”

“I propose implementing the AKS Model Context Protocol (MCP) server. This will allow us to integrate AI-powered troubleshooting directly with our cluster. It enables us to use natural language to query logs and cluster states, reducing our time-to-fix from minutes to seconds, all while maintaining strict security through our existing RBAC policies.”

Integrating AI in Microservices: The 2026 Gold Standard

To integrate AI features like chatbots and data analysis into your microservices, the “Gold Standard” in 2026 is to treat AI as a secured external dependency, much like a database.

Instead of building your own models, you connect your Docker containers to Azure OpenAI or Microsoft Foundry via specialized networking and identity layers.


1. The Architecture: The “AI Gateway” Pattern

In a microservices environment, you shouldn’t let every container talk to the AI API directly. Instead, implement an AI Gateway (using NGINX or Azure API Management).

  • Why? It allows you to centralize Rate Limiting (so one chatbot doesn’t eat the company’s entire AI budget) and Content Filtering (ensuring sensitive company data isn’t sent to the model).
  • Networking: Use Azure Private Link. This ensures the traffic between your AKS pods and the AI models never touches the public internet.

2. Identity: Workload Identity (No API Keys)

In 2026, using OPENAI_API_KEY in your Docker environment variables is considered a security failure.

Use Entra Workload Identity to give your chatbot pod its own identity. In your code, you use the DefaultAzureCredential library, which automatically “grabs” a token from the AKS environment to authenticate with Azure OpenAI.

Python

# Example: Secure Python Chatbot Connection
from azure.identity import DefaultAzureCredential
from openai import AzureOpenAI
# Automatically uses the AKS Managed Identity
credential = DefaultAzureCredential()
token = credential.get_token("https://cognitiveservices.azure.com/.default")
client = AzureOpenAI(
azure_endpoint="https://your-ai-resource.openai.azure.com/",
api_version="2024-02-15-preview",
azure_ad_token=token.token
)

3. Data Analysis: The “RAG” Pattern

For “Data Analysis” features, you likely need Retrieval-Augmented Generation (RAG). This allows the AI to “read” your company’s private PDF manuals or SQL databases without training a new model.

  • The Workflow: 1. Your Linux microservice extracts data from your SQL/NoSQL DB.2. It sends it to Azure AI Search (a vector database).3. The AI “retrieves” the relevant facts and uses them to answer the user’s question.

4. Framework Selection (2026 Standards)

When proposing this to your company, you’ll need to choose an orchestration framework:

FrameworkBest For…Why?
Semantic KernelEnterprise .NET/JavaMicrosoft’s official SDK. It’s highly structured and integrates perfectly with AKS monitoring.
LangChainPython/Fast PrototypingThe most popular open-source tool. Great for complex data analysis “chains.”
AutoGenMulti-Agent SystemsUse this if you want one AI agent to “code” and another to “test” the data analysis.

5. Proposing “AI-Ready Infrastructure”

To sell this as a support upgrade, use this pitch:

“I can implement an AI Service Mesh on our cluster. This includes a secure Private Link to Azure OpenAI and Workload Identity for our containers. This setup prevents API key leaks and gives us a centralized ‘AI Gateway’ to monitor our token usage and costs, ensuring our new chatbot features are both secure and budget-friendly.”

To integrate AI features like chatbots securely, you need to ensure that your AKS cluster can talk to Azure OpenAI without going over the public internet.

By 2026, the best practice is to use Private Endpoints and Private DNS Zones. This “locks” the AI service into your Virtual Network.


1. Terraform: Azure OpenAI with Private Endpoint

Add this to your Terraform configuration. It creates the AI account, a model deployment (GPT-4o), and the private networking.

Terraform

# 1. Create the Azure OpenAI Account
resource "azurerm_cognitive_account" "openai" {
name = "oai-prod-aks-01"
location = azurerm_resource_group.aks_rg.location
resource_group_name = azurerm_resource_group.aks_rg.name
kind = "OpenAI"
sku_name = "S0"
# Disable public access - mandatory for 2026 security standards
public_network_access_enabled = false
custom_subdomain_name = "oai-prod-aks-01"
}
# 2. Deploy a Model (e.g., GPT-4o for Chatbots)
resource "azurerm_cognitive_deployment" "gpt4" {
name = "gpt-4o-deployment"
cognitive_account_id = azurerm_cognitive_account.openai.id
model {
format = "OpenAI"
name = "gpt-4o"
version = "2024-05-13" # Use the latest stable 2026 version
}
scale {
type = "Standard"
}
}
# 3. Create the Private Endpoint (The "Private Bridge")
resource "azurerm_private_endpoint" "openai_pe" {
name = "pe-openai-prod"
location = azurerm_resource_group.aks_rg.location
resource_group_name = azurerm_resource_group.aks_rg.name
subnet_id = azurerm_subnet.aks_subnet.id
private_service_connection {
name = "psc-openai"
private_connection_resource_id = azurerm_cognitive_account.openai.id
is_manual_connection = false
subresource_names = ["account"]
}
}

2. DNS Configuration

For your pods to find the AI service at oai-prod-aks-01.openai.azure.com, you need a Private DNS zone linked to your VNet.

Terraform

resource "azurerm_private_dns_zone" "openai_dns" {
name = "privatelink.openai.azure.com"
resource_group_name = azurerm_resource_group.aks_rg.name
}
resource "azurerm_private_dns_zone_virtual_network_link" "dns_link" {
name = "dns-link-openai"
resource_group_name = azurerm_resource_group.aks_rg.name
private_dns_zone_name = azurerm_private_dns_zone.openai_dns.name
virtual_network_id = azurerm_virtual_network.aks_vnet.id
}

3. The “Service” Pitch to Your Company

When you present this to your manager, focus on Data Privacy and Cost Management:

  • Data Privacy: “By using Private Endpoints, our company’s proprietary data never leaves our Azure network. It is not used to train public models.”
  • Reliability: “Since traffic stays on the Azure backbone, we avoid latency spikes and potential outages of the public internet.”
  • Workload Identity: “I’ve set this up so our containers don’t need API keys. They use their own identity, which means one less secret for us to rotate or lose.”

Next Steps for Support

Once this is deployed, you can offer to set up AI Token Monitoring:

  1. Create a dashboard in Azure Managed Grafana.
  2. Track “Tokens Consumed” per microservice.
  3. Set alerts for “Token Spikes” to prevent unexpected cloud bills.

To provide the best support, you can give your developers a ready-to-use template for connecting to the secured AI infrastructure.

Since you have set up Workload Identity (no keys), the code uses the DefaultAzureCredential from the @azure/identity library. In 2026, this is the safest and most portable way to authenticate.

1. Python Integration (Standard for Data Analysis)

This script uses the latest OpenAI-compatible Azure SDK. It automatically detects the identity you assigned to the pod.

Python

import os
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from openai import AzureOpenAI
# 1. Setup Identity (No API Keys needed)
credential = DefaultAzureCredential()
token_provider = get_bearer_token_provider(
credential, "https://cognitiveservices.azure.com/.default"
)
# 2. Initialize Client
# These environment variables should be set in your Docker/K8s deployment
client = AzureOpenAI(
azure_ad_token_provider=token_provider,
api_version="2024-05-13", # Latest stable 2026 version
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT")
)
# 3. Simple Chatbot Call
response = client.chat.completions.create(
model=os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"), # e.g., "gpt-4o-deployment"
messages=[
{"role": "system", "content": "You are a data analysis assistant for our Linux/Docker apps."},
{"role": "user", "content": "How can I optimize our container logs?"}
]
)
print(response.choices[0].message.content)

2. Node.js Integration (Standard for Chatbots)

If your microservices are in Node.js, use this pattern:

JavaScript

const { DefaultAzureCredential, getBearerTokenProvider } = require("@azure/identity");
const { AzureOpenAI } = require("openai");
async function main() {
const scope = "https://cognitiveservices.azure.com/.default";
const azureADTokenProvider = getBearerTokenProvider(new DefaultAzureCredential(), scope);
const deployment = process.env.AZURE_OPENAI_DEPLOYMENT_NAME;
const apiVersion = "2024-05-13";
const client = new AzureOpenAI({
azureADTokenProvider,
deployment,
apiVersion,
endpoint: process.env.AZURE_OPENAI_ENDPOINT
});
const result = await client.chat.completions.create({
messages: [{ role: "user", content: "Analyze these logs for errors." }],
model: "", // Model is determined by the deployment name in AzureOpenAI constructor
});
console.log(result.choices[0].message.content);
}
main().catch(console.error);

3. Kubernetes Deployment Checklist (Your “Support” Task)

To make the code above work, you need to ensure the developer’s deployment.yaml has three specific things:

  1. Label for Identity: azure.workload.identity/use: "true"
  2. Service Account: The one linked to your Managed Identity in Terraform.
  3. Environment Variables: * AZURE_OPENAI_ENDPOINT: The private link URL we created (e.g., https://oai-prod-aks-01.openai.azure.com/).
    • AZURE_OPENAI_DEPLOYMENT_NAME: The name of the model (e.g., gpt-4o-deployment).

How to Propose This “Developer Experience” Upgrade

When you present this to the team, focus on how much time you are saving the developers:

“I’ve developed a standardized AI Bootstrap Kit for our microservices. It includes the Terraform infrastructure for secure private networking and ready-to-use code templates. This allows our dev team to add AI chatbots or analysis features in minutes, without worrying about security, API keys, or networking. I’ll handle the ‘plumbing’ so they can focus on the ‘features’.”

Integrating AI with Azure Kubernetes Service in 2026

Integrating Azure Kubernetes Service (AKS) with AI in 2026 generally falls into two categories: Consuming AI (connecting to models like GPT-4 via API) or Hosting AI (running your own models on GPUs).

Since you are already supporting a microservices environment, adding AI capabilities is a natural “next-tier” service to offer.


1. Consuming AI (The “API” Route)

The most common way to integrate AI is by connecting your Docker microservices to Azure OpenAI.

  • Service Connector: Use the Azure Service Connector to link your AKS cluster to an Azure OpenAI resource. This handles the networking and credentials for you.
  • Workload Identity: Avoid using API keys in your code. Grant your pod a User-Assigned Managed Identity and give it the Cognitive Services User role.
  • Vector Databases: If your microservices need “memory” (Retrieval-Augmented Generation or RAG), you can deploy a vector database like Qdrant or Weaviate directly as a Docker container in AKS to store and search through company data.

2. Hosting AI (The “KAITO” Route)

If your client wants to run their own open-source models (like Llama 3 or Mistral) for privacy or cost reasons, you should use the AI Toolchain Operator (KAITO).

  • What is KAITO? It’s an AKS-managed operator that simplifies the complex task of running Large Language Models (LLMs).
  • Auto-Provisioning: KAITO automatically picks the right GPU node size (e.g., Standard_NC) and handles the driver installation so you don’t have to manually configure NVIDIA settings.
  • Inference Presets: It provides pre-configured images for popular models, making it as easy as deploying a regular Docker microservice.

3. Infrastructure Requirements (GPU Nodes)

AI models are compute-heavy. You cannot run them on standard Linux nodes.

  • GPU Node Pools: Add a specialized node pool to your cluster using Terraform or CLI.2026 Best Practice: Use Azure Linux 3.0 as the OS for GPU nodes for better performance and reduced overhead.
  • Scale-to-Zero: Since GPU nodes are expensive ($2-$30+ per hour), configure the Cluster Autoscaler to scale the GPU node pool to zero when no AI jobs are running.

4. Monitoring AI Performance

AI workloads fail differently than web apps. A model might be “up” but providing extremely slow responses.

  • vLLM Metrics: If you use KAITO, it exposes metrics like Time to First Token (TTFT) and Tokens Per Second.
  • Managed Grafana: Import the standard “AI Inference Dashboard” into your Grafana instance to track how much GPU memory your models are consuming and whether you need to scale up.

How to Pitch This to Your Client

You can frame AI integration as a “Modernization Initiative”:

“I can upgrade our AKS cluster to support AI Workloads. We can implement the KAITO Operator to host private, cost-effective models for our internal tools, or use Workload Identity to securely connect our microservices to Azure OpenAI without using risky API keys. This ensures our infrastructure is ‘AI-Ready’ for any future features.”

Automate Velero AKS Backups with Terraform and Ansible

Automating Velero AKS Backup with Ansible & Terraform


Option 1: Terraform

Project Structure

velero-terraform/
├── main.tf
├── variables.tf
├── outputs.tf
├── providers.tf
└── modules/
├── storage/
│ ├── main.tf
│ └── variables.tf
├── identity/
│ ├── main.tf
│ └── variables.tf
└── velero/
├── main.tf
└── variables.tf

providers.tf

terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
helm = {
source = "hashicorp/helm"
version = "~> 2.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.0"
}
}
}
provider "azurerm" {
features {}
}
provider "helm" {
kubernetes {
host = azurerm_kubernetes_cluster.aks.kube_config.0.host
client_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate)
client_key = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_key)
cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.cluster_ca_certificate)
}
}
provider "kubernetes" {
host = azurerm_kubernetes_cluster.aks.kube_config.0.host
client_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_certificate)
client_key = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.client_key)
cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config.0.cluster_ca_certificate)
}

variables.tf

variable "resource_group_name" {
description = "Resource group name"
type = string
default = "myResourceGroup"
}
variable "location" {
description = "Azure region"
type = string
default = "eastus"
}
variable "aks_cluster_name" {
description = "AKS cluster name"
type = string
default = "myAKSCluster"
}
variable "storage_account_name" {
description = "Storage account for Velero backups"
type = string
default = "velerobackupstorage"
}
variable "blob_container_name" {
description = "Blob container for Velero backups"
type = string
default = "velero-backups"
}
variable "velero_namespace" {
description = "Kubernetes namespace for Velero"
type = string
default = "velero"
}
variable "backup_retention_hours" {
description = "Backup TTL in hours"
type = number
default = 720 # 30 days
}
variable "backup_schedule" {
description = "Cron schedule for backups"
type = string
default = "0 2 * * *" # Daily at 2am
}

main.tf

# Resource Group
resource "azurerm_resource_group" "rg" {
name = var.resource_group_name
location = var.location
}
# ── STORAGE ──────────────────────────────────────────────
resource "azurerm_storage_account" "velero" {
name = var.storage_account_name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
blob_properties {
delete_retention_policy {
days = 30
}
}
tags = {
purpose = "velero-backup"
}
}
resource "azurerm_storage_container" "velero" {
name = var.blob_container_name
storage_account_name = azurerm_storage_account.velero.name
container_access_type = "private"
}
# ── IDENTITY ─────────────────────────────────────────────
resource "azurerm_user_assigned_identity" "velero" {
name = "velero-identity"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
}
# Assign Contributor role to storage account
resource "azurerm_role_assignment" "velero_storage" {
scope = azurerm_storage_account.velero.id
role_definition_name = "Storage Blob Data Contributor"
principal_id = azurerm_user_assigned_identity.velero.principal_id
}
# Assign Contributor role to resource group (for disk snapshots)
resource "azurerm_role_assignment" "velero_rg" {
scope = azurerm_resource_group.rg.id
role_definition_name = "Contributor"
principal_id = azurerm_user_assigned_identity.velero.principal_id
}
# ── AKS CLUSTER ──────────────────────────────────────────
resource "azurerm_kubernetes_cluster" "aks" {
name = var.aks_cluster_name
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
dns_prefix = var.aks_cluster_name
default_node_pool {
name = "default"
node_count = 2
vm_size = "Standard_D2_v2"
}
identity {
type = "SystemAssigned"
}
tags = {
environment = "production"
}
}
# ── VELERO NAMESPACE ─────────────────────────────────────
resource "kubernetes_namespace" "velero" {
metadata {
name = var.velero_namespace
}
depends_on = [azurerm_kubernetes_cluster.aks]
}
# ── VELERO CREDENTIALS SECRET ────────────────────────────
resource "kubernetes_secret" "velero_credentials" {
metadata {
name = "velero-credentials"
namespace = kubernetes_namespace.velero.metadata[0].name
}
data = {
"cloud" = <<EOF
AZURE_SUBSCRIPTION_ID=${data.azurerm_subscription.current.subscription_id}
AZURE_TENANT_ID=${data.azurerm_subscription.current.tenant_id}
AZURE_CLIENT_ID=${azurerm_user_assigned_identity.velero.client_id}
AZURE_RESOURCE_GROUP=${azurerm_resource_group.rg.name}
AZURE_CLOUD_NAME=AzurePublicCloud
EOF
}
}
# Current subscription data
data "azurerm_subscription" "current" {}
# ── VELERO HELM RELEASE ──────────────────────────────────
resource "helm_release" "velero" {
name = "velero"
repository = "https://vmware-tanzu.github.io/helm-charts"
chart = "velero"
namespace = kubernetes_namespace.velero.metadata[0].name
version = "5.0.0"
values = [
yamlencode({
configuration = {
provider = "azure"
backupStorageLocation = {
name = "default"
provider = "velero.io/azure"
bucket = azurerm_storage_container.velero.name
config = {
resourceGroup = azurerm_resource_group.rg.name
storageAccount = azurerm_storage_account.velero.name
subscriptionId = data.azurerm_subscription.current.subscription_id
}
}
volumeSnapshotLocation = {
name = "default"
provider = "velero.io/azure"
config = {
resourceGroup = azurerm_resource_group.rg.name
subscriptionId = data.azurerm_subscription.current.subscription_id
}
}
}
credentials = {
existingSecret = kubernetes_secret.velero_credentials.metadata[0].name
}
initContainers = [
{
name = "velero-plugin-for-azure"
image = "velero/velero-plugin-for-microsoft-azure:v1.8.0"
imagePullPolicy = "IfNotPresent"
volumeMounts = [
{
mountPath = "/target"
name = "plugins"
}
]
}
]
schedules = {
daily-backup = {
schedule = var.backup_schedule
template = {
ttl = "${var.backup_retention_hours}h0m0s"
includeClusterResources = true
excludedNamespaces = ["kube-system", "velero"]
}
}
}
})
]
depends_on = [
kubernetes_secret.velero_credentials,
azurerm_role_assignment.velero_storage,
azurerm_role_assignment.velero_rg
]
}

outputs.tf

output "storage_account_name" {
value = azurerm_storage_account.velero.name
}
output "blob_container_name" {
value = azurerm_storage_container.velero.name
}
output "velero_identity_client_id" {
value = azurerm_user_assigned_identity.velero.client_id
}
output "aks_cluster_name" {
value = azurerm_kubernetes_cluster.aks.name
}
output "kube_config" {
value = azurerm_kubernetes_cluster.aks.kube_config_raw
sensitive = true
}

Deploy with Terraform

# Initialize
terraform init
# Preview changes
terraform plan -out=tfplan
# Apply
terraform apply tfplan
# Get kubeconfig
terraform output -raw kube_config > ~/.kube/config
# Verify Velero
kubectl get pods -n velero
velero backup-location get


Option 2: Ansible

Project Structure

velero-ansible/
├── inventory/
│ └── hosts.yml
├── group_vars/
│ └── all.yml
├── roles/
│ ├── azure_storage/
│ │ └── tasks/
│ │ └── main.yml
│ ├── azure_identity/
│ │ └── tasks/
│ │ └── main.yml
│ └── velero/
│ ├── tasks/
│ │ └── main.yml
│ └── templates/
│ ├── credentials.j2
│ └── backup-schedule.yml.j2
└── site.yml

group_vars/all.yml

# Azure Settings
resource_group: "myResourceGroup"
location: "eastus"
aks_cluster_name: "myAKSCluster"
# Storage Settings
storage_account_name: "velerobackupstorage"
blob_container_name: "velero-backups"
# Velero Settings
velero_namespace: "velero"
velero_version: "v1.12.0"
velero_azure_plugin_version: "v1.8.0"
velero_chart_version: "5.0.0"
# Backup Settings
backup_schedule: "0 2 * * *"
backup_ttl: "720h"
backup_name: "daily-backup"
# Namespaces to exclude
excluded_namespaces:
- kube-system
- velero

roles/azure_storage/tasks/main.yml

---
- name: Create Resource Group
azure.azcollection.azure_rm_resourcegroup:
name: "{{ resource_group }}"
location: "{{ location }}"
state: present
- name: Create Storage Account
azure.azcollection.azure_rm_storageaccount:
resource_group: "{{ resource_group }}"
name: "{{ storage_account_name }}"
type: Standard_LRS
kind: StorageV2
state: present
register: storage_account_result
- name: Create Blob Container
azure.azcollection.azure_rm_storageblob:
resource_group: "{{ resource_group }}"
storage_account_name: "{{ storage_account_name }}"
container: "{{ blob_container_name }}"
state: present
- name: Get Storage Account Keys
azure.azcollection.azure_rm_storageaccount_info:
resource_group: "{{ resource_group }}"
name: "{{ storage_account_name }}"
register: storage_info
- name: Set Storage Key Fact
set_fact:
storage_account_key: "{{ storage_info.storageaccounts[0].primary_endpoints.key }}"

roles/azure_identity/tasks/main.yml

---
- name: Get Azure Subscription Info
azure.azcollection.azure_rm_subscription_info:
register: subscription_info
- name: Set Subscription Facts
set_fact:
subscription_id: "{{ subscription_info.subscriptions[0].subscription_id }}"
tenant_id: "{{ subscription_info.subscriptions[0].tenant_id }}"
- name: Create Service Principal for Velero
azure.azcollection.azure_rm_adserviceprincipal:
app_id: "velero-sp"
state: present
register: sp_result
- name: Assign Contributor Role to Service Principal
azure.azcollection.azure_rm_roleassignment:
scope: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}"
assignee_object_id: "{{ sp_result.object_id }}"
role_definition_name: Contributor
state: present
- name: Assign Storage Blob Contributor Role
azure.azcollection.azure_rm_roleassignment:
scope: "/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}/providers/Microsoft.Storage/storageAccounts/{{ storage_account_name }}"
assignee_object_id: "{{ sp_result.object_id }}"
role_definition_name: "Storage Blob Data Contributor"
state: present

roles/velero/templates/credentials.j2

AZURE_SUBSCRIPTION_ID={{ subscription_id }}
AZURE_TENANT_ID={{ tenant_id }}
AZURE_CLIENT_ID={{ client_id }}
AZURE_CLIENT_SECRET={{ client_secret }}
AZURE_RESOURCE_GROUP={{ resource_group }}
AZURE_CLOUD_NAME=AzurePublicCloud

roles/velero/templates/backup-schedule.yml.j2

apiVersion: velero.io/v1
kind: Schedule
metadata:
name: {{ backup_name }}
namespace: {{ velero_namespace }}
spec:
schedule: "{{ backup_schedule }}"
template:
ttl: "{{ backup_ttl }}"
includeClusterResources: true
excludedNamespaces:
{% for ns in excluded_namespaces %}
- {{ ns }}
{% endfor %}

roles/velero/tasks/main.yml

---
- name: Create Velero Namespace
kubernetes.core.k8s:
name: "{{ velero_namespace }}"
api_version: v1
kind: Namespace
state: present
- name: Create Velero Credentials File
template:
src: credentials.j2
dest: /tmp/credentials-velero
mode: '0600'
- name: Create Kubernetes Secret for Velero Credentials
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Secret
metadata:
name: velero-credentials
namespace: "{{ velero_namespace }}"
stringData:
cloud: |
AZURE_SUBSCRIPTION_ID={{ subscription_id }}
AZURE_TENANT_ID={{ tenant_id }}
AZURE_CLIENT_ID={{ client_id }}
AZURE_CLIENT_SECRET={{ client_secret }}
AZURE_RESOURCE_GROUP={{ resource_group }}
AZURE_CLOUD_NAME=AzurePublicCloud
- name: Add Velero Helm Repository
kubernetes.core.helm_repository:
name: vmware-tanzu
repo_url: "https://vmware-tanzu.github.io/helm-charts"
state: present
- name: Install Velero via Helm
kubernetes.core.helm:
name: velero
chart_ref: vmware-tanzu/velero
chart_version: "{{ velero_chart_version }}"
namespace: "{{ velero_namespace }}"
state: present
values:
configuration:
provider: azure
backupStorageLocation:
name: default
provider: velero.io/azure
bucket: "{{ blob_container_name }}"
config:
resourceGroup: "{{ resource_group }}"
storageAccount: "{{ storage_account_name }}"
subscriptionId: "{{ subscription_id }}"
volumeSnapshotLocation:
name: default
provider: velero.io/azure
config:
resourceGroup: "{{ resource_group }}"
subscriptionId: "{{ subscription_id }}"
credentials:
existingSecret: velero-credentials
initContainers:
- name: velero-plugin-for-azure
image: "velero/velero-plugin-for-microsoft-azure:{{ velero_azure_plugin_version }}"
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /target
name: plugins
- name: Wait for Velero Pod to be Ready
kubernetes.core.k8s_info:
kind: Pod
namespace: "{{ velero_namespace }}"
label_selectors:
- app.kubernetes.io/name=velero
register: velero_pod
until: velero_pod.resources[0].status.phase == "Running"
retries: 10
delay: 15
- name: Apply Backup Schedule
kubernetes.core.k8s:
state: present
template: backup-schedule.yml.j2
- name: Verify Backup Location
command: velero backup-location get
register: backup_location_status
changed_when: false
- name: Display Backup Location Status
debug:
msg: "{{ backup_location_status.stdout }}"
- name: Clean Up Credentials File
file:
path: /tmp/credentials-velero
state: absent

site.yml (Main Playbook)

---
- name: Setup Velero Backup for AKS
hosts: localhost
connection: local
gather_facts: false
pre_tasks:
- name: Verify required tools are installed
command: "{{ item }} --version"
loop:
- az
- kubectl
- helm
register: tool_check
changed_when: false
- name: Verify AKS context
command: kubectl cluster-info
register: cluster_info
changed_when: false
- name: Display cluster info
debug:
msg: "{{ cluster_info.stdout_lines[0] }}"
roles:
- azure_storage
- azure_identity
- velero
post_tasks:
- name: Trigger initial manual backup
command: >
velero backup create initial-backup
--include-cluster-resources=true
--wait
register: initial_backup
changed_when: true
- name: Display backup result
debug:
msg: "{{ initial_backup.stdout }}"

Run the Ansible Playbook

# Install required collections
ansible-galaxy collection install azure.azcollection
ansible-galaxy collection install kubernetes.core
# Install Python dependencies
pip install ansible[azure] kubernetes
# Run the playbook
ansible-playbook site.yml -v
# Run specific role only
ansible-playbook site.yml --tags "velero" -v
# Dry run
ansible-playbook site.yml --check -v

Comparison: Terraform vs Ansible

FeatureTerraformAnsible
Best ForInfrastructure provisioningConfiguration & app deployment
State ManagementYes (tfstate file)No native state
IdempotencyBuilt-inTask-level
Azure ResourcesExcellentGood
Kubernetes ResourcesGoodExcellent
Learning CurveMediumLow
RollbackVia stateManual
Recommended UseCreate AKS + StorageInstall & configure Velero

Best Practice: Combine Both

Terraform → Creates Azure infrastructure (AKS, Storage, Identity)
Ansible → Installs and configures Velero on the cluster
Velero → Runs scheduled backups automatically

This gives you the best of both worlds — Terraform for infrastructure and Ansible for application configuration.

How to Backup AKS with Velero: A Step-by-Step Guide

Backing Up AKS with Velero

Prerequisites

  • AKS cluster running
  • Azure CLI installed
  • kubectl configured
  • Helm installed

Step 1: Create Azure Storage Account & Blob Container

# Set variables
RESOURCE_GROUP="myResourceGroup"
LOCATION="eastus"
STORAGE_ACCOUNT="velerobackupstorage"
BLOB_CONTAINER="velero-backups"
AKS_CLUSTER="myAKSCluster"
# Create resource group (if not exists)
az group create --name $RESOURCE_GROUP --location $LOCATION
# Create storage account
az storage account create \
--name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP \
--location $LOCATION \
--sku Standard_LRS \
--encryption-services blob
# Create blob container
az storage container create \
--name $BLOB_CONTAINER \
--account-name $STORAGE_ACCOUNT

Step 2: Create Service Principal for Velero

# Create service principal
AZURE_SUBSCRIPTION_ID=$(az account show --query id -o tsv)
AZURE_TENANT_ID=$(az account show --query tenantId -o tsv)
# Create SP and assign contributor role
AZURE_CLIENT_SECRET=$(az ad sp create-for-rbac \
--name velero-sp \
--role Contributor \
--scopes /subscriptions/$AZURE_SUBSCRIPTION_ID \
--query password \
-o tsv)
AZURE_CLIENT_ID=$(az ad sp list \
--display-name velero-sp \
--query '[0].appId' \
-o tsv)
echo "Client ID: $AZURE_CLIENT_ID"
echo "Client Secret: $AZURE_CLIENT_SECRET"

Step 3: Create Velero Credentials File

# Create credentials file
cat << EOF > ./credentials-velero
AZURE_SUBSCRIPTION_ID=${AZURE_SUBSCRIPTION_ID}
AZURE_TENANT_ID=${AZURE_TENANT_ID}
AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
AZURE_RESOURCE_GROUP=${RESOURCE_GROUP}
AZURE_CLOUD_NAME=AzurePublicCloud
EOF

Step 4: Install Velero on AKS

# Add Velero Helm repo
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm repo update
# Get storage account access key
STORAGE_ACCOUNT_KEY=$(az storage account keys list \
--account-name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP \
--query '[0].value' \
-o tsv)
# Install Velero with Azure plugin
velero install \
--provider azure \
--plugins velero/velero-plugin-for-microsoft-azure:v1.8.0 \
--bucket $BLOB_CONTAINER \
--secret-file ./credentials-velero \
--backup-location-config \
resourceGroup=$RESOURCE_GROUP,\
storageAccount=$STORAGE_ACCOUNT,\
storageAccountKeyEnvVar=AZURE_STORAGE_ACCOUNT_ACCESS_KEY \
--snapshot-location-config \
resourceGroup=$RESOURCE_GROUP,\
apiTimeout=5m \
--use-volume-snapshots=true \
--wait

Step 5: Verify Velero Installation

# Check Velero pods are running
kubectl get pods -n velero
# Check backup storage location is available
velero backup-location get
# Expected output:
# NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED
# default azure velero-backups Available ...

Step 6: Create Backups

Manual Backup (Full Cluster)

# Backup entire cluster
velero backup create full-cluster-backup \
--include-cluster-resources=true \
--wait
# Check backup status
velero backup describe full-cluster-backup
velero backup logs full-cluster-backup

Backup Specific Namespace

# Backup a single namespace
velero backup create my-app-backup \
--include-namespaces my-app-namespace \
--wait
# Backup multiple namespaces
velero backup create multi-ns-backup \
--include-namespaces namespace1,namespace2 \
--wait

Backup with Labels

# Backup resources matching a label
velero backup create label-backup \
--selector app=my-application \
--wait

Exclude Specific Resources

# Exclude secrets and specific namespaces
velero backup create selective-backup \
--exclude-namespaces kube-system,velero \
--exclude-resources secrets \
--wait

Step 7: Schedule Automated Backups

# Daily backup at 2am UTC (keep 30 days)
velero schedule create daily-backup \
--schedule="0 2 * * *" \
--ttl 720h \
--include-cluster-resources=true
# Weekly backup every Sunday at midnight (keep 90 days)
velero schedule create weekly-backup \
--schedule="0 0 * * 0" \
--ttl 2160h
# Namespace-specific daily backup
velero schedule create daily-app-backup \
--schedule="0 2 * * *" \
--include-namespaces production \
--ttl 168h
# List all schedules
velero schedule get

Step 8: Restore from Backup

Full Restore

# List available backups
velero backup get
# Restore full cluster backup
velero restore create \
--from-backup full-cluster-backup \
--wait
# Check restore status
velero restore get
velero restore describe <restore-name>

Restore Specific Namespace

# Restore a specific namespace
velero restore create \
--from-backup my-app-backup \
--include-namespaces my-app-namespace \
--wait

Restore to Different Namespace

# Restore namespace-A into namespace-B
velero restore create \
--from-backup my-app-backup \
--namespace-mappings old-namespace:new-namespace \
--wait

Restore Specific Resources Only

# Restore only deployments and services
velero restore create \
--from-backup full-cluster-backup \
--include-resources deployments,services \
--wait

Step 9: Backup Hooks (Pre/Post Actions)

Useful for database consistency before backup:

# deployment-with-backup-hooks.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
annotations:
pre.hook.backup.velero.io/command: '["/bin/bash", "-c", "mysqldump -u root -p$MYSQL_ROOT_PASSWORD mydb > /backup/dump.sql"]'
pre.hook.backup.velero.io/timeout: "60s"
post.hook.backup.velero.io/command: '["/bin/bash", "-c", "rm -f /backup/dump.sql"]'
kubectl apply -f deployment-with-backup-hooks.yaml

Step 10: Monitor & Troubleshoot

# View backup details
velero backup describe my-backup --details
# View backup logs
velero backup logs my-backup
# View restore logs
velero restore logs my-restore
# Check Velero server logs
kubectl logs deployment/velero -n velero
# List all backups with status
velero backup get
# Delete old backup manually
velero backup delete old-backup-name

Summary Cheat Sheet

TaskCommand
Full backupvelero backup create <name> --include-cluster-resources=true
Namespace backupvelero backup create <name> --include-namespaces <ns>
Schedule dailyvelero schedule create <name> --schedule="0 2 * * *"
List backupsvelero backup get
Restore backupvelero restore create --from-backup <name>
Check statusvelero backup describe <name>
View logsvelero backup logs <name>

Best Practices

  • Test restores regularly – don’t wait for disaster to find out your backup is broken
  • Use TTL to automatically expire old backups and save storage costs
  • Backup before upgrades – always take a snapshot before AKS version upgrades
  • Store credentials securely – use Azure Key Vault instead of plain credentials files
  • Use hooks for databases to ensure data consistency
  • Cross-region storage – store backups in a different Azure region for disaster recovery
  • Combine with GitOps – use Velero for stateful data + Git for manifests

Top Methods for Backing Up AKS Effectively

There are several ways to back up AKS:

1. Velero (Most Popular Open-Source Tool)

  • Backs up Kubernetes resources (deployments, configmaps, secrets, etc.)
  • Backs up persistent volumes using snapshots
  • Stores backups in Azure Blob Storage
  • Supports scheduled backups and restores to same or different cluster

2. Azure Backup for AKS (Native Solution)

  • Microsoft’s built-in backup service for AKS
  • Backs up workloads and persistent volumes
  • Managed via Azure Portal, CLI, or ARM templates
  • Supports backup policies and restore points
  • Integrates with Azure Backup Vault

3. Persistent Volume Snapshots

  • Use Azure Disk Snapshots for stateful data
  • Can be automated via Azure Snapshot Policies
  • Best for database workloads (SQL, MongoDB, etc.)

4. GitOps / Infrastructure as Code

  • Store all manifests in Git (Helm charts, YAML files)
  • Tools like Flux or ArgoCD redeploy state from Git
  • Not a traditional backup but enables fast cluster recreation

5. etcd Backup

  • Backs up the cluster state directly
  • More relevant for self-managed Kubernetes; in AKS, Microsoft manages etcd

What You Should Typically Back Up

  • Kubernetes manifests (deployments, services, configmaps)
  • Secrets (or reference them from Key Vault)
  • Persistent volume data
  • Namespace configurations
  • RBAC roles and bindings

Best Practice Recommendation

ApproachBest For
Azure Backup for AKSSimplicity, native Azure integration
Velero + Blob StorageFlexibility, multi-cloud, open-source
GitOpsStateless workloads, fast redeployment
Disk SnapshotsStateful apps with heavy data

A solid strategy usually combines Azure Backup or Velero for cluster state + Disk Snapshots for persistent data + GitOps for fast recovery.

Key Components of Azure Kubernetes Service Explained

Azure Kubernetes Service (AKS) has these main components:

Control Plane (managed by Azure)

  • API Server – entry point for all Kubernetes commands and REST requests
  • etcd – distributed key-value store that holds the cluster state and configuration
  • Scheduler – assigns pods to nodes based on resource availability
  • Controller Manager – maintains desired cluster state (handles node, pod, and endpoint controllers)

Data Plane (managed by you)

  • Nodes – VMs that run your workloads; grouped into node pools
  • Kubelet – agent on each node that ensures containers are running as instructed
  • Kube-proxy – handles network routing and load balancing across pods
  • Container Runtime – runs containers (AKS uses containerd by default)

Networking

  • Virtual Network (VNet) – connects nodes and pods; supports kubenet and Azure CNI
  • Load Balancer – exposes services externally
  • DNS – CoreDNS for internal service discovery
  • Ingress Controller – manages external HTTP/S routing into the cluster

Storage

  • Persistent Volumes (PV) – backed by Azure Disks or Azure Files
  • Storage Classes – define dynamic provisioning policies

Identity & Security

  • Azure Active Directory (Entra ID) integration – for RBAC and authentication
  • Managed Identity – allows AKS to interact with other Azure services securely
  • Azure Key Vault – secrets management via the Secrets Store CSI driver

Monitoring & Management

  • Azure Monitor / Container Insights – metrics, logs, and diagnostics
  • Cluster Autoscaler – automatically scales nodes based on demand
  • Horizontal Pod Autoscaler (HPA) – scales pods based on CPU/memory usage

Top AKS Troubleshooting Steps for Common Issues

AKS Troubleshooting Decision Tree

AKS ISSUE
├── 1. Is the app unreachable?
│ │
│ ├── External access issue
│ │ ├── Check DNS
│ │ ├── Check Public/Internal Load Balancer
│ │ ├── Check Ingress Controller
│ │ ├── Check Service
│ │ └── Check Pods
│ │
│ └── Internal access issue
│ ├── Check Service name
│ ├── Check CoreDNS
│ ├── Check Network Policy
│ └── Check Pod-to-Pod connectivity
├── 2. Are pods not running?
│ │
│ ├── Pending
│ │ ├── Not enough CPU/memory
│ │ ├── Taints/tolerations issue
│ │ ├── Node selector/affinity issue
│ │ ├── Cluster autoscaler maxed out
│ │ └── Subnet IP exhaustion
│ │
│ ├── ImagePullBackOff
│ │ ├── Wrong image name/tag
│ │ ├── ACR permission missing
│ │ └── Network/DNS issue to registry
│ │
│ └── CrashLoopBackOff
│ ├── App bug
│ ├── Missing secret/config map
│ ├── Bad env variable
│ └── Probe misconfigured
├── 3. Are nodes unhealthy?
│ │
│ ├── Node NotReady
│ │ ├── VMSS health
│ │ ├── Kubelet issue
│ │ ├── Disk pressure
│ │ ├── Memory pressure
│ │ └── Network issue
│ │
│ └── Node pool issue
│ ├── Upgrade failed
│ ├── Scale operation failed
│ └── Quota/capacity issue
├── 4. Is it a networking issue?
│ │
│ ├── DNS failure
│ │ ├── CoreDNS
│ │ ├── Private DNS zone
│ │ └── Custom DNS forwarders
│ │
│ ├── Routing failure
│ │ ├── UDR
│ │ ├── Azure Firewall
│ │ ├── NSG
│ │ └── Route table association
│ │
│ └── Private Endpoint failure
│ ├── DNS resolves to private IP?
│ ├── VNet peering working?
│ ├── NSG allows traffic?
│ └── Private endpoint approved?
├── 5. Is it identity/security?
│ │
│ ├── Azure resource access failing
│ │ ├── Managed identity assigned?
│ │ ├── RBAC role correct?
│ │ └── Workload Identity configured?
│ │
│ └── Kubernetes access failing
│ ├── Azure AD login?
│ ├── Kubernetes RBAC?
│ └── Namespace permissions?
└── 6. Is it platform-wide?
├── Multiple services affected
│ ├── Check Azure Service Health
│ ├── Check regional outage
│ └── Check dependency outage
└── Only one app affected
├── Check recent deployment
├── Rollback if needed
└── Compare config/secrets

Memorize This Shortcut

DNS → LB/Ingress → Service → Pod → Node → Network → Identity → Azure

Interview Line

“I troubleshoot AKS layer by layer: first access path, then Kubernetes objects, then node health, then Azure networking, identity, and platform dependencies.”

Top Scenarios to Ace Your AKS Interviews

These are the kinds of enterprise failure scenarios where interviewers test depth, not just commands. A real interview: scenario → pressure → how you respond → what impresses.


Scenario 1: Entire AKS Cluster Becomes Unreachable

Situation

  • Apps are down
  • kubectl not responding
  • API server unreachable

What’s actually happening?

In Azure Kubernetes Service, the control plane is managed by Azure—so this is usually:

  • Network isolation issue (private cluster)
  • DNS issue
  • Azure-side outage (rare)

How to respond (structured)

1. Validate scope

  • Is it just you or everyone?
  • Can CI/CD still deploy?

2. Check cluster type

  • Private cluster?
  • API server behind Private Endpoint?

3. DNS resolution

  • Does API server FQDN resolve?

4. Network path

  • VPN / ExpressRoute working?
  • NSG blocking?

5. Azure health

  • Region outage?

Strong answer

“Since AKS control plane is managed, I’d immediately suspect network or DNS issues—especially in private clusters. I’d validate API server resolution, connectivity path, and Azure service health.”


Scenario 2: Production Outage After Deployment

Situation

  • New release deployed
  • All pods running
  • App returning 500 errors

Key Insight

This is NOT infrastructure—it’s application or config.


Approach

1. Rollback immediately

kubectl rollout undo deployment <app>

2. Compare versions

  • Env vars changed?
  • Secrets updated?

3. Check logs

  • App-level errors

4. Validate dependencies

  • DB reachable?
  • API endpoints correct?

Strong answer

“If pods are healthy but app fails, I treat it as an application issue. I’d rollback first to restore service, then investigate config drift or dependency failures.”


Scenario 3: Intermittent Failures Across Services

Situation

  • Random timeouts
  • Some requests succeed, others fail

Think: networking or scaling


Likely Causes

  • SNAT port exhaustion
  • DNS latency
  • Pod autoscaling delays
  • Node pressure

What you check

1. Node metrics

  • CPU/memory spikes

2. Pod distribution

  • Are pods unevenly spread?

3. Networking limits

  • Outbound connections?

Strong answer

“Intermittent failures usually point to resource contention or networking limits like SNAT exhaustion. I’d correlate metrics with traffic patterns.”


Scenario 4: AKS Can’t Pull Images from ACR

Situation

  • Pods stuck in ImagePullBackOff

Root cause area

  • Identity / permissions

Common causes

  • AKS not authorized to Azure Container Registry
  • Managed identity missing role

Fix

  • Assign AcrPull role to AKS identity

Strong answer

“This is typically a managed identity RBAC issue. I’d verify the cluster identity has AcrPull access to the registry.”


Scenario 5: Traffic Not Routing in Private AKS

Situation

  • Internal services work
  • External users can’t reach app

Think enterprise networking


Check:

1. Ingress controller

  • Running?

2. Azure Load Balancer / App Gateway

3. NSG rules

  • Ports open?

4. DNS

  • Internal vs external resolution

Strong answer

“In private AKS, exposure depends on controlled ingress. I’d trace traffic from DNS to ingress to service, checking NSGs and routing.”


Scenario 6: Cluster Autoscaler Not Working

Situation

  • Pods stuck in Pending
  • Nodes not scaling

Key checks

  • Autoscaler enabled?
  • Max node limit reached?
  • Subnet IP exhausted?

Strong answer

“Autoscaling failures often tie back to limits—either max node count or subnet capacity in Azure CNI setups.”


Scenario 7: Security Breach Suspicion

Situation

  • Unexpected outbound traffic
  • Suspicious container behavior

What matters

Containment + investigation


Actions

1. Isolate

  • Scale down or cordon node

2. Inspect

  • Container logs
  • Image source

3. Check runtime security

  • Alerts from Microsoft Defender for Cloud

Strong answer

“I’d isolate affected workloads immediately, then investigate logs and image provenance while leveraging Defender for alerts.”


Scenario 8: Multi-Region Failover Fails

Situation

  • Primary region down
  • Traffic not failing over

Root causes

  • DNS not switching
  • Traffic manager misconfigured
  • Backend unhealthy

Strong answer

“I’d validate DNS failover mechanism (Traffic Manager/Front Door), then confirm secondary cluster health and readiness.”


ENTERPRISE TROUBLESHOOTING MINDSET

Always think in layers:

1. Application

  • Logs, config, dependencies

2. Kubernetes

  • Pods, services, scheduling

3. Node / Compute

  • VMSS health

4. Networking

  • VNet, NSG, DNS

5. Azure Platform

  • Identity, RBAC, outages

What Interviewers REALLY Want

They’re looking for:

  • Structured thinking
  • Fast isolation of failure domain
  • Awareness of Azure-specific constraints
  • Calm, rollback-first mindset

If you want to go even deeper:

Top Azure Kubernetes Service Interview Questions

Here are high-impact Azure Kubernetes Service (AKS) interview questions—the kind that actually get asked in real interviews—plus what interviewers are looking for in your answers.


1. AKS Fundamentals

What is Azure Kubernetes Service (AKS)?
  • Managed Kubernetes cluster on Azure
  • Azure manages control plane (free), you manage node pools
  • Integrates with Azure networking, identity, and security services

Interviewer wants:

  • You understand shared responsibility
  • You know why AKS vs self-managed Kubernetes

Difference between AKS and Kubernetes?
  • Kubernetes = open-source container orchestrator
  • AKS = managed implementation of Kubernetes in Azure

Bonus:

  • Mention upgrades, scaling, monitoring handled by Azure

2. Architecture & Components

What are the main components of AKS?

  • Control plane (API server, scheduler, etcd)
  • Node pools (VMs running pods)
  • Pods, deployments, services

Strong answer:

  • Mention system node pool vs user node pool

What is a node pool?
  • Group of nodes with same configuration
  • Used for:
    • Scaling
    • Workload isolation (e.g., GPU vs general compute)

System node pool vs user node pool?
  • System pool → runs critical pods (CoreDNS, kube-proxy)
  • User pool → runs your apps

Interview tip: mention taints/tolerations


3. Networking (VERY IMPORTANT)

How does networking work in AKS?
Image
  • Two main models:
    • Kubenet
    • Azure CNI

Kubenet vs Azure CNI?
FeatureKubenetAzure CNI
IP assignmentNATReal VNet IP
ScalabilityBetterLimited by subnet
ComplexityLowerHigher
Use caseSmall clustersEnterprise

Strong answer:

  • Azure CNI = required for private endpoints / enterprise networking

What is a private AKS cluster?
  • API server is exposed via private IP
  • No public access

Mention:

  • Uses Private Endpoint + Private DNS

How do you expose applications?
  • LoadBalancer service
  • Ingress Controller (e.g., NGINX, AGIC)

Bonus:

  • Mention Application Gateway Ingress Controller (AGIC)

4. Identity & Security

How does AKS handle identity?
  • Uses Azure Active Directory
  • Managed Identity for cluster
  • RBAC for authorization

What is pod identity?
  • Allows pods to access Azure resources securely

Mention:

  • Workload Identity (modern replacement)

How do you secure AKS?
  • Network policies
  • RBAC
  • Private clusters
  • Secrets via Key Vault
  • Defender for Kubernetes

Strong answer = layered security


5. Scaling & Availability

How do you scale AKS?
  • Horizontal Pod Autoscaler (HPA)
  • Cluster Autoscaler

👉 Explain:

  • HPA = pods
  • Cluster autoscaler = nodes

How do you ensure high availability?
  • Multiple node pools
  • Availability zones
  • Replica sets

6. Storage

How does storage work in AKS?
  • Persistent Volumes (PV)
  • Persistent Volume Claims (PVC)
  • Azure Disks / Azure Files

Azure Disk vs Azure File?
FeatureDiskFile
AccessSingle podMultiple pods
PerformanceHighModerate

7. CI/CD & Deployment

How do you deploy apps to AKS?
  • kubectl
  • Helm
  • GitHub Actions / Azure DevOps

What is Helm?
  • Kubernetes package manager

Think:

  • “apt-get for Kubernetes”

8. Monitoring & Troubleshooting

How do you monitor AKS?
  • Azure Monitor
  • Log Analytics
  • Container Insights

Pod is not starting—what do you check?

👉 Interview GOLD answer:

  1. kubectl describe pod
  2. kubectl logs
  3. Check events
  4. Image pull issues?
  5. Resource limits?

Node is not ready—what do you check?
  • VM health
  • kubelet status
  • networking issues
  • disk pressure

9. Real-World Scenario Questions

Your app is not reachable externally—what do you check?
  • Service type (LoadBalancer?)
  • NSG rules
  • Ingress config
  • DNS resolution

Pods cannot reach database in Azure SQL
  • VNet integration
  • Private endpoint DNS
  • NSG / firewall rules

Cluster ran out of IPs

This is a BIG one:

  • Happens in Azure CNI
  • Fix:
    • Increase subnet size
    • Use multiple node pools
    • Switch to overlay (advanced)

10. Advanced / Senior-Level Questions

How do you design AKS for enterprise?
  • Hub-spoke networking
  • Private cluster
  • Azure Firewall
  • Azure Policy
  • Multiple environments (dev/test/prod)

What are common AKS pitfalls?
  • IP exhaustion
  • Misconfigured DNS
  • Over-permissioned identities
  • No autoscaling

How do you upgrade AKS safely?
  • Upgrade node pools one at a time
  • Use surge upgrade
  • Test in staging

If You Want to Stand Out

Say things like:

  • “I’d default to private AKS + Azure CNI in enterprise”
  • “I always plan subnet sizing early to avoid IP exhaustion”
  • “I separate system and user node pools for reliability”

I’ll walk you through real interview-style troubleshooting drills, the way an interviewer would push you step-by-step.


Drill 1: “Pod is stuck in Pending”

Scenario

You deploy an app, but the pod never starts.


How you should think (out loud)

Step 1 — Describe the pod

kubectl describe pod <pod-name>

Look for:

  • Insufficient CPU/Memory
  • node affinity
  • taints not tolerated

Common Root Causes

1. Not enough resources

  • Node pool too small
  • No autoscaler

2. Taints / tolerations mismatch

  • Pod can’t be scheduled

3. No available nodes

  • Cluster autoscaler disabled or maxed out

Strong interview answer

“I’d start with kubectl describe pod to check scheduling events. Most Pending issues are either resource constraints, taints, or node availability. Then I’d verify node pool capacity and autoscaler behavior.”


Drill 2: “Pod is crashing (CrashLoopBackOff)”

Scenario

Pod starts but keeps restarting.


Steps

Step 1 — Check logs

kubectl logs <pod-name>

Step 2 — Describe pod

kubectl describe pod <pod-name>

Common Causes
  • App crash (bad config, env vars)
  • Liveness probe killing container
  • Missing secret/config map

Pro answer

“I’d first check container logs, then validate probes and configuration dependencies like secrets. CrashLoopBackOff is usually application or probe-related.”


Drill 3: “App not accessible externally”

Scenario

App deployed but browser can’t reach it.


Debug flow
Image
Image

Step-by-step
  1. Check service
kubectl get svc
  • Is it LoadBalancer?

  1. Check external IP
  • Assigned or stuck in <pending>?

  1. Check ingress
kubectl get ingress

  1. Check NSG / firewall
  • Port 80/443 open?

  1. DNS resolution
  • Is domain pointing correctly?

Common Causes
  • Service is ClusterIP only
  • NSG blocking traffic
  • Ingress misconfigured
  • Backend pods not healthy

Strong answer

“I’d trace from outside in: DNS → Load Balancer → Ingress → Service → Pod. That quickly isolates where traffic is breaking.”


Drill 4: “Pods cannot reach Azure SQL / external service”

Scenario

App runs but can’t connect to DB.


Think networking first

Steps
  1. Test from inside pod
kubectl exec -it <pod> -- curl <endpoint>

  1. Check DNS resolution
nslookup <db-name>

  1. Check networking
  • VNet integration
  • Private endpoint?

  1. Check NSG rules
  • Outbound allowed?

  1. Check Azure SQL firewall

Common Causes
  • Private endpoint DNS not configured
  • NSG blocking outbound
  • Wrong connection string

Pro answer

“I’d validate connectivity from inside the pod, then check DNS resolution for private endpoints, and finally NSG and firewall rules.”


Drill 5: “Cluster ran out of IPs” (VERY COMMON)

Scenario

Pods stop scheduling, errors appear.


What’s happening?
  • Using Azure CNI → each pod gets real VNet IP
  • Subnet is exhausted

Symptoms
  • Pods stuck in Pending
  • Errors about IP allocation

Fixes
  • Expand subnet
  • Add new node pool with bigger subnet
  • Use Azure CNI Overlay (advanced)

Strong answer

“This is a classic Azure CNI limitation. I’d check subnet utilization and either expand it or redesign with better IP planning.”


Drill 6: “Node shows NotReady”

Scenario

One or more nodes go unhealthy.


Steps
kubectl get nodes
kubectl describe node <node>

Check for:
  • Disk pressure
  • Memory pressure
  • kubelet stopped
  • Network issues

Azure-specific checks
  • VM status in Azure Portal
  • Underlying VMSS health

Strong answer

“I’d check node conditions via kubectl describe, then validate VM health in Azure and kubelet status.”


Drill 7: “Deployment succeeded but no pods created”

🎯 Scenario

You applied YAML, nothing runs.


Steps

kubectl get deployments
kubectl describe deployment <name>

Causes

  • Replica = 0
  • Image pull error
  • Invalid YAML


MASTER TROUBLESHOOTING FRAMEWORK (Memorize This)

When stuck, always go:

Flow

1. Pod

  • Status? Logs?

2. Node

  • Capacity? Healthy?

3. Network

  • Service? DNS? NSG?

4. Azure layer

  • VNet / Subnet / Private endpoint?

How to Sound Senior in Interviews

Say this:

“I follow a layered troubleshooting approach:
Kubernetes layer (pods, services),
then node health,
then networking,
and finally Azure infrastructure like VNets and NSGs.”