4. Kubernetes基础:核心概念与集群架构

说实话,Kubernetes 刚出来那会儿,我第一反应是「这玩意儿也太复杂了吧?」但真正用起来之后,你会发现它的设计其实很优雅。今天咱们就聊聊 K8s 里最核心的几个概念,以及怎么跟它打交道。

4.1 Pod:最小的调度单元

Pod 是 K8s 里你能创建和部署的最小单位。说白了,就是一个或多个容器的「合租屋」。这些容器共享网络、存储,还有生命周期。

我记得刚带团队时,有个同事非要把一个应用拆成三个独立的 Pod,结果网络通信搞得一团糟。我告诉他:「你想想看,如果两个进程需要频繁通信,或者共享同一个数据卷,把它们放在一个 Pod 里不香吗?」

核心要点:
  • 一个 Pod 可以包含一个或多个容器
  • Pod 内的容器共享 IP 和端口空间
  • Pod 是临时性的,随时可能被销毁重建

举个实际例子。我做过一个日志采集项目,业务容器和日志采集容器就放在同一个 Pod 里。它们通过 localhost 通信,共享一个 emptyDir 卷。这样业务容器只管写日志,采集容器只管转发,互不干扰。

4.2 Service:稳定的访问入口

Pod 是会「漂移」的。今天这个 Pod 在 Node A 上,明天可能就跑到 Node B 上去了。那客户端怎么找到它?这就是 Service 要解决的问题。

Service 说白了就是一个稳定的虚拟 IP + 端口映射。它背后通过标签选择器(Label Selector)动态关联一组 Pod。我习惯把 Service 理解为「永不掉线的电话总机」——不管接线员(Pod)怎么换,你拨总机号码总能找到人。

我的经验: 刚开始用 Service 时,我总忘记给 Pod 打标签。结果 Service 选不到 Pod,流量全丢了。后来我养成了习惯:创建 Deployment 之前,先把标签规划好。

Service 有几种类型,我列个表方便你对比:

类型 访问方式 适用场景
ClusterIP 集群内部 IP 内部服务间调用
NodePort 节点 IP + 固定端口 外部简单访问
LoadBalancer 云厂商负载均衡器 生产环境对外暴露

4.3 Deployment:声明式应用管理

Deployment 是我用得最多的资源对象。它负责管理 Pod 的「生老病死」——创建、更新、扩缩容、回滚。

你想想看,如果让你手动管理几百个 Pod,那不得疯掉?Deployment 就是帮你做这件事的。你只需要告诉它「我要跑 3 个副本,镜像版本是 v2.0」,剩下的它自己搞定。

我曾经在生产环境遇到过一个问题:更新 Deployment 时,新 Pod 一直起不来,旧 Pod 又被删掉了,导致服务中断了几分钟。后来我查了半天,发现是健康检查配置写错了。嗯,这里要注意:一定要配置 readinessProbe 和 livenessProbe,否则滚动更新就是「盲人摸象」。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: my-app:v2.0
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
避坑指南: 我曾经因为忘记设置 resource requests/limits,导致某个 Pod 把节点内存吃光,整个节点上的 Pod 全挂了。从那以后,我每个 Deployment 都会加上资源限制。

4.4 Namespace:逻辑隔离的艺术

Namespace 就是 K8s 里的「虚拟集群」。同一个物理集群里,你可以划分出多个 Namespace,每个 Namespace 里的资源是相互隔离的。

我习惯这样划分:

  • dev:开发环境,随便折腾
  • test:测试环境,跑自动化测试
  • prod:生产环境,严格管控

这样做的好处很明显:开发同学在 dev 里搞坏了什么东西,不会影响到生产。而且每个 Namespace 可以单独设置资源配额(ResourceQuota),防止某个团队「吃独食」。

4.5 kubectl:你的瑞士军刀

kubectl 是跟 K8s 集群交互的主要工具。我每天至少要用几十次。下面这些命令是我最常用的:

# 查看所有 Pod
kubectl get pods -n my-namespace

# 查看 Pod 详细信息
kubectl describe pod my-pod -n my-namespace

# 查看 Pod 日志
kubectl logs -f my-pod -n my-namespace

# 进入 Pod 内部
kubectl exec -it my-pod -- /bin/sh

# 查看所有资源
kubectl get all -n my-namespace

# 应用 YAML 文件
kubectl apply -f deployment.yaml

# 删除资源
kubectl delete pod my-pod -n my-namespace
小技巧: 我习惯给 kubectl 设置别名:alias k='kubectl'。再配合 --all-namespaces 参数,排查问题快很多。

4.6 集群架构:从宏观到微观

K8s 集群分两部分:控制平面(Control Plane)和工作节点(Worker Node)。

控制平面是集群的「大脑」,负责决策和调度。它包含:

  • kube-apiserver:所有操作的入口,相当于「门卫」
  • kube-scheduler:决定 Pod 跑在哪个节点上,相当于「调度员」
  • kube-controller-manager:管理各种控制器,相当于「监工」
  • etcd:存储集群状态,相当于「档案室」

工作节点是真正跑应用的地方:

  • kubelet:节点上的「代理人」,跟 apiserver 通信
  • kube-proxy:负责网络代理和负载均衡
  • 容器运行时:比如 Docker、containerd

我记得刚开始学 K8s 时,总觉得这些组件之间的关系很绕。后来我画了一张图:用户通过 kubectl 发请求给 apiserver,apiserver 把请求存到 etcd,scheduler 监听到新的 Pod 请求就分配节点,然后该节点上的 kubelet 负责拉起容器。这么一想,其实流程很清晰。

一句话总结: K8s 的核心思想就是「声明式管理」。你告诉它你想要什么状态,它自己想办法达到那个状态。你不需要关心具体怎么实现,只需要关注你的应用本身。

好了,这一章的内容就到这里。下一章我们会聊聊如何把现有的应用迁移到 K8s 上,包括容器化改造、配置管理、存储挂载这些实战内容。到时候我会分享一些我在迁移过程中踩过的坑,保证让你少走弯路。