Files
k3s_auto_deploy/scripts/push-nginx-app.sh

539 lines
14 KiB
Bash
Executable File
Raw Permalink 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
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
CONFIG_FILE="$PROJECT_DIR/config/cluster-vars.yml"
echo "=== 推送Nginx测试应用到Gitea ==="
# 读取配置
GITEA_USER=$(yq eval '.gitea_user_name' "$CONFIG_FILE")
GITEA_PASSWORD=$(yq eval '.gitea_user_password' "$CONFIG_FILE")
GITEA_ORG=$(yq eval '.gitea_org_name' "$CONFIG_FILE")
NGINX_REPO=$(yq eval '.nginx_app_repo_name' "$CONFIG_FILE")
NGINX_DOMAIN=$(yq eval '.nginx_app_domain' "$CONFIG_FILE")
# 获取Gitea NodePort
GITEA_NODEPORT=$(kubectl get svc gitea-http -n gitea -o jsonpath='{.spec.ports[0].nodePort}')
NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="ExternalIP")].address}')
if [ -z "$NODE_IP" ]; then
NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
fi
GITEA_URL="http://$NODE_IP:$GITEA_NODEPORT"
REPO_URL="$GITEA_URL/$GITEA_ORG/$NGINX_REPO.git"
# 创建临时目录
TEMP_DIR=$(mktemp -d)
cd "$TEMP_DIR"
echo "📝 创建Nginx应用清单..."
# 创建manifests目录
mkdir -p manifests
# 创建Nginx Deployment
cat > manifests/deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-test
namespace: default
labels:
app: nginx-test
spec:
replicas: 2
selector:
matchLabels:
app: nginx-test
template:
metadata:
labels:
app: nginx-test
spec:
containers:
- name: nginx
image: nginx:1.25-alpine
ports:
- containerPort: 80
name: http
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
- name: html
mountPath: /usr/share/nginx/html
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: nginx-config
configMap:
name: nginx-config
- name: html
configMap:
name: nginx-html
EOF
# 创建Nginx ConfigMap
cat > manifests/configmap.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: default
data:
default.conf: |
server {
listen 80;
server_name ${NGINX_DOMAIN};
location / {
root /usr/share/nginx/html;
index index.html;
}
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-html
namespace: default
data:
index.html: |
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nginx Test - GitOps Demo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
padding: 60px;
max-width: 800px;
text-align: center;
}
h1 {
color: #667eea;
font-size: 3em;
margin-bottom: 20px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
}
.version {
display: inline-block;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 10px 30px;
border-radius: 50px;
font-size: 1.2em;
font-weight: bold;
margin: 20px 0;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}
.info {
background: #f8f9fa;
border-radius: 10px;
padding: 30px;
margin: 30px 0;
text-align: left;
}
.info-item {
display: flex;
justify-content: space-between;
padding: 15px 0;
border-bottom: 1px solid #e9ecef;
}
.info-item:last-child {
border-bottom: none;
}
.info-label {
font-weight: bold;
color: #495057;
}
.info-value {
color: #667eea;
font-family: 'Courier New', monospace;
}
.badge {
display: inline-block;
background: #28a745;
color: white;
padding: 5px 15px;
border-radius: 20px;
font-size: 0.9em;
margin: 10px 5px;
}
.footer {
margin-top: 30px;
color: #6c757d;
font-size: 0.9em;
}
.emoji {
font-size: 3em;
margin-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="emoji">🚀</div>
<h1>Nginx Test Application</h1>
<div class="version">Version: v1.0</div>
<div class="info">
<div class="info-item">
<span class="info-label">域名:</span>
<span class="info-value">${NGINX_DOMAIN}</span>
</div>
<div class="info-item">
<span class="info-label">应用名称:</span>
<span class="info-value">nginx-test</span>
</div>
<div class="info-item">
<span class="info-label">镜像:</span>
<span class="info-value">nginx:1.25-alpine</span>
</div>
<div class="info-item">
<span class="info-label">副本数:</span>
<span class="info-value">2</span>
</div>
<div class="info-item">
<span class="info-label">部署方式:</span>
<span class="info-value">GitOps (ArgoCD)</span>
</div>
</div>
<div>
<span class="badge">✓ Kubernetes</span>
<span class="badge">✓ GitOps</span>
<span class="badge">✓ ArgoCD</span>
<span class="badge">✓ Nginx</span>
</div>
<div class="footer">
<p>🎯 这是一个通过GitOps自动部署的Nginx测试应用</p>
<p>修改Git仓库中的配置ArgoCD会自动同步部署</p>
</div>
</div>
</body>
</html>
EOF
# 创建Service
cat > manifests/service.yaml <<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx-test
namespace: default
labels:
app: nginx-test
spec:
type: ClusterIP
selector:
app: nginx-test
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
EOF
# 创建Ingress
cat > manifests/ingress.yaml <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-test
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- ${NGINX_DOMAIN}
secretName: nginx-test-tls
rules:
- host: ${NGINX_DOMAIN}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-test
port:
number: 80
EOF
# 创建README
cat > README.md <<EOF
# Nginx Test Application
这是一个由ArgoCD管理的Nginx测试应用用于演示GitOps自动化部署。
## 应用信息
- **应用名称**: nginx-test
- **镜像**: nginx:1.25-alpine
- **副本数**: 2
- **域名**: ${NGINX_DOMAIN}
- **命名空间**: default
## 架构说明
\`\`\`
Git仓库 (Gitea) → ArgoCD监控 → 自动同步 → K3s集群部署
\`\`\`
## 访问方式
### 通过域名访问(推荐)
\`\`\`bash
curl https://${NGINX_DOMAIN}
\`\`\`
### 通过NodePort访问
\`\`\`bash
# 获取Service信息
kubectl get svc nginx-test -n default
# 访问应用
curl http://<NODE_IP>:<NODE_PORT>
\`\`\`
## 更新应用
### 方式1: 修改版本号
编辑 \`manifests/configmap.yaml\` 中的 HTML 内容,修改版本号:
\`\`\`html
<div class="version">Version: v2.0</div>
\`\`\`
### 方式2: 修改副本数
编辑 \`manifests/deployment.yaml\`
\`\`\`yaml
spec:
replicas: 3 # 修改副本数
\`\`\`
### 方式3: 更新Nginx配置
编辑 \`manifests/configmap.yaml\` 中的 nginx 配置。
提交更改后ArgoCD会在3分钟内自动检测并部署新版本。
## 监控部署状态
\`\`\`bash
# 查看ArgoCD Application状态
kubectl get application nginx-app -n argocd
# 查看Pod状态
kubectl get pods -l app=nginx-test -n default
# 查看Ingress状态
kubectl get ingress nginx-test -n default
# 查看应用日志
kubectl logs -l app=nginx-test -n default --tail=50
\`\`\`
## 健康检查
应用提供了健康检查端点:
\`\`\`bash
curl https://${NGINX_DOMAIN}/health
\`\`\`
## 故障排查
### 检查Pod状态
\`\`\`bash
kubectl describe pod -l app=nginx-test -n default
\`\`\`
### 检查Ingress
\`\`\`bash
kubectl describe ingress nginx-test -n default
\`\`\`
### 检查ArgoCD同步状态
\`\`\`bash
kubectl describe application nginx-app -n argocd
\`\`\`
## GitOps工作流
1. 开发者修改 \`manifests/\` 目录下的配置文件
2. 提交并推送到Git仓库
3. ArgoCD自动检测到变化每3分钟轮询一次
4. ArgoCD自动同步并部署到K3s集群
5. 应用自动更新无需手动执行kubectl命令
## 回滚操作
如果需要回滚到之前的版本:
\`\`\`bash
# 查看Git历史
git log --oneline
# 回滚到指定commit
git revert <commit-hash>
git push
# 或者通过ArgoCD UI进行回滚
\`\`\`
## 技术栈
- **容器编排**: Kubernetes (K3s)
- **Web服务器**: Nginx 1.25
- **GitOps工具**: ArgoCD
- **Git仓库**: Gitea
- **Ingress控制器**: Nginx Ingress Controller
- **证书管理**: cert-manager (Let's Encrypt)
## 注意事项
1. 确保DNS已正确配置${NGINX_DOMAIN} 指向K3s集群节点IP
2. 首次访问HTTPS可能需要等待证书签发约1-2分钟
3. ArgoCD默认每3分钟检查一次Git仓库更新
4. 可以通过ArgoCD UI手动触发同步以立即部署更改
## 相关链接
- ArgoCD Dashboard: https://argocd.jpc.net3w.com
- Gitea Repository: http://<NODE_IP>:<GITEA_PORT>/k3s-apps/nginx-app
- Application URL: https://${NGINX_DOMAIN}
EOF
# 创建更新脚本
cat > update-app.sh <<'SCRIPT_EOF'
#!/bin/bash
set -e
VERSION=${1:-v2.0}
echo "🔄 更新Nginx应用到版本 $VERSION"
# 修改版本号
sed -i "s/Version: v[0-9.]*/Version: $VERSION/" manifests/configmap.yaml
# 根据版本修改背景色
case $VERSION in
v1.0)
COLOR="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
;;
v2.0)
COLOR="linear-gradient(135deg, #f093fb 0%, #f5576c 100%)"
;;
v3.0)
COLOR="linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)"
;;
*)
COLOR="linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)"
;;
esac
sed -i "s|background: linear-gradient([^)]*)|background: $COLOR|" manifests/configmap.yaml
# 提交更改
git add manifests/configmap.yaml
git commit -m "Update nginx-app to $VERSION
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
git push
echo "✅ 更新完成!"
echo "⏳ 等待ArgoCD同步约3分钟..."
echo "🌐 访问 https://ng.jpc.net3w.com 查看更新"
SCRIPT_EOF
chmod +x update-app.sh
# 初始化Git仓库
echo "🔧 初始化Git仓库..."
git init -b main
git config user.name "$GITEA_USER"
git config user.email "$GITEA_USER@example.com"
git add .
git commit -m "Initial commit: Add nginx test application
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
# 推送到Gitea
echo "📤 推送到Gitea..."
git remote add origin "$REPO_URL"
# URL encode the password to handle special characters
ENCODED_PASSWORD=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$GITEA_PASSWORD'))")
git push -u origin main || {
echo "⚠️ 首次推送失败,尝试使用凭证..."
git remote set-url origin "http://$GITEA_USER:$ENCODED_PASSWORD@$NODE_IP:$GITEA_NODEPORT/$GITEA_ORG/$NGINX_REPO.git"
git push -u origin main
}
# 清理
cd "$PROJECT_DIR"
rm -rf "$TEMP_DIR"
echo ""
echo "✅ Nginx测试应用推送成功"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 仓库信息:"
echo " - 仓库地址: $REPO_URL"
echo " - Gitea访问: $GITEA_URL/$GITEA_ORG/$NGINX_REPO"
echo ""
echo "🌐 应用信息:"
echo " - 域名: https://${NGINX_DOMAIN}"
echo " - 应用名称: nginx-test"
echo " - 命名空间: default"
echo ""
echo "📝 下一步:"
echo " 1. 运行: ./scripts/create-nginx-argocd-app.sh"
echo " 2. 等待ArgoCD同步约3分钟"
echo " 3. 访问: https://${NGINX_DOMAIN}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"