Jenkins K8s 部署实例
梗概
通过 [Jenkins Pipeline](mdc:笔记/计算机知识/app应用/Jenkins Pipeline详解.md) 实现 Java 项目自动构建 Docker 镜像并部署到 Kubernetes 集群的完整流程。
前提条件
-
安装必要插件:
- Kubernetes Plugin
- Docker Plugin
-
环境准备:
- Jenkins 可访问 Docker 服务
- Jenkins 可访问 Kubernetes 集群
- 配置好私有镜像仓库凭证
完整 Pipeline 实现
pipeline {
agent any
environment {
DOCKER_REGISTRY = 'registry.example.com'
APP_NAME = 'myapp'
K8S_NAMESPACE = 'production'
}
stages {
stage('拉取代码') {
steps {
git url: 'https://github.com/your-org/your-java-app.git', branch: 'main'
}
}
stage('单元测试') {
steps {
sh 'mvn clean test'
}
post {
always {
publishTestResults testResultsPattern: 'target/surefire-reports/*.xml'
}
}
}
stage('构建应用') {
steps {
sh 'mvn package -DskipTests' // 跳过测试,因为前面已经执行过
}
}
stage('构建 Docker 镜像') {
steps {
script {
// 使用构建号作为镜像标签
def imageTag = "${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}"
// 构建镜像
sh "docker build -t ${imageTag} ."
// 推送到私有仓库
withCredentials([usernamePassword(credentialsId: 'docker-registry-creds',
usernameVariable: 'DOCKER_USER',
passwordVariable: 'DOCKER_PASS')]) {
sh "echo \$DOCKER_PASS | docker login ${DOCKER_REGISTRY} -u \$DOCKER_USER --password-stdin"
sh "docker push ${imageTag}"
}
}
}
}
stage('部署到 K8s') {
steps {
script {
def imageTag = "${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}"
// 更新 Deployment 镜像
sh "kubectl set image deployment/${APP_NAME} ${APP_NAME}=${imageTag} -n ${K8S_NAMESPACE}"
// 等待部署完成
sh "kubectl rollout status deployment/${APP_NAME} -n ${K8S_NAMESPACE} --timeout=300s"
// 验证部署
sh "kubectl get pods -n ${K8S_NAMESPACE} -l app=${APP_NAME}"
}
}
}
}
post {
success {
echo "🎉 部署成功!应用 ${APP_NAME} 已更新到版本 ${BUILD_NUMBER}"
}
failure {
echo "❌ 部署失败!请检查日志"
// 可以添加回滚逻辑
script {
sh "kubectl rollout undo deployment/${APP_NAME} -n ${K8S_NAMESPACE}"
}
}
cleanup {
// 清理本地 Docker 镜像节省空间
sh "docker rmi ${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER} || true"
}
}
}必要的 Kubernetes 配置文件
Deployment 配置示例 (deployment.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: registry.example.com/myapp:latest
ports:
- containerPort: 8080
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"Service 配置示例 (service.yaml)
apiVersion: v1
kind: Service
metadata:
name: myapp-service
namespace: production
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 8080
type: LoadBalancer安全考虑
- 凭证管理:使用 Jenkins 凭证管理器存储敏感信息
- 镜像扫描:在推送前进行安全扫描
- 资源限制:在 K8s 中设置合理的资源限制
- 网络策略:配置适当的网络访问控制
监控与日志
stage('健康检查') {
steps {
script {
// 等待服务就绪
timeout(time: 5, unit: 'MINUTES') {
waitUntil {
script {
def result = sh(script: "curl -f http://${APP_NAME}-service/health", returnStatus: true)
return result == 0
}
}
}
}
}
}相关概念
- parent::Jenkins Pipeline详解
- related::前端部署K8s极简总结
- related::Deployment