522 lines
15 KiB
Bash
Executable File
522 lines
15 KiB
Bash
Executable File
#!/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 "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|