Files
k3s_auto_deploy/scripts/complete-automation.sh

522 lines
15 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# JPD集群完整自动化配置脚本
# 包括Ingress配置、cert-manager、ArgoCD配置、测试应用部署
set -e
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🚀 JPD集群完整自动化配置"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# ============================================
# 步骤 1: 配置Gitea Ingress
# ============================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 步骤 1/6: 配置Gitea Ingress"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitea
namespace: gitea
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
ingressClassName: traefik
rules:
- host: git.jpd.net3w.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitea-http
port:
number: 3000
EOF
echo "✅ Gitea Ingress配置完成"
echo " 访问地址: http://git.jpd.net3w.com"
echo ""
# ============================================
# 步骤 2: 配置ArgoCD访问
# ============================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 步骤 2/6: 配置ArgoCD访问"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# 配置ArgoCD为NodePort
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}'
# 创建ArgoCD Ingress
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server
namespace: argocd
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: argocd-stripprefix@kubernetescrd
spec:
ingressClassName: traefik
rules:
- host: argocd.jpd.net3w.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 80
EOF
ARGOCD_PORT=$(kubectl get svc argocd-server -n argocd -o jsonpath='{.spec.ports[0].nodePort}')
ARGOCD_PASSWORD=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)
echo "✅ ArgoCD访问配置完成"
echo " NodePort访问: http://149.13.91.216:$ARGOCD_PORT"
echo " 域名访问: http://argocd.jpd.net3w.com"
echo " 用户名: admin"
echo " 密码: $ARGOCD_PASSWORD"
echo ""
# ============================================
# 步骤 3: 部署cert-manager
# ============================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 步骤 3/6: 部署cert-manager"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
echo "⏳ 等待cert-manager就绪..."
sleep 30
kubectl wait --for=condition=ready pod -l app=cert-manager -n cert-manager --timeout=300s || true
kubectl wait --for=condition=ready pod -l app=webhook -n cert-manager --timeout=300s || true
# 创建Let's Encrypt ClusterIssuer
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@jpd.net3w.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: traefik
EOF
echo "✅ cert-manager部署完成"
echo ""
# ============================================
# 步骤 4: 配置HTTPS Ingress
# ============================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 步骤 4/6: 配置HTTPS Ingress"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# 更新Gitea Ingress支持HTTPS
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:
- git.jpd.net3w.com
secretName: gitea-tls
rules:
- host: git.jpd.net3w.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitea-http
port:
number: 3000
EOF
# 更新ArgoCD Ingress支持HTTPS
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.jpd.net3w.com
secretName: argocd-server-tls
rules:
- host: argocd.jpd.net3w.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 80
EOF
echo "✅ HTTPS Ingress配置完成"
echo " Gitea HTTPS: https://git.jpd.net3w.com"
echo " ArgoCD HTTPS: https://argocd.jpd.net3w.com"
echo ""
# ============================================
# 步骤 5: 部署测试应用
# ============================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 步骤 5/6: 部署测试应用"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# 创建测试应用命名空间
kubectl create namespace demo-app --dry-run=client -o yaml | kubectl apply -f -
# 部署Nginx测试应用
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
namespace: demo-app
labels:
app: nginx-demo
spec:
replicas: 3
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
configMap:
name: nginx-html
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-html
namespace: demo-app
data:
index.html: |
<!DOCTYPE html>
<html>
<head>
<title>JPD集群测试应用</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
background: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
text-align: center;
max-width: 600px;
}
h1 {
color: #667eea;
margin-bottom: 20px;
}
.status {
background: #10b981;
color: white;
padding: 10px 20px;
border-radius: 5px;
display: inline-block;
margin: 20px 0;
}
.info {
text-align: left;
background: #f3f4f6;
padding: 20px;
border-radius: 5px;
margin-top: 20px;
}
.info p {
margin: 10px 0;
}
.emoji {
font-size: 48px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="emoji">🚀</div>
<h1>JPD K3s集群测试应用</h1>
<div class="status">✅ 运行正常</div>
<div class="info">
<p><strong>集群名称:</strong> JPD Cluster</p>
<p><strong>部署方式:</strong> Kubernetes Deployment</p>
<p><strong>副本数:</strong> 3</p>
<p><strong>容器镜像:</strong> nginx:alpine</p>
<p><strong>访问域名:</strong> demo.jpd.net3w.com</p>
<p><strong>GitOps工具:</strong> ArgoCD</p>
<p><strong>Git仓库:</strong> Gitea</p>
</div>
<p style="margin-top: 20px; color: #6b7280;">
主机名: <span id="hostname">加载中...</span>
</p>
</div>
<script>
fetch('/hostname.txt')
.then(r => r.text())
.then(h => document.getElementById('hostname').textContent = h)
.catch(() => document.getElementById('hostname').textContent = '未知');
</script>
</body>
</html>
---
apiVersion: v1
kind: Service
metadata:
name: nginx-demo
namespace: demo-app
spec:
selector:
app: nginx-demo
ports:
- port: 80
targetPort: 80
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-demo
namespace: demo-app
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
ingressClassName: traefik
rules:
- host: demo.jpd.net3w.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-demo
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-demo-https
namespace: demo-app
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:
- demo.jpd.net3w.com
secretName: nginx-demo-tls
rules:
- host: demo.jpd.net3w.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-demo
port:
number: 80
EOF
echo "⏳ 等待测试应用就绪..."
kubectl wait --for=condition=ready pod -l app=nginx-demo -n demo-app --timeout=120s
echo "✅ 测试应用部署完成"
echo " 访问地址: http://demo.jpd.net3w.com"
echo " HTTPS访问: https://demo.jpd.net3w.com"
echo ""
# ============================================
# 步骤 6: 部署自动化测试
# ============================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 步骤 6/6: 部署自动化测试"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# 创建自动化测试CronJob
cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: CronJob
metadata:
name: health-check
namespace: demo-app
spec:
schedule: "*/5 * * * *" # 每5分钟运行一次
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
spec:
containers:
- name: curl
image: curlimages/curl:latest
command:
- /bin/sh
- -c
- |
echo "=== 健康检查开始 ==="
echo "时间: \$(date)"
echo ""
# 测试Gitea
echo "测试 Gitea..."
if curl -f -s http://gitea-http.gitea.svc.cluster.local:3000 > /dev/null; then
echo "✅ Gitea: 正常"
else
echo "❌ Gitea: 异常"
exit 1
fi
# 测试ArgoCD
echo "测试 ArgoCD..."
if curl -f -s -k http://argocd-server.argocd.svc.cluster.local > /dev/null; then
echo "✅ ArgoCD: 正常"
else
echo "❌ ArgoCD: 异常"
exit 1
fi
# 测试Demo应用
echo "测试 Demo应用..."
if curl -f -s http://nginx-demo.demo-app.svc.cluster.local > /dev/null; then
echo "✅ Demo应用: 正常"
else
echo "❌ Demo应用: 异常"
exit 1
fi
echo ""
echo "=== 所有服务健康检查通过 ==="
restartPolicy: OnFailure
EOF
# 立即运行一次测试
kubectl create job --from=cronjob/health-check health-check-manual -n demo-app || true
echo "✅ 自动化测试部署完成"
echo " 测试频率: 每5分钟"
echo " 查看测试日志: kubectl logs -n demo-app -l job-name=health-check-manual"
echo ""
# ============================================
# 最终状态检查
# ============================================
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🎉 部署完成!最终状态"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "📊 集群资源:"
kubectl get nodes -o wide
echo ""
echo "📦 所有Pod:"
kubectl get pods --all-namespaces | grep -E "NAMESPACE|Running|Completed"
echo ""
echo "🌐 所有Ingress:"
kubectl get ingress --all-namespaces
echo ""
echo "🔐 访问信息:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Gitea:"
echo " HTTP: http://git.jpd.net3w.com"
echo " HTTPS: https://git.jpd.net3w.com"
echo " 用户名: gitea_admin"
echo " 密码: GitAdmin@2026"
echo ""
echo "ArgoCD:"
echo " HTTP: http://argocd.jpd.net3w.com"
echo " HTTPS: https://argocd.jpd.net3w.com"
echo " NodePort: http://149.13.91.216:$ARGOCD_PORT"
echo " 用户名: admin"
echo " 密码: $ARGOCD_PASSWORD"
echo ""
echo "测试应用:"
echo " HTTP: http://demo.jpd.net3w.com"
echo " HTTPS: https://demo.jpd.net3w.com"
echo ""
echo "💡 提示:"
echo " - HTTPS证书需要1-2分钟签发"
echo " - 自动化测试每5分钟运行一次"
echo " - 查看测试日志: kubectl logs -n demo-app -l job-name=health-check-manual"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"