Files
k3s_auto_deploy/MANUAL-DEPLOYMENT-GUIDE.md

20 KiB
Raw Permalink Blame History

手动创建项目并实现GitOps自动化部署指南

本指南将带你从零开始手动创建一个项目并实现GitOps自动化部署。

目录

  1. 准备工作
  2. 创建项目结构
  3. 编写Kubernetes Manifests
  4. 本地测试验证
  5. 上传到Gitea
  6. 配置ArgoCD自动部署
  7. 验证和监控
  8. 更新应用

准备工作

环境要求

  • 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/ 目录下的文件并提交到GitArgoCD会自动同步部署。

监控部署

# 查看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 标签的Pod
  • port: 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界面创建

  1. 访问Gitea: http://<NODE_IP>:<GITEA_PORT>
  2. 使用管理员账户登录gitea_admin / GitAdmin@2026
  3. 点击右上角 "+" → "新建仓库"
  4. 填写信息:
    • 所有者: k3s-apps(组织)
    • 仓库名称: my-app
    • 描述: My application for GitOps demo
    • 可见性: 公开
    • 不要勾选"使用README初始化"
  5. 点击"创建仓库"

方式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手动同步

  1. 访问ArgoCD UI
  2. 找到你的应用
  3. 点击"SYNC"按钮
  4. 选择同步选项
  5. 点击"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/ 目录找到,或参考现有项目:


总结

通过本指南,你已经学会了:

  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

相关文档

技术支持

如有问题,请查看:

  • 项目README: /home/fei/opk3s/k3s自动化部署/README.md
  • 故障排查指南: /home/fei/opk3s/k3s自动化部署/TROUBLESHOOTING-ACCESS.md
  • 部署指南: /home/fei/opk3s/k3s自动化部署/DEPLOYMENT-GUIDE.md