Skip to content

cs0511/PracticeCI

Repository files navigation

Practice CI - Rails Application with Jenkins & Kubernetes

这是一个使用 Jenkins CI/CD 部署到本地 Docker Kubernetes 的 Ruby on Rails 应用程序。

目录结构

PracticeCI/
├── Dockerfile                  # Docker 镜像构建文件
├── Jenkinsfile                 # Jenkins Pipeline 配置
├── k8s/                        # Kubernetes 配置文件
│   ├── deployment.yaml         # 部署配置
│   ├── service.yaml            # 服务配置
│   └── secret.yaml             # 密钥配置模板
└── scripts/                    # 自动化脚本
    ├── setup-jenkins.sh        # Jenkins 设置脚本
    ├── setup-kubernetes.sh     # Kubernetes 初始化脚本
    ├── deploy.sh               # 手动部署脚本
    └── cleanup.sh              # 清理脚本

前置要求

必需软件

  1. Docker Desktop (包含 Kubernetes)

  2. kubectl (Kubernetes 命令行工具)

    # macOS
    brew install kubectl
    
    # 验证安装
    kubectl version --client
  3. Git

    # macOS
    brew install git
  4. Ruby (用于本地开发)

    # 使用 rbenv 或 rvm 安装 Ruby 3.3.4
    rbenv install 3.3.4

快速开始

第一步: 启用 Docker Desktop Kubernetes

  1. 打开 Docker Desktop
  2. 进入 Settings > Kubernetes
  3. 勾选 "Enable Kubernetes"
  4. 点击 "Apply & Restart"
  5. 等待 Kubernetes 启动完成(状态显示为绿色)

验证 Kubernetes 是否运行:

kubectl cluster-info
kubectl get nodes

第二步: 设置 Rails Master Key

  1. 如果项目中有 config/master.key 文件,保持原样

  2. 如果没有,创建一个:

    # 生成新的 master key
    rails credentials:edit
    # 或手动创建
    echo "your-secret-key-here" > config/master.key
  3. 更新 Kubernetes Secret:

    # 方式 1: 使用脚本自动创建(推荐)
    ./scripts/setup-kubernetes.sh
    
    # 方式 2: 手动创建
    kubectl create secret generic rails-secrets \
      --from-literal=master-key="$(cat config/master.key)"

第三步: 设置本地 Docker Registry

Jenkins 需要一个 Docker Registry 来存储镜像:

# 启动本地 Docker Registry
docker run -d -p 5000:5000 --name registry --restart=always registry:2

# 验证 Registry 运行
curl http://localhost:5000/v2/_catalog

第四步: 设置 Jenkins

运行自动化设置脚本:

./scripts/setup-jenkins.sh

或手动设置:

# 创建 Jenkins 数据目录
mkdir -p ~/jenkins_home

# 启动 Jenkins 容器
docker run -d \
  --name jenkins \
  --restart unless-stopped \
  -p 8080:8080 \
  -p 50000:50000 \
  -v ~/jenkins_home:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v ~/.kube:/var/jenkins_home/.kube \
  jenkins/jenkins:lts

# 获取初始管理员密码
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

第五步: 配置 Jenkins

  1. 访问 Jenkins

  2. 安装插件

    • 选择 "Install suggested plugins"
    • 额外安装以下插件:
      • Docker Plugin
      • Kubernetes Plugin
      • Pipeline Plugin (通常已预装)
      • Git Plugin (通常已预装)
  3. 创建管理员用户

    • 填写用户名、密码、邮箱等信息
  4. 配置 Jenkins

    a. 配置 Docker:

    • Manage Jenkins > System
    • 找到 Docker 部分(如果没有,先安装 Docker Plugin)
    • 添加 Docker Host: unix:///var/run/docker.sock

    b. 配置 Kubernetes (可选):

    c. 安装 kubectl 到 Jenkins 容器:

    docker exec -u root jenkins sh -c "curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl && chmod +x kubectl && mv kubectl /usr/local/bin/"

第六步: 创建 Jenkins Pipeline

  1. 新建 Pipeline Job

    • 点击 "New Item"
    • 输入名称: "practice-ci-pipeline"
    • 选择 "Pipeline"
    • 点击 "OK"
  2. 配置 Pipeline

    • 在 Pipeline 部分:
      • Definition: Pipeline script from SCM
      • SCM: Git
      • Repository URL: 你的 Git 仓库地址
      • Branch: */main (或你的默认分支)
      • Script Path: Jenkinsfile
  3. 配置触发器 (可选)

    • 勾选 "Poll SCM"
    • Schedule: H/5 * * * * (每 5 分钟检查一次)
    • 或配置 GitHub Webhook 实现自动触发

第七步: 初始化 Kubernetes 资源

运行初始化脚本:

./scripts/setup-kubernetes.sh

这个脚本会:

  • 创建必要的 Namespace
  • 创建 Rails Secrets
  • 部署应用到 Kubernetes
  • 创建 Service 和 PVC

第八步: 运行第一次部署

有两种方式部署:

方式 1: 通过 Jenkins (推荐)

  1. 在 Jenkins 中打开你的 Pipeline Job
  2. 点击 "Build Now"
  3. 观察构建日志
  4. 等待构建完成

方式 2: 手动部署

./scripts/deploy.sh

第九步: 验证部署

# 查看 Pods 状态
kubectl get pods -l app=practice-ci

# 查看 Service
kubectl get svc practice-ci-service

# 查看日志
kubectl logs -f deployment/practice-ci

# 查看详细信息
kubectl describe deployment practice-ci

第十步: 访问应用

# 获取服务 URL
kubectl get svc practice-ci-service

# 对于 Docker Desktop Kubernetes,应用应该在:
# http://localhost

如果使用 LoadBalancer 类型的 Service,应用会自动暴露在 localhost 的 80 端口。

CI/CD 工作流程

Pipeline 流程

  1. Checkout - 从 Git 仓库拉取代码
  2. Build Docker Image - 构建 Docker 镜像
  3. Push to Registry - 推送镜像到本地 Registry
  4. Deploy to Kubernetes - 更新 Kubernetes Deployment
  5. Verify Deployment - 验证部署状态

自动触发

配置后,每次代码推送到 main 分支时,Jenkins 会自动:

  1. 检测到代码变更
  2. 触发 Pipeline 构建
  3. 构建新的 Docker 镜像
  4. 部署到 Kubernetes
  5. 验证部署成功

常用命令

Docker 命令

# 查看本地镜像
docker images | grep practice-ci

# 查看运行中的容器
docker ps

# 查看 Jenkins 日志
docker logs -f jenkins

# 重启 Jenkins
docker restart jenkins

# 停止本地 Registry
docker stop registry

# 启动本地 Registry
docker start registry

Kubernetes 命令

# 查看所有资源
kubectl get all

# 查看 Pods
kubectl get pods -l app=practice-ci

# 查看 Pod 详情
kubectl describe pod <pod-name>

# 查看日志
kubectl logs -f <pod-name>

# 进入 Pod 终端
kubectl exec -it <pod-name> -- /bin/bash

# 查看 Service
kubectl get svc

# 强制重启 Deployment
kubectl rollout restart deployment/practice-ci

# 查看部署历史
kubectl rollout history deployment/practice-ci

# 回滚到上一个版本
kubectl rollout undo deployment/practice-ci

# 扩容/缩容
kubectl scale deployment practice-ci --replicas=3

Jenkins 命令

# 查看 Jenkins 初始密码
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

# 进入 Jenkins 容器
docker exec -it jenkins /bin/bash

# 重启 Jenkins (在容器内)
docker exec jenkins systemctl reload jenkins

故障排查

问题 1: Pods 一直处于 Pending 状态

原因: 可能是资源不足或存储卷问题

解决方案:

# 查看详细信息
kubectl describe pod <pod-name>

# 检查 PVC 状态
kubectl get pvc

# 如果是 PVC 问题,删除并重新创建
kubectl delete pvc practice-ci-pvc
kubectl apply -f k8s/deployment.yaml

问题 2: 镜像拉取失败

原因: 本地 Registry 未运行或镜像不存在

解决方案:

# 检查 Registry 是否运行
curl http://localhost:5000/v2/_catalog

# 重启 Registry
docker restart registry

# 手动构建并推送镜像
./scripts/deploy.sh

问题 3: Jenkins 无法访问 Docker

原因: Docker socket 未正确挂载

解决方案:

# 重新创建 Jenkins 容器,确保挂载正确
docker rm -f jenkins
./scripts/setup-jenkins.sh

问题 4: 应用启动失败

原因: Rails Master Key 未正确配置

解决方案:

# 检查 Secret
kubectl get secret rails-secrets -o yaml

# 重新创建 Secret
kubectl delete secret rails-secrets
kubectl create secret generic rails-secrets \
  --from-literal=master-key="$(cat config/master.key)"

# 重启 Deployment
kubectl rollout restart deployment/practice-ci

问题 5: 无法访问应用

原因: Service 配置问题或端口占用

解决方案:

# 检查 Service
kubectl get svc practice-ci-service

# 查看端口映射
kubectl describe svc practice-ci-service

# 使用 port-forward 临时访问
kubectl port-forward svc/practice-ci-service 8081:80

# 然后访问 http://localhost:8081

清理资源

如果需要完全清理部署:

# 使用清理脚本(推荐)
./scripts/cleanup.sh

# 或手动清理
kubectl delete deployment practice-ci
kubectl delete service practice-ci-service
kubectl delete secret rails-secrets
kubectl delete pvc practice-ci-pvc

# 清理 Docker 镜像
docker rmi localhost:5000/practice-ci-rails:latest
docker system prune -f

# 停止并删除 Jenkins
docker stop jenkins
docker rm jenkins

# 停止并删除 Registry
docker stop registry
docker rm registry

生产环境注意事项

如果要部署到生产环境,需要考虑:

  1. 安全性

    • 使用私有 Docker Registry
    • 配置 HTTPS/TLS
    • 使用 Kubernetes Secrets 管理敏感信息
    • 配置网络策略
  2. 高可用性

    • 增加副本数量 (replicas)
    • 配置自动扩缩容 (HPA)
    • 使用持久化存储
  3. 监控和日志

    • 集成 Prometheus + Grafana
    • 配置集中日志收集 (ELK/EFK Stack)
    • 设置告警
  4. 备份和恢复

    • 定期备份数据库
    • 配置灾难恢复方案
  5. 性能优化

    • 配置资源限制和请求
    • 优化 Docker 镜像大小
    • 使用 CDN 加速静态资源

更多资源

技术支持

如有问题,请查看:

  1. Jenkins 构建日志
  2. Kubernetes Pod 日志: kubectl logs -f <pod-name>
  3. Kubernetes 事件: kubectl get events --sort-by=.metadata.creationTimestamp

Ruby 版本

  • Ruby 3.3.4
  • Rails 8.1.2

许可证

这是一个学习和实践项目。

About

PracticeCI

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published