# 手动创建项目并实现GitOps自动化部署指南
本指南将带你从零开始,手动创建一个项目并实现GitOps自动化部署。
## 目录
1. [准备工作](#准备工作)
2. [创建项目结构](#创建项目结构)
3. [编写Kubernetes Manifests](#编写kubernetes-manifests)
4. [本地测试验证](#本地测试验证)
5. [上传到Gitea](#上传到gitea)
6. [配置ArgoCD自动部署](#配置argocd自动部署)
7. [验证和监控](#验证和监控)
8. [更新应用](#更新应用)
---
## 准备工作
### 环境要求
- K3s集群已部署并运行
- kubectl已配置并可访问集群
- Gitea已部署(Git仓库服务)
- ArgoCD已部署(GitOps工具)
- 域名已配置DNS解析
### 获取集群信息
```bash
# 查看集群节点
kubectl get nodes -o wide
# 获取Gitea访问地址
GITEA_PORT=$(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}')
echo "Gitea地址: http://$NODE_IP:$GITEA_PORT"
# 查看可用的IngressClass
kubectl get ingressclass
```
### 准备项目信息
在开始之前,确定以下信息:
- **项目名称**: 例如 `my-app`
- **域名**: 例如 `myapp.jpc.net3w.com`
- **应用类型**: Web应用、API服务、数据库等
- **容器镜像**: 例如 `nginx:1.25-alpine`
---
## 创建项目结构
### 步骤1: 创建项目目录
```bash
# 创建项目根目录
mkdir -p ~/my-app
cd ~/my-app
# 创建manifests目录(存放Kubernetes配置文件)
mkdir -p manifests
# 创建项目结构
tree
# my-app/
# └── manifests/
```
### 步骤2: 创建README文件
```bash
cat > README.md <<'EOF'
# My Application
这是一个由ArgoCD管理的应用,使用GitOps自动化部署。
## 应用信息
- **应用名称**: my-app
- **域名**: myapp.jpc.net3w.com
- **命名空间**: default
## 访问方式
```bash
# HTTP访问
curl http://myapp.jpc.net3w.com
# HTTPS访问
curl https://myapp.jpc.net3w.com
```
## 更新应用
修改 `manifests/` 目录下的文件并提交到Git,ArgoCD会自动同步部署。
## 监控部署
```bash
# 查看Pod状态
kubectl get pods -l app=my-app -n default
# 查看ArgoCD Application
kubectl get application my-app -n argocd
```
EOF
```
---
## 编写Kubernetes Manifests
### 步骤3: 创建Deployment配置
```bash
cat > manifests/deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: default
labels:
app: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: nginx:1.25-alpine # 替换为你的镜像
ports:
- containerPort: 80
name: http
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
EOF
```
**配置说明**:
- `replicas: 2` - 运行2个Pod副本
- `image` - 容器镜像,根据实际情况修改
- `resources` - 资源限制,防止资源耗尽
- `livenessProbe` - 存活探针,Pod不健康时自动重启
- `readinessProbe` - 就绪探针,Pod未就绪时不接收流量
### 步骤4: 创建Service配置
```bash
cat > manifests/service.yaml <<'EOF'
apiVersion: v1
kind: Service
metadata:
name: my-app
namespace: default
labels:
app: my-app
spec:
type: ClusterIP
selector:
app: my-app
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
EOF
```
**配置说明**:
- `type: ClusterIP` - 集群内部访问
- `selector` - 选择带有 `app=my-app` 标签的Pod
- `port: 80` - Service端口
### 步骤5: 创建Ingress配置
```bash
cat > manifests/ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
ingressClassName: traefik # 使用traefik(根据集群实际情况修改)
tls:
- hosts:
- myapp.jpc.net3w.com # 替换为你的域名
secretName: my-app-tls
rules:
- host: myapp.jpc.net3w.com # 替换为你的域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80
EOF
```
**配置说明**:
- `ingressClassName` - 使用的Ingress控制器(traefik或nginx)
- `cert-manager.io/cluster-issuer` - 自动签发HTTPS证书
- `tls` - HTTPS配置
- `rules` - 路由规则,将域名流量转发到Service
### 步骤6: 创建ConfigMap(可选)
如果需要自定义配置文件或HTML内容:
```bash
cat > manifests/configmap.yaml <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
namespace: default
data:
# 配置文件内容
app.conf: |
server {
listen 80;
server_name myapp.jpc.net3w.com;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
# HTML内容
index.html: |
My Application
Welcome to My Application
Version: v1.0
EOF
```
如果使用ConfigMap,需要在Deployment中挂载:
```yaml
# 在deployment.yaml的containers部分添加
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d/app.conf
subPath: app.conf
- name: html
mountPath: /usr/share/nginx/html
# 在spec部分添加
volumes:
- name: config
configMap:
name: my-app-config
- name: html
configMap:
name: my-app-config
```
---
## 本地测试验证
### 步骤7: 验证YAML语法
```bash
# 验证所有manifest文件的语法
kubectl apply --dry-run=client -f manifests/
# 应该看到类似输出:
# deployment.apps/my-app created (dry run)
# service/my-app created (dry run)
# ingress.networking.k8s.io/my-app created (dry run)
```
### 步骤8: 本地部署测试
```bash
# 部署到集群
kubectl apply -f manifests/
# 查看部署状态
kubectl get pods -l app=my-app -n default
kubectl get svc my-app -n default
kubectl get ingress my-app -n default
# 查看Pod日志
kubectl logs -l app=my-app -n default --tail=50
# 查看Pod详情(如果有问题)
kubectl describe pod -l app=my-app -n default
```
### 步骤9: 测试访问
```bash
# 方式1: 通过Service ClusterIP测试(集群内部)
kubectl run test-pod --rm -it --image=curlimages/curl -- sh
# 在Pod内执行: curl http://my-app.default.svc.cluster.local
# 方式2: 通过域名测试
curl http://myapp.jpc.net3w.com
curl https://myapp.jpc.net3w.com
# 方式3: 通过Host header测试
NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[0].address}')
curl -H "Host: myapp.jpc.net3w.com" http://$NODE_IP
```
### 步骤10: 验证成功后清理
```bash
# 测试成功后,删除手动部署的资源
# 稍后会通过ArgoCD重新部署
kubectl delete -f manifests/
```
---
## 上传到Gitea
### 步骤11: 在Gitea中创建仓库
**方式1: 通过Web界面创建**
1. 访问Gitea: `http://:`
2. 使用管理员账户登录(gitea_admin / GitAdmin@2026)
3. 点击右上角 "+" → "新建仓库"
4. 填写信息:
- 所有者: `k3s-apps`(组织)
- 仓库名称: `my-app`
- 描述: `My application for GitOps demo`
- 可见性: 公开
- 不要勾选"使用README初始化"
5. 点击"创建仓库"
**方式2: 通过API创建**
```bash
# 获取Gitea信息
GITEA_PORT=$(kubectl get svc gitea-http -n gitea -o jsonpath='{.spec.ports[0].nodePort}')
NODE_IP=8.216.38.248 # 替换为你的节点IP
GITEA_URL="http://$NODE_IP:$GITEA_PORT"
# 创建仓库
curl -X POST \
-u "gitea_admin:GitAdmin@2026" \
-H "Content-Type: application/json" \
-d '{"name":"my-app","description":"My application for GitOps demo","private":false,"auto_init":false}' \
"$GITEA_URL/api/v1/org/k3s-apps/repos"
# 验证仓库已创建
curl -s -u "gitea_admin:GitAdmin@2026" "$GITEA_URL/api/v1/orgs/k3s-apps/repos" | jq -r '.[].name'
```
### 步骤12: 初始化Git仓库
```bash
cd ~/my-app
# 初始化Git仓库
git init -b main
# 配置Git用户信息
git config user.name "gitea_admin"
git config user.email "admin@jpc.net3w.com"
# 添加所有文件
git add .
# 查看将要提交的文件
git status
# 提交
git commit -m "Initial commit: Add my-app manifests
Co-Authored-By: Claude Sonnet 4.5 "
```
### 步骤13: 推送到Gitea
```bash
# 添加远程仓库
GITEA_PORT=$(kubectl get svc gitea-http -n gitea -o jsonpath='{.spec.ports[0].nodePort}')
NODE_IP=8.216.38.248 # 替换为你的节点IP
REPO_URL="http://$NODE_IP:$GITEA_PORT/k3s-apps/my-app.git"
git remote add origin "$REPO_URL"
# 推送(使用管理员账户)
git remote set-url origin "http://gitea_admin:GitAdmin%402026@$NODE_IP:$GITEA_PORT/k3s-apps/my-app.git"
git push -u origin main
# 验证推送成功
echo "访问Gitea查看仓库: $REPO_URL"
```
**常见问题**:
- **503错误**: Gitea服务可能正在启动,等待几秒后重试
- **403错误**: 检查用户名密码是否正确
- **认证失败**: 确保密码中的特殊字符已URL编码(@编码为%40)
---
## 配置ArgoCD自动部署
### 步骤14: 创建ArgoCD Application
```bash
# 创建Application配置文件
cat > /tmp/my-app-argocd.yaml < update-app.sh <<'EOF'
#!/bin/bash
set -e
VERSION=${1:-v2.0}
echo "🔄 更新应用到版本 $VERSION"
# 修改版本号(根据实际情况修改)
sed -i "s/Version: v[0-9.]*/Version: $VERSION/" manifests/configmap.yaml
# 提交更改
git add .
git commit -m "Update to $VERSION
Co-Authored-By: Claude Sonnet 4.5 "
git push
echo "✅ 更新完成!"
echo "⏳ 等待ArgoCD同步(约3分钟)..."
EOF
chmod +x update-app.sh
# 使用脚本更新
./update-app.sh v2.0
```
### 方式3: 通过ArgoCD UI手动同步
1. 访问ArgoCD UI
2. 找到你的应用
3. 点击"SYNC"按钮
4. 选择同步选项
5. 点击"SYNCHRONIZE"
### 监控更新进度
```bash
# 监控Pod更新
watch kubectl get pods -l app=my-app -n default
# 查看滚动更新状态
kubectl rollout status deployment/my-app -n default
# 查看更新历史
kubectl rollout history deployment/my-app -n default
```
---
## 故障排查
### 常见问题1: Pod无法启动
```bash
# 查看Pod状态
kubectl get pods -l app=my-app -n default
# 查看Pod详情
kubectl describe pod -l app=my-app -n default
# 查看Pod日志
kubectl logs -l app=my-app -n default --tail=100
# 查看事件
kubectl get events -n default --sort-by='.lastTimestamp' | grep my-app
```
**可能原因**:
- 镜像拉取失败
- 资源不足
- 配置错误
- 健康检查失败
### 常见问题2: Ingress无法访问
```bash
# 检查Ingress配置
kubectl describe ingress my-app -n default
# 检查IngressClass
kubectl get ingressclass
# 测试Service是否正常
kubectl run test-pod --rm -it --image=curlimages/curl -- \
curl http://my-app.default.svc.cluster.local
# 检查DNS解析
nslookup myapp.jpc.net3w.com
```
**可能原因**:
- IngressClass配置错误(应该是traefik)
- DNS未解析到正确IP
- 证书未签发
- Service配置错误
### 常见问题3: ArgoCD不同步
```bash
# 查看Application状态
kubectl describe application my-app -n argocd
# 查看ArgoCD repo-server日志
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-repo-server --tail=50
# 清除ArgoCD缓存
kubectl exec -n argocd deployment/argocd-repo-server -- \
sh -c "rm -rf /tmp/_argocd-repo/*"
# 重启repo-server
kubectl delete pod -n argocd -l app.kubernetes.io/name=argocd-repo-server
# 手动触发同步
kubectl patch application my-app -n argocd \
--type merge \
-p '{"operation":{"initiatedBy":{"username":"admin"},"sync":{"revision":"HEAD"}}}'
```
**可能原因**:
- Git仓库访问失败
- YAML语法错误
- ArgoCD缓存问题
- 网络问题
### 常见问题4: 证书未签发
```bash
# 查看证书状态
kubectl get certificate -n default
# 查看证书详情
kubectl describe certificate my-app-tls -n default
# 查看cert-manager日志
kubectl logs -n cert-manager -l app=cert-manager --tail=50
# 查看证书请求
kubectl get certificaterequest -n default
```
**可能原因**:
- cert-manager未正确配置
- DNS验证失败
- Let's Encrypt速率限制
- Ingress注解错误
---
## 回滚操作
### 通过Git回滚
```bash
cd ~/my-app
# 查看提交历史
git log --oneline
# 回滚到指定commit
git revert
git push
# ArgoCD会自动同步回滚
```
### 通过kubectl回滚
```bash
# 查看部署历史
kubectl rollout history deployment/my-app -n default
# 回滚到上一个版本
kubectl rollout undo deployment/my-app -n default
# 回滚到指定版本
kubectl rollout undo deployment/my-app -n default --to-revision=2
```
### 通过ArgoCD回滚
```bash
# 查看历史版本
argocd app history my-app
# 回滚到指定版本
argocd app rollback my-app
```
---
## 清理资源
### 删除应用
```bash
# 删除ArgoCD Application(会自动删除K8s资源)
kubectl delete application my-app -n argocd
# 或者手动删除资源
kubectl delete -f manifests/
```
### 删除Git仓库
```bash
# 通过API删除
GITEA_PORT=$(kubectl get svc gitea-http -n gitea -o jsonpath='{.spec.ports[0].nodePort}')
NODE_IP=8.216.38.248
curl -X DELETE \
-u "gitea_admin:GitAdmin@2026" \
"http://$NODE_IP:$GITEA_PORT/api/v1/repos/k3s-apps/my-app"
```
---
## 最佳实践
### 1. 项目结构
```
my-app/
├── README.md # 项目说明
├── manifests/ # Kubernetes配置
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ └── configmap.yaml
├── update-app.sh # 更新脚本
└── .gitignore # Git忽略文件
```
### 2. 命名规范
- **应用名称**: 使用小写字母和连字符,如 `my-app`
- **标签**: 统一使用 `app=my-app`
- **命名空间**: 根据环境划分,如 `default`, `staging`, `production`
### 3. 资源配置
- **副本数**: 至少2个,保证高可用
- **资源限制**: 必须设置requests和limits
- **健康检查**: 配置liveness和readiness探针
- **镜像标签**: 使用具体版本号,避免使用latest
### 4. Git提交规范
```bash
# 好的提交信息
git commit -m "Add health check endpoint"
git commit -m "Scale up to 3 replicas"
git commit -m "Update to version 2.0"
# 不好的提交信息
git commit -m "update"
git commit -m "fix"
```
### 5. 安全建议
- 使用私有仓库存储敏感配置
- 使用Kubernetes Secrets存储密码
- 定期更新镜像版本
- 启用HTTPS和证书自动续期
- 配置网络策略限制Pod通信
### 6. 监控和日志
```bash
# 配置日志收集
kubectl logs -l app=my-app -n default --tail=100 -f
# 配置监控告警
# 使用Prometheus + Grafana监控应用指标
# 配置资源监控
kubectl top pods -l app=my-app -n default
```
---
## 快速参考
### 常用命令
```bash
# 查看应用状态
kubectl get all -l app=my-app -n default
# 查看ArgoCD Application
kubectl get application my-app -n argocd
# 查看日志
kubectl logs -l app=my-app -n default --tail=50 -f
# 进入Pod调试
kubectl exec -it -n default -- sh
# 查看资源使用
kubectl top pods -l app=my-app -n default
# 手动触发同步
kubectl patch application my-app -n argocd \
--type merge \
-p '{"operation":{"initiatedBy":{"username":"admin"},"sync":{"revision":"HEAD"}}}'
```
### 配置文件模板
所有配置文件模板可以在 `templates/` 目录找到,或参考现有项目:
- nginx-app: http://8.216.38.248:32158/k3s-apps/nginx-app
- test-app: http://8.216.38.248:32158/k3s-apps/test-app
- demo-app: http://8.216.38.248:32158/k3s-apps/demo-app
---
## 总结
通过本指南,你已经学会了:
1. ✅ 创建项目结构和编写Kubernetes manifests
2. ✅ 本地测试和验证配置
3. ✅ 上传代码到Gitea Git仓库
4. ✅ 配置ArgoCD实现GitOps自动化部署
5. ✅ 监控和更新应用
6. ✅ 故障排查和回滚操作
**GitOps工作流**:
```
开发者修改代码 → 提交到Git → ArgoCD检测变化 → 自动同步部署 → 应用更新完成
```
**下一步**:
- 学习更多Kubernetes资源类型(StatefulSet, DaemonSet等)
- 配置多环境部署(dev, staging, production)
- 集成CI/CD流水线(Jenkins, GitLab CI等)
- 配置监控告警系统(Prometheus, Grafana)
---
## 相关文档
- [K3s官方文档](https://docs.k3s.io/)
- [ArgoCD官方文档](https://argo-cd.readthedocs.io/)
- [Kubernetes官方文档](https://kubernetes.io/docs/)
- [Gitea官方文档](https://docs.gitea.io/)
## 技术支持
如有问题,请查看:
- 项目README: `/home/fei/opk3s/k3s自动化部署/README.md`
- 故障排查指南: `/home/fei/opk3s/k3s自动化部署/TROUBLESHOOTING-ACCESS.md`
- 部署指南: `/home/fei/opk3s/k3s自动化部署/DEPLOYMENT-GUIDE.md`