在 Kubernetes 中部署和管理应用程序:完整指南

        

目录

一、前置准备:应用容器化

1. 编写 Dockerfile

2. 构建并推送镜像

二、基础部署:通过资源清单定义应用

1. 部署无状态应用(Deployment)

2. 配置应用参数(ConfigMap/Secret)

3. 暴露服务(Service/Ingress)

(1)Service:基础网络暴露

(2)Ingress:HTTP/HTTPS 路由(推荐)

4. 执行部署

三、应用管理:扩缩容、更新与回滚

1. 扩缩容

(1)手动扩缩容

(2)自动扩缩容(HPA)

2. 应用更新

(1)滚动更新(默认)

(2)查看更新状态

3. 版本回滚

四、数据持久化(有状态应用)

1. 创建 PV(集群存储资源)

2. 创建 PVC(Pod 存储申请)

3. 部署 StatefulSet(MySQL 示例)

五、监控与运维

1. 日志管理

2. 容器调试

3. 监控指标

六、最佳实践

总结


         在 Kubernetes(K8s)中部署和管理应用程序需遵循 “声明式定义、自动化运维” 的核心思路,从应用打包部署发布,再到监控运维形成完整闭环。以下是分阶段的实践指南,涵盖核心流程、关键操作与最佳实践。

一、前置准备:应用容器化

K8s 仅运行容器化应用,需先通过 Docker 等工具将应用打包为符合 OCI 标准的容器镜像,并推送到镜像仓库(如 Docker Hub、Harbor)。

1. 编写 Dockerfile

以 Java Spring Boot 应用为例,创建Dockerfile

dockerfile

# 构建阶段(多阶段构建减小镜像体积)
FROM maven:3.8-openjdk-17 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

# 运行阶段
FROM openjdk:17-slim
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

2. 构建并推送镜像

bash

运行

# 构建镜像(格式:仓库地址/用户名/镜像名:版本)
docker build -t myusername/springboot-app:v1 .

# 推送到镜像仓库(需先登录)
docker login
docker push myusername/springboot-app:v1

二、基础部署:通过资源清单定义应用

K8s 通过YAML 资源清单声明应用的期望状态(如副本数、镜像版本、端口),核心资源包括Deployment(无状态应用)、StatefulSet(有状态应用)、Service(服务暴露)等。

1. 部署无状态应用(Deployment)

Deployment是最常用的部署方式,支持滚动更新、扩缩容、自愈等能力。创建app-deployment.yaml

yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: springboot-app  # 部署名称
  namespace: default    # 命名空间(默认default)
spec:
  replicas: 3  # 期望的Pod副本数
  selector:
    matchLabels:
      app: springboot-app  # 匹配Pod标签
  strategy:
    type: RollingUpdate  # 滚动更新策略(默认)
    rollingUpdate:
      maxSurge: 1        # 最多超出1个副本
      maxUnavailable: 0  # 更新过程中不可用副本数为0
  template:
    metadata:
      labels:
        app: springboot-app  # Pod标签
    spec:
      containers:
      - name: app-container
        image: myusername/springboot-app:v1  # 容器镜像地址
        ports:
        - containerPort: 8080  # 容器内端口
        resources:
          requests:  # 资源请求(调度依据)
            cpu: 100m
            memory: 256Mi
          limits:    # 资源限制(最大使用量)
            cpu: 500m
            memory: 512Mi
        livenessProbe:  # 存活探针(检测容器是否存活)
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 30  # 启动后30秒开始检测
          periodSeconds: 10        # 每10秒检测一次
        readinessProbe: # 就绪探针(检测容器是否就绪接收流量)
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 20
          periodSeconds: 5
        env:  # 环境变量
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: app-config  # 从ConfigMap获取配置
              key: db_host

2. 配置应用参数(ConfigMap/Secret)

  • ConfigMap:存储非敏感配置(如数据库地址、端口):

    bash

    运行

    # 创建ConfigMap(从字面量)
    kubectl create configmap app-config \
      --from-literal=db_host=mysql-service \
      --from-literal=db_port=3306
    
    # 或从文件创建
    kubectl create configmap app-config --from-file=application.properties
    
  • Secret:存储敏感数据(如密码、Token):

    bash

    运行

    # 创建Secret(从字面量)
    kubectl create secret generic app-secret \
      --from-literal=db_username=root \
      --from-literal=db_password=123456
    

在 Deployment 中引用 Secret:

yaml

env:
- name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: app-secret
      key: db_password

3. 暴露服务(Service/Ingress)

Pod 的 IP 是动态的,需通过ServiceIngress提供稳定访问入口。

(1)Service:基础网络暴露

创建app-service.yaml

yaml

apiVersion: v1
kind: Service
metadata:
  name: springboot-service
spec:
  type: NodePort  # 节点端口类型(集群外可访问)
  selector:
    app: springboot-app  # 关联Pod标签
  ports:
  - port: 8080          # Service端口
    targetPort: 8080    # Pod端口
    nodePort: 30080     # 节点端口(范围30000-32767)
(2)Ingress:HTTP/HTTPS 路由(推荐)

需先部署 Ingress 控制器(如 Nginx Ingress),再创建 Ingress 资源:

yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /  # 重写规则
spec:
  ingressClassName: nginx  # 指定Ingress控制器
  rules:
  - host: app.example.com  # 域名
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: springboot-service
            port:
              number: 8080

4. 执行部署

bash

运行

# 应用Deployment配置
kubectl apply -f app-deployment.yaml

# 应用Service配置
kubectl apply -f app-service.yaml

# 应用Ingress配置(若有)
kubectl apply -f app-ingress.yaml

# 查看部署状态
kubectl get deployments
kubectl get pods
kubectl get services
kubectl get ingress

三、应用管理:扩缩容、更新与回滚

1. 扩缩容

(1)手动扩缩容

bash

运行

# 调整Deployment副本数
kubectl scale deployment springboot-app --replicas=5

# 或编辑Deployment配置
kubectl edit deployment springboot-app
(2)自动扩缩容(HPA)

基于 CPU 使用率或自定义指标自动调整副本数:

bash

运行

# 创建HPA(CPU使用率≥50%时扩容,最多10副本,最少2副本)
kubectl autoscale deployment springboot-app \
  --min=2 --max=10 --cpu-percent=50

# 查看HPA状态
kubectl get hpa

2. 应用更新

(1)滚动更新(默认)

更新镜像版本,K8s 会逐步替换旧 Pod,保证服务不中断:

bash

运行

# 直接更新镜像
kubectl set image deployment/springboot-app app-container=myusername/springboot-app:v2

# 或编辑Deployment(修改image字段)
kubectl edit deployment springboot-app
(2)查看更新状态

bash

运行

kubectl rollout status deployment/springboot-app
kubectl get pods  # 观察新旧Pod替换过程

3. 版本回滚

若更新后出现问题,可回滚到上一版本:

bash

运行

# 查看更新历史
kubectl rollout history deployment/springboot-app

# 回滚到上一版本
kubectl rollout undo deployment/springboot-app

# 回滚到指定版本(--to-revision指定版本号)
kubectl rollout undo deployment/springboot-app --to-revision=1

四、数据持久化(有状态应用)

对于数据库、缓存等有状态应用,需使用StatefulSetPersistentVolume(PV)/PersistentVolumeClaim(PVC)保证数据持久化。

1. 创建 PV(集群存储资源)

yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce  # 单节点读写
  persistentVolumeReclaimPolicy: Retain  # 回收策略(保留数据)
  storageClassName: standard
  hostPath:  # 本地存储(生产环境推荐云存储/NFS)
    path: /data/mysql-pv

2. 创建 PVC(Pod 存储申请)

yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard

3. 部署 StatefulSet(MySQL 示例)

yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql-service  # 关联Headless Service
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: root_password
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql  # 挂载存储到数据目录
  volumeClaimTemplates:  # 自动创建PVC(无需手动创建)
  - metadata:
      name: mysql-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi

五、监控与运维

1. 日志管理

bash

运行

# 查看Pod日志
kubectl logs <pod-name>

# 实时查看日志
kubectl logs -f <pod-name>

# 查看容器日志(多容器Pod)
kubectl logs <pod-name> -c <container-name>

2. 容器调试

bash

运行

# 进入Pod容器
kubectl exec -it <pod-name> -- /bin/bash

# 查看Pod详情(排查故障)
kubectl describe pod <pod-name>

3. 监控指标

集成 Prometheus+Grafana 监控集群和应用指标:

  • 部署 Prometheus Operator 采集指标。
  • 通过ServiceMonitor配置应用监控(需应用暴露 metrics 接口)。
  • Grafana 导入 Dashboard 可视化指标(如 Pod CPU / 内存使用率、应用 QPS)。

六、最佳实践

  1. 使用命名空间隔离环境:为开发、测试、生产环境创建独立命名空间(如devtestprod)。
  2. 设置资源限制:避免单个应用占用过多集群资源,导致其他应用饥饿。
  3. 配置健康探针:通过livenessProbereadinessProbe确保容器异常时自动重启、未就绪时不接收流量。
  4. 镜像版本使用固定标签:避免使用latest标签,防止部署不可控。
  5. 使用 Helm 简化部署:通过 Helm Chart 打包应用资源,实现一键部署、版本管理。
  6. 启用 RBAC 权限控制:限制 Pod 和用户的权限,提升集群安全性。

总结

Kubernetes 部署和管理应用的核心是 “声明式 API + 控制器模式”:通过 YAML 定义应用期望状态,K8s 控制器自动将实际状态调整为期望状态。从容器化打包到部署发布,再到扩缩容、监控运维,需结合DeploymentServiceConfigMap等资源,遵循云原生最佳实践,确保应用高可用、可扩展。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值