Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article shows how to configure NFS with Kerberos (krb5p) authentication for ingestion workloads in Agentic Retrieval.
Important
Agentic Retrieval in Foundry Local is currently in PREVIEW. See the Supplemental Terms of Use for Microsoft Azure Previews for legal terms that apply to Azure features that are in beta, preview, or otherwise not yet released into general availability.
Prerequisites
Before you begin, make sure you have:
- An Azure Local cluster deployed and operational.
- An Arc-enabled Kubernetes cluster connected to Azure.
- At least one available worker node for Kerberos workloads.
- Active Directory Domain Services (AD DS), including a key distribution center (KDC).
- An NFS server configured for NFSv4.1 (or later) with
sec=krb5pexport options. - Required network paths and ports open between worker nodes, domain controllers, DNS/NTP services, and the NFS server. For details, see Network requirements.
- Reviewed the NFS with Kerberos authentication overview.
Step 1: Verify your Azure Local cluster
Verify cluster connectivity and node readiness before you configure Kerberos.
# Verify cluster nodes
kubectl get nodes
# All worker nodes should show STATUS: Ready
# Verify Arc connection
az connectedk8s show \
--name <cluster_name> \
--resource-group <resource_group> \
-o table
New or replaced nodes don't automatically have Kerberos prerequisites (keytab, rpc.gssd, domain join). Use a fixed node pool for Kerberos workloads. If you need autoscaling, see Add new nodes.
Step 2: Join worker nodes to Active Directory
Join all Kubernetes worker nodes that run NFS ingestion to your Active Directory domain.
Install required packages
# Ubuntu / Debian
sudo apt update && sudo apt install -y realmd sssd sssd-tools adcli packagekit
# RHEL / CentOS
sudo yum install -y realmd sssd sssd-tools adcli oddjob oddjob-mkhomedir
Discover and join the domain
# Discover the domain
sudo realm discover <YOUR_DOMAIN>
# Join the domain (prompts for AD admin credentials)
sudo realm join --verbose <YOUR_DOMAIN> -U <admin_user>@<YOUR_DOMAIN>
Verify domain join
# Verify membership
realm list
# Expected output includes:
# configured: kerberos-member
# Verify SSSD is running
sudo systemctl status sssd
# Verify machine keytab was created
sudo klist -kt /etc/krb5.keytab
# Should list host/<hostname>@<YOUR_DOMAIN> entries
Alternative: Manually create a machine SPN (without full domain join)
If full domain join isn't possible, create a machine SPN manually on the domain controller.
# On Windows Domain Controller (PowerShell)
New-ADComputer -Name "<NODE_NAME>" -SamAccountName "<NODE_NAME>$" `
-Path "OU=Kubernetes,DC=contoso,DC=com"
setspn -A nfs/<node_fqdn> <NODE_NAME>
ktpass /out <node_name>.keytab `
/princ host/<node_fqdn>@<YOUR_REALM> `
/mapuser <NODE_NAME>$ /pass * `
/crypto AES256-SHA1 /ptype KRB5_NT_PRINCIPAL
# On the Linux node, copy the keytab
sudo scp <admin_user>@<domain_controller>:/path/<node_name>.keytab /etc/krb5.keytab
sudo chmod 600 /etc/krb5.keytab
sudo chown root:root /etc/krb5.keytab
Step 3: Install and configure Kerberos client
Each worker node requires Kerberos client tools and a configuration file (/etc/krb5.conf) to communicate securely with your Active Directory domain.
Install packages
# Ubuntu / Debian
sudo apt update && sudo apt install -y krb5-user libpam-krb5
# RHEL / CentOS
sudo yum install -y krb5-workstation krb5-libs
Configure /etc/krb5.conf
Create or edit /etc/krb5.conf on every worker node:
[libdefaults]
default_realm = <YOUR_REALM>
dns_lookup_kdc = true
dns_lookup_realm = true
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = true
[realms]
<YOUR_REALM> = {
kdc = <kdc_server_1>
kdc = <kdc_server_2>
admin_server = <kdc_server_1>
default_domain = <your_domain_lowercase>
}
[domain_realm]
.<your_domain_lowercase> = <YOUR_REALM>
<your_domain_lowercase> = <YOUR_REALM>
Replace the placeholders with your values:
| Placeholder | Example |
|---|---|
<YOUR_REALM> (uppercase) |
CORP.EXAMPLE.COM |
<kdc_server_1> |
ad-dc1.corp.example.com |
<kdc_server_2> |
ad-dc2.corp.example.com (optional, for HA) |
<your_domain_lowercase> |
corp.example.com |
Validate Kerberos configuration
# Test KDC reachability
kinit <admin_user>@<YOUR_REALM>
# Enter password when prompted
# Verify ticket
klist
# Should show: krbtgt/<YOUR_REALM>@<YOUR_REALM>
# Clean up
kdestroy
Step 4: Create a service principal and deploy the keytab
Create the AD service principal and distribute its keytab to each ingestion worker node.
- Create the service principal in AD.
- Deploy the keytab to all worker nodes.
- Verify keytab-based authentication on each node.
Create the service principal in AD
Option A: Use kadmin (Linux)
sudo kadmin -p <admin_user>@<YOUR_REALM> <<EOF
addprinc -randkey nfs/<service_account>@<YOUR_REALM>
ktadd -k /tmp/edgerag-nfs.keytab nfs/<service_account>@<YOUR_REALM>
EOF
Option B: Use PowerShell (Windows domain controller)
# Create service account
New-ADUser -Name "<service_account_name>" `
-UserPrincipalName "<service_account_name>@<your_domain>" `
-PasswordNeverExpires $true `
-CannotChangePassword $true `
-Enabled $true `
-AccountPassword (ConvertTo-SecureString "<temp_password>" -AsPlainText -Force)
# Create SPN
setspn -A nfs/<service_account> <service_account_name>
# Export keytab
ktpass /out edgerag-nfs.keytab `
/princ nfs/<service_account>@<YOUR_REALM> `
/mapuser <service_account_name>@<your_domain> `
/pass * `
/crypto AES256-SHA1 `
/ptype KRB5_NT_PRINCIPAL
Deploy keytab to all worker nodes
for NODE in <node_1> <node_2> <node_3>; do
echo "Deploying keytab to $NODE..."
scp /tmp/edgerag-nfs.keytab ${NODE}:/etc/krb5.keytab
ssh ${NODE} "sudo chmod 600 /etc/krb5.keytab && sudo chown root:root /etc/krb5.keytab"
echo " Done."
done
Verify keytab on each node
# List principals in keytab
sudo klist -kt /etc/krb5.keytab
# Test non-interactive authentication
sudo kinit -kt /etc/krb5.keytab nfs/<service_account>@<YOUR_REALM>
sudo klist
# Should show valid TGT
# Clean up
sudo kdestroy
Enter the SPN value (for example, nfs/edgerag-svc@CONTOSO.COM) in the Service Principal Name field during installation.
Step 5: Install NFS client and enable rpc-gssd
rpc-gssd is the kernel-level Kerberos daemon that intercepts NFS mount requests and acquires tickets by using the keytab. It must run on every worker node.
# Install NFS client
sudo apt install -y nfs-common # Ubuntu / Debian
sudo yum install -y nfs-utils # RHEL / CentOS
# Enable and start rpc-gssd
sudo systemctl enable rpc-gssd
sudo systemctl start rpc-gssd
# Verify
sudo systemctl status rpc-gssd
# Should show: active (running)
Step 6: Validate NFS Kerberos mount
Test an NFS mount with Kerberos to verify that the full authentication chain works.
# Create a test mount point
sudo mkdir -p /mnt/nfs-kerberos-test
# Mount with Kerberos
sudo mount -t nfs4 -o sec=krb5p,vers=4.1 \
<nfs_server_fqdn>:<export_path> \
/mnt/nfs-kerberos-test
# Verify mount options
mount | grep nfs-kerberos-test
# Expected: ... type nfs4 (... sec=krb5p ...)
# Test file access
ls /mnt/nfs-kerberos-test/
# Clean up
sudo umount /mnt/nfs-kerberos-test
sudo rmdir /mnt/nfs-kerberos-test
If this mount fails, deployment of Agentic Retrieval can't continue. Resolve the issue before you continue. For help, see Troubleshooting.
NFS server requirements
Your NFS server must be configured to accept Kerberos-authenticated clients.
| Requirement | Details |
|---|---|
| NFSv4.1 or later | Required for Kerberos (NFSv3 doesn't support it). |
sec=krb5p in export options |
The export must allow krb5p security mode. |
| NFS server has its own SPN in AD | For example, nfs/nfs-server@<YOUR_REALM>. |
| Proper NFSv4 ID mapping | Should match client configuration. |
Example NFS server export (/etc/exports):
/exports/data *.contoso.com(ro,sync,sec=krb5p,no_subtree_check)
Agentic Retrieval requires you to specify the NFS server by hostname (not IP address). Kerberos SPN construction by rpc.gssd relies on DNS, so using an IP address causes authentication to fail.
Step 7: Configure DNS and time sync
Kerberos authentication depends on correct DNS resolution and time synchronization between your nodes and domain controllers.
Verify forward and reverse DNS resolution
Kerberos requires both forward and reverse DNS. Without proper DNS, ticket requests can fail.
# Forward lookup for the NFS server
nslookup <nfs_server_fqdn>
# Reverse lookup for the NFS server (required for Kerberos)
nslookup <nfs_server_ip>
# Must return the FQDN
# Forward lookup for domain controllers
nslookup <domain_controller_fqdn>
# KDC SRV records
nslookup -type=SRV _kerberos._tcp.<your_domain>
Ensure clock skew is less than 5 minutes
# Enable NTP
sudo timedatectl set-ntp true
# Verify
timedatectl status
# NTP synchronized: yes
# Check offset
chronyc tracking # or: ntpq -p
Step 8: Label worker nodes
Label each prepared worker node so pre-install validation can target Kerberos-ready infrastructure.
# Label each prepared node
kubectl label node <node_name> edge-rag/kerberos-provisioned=true
# Verify
kubectl get nodes -l edge-rag/kerberos-provisioned=true
Understand the three-label system
Agentic Retrieval uses three distinct node labels for Kerberos:
| Label | Set by | Meaning |
|---|---|---|
edge-rag/kerberos-provisioned=true |
You (manual kubectl label) |
Your assertion that you prepared this node with krb5.conf, keytab, and rpc.gssd. |
edge-rag/kerberos-ready=true or false |
DaemonSet (automatic, every 60 seconds) | System verification that Kerberos prerequisites are currently healthy on this node. |
edge-rag/kerberos-reason=<REASON> |
DaemonSet (automatic) | If ready=false, the specific failure reason (for example, KRB5_CONF_MISSING, KEYTAB_MISSING, KDC_UNREACHABLE). |
The provisioned label is your assertion. The ready label is the system's current verification. Ingestion pods schedule only on nodes where kerberos-ready=true.
Step 9: Run the validation script
Run this script on each prepared node before you install Agentic Retrieval.
#!/bin/bash
# Agentic Retrieval: Kerberos prerequisites validation
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
PASS=0
FAIL=0
WARN=0
check() {
local description="$1"
local command="$2"
local required="${3:-true}"
if eval "$command" &>/dev/null; then
echo -e " ${GREEN}[PASS]${NC} $description"
PASS=$((PASS + 1))
elif [ "$required" = "true" ]; then
echo -e " ${RED}[FAIL]${NC} $description"
FAIL=$((FAIL + 1))
else
echo -e " ${YELLOW}[WARN]${NC} $description (optional)"
WARN=$((WARN + 1))
fi
}
echo "============================================================"
echo " Kerberos prerequisites validation"
echo " Node: $(hostname -f)"
echo " Date: $(date -Iseconds)"
echo "============================================================"
echo ""
echo "1. Domain and identity"
check "Domain joined (realm list)" "realm list 2>/dev/null | grep -qi 'configured: kerberos-member'"
check "SSSD service running" "systemctl is-active sssd"
check "Machine hostname resolvable" "nslookup $(hostname -f)"
echo ""
echo "2. Kerberos configuration"
check "/etc/krb5.conf exists" "test -f /etc/krb5.conf"
check "/etc/krb5.conf has default_realm" "grep -q 'default_realm' /etc/krb5.conf"
check "/etc/krb5.keytab exists" "test -f /etc/krb5.keytab"
check "/etc/krb5.keytab is non-empty" "test -s /etc/krb5.keytab"
check "Keytab readable (klist -kt)" "klist -kt /etc/krb5.keytab"
check "kinit with keytab succeeds" \
"kinit -kt /etc/krb5.keytab \$(klist -kt /etc/krb5.keytab 2>/dev/null | tail -1 | awk '{print \$NF}') && kdestroy"
echo ""
echo "3. NFS services"
check "nfs-common/nfs-utils installed" \
"dpkg -l nfs-common 2>/dev/null | grep -q '^ii' || rpm -q nfs-utils 2>/dev/null"
check "rpc-gssd enabled" "systemctl is-enabled rpc-gssd"
check "rpc-gssd running" "systemctl is-active rpc-gssd"
echo ""
echo "4. DNS resolution"
REALM=$(grep 'default_realm' /etc/krb5.conf 2>/dev/null | awk '{print $NF}' | tr -d ' ')
DOMAIN=$(echo "$REALM" | tr '[:upper:]' '[:lower:]')
check "KDC SRV record resolvable" "nslookup -type=SRV _kerberos._tcp.$DOMAIN"
check "KDC hostname resolvable" \
"grep 'kdc' /etc/krb5.conf | head -1 | awk -F= '{print \$2}' | xargs nslookup"
echo ""
echo "5. Time synchronization"
check "NTP synchronized" \
"timedatectl status 2>/dev/null | grep -qi 'synchronized: yes\|ntp.*active'"
echo ""
echo "============================================================"
echo -e " Results: ${GREEN}$PASS passed${NC}, ${RED}$FAIL failed${NC}, ${YELLOW}$WARN warnings${NC}"
if [ $FAIL -eq 0 ]; then
echo -e " ${GREEN}[PASS] Node is ready for Kerberos installation${NC}"
echo ""
echo " Next step: apply the label (if not already set):"
echo " kubectl label node $(hostname) edge-rag/kerberos-provisioned=true"
else
echo -e " ${RED}[FAIL] Node has $FAIL failing checks; resolve them before installation${NC}"
fi
echo "============================================================"
Save the script as validate-kerberos-prereqs.sh and run it on each node:
chmod +x validate-kerberos-prereqs.sh
sudo ./validate-kerberos-prereqs.sh
Deploy the extension with Kerberos enabled
After you complete this Kerberos setup, return to the deployment prerequisites checklist and finish any remaining prerequisite steps. When you're ready to deploy, use Deploy the extension for Agentic Retrieval and the Kerberos-specific values in this section.
During deployment:
- In the Azure portal, on the Configurations tab, turn on Kerberos and enter the Kerberos SPN value from this article (for example,
nfs/<service_account>@<YOUR_REALM>). - In Azure CLI, set
enableKerberos="true"and providekerberosSpnin the CLI script in Deploy the extension for Agentic Retrieval.
If you don't plan to use Kerberos, skip this article and continue with the standard deployment flow in Deploy the extension for Agentic Retrieval.
Confirm completion
You're ready to continue when:
- Nodes intended for ingestion are labeled
edge-rag/kerberos-provisioned=true. - Kerberos client and keytab validation pass on each worker node.
- A test NFS mount succeeds with
sec=krb5p. - You applied Kerberos-enabled installation settings successfully.