262 lines
6.8 KiB
Bash
Executable File
262 lines
6.8 KiB
Bash
Executable File
#!/bin/bash
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||
CONFIG_FILE="$PROJECT_DIR/config/cluster-vars.yml"
|
||
|
||
# Source common library if available
|
||
if [ -f "$SCRIPT_DIR/lib/common.sh" ]; then
|
||
source "$SCRIPT_DIR/lib/common.sh"
|
||
else
|
||
log() { echo "[INFO] $1"; }
|
||
log_error() { echo "[ERROR] $1" >&2; }
|
||
log_warn() { echo "[WARN] $1"; }
|
||
fi
|
||
|
||
log "=== 配置HTTPS证书 ==="
|
||
echo ""
|
||
|
||
# Ensure yq is available
|
||
if [ -f "$SCRIPT_DIR/lib/common.sh" ]; then
|
||
ensure_yq || exit 1
|
||
else
|
||
if ! command -v yq &> /dev/null; then
|
||
log_error "yq未安装,请先运行: sudo apt install yq"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
# Read configuration
|
||
ARGOCD_DOMAIN=$(yq eval '.argocd_domain' "$CONFIG_FILE")
|
||
GITEA_DOMAIN=$(yq eval '.gitea_domain' "$CONFIG_FILE")
|
||
DOMAIN_NAME=$(yq eval '.domain_name' "$CONFIG_FILE")
|
||
|
||
log "域名配置:"
|
||
echo " ArgoCD: $ARGOCD_DOMAIN"
|
||
echo " Gitea: $GITEA_DOMAIN"
|
||
echo " 主域名: $DOMAIN_NAME"
|
||
echo ""
|
||
|
||
# Step 1: Install cert-manager CRDs
|
||
log "步骤 1/4: 安装cert-manager CRDs..."
|
||
|
||
CERT_MANAGER_VERSION="v1.13.3"
|
||
CERT_MANAGER_CRD_URL="https://github.com/cert-manager/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.crds.yaml"
|
||
|
||
if [ -f "$SCRIPT_DIR/lib/common.sh" ]; then
|
||
retry 3 5 "kubectl apply -f $CERT_MANAGER_CRD_URL" || {
|
||
log_error "cert-manager CRDs安装失败"
|
||
exit 1
|
||
}
|
||
else
|
||
kubectl apply -f "$CERT_MANAGER_CRD_URL" || {
|
||
log_error "cert-manager CRDs安装失败"
|
||
exit 1
|
||
}
|
||
fi
|
||
|
||
log "✓ cert-manager CRDs安装成功"
|
||
echo ""
|
||
|
||
# Step 2: Install cert-manager
|
||
log "步骤 2/4: 安装cert-manager..."
|
||
|
||
kubectl create namespace cert-manager --dry-run=client -o yaml | kubectl apply -f -
|
||
|
||
CERT_MANAGER_URL="https://github.com/cert-manager/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml"
|
||
|
||
if [ -f "$SCRIPT_DIR/lib/common.sh" ]; then
|
||
retry 3 5 "kubectl apply -f $CERT_MANAGER_URL" || {
|
||
log_error "cert-manager安装失败"
|
||
exit 1
|
||
}
|
||
else
|
||
kubectl apply -f "$CERT_MANAGER_URL" || {
|
||
log_error "cert-manager安装失败"
|
||
exit 1
|
||
}
|
||
fi
|
||
|
||
log "等待cert-manager就绪..."
|
||
kubectl wait --for=condition=available --timeout=300s deployment/cert-manager -n cert-manager || {
|
||
log_error "cert-manager部署超时"
|
||
exit 1
|
||
}
|
||
|
||
kubectl wait --for=condition=available --timeout=300s deployment/cert-manager-webhook -n cert-manager || {
|
||
log_error "cert-manager-webhook部署超时"
|
||
exit 1
|
||
}
|
||
|
||
log "✓ cert-manager安装成功"
|
||
echo ""
|
||
|
||
# Step 3: Create ClusterIssuers
|
||
log "步骤 3/4: 创建Let's Encrypt ClusterIssuers..."
|
||
|
||
# Create staging issuer (for testing)
|
||
cat <<EOF | kubectl apply -f -
|
||
apiVersion: cert-manager.io/v1
|
||
kind: ClusterIssuer
|
||
metadata:
|
||
name: letsencrypt-staging
|
||
spec:
|
||
acme:
|
||
server: https://acme-staging-v02.api.letsencrypt.org/directory
|
||
email: admin@${DOMAIN_NAME}
|
||
privateKeySecretRef:
|
||
name: letsencrypt-staging
|
||
solvers:
|
||
- http01:
|
||
ingress:
|
||
class: traefik
|
||
EOF
|
||
|
||
log "✓ Staging ClusterIssuer创建成功"
|
||
|
||
# Create production issuer
|
||
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: admin@${DOMAIN_NAME}
|
||
privateKeySecretRef:
|
||
name: letsencrypt-prod
|
||
solvers:
|
||
- http01:
|
||
ingress:
|
||
class: traefik
|
||
EOF
|
||
|
||
log "✓ Production ClusterIssuer创建成功"
|
||
echo ""
|
||
|
||
# Wait for ClusterIssuers to be ready
|
||
log "等待ClusterIssuers就绪..."
|
||
sleep 5
|
||
|
||
if kubectl get clusterissuer letsencrypt-staging -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null | grep -q "True"; then
|
||
log "✓ Staging ClusterIssuer就绪"
|
||
else
|
||
log_warn "Staging ClusterIssuer可能未就绪,请检查: kubectl describe clusterissuer letsencrypt-staging"
|
||
fi
|
||
|
||
if kubectl get clusterissuer letsencrypt-prod -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null | grep -q "True"; then
|
||
log "✓ Production ClusterIssuer就绪"
|
||
else
|
||
log_warn "Production ClusterIssuer可能未就绪,请检查: kubectl describe clusterissuer letsencrypt-prod"
|
||
fi
|
||
|
||
echo ""
|
||
|
||
# Step 4: Create HTTPS Ingresses
|
||
log "步骤 4/4: 创建HTTPS Ingress..."
|
||
|
||
# ArgoCD HTTPS Ingress
|
||
if kubectl get namespace argocd &>/dev/null; then
|
||
log "创建ArgoCD HTTPS Ingress..."
|
||
|
||
cat <<EOF | kubectl apply -f -
|
||
apiVersion: networking.k8s.io/v1
|
||
kind: Ingress
|
||
metadata:
|
||
name: argocd-server-https
|
||
namespace: argocd
|
||
annotations:
|
||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||
traefik.ingress.kubernetes.io/router.tls: "true"
|
||
spec:
|
||
ingressClassName: traefik
|
||
tls:
|
||
- hosts:
|
||
- ${ARGOCD_DOMAIN}
|
||
secretName: argocd-tls-cert
|
||
rules:
|
||
- host: ${ARGOCD_DOMAIN}
|
||
http:
|
||
paths:
|
||
- path: /
|
||
pathType: Prefix
|
||
backend:
|
||
service:
|
||
name: argocd-server
|
||
port:
|
||
number: 80
|
||
EOF
|
||
|
||
log "✓ ArgoCD HTTPS Ingress创建成功"
|
||
else
|
||
log_warn "ArgoCD未部署,跳过Ingress创建"
|
||
fi
|
||
|
||
# Gitea HTTPS Ingress
|
||
if kubectl get namespace gitea &>/dev/null; then
|
||
log "创建Gitea HTTPS Ingress..."
|
||
|
||
cat <<EOF | kubectl apply -f -
|
||
apiVersion: networking.k8s.io/v1
|
||
kind: Ingress
|
||
metadata:
|
||
name: gitea-https
|
||
namespace: gitea
|
||
annotations:
|
||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||
traefik.ingress.kubernetes.io/router.tls: "true"
|
||
spec:
|
||
ingressClassName: traefik
|
||
tls:
|
||
- hosts:
|
||
- ${GITEA_DOMAIN}
|
||
secretName: gitea-tls-cert
|
||
rules:
|
||
- host: ${GITEA_DOMAIN}
|
||
http:
|
||
paths:
|
||
- path: /
|
||
pathType: Prefix
|
||
backend:
|
||
service:
|
||
name: gitea-http
|
||
port:
|
||
number: 3000
|
||
EOF
|
||
|
||
log "✓ Gitea HTTPS Ingress创建成功"
|
||
else
|
||
log_warn "Gitea未部署,跳过Ingress创建"
|
||
fi
|
||
|
||
echo ""
|
||
log "=== HTTPS配置完成 ==="
|
||
echo ""
|
||
|
||
log "证书申请状态检查:"
|
||
echo " 查看证书: kubectl get certificate -A"
|
||
echo " 查看ClusterIssuer: kubectl get clusterissuer"
|
||
echo ""
|
||
|
||
log "注意事项:"
|
||
echo " 1. 证书申请需要几分钟时间"
|
||
echo " 2. 确保DNS已正确解析到集群IP"
|
||
echo " 3. 确保80端口可从外网访问(用于HTTP-01验证)"
|
||
echo " 4. 首次使用建议先用staging测试,避免触发速率限制"
|
||
echo ""
|
||
|
||
log "验证HTTPS访问:"
|
||
echo " ArgoCD: https://${ARGOCD_DOMAIN}"
|
||
echo " Gitea: https://${GITEA_DOMAIN}"
|
||
echo ""
|
||
|
||
log "故障排查:"
|
||
echo " 查看cert-manager日志: kubectl logs -n cert-manager deployment/cert-manager"
|
||
echo " 查看证书详情: kubectl describe certificate <cert-name> -n <namespace>"
|
||
echo " 查看证书请求: kubectl get certificaterequest -A"
|
||
echo ""
|