20 KiB
20 KiB
手动创建项目并实现GitOps自动化部署指南
本指南将带你从零开始,手动创建一个项目并实现GitOps自动化部署。
目录
准备工作
环境要求
- K3s集群已部署并运行
- kubectl已配置并可访问集群
- Gitea已部署(Git仓库服务)
- ArgoCD已部署(GitOps工具)
- 域名已配置DNS解析
获取集群信息
# 查看集群节点
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: 创建项目目录
# 创建项目根目录
mkdir -p ~/my-app
cd ~/my-app
# 创建manifests目录(存放Kubernetes配置文件)
mkdir -p manifests
# 创建项目结构
tree
# my-app/
# └── manifests/
步骤2: 创建README文件
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会自动同步部署。
监控部署
# 查看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配置
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标签的Podport: 80- Service端口
步骤5: 创建Ingress配置
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内容:
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: |
<!DOCTYPE html>
<html>
<head>
<title>My Application</title>
</head>
<body>
<h1>Welcome to My Application</h1>
<p>Version: v1.0</p>
</body>
</html>
EOF
如果使用ConfigMap,需要在Deployment中挂载:
# 在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语法
# 验证所有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: 本地部署测试
# 部署到集群
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: 测试访问
# 方式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: 验证成功后清理
# 测试成功后,删除手动部署的资源
# 稍后会通过ArgoCD重新部署
kubectl delete -f manifests/
上传到Gitea
步骤11: 在Gitea中创建仓库
方式1: 通过Web界面创建
- 访问Gitea:
http://<NODE_IP>:<GITEA_PORT> - 使用管理员账户登录(gitea_admin / GitAdmin@2026)
- 点击右上角 "+" → "新建仓库"
- 填写信息:
- 所有者:
k3s-apps(组织) - 仓库名称:
my-app - 描述:
My application for GitOps demo - 可见性: 公开
- 不要勾选"使用README初始化"
- 所有者:
- 点击"创建仓库"
方式2: 通过API创建
# 获取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仓库
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 <noreply@anthropic.com>"
步骤13: 推送到Gitea
# 添加远程仓库
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
# 创建Application配置文件
cat > /tmp/my-app-argocd.yaml <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
labels:
app: my-app
spec:
project: default
source:
repoURL: http://gitea-http.gitea.svc.cluster.local:3000/k3s-apps/my-app.git
targetRevision: main
path: manifests
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true # 自动删除Git中不存在的资源
selfHeal: true # 自动修复手动修改的资源
syncOptions:
- CreateNamespace=true
EOF
# 应用配置
kubectl apply -f /tmp/my-app-argocd.yaml
# 查看Application状态
kubectl get application my-app -n argocd
配置说明:
repoURL- Git仓库地址(使用集群内部地址)targetRevision: main- 监控main分支path: manifests- manifests目录automated- 启用自动同步prune: true- 自动删除不需要的资源selfHeal: true- 自动修复被手动修改的资源
步骤15: 配置Git仓库凭证(如果是私有仓库)
# 创建Git凭证Secret
kubectl create secret generic gitea-creds \
-n argocd \
--from-literal=username="argocd" \
--from-literal=password="ArgoCD@2026" \
--dry-run=client -o yaml | kubectl apply -f -
步骤16: 手动触发首次同步
# 触发同步
kubectl patch application my-app -n argocd \
--type merge \
-p '{"operation":{"initiatedBy":{"username":"admin"},"sync":{"revision":"HEAD"}}}'
# 或者使用ArgoCD CLI(如果已安装)
argocd app sync my-app
验证和监控
步骤17: 监控同步状态
# 实时监控Application状态
watch kubectl get application my-app -n argocd
# 查看详细状态
kubectl describe application my-app -n argocd
# 查看同步历史
kubectl get application my-app -n argocd -o jsonpath='{.status.operationState}'
状态说明:
Sync Status: Synced- 已同步Health Status: Healthy- 健康Sync Status: OutOfSync- 未同步(Git有更新)Sync Status: Unknown- 未知(可能有错误)
步骤18: 查看部署的资源
# 查看所有资源
kubectl get all -l app=my-app -n default
# 查看Pod
kubectl get pods -l app=my-app -n default -o wide
# 查看Service
kubectl get svc my-app -n default
# 查看Ingress
kubectl get ingress my-app -n default
# 查看证书状态
kubectl get certificate -n default | grep my-app
步骤19: 测试应用访问
# HTTP访问
curl http://myapp.jpc.net3w.com
# HTTPS访问
curl https://myapp.jpc.net3w.com
# 查看响应头
curl -I https://myapp.jpc.net3w.com
# 浏览器访问
echo "在浏览器中访问: https://myapp.jpc.net3w.com"
步骤20: 查看ArgoCD UI
# 获取ArgoCD访问地址
echo "ArgoCD UI: https://argocd.jpc.net3w.com"
# 获取admin密码(如果忘记)
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d && echo
在ArgoCD UI中可以看到:
- 应用的同步状态
- 资源拓扑图
- 同步历史
- 事件日志
更新应用
方式1: 修改Git仓库
cd ~/my-app
# 修改配置(例如:增加副本数)
sed -i 's/replicas: 2/replicas: 3/' manifests/deployment.yaml
# 查看修改
git diff
# 提交更改
git add manifests/deployment.yaml
git commit -m "Scale up to 3 replicas"
git push
# ArgoCD会在3分钟内自动检测并同步
方式2: 创建更新脚本
cat > 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 <noreply@anthropic.com>"
git push
echo "✅ 更新完成!"
echo "⏳ 等待ArgoCD同步(约3分钟)..."
EOF
chmod +x update-app.sh
# 使用脚本更新
./update-app.sh v2.0
方式3: 通过ArgoCD UI手动同步
- 访问ArgoCD UI
- 找到你的应用
- 点击"SYNC"按钮
- 选择同步选项
- 点击"SYNCHRONIZE"
监控更新进度
# 监控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无法启动
# 查看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无法访问
# 检查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不同步
# 查看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: 证书未签发
# 查看证书状态
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回滚
cd ~/my-app
# 查看提交历史
git log --oneline
# 回滚到指定commit
git revert <commit-hash>
git push
# ArgoCD会自动同步回滚
通过kubectl回滚
# 查看部署历史
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回滚
# 查看历史版本
argocd app history my-app
# 回滚到指定版本
argocd app rollback my-app <revision-id>
清理资源
删除应用
# 删除ArgoCD Application(会自动删除K8s资源)
kubectl delete application my-app -n argocd
# 或者手动删除资源
kubectl delete -f manifests/
删除Git仓库
# 通过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提交规范
# 好的提交信息
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. 监控和日志
# 配置日志收集
kubectl logs -l app=my-app -n default --tail=100 -f
# 配置监控告警
# 使用Prometheus + Grafana监控应用指标
# 配置资源监控
kubectl top pods -l app=my-app -n default
快速参考
常用命令
# 查看应用状态
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 <pod-name> -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
总结
通过本指南,你已经学会了:
- ✅ 创建项目结构和编写Kubernetes manifests
- ✅ 本地测试和验证配置
- ✅ 上传代码到Gitea Git仓库
- ✅ 配置ArgoCD实现GitOps自动化部署
- ✅ 监控和更新应用
- ✅ 故障排查和回滚操作
GitOps工作流:
开发者修改代码 → 提交到Git → ArgoCD检测变化 → 自动同步部署 → 应用更新完成
下一步:
- 学习更多Kubernetes资源类型(StatefulSet, DaemonSet等)
- 配置多环境部署(dev, staging, production)
- 集成CI/CD流水线(Jenkins, GitLab CI等)
- 配置监控告警系统(Prometheus, Grafana)
相关文档
技术支持
如有问题,请查看:
- 项目README:
/home/fei/opk3s/k3s自动化部署/README.md - 故障排查指南:
/home/fei/opk3s/k3s自动化部署/TROUBLESHOOTING-ACCESS.md - 部署指南:
/home/fei/opk3s/k3s自动化部署/DEPLOYMENT-GUIDE.md