前言:作为后端工程师,K8S 不需要学得特别深。现在有 Codex 这类 AI 工具帮忙,很多命令可以让 AI 辅助执行,没必要死记每一条命令;但基本概念必须有。至少要知道:K8S 是什么;怎么使用已经部署好的 K8S,比如查看节点和 Pod、发布新的镜像版本、确认 Java 配置文件放在哪里、持久化目录挂到哪里;怎么调整已有服务的暴露方式,比如个别服务需要通过节点端口,也就是 NodePort 访问;怎么通过 YAML 部署一个服务,以及 YAML 大概怎么看;Rancher、Kuboard 和 K8S 到底是什么关系。

本文属于概念扫盲文,细节知识可以问AI,另外,对于后端,自己要部署K8S环境时,了解这些概念后,可以指导Codex进行部署,注意不要在生产环境干,可能会干崩原先的环境,此外非常费Token。

看完本文,重点知道这些内容:

  • K8S 是什么,和 Docker 有什么区别?
  • K8S 最基本的概念有哪些?
  • Rancher、Kuboard 这类可视化界面是什么?
  • 工作中一般怎么用 K8S?
  • K8S 环境一般怎么部署?
  • K8S 常用操作命令有哪些?

K8S 是什么

Docker 更偏向于“在一台机器上把容器跑起来”。K8S,也就是 Kubernetes,更偏向于“管理一批机器上的大量容器”。

如果服务都靠每台机器手动 docker run,会有很多问题:服务挂了谁来重启?机器资源怎么分配?新版本怎么平滑发布?服务之间怎么互相访问?K8S 主要就是解决这些问题。

能力 说明
部署 把 Java 服务镜像拉起来
调度 决定服务跑在哪台服务器上
自愈 Pod 或容器异常后自动拉起
扩缩容 让 1 个实例变成 3 个、5 个、10 个
服务发现 服务之间用名字访问,不用写死 IP
滚动发布 新版本逐步替换旧版本
配置管理 环境变量、配置文件、密钥统一管理
存储挂载 给 MySQL、MongoDB、ClickHouse 等组件挂载数据目录

一句话:K8S 是一个容器编排平台,负责让一组容器按你期望的状态运行。

K8S 最基本的概念

后端工程师先记住下面这些就够用了。

概念 说明
Pod K8S 最小调度单位。真正的容器运行在 Pod 里面,一个 Pod 里可以有一个或多个容器。
Deployment 管理 Pod 副本数、滚动发布、回滚等。平时部署 Java 服务最常接触它。
Service 给一组 Pod 提供稳定访问入口。Service 通过 selector 找到 Pod,不直接绑定某个 Pod IP。
Ingress 管理 HTTP/HTTPS 入口规则,把外部请求转发到内部 Service。它需要 Ingress Controller 才能真正生效。
ConfigMap 存放非敏感配置,比如环境变量、普通配置文件内容。
Secret 存放密码、Token、证书等敏感信息。注意 Secret 默认只是 base64 编码,不等于天然加密。
PV PersistentVolume,集群里的持久化存储资源,比如 NFS、云盘、块存储。
PVC PersistentVolumeClaim,Pod 对存储资源的申请。Pod 通常挂载 PVC,而不是直接关心 PV 是什么实现。
Namespace 命名空间,用来隔离不同项目、环境或团队的资源。

几个容易混的点:

  • Pod 不是容器本身,而是容器的运行环境。
  • Deployment 不直接“暴露服务”,它主要负责创建和维护 Pod。
  • Service 负责让 Pod 有稳定入口,因为 Pod IP 会变。
  • ClusterIP 是集群内部访问,NodePort 是通过节点端口暴露,LoadBalancer 通常依赖云厂商负载均衡。
  • ConfigMap 不适合放密码,敏感信息应该放 Secret 或公司的密钥管理系统。

Deployment、Service、Ingress 的关系可以先这样理解:

外部用户
    |
    v
Ingress Controller
    |
    v
Ingress 规则
    |
    v
Service
    |
    +------------+------------+
    |                         |
    v                         v
  Pod-1                     Pod-2
    ^                         ^
    |                         |
    +------ Deployment -------+

配置和存储的关系可以这样理解:

Deployment
    |
    v
Pod
    |
    +--> 使用 ConfigMap / Secret 作为环境变量或配置文件
    |
    +--> 挂载 PVC
             |
             v
             PV
             |
             v
        NFS / 云盘 / 本地磁盘等实际存储

Pod的持久化,需要先绑定PVC,然后PVC根据storageClassName、accessModes、volumeMode、label selector、容量等多条件综合匹配 到对应的PV。
这样设计是为了将Pod和实际的PV解耦,因为实际PV可以有多种实现,可以是本地储存,也可以是NFS或者其他的,具体怎么存,Pod不需要知道。
PVC 绑定 PV 时,会根据 storageClassName、容量、访问模式、标签等条件匹配。很多集群还会通过 StorageClass 动态创建 PV,这样开发只需要申请 PVC,不需要手动创建底层存储。

Rancher 和 Kuboard 是什么

Rancher 和 Kuboard 都是 K8S 的可视化管理平台。它们不是另一套 K8S,本质上还是在调用 K8S API。

常见功能包括:

  • 查看 Pod、Deployment、Service、Ingress
  • 查看日志和事件
  • 重启服务
  • 修改镜像版本
  • 修改副本数
  • 查看和编辑 YAML
  • 进入容器终端
  • 管理 Namespace
  • 管理 ConfigMap、Secret、PVC

以“重启服务”为例:

你在 Rancher/Kuboard 页面点击重启
    |
    v
平台调用 K8S API
    |
    v
K8S 更新 Deployment
    |
    v
Deployment 创建新的 Pod,旧 Pod 退出

它们和 kubectl 的区别:

工具 本质 适合谁
kubectl 命令行工具 后端、运维、平台工程师
Rancher 企业级 K8S 管理平台 运维团队、平台团队
Kuboard 轻量级 K8S 可视化平台 开发、运维、中小团队

核心原理都是调用 K8S API 创建或修改资源,只是一个用命令行,一个用页面。

工作中一般怎么用 K8S

后端工程师日常最常见的是下面这些操作:

  1. 找到自己的 Namespace。
  2. 找到自己的 Deployment。
  3. 看 Pod 是否 Running。
  4. 看 Pod 日志。
  5. 看事件 Events,排查为什么启动失败。
  6. 重启 Deployment。
  7. 修改镜像版本。
  8. 查看 Service 暴露端口。
  9. 查看 ConfigMap、Secret 配置是否正确。
  10. 查看 PVC 是否绑定成功。

排查问题时可以按这个顺序看:

Deployment 是否存在
    -> ReplicaSet 是否创建
    -> Pod 是否 Running
    -> Pod 日志是否报错
    -> Pod Events 是否有拉镜像失败、调度失败、健康检查失败
    -> Service selector 是否能选中 Pod
    -> Ingress 规则和域名是否正确

K8S 环境怎么部署

K8S 一般用 YAML 部署。核心思想是:用 YAML 描述“我希望集群变成什么样”,K8S 负责把实际状态调整成你描述的状态。

后端工程师不用背完整 YAML 字段,先看懂几个最常改的地方就行:

  • metadata.name:资源名字,比如服务名。
  • metadata.namespace:资源放在哪个命名空间。
  • spec.replicas:服务要跑几个副本。
  • containers.image:部署哪个镜像版本。
  • env / envFrom:Java 启动参数和配置从哪里来。
  • ports:容器内部监听端口。
  • readinessProbe / livenessProbe:健康检查接口。
  • volumeMounts / volumes:容器内目录挂到哪里,是否需要持久化。
  • Service.spec.type:服务怎么暴露,常见是 ClusterIPNodePort
  • Ingress.rules.host:HTTP/HTTPS 对外访问的域名。

实际工作里经常会从已有环境导出 YAML,先参考当前配置:

# 导出已有 Deployment,方便参考当前配置。
kubectl get deployment demo-backend -n demo -o yaml > deployment.yaml

但是导出的 YAML 里会包含很多运行时字段,比如 uidresourceVersionmanagedFieldsstatuscreationTimestamp。这些字段一般不需要手动维护,整理部署模板时可以删掉。

下面这份 YAML 重点看注释里的“常改”位置。

apiVersion: apps/v1
kind: Deployment
metadata:
  # 常改:服务名,kubectl 和 Rancher/Kuboard 里都会看到它。
  name: demo-backend
  # 常改:命名空间,区分不同项目或环境。
  namespace: demo
  labels:
    # 重要:Service 会用这个标签找到对应的 Pod。
    app: demo-backend
spec:
  # 常改:副本数,1 表示跑一个 Pod,3 表示跑三个 Pod。
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      # 重要:这里必须和 template.metadata.labels 对上。
      app: demo-backend
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        # 重要:Pod 的标签,Service selector 靠它匹配 Pod。
        app: demo-backend
    spec:
      imagePullSecrets:
        # 常改:拉私有镜像仓库时用的 Secret。
        - name: aliyun-registry
      containers:
        - name: demo-backend
          # 最常改:镜像地址和版本号,发版通常就是改这里。
          image: registry.example.com/demo-backend:202605232328
          imagePullPolicy: IfNotPresent
          ports:
            # 常改:容器内部监听端口,要和 Java 服务实际端口一致。
            - name: http
              containerPort: 9700
              protocol: TCP
          env:
            - name: JAVA_TOOL_OPTIONS
              # 常改:Java JVM 参数,例如容器内存比例、OOM 后退出等。
              value: >-
                -XX:+UseContainerSupport
                -XX:MaxRAMPercentage=60.0
                -XX:+ExitOnOutOfMemoryError
          envFrom:
            # 常改:普通配置放 ConfigMap,例如 Spring Profile、业务开关等。
            - configMapRef:
                name: demo-app-env
          resources:
            # 常改:资源请求和限制,别直接照抄生产配置。
            requests:
              memory: 1500Mi
            limits:
              memory: 1800Mi
          readinessProbe:
            # 常改:就绪检查路径。失败时,Service 不会把流量转发给这个 Pod。
            httpGet:
              path: /actuator/health/readiness
              port: http
            initialDelaySeconds: 20
            periodSeconds: 10
          livenessProbe:
            # 常改:存活检查路径。持续失败时,K8S 会重启容器。
            httpGet:
              path: /actuator/health/liveness
              port: http
            initialDelaySeconds: 60
            periodSeconds: 20
          volumeMounts:
            # 常改:容器内目录。Java 服务写到 /data/app 的文件会进入下面的 PVC。
            - name: app-data
              mountPath: /data/app
      volumes:
        - name: app-data
          # 常改:持久化存储。claimName 对应下面的 PVC 名字。
          persistentVolumeClaim:
            claimName: demo-backend-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  # 常改:PVC 名字,要和上面 volumes.persistentVolumeClaim.claimName 一致。
  name: demo-backend-data
  namespace: demo
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      # 常改:申请的磁盘大小。
      storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
  # 常改:Service 名字,集群内服务之间可以用这个名字访问。
  name: demo-backend
  namespace: demo
spec:
  # 常改:ClusterIP 只在集群内访问;需要通过节点端口访问时可改成 NodePort。
  type: ClusterIP
  selector:
    # 这里必须和 Deployment template.metadata.labels 对上。
    app: demo-backend
  ports:
    - name: http
      # Service 暴露的端口,集群内访问 demo-backend:9700。
      port: 9700
      # 转发到容器端口,这里用上面 ports.name=http。
      targetPort: http
      protocol: TCP
      # 如果 type 改成 NodePort,可以增加 nodePort,例如 30080。
      # nodePort: 30080

如果服务需要通过 HTTP/HTTPS 对外访问,可以再配 Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-backend
  namespace: demo
spec:
  # 常改:这里以 nginx ingress controller 为例,具体值看集群安装情况。
  ingressClassName: nginx
  rules:
    # 常改:对外访问域名。
    - host: demo.example.com
      http:
        paths:
          # 常改:路径匹配规则,/ 表示这个域名下全部请求都转给后端服务。
          - path: /
            pathType: Prefix
            backend:
              service:
                # 重要:这里指向上面的 Service 名字。
                name: demo-backend
                port:
                  # 重要:这里是 Service 的 port,不是 containerPort。
                  number: 9700

读 YAML 时可以先抓住三条线:

  1. Deployment 看镜像、副本数、Java 配置、健康检查、挂载目录。
  2. Service 看服务名、端口、selector,以及是否需要 NodePort
  3. Ingress 看域名、路径,以及转发到哪个 Service。

K8S 常用操作命令

下面这些命令基本能覆盖后端日常排查(偶尔用)。后端正常都是通过Rancher和Kuboard来管理K8S集群的。

# 看当前连的是哪个集群,避免操作错环境。
kubectl config current-context

# 查看命名空间。
kubectl get namespace

# 查看常见资源。
kubectl get deployment -n demo
kubectl get pod -n demo -o wide
kubectl get service -n demo
kubectl get ingress -n demo
kubectl get configmap -n demo
kubectl get secret -n demo
kubectl get pvc -n demo

# 查看 Pod 详情和事件,启动失败时很常用。
kubectl describe pod <pod-name> -n demo

# 查看日志。Deployment 写法适合只有一个主容器的服务。
kubectl logs -f deployment/demo-backend -n demo --tail=200

# 如果一个 Pod 里有多个容器,需要指定容器名。
kubectl logs -f <pod-name> -c <container-name> -n demo --tail=200

# 进入容器排查问题。
kubectl exec -it <pod-name> -n demo -- /bin/sh

# 应用 YAML。
kubectl apply -f k8s.yaml

# 查看发布进度。
kubectl rollout status deployment/demo-backend -n demo

# 重启 Deployment,常用于重新加载配置或排查偶发问题。
kubectl rollout restart deployment/demo-backend -n demo

# 修改镜像版本。
kubectl set image deployment/demo-backend \
  demo-backend=registry.example.com/demo-backend:202605232328 \
  -n demo

# 回滚到上一个版本。
kubectl rollout undo deployment/demo-backend -n demo

# 扩缩容。
kubectl scale deployment/demo-backend --replicas=3 -n demo

# 本地临时访问集群内服务,适合调试。
kubectl port-forward service/demo-backend 9700:9700 -n demo

最后总结

后端工程师理解 K8S,可以先抓住这条主线:

Deployment 负责让服务跑起来,并维持指定副本数。
Service 负责给 Pod 一个稳定访问入口。
Ingress 负责把外部 HTTP/HTTPS 请求转进集群。
ConfigMap 和 Secret 负责配置。
PVC/PV 负责持久化存储。
kubectl、Rancher、Kuboard 都是在调用 K8S API 管理这些资源。

日常工作里,最重要的是会看状态、看日志、看事件、改镜像版本、重启 Deployment,以及知道 YAML 里哪些字段能改、哪些字段只是 K8S 自动生成的运行时信息。

更多推荐