前言:作为后端工程师,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 最基本的概念

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

概念说明
PodK8S 最小调度单位。真正的容器运行在 Pod 里面,一个 Pod 里可以有一个或多个容器。
Deployment管理 Pod 副本数、滚动发布、回滚等。平时部署 Java 服务最常接触它。
Service给一组 Pod 提供稳定访问入口。Service 通过 selector 找到 Pod,不直接绑定某个 Pod IP。
Ingress管理 HTTP/HTTPS 入口规则,把外部请求转发到内部 Service。它需要 Ingress Controller 才能真正生效。
ConfigMap存放非敏感配置,比如环境变量、普通配置文件内容。
Secret存放密码、Token、证书等敏感信息。注意 Secret 默认只是 base64 编码,不等于天然加密。
PVPersistentVolume,集群里的持久化存储资源,比如 NFS、云盘、块存储。
PVCPersistentVolumeClaim,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:服务怎么暴露,常见是 ClusterIP、NodePort。
  • Ingress.rules.host:HTTP/HTTPS 对外访问的域名。

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

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

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

下面这份 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 自动生成的运行时信息。

更多推荐