fix: 将 k3s-ansible 作为普通目录添加
This commit is contained in:
538
scripts/push-nginx-app.sh
Executable file
538
scripts/push-nginx-app.sh
Executable file
@@ -0,0 +1,538 @@
|
||||
#!/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 "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
Reference in New Issue
Block a user