当前位置: 代码网 > it编程>编程语言>Java > Docker与Kubernetes部署Java应用容器化实践指南

Docker与Kubernetes部署Java应用容器化实践指南

2026年05月11日 Java 我要评论
今天我们来聊聊 docker 与 kubernetes 部署 java 应用的最佳实践,这是容器化实践的重要技术。一、容器化概述容器化是一种将应用及其依赖打包为容器的技术,它提供了环境一致性、快速部署

今天我们来聊聊 docker 与 kubernetes 部署 java 应用的最佳实践,这是容器化实践的重要技术。

一、容器化概述

容器化是一种将应用及其依赖打包为容器的技术,它提供了环境一致性、快速部署和资源隔离等优势。docker 是目前最流行的容器化平台,而 kubernetes 则是最流行的容器编排平台。

核心优势

  • 环境一致性:容器在不同环境中运行一致
  • 快速部署:容器启动速度快,部署时间短
  • 资源隔离:容器之间相互隔离,避免干扰
  • 资源利用率:容器占用资源少,提高服务器利用率
  • 易于扩展:支持水平扩展,适应不同负载

二、docker 容器化实践

1. dockerfile 编写

# 基础镜像
from eclipse-temurin:25-jdk-alpine

# 设置工作目录
workdir /app

# 复制依赖文件
copy pom.xml ./

# 下载依赖
run mvn dependency:go-offline

# 复制源代码
copy src ./src

# 构建应用
run mvn package -dskiptests

# 暴露端口
expose 8080

# 运行应用
cmd ["java", "-jar", "target/app.jar"]

2. 多阶段构建

# 构建阶段
from eclipse-temurin:25-jdk-alpine as build
workdir /app
copy pom.xml ./
run mvn dependency:go-offline
copy src ./src
run mvn package -dskiptests

# 运行阶段
from eclipse-temurin:25-jre-alpine
workdir /app
copy --from=build /app/target/app.jar ./
expose 8080
cmd ["java", "-jar", "app.jar"]

3. 优化 dockerfile

# 使用最小基础镜像
from eclipse-temurin:25-jre-alpine

# 设置时区
env tz=asia/shanghai
run apk add --no-cache tzdata && ln -sf /usr/share/zoneinfo/$tz /etc/localtime && echo $tz > /etc/timezone

# 创建非 root 用户
run addgroup -s appgroup && adduser -s appuser -g appgroup
user appuser

# 设置工作目录
workdir /app

# 复制应用
copy target/app.jar ./

# 暴露端口
expose 8080

# 运行应用
cmd ["java", "-jar", "app.jar"]

4. 构建和运行

# 构建镜像
docker build -t my-java-app:latest .

# 运行容器
docker run -d -p 8080:8080 --name my-app my-java-app:latest

# 查看容器状态
docker ps

# 查看容器日志
docker logs my-app

# 进入容器
docker exec -it my-app /bin/sh

5. docker compose

# docker-compose.yml
version: '3.8'
services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - spring_profiles_active=prod
      - db_host=db
      - db_port=5432
      - db_name=mydb
      - db_user=user
      - db_password=password
    depends_on:
      - db
  db:
    image: postgres:13
    environment:
      - postgres_db=mydb
      - postgres_user=user
      - postgres_password=password
    volumes:
      - postgres-data:/var/lib/postgresql/data

volumes:
  postgres-data:
# 启动服务
docker-compose up -d

# 停止服务
docker-compose down

# 查看服务状态
docker-compose ps

三、kubernetes 部署实践

1. 部署配置

# deployment.yml
apiversion: apps/v1
kind: deployment
metadata:
  name: my-java-app
spec:
  replicas: 3
  selector:
    matchlabels:
      app: my-java-app
  template:
    metadata:
      labels:
        app: my-java-app
    spec:
      containers:
      - name: my-java-app
        image: my-java-app:latest
        ports:
        - containerport: 8080
        env:
        - name: spring_profiles_active
          value: "prod"
        - name: db_host
          value: "db-service"
        - name: db_port
          value: "5432"
        - name: db_name
          value: "mydb"
        - name: db_user
          value: "user"
        - name: db_password
          value: "password"
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"

2. 服务配置

# service.yml
apiversion: v1
kind: service
metadata:
  name: my-java-app-service
spec:
  selector:
    app: my-java-app
  ports:
  - port: 8080
    targetport: 8080
  type: loadbalancer

3. 配置管理

# configmap.yml
apiversion: v1
kind: configmap
metadata:
  name: my-java-app-config
data:
  application.yml: |
    spring:
      profiles:
        active: prod
      datasource:
        url: jdbc:postgresql://db-service:5432/mydb
        username: user
        password: password
      jpa:
        hibernate:
          ddl-auto: update
        properties:
          hibernate:
            format_sql: true
# deployment.yml (with configmap)
apiversion: apps/v1
kind: deployment
metadata:
  name: my-java-app
spec:
  replicas: 3
  selector:
    matchlabels:
      app: my-java-app
  template:
    metadata:
      labels:
        app: my-java-app
    spec:
      containers:
      - name: my-java-app
        image: my-java-app:latest
        ports:
        - containerport: 8080
        volumemounts:
        - name: config-volume
          mountpath: /app/config
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"
      volumes:
      - name: config-volume
        configmap:
          name: my-java-app-config

4. 密钥管理

# secret.yml
apiversion: v1
kind: secret
metadata:
  name: my-java-app-secret
type: opaque
data:
  db-password: dxnlci1wyxnzd29yza==  # base64 encoded
  jwt-secret: c29tzs1qd3qtc2vjcmv0
# deployment.yml (with secret)
apiversion: apps/v1
kind: deployment
metadata:
  name: my-java-app
spec:
  replicas: 3
  selector:
    matchlabels:
      app: my-java-app
  template:
    metadata:
      labels:
        app: my-java-app
    spec:
      containers:
      - name: my-java-app
        image: my-java-app:latest
        ports:
        - containerport: 8080
        env:
        - name: db_password
          valuefrom:
            secretkeyref:
              name: my-java-app-secret
              key: db-password
        - name: jwt_secret
          valuefrom:
            secretkeyref:
              name: my-java-app-secret
              key: jwt-secret
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"

5. 持久化存储

# persistentvolumeclaim.yml
apiversion: v1
kind: persistentvolumeclaim
metadata:
  name: my-java-app-pvc
spec:
  accessmodes:
    - readwriteonce
  resources:
    requests:
      storage: 10gi
  storageclassname: standard
# deployment.yml (with pvc)
apiversion: apps/v1
kind: deployment
metadata:
  name: my-java-app
spec:
  replicas: 3
  selector:
    matchlabels:
      app: my-java-app
  template:
    metadata:
      labels:
        app: my-java-app
    spec:
      containers:
      - name: my-java-app
        image: my-java-app:latest
        ports:
        - containerport: 8080
        volumemounts:
        - name: data-volume
          mountpath: /app/data
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"
      volumes:
      - name: data-volume
        persistentvolumeclaim:
          claimname: my-java-app-pvc

6. 水平自动伸缩

# horizontalpodautoscaler.yml
apiversion: autoscaling/v2
kind: horizontalpodautoscaler
metadata:
  name: my-java-app-hpa
spec:
  scaletargetref:
    apiversion: apps/v1
    kind: deployment
    name: my-java-app
  minreplicas: 3
  maxreplicas: 10
  metrics:
  - type: resource
    resource:
      name: cpu
      target:
        type: utilization
        averageutilization: 70
  - type: resource
    resource:
      name: memory
      target:
        type: utilization
        averageutilization: 80

7. 健康检查

# deployment.yml (with health checks)
apiversion: apps/v1
kind: deployment
metadata:
  name: my-java-app
spec:
  replicas: 3
  selector:
    matchlabels:
      app: my-java-app
  template:
    metadata:
      labels:
        app: my-java-app
    spec:
      containers:
      - name: my-java-app
        image: my-java-app:latest
        ports:
        - containerport: 8080
        readinessprobe:
          httpget:
            path: /actuator/health/readiness
            port: 8080
          initialdelayseconds: 30
          periodseconds: 10
        livenessprobe:
          httpget:
            path: /actuator/health/liveness
            port: 8080
          initialdelayseconds: 60
          periodseconds: 30
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"

四、ci/cd 集成

1. jenkins 流水线

pipeline {
    agent any
    stages {
        stage('build') {
            steps {
                sh 'mvn clean package -dskiptests'
            }
        }
        stage('test') {
            steps {
                sh 'mvn test'
            }
        }
        stage('build docker image') {
            steps {
                sh 'docker build -t my-java-app:${build_number} .'
                sh 'docker tag my-java-app:${build_number} my-java-app:latest'
            }
        }
        stage('push to registry') {
            steps {
                sh 'docker push my-java-app:${build_number}'
                sh 'docker push my-java-app:latest'
            }
        }
        stage('deploy to kubernetes') {
            steps {
                sh 'kubectl apply -f k8s/deployment.yml'
                sh 'kubectl apply -f k8s/service.yml'
                sh 'kubectl rollout status deployment/my-java-app'
            }
        }
    }
}

2. github actions

name: ci/cd pipeline

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: set up jdk 25
      uses: actions/setup-java@v2
      with:
        java-version: '25'
        distribution: 'adopt'
    - name: build with maven
      run: mvn clean package -dskiptests
    - name: run tests
      run: mvn test
    - name: build docker image
      run: docker build -t my-java-app:${{ github.sha }} .
    - name: push to docker hub
      run: |
        docker tag my-java-app:${{ github.sha }} my-java-app:latest
        docker login -u ${{ secrets.docker_username }} -p ${{ secrets.docker_password }}
        docker push my-java-app:${{ github.sha }}
        docker push my-java-app:latest
    - name: deploy to kubernetes
      run: |
        kubectl config use-context my-cluster
        kubectl apply -f k8s/deployment.yml
        kubectl apply -f k8s/service.yml
        kubectl rollout status deployment/my-java-app

五、监控与日志

1. 监控

# prometheus.yml
apiversion: monitoring.coreos.com/v1
kind: servicemonitor
metadata:
  name: my-java-app-monitor
  labels:
    release: prometheus
spec:
  selector:
    matchlabels:
      app: my-java-app
  endpoints:
  - port: 8080
    path: /actuator/prometheus
    interval: 15s

2. 日志

# deployment.yml (with logging)
apiversion: apps/v1
kind: deployment
metadata:
  name: my-java-app
spec:
  replicas: 3
  selector:
    matchlabels:
      app: my-java-app
  template:
    metadata:
      labels:
        app: my-java-app
    spec:
      containers:
      - name: my-java-app
        image: my-java-app:latest
        ports:
        - containerport: 8080
        env:
        - name: logging_level_root
          value: "info"
        - name: logging_level_com_example
          value: "debug"
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"

六、实践案例:java 微服务部署

场景描述

部署一个包含用户服务、订单服务、产品服务的 java 微服务架构到 kubernetes。

实现方案

1. 服务配置

用户服务

# user-service-deployment.yml
apiversion: apps/v1
kind: deployment
metadata:
  name: user-service
spec:
  replicas: 3
  selector:
    matchlabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: user-service:latest
        ports:
        - containerport: 8080
        env:
        - name: spring_profiles_active
          value: "prod"
        - name: eureka_client_serviceurl_defaultzone
          value: "http://eureka-service:8761/eureka/"
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"
---
apiversion: v1
kind: service
metadata:
  name: user-service
spec:
  selector:
    app: user-service
  ports:
  - port: 8080
    targetport: 8080
  type: clusterip

订单服务

# order-service-deployment.yml
apiversion: apps/v1
kind: deployment
metadata:
  name: order-service
spec:
  replicas: 3
  selector:
    matchlabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
      - name: order-service
        image: order-service:latest
        ports:
        - containerport: 8080
        env:
        - name: spring_profiles_active
          value: "prod"
        - name: eureka_client_serviceurl_defaultzone
          value: "http://eureka-service:8761/eureka/"
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"
---
apiversion: v1
kind: service
metadata:
  name: order-service
spec:
  selector:
    app: order-service
  ports:
  - port: 8080
    targetport: 8080
  type: clusterip

产品服务

# product-service-deployment.yml
apiversion: apps/v1
kind: deployment
metadata:
  name: product-service
spec:
  replicas: 3
  selector:
    matchlabels:
      app: product-service
  template:
    metadata:
      labels:
        app: product-service
    spec:
      containers:
      - name: product-service
        image: product-service:latest
        ports:
        - containerport: 8080
        env:
        - name: spring_profiles_active
          value: "prod"
        - name: eureka_client_serviceurl_defaultzone
          value: "http://eureka-service:8761/eureka/"
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"
---
apiversion: v1
kind: service
metadata:
  name: product-service
spec:
  selector:
    app: product-service
  ports:
  - port: 8080
    targetport: 8080
  type: clusterip

eureka 服务

# eureka-service-deployment.yml
apiversion: apps/v1
kind: deployment
metadata:
  name: eureka-service
spec:
  replicas: 1
  selector:
    matchlabels:
      app: eureka-service
  template:
    metadata:
      labels:
        app: eureka-service
    spec:
      containers:
      - name: eureka-service
        image: eureka-service:latest
        ports:
        - containerport: 8761
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"
---
apiversion: v1
kind: service
metadata:
  name: eureka-service
spec:
  selector:
    app: eureka-service
  ports:
  - port: 8761
    targetport: 8761
  type: clusterip

api 网关

# gateway-service-deployment.yml
apiversion: apps/v1
kind: deployment
metadata:
  name: gateway-service
spec:
  replicas: 3
  selector:
    matchlabels:
      app: gateway-service
  template:
    metadata:
      labels:
        app: gateway-service
    spec:
      containers:
      - name: gateway-service
        image: gateway-service:latest
        ports:
        - containerport: 8080
        env:
        - name: spring_profiles_active
          value: "prod"
        - name: eureka_client_serviceurl_defaultzone
          value: "http://eureka-service:8761/eureka/"
        resources:
          limits:
            cpu: "1"
            memory: "1gi"
          requests:
            cpu: "500m"
            memory: "512mi"
---
apiversion: v1
kind: service
metadata:
  name: gateway-service
spec:
  selector:
    app: gateway-service
  ports:
  - port: 8080
    targetport: 8080
  type: loadbalancer

2. 部署步骤

  1. 构建镜像:为每个服务构建 docker 镜像
  2. 推送镜像:将镜像推送到 docker 仓库
  3. 部署服务:使用 kubectl 部署所有服务
  4. 验证部署:检查服务状态和日志
  5. 配置监控:设置 prometheus 和 grafana 监控

七、最佳实践总结

1. docker 最佳实践

  • 使用多阶段构建:减小镜像大小
  • 优化基础镜像:使用最小基础镜像
  • 非 root 用户:使用非 root 用户运行容器
  • 环境变量:使用环境变量配置应用
  • 健康检查:添加健康检查端点
  • 日志管理:使用标准输出和标准错误

2. kubernetes 最佳实践

  • 资源限制:为每个容器设置资源限制
  • 健康检查:配置就绪探针和存活探针
  • 水平伸缩:使用 hpa 实现自动伸缩
  • 配置管理:使用 configmap 管理配置
  • 密钥管理:使用 secret 管理敏感数据
  • 持久化存储:使用 pvc 管理持久化数据
  • 服务发现:使用 kubernetes 服务实现服务发现

3. ci/cd 最佳实践

  • 自动化构建:使用 jenkins 或 github actions 自动化构建
  • 自动化测试:在构建过程中运行测试
  • 自动化部署:自动部署到测试和生产环境
  • 版本管理:使用语义化版本控制
  • 回滚机制:在部署失败时能够回滚

4. 监控与日志

  • 应用监控:使用 prometheus 监控应用指标
  • 系统监控:监控 kubernetes 集群状态
  • 日志聚合:使用 elk 或 loki 聚合日志
  • 告警机制:设置合理的告警规则
  • 仪表盘:使用 grafana 创建监控仪表盘

八、总结与建议

docker 与 kubernetes 部署 java 应用是现代应用部署的重要方式。通过合理使用容器化技术,我们可以:

  1. 提高部署效率:快速部署和扩展应用
  2. 增强系统可靠性:通过健康检查和自动伸缩提高系统可用性
  3. 改善资源利用率:容器占用资源少,提高服务器利用率
  4. 简化环境管理:容器在不同环境中运行一致
  5. 提高开发效率:开发环境与生产环境一致,减少环境问题

这其实可以更优雅一点,通过合理使用 docker 和 kubernetes,我们可以构建出更现代化、更可靠的 java 应用部署方案。

到此这篇关于docker与kubernetes部署java应用容器化实践指南的文章就介绍到这了,更多相关docker与k8s部署java应用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com