3. Kubernetes核心概念:Pod、Service、Deployment、Namespace、ConfigMap与Secret

好,咱们今天聊聊Kubernetes里最核心的几个概念。说实话,我刚接触K8s那会儿,也被这些名词搞得晕头转向。Pod是什么?Service又是干嘛的?Deployment和Pod有啥关系?

别急,我一个一个给你拆开讲。这些都是你日常运维中天天要打交道的对象,搞懂了它们,K8s就算入门了。

3.1 Pod:最小的调度单元

Pod是Kubernetes里你能创建和管理的最小计算单元。你可以把它理解成一组容器的"共享运行环境"。

核心要点:Pod里的所有容器共享同一个网络命名空间、存储卷和IP地址。它们可以通过localhost互相通信。

我遇到过不少新手问:"为什么不能直接跑容器,非要套一层Pod?" 嗯,这个问题问得好。你想想看,有时候两个进程需要紧密协作——比如一个日志收集器和一个业务容器,它们需要共享存储、共享网络。Pod就是为这种场景设计的。

来看一个最简单的Pod定义:

apiVersion: v1
kind: Pod
metadata:
  name: my-nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.21
    ports:
    - containerPort: 80

我个人习惯把Pod看作"逻辑主机"。它里面的容器就像这台主机上的进程,共享资源,协同工作。

避坑指南:我曾经在生产环境里把多个业务容器塞进同一个Pod,结果发现扩缩容非常痛苦。记住,Pod里的容器应该是一荣俱荣、一损俱损的关系。如果它们可以独立扩缩,那就应该拆成不同的Pod。

3.2 Deployment:声明式应用管理

Deployment说白了就是Pod的管理器。你告诉它"我要跑3个nginx副本",它就会帮你创建3个Pod,并且保证一直有3个在运行。

为什么需要Deployment?直接创建Pod不行吗?行,但你会很痛苦。Pod挂了不会自动恢复,更新版本要手动删了重建,扩缩容更是噩梦。

Deployment解决了这些问题:

  • 自愈能力:Pod挂了自动重建
  • 滚动更新:零停机更新应用版本
  • 回滚:更新出问题一键回退
  • 扩缩容:调整副本数就像改个数字

看个例子:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80

我记得有一次线上事故,就是因为有人直接操作Pod,没有用Deployment。那个Pod被节点驱逐后,业务直接挂了半小时。从那以后,我定了个规矩:任何工作负载都必须通过Deployment管理,没有例外。

3.3 Service:稳定的网络入口

Pod是"朝生暮死"的。今天叫nginx-abc123,明天重启后就变成nginx-def456了。IP地址也会变。那问题来了——客户端怎么找到它?

Service就是来解决这个问题的。它提供了一组Pod的稳定访问入口,不管Pod怎么变,Service的IP和端口不变。

Service有几种类型:

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

我个人最常用的是ClusterIP,内部服务通信用它就够了。对外暴露的话,我建议用Ingress,而不是直接开NodePort。

注意:我曾经见过有人把Service的端口和Pod的端口搞混。记住,Service的port是服务端口,targetPort才是Pod里容器监听的端口。这两个可以不一样。

3.4 Namespace:逻辑隔离的利器

Namespace就是K8s里的"虚拟集群"。同一个物理集群里,可以用Namespace把不同环境、不同团队、不同项目隔离开。

我习惯这样划分Namespace:

  • production:生产环境
  • staging:预发布环境
  • development:开发环境
  • 每个团队一个:team-aiteam-billing

Namespace的好处很明显:

  • 资源隔离:可以给每个Namespace设置资源配额
  • 权限控制:RBAC可以精确到Namespace级别
  • 网络策略:可以控制Namespace之间的流量

嗯,这里要注意:Namespace不是万能的。它不能隔离Pod之间的网络(需要NetworkPolicy配合),也不能隔离存储。说白了,它就是个逻辑上的"文件夹"。

3.5 ConfigMap与Secret:配置管理

这两个东西放在一起讲,因为它们干的事差不多——把配置从应用代码里抽离出来。

ConfigMap:明文配置

ConfigMap用来存非敏感配置,比如配置文件、环境变量、命令行参数。

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  app.properties: |
    log.level=INFO
    max.connections=100
  DB_HOST: mysql-service

使用方式也很灵活:可以挂载成文件,也可以注入成环境变量。

Secret:敏感信息

Secret和ConfigMap几乎一样,区别在于它的值是Base64编码的。注意,只是编码,不是加密!

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=  # admin
  password: cGFzc3dvcmQxMjM=  # password123

重要提醒:我曾经在代码仓库里看到有人把Secret的明文值直接提交了。记住,Base64不是加密,它只是编码。真正生产环境要用外部密钥管理服务,比如Vault、AWS Secrets Manager。

我个人的最佳实践是:

  • 非敏感配置用ConfigMap
  • 密码、密钥、Token用Secret
  • Secret的存储要开启加密(etcd加密)
  • 定期轮换Secret中的敏感信息

3.6 它们是怎么配合的?

说了这么多,咱们串起来看看。一个典型的应用部署流程是这样的:

  1. 用ConfigMap和Secret定义配置
  2. 用Deployment定义Pod模板,引用ConfigMap和Secret
  3. 用Service暴露Pod的访问入口
  4. 所有资源放在同一个Namespace里

你想想看,这套组合拳打下来,应用部署、配置管理、服务发现、扩缩容,全齐了。这就是Kubernetes的魅力所在——用几个核心概念,组合出强大的编排能力。

我的建议:刚开始学的时候,别急着搞太复杂。先玩明白Pod和Deployment,再慢慢加Service、ConfigMap。一步一个脚印,比什么都重要。

好了,这一章的核心概念就讲到这里。下一章咱们聊聊K8s的网络模型,那可是个有意思的话题。