Fix Talos iSCSI configuration for Portworx CSI

Root cause: Previous config violated boot-time security model
- Removed /etc/iscsi mount (iscsi-tools extension manages it)
- Moved multipath.conf to post-boot DaemonSet
- Added explicit kubelet nodeIP for dual-NIC workers

Deliverables:
- Fixed talconfig.yaml with working worker patch
- iscsi-multipath-init.yaml DaemonSet for multipath config
- Automated deployment and verification scripts
- Complete documentation suite

Ready for production deployment to fastpass worker nodes.

Co-authored-by: Talos Specialist <subagent@hermes>
This commit is contained in:
Hermes Agent service account
2026-06-20 21:18:48 -05:00
parent f37021346b
commit e8303d5129
10 changed files with 2648 additions and 31 deletions

183
talos/talhelper/verify-iscsi.sh Executable file
View File

@@ -0,0 +1,183 @@
#!/usr/bin/env bash
# verify-iscsi.sh
#
# Verifies iSCSI configuration on Talos worker nodes
# Run after applying the fixed configuration
set -euo pipefail
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
WORKER_NODES=(
"jungle-cruise:10.1.71.69"
"haunted-mansion:10.1.71.70"
"peter-pans-flight:10.1.71.71"
)
FLASHARRAY_ISCSI_IP="${1:-}"
if [[ -z "$FLASHARRAY_ISCSI_IP" ]]; then
echo -e "${YELLOW}Usage: $0 <flasharray-iscsi-ip>${NC}"
echo "Example: $0 10.1.75.100"
echo
echo "Testing without FlashArray connectivity check..."
echo
fi
echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ Talos iSCSI Configuration Verification Report ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}"
echo
for node_spec in "${WORKER_NODES[@]}"; do
IFS=':' read -r hostname ip <<< "$node_spec"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE}Node: $hostname ($ip)${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo
# Check node is Ready
echo -n " Kubernetes node status: "
if kubectl get node "$hostname" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null | grep -q "True"; then
echo -e "${GREEN}✓ Ready${NC}"
else
echo -e "${RED}✗ Not Ready${NC}"
fi
# Check node IP
echo -n " Node internal IP: "
node_ip=$(kubectl get node "$hostname" -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}' 2>/dev/null)
if [[ "$node_ip" == "10.1.71."* ]]; then
echo -e "${GREEN}$node_ip (correct network)${NC}"
else
echo -e "${RED}$node_ip (expected 10.1.71.x)${NC}"
fi
# Check system extensions
echo -n " iscsi-tools extension: "
if talosctl -n "$ip" get extensions 2>/dev/null | grep -q "iscsi-tools"; then
echo -e "${GREEN}✓ installed${NC}"
else
if talosctl -n "$ip" read /proc/modules 2>/dev/null | grep -q "iscsi_tcp"; then
echo -e "${GREEN}✓ active (module loaded)${NC}"
else
echo -e "${RED}✗ not found${NC}"
fi
fi
# Check kernel modules
echo -n " Kernel modules: "
modules_ok=true
for mod in iscsi_tcp dm_multipath dm_round_robin; do
if ! talosctl -n "$ip" read /proc/modules 2>/dev/null | grep -q "^$mod "; then
modules_ok=false
echo -e "${RED}$mod not loaded${NC}"
echo -n " "
fi
done
if $modules_ok; then
echo -e "${GREEN}✓ all loaded${NC}"
fi
# Check iscsid service
echo -n " iscsid service: "
service_status=$(talosctl -n "$ip" service iscsid 2>/dev/null | grep "STATE" | awk '{print $2}' || echo "Unknown")
if [[ "$service_status" == "Running" ]]; then
echo -e "${GREEN}✓ Running${NC}"
elif [[ "$service_status" == "Finished" ]]; then
echo -e "${YELLOW}⚠ Finished (starts on-demand)${NC}"
else
echo -e "${YELLOW}$service_status${NC}"
fi
# Check initiator name
echo -n " iSCSI initiator: "
initiator=$(talosctl -n "$ip" read /etc/iscsi/initiatorname.iscsi 2>/dev/null | grep "InitiatorName=" | cut -d= -f2 || echo "")
if [[ -n "$initiator" ]]; then
echo -e "${GREEN}${initiator:0:40}...${NC}"
else
echo -e "${RED}✗ not configured${NC}"
fi
# Check /var/lib/iscsi
echo -n " iSCSI data directory: "
if talosctl -n "$ip" ls /var/lib/iscsi >/dev/null 2>&1; then
file_count=$(talosctl -n "$ip" ls /var/lib/iscsi 2>/dev/null | wc -l)
echo -e "${GREEN}✓ accessible ($file_count entries)${NC}"
else
echo -e "${RED}✗ not accessible${NC}"
fi
# Check multipath
echo -n " Multipath config: "
if talosctl -n "$ip" read /etc/multipath.conf >/dev/null 2>&1; then
if talosctl -n "$ip" read /etc/multipath.conf 2>/dev/null | grep -q "PURE"; then
echo -e "${GREEN}✓ configured for Pure Storage${NC}"
else
echo -e "${YELLOW}⚠ present but missing Pure config${NC}"
fi
else
echo -e "${YELLOW}⚠ not found (will be created by DaemonSet)${NC}"
fi
echo -n " Multipath devices: "
mp_devices=$(talosctl -n "$ip" exec -- multipath -ll 2>/dev/null | grep -c "^[a-z0-9]" || echo "0")
if [[ "$mp_devices" -gt 0 ]]; then
echo -e "${GREEN}$mp_devices device(s)${NC}"
else
echo -e "${YELLOW}⚠ none (expected until iSCSI volumes attached)${NC}"
fi
# Check network connectivity on iSCSI interface
echo -n " iSCSI network (ens19): "
if talosctl -n "$ip" read /sys/class/net/ens19/operstate 2>/dev/null | grep -q "up"; then
iscsi_ip=$(talosctl -n "$ip" exec -- ip addr show ens19 2>/dev/null | grep "inet " | awk '{print $2}' | cut -d/ -f1)
echo -e "${GREEN}✓ up ($iscsi_ip)${NC}"
else
echo -e "${RED}✗ down${NC}"
fi
# Test FlashArray connectivity if IP provided
if [[ -n "$FLASHARRAY_ISCSI_IP" ]]; then
echo -n " FlashArray ping: "
if talosctl -n "$ip" exec -- ping -c 1 -W 2 "$FLASHARRAY_ISCSI_IP" >/dev/null 2>&1; then
echo -e "${GREEN}✓ reachable${NC}"
else
echo -e "${RED}✗ not reachable${NC}"
fi
echo -n " iSCSI discovery: "
if discovery_out=$(talosctl -n "$ip" exec -- iscsiadm -m discovery -t st -p "$FLASHARRAY_ISCSI_IP" 2>&1); then
target_count=$(echo "$discovery_out" | grep -c "iqn\." || echo "0")
echo -e "${GREEN}✓ found $target_count target(s)${NC}"
else
echo -e "${RED}✗ failed${NC}"
fi
fi
echo
done
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE}DaemonSet Status${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo
if kubectl get daemonset iscsi-multipath-init -n kube-system >/dev/null 2>&1; then
kubectl get daemonset iscsi-multipath-init -n kube-system
echo
kubectl get pods -n kube-system -l app=iscsi-multipath-init -o wide
else
echo -e "${YELLOW}⚠ iscsi-multipath-init DaemonSet not deployed${NC}"
echo " Deploy with: kubectl apply -f iscsi-multipath-init.yaml"
fi
echo
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}Verification complete!${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"