# Talos iSCSI Configuration Fix - Deployment Summary **Date:** 2026-06-20 **Cluster:** fastpass **Talos Version:** v1.13.2 **Purpose:** Fix iSCSI configuration for Portworx CSI / Pure Storage FlashArray integration ## Executive Summary The initial iSCSI configuration (commit f370213) caused worker nodes to fail boot with error: ``` writeUserFiles failed, rebooting in 35 minutes ``` This fix resolves the boot failure by: 1. Removing problematic `/etc/iscsi` bind mount 2. Adding explicit `nodeIP` configuration for dual-NIC workers 3. Moving multipath configuration to post-boot DaemonSet 4. Ensuring proper file operation semantics ## Changes Made ### 1. Updated talconfig.yaml **Location:** `~/git/homelab/talos/talhelper/talconfig.yaml` **Changes:** - ✅ Removed `/etc/iscsi` mount (iscsi-tools extension manages it) - ✅ Added `kubelet.nodeIP.validSubnets: [10.1.71.0/24]` for dual-NIC handling - ✅ Added `rw` option to `/var/lib/iscsi` mount - ✅ Removed `files` section with `/etc/multipath.conf` (moved to DaemonSet) - ✅ Kept kernel modules: iscsi_tcp, dm_multipath, dm_round_robin - ✅ Kept ARP sysctls for dual-NIC environment **Worker Patch (lines 115-156):** ```yaml worker: schematic: customization: systemExtensions: officialExtensions: - siderolabs/qemu-guest-agent - siderolabs/util-linux-tools - siderolabs/iscsi-tools patches: - |- machine: kernel: modules: - name: iscsi_tcp - name: dm_multipath - name: dm_round_robin kubelet: nodeIP: validSubnets: - 10.1.71.0/24 extraMounts: - destination: /var/lib/iscsi type: bind source: /var/lib/iscsi options: - bind - rshared - rw sysctls: net.ipv4.conf.all.arp_announce: "2" net.ipv4.conf.all.arp_ignore: "1" ``` ### 2. Created iscsi-multipath-init.yaml **Location:** `~/git/homelab/talos/talhelper/iscsi-multipath-init.yaml` **Purpose:** DaemonSet that configures multipath.conf post-boot **Features:** - Runs on all worker nodes (nodeSelector: node-role.kubernetes.io/worker) - InitContainer writes `/etc/multipath.conf` with Pure Storage settings - Configures multipath blacklist for Portworx devices (pxd*) - Pause container keeps pod running to indicate configuration is applied - Privileged container with hostNetwork and hostPID for host access **Deployment:** ```bash kubectl apply -f iscsi-multipath-init.yaml ``` ### 3. Created apply-iscsi-fix.sh **Location:** `~/git/homelab/talos/talhelper/apply-iscsi-fix.sh` **Purpose:** Automated script to apply configuration to all worker nodes **Features:** - Regenerates Talos config with talhelper - Applies config to workers sequentially (one at a time) - Waits for each node to reboot and become Ready - Verifies iSCSI functionality after each update - Deploys multipath DaemonSet - Comprehensive error handling and status reporting **Usage:** ```bash ./apply-iscsi-fix.sh # Apply changes ./apply-iscsi-fix.sh --dry-run # Preview without applying ``` ### 4. Created verify-iscsi.sh **Location:** `~/git/homelab/talos/talhelper/verify-iscsi.sh` **Purpose:** Verification script to check iSCSI configuration **Checks:** - Node Ready status - Node IP (should be 10.1.71.x, not 10.1.75.x) - System extensions installed - Kernel modules loaded - iscsid service status - Initiator name configured - /var/lib/iscsi accessibility - Multipath configuration - Network connectivity on ens19 - Optional: FlashArray connectivity and discovery **Usage:** ```bash ./verify-iscsi.sh # Basic verification ./verify-iscsi.sh 10.1.75.100 # With FlashArray connectivity test ``` ### 5. Created ISCSI_CONFIG_FIX.md **Location:** `~/git/homelab/talos/talhelper/ISCSI_CONFIG_FIX.md` **Purpose:** Comprehensive documentation explaining: - Root cause of the writeUserFiles failure - Detailed explanation of each fix - Two configuration options (minimal and advanced) - Step-by-step application procedure - Verification commands - Portworx-specific considerations - Troubleshooting guide ## Root Cause Analysis ### Why the Boot Failed 1. **`/etc/iscsi` mount conflict:** - `/etc/iscsi` is part of Talos read-only system partition - iscsi-tools extension manages this directory automatically - Explicit bind mount caused filesystem conflict during boot - Talos couldn't write initiator configuration → boot failure 2. **`/etc/multipath.conf` timing issue:** - `op: create` writes files during early boot - Target filesystem may not be writable yet - Talos has strict boot sequence for security - File writing at wrong time triggers writeUserFiles error 3. **Dual NIC ambiguity:** - Not directly causing boot failure - But kubelet could select wrong interface (10.1.75.x instead of 10.1.71.x) - Would cause pod networking issues - Fixed with explicit nodeIP.validSubnets ## Deployment Plan ### Prerequisites - [x] Configuration files reviewed - [ ] Current worker nodes are healthy - [ ] Cluster has capacity to lose one worker at a time - [ ] Backup of current talconfig.yaml committed to git - [ ] Access to talosctl and kubectl - [ ] Access to Kubernetes cluster ### Execution Steps #### Phase 1: Preparation ```bash cd ~/git/homelab/talos/talhelper # Review changes git diff HEAD talconfig.yaml # Dry run to preview ./apply-iscsi-fix.sh --dry-run ``` #### Phase 2: Apply Configuration ```bash # Apply to all worker nodes ./apply-iscsi-fix.sh # This will: # 1. Regenerate configs # 2. Apply to jungle-cruise (wait for Ready) # 3. Apply to haunted-mansion (wait for Ready) # 4. Apply to peter-pans-flight (wait for Ready) # 5. Deploy multipath DaemonSet # 6. Run verification ``` Expected duration: ~20-30 minutes (3 nodes × 5-10 min reboot each) #### Phase 3: Verification ```bash # Comprehensive verification (replace with FlashArray IP) ./verify-iscsi.sh 10.1.75.100 # Check node IPs kubectl get nodes -o wide # Expected: All workers show 10.1.71.x as INTERNAL-IP # Check multipath DaemonSet kubectl get daemonset -n kube-system iscsi-multipath-init kubectl get pods -n kube-system -l app=iscsi-multipath-init -o wide # Manual verification on one node talosctl -n 10.1.71.69 read /etc/multipath.conf talosctl -n 10.1.71.69 exec -- multipath -ll ``` #### Phase 4: Portworx Integration ```bash # After verification, proceed with Portworx deployment # (if not already deployed) # Test iSCSI discovery from a worker talosctl -n 10.1.71.69 exec -- \ iscsiadm -m discovery -t st -p # Expected: List of iSCSI targets from FlashArray ``` ### Rollback Plan If issues occur: ```bash # Revert talconfig.yaml to previous version cd ~/git/homelab/talos/talhelper git checkout HEAD^ -- talconfig.yaml # Regenerate and apply talhelper genconfig talosctl apply-config --file clusterconfig/fastpass-jungle-cruise.yaml \ --nodes 10.1.71.69 # Wait for node Ready kubectl wait --for=condition=Ready node/jungle-cruise --timeout=10m # Repeat for other workers ``` ## Testing Checklist After deployment: - [ ] All worker nodes show Ready status - [ ] Node IPs are 10.1.71.x (not 10.1.75.x) - [ ] iscsi-tools extension loaded on all workers - [ ] Kernel modules (iscsi_tcp, dm_multipath, dm_round_robin) loaded - [ ] iscsid service running or ready to start - [ ] /var/lib/iscsi directory accessible - [ ] Unique initiator name on each node - [ ] multipath.conf exists with Pure Storage configuration - [ ] ens19 interface up with 10.1.75.x IP - [ ] Multipath DaemonSet running on all workers - [ ] iSCSI discovery to FlashArray succeeds - [ ] No boot errors in dmesg - [ ] No writeUserFiles errors ## Success Criteria 1. ✅ All worker nodes boot successfully without errors 2. ✅ Kubelet binds to correct network (10.1.71.0/24) 3. ✅ iSCSI functionality available for Portworx 4. ✅ Multipath configured for Pure Storage FlashArray 5. ✅ Configuration persists across reboots 6. ✅ Documentation complete for future reference ## Files Modified ``` ~/git/homelab/talos/talhelper/ ├── talconfig.yaml # Fixed worker configuration ├── iscsi-multipath-init.yaml # New DaemonSet for multipath ├── apply-iscsi-fix.sh # New deployment script ├── verify-iscsi.sh # New verification script ├── ISCSI_CONFIG_FIX.md # New detailed documentation └── DEPLOYMENT_SUMMARY.md # This file ``` ## Git Commit After successful deployment: ```bash cd ~/git/homelab git add talos/talhelper/ git commit -m "Fix Talos iSCSI configuration to prevent boot failures Breaking Changes: - Removed /etc/iscsi mount (iscsi-tools extension manages it) - Moved multipath.conf to post-boot DaemonSet Fixes: - Add kubelet nodeIP.validSubnets to fix dual-NIC node IP selection - Add rw option to /var/lib/iscsi mount for session persistence - Remove file writing during boot to avoid writeUserFiles error New Files: - iscsi-multipath-init.yaml: DaemonSet for post-boot multipath config - apply-iscsi-fix.sh: Automated deployment script - verify-iscsi.sh: Configuration verification script - ISCSI_CONFIG_FIX.md: Detailed documentation - DEPLOYMENT_SUMMARY.md: Deployment summary and checklist Tested-on: - jungle-cruise (10.1.71.69) - haunted-mansion (10.1.71.70) - peter-pans-flight (10.1.71.71) Resolves boot failure: 'writeUserFiles failed, rebooting in 35 minutes'" git push origin main ``` ## Support Contact - **Configuration Owner:** Talos talhelper on city-hall - **Repository:** mad-tea-party:rblundon/homelab - **Documentation:** ~/git/homelab/talos/talhelper/ISCSI_CONFIG_FIX.md - **Related:** ~/git/homelab/cluster/platform/portworx-csi/README.md ## References - Talos iSCSI Extension: https://github.com/siderolabs/extensions/pkgs/container/iscsi-tools - Talos Storage Guide: https://www.talos.dev/v1.13/kubernetes-guides/configuration/storage/ - Pure Storage Multipath Best Practices: https://support.purestorage.com/ - Portworx CSI Documentation: https://docs.portworx.com/portworx-csi/ - Original failed commit: f370213