211 lines
7.1 KiB
Bash
Executable File
211 lines
7.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Set up error handling
|
|
set -e
|
|
|
|
# Define colors for better readability
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
RED='\033[0;31m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Load environment variables
|
|
if [ -f "$(dirname "$0")/../load-env.sh" ]; then
|
|
echo -e "${YELLOW}Loading environment variables...${NC}"
|
|
source "$(dirname "$0")/../load-env.sh"
|
|
fi
|
|
|
|
# Get cluster IP
|
|
echo -e "${YELLOW}Getting cluster IP address...${NC}"
|
|
CLUSTER_IP=$(kubectl get -n kube-system service traefik -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
|
|
|
|
if [ -z "$CLUSTER_IP" ]; then
|
|
echo -e "${RED}Failed to get cluster IP. Is Traefik running?${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${YELLOW}Using cluster IP: ${CLUSTER_IP}${NC}"
|
|
|
|
# Domain settings
|
|
DOMAIN="cloud.payne.io"
|
|
INTERNAL_DOMAIN="in.${DOMAIN}"
|
|
DASHBOARD_DOMAIN="kubernetes-dashboard.${INTERNAL_DOMAIN}"
|
|
|
|
echo -e "${BLUE}=== Setting up Split DNS with systemd-resolved ===${NC}"
|
|
echo -e "${YELLOW}Internal Domain: ${INTERNAL_DOMAIN}${NC}"
|
|
echo -e "${YELLOW}Dashboard Domain: ${DASHBOARD_DOMAIN}${NC}"
|
|
echo
|
|
|
|
# Check if running as root
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo -e "${RED}This script must be run as root to configure systemd-resolved.${NC}"
|
|
echo -e "${YELLOW}Please run: sudo $0${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Create systemd-resolved configuration directory if it doesn't exist
|
|
echo -e "${YELLOW}Creating systemd-resolved configuration directory...${NC}"
|
|
mkdir -p /etc/systemd/resolved.conf.d/
|
|
|
|
# Create the configuration file for split DNS
|
|
echo -e "${YELLOW}Creating split DNS configuration...${NC}"
|
|
cat > /etc/systemd/resolved.conf.d/split-dns.conf << EOF
|
|
[Resolve]
|
|
# Use Google DNS servers as fallback
|
|
FallbackDNS=8.8.8.8 8.8.4.4
|
|
|
|
# Define our domain for special handling
|
|
Domains=~${INTERNAL_DOMAIN}
|
|
|
|
# Enable split DNS
|
|
DNSStubListenerExtra=${CLUSTER_IP}
|
|
EOF
|
|
|
|
# Create a static host entry for the dashboard domain
|
|
echo -e "${YELLOW}Creating static address mapping for ${DASHBOARD_DOMAIN}...${NC}"
|
|
mkdir -p /etc/systemd/resolved.conf.d/
|
|
|
|
cat > /etc/systemd/resolved.conf.d/static-domains.conf << EOF
|
|
[Resolve]
|
|
# Map our dashboard domain to the cluster IP
|
|
$(echo "${DASHBOARD_DOMAIN} ${CLUSTER_IP}" | awk '{print "DNS=" $2 "#" $1}')
|
|
EOF
|
|
|
|
# Restart systemd-resolved
|
|
echo -e "${YELLOW}Restarting systemd-resolved...${NC}"
|
|
systemctl restart systemd-resolved
|
|
|
|
# Remove immutable flag from resolv.conf if set
|
|
if lsattr /etc/resolv.conf 2>/dev/null | grep -q 'i'; then
|
|
echo -e "${YELLOW}Removing immutable flag from /etc/resolv.conf...${NC}"
|
|
chattr -i /etc/resolv.conf
|
|
fi
|
|
|
|
# Configure resolv.conf to use systemd-resolved
|
|
echo -e "${YELLOW}Configuring /etc/resolv.conf to use systemd-resolved...${NC}"
|
|
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
|
|
|
|
# Now for the Kubernetes parts
|
|
echo -e "${YELLOW}Setting up Kubernetes components...${NC}"
|
|
|
|
# Get email for Let's Encrypt
|
|
echo -e "${YELLOW}Please enter an email address for Let's Encrypt registration:${NC}"
|
|
read -p "Email: " EMAIL_ADDRESS
|
|
|
|
# Ensure cert-manager namespace exists
|
|
kubectl get namespace cert-manager >/dev/null 2>&1 || kubectl create namespace cert-manager
|
|
|
|
# Install cert-manager if needed
|
|
if ! kubectl get deployment -n cert-manager cert-manager >/dev/null 2>&1; then
|
|
echo -e "${YELLOW}Installing cert-manager...${NC}"
|
|
helm repo add jetstack https://charts.jetstack.io
|
|
helm repo update
|
|
helm upgrade --install cert-manager jetstack/cert-manager \
|
|
--namespace cert-manager \
|
|
--set installCRDs=true
|
|
|
|
# Wait for cert-manager to be ready
|
|
echo -e "${YELLOW}Waiting for cert-manager to be ready (this may take a minute)...${NC}"
|
|
sleep 30
|
|
kubectl wait --for=condition=available --timeout=300s deployment/cert-manager -n cert-manager
|
|
kubectl wait --for=condition=available --timeout=300s deployment/cert-manager-webhook -n cert-manager
|
|
fi
|
|
|
|
# Ensure kubernetes-dashboard namespace exists
|
|
kubectl get namespace kubernetes-dashboard >/dev/null 2>&1 || kubectl create namespace kubernetes-dashboard
|
|
|
|
# Install the dashboard if not already installed
|
|
if ! kubectl get deployment -n kubernetes-dashboard kubernetes-dashboard >/dev/null 2>&1; then
|
|
echo -e "${YELLOW}Installing Kubernetes Dashboard...${NC}"
|
|
"$(dirname "$0")/install-simple-dashboard"
|
|
fi
|
|
|
|
# Create a ClusterIssuer for Let's Encrypt
|
|
echo -e "${YELLOW}Setting up Let's Encrypt ClusterIssuer...${NC}"
|
|
cat << EOF | kubectl apply -f -
|
|
apiVersion: cert-manager.io/v1
|
|
kind: ClusterIssuer
|
|
metadata:
|
|
name: letsencrypt-prod
|
|
spec:
|
|
acme:
|
|
server: https://acme-v02.api.letsencrypt.org/directory
|
|
email: ${EMAIL_ADDRESS}
|
|
privateKeySecretRef:
|
|
name: letsencrypt-prod
|
|
solvers:
|
|
- http01:
|
|
ingress:
|
|
class: traefik
|
|
EOF
|
|
|
|
# Check dashboard service name and port
|
|
echo -e "${YELLOW}Checking kubernetes-dashboard service...${NC}"
|
|
DASHBOARD_SERVICE=$(kubectl get svc -n kubernetes-dashboard -o name | grep kubernetes-dashboard | grep -v metrics-scraper | grep -v api | grep -v auth | head -1)
|
|
|
|
if [ -z "$DASHBOARD_SERVICE" ]; then
|
|
echo -e "${RED}Kubernetes Dashboard service not found. Please check your installation.${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Get the service name without the "service/" prefix
|
|
DASHBOARD_SERVICE_NAME=$(echo $DASHBOARD_SERVICE | cut -d'/' -f2)
|
|
echo -e "${YELLOW}Found dashboard service: ${DASHBOARD_SERVICE_NAME}${NC}"
|
|
|
|
# Get the service port
|
|
DASHBOARD_PORT=$(kubectl get svc $DASHBOARD_SERVICE_NAME -n kubernetes-dashboard -o jsonpath='{.spec.ports[0].port}')
|
|
echo -e "${YELLOW}Dashboard port: ${DASHBOARD_PORT}${NC}"
|
|
|
|
# Create an Ingress with TLS
|
|
echo -e "${YELLOW}Creating ingress with TLS for ${DASHBOARD_DOMAIN}...${NC}"
|
|
cat << EOF | kubectl apply -f -
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
name: kubernetes-dashboard
|
|
namespace: kubernetes-dashboard
|
|
annotations:
|
|
kubernetes.io/ingress.class: traefik
|
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
traefik.ingress.kubernetes.io/service.serversscheme: https
|
|
traefik.ingress.kubernetes.io/service.serverstransport.insecureskipverify: "true"
|
|
spec:
|
|
tls:
|
|
- hosts:
|
|
- ${DASHBOARD_DOMAIN}
|
|
secretName: kubernetes-dashboard-tls
|
|
rules:
|
|
- host: ${DASHBOARD_DOMAIN}
|
|
http:
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: ${DASHBOARD_SERVICE_NAME}
|
|
port:
|
|
number: ${DASHBOARD_PORT}
|
|
EOF
|
|
|
|
echo
|
|
echo -e "${GREEN}=== Split DNS Setup Complete! ===${NC}"
|
|
echo
|
|
echo -e "${YELLOW}Your Kubernetes Dashboard will be available at:${NC}"
|
|
echo -e "${BLUE}https://${DASHBOARD_DOMAIN}${NC}"
|
|
echo
|
|
echo -e "${YELLOW}Key points:${NC}"
|
|
echo "1. systemd-resolved is now configured to resolve ${INTERNAL_DOMAIN} domains locally"
|
|
echo "2. The dashboard domain ${DASHBOARD_DOMAIN} is mapped to ${CLUSTER_IP}"
|
|
echo "3. Let's Encrypt will issue a valid certificate for secure HTTPS (may take a few minutes)"
|
|
echo "4. External users cannot access these domains (special DNS configuration required)"
|
|
echo
|
|
echo -e "${YELLOW}To test the DNS resolution:${NC}"
|
|
echo -e "${BLUE}nslookup ${DASHBOARD_DOMAIN}${NC}"
|
|
echo
|
|
echo -e "${YELLOW}To verify systemd-resolved configuration:${NC}"
|
|
echo -e "${BLUE}resolvectl status${NC}"
|
|
echo
|
|
echo -e "${YELLOW}Certificate status:${NC}"
|
|
echo -e "${BLUE}kubectl get certificate -n kubernetes-dashboard${NC}"
|
|
echo |