从 Docker 到 K8s:Linux 平台微服务容器化全流程拆解
本文面向中高级开发者,聚焦 Linux 环境下传统微服务从单机 Docker 容器向 Kubernetes(K8s)集群迁移部署的完整实践。通过“环境准备→容器化改造→K8s 编排→网络存储配置→部署验证→运维增强→问题排查”的全链路拆解,结合实操命令、YAML 清单示例与架构解析,帮助开发者掌握微服务容器化演进的核心逻辑与落地技巧。

一、背景与动机:从 Docker 到 K8s 的必然演进
在微服务架构落地初期,Docker 作为轻量级容器技术,凭借“一次构建、到处运行”的特性,解决了传统应用“开发环境与生产环境不一致”的核心痛点,成为单机场景下微服务容器化的首选方案。但随着业务规模扩大,单机 Docker 部署的局限性逐渐凸显:
-
可扩展性不足:服务扩容需手动在多台主机部署 Docker 容器,无法实现动态伸缩,难以应对流量峰值;
-
高可用缺失:容器故障后需手动重启,无自动恢复机制,单点故障易导致服务中断;
-
服务治理复杂:多服务间通信需手动配置网络,服务发现、负载均衡需额外搭建组件(如 Nginx),维护成本高;
-
版本管理混乱:服务更新需手动停止旧容器、启动新容器,易出现版本不一致,无法实现平滑滚动更新。

Kubernetes 作为开源容器编排平台,恰好弥补了单机 Docker 的短板,其核心优势在于:
-
自动化运维:提供容器自动部署、扩缩容、故障自愈、滚动更新等能力,降低人工操作成本;
-
高效服务治理:内置服务发现、负载均衡、DNS 解析,支持跨节点 Pod 通信;
-
资源精细化管控:通过 Namespace、Cgroup 实现资源隔离与配额管理,提升资源利用率;
-
生态兼容性强:支持 Docker、containerd 等多种容器运行时,兼容主流云原生工具(如 Helm、Prometheus)。
因此,当微服务规模从“单机多容器”演进到“多机集群”时,从 Docker 单机部署迁移到 K8s 编排,是实现服务规模化、高可用、可运维的必然选择。
二、环境准备:Linux 下 Docker 与 K8s 集群搭建
本章节以 Ubuntu 22.04 LTS 系统为例,详细说明 Docker、containerd、kubectl、kubeadm 等组件的安装步骤,以及单节点 K8s 集群(适用于测试)和多节点集群(适用于生产)的初始化流程。
2.1 前置环境配置
首先完成 Linux 系统基础配置,关闭防火墙、SELinux,禁用 Swap,配置主机名与 hosts 解析(多节点集群必需):
# 关闭防火墙
sudo ufw disable
sudo ufw status
# 关闭 SE Linux(Ubuntu 默认未启用,CentOS 需额外执行)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# 禁用 Swap(K8s 要求禁用 Swap 以保证性能)
sudo swapoff -a
sudo sed -i '/swap/s/^/#/' /etc/fstab
# 配置主机名(单节点可设为 k8s-master,多节点分别设为 k8s-master、k8s-node1、k8s-node2)
sudo hostnamectl set-hostname k8s-master
# 配置 hosts 解析(多节点需在所有节点执行)
sudo cat >> /etc/hosts << EOF
192.168.1.100 k8s-master
192.168.1.101 k8s-node1
192.168.1.102 k8s-node2
EOF
# 配置内核参数,开启 IP 转发与桥接
sudo cat >> /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
2.2 安装 Docker 与 containerd
K8s 支持多种容器运行时,此处选择主流的 containerd(Docker 底层也基于 containerd),同时安装 Docker 方便本地构建镜像:
# 安装 Docker 依赖
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg
# 添加 Docker 软件源
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 安装 Docker 与 containerd
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io
# 配置 containerd 为 K8s 兼容模式
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 修改 containerd 配置(设置 SystemdCgroup = true,适配 K8s 资源管理)
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/' /etc/containerd/config.toml
# 重启 containerd 与 Docker
sudo systemctl restart containerd docker
sudo systemctl enable containerd docker
# 验证安装
docker --version
containerd --version
2.3 安装 kubectl、kubeadm、kubelet
kubectl 是 K8s 命令行工具,kubeadm 用于快速初始化 K8s 集群,kubelet 是集群节点上的核心组件,负责管理容器生命周期:
# 添加 K8s 官方 GPG 密钥
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes.gpg
# 添加 K8s 软件源
sudo add-apt-repository "deb [arch=amd64] https://apt.kubernetes.io/ kubernetes-xenial main"
# 安装指定版本(建议选择稳定版,如 1.28.0)
sudo apt update
sudo apt install -y kubelet=1.28.0-00 kubeadm=1.28.0-00 kubectl=1.28.0-00
# 禁止组件自动更新
sudo apt-mark hold kubelet kubeadm kubectl
# 验证安装
kubectl version --client
kubeadm version
2.4 初始化 K8s 集群
2.4.1 单节点集群(测试环境)
单节点集群将 Master 节点同时作为 Worker 节点(生产环境不建议,存在单点故障):
# 初始化 Master 节点(指定容器运行时为 containerd,Pod 网段为 10.244.0.0/16)
sudo kubeadm init --image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.28.0 \
--pod-network-cidr=10.244.0.0/16 \
--cri-socket unix:///run/containerd/containerd.sock
# 配置 kubectl 权限(当前用户)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 安装网络插件(Flannel,必需,否则 Pod 无法通信)
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.22.0/Documentation/kube-flannel.yml
# 单节点集群允许 Master 节点调度 Pod(默认禁止)
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
kubectl taint nodes --all node-role.kubernetes.io/master-
# 验证集群状态(所有组件应处于 Running 状态)
kubectl get nodes
kubectl get pods -n kube-system
2.4.2 多节点集群(生产环境)
多节点集群包含 1 个 Master 节点和 2 个 Worker 节点,初始化流程如下:
-
在 Master 节点执行初始化命令(同 2.4.1 第一步),初始化完成后记录join命令(类似
kubeadm join 192.168.1.100:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx); -
在所有 Worker 节点执行上述join命令,加入集群;
-
在 Master 节点安装 Flannel 网络插件(同 2.4.1 第四步);
-
验证集群状态:
kubectl get nodes应显示所有节点为 Ready 状态。
三、微服务容器化:多服务 Docker 镜像构建与优化
本章节以“前端(Vue)+ API 服务(Spring Boot)+ 数据库(MySQL)”的典型三服务架构为例,演示 Dockerfile 编写、镜像优化、构建与推送的完整流程。
3.1 示例微服务架构说明
架构图描述:前端 Vue 应用作为静态资源服务,通过 Nginx 部署;API 服务基于 Spring Boot 开发,提供后端接口;MySQL 作为数据存储,需持久化数据。三者通过网络通信,前端调用 API 服务,API 服务连接 MySQL。
3.2 编写 Dockerfile 与构建镜像
3.2.1 前端 Vue 应用 Dockerfile
采用多阶段构建,先通过 Node 构建静态资源,再使用 Nginx 部署,减少镜像体积:
# 第一阶段:构建静态资源
FROM node:16-alpine AS build
WORKDIR /app
# 复制 package.json 与 package-lock.json,缓存依赖
COPY package*.json ./
RUN npm install --registry=https://registry.npm.taobao.org
# 复制源代码并构建
COPY . .
RUN npm run build
# 第二阶段:部署静态资源
FROM nginx:alpine
# 复制构建产物到 Nginx 静态目录
COPY --from=build /app/dist /usr/share/nginx/html
# 复制自定义 Nginx 配置(解决前端路由问题)
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 暴露 80 端口
EXPOSE 80
# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]
配套 nginx.conf 配置(解决 Vue 路由刷新 404 问题):
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
构建前端镜像:
# 进入前端项目目录
cd vue-frontend
# 构建镜像,标签为 vue-frontend:v1.0
docker build -t vue-frontend:v1.0 .
3.2.2 API 服务(Spring Boot)Dockerfile
采用多阶段构建,分离编译环境与运行环境,使用 OpenJDK 轻量镜像:
# 第一阶段:编译 Spring Boot 项目
FROM maven:3.8.6-openjdk-17 AS build
WORKDIR /app
# 复制 pom.xml 缓存依赖
COPY pom.xml ./
RUN mvn dependency:go-offline
# 复制源代码并编译打包
COPY src ./src
RUN mvn package -DskipTests
# 第二阶段:运行服务
FROM openjdk:17-jdk-slim
WORKDIR /app
# 复制编译产物(jar 包)
COPY --from=build /app/target/api-service-0.0.1-SNAPSHOT.jar api-service.jar
# 暴露 8080 端口
EXPOSE 8080
# 启动命令(指定配置文件,适配 K8s 配置中心)
CMD ["java", "-jar", "api-service.jar", "--spring.config.location=file:/config/application.yml"]
构建 API 服务镜像:
# 进入 API 项目目录
cd springboot-api
# 构建镜像,标签为 api-service:v1.0
docker build -t api-service:v1.0 .
3.2.3 MySQL 镜像(基于官方镜像定制)
直接使用官方 MySQL 镜像,通过配置文件定制初始化脚本与参数:
FROM mysql:8.0
# 复制初始化 SQL 脚本(创建数据库、表结构)
COPY init.sql /docker-entrypoint-initdb.d/
# 复制自定义配置文件(优化性能、适配微服务)
COPY my.cnf /etc/mysql/conf.d/
# 暴露 3306 端口
EXPOSE 3306
构建 MySQL 镜像:
# 进入 MySQL 配置目录
cd mysql-config
# 构建镜像,标签为 mysql:v8.0-custom
docker build -t mysql:v8.0-custom .
3.3 镜像优化技巧
-
多阶段构建:分离构建环境与运行环境,避免将编译依赖(如 Maven、Node)带入最终镜像;
-
使用轻量基础镜像:优先选择 alpine、slim 版本,减少镜像体积(如 openjdk:17-jdk-slim 比 openjdk:17 小 50%+);
-
缓存依赖层:将
COPY package*.json、COPY pom.xml放在COPY 源代码之前,利用 Docker 分层缓存,加速后续构建; -
清理冗余文件:构建过程中删除无用依赖(如
npm cache clean、mvn clean); -
指定镜像标签:避免使用 latest 标签,使用固定版本(如 v1.0),确保部署一致性。
3.4 镜像推送至 Registry
K8s 集群部署时需从 Registry 拉取镜像,此处提供两种方案:
3.4.1 本地 Registry(测试环境)
# 启动本地 Registry(端口 5000)
docker run -d -p 5000:5000 --name registry --restart=always registry:2
# 给镜像打标签(适配本地 Registry)
docker tag vue-frontend:v1.0 localhost:5000/vue-frontend:v1.0
docker tag api-service:v1.0 localhost:5000/api-service:v1.0
docker tag mysql:v8.0-custom localhost:5000/mysql:v8.0-custom
# 推送镜像至本地 Registry
docker push localhost:5000/vue-frontend:v1.0
docker push localhost:5000/api-service:v1.0
docker push localhost:5000/mysql:v8.0-custom
3.4.2 远程 Registry(生产环境)
以阿里云容器镜像服务为例:
# 登录阿里云 Registry(替换为自己的 Registry 地址)
docker login --username=xxx registry.cn-hangzhou.aliyuncs.com
# 给镜像打标签
docker tag vue-frontend:v1.0 registry.cn-hangzhou.aliyuncs.com/xxx/vue-frontend:v1.0
docker tag api-service:v1.0 registry.cn-hangzhou.aliyuncs.com/xxx/api-service:v1.0
docker tag mysql:v8.0-custom registry.cn-hangzhou.aliyuncs.com/xxx/mysql:v8.0-custom
# 推送镜像
docker push registry.cn-hangzhou.aliyuncs.com/xxx/vue-frontend:v1.0
docker push registry.cn-hangzhou.aliyuncs.com/xxx/api-service:v1.0
docker push registry.cn-hangzhou.aliyuncs.com/xxx/mysql:v8.0-custom
四、Kubernetes 资源编排:YAML 清单编写与解析
K8s 通过 YAML 资源清单定义应用部署规则,本章节将前端、API 服务、MySQL 分别转化为 Deployment、Service、ConfigMap、Secret 等资源,详细解析核心字段含义。
4.1 核心资源说明
-
Deployment:管理无状态应用的部署与更新,负责创建 Pod、滚动更新、故障自愈;
-
Service:为 Pod 提供稳定网络访问入口,实现负载均衡与服务发现;
-
ConfigMap:存储非敏感配置信息(如数据库地址、API 地址),支持动态更新;
-
Secret:存储敏感信息(如数据库密码、密钥),数据经过 Base64 编码(需注意:Base64 可逆,生产环境建议使用加密插件);
-
PersistentVolumeClaim(PVC):申请持久化存储资源,与 PersistentVolume(PV)绑定,实现数据持久化。
4.2 编写 YAML 资源清单
4.2.1 ConfigMap:存储非敏感配置
创建 app-configmap.yaml,存储前端 API 地址、MySQL 地址等配置:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config # ConfigMap 名称
namespace: microservice # 命名空间(隔离资源)
data:
# 前端配置:API 服务地址
VUE_APP_API_URL: "http://api-service:8080"
# API 服务配置:MySQL 地址
MYSQL_HOST: "mysql-service"
# MySQL 配置:数据库名称
MYSQL_DATABASE: "microservice_db"
# API 服务配置文件(完整 YAML 内容)
application.yml: |
spring:
datasource:
url: jdbc:mysql://${MYSQL_HOST}:3306/${MYSQL_DATABASE}?useSSL=false&serverTimezone=Asia/Shanghai
username: ${MYSQL_USERNAME}
password: ${MYSQL_PASSWORD}
server:
port: 8080
4.2.2 Secret:存储敏感配置
创建 app-secret.yaml,存储 MySQL 用户名与密码(需先将明文转换为 Base64 编码):
# 生成 Base64 编码(示例:用户名 root,密码 123456)
echo -n "root" | base64 # 输出:cm9vdA==
echo -n "123456" | base64 # 输出:MTIzNDU2
apiVersion: v1
kind: Secret
metadata:
name: app-secret
namespace: microservice
type: Opaque # 通用类型,存储任意敏感数据
data:
# MySQL 用户名(Base64 编码)
MYSQL_USERNAME: cm9vdA==
# MySQL 密码(Base64 编码)
MYSQL_PASSWORD: MTIzNDU2
4.2.3 MySQL:Deployment + Service + PVC
创建 mysql-deploy.yaml,包含 Deployment(部署 MySQL)、Service(暴露 MySQL 服务)、PVC(申请持久化存储):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: microservice
spec:
accessModes:
- ReadWriteOnce # 仅允许单节点读写
resources:
requests:
storage: 10Gi # 申请 10GB 存储
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
namespace: microservice
spec:
replicas: 1 # 副本数(MySQL 单节点,生产环境可使用主从架构)
selector:
matchLabels:
app: mysql # 匹配 Pod 标签
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: localhost:5000/mysql:v8.0-custom # 本地 Registry 镜像(生产环境替换为远程地址)
ports:
- containerPort: 3306
env:
# 从 Secret 注入敏感配置
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: MYSQL_PASSWORD
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: app-secret
key: MYSQL_USERNAME
# 从 ConfigMap 注入非敏感配置
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: app-config
key: MYSQL_DATABASE
# 挂载 PVC 实现数据持久化(挂载 MySQL 数据目录)
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumes:
- name: mysql-data
persistentVolumeClaim:
claimName: mysql-pvc # 关联 PVC
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
namespace: microservice
spec:
selector:
app: mysql # 匹配 MySQL Pod
ports:
- port: 3306 # Service 暴露端口
targetPort: 3306 # Pod 内部端口
clusterIP: None # Headless Service(无集群 IP,通过域名直接访问 Pod)
4.2.4 API 服务:Deployment + Service
创建 api-deploy.yaml,部署 Spring Boot API 服务并暴露网络:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deploy
namespace: microservice
spec:
replicas: 2 # 副本数 2,实现高可用
selector:
matchLabels:
app: api-service
strategy:
# 滚动更新策略(先启动新副本,再删除旧副本,实现平滑更新)
rollingUpdate:
maxSurge: 1 # 最大额外可启动的副本数
maxUnavailable: 0 # 最大不可用副本数(0 表示更新过程中服务不中断)
type: RollingUpdate
template:
metadata:
labels:
app: api-service
spec:
containers:
- name: api-service
image: localhost:5000/api-service:v1.0 # 本地 Registry 镜像
ports:
- containerPort: 8080
env:
# 从 Secret 注入 MySQL 用户名密码
- name: MYSQL_USERNAME
valueFrom:
secretKeyRef:
name: app-secret
key: MYSQL_USERNAME
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: MYSQL_PASSWORD
# 从 ConfigMap 注入 MySQL 地址
- name: MYSQL_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: MYSQL_HOST
# 挂载 ConfigMap 中的配置文件
volumeMounts:
- name: api-config
mountPath: /config # 对应 Dockerfile 中指定的配置目录
volumes:
- name: api-config
configMap:
name: app-config # 关联 ConfigMap
items:
- key: application.yml
path: application.yml # 挂载为 /config/application.yml
---
apiVersion: v1
kind: Service
metadata:
name: api-service
namespace: microservice
spec:
selector:
app: api-service
ports:
- port: 8080
targetPort: 8080
type: ClusterIP # 仅集群内部可访问(前端通过集群内部域名访问)
4.2.5 前端应用:Deployment + Service
创建 frontend-deploy.yaml,部署 Vue 前端应用:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend-deploy
namespace: microservice
spec:
replicas: 2
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: localhost:5000/vue-frontend:v1.0
ports:
- containerPort: 80
env:
# 从 ConfigMap 注入 API 服务地址
- name: VUE_APP_API_URL
valueFrom:
configMapKeyRef:
name: app-config
key: VUE_APP_API_URL
---
apiVersion: v1
kind: Service
metadata:
name: frontend-service
namespace: microservice
spec:
selector:
app: frontend
ports:
- port: 80
targetPort: 80
type: ClusterIP
4.3 YAML 核心字段解析
-
apiVersion:资源 API 版本(如 v1 为核心资源版本,apps/v1 为 Deployment 等应用资源版本); -
kind:资源类型(如 ConfigMap、Secret、Deployment、Service); -
metadata:资源元数据,包含name(资源名称)、namespace(命名空间,用于资源隔离); -
spec:资源规格,核心配置区域:-
Deployment 的
replicas:指定 Pod 副本数; -
Deployment 的
selector:通过标签匹配 Pod,用于管理 Pod 生命周期; -
Deployment 的
template:Pod 模板,定义 Pod 中容器的配置(镜像、端口、环境变量等); -
Service 的
type:服务暴露类型(ClusterIP 仅集群内部访问,NodePort 暴露节点端口,LoadBalancer 结合云服务负载均衡); -
PVC 的
accessModes:存储访问模式(ReadWriteOnce 单节点读写,ReadOnlyMany 多节点只读,ReadWriteMany 多节点读写)。
-
五、网络与存储配置:Ingress 与 PV/PVC 实战
本章节解决“外部访问集群应用”和“数据持久化”两大核心问题,详细说明 Ingress 控制器配置、PV/PVC 挂载机制及跨 Pod 通信原理。
5.1 跨 Pod 通信机制
K8s 集群内部 Pod 通信依赖网络插件(如 Flannel),核心原理:
-
网络插件为每个 Pod 分配唯一的集群内部 IP(Pod IP);
-
通过 Overlay 网络技术(如 VXLAN)实现跨节点 Pod 通信;
-
Service 通过标签选择器关联 Pod,实现 Pod 访问的负载均衡与服务发现(即使 Pod 重启 IP 变化,Service 地址保持不变)。
示例:前端 Pod 访问 API 服务,直接通过 Service 域名 api-service.microservice.svc.cluster.local:8080(格式:<Service 名称>.<命名空间>.svc.cluster.local),K8s 内置 DNS 组件(CoreDNS)会自动解析为 API 服务对应的 Pod IP。
5.2 持久化存储:PV 与 PVC 配置
PV(PersistentVolume)是集群级别的持久化存储资源,由管理员创建;PVC 是 Pod 对 PV 的申请,由开发者创建。两者通过存储类型、容量、访问模式匹配绑定。
5.2.1 创建 PV(管理员操作)
以本地存储为例,创建 mysql-pv.yaml:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 10Gi # 存储容量,需大于等于 PVC 申请容量
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain # 回收策略(Retain 保留,Recycle 回收,Delete 删除)
storageClassName: "" # 存储类名称,为空表示使用默认存储类
hostPath:
path: /data/mysql-pv # 本地存储路径(需在节点上创建)
type: DirectoryOrCreate
创建 PV 并验证:
# 在 Master 节点创建本地目录(多节点集群需在所有节点创建)
sudo mkdir -p /data/mysql-pv
sudo chmod 777 /data/mysql-pv
# 应用 PV 配置
kubectl apply -f mysql-pv.yaml
# 查看 PV 状态(STATUS 为 Available 表示可用)
kubectl get pv
5.2.2 PVC 与 PV 绑定(开发者操作)
前文 4.2.3 中已创建 MySQL 的 PVC(mysql-pvc),应用配置后,K8s 会自动匹配符合条件的 PV 并绑定:
# 查看 PVC 状态(STATUS 为 Bound 表示绑定成功)
kubectl get pvc -n microservice
5.3 外部访问:Ingress 控制器配置
Service 的 ClusterIP 仅集群内部可访问,NodePort 暴露端口过多难以管理,Ingress 作为集群入口,通过域名路由实现外部流量的统一管理。
5.3.1 安装 Ingress-NGINX 控制器
# 安装 Ingress-NGINX(适用于 K8s 1.28+)
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.5/deploy/static/provider/cloud/deploy.yaml
# 验证安装(Ingress 控制器 Pod 应处于 Running 状态)
kubectl get pods -n ingress-nginx
# 查看 Ingress 控制器 Service(获取外部访问 IP)
kubectl get svc -n ingress-nginx
5.3.2 配置 Ingress 规则
创建 app-ingress.yaml,通过域名 frontend.microservice.com 访问前端应用:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
namespace: microservice
annotations:
# 指定 Ingress 控制器(Ingress-NGINX)
kubernetes.io/ingress.class: "nginx"
# 启用 HTTPS 重定向(可选)
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
# 前端应用域名(需在本地 hosts 或 DNS 中解析到 Ingress 控制器外部 IP)
- host: frontend.microservice.com
http:
paths:
- path: /
pathType: Prefix # 路径匹配规则(前缀匹配)
backend:
service:
name: frontend-service # 关联前端 Service
port:
number: 80
应用 Ingress 配置并验证:
# 应用配置
kubectl apply -f app-ingress.yaml
# 查看 Ingress 状态(RULES 列显示域名路由规则)
kubectl get ingress -n microservice
# 本地 hosts 配置(Windows:C:\Windows\System32\drivers\etc\hosts;Linux:/etc/hosts)
192.168.1.100 frontend.microservice.com # 192.168.1.100 为 Ingress 控制器外部 IP
# 测试访问(浏览器访问 http://frontend.microservice.com)
curl http://frontend.microservice.com
六、部署与验证:全流程部署与服务校验
本章节按“命名空间→配置资源→存储→应用服务→Ingress”的顺序部署所有资源,并通过多种方式验证服务运行状态。
6.1 全流程部署步骤
# 1. 创建命名空间(隔离微服务资源)
kubectl create namespace microservice
# 2. 部署 ConfigMap 与 Secret
kubectl apply -f app-configmap.yaml
kubectl apply -f app-secret.yaml
# 3. 部署 PV 与 MySQL(包含 PVC)
kubectl apply -f mysql-pv.yaml
kubectl apply -f mysql-deploy.yaml
# 4. 部署 API 服务
kubectl apply -f api-deploy.yaml
# 5. 部署前端应用
kubectl apply -f frontend-deploy.yaml
# 6. 部署 Ingress 规则
kubectl apply -f app-ingress.yaml
# 查看所有资源状态(验证部署)
kubectl get all -n microservice
kubectl get configmap,secret -n microservice
kubectl get pv,pvc -n microservice
kubectl get ingress -n microservice
6.2 服务验证方法
6.2.1 查看 Pod 日志
# 查看 MySQL Pod 日志(验证启动状态)
kubectl logs -n microservice <mysql-pod-name>
# 查看 API 服务 Pod 日志(验证连接 MySQL 成功)
kubectl logs -n microservice <api-pod-name>
# 实时查看日志(添加 -f 参数)
kubectl logs -n microservice -f <api-pod-name>
6.2.2 端口转发(临时访问 Pod)
当 Ingress 未配置完成时,可通过端口转发直接访问 Pod:
# 转发 API 服务端口(本地 8080 端口映射到 Pod 8080 端口)
kubectl port-forward -n microservice <api-pod-name> 8080:8080
# 测试 API 接口(本地访问)
curl http://localhost:8080/api/health # 假设健康检查接口
# 转发前端应用端口
kubectl port-forward -n microservice <frontend-pod-name> 80:80
# 浏览器访问 http://localhost
6.2.3 健康探针验证
为 API 服务添加健康探针(修改 api-deploy.yaml 的 container 配置),K8s 会自动检测服务状态:
livenessProbe: # 存活探针(检测服务是否运行)
httpGet:
path: /api/health
port: 8080
initialDelaySeconds: 60 # 启动后延迟 60 秒开始检测
periodSeconds: 10 # 检测周期 10 秒
readinessProbe: # 就绪探针(检测服务是否可用)
httpGet:
path: /api/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
查看 Pod 探针状态:
kubectl describe pod -n microservice <api-pod-name> | grep -A 10 "Liveness"
kubectl describe pod -n microservice <api-pod-name> | grep -A 10 "Readiness"
6.2.4 外部访问验证
通过 Ingress 域名访问前端应用,验证前端能否正常调用 API 服务,API 服务能否正常连接 MySQL:
-
浏览器访问
http://frontend.microservice.com,查看前端页面是否正常加载; -
在前端页面执行数据查询、提交等操作,验证 API 服务与 MySQL 交互正常;
-
查看 API 服务日志,确认请求正常处理。
七、运维增强建议:Helm、监控与自动扩缩容
本章节介绍进阶运维实践,帮助开发者简化部署流程、实时监控服务状态、实现资源弹性伸缩。
7.1 使用 Helm 简化部署
Helm 是 K8s 包管理工具,将多个 YAML 资源打包为 Chart,实现“一键部署、版本管理、回滚”等功能。
7.1.1 安装 Helm
# 下载 Helm 二进制包(适用于 Linux amd64)
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
# 验证安装
helm version
7.1.2 创建 Helm Chart 并部署
# 1. 创建 Chart(命名为 microservice-chart)
helm create microservice-chart
# 2. 整理资源:将前文的 YAML 资源按类型放入 Chart 的 templates 目录
# 3. 配置动态参数:在 values.yaml 中定义可配置参数(如镜像地址、副本数、资源配额)
# 示例 values.yaml 片段:
# replicas: 2
# images:
# frontend: localhost:5000/vue-frontend:v1.0
# api: localhost:5000/api-service:v1.0
# mysql: localhost:5000/mysql:v8.0-custom
# 4. 部署 Chart
helm install microservice ./microservice-chart -n microservice --create-namespace
# 5. 查看部署状态
helm list -n microservice
# 6. 升级部署(修改参数后重新部署)
helm upgrade microservice ./microservice-chart -n microservice --set replicas=3
# 7. 回滚部署(回滚到上一版本)
helm rollback microservice 1 -n microservice
7.2 Prometheus + Grafana 监控
使用 Prometheus 采集 K8s 集群与应用 metrics,Grafana 可视化监控数据。
7.2.1 安装 Prometheus + Grafana
# 使用 Helm 安装 Prometheus 与 Grafana(官方 Chart)
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# 安装 Prometheus
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring --create-namespace
# 查看监控组件状态
kubectl get all -n monitoring
7.2.2 配置应用监控
为 API 服务添加 Prometheus 监控(Spring Boot 应用可通过 spring-boot-starter-actuator 暴露 metrics):
-
在 API 服务 pom.xml 中添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> -
在 application.yml 中配置暴露 metrics:
management: endpoints: web: exposure: include: prometheus,health,info metrics: tags: application: api-service -
在 K8s 中创建 ServiceMonitor(让 Prometheus 自动发现并采集 API 服务 metrics):
`apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: api-service-monitor
namespace: monitoring
labels:
release: prometheus
spec:
selector:
matchLabels:
app: api-service # 匹配 API 服务 Service 标签
namespaceSelector:
matchNames:- microservice # 监控 microservice 命名空间
endpoints:
- microservice # 监控 microservice 命名空间
- port: 8080
path: /actuator/prometheus
interval: 15s`
访问 Grafana:通过端口转发访问 Grafana 界面(默认用户名/密码:admin/prom-operator),导入 Spring Boot 监控模板(ID:12856),即可查看 API 服务的 JVM 状态、请求量、响应时间等指标。
7.3 自动扩缩容(HPA)
Horizontal Pod Autoscaler(HPA)根据 CPU 使用率、内存使用率或自定义指标(如请求量)自动调整 Pod 副本数,实现弹性伸缩。
7.3.1 创建 HPA 配置
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
namespace: microservice
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-deploy # 关联 API 服务 Deployment
minReplicas: 2 # 最小副本数
462

被折叠的 条评论
为什么被折叠?



