实践案例:Rancher+K8s+Gogs+Jenkins 自动部署
本实践案例展示如何构建一个完整的CI/CD流水线,实现从代码提交到自动部署的完整流程。该方案使用Gogs作为代码仓库,Jenkins作为CI/CD工具,Kubernetes作为容器编排平台,Rancher作为K8s集群管理工具。
整体架构
graph TB
subgraph "开发环境"
DEV[开发者]
GOGS[Gogs 代码仓库]
end
subgraph "CI/CD 环境"
JENKINS[Jenkins CI服务器]
DOCKER[容器化构建]
DOCKER_REGISTRY[镜像仓库]
end
subgraph "Kubernetes 环境"
RANCHER[Rancher 管理界面]
K8S[K8s 集群]
APP[应用程序 Pod]
end
DEV --> GOGS
GOGS --> JENKINS
JENKINS --> DOCKER
DOCKER --> DOCKER_REGISTRY
DOCKER_REGISTRY --> K8S
RANCHER --> K8S
K8S --> APP
JENKINS --> K8S
部署前准备
在开始部署前,需要准备以下环境和工具:
基础设施要求
- 至少3台服务器(推荐4核8G配置)
- Docker 已安装(版本 19.03+)
- 服务器间网络互通
- 防火墙开放必要端口
软件版本要求
- Kubernetes 1.20+
- Rancher 2.6+
- Jenkins 2.300+
- Gogs 最新版
第一步:部署 Rancher 管理平台
首先部署 Rancher 来管理 Kubernetes 集群。
1. 单动 Docker 容器部署 Rancher
# 拉取并运行 Rancher 容器
# 创建 Rancher 数据持久化目录
sudo mkdir -p /opt/rancher
# 运行 Rancher 容器
sudo docker run -d \
--name rancher \
--restart=unless-stopped \
-p 80:80 -p 443:443 \
-v /opt/rancher:/var/lib/rancher \
rancher/rancher:latest
2. 初始化 Rancher
# 访问 Rancher 管理界面并设置初始密码
# 访问 https://your-server-ip
# 设置管理员密码
# 配置 Rancher Server URL
第二步:部署 Gogs 代码仓库
使用 Kubernetes 部署 Gogs 作为 Git 代码仓库服务。
1. 创建 Gogs 部署配置
# gogs-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gogs-deployment
namespace: gogs
spec:
replicas: 1
selector:
matchLabels:
app: gogs
template:
metadata:
labels:
app: gogs
spec:
containers:
- name: gogs
image: gogs/gogs:latest
ports:
- containerPort: 3000
- containerPort: 22
env:
- name: RUN_MODE
value: "prod"
- name: SSH_PORT_OFFSET
value: "0"
volumeMounts:
- name: gogs-data
mountPath: /data
volumes:
- name: gogs-data
persistentVolumeClaim:
claimName: gogs-pvc
---
apiVersion: v1
kind: Service
metadata:
name: gogs-service
namespace: gogs
spec:
type: NodePort
selector:
app: gogs
ports:
- name: http
port: 3000
targetPort: 3000
nodePort: 30080
- name: ssh
port: 22
targetPort: 22
nodePort: 30022
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gogs-pvc
namespace: gogs
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
2. 部署 Gogs
# 创建命名空间并部署 Gogs
# 创建命名空间
kubectl create namespace gogs
# 应用部署配置
kubectl apply -f gogs-deployment.yaml
# 检查部署状态
kubectl get pods -n gogs
kubectl get services -n gogs
第三步:部署 Jenkins CI/CD 服务器
部署 Jenkins 作为 CI/CD 流水线的核心服务。
1. 创建 Jenkins 部署配置
# jenkins-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-deployment
namespace: jenkins
spec:
replicas: 1
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
serviceAccountName: jenkins
containers:
- name: jenkins
image: jenkins/jenkins:lts
ports:
- containerPort: 8080
- containerPort: 50000
volumeMounts:
- name: jenkins-home
mountPath: /var/jenkins_home
- name: docker-sock
mountPath: /var/run/docker.sock
env:
- name: JAVA_OPTS
value: "-Djenkins.install.runSetupWizard=false"
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: jenkins-pvc
- name: docker-sock
hostPath:
path: /var/run/docker.sock
---
apiVersion: v1
kind: Service
metadata:
name: jenkins-service
namespace: jenkins
spec:
type: NodePort
selector:
app: jenkins
ports:
- name: http
port: 8080
targetPort: 8080
nodePort: 30081
- name: agent
port: 50000
targetPort: 50000
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
namespace: jenkins
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
2. 创建 Jenkins ServiceAccount 和 RBAC
# jenkins-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
namespace: jenkins
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: jenkins-role
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["deployments", "replicasets", "pods", "services"]
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- apiGroups: ["", "extensions", "apps"]
resources: ["configmaps", "secrets"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: jenkins-role
subjects:
- kind: ServiceAccount
name: jenkins
namespace: jenkins
3. 部署 Jenkins
# 创建 Jenkins 命名空间并部署
# 创建命名空间
kubectl create namespace jenkins
# 应用 RBAC 配置
kubectl apply -f jenkins-rbac.yaml
# 应用部署配置
kubectl apply -f jenkins-deployment.yaml
# 检查部署状态
kubectl get pods -n jenkins
kubectl get services -n jenkins
第四步:配置 Jenkins 自动化流水线
配置 Jenkins 以实现从 Gogs 代码仓库到 Kubernetes 的自动化部署。
1. Jenkins 安装必要插件
需要安装以下插件:
- Kubernetes plugin
- Docker plugin
- Git plugin
- Pipeline plugin
- Blue Ocean plugin
2. Jenkins Pipeline 脚本示例
# Jenkinsfile 示例
pipeline {
agent {
label 'master'
}
environment {
DOCKER_REGISTRY = 'your-registry.com'
IMAGE_NAME = 'myapp'
NAMESPACE = 'production'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
script {
def appImage = docker.build("${env.DOCKER_REGISTRY}/${env.IMAGE_NAME}:${env.BUILD_NUMBER}")
docker.withRegistry('', 'docker-registry-credential') {
appImage.push()
appImage.push('latest')
}
}
}
}
stage('Deploy to Kubernetes') {
steps {
script {
// 更新 Kubernetes 部署
sh """
kubectl set image deployment/${env.IMAGE_NAME}-deployment \\
${env.IMAGE_NAME}=${env.DOCKER_REGISTRY}/${env.IMAGE_NAME}:${env.BUILD_NUMBER} \\
--namespace=${env.NAMESPACE}
"""
}
}
}
stage('Verify Deployment') {
steps {
script {
sh """
echo '验证部署状态...'
kubectl rollout status deployment/${env.IMAGE_NAME}-deployment --namespace=${env.NAMESPACE}
"""
}
}
}
}
post {
always {
echo 'Pipeline completed'
}
success {
echo 'Pipeline succeeded'
}
failure {
echo 'Pipeline failed'
}
}
}
第五步:配置 Gogs Webhook
配置 Gogs 仓库的 Webhook,实现代码提交后自动触发 Jenkins 构建。
1. Webhook 配置示例
# Gogs Webhook 配置
Webhook URL: http://jenkins-service.jenkins.svc.cluster.local:8080/gogs-webhook/post
Content type: application/json
Push events: checked
Payload URL: http://jenkins-service.jenkins.svc.cluster.local:8080/gogs-webhook/post
第六步:创建应用部署示例
创建一个简单的应用程序示例,用于演示自动部署流程。
1. 示例应用 Dockerfile
# Dockerfile 示例
# 使用官方 Node.js 运行时作为基础镜像
FROM node:16-alpine
# 设置工作目录
WORKDIR /app
# 复制 package 文件并安装依赖
COPY package*.json ./
RUN npm install --only=production
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 3000
# 定义启动命令
CMD ["npm", "start"]
2. 应用部署配置
# app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
namespace: production
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
---
apiVersion: v1
kind: Service
metadata:
name: myapp-service
namespace: production
spec:
type: ClusterIP
selector:
app: myapp
ports:
- port: 80
targetPort: 3000
自动化部署流程
完整的自动化部署流程如下:
sequenceDiagram
participant Dev as 开发者
participant Gogs as Gogs 仓库
participant Jenkins as Jenkins
participant Docker as Docker
participant Registry as 镜像仓库
participant K8s as Kubernetes
Dev->>Gogs: 提交代码
Gogs->>Jenkins: 触发 Webhook
Jenkins->>Docker: 构建 Docker 镜像
Docker->>Registry: 推送镜像
Jenkins->>K8s: 部署到 K8s 集群
K8s->>K8s: 更新应用部署
K8s->>Jenkins: 返回部署状态
Jenkins->>Dev: 通知构建结果
最佳实践和注意事项
安全最佳实践
- 使用 Kubernetes Secrets 管理敏感信息
- 配置 RBAC 权限控制
- 使用私有镜像仓库
- 定期更新系统和组件
运维最佳实践
- 配置健康检查和监控
- 使用配置管理(ConfigMap/Secret)
- 实现蓝绿部署或滚动更新
- 备份和恢复策略
故障排除
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| Webhook 无法触发 | 网络不通或认证失败 | 检查 Jenkins 服务可访问性,验证 Webhook URL |
| 镜像构建失败 | Dockerfile 问题或依赖缺失 | 检查 Dockerfile 语法,验证构建环境 |
| 部署失败 | K8s 权限不足或资源配置错误 | 检查 RBAC 权限,验证资源清单 |
| 应用无法访问 | 服务配置错误或网络策略限制 | 检查 Service 和 Ingress 配置 |
常用命令
# 检查所有组件状态
kubectl get pods -A
# 查看 Jenkins 日志
kubectl logs -f deployment/jenkins-deployment -n jenkins
# 查看应用部署状态
kubectl rollout status deployment/myapp-deployment -n production
# 测试应用访问
kubectl port-forward service/myapp-service -n production 8080:80