这是一个使用 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 # 清理脚本
-
Docker Desktop (包含 Kubernetes)
- 下载: https://www.docker.com/products/docker-desktop
- 确保在 Docker Desktop 设置中启用 Kubernetes
- 版本: 最新稳定版
-
kubectl (Kubernetes 命令行工具)
# macOS brew install kubectl # 验证安装 kubectl version --client
-
Git
# macOS brew install git -
Ruby (用于本地开发)
# 使用 rbenv 或 rvm 安装 Ruby 3.3.4 rbenv install 3.3.4
- 打开 Docker Desktop
- 进入 Settings > Kubernetes
- 勾选 "Enable Kubernetes"
- 点击 "Apply & Restart"
- 等待 Kubernetes 启动完成(状态显示为绿色)
验证 Kubernetes 是否运行:
kubectl cluster-info
kubectl get nodes-
如果项目中有
config/master.key文件,保持原样 -
如果没有,创建一个:
# 生成新的 master key rails credentials:edit # 或手动创建 echo "your-secret-key-here" > config/master.key
-
更新 Kubernetes Secret:
# 方式 1: 使用脚本自动创建(推荐) ./scripts/setup-kubernetes.sh # 方式 2: 手动创建 kubectl create secret generic rails-secrets \ --from-literal=master-key="$(cat config/master.key)"
Jenkins 需要一个 Docker Registry 来存储镜像:
# 启动本地 Docker Registry
docker run -d -p 5000:5000 --name registry --restart=always registry:2
# 验证 Registry 运行
curl http://localhost:5000/v2/_catalog运行自动化设置脚本:
./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
- 打开浏览器访问: http://localhost:8080
- 输入初始管理员密码(从上一步获取)
-
安装插件
- 选择 "Install suggested plugins"
- 额外安装以下插件:
- Docker Plugin
- Kubernetes Plugin
- Pipeline Plugin (通常已预装)
- Git Plugin (通常已预装)
-
创建管理员用户
- 填写用户名、密码、邮箱等信息
-
配置 Jenkins
a. 配置 Docker:
- Manage Jenkins > System
- 找到 Docker 部分(如果没有,先安装 Docker Plugin)
- 添加 Docker Host: unix:///var/run/docker.sock
b. 配置 Kubernetes (可选):
- Manage Jenkins > Clouds
- 添加 Kubernetes Cloud
- Kubernetes URL: https://kubernetes.default.svc
- Jenkins URL: http://jenkins:8080
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/"
-
新建 Pipeline Job
- 点击 "New Item"
- 输入名称: "practice-ci-pipeline"
- 选择 "Pipeline"
- 点击 "OK"
-
配置 Pipeline
- 在 Pipeline 部分:
- Definition: Pipeline script from SCM
- SCM: Git
- Repository URL: 你的 Git 仓库地址
- Branch: */main (或你的默认分支)
- Script Path: Jenkinsfile
- 在 Pipeline 部分:
-
配置触发器 (可选)
- 勾选 "Poll SCM"
- Schedule:
H/5 * * * *(每 5 分钟检查一次) - 或配置 GitHub Webhook 实现自动触发
运行初始化脚本:
./scripts/setup-kubernetes.sh这个脚本会:
- 创建必要的 Namespace
- 创建 Rails Secrets
- 部署应用到 Kubernetes
- 创建 Service 和 PVC
有两种方式部署:
方式 1: 通过 Jenkins (推荐)
- 在 Jenkins 中打开你的 Pipeline Job
- 点击 "Build Now"
- 观察构建日志
- 等待构建完成
方式 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 端口。
- Checkout - 从 Git 仓库拉取代码
- Build Docker Image - 构建 Docker 镜像
- Push to Registry - 推送镜像到本地 Registry
- Deploy to Kubernetes - 更新 Kubernetes Deployment
- Verify Deployment - 验证部署状态
配置后,每次代码推送到 main 分支时,Jenkins 会自动:
- 检测到代码变更
- 触发 Pipeline 构建
- 构建新的 Docker 镜像
- 部署到 Kubernetes
- 验证部署成功
# 查看本地镜像
docker images | grep practice-ci
# 查看运行中的容器
docker ps
# 查看 Jenkins 日志
docker logs -f jenkins
# 重启 Jenkins
docker restart jenkins
# 停止本地 Registry
docker stop registry
# 启动本地 Registry
docker start registry# 查看所有资源
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 初始密码
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
# 进入 Jenkins 容器
docker exec -it jenkins /bin/bash
# 重启 Jenkins (在容器内)
docker exec jenkins systemctl reload jenkins原因: 可能是资源不足或存储卷问题
解决方案:
# 查看详细信息
kubectl describe pod <pod-name>
# 检查 PVC 状态
kubectl get pvc
# 如果是 PVC 问题,删除并重新创建
kubectl delete pvc practice-ci-pvc
kubectl apply -f k8s/deployment.yaml原因: 本地 Registry 未运行或镜像不存在
解决方案:
# 检查 Registry 是否运行
curl http://localhost:5000/v2/_catalog
# 重启 Registry
docker restart registry
# 手动构建并推送镜像
./scripts/deploy.sh原因: Docker socket 未正确挂载
解决方案:
# 重新创建 Jenkins 容器,确保挂载正确
docker rm -f jenkins
./scripts/setup-jenkins.sh原因: 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原因: 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如果要部署到生产环境,需要考虑:
-
安全性
- 使用私有 Docker Registry
- 配置 HTTPS/TLS
- 使用 Kubernetes Secrets 管理敏感信息
- 配置网络策略
-
高可用性
- 增加副本数量 (replicas)
- 配置自动扩缩容 (HPA)
- 使用持久化存储
-
监控和日志
- 集成 Prometheus + Grafana
- 配置集中日志收集 (ELK/EFK Stack)
- 设置告警
-
备份和恢复
- 定期备份数据库
- 配置灾难恢复方案
-
性能优化
- 配置资源限制和请求
- 优化 Docker 镜像大小
- 使用 CDN 加速静态资源
如有问题,请查看:
- Jenkins 构建日志
- Kubernetes Pod 日志:
kubectl logs -f <pod-name> - Kubernetes 事件:
kubectl get events --sort-by=.metadata.creationTimestamp
- Ruby 3.3.4
- Rails 8.1.2
这是一个学习和实践项目。