跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

微服务容器化与云原生部署:Docker + Kubernetes 实战

介绍微服务容器化与云原生部署方案。涵盖 Docker 核心概念及 Java 微服务镜像构建优化,包括 Dockerfile 编写与多阶段构建。详解 Kubernetes 架构组件与资源对象配置,演示通过 Deployment、Service、Ingress 实现微服务部署与服务暴露。结合 Nacos、Sentinel 进行服务治理,利用 HPA 实现自动扩缩容,并通过 Prometheus + Grafana 搭建监控体系。最后总结高可用设计原则与常见运维问题解决方案,提供完整的云原生落地实践指南。

HadoopMan发布于 2026/2/24更新于 2026/7/2141 浏览
微服务容器化与云原生部署:Docker + Kubernetes 实战

第二十章 微服务容器化与云原生部署:Docker + Kubernetes 实战

在这里插入图片描述

一、章节学习目标与重点

1.1 学习目标
  • 理解容器化与云原生的核心概念、价值及技术体系,掌握 Docker 的核心原理与操作流程。
  • 熟练使用 Docker 打包 Java 微服务,编写 Dockerfile、构建镜像、管理容器,解决容器化过程中的常见问题。
  • 掌握 Kubernetes(K8s)的核心组件与架构,能够使用 K8s 实现微服务的部署、扩容、滚动更新、服务发现与负载均衡。
  • 结合 Spring Cloud Alibaba 生态,实现微服务在 K8s 环境中的完整部署(含配置中心、注册中心、网关、监控组件)。
  • 能够独立设计云原生微服务的部署架构,解决容器编排、高可用、资源调度等实际问题。
1.2 学习重点
  • Docker 核心概念(镜像、容器、仓库)与 Java 微服务容器化实战(Dockerfile 编写、镜像优化)。
  • K8s 核心组件(Pod、Service、Deployment、ConfigMap、Secret)的作用与配置。
  • 微服务在 K8s 中的部署流程:镜像推送、资源配置、服务暴露、健康检查。
  • K8s 与 Nacos、Sentinel、Prometheus 的整合,实现云原生环境下的服务治理与监控。
  • 云原生架构的高可用设计(多副本、滚动更新、故障转移)与运维技巧。

二、容器化与云原生核心概念

2.1 为什么需要容器化?

💡 传统微服务部署面临诸多痛点:

  • 环境不一致:开发、测试、生产环境的操作系统、依赖库、配置不同,导致'开发环境能跑,生产环境报错'。
  • 部署复杂:微服务数量多,需手动配置服务器、安装依赖、部署应用,效率低且易出错。
  • 资源浪费:每个服务单独部署在物理机或虚拟机,资源利用率低(如一台服务器仅部署一个低负载服务)。
  • 扩展困难:需手动添加服务器、部署应用、配置负载均衡,无法快速响应流量波动。

容器化(Docker) 正是为解决这些问题而生,核心是将应用及其依赖(库、配置、环境变量)打包成一个可移植的'容器',实现'一次构建,到处运行'。容器与虚拟机(VM)的核心区别:

  • 虚拟机:包含完整操作系统,资源占用高、启动慢(分钟级)。
  • 容器:共享宿主机操作系统内核,仅包含应用及必要依赖,资源占用低、启动快(秒级)。
2.2 云原生核心概念

云原生(Cloud Native) 是基于容器化技术构建、部署、运行应用的架构理念,核心目标是实现应用的高可用、弹性伸缩、快速迭代。云原生的三大核心特征:

  1. 容器化:应用打包为容器,确保环境一致性与可移植性。
  2. 微服务:应用拆分为独立微服务,支持独立部署与扩展。
  3. DevOps:开发与运维流程自动化(持续集成 CI/持续部署 CD),提升迭代效率。

云原生技术栈核心组件:

  • 容器引擎:Docker(容器打包与运行)。
  • 容器编排:Kubernetes(K8s,容器集群管理)。
  • 服务网格:Istio(微服务通信、流量控制、安全防护)。
  • CI/CD 工具:Jenkins、GitLab CI(自动化构建、测试、部署)。
  • 监控告警:Prometheus + Grafana(容器与应用监控)。
2.3 容器化与云原生架构图

一个完整的云原生微服务部署架构如下:

┌─────────────────────────────────────────────────────────────────┐ │ 客户端(Web/APP) │ └───────────────────────────────┬─────────────────────────────────┘ │ ┌───────────────────────────────▼─────────────────────────────────┐ │ 负载均衡器(Ingress/Nginx) │ └───────────────────────────────┬─────────────────────────────────┘ │ ┌───────────────────────────────▼─────────────────────────────────┐ │ Kubernetes 集群 │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 节点 1 │ │ 节点 2 │ │ 节点 3 │ │ 节点 4 │ │ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │ │ │Pod(网关)│ │ │Pod(用户服务)│ │Pod(订单服务)│ │Pod(商品服务)│ │ │ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │ │ │Pod(Nacos)│ │ │Pod(Sentinel)│ │Pod(Prometheus)│ │Pod(数据库)│ │ │ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ └───────────────────────────────┬─────────────────────────────────┘ │ ┌───────────────────────────────▼─────────────────────────────────┐ │ 存储层(持久化存储:MySQL、Redis、Elasticsearch) │ └─────────────────────────────────────────────────────────────────┘ 

三、Docker 实战:Java 微服务容器化

3.1 Docker 核心概念与环境准备
3.1.1 Docker 核心概念
  • 镜像(Image):容器的模板,包含应用及依赖,只读不可修改(如 Java 微服务镜像、MySQL 镜像)。
  • 容器(Container):镜像的运行实例,可启动、停止、删除,是动态的、可写的。
  • 仓库(Repository):存储镜像的仓库(如 Docker Hub 公共仓库、私有仓库 Harbor)。
  • Dockerfile:构建镜像的配置文件,包含镜像构建的步骤(如基础镜像、复制文件、运行命令)。
3.1.2 环境准备
  • 操作系统:Windows 10/11(需开启 WSL2)、Linux(CentOS 7+/Ubuntu 18.04+)、Mac OS。
  • Docker 版本:Docker Desktop 4.20+(Windows/Mac)、Docker CE 20.10+(Linux)。
  • 微服务:基于 Spring Boot 2.7.x 的 Java 微服务(user-service、order-service 等)。
  • 构建工具:Maven 3.6+(打包微服务为 JAR 包)。
3.1.3 Docker 安装与验证

① 安装 Docker:

  • Windows/Mac:从 Docker 官网 下载 Docker Desktop,双击安装(需开启 WSL2)。
  • Linux(CentOS):
# 安装依赖 yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加 Docker 仓库 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 安装 Docker CE yum install -y docker-ce docker-ce-cli containerd.io # 启动 Docker 并设置开机自启 systemctl start docker&& systemctl enabledocker

② 验证 Docker 安装:

docker --version # 查看 Docker 版本docker run hello-world # 运行测试镜像,成功则输出 Hello from Docker!
3.2 Java 微服务容器化实战(Dockerfile 编写)

以 user-service 为例,实现 Java 微服务的容器化打包。

3.2.1 微服务打包(JAR 包)

使用 Maven 将 user-service 打包为可执行 JAR 包:

cd user-service mvn clean package -Dmaven.test.skip=true # 跳过测试,生成 JAR 包

打包完成后,JAR 包位于 target/user-service-1.0.0.jar(名称根据 pom.xml 配置)。

3.2.2 编写 Dockerfile

在 user-service 项目根目录创建 Dockerfile(无后缀名),内容如下:

# 基础镜像:使用官方 OpenJDK 11 镜像(轻量级,基于 Alpine Linux) FROM openjdk:11-jre-slim # 维护者信息(可选) LABEL maintainer="[email protected]" # 环境变量:JAR 包名称、端口号 ENV JAR_NAME=user-service-1.0.0.jar ENV PORT=8081 # 创建工作目录 WORKDIR /app # 复制本地 JAR 包到容器工作目录 COPY target/$JAR_NAME /app/$JAR_NAME # 暴露容器端口(与微服务端口一致) EXPOSE $PORT # 容器启动命令(运行 JAR 包) ENTRYPOINT ["sh", "-c", "java -jar $JAR_NAME --server.port=$PORT"] 
3.2.3 Dockerfile 优化技巧

💡 优化目标:减小镜像体积、提升构建速度、增强安全性。

  1. 使用轻量级基础镜像:优先选择 openjdk:11-jre-slim(约 200MB)而非 openjdk:11(约 600MB),仅包含 JRE(运行时)而非 JDK(开发工具)。
  2. 分层构建:分离依赖与代码,利用 Docker 缓存机制提升构建速度:
# 第一阶段:构建 JAR 包(使用 JDK 镜像) FROM maven:3.8.5-openjdk-11 AS builder WORKDIR /build COPY pom.xml . # 下载依赖(缓存依赖层,pom.xml 不变则不重新下载) RUN mvn dependency:go-offline COPY src ./src # 构建 JAR 包 RUN mvn package -Dmaven.test.skip=true # 第二阶段:运行 JAR 包(使用 JRE 镜像) FROM openjdk:11-jre-slim WORKDIR /app # 从构建阶段复制 JAR 包 COPY --from=builder /build/target/user-service-1.0.0.jar /app/user-service-1.0.0.jar EXPOSE 8081 ENTRYPOINT ["java", "-jar", "user-service-1.0.0.jar"] 
  1. 非 root 用户运行:避免容器以 root 用户运行,降低安全风险:
# 创建非 root 用户 RUN addgroup --system --gid 1001 appgroup && adduser --system --uid 1001 --gid 1001 appuser # 切换用户 USER appuser 
  1. 清理无用文件:构建过程中删除缓存文件(如 Maven 仓库、编译临时文件)。
3.2.4 构建 Docker 镜像

在 Dockerfile 所在目录执行构建命令:

# 格式:docker build -t 镜像名称:标签 .docker build -t user-service:1.0.0 .
  • -t:指定镜像名称与标签(标签用于区分版本)。
  • .:表示 Dockerfile 所在目录(当前目录)。

构建成功后,查看镜像:

docker images # 列出所有镜像,可看到 user-service:1.0.0
3.2.5 运行 Docker 容器

基于镜像启动容器:

# 格式:docker run -d -p 主机端口:容器端口 --name 容器名称 镜像名称:标签docker run -d -p 8081:8081 --name user-service-container user-service:1.0.0 
  • -d:后台运行容器。
  • -p:端口映射(主机端口 8081 映射到容器端口 8081)。
  • --name:指定容器名称(便于管理)。

验证容器运行:

dockerps# 列出运行中的容器curl http://localhost:8081/api/user/1 # 访问微服务接口,返回用户信息则成功
3.2.6 容器常用操作
# 查看容器日志(实时输出)docker logs -f user-service-container # 进入容器内部dockereexec -it user-service-container /bin/bash # 停止容器docker stop user-service-container # 启动已停止的容器docker start user-service-container # 删除容器(需先停止)dockerrm user-service-container # 删除镜像docker rmi user-service:1.0.0 
3.3 镜像仓库实战(推送与拉取)
3.3.1 公共仓库(Docker Hub)

① 注册 Docker Hub 账号(官网)。
② 登录 Docker Hub:

docker login -u 用户名 -p 密码 

③ 给镜像打标签(需包含 Docker Hub 用户名):

docker tag user-service:1.0.0 用户名/user-service:1.0.0 

④ 推送镜像到 Docker Hub:

docker push 用户名/user-service:1.0.0 

⑤ 从 Docker Hub 拉取镜像(其他机器):

docker pull 用户名/user-service:1.0.0 
3.3.2 私有仓库(Harbor)

生产环境常用私有仓库存储镜像(避免公开泄露),以 Harbor 为例:
① 部署 Harbor 私有仓库(参考 Harbor 官网)。
② 登录私有仓库:

docker login -u 用户名 -p 密码 私有仓库地址(如 192.168.1.100:8080) 

③ 打标签并推送:

docker tag user-service:1.0.0 192.168.1.100:8080/microservice/user-service:1.0.0 docker push 192.168.1.100:8080/microservice/user-service:1.0.0 

四、Kubernetes 核心概念与环境准备

4.1 K8s 核心组件与架构

Kubernetes(简称 K8s)是容器编排平台,用于管理大规模容器集群,核心功能包括:容器调度、服务发现、负载均衡、自动扩缩容、滚动更新、故障转移。

4.1.1 K8s 核心组件

K8s 集群分为控制平面(Control Plane) 和节点(Node) 两部分:

  1. 控制平面组件(管理集群状态):
    • kube-apiserver:集群统一入口,提供 REST API,所有操作通过 API Server 执行。
    • etcd:分布式键值数据库,存储集群所有配置与状态数据(如 Pod、Service 配置)。
    • kube-scheduler:调度器,根据 Pod 资源需求(CPU、内存)和节点负载,将 Pod 调度到合适节点。
    • kube-controller-manager:控制器管理器,包含多种控制器(如 Deployment 控制器、Node 控制器),确保集群状态与期望状态一致。
    • cloud-controller-manager:云服务提供商相关控制器(如 AWS、阿里云适配),可选。
  2. 节点组件(运行容器):
    • kubelet:运行在每个节点,负责管理 Pod 的生命周期(启动、停止、监控容器)。
    • kube-proxy:网络代理,负责 Pod 网络通信、Service 负载均衡(实现 TCP/UDP 转发)。
    • 容器运行时:如 Docker、containerd,负责容器的创建与运行。
4.1.2 K8s 核心资源对象
  • Pod:K8s 最小部署单元,包含一个或多个容器(如一个 user-service 容器 + 一个日志收集容器),共享网络和存储。
  • Service:定义 Pod 的访问入口,实现 Pod 的服务发现与负载均衡(PodIP 可能变化,ServiceIP 固定)。
  • Deployment:声明式管理 Pod,支持创建多副本、滚动更新、回滚等功能(不直接管理 Pod,通过 ReplicaSet 管理)。
  • ConfigMap:存储非敏感配置数据(如应用配置、环境变量),可被 Pod 挂载使用。
  • Secret:存储敏感数据(如密码、密钥、令牌),加密存储,挂载到 Pod 时以文件或环境变量形式提供。
  • Ingress:管理外部访问集群内服务的规则(如 HTTP/HTTPS 路由、域名转发),替代 NodePort 和 LoadBalancer。
  • Namespace:集群资源隔离,将集群划分为多个独立命名空间(如 dev、test、prod)。
4.2 K8s 环境准备
4.2.1 环境选型
  • 本地测试:Minikube(单节点 K8s 集群,适合开发测试)、Kind(多节点集群,轻量级)。
  • 生产环境:Kubernetes 集群(多节点部署,支持高可用)、云厂商托管 K8s(如阿里云 ACK、腾讯云 EKS)。
4.2.2 Minikube 安装与启动(本地测试)

① 安装 Minikube(参考 Minikube 官网):

  • Windows(PowerShell):
New-Item-Path 'c:\'-Name 'minikube'-ItemType Directory -Force Invoke-WebRequest-OutFile 'c:\minikube\minikube.exe'-Uri 'https://github.com/kubernetes/minikube/releases/latest/download/minikube-windows-amd64.exe'-UseBasicParsing 
  • Linux:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudoinstall minikube-linux-amd64 /usr/local/bin/minikube 

② 启动 Minikube 集群:

minikube start --driver=docker # 使用 Docker 作为容器运行时

启动成功后,验证集群状态:

minikube status # 查看 Minikube 状态 kubectl cluster-info # 查看集群信息 kubectl get nodes # 查看节点(Minikube 为单节点)
4.2.3 kubectl 命令行工具

kubectl 是 K8s 命令行工具,用于操作集群资源,常用命令:

# 查看资源列表(Pod、Service、Deployment 等) kubectl get pods [-n 命名空间]# 查看 Pod kubectl get services # 查看 Service kubectl get deployments # 查看 Deployment# 查看资源详细信息 kubectl describe pod <pod 名称># 查看 Pod 日志 kubectl logs <pod 名称>[-f]# -f 实时输出# 执行 Pod 内命令 kubectl exec -it <pod 名称> -- /bin/bash # 创建/删除资源(通过配置文件) kubectl apply -f <配置文件.yaml># 创建资源 kubectl delete -f <配置文件.yaml># 删除资源# 进入 Minikube 节点(本地测试) minikube ssh

五、K8s 实战:Java 微服务部署

5.1 部署流程概述

Java 微服务在 K8s 中的部署流程:

  1. 微服务容器化(Dockerfile 构建镜像)。
  2. 镜像推送至仓库(Docker Hub/Harbor)。
  3. 编写 K8s 资源配置文件(Deployment、Service、ConfigMap 等)。
  4. 使用 kubectl 应用配置文件,创建资源。
  5. 验证服务部署与访问。
5.2 编写 K8s 资源配置文件

以 user-service 为例,编写完整的资源配置文件 user-service-deploy.yaml,包含 Namespace、ConfigMap、Secret、Deployment、Service。

5.2.1 配置文件内容
# 1. 命名空间(隔离 dev 环境资源)apiVersion: v1 kind: Namespace metadata:name: microservice-dev ---# 2. ConfigMap(存储非敏感配置)apiVersion: v1 kind: ConfigMap metadata:name: user-service-config namespace: microservice-dev data:# 应用配置(键值对形式,可通过环境变量或文件挂载到 Pod)SPRING_PROFILES_ACTIVE:"dev"NACOS_SERVER_ADDR:"nacos-service:8848"LOG_LEVEL:"INFO"---# 3. Secret(存储敏感配置,如数据库密码)apiVersion: v1 kind: Secret metadata:name: user-service-secret namespace: microservice-dev type: Opaque # 通用类型,存储键值对data:# 敏感数据需 Base64 编码(echo -n "密码" | base64)DB_PASSWORD:"cGFzc3dvcmQxMjM="# 解码后:password123JWT_SECRET:"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="# 解码后:abcdefghijklmnopqrstuvwxyz---# 4. Deployment(管理 Pod 生命周期)apiVersion: apps/v1 kind: Deployment metadata:name: user-service-deploy namespace: microservice-dev labels:app: user-service spec:replicas:2# Pod 副本数(高可用,2 个实例)selector:matchLabels:app: user-service # 匹配 Pod 标签strategy:# 滚动更新策略(避免服务中断)rollingUpdate:maxSurge:1# 滚动更新时最多新增 1 个 PodmaxUnavailable:0# 滚动更新时不可用 Pod 数为 0template:metadata:labels:app: user-service # Pod 标签spec:containers:-name: user-service # 容器名称image: user-service:1.0.0 # 镜像名称(本地测试用 Minikube 可直接使用本地镜像)# 本地镜像需配置 ImagePullPolicy 为 Never(不拉取远程镜像)imagePullPolicy: Never ports:-containerPort:8081# 容器端口(与微服务端口一致)# 环境变量(从 ConfigMap 和 Secret 读取)env:-name: SPRING_PROFILES_ACTIVE valueFrom:configMapKeyRef:name: user-service-config key: SPRING_PROFILES_ACTIVE -name: NACOS_SERVER_ADDR valueFrom:configMapKeyRef:name: user-service-config key: NACOS_SERVER_ADDR -name: DB_PASSWORD valueFrom:secretKeyRef:name: user-service-secret key: DB_PASSWORD # 健康检查(存活探针:判断容器是否存活,失败则重启)livenessProbe:httpGet:path: /actuator/health port:8081initialDelaySeconds:60# 容器启动后 60 秒开始检查periodSeconds:10# 每 10 秒检查一次timeoutSeconds:5# 检查超时时间 5 秒# 就绪探针:判断容器是否就绪,就绪后才接收请求readinessProbe:httpGet:path: /actuator/health port:8081initialDelaySeconds:30periodSeconds:5# 资源限制(避免 Pod 占用过多资源)resources:requests:# 最小资源需求cpu:"100m"# 100 毫核(0.1 核)memory:"256Mi"# 256MB 内存limits:# 最大资源限制cpu:"500m"# 0.5 核memory:"512Mi"# 512MB 内存---# 5. Service(暴露 Pod 访问入口)apiVersion: v1 kind: Service metadata:name: user-service namespace: microservice-dev spec:selector:app: user-service # 匹配 Deployment 管理的 Podports:-port:8881# Service 端口targetPort:8081# 映射到 Pod 的端口type: ClusterIP # 集群内部访问(仅集群内其他服务可访问)
5.2.2 配置文件关键说明
  • Namespace:创建 microservice-dev 命名空间,隔离开发环境资源,避免与其他环境冲突。
  • ConfigMap/Secret:分离配置与代码,实现配置动态更新(无需重新构建镜像)。
  • Deployment:
    • replicas: 2:创建 2 个 Pod 副本,确保高可用(一个 Pod 故障,另一个仍可提供服务)。
    • 健康检查(livenessProbe/readinessProbe):避免容器'假活'(容器运行但服务不可用)。
    • 资源限制:防止单个 Pod 占用过多 CPU/内存,影响其他 Pod。
  • Service:type: ClusterIP 表示仅集群内部访问,若需外部访问,可使用 NodePort 或 Ingress。
5.3 应用配置文件部署服务

① 应用配置文件:

kubectl apply -f user-service-deploy.yaml 

② 查看部署状态:

# 查看命名空间 kubectl get namespaces # 可看到 microservice-dev# 查看 Deployment kubectl get deployments -n microservice-dev # 状态为 READY 2/2 表示 2 个副本就绪# 查看 Pod kubectl get pods -n microservice-dev # 2 个 Pod 状态为 Running# 查看 Service kubectl get services -n microservice-dev # 可看到 user-service 的 ClusterIP

③ 验证服务访问(集群内部):
通过集群内其他 Pod 访问 user-service(如通过 kubectl exec 进入某个 Pod):

# 进入 Minikube 节点 minikube ssh# 访问 user-service 的 ClusterIP(如 10.100.200.3)curl http://10.100.200.3:8881/api/user/1 
5.4 外部访问服务(Ingress 实战)

ClusterIP 类型的 Service 仅集群内部可访问,需通过 Ingress 实现外部访问。

5.4.1 安装 Ingress 控制器(Minikube)
minikube addons enable ingress # 启用 Ingress 插件 kubectl get pods -n kube-system |grep ingress # 查看 Ingress 控制器 Pod 是否运行
5.4.2 编写 Ingress 配置文件 ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: microservice-ingress namespace: microservice-dev annotations:# 启用 rewrite-target(路径重写)nginx.ingress.kubernetes.io/rewrite-target: /$1 spec:rules:# 本地测试使用 MinikubeIP 作为域名(通过 minikube ip 获取)-host: minikube.local http:paths:-path: /user/(.*)# 外部访问路径:http://minikube.local/user/xxxpathType: Prefix backend:service:name: user-service # 映射到 user-serviceport:number:8881-path: /order/(.*)# 后续部署 order-service 后可添加pathType: Prefix backend:service:name: order-service port:number:8882
5.4.3 应用 Ingress 配置并测试

① 应用配置:

kubectl apply -f ingress.yaml 

② 配置本地 hosts 文件(Windows:C:\Windows\System32\drivers\etc\hosts,Linux/Mac:/etc/hosts):

# 添加映射(MinikubeIP 通过 minikube ip 命令获取,如 192.168.49.2) 192.168.49.2 minikube.local 

③ 外部访问服务:
打开浏览器访问 http://minikube.local/user/api/user/1,即可看到 user-service 返回的用户信息。

5.5 部署 Nacos 与 Sentinel(K8s 环境)

微服务依赖的注册中心(Nacos)、熔断限流组件(Sentinel)也需部署在 K8s 中,以 Nacos 为例:

5.5.1 Nacos 部署配置文件 nacos-deploy.yaml
apiVersion: v1 kind: Namespace metadata:name: microservice-dev ---apiVersion: apps/v1 kind: Deployment metadata:name: nacos-deploy namespace: microservice-dev spec:replicas:1selector:matchLabels:app: nacos template:metadata:labels:app: nacos spec:containers:-name: nacos image: nacos/nacos-server:v2.2.3 ports:-containerPort:8848-containerPort:9848env:-name: MODE value:"standalone"# 单机模式(开发测试)-name: NACOS_AUTH_ENABLE value:"false"# 关闭认证resources:requests:cpu:"500m"memory:"1Gi"limits:cpu:"1000m"memory:"2Gi"---apiVersion: v1 kind: Service metadata:name: nacos-service namespace: microservice-dev spec:selector:app: nacos ports:-port:8848targetPort:8848type: ClusterIP 
5.5.2 部署 Nacos 并验证
kubectl apply -f nacos-deploy.yaml kubectl get pods -n microservice-dev |grep nacos # 查看 Nacos Pod 状态

访问 http://minikube.local/nacos(需添加 Ingress 规则),即可进入 Nacos 控制台,user-service 会自动注册到 Nacos。

六、K8s 高级功能实战:扩缩容、滚动更新与监控

6.1 自动扩缩容(HPA)

K8s 的 Horizontal Pod Autoscaler(HPA)可根据 CPU 使用率、内存使用率或自定义指标,自动调整 Pod 副本数,应对流量波动。

6.1.1 部署 Metrics Server(指标采集)

HPA 依赖 Metrics Server 采集 Pod 资源指标:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml # 修改 Metrics Server 配置(解决 Minikube 证书问题) kubectl edit deployment metrics-server -n kube-system # 在 spec.template.spec.containers.args 中添加: - --kubelet-insecure-tls 
6.1.2 创建 HPA 配置文件 user-service-hpa.yaml
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata:name: user-service-hpa namespace: microservice-dev spec:scaleTargetRef:apiVersion: apps/v1 kind: Deployment name: user-service-deploy # 关联的 DeploymentminReplicas:2# 最小副本数maxReplicas:5# 最大副本数metrics:-type: Resource resource:name: cpu target:type: Utilization averageUtilization:70# CPU 使用率超过 70% 则扩容-type: Resource resource:name: memory target:type: Utilization averageUtilization:80# 内存使用率超过 80% 则扩容
6.1.3 应用 HPA 并测试
kubectl apply -f user-service-hpa.yaml kubectl get hpa -n microservice-dev # 查看 HPA 状态

当 user-service 的 CPU 使用率超过 70% 时,HPA 会自动增加 Pod 副本数;使用率下降后,会自动减少副本数(默认冷却时间 3 分钟)。

6.2 滚动更新与回滚
6.2.1 滚动更新(更新微服务版本)

当 user-service 发布新版本(如 1.0.1)时,通过 Deployment 实现滚动更新(不中断服务):

# 方式 1:直接修改镜像版本 kubectl set image deployment/user-service-deploy user-service=user-service:1.0.1 -n microservice-dev # 方式 2:修改配置文件后应用 kubectl apply -f user-service-deploy.yaml(已更新 image 为 1.0.1) 

查看更新状态:

kubectl rollout status deployment/user-service-deploy -n microservice-dev 

滚动更新过程中,K8s 会先创建新版本 Pod,待其就绪后再删除旧版本 Pod,确保服务不中断。

6.2.2 回滚(版本回退)

若新版本存在问题,可回滚到上一版本:

# 查看 Deployment 历史版本 kubectl rollout history deployment/user-service-deploy -n microservice-dev # 回滚到上一版本 kubectl rollout undo deployment/user-service-deploy -n microservice-dev # 回滚到指定版本(如版本 1) kubectl rollout undo deployment/user-service-deploy --to-revision=1 -n microservice-dev 
6.3 K8s 监控实战(Prometheus + Grafana)
6.3.1 部署 Prometheus Operator(Helm)

使用 Helm(K8s 包管理工具)快速部署 Prometheus + Grafana:
① 安装 Helm(参考 Helm 官网)。
② 添加 Prometheus 仓库:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update 

③ 部署 Prometheus + Grafana:

helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring --create-namespace 
6.3.2 配置微服务指标采集

微服务已通过 Actuator + Micrometer 暴露 Prometheus 指标,需在 K8s 中配置 ServiceMonitor,让 Prometheus 自动发现并采集指标:

apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata:name: user-service-monitor namespace: monitoring labels:release: prometheus spec:selector:matchLabels:app: user-service # 匹配 user-service 的 Service 标签namespaceSelector:matchNames:- microservice-dev # 微服务所在命名空间endpoints:-port:8881# Service 端口path: /actuator/prometheus # 指标端点interval: 15s # 采集间隔
6.3.3 访问 Grafana 查看监控

① 暴露 Grafana 服务(NodePort):

kubectl expose service prometheus-grafana -n monitoring --type=NodePort --port=80

② 获取 Grafana 访问地址:

minikube service prometheus-grafana -n monitoring --url 

③ 登录 Grafana(默认用户名 admin,密码通过以下命令获取):

kubectl get secret prometheus-grafana -n monitoring -o jsonpath="{.data.admin-password}"| base64 -d 

④ 导入 Spring Boot 微服务监控模板(ID:12900),即可查看微服务的 CPU、内存、响应时间等指标。

七、云原生架构高可用与运维实战

7.1 高可用设计原则
7.1.1 应用层高可用
  • 多副本部署:关键服务(如网关、用户服务)部署至少 2 个副本,避免单点故障。
  • 无状态设计:微服务设计为无状态(不存储本地数据),便于水平扩容与故障转移。
  • 健康检查:配置 livenessProbe 和 readinessProbe,及时剔除故障 Pod。
7.1.2 基础设施层高可用
  • 多节点部署:K8s 集群至少部署 3 个控制平面节点和 2 个工作节点(生产环境)。
  • 持久化存储:使用 K8s PV/PVC(持久卷/持久卷声明)管理数据存储,确保 Pod 重启后数据不丢失。
  • 负载均衡:Ingress 或云厂商负载均衡器配置多可用区部署,避免单可用区故障。
7.2 常见运维问题与解决方案
问题现象排查步骤解决方案
Pod 处于 Pending 状态1. kubectl describe pod <pod 名称> 查看事件;
  1. 检查节点资源是否充足;
  2. 检查镜像是否存在 | 1. 扩容节点资源;
  3. 修正镜像名称/标签;
  4. 配置镜像拉取密钥 | | Pod 处于 CrashLoopBackOff | 1. kubectl logs <pod 名称> 查看日志;
  5. 检查容器启动命令;
  6. 检查应用配置 | 1. 修复应用代码 bug;
  7. 修正启动命令;
  8. 检查 ConfigMap/Secret 配置 | | 服务外部无法访问 | 1. 检查 Pod 是否运行;
  9. 检查 Service 是否正确匹配 Pod;
  10. 检查 Ingress 规则 | 1. 重启故障 Pod;
  11. 修正 Service 的 selector;
  12. 检查 Ingress 控制器是否运行 | | 滚动更新失败 | 1. kubectl rollout status 查看更新状态;
  13. 检查新版本镜像是否正常;
  14. 检查健康检查配置 | 1. 回滚到上一版本;
  15. 修复新版本镜像;
  16. 调整健康检查参数(如延长 initialDelaySeconds) |
7.3 容器化微服务性能优化
7.3.1 应用层优化
  • JVM 参数优化:容器环境下需指定 JVM 内存(避免占用过多容器内存),如 -Xms256m -Xmx512m。
  • 连接池优化:数据库、Redis 连接池大小适配容器资源(如最大连接数=CPU 核心数*2+1)。
  • 日志优化:避免打印大量日志,日志输出到标准输出(由 K8s 统一收集)。
7.3.2 容器层优化
  • 镜像优化:减小镜像体积(如分层构建、清理缓存),提升拉取速度。
  • 资源限制:合理设置 CPU/内存限制,避免资源争抢。
  • 容器网络:使用 Calico 等高性能网络插件,提升 Pod 网络通信效率。

八、本章总结

✅ 本章详细讲解了容器化与云原生的核心概念,实战了 Docker 打包 Java 微服务、Kubernetes 部署与管理微服务的完整流程,涵盖了镜像构建、资源配置、服务暴露、自动扩缩容、监控告警等核心功能,最后分享了云原生架构的高可用设计与运维技巧。

通过本章学习,读者应掌握:

  1. Docker 的核心概念与 Java 微服务容器化方法(Dockerfile 编写、镜像优化、容器管理)。
  2. Kubernetes 的核心组件与资源对象(Pod、Service、Deployment、Ingress)的作用与配置。
  3. 微服务在 K8s 中的完整部署流程,包括注册中心、配置中心、网关的协同部署。
  4. K8s 高级功能(自动扩缩容、滚动更新、回滚)的实战应用。
  5. 云原生架构的高可用设计原则与常见运维问题的解决方案。

容器化与云原生是 Java 微服务落地的必然趋势,能够大幅提升部署效率、环境一致性与系统弹性。至此,本章关于微服务容器化与云原生部署的核心内容已全部讲解完成,形成了完整的 Java 开发知识体系。读者可结合实际项目,将所学知识灵活应用,构建高性能、高可用的 Java 应用系统。

目录

  1. 第二十章 微服务容器化与云原生部署:Docker + Kubernetes 实战
  2. 一、章节学习目标与重点
  3. 1.1 学习目标
  4. 1.2 学习重点
  5. 二、容器化与云原生核心概念
  6. 2.1 为什么需要容器化?
  7. 2.2 云原生核心概念
  8. 2.3 容器化与云原生架构图
  9. 三、Docker 实战:Java 微服务容器化
  10. 3.1 Docker 核心概念与环境准备
  11. 3.1.1 Docker 核心概念
  12. 3.1.2 环境准备
  13. 3.1.3 Docker 安装与验证
  14. 安装依赖 yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加 Docker 仓库 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 安装 Docker CE yum install -y docker-ce docker-ce-cli containerd.io # 启动 Docker 并设置开机自启 systemctl start docker&& systemctl enabledocker
  15. 3.2 Java 微服务容器化实战(Dockerfile 编写)
  16. 3.2.1 微服务打包(JAR 包)
  17. 3.2.2 编写 Dockerfile
  18. 基础镜像:使用官方 OpenJDK 11 镜像(轻量级,基于 Alpine Linux) FROM openjdk:11-jre-slim # 维护者信息(可选) LABEL maintainer="[email protected]" # 环境变量:JAR 包名称、端口号 ENV JARNAME=user-service-1.0.0.jar ENV PORT=8081 # 创建工作目录 WORKDIR /app # 复制本地 JAR 包到容器工作目录 COPY target/$JARNAME /app/$JARNAME # 暴露容器端口(与微服务端口一致) EXPOSE $PORT # 容器启动命令(运行 JAR 包) ENTRYPOINT ["sh", "-c", "java -jar $JARNAME --server.port=$PORT"]
  19. 3.2.3 Dockerfile 优化技巧
  20. 第一阶段:构建 JAR 包(使用 JDK 镜像) FROM maven:3.8.5-openjdk-11 AS builder WORKDIR /build COPY pom.xml . # 下载依赖(缓存依赖层,pom.xml 不变则不重新下载) RUN mvn dependency:go-offline COPY src ./src # 构建 JAR 包 RUN mvn package -Dmaven.test.skip=true # 第二阶段:运行 JAR 包(使用 JRE 镜像) FROM openjdk:11-jre-slim WORKDIR /app # 从构建阶段复制 JAR 包 COPY --from=builder /build/target/user-service-1.0.0.jar /app/user-service-1.0.0.jar EXPOSE 8081 ENTRYPOINT ["java", "-jar", "user-service-1.0.0.jar"]
  21. 创建非 root 用户 RUN addgroup --system --gid 1001 appgroup && adduser --system --uid 1001 --gid 1001 appuser # 切换用户 USER appuser
  22. 3.2.4 构建 Docker 镜像
  23. 格式:docker build -t 镜像名称:标签 .docker build -t user-service:1.0.0 .
  24. 3.2.5 运行 Docker 容器
  25. 格式:docker run -d -p 主机端口:容器端口 --name 容器名称 镜像名称:标签docker run -d -p 8081:8081 --name user-service-container user-service:1.0.0
  26. 3.2.6 容器常用操作
  27. 查看容器日志(实时输出)docker logs -f user-service-container # 进入容器内部dockereexec -it user-service-container /bin/bash # 停止容器docker stop user-service-container # 启动已停止的容器docker start user-service-container # 删除容器(需先停止)dockerrm user-service-container # 删除镜像docker rmi user-service:1.0.0
  28. 3.3 镜像仓库实战(推送与拉取)
  29. 3.3.1 公共仓库(Docker Hub)
  30. 3.3.2 私有仓库(Harbor)
  31. 四、Kubernetes 核心概念与环境准备
  32. 4.1 K8s 核心组件与架构
  33. 4.1.1 K8s 核心组件
  34. 4.1.2 K8s 核心资源对象
  35. 4.2 K8s 环境准备
  36. 4.2.1 环境选型
  37. 4.2.2 Minikube 安装与启动(本地测试)
  38. 4.2.3 kubectl 命令行工具
  39. 查看资源列表(Pod、Service、Deployment 等) kubectl get pods [-n 命名空间]# 查看 Pod kubectl get services # 查看 Service kubectl get deployments # 查看 Deployment# 查看资源详细信息 kubectl describe pod <pod 名称># 查看 Pod 日志 kubectl logs <pod 名称>[-f]# -f 实时输出# 执行 Pod 内命令 kubectl exec -it <pod 名称> -- /bin/bash # 创建/删除资源(通过配置文件) kubectl apply -f <配置文件.yaml># 创建资源 kubectl delete -f <配置文件.yaml># 删除资源# 进入 Minikube 节点(本地测试) minikube ssh
  40. 五、K8s 实战:Java 微服务部署
  41. 5.1 部署流程概述
  42. 5.2 编写 K8s 资源配置文件
  43. 5.2.1 配置文件内容
  44. 1. 命名空间(隔离 dev 环境资源)apiVersion: v1 kind: Namespace metadata:name: microservice-dev ---# 2. ConfigMap(存储非敏感配置)apiVersion: v1 kind: ConfigMap metadata:name: user-service-config namespace: microservice-dev data:# 应用配置(键值对形式,可通过环境变量或文件挂载到 Pod)SPRINGPROFILESACTIVE:"dev"NACOSSERVERADDR:"nacos-service:8848"LOGLEVEL:"INFO"---# 3. Secret(存储敏感配置,如数据库密码)apiVersion: v1 kind: Secret metadata:name: user-service-secret namespace: microservice-dev type: Opaque # 通用类型,存储键值对data:# 敏感数据需 Base64 编码(echo -n "密码" | base64)DBPASSWORD:"cGFzc3dvcmQxMjM="# 解码后:password123JWTSECRET:"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="# 解码后:abcdefghijklmnopqrstuvwxyz---# 4. Deployment(管理 Pod 生命周期)apiVersion: apps/v1 kind: Deployment metadata:name: user-service-deploy namespace: microservice-dev labels:app: user-service spec:replicas:2# Pod 副本数(高可用,2 个实例)selector:matchLabels:app: user-service # 匹配 Pod 标签strategy:# 滚动更新策略(避免服务中断)rollingUpdate:maxSurge:1# 滚动更新时最多新增 1 个 PodmaxUnavailable:0# 滚动更新时不可用 Pod 数为 0template:metadata:labels:app: user-service # Pod 标签spec:containers:-name: user-service # 容器名称image: user-service:1.0.0 # 镜像名称(本地测试用 Minikube 可直接使用本地镜像)# 本地镜像需配置 ImagePullPolicy 为 Never(不拉取远程镜像)imagePullPolicy: Never ports:-containerPort:8081# 容器端口(与微服务端口一致)# 环境变量(从 ConfigMap 和 Secret 读取)env:-name: SPRINGPROFILESACTIVE valueFrom:configMapKeyRef:name: user-service-config key: SPRINGPROFILESACTIVE -name: NACOSSERVERADDR valueFrom:configMapKeyRef:name: user-service-config key: NACOSSERVERADDR -name: DBPASSWORD valueFrom:secretKeyRef:name: user-service-secret key: DB_PASSWORD # 健康检查(存活探针:判断容器是否存活,失败则重启)livenessProbe:httpGet:path: /actuator/health port:8081initialDelaySeconds:60# 容器启动后 60 秒开始检查periodSeconds:10# 每 10 秒检查一次timeoutSeconds:5# 检查超时时间 5 秒# 就绪探针:判断容器是否就绪,就绪后才接收请求readinessProbe:httpGet:path: /actuator/health port:8081initialDelaySeconds:30periodSeconds:5# 资源限制(避免 Pod 占用过多资源)resources:requests:# 最小资源需求cpu:"100m"# 100 毫核(0.1 核)memory:"256Mi"# 256MB 内存limits:# 最大资源限制cpu:"500m"# 0.5 核memory:"512Mi"# 512MB 内存---# 5. Service(暴露 Pod 访问入口)apiVersion: v1 kind: Service metadata:name: user-service namespace: microservice-dev spec:selector:app: user-service # 匹配 Deployment 管理的 Podports:-port:8881# Service 端口targetPort:8081# 映射到 Pod 的端口type: ClusterIP # 集群内部访问(仅集群内其他服务可访问)
  45. 5.2.2 配置文件关键说明
  46. 5.3 应用配置文件部署服务
  47. 查看命名空间 kubectl get namespaces # 可看到 microservice-dev# 查看 Deployment kubectl get deployments -n microservice-dev # 状态为 READY 2/2 表示 2 个副本就绪# 查看 Pod kubectl get pods -n microservice-dev # 2 个 Pod 状态为 Running# 查看 Service kubectl get services -n microservice-dev # 可看到 user-service 的 ClusterIP
  48. 进入 Minikube 节点 minikube ssh# 访问 user-service 的 ClusterIP(如 10.100.200.3)curl http://10.100.200.3:8881/api/user/1
  49. 5.4 外部访问服务(Ingress 实战)
  50. 5.4.1 安装 Ingress 控制器(Minikube)
  51. 5.4.2 编写 Ingress 配置文件 ingress.yaml
  52. 5.4.3 应用 Ingress 配置并测试
  53. 添加映射(MinikubeIP 通过 minikube ip 命令获取,如 192.168.49.2) 192.168.49.2 minikube.local
  54. 5.5 部署 Nacos 与 Sentinel(K8s 环境)
  55. 5.5.1 Nacos 部署配置文件 nacos-deploy.yaml
  56. 5.5.2 部署 Nacos 并验证
  57. 六、K8s 高级功能实战:扩缩容、滚动更新与监控
  58. 6.1 自动扩缩容(HPA)
  59. 6.1.1 部署 Metrics Server(指标采集)
  60. 6.1.2 创建 HPA 配置文件 user-service-hpa.yaml
  61. 6.1.3 应用 HPA 并测试
  62. 6.2 滚动更新与回滚
  63. 6.2.1 滚动更新(更新微服务版本)
  64. 方式 1:直接修改镜像版本 kubectl set image deployment/user-service-deploy user-service=user-service:1.0.1 -n microservice-dev # 方式 2:修改配置文件后应用 kubectl apply -f user-service-deploy.yaml(已更新 image 为 1.0.1)
  65. 6.2.2 回滚(版本回退)
  66. 查看 Deployment 历史版本 kubectl rollout history deployment/user-service-deploy -n microservice-dev # 回滚到上一版本 kubectl rollout undo deployment/user-service-deploy -n microservice-dev # 回滚到指定版本(如版本 1) kubectl rollout undo deployment/user-service-deploy --to-revision=1 -n microservice-dev
  67. 6.3 K8s 监控实战(Prometheus + Grafana)
  68. 6.3.1 部署 Prometheus Operator(Helm)
  69. 6.3.2 配置微服务指标采集
  70. 6.3.3 访问 Grafana 查看监控
  71. 七、云原生架构高可用与运维实战
  72. 7.1 高可用设计原则
  73. 7.1.1 应用层高可用
  74. 7.1.2 基础设施层高可用
  75. 7.2 常见运维问题与解决方案
  76. 7.3 容器化微服务性能优化
  77. 7.3.1 应用层优化
  78. 7.3.2 容器层优化
  79. 八、本章总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • OpenClaw 安装部署全流程:搭建自托管 AI 助手
  • OpenClaw 接入飞书机器人并集成 Ollama 本地大模型实战
  • 12 款主流 AI 降重工具评测与选择指南
  • OpenClaw QQ 机器人插件安装与配置指南
  • 25 个实用 Prompt 技巧:有效降低 AI 生成内容检测率
  • AI 时代技术民主化:文科生为何成最大受益者
  • GitHub Copilot 学生认证通过指南:2FA 配置与材料提交注意事项
  • 【大模型 】API 对接指南:OpenAI/Claude/LLaMA 3 调用技巧
  • Stable Diffusion WebUI Forge 图像质量评估核心指标解析
  • 软件架构师的核心职责与能力要求
  • C++ 并发模型:内存序、可见性与指令重排
  • 大模型实战技术指南:集群、训练、微调与推理加速
  • 路径类动态规划入门:3 道经典例题全解
  • Floweb 超轻量浮动浏览器功能介绍
  • 基于遗传算法的 LQR 控制器最优设计算法
  • Linux 库制作与原理详解
  • 使用 Claude Code 修改 Jakarta EE 消息队列 Java 代码实战
  • 提升 AI 大模型回答质量的 9 个提示词技巧
  • 大模型时代 Java 程序员如何借助 LangChain4j 构建智能应用
  • OpenClaw 清理 Skill 实战:基于 Rust+Tauri 构建安全沙箱

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online