一、从单机容器迁移到 Deployment 的通用思路

迁移任意开源服务到 Kubernetes 时,最实用的路径通常只有三步:

  1. 先看镜像官方说明,搞清楚端口、启动参数、环境变量和数据目录
  2. 再把这些信息写进 Deployment 的 containers 配置
  3. 最后补齐 readiness、liveness、resources 和副本策略

也就是说,Kubernetes YAML 不是凭空写出来的,而是把镜像说明书“翻译”成声明式配置。

二、Vue 前端服务怎么部署

原始镜像可以先在 Docker 里验证:

docker run -d -p 10080:80 registry.cn-hangzhou.aliyuncs.com/abroad_images/vue:v1

迁移到 Kubernetes 时,重点是:

  • 使用 2 个副本做基础高可用
  • 对 80 端口配置 TCP 探针
  • 给前端容器补上合理的请求和限制

示例配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vue
spec:
  replicas: 2
  selector:
    matchLabels:
      app: vue
  template:
    metadata:
      labels:
        app: vue
    spec:
      containers:
      - name: vue
        image: registry.cn-hangzhou.aliyuncs.com/abroad_images/vue:v1
        imagePullPolicy: IfNotPresent
        livenessProbe:
          tcpSocket:
            port: 80
        readinessProbe:
          tcpSocket:
            port: 80
        resources:
          requests:
            cpu: "80m"
            memory: "100Mi"
          limits:
            cpu: "500m"
            memory: "1Gi"

三、Go 服务的重点在端口和环境变量

Go 服务往往更轻量,但也更容易因为环境变量和监听端口不一致而出现“镜像能跑,探针不通”的问题。原文示例里就给了 ENVPORT 等环境变量配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: go
spec:
  replicas: 2
  selector:
    matchLabels:
      app: go
  template:
    metadata:
      labels:
        app: go
    spec:
      containers:
      - name: go
        image: registry.cn-hangzhou.aliyuncs.com/abroad_images/go:v1
        env:
        - name: ENV
          value: test
        - name: PORT
          value: "8081"
        livenessProbe:
          tcpSocket:
            port: 8080
        readinessProbe:
          tcpSocket:
            port: 8080

这里最值得记住的不是字段本身,而是迁移时一定要核对三件事:

  • 程序真实监听的是哪个端口
  • 容器对外暴露的是哪个端口
  • 探针检查打到的是哪个端口

四、Java 服务迁移时,JVM 参数往往比 YAML 本身更关键

Java 服务上云原生最容易出问题的地方,不是 Deployment 语法,而是 JVM 默认配置过大、启动慢、环境变量不完整。

原文示例里重点配置了:

  • JAVA_TOOL_OPTIONS
  • SPRING_PROFILES_ACTIVE
  • SERVER_PORT
  • 更高的 CPU 和内存请求限制

示例片段:

env:
- name: SERVER_PORT
  value: "8080"
- name: JAVA_TOOL_OPTIONS
  value: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -Xms512m -Xmx512m -Xss256K -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF-8
- name: SPRING_PROFILES_ACTIVE
  value: test
resources:
  requests:
    cpu: "1"
    memory: "1Gi"
  limits:
    cpu: "2"
    memory: "2Gi"

如果 Java 服务启动较慢,还应该进一步评估是否需要 startupProbe,否则上线时非常容易被探针过早判死。

五、迁移开源服务时,先学会读 Docker Hub 说明书

原文用 Redis 做了一个通用示范。思路非常标准:

  • 去 Docker Hub 看官方镜像文档
  • 找端口、数据目录、参数和环境变量
  • 先按单副本部署,先跑通再谈高可用

Redis 的示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: registry.cn-hangzhou.aliyuncs.com/abroad_images/redis:7.2.5
        ports:
        - name: tcp-6379
          containerPort: 6379
        readinessProbe:
          tcpSocket:
            port: tcp-6379
        livenessProbe:
          tcpSocket:
            port: tcp-6379

验证时可以直接进容器:

kubectl exec -it redis-xxxx -- bash
redis-cli
set a 1
get a
save
ls /data

不过这里一定要记住:像 Redis 这种明显带状态的数据服务,单副本验证可以先用 Deployment,但真正走生产化时,更适合继续演进到 StatefulSet 加持久化存储。

把前端、Go、Java 和通用中间件的迁移模式看懂后,你会发现“上 K8s”不是换个地方跑镜像,而是把原本散落在镜像、命令、文档里的运行规则全部显式化。