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

好,咱们今天聊聊Kubernetes里最核心的几个概念。说实话,我刚接触K8s那会儿,也被这些名词搞得有点晕。Pod、Service、Deployment……它们到底啥关系?别急,我带你一个一个捋清楚。

3.1 Pod:最小的调度单元

Pod是Kubernetes里你能创建和管理的最小计算单元。你可以把它理解成一组容器的“共享沙盒”。

Pod的特点:

  • 一个Pod里可以跑一个或多个容器
  • 这些容器共享网络栈(同一个IP和端口空间)
  • 它们共享存储卷(Volume)
  • Pod是“临时”的,随时可能被销毁重建

我在项目中遇到过一个问题:有同事把两个需要独立扩缩容的服务塞进同一个Pod。结果一个服务流量暴涨,另一个也跟着遭殃。嗯,这里要注意——Pod里的容器应该“同生共死”,比如一个日志收集sidecar和主应用容器,这才合理。

核心原则:Pod是原子的。要么一起启动,要么一起挂掉。

3.2 Service:稳定的网络入口

Pod的IP是动态的,重启一次就变了。那怎么让客户端稳定访问?Service就是干这个的。

Service为一组Pod提供稳定的虚拟IP和DNS名称。它通过标签选择器(Label Selector)找到对应的Pod,然后把流量转发过去。

Service的几种类型:

类型 说明 适用场景
ClusterIP 集群内部虚拟IP,外部不可达 内部服务间调用
NodePort 在每个节点上开放一个端口 开发测试、外部简单访问
LoadBalancer 云厂商提供负载均衡器 生产环境对外暴露服务
ExternalName 返回外部DNS的CNAME记录 将外部服务映射到集群内

我个人习惯,开发环境用NodePort就够了。生产环境一定要用LoadBalancer或者Ingress。为什么?NodePort的端口范围有限(30000-32767),而且没法做高级路由。

小技巧:Service的Session Affinity可以保持用户会话粘性。我曾在电商项目里用它解决购物车状态丢失的问题。

3.3 Deployment:声明式应用管理

Deployment是Kubernetes里最常用的工作负载控制器。它负责声明你想要的最终状态,然后K8s帮你搞定一切。

Deployment能做什么?

  • 滚动更新(Rolling Update)
  • 回滚到历史版本
  • 扩缩容(手动或自动)
  • 自愈(Pod挂了自动重建)

来看一个简单的Deployment YAML:

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

我曾经犯过一个低级错误——更新镜像时忘了改imagePullPolicy。结果Pod一直用本地缓存的旧镜像,折腾了半天才发现。所以,如果镜像tag是latest,记得把imagePullPolicy设为Always

避坑指南:我曾经在生产环境直接kubectl delete deployment,结果所有Pod瞬间消失。记住,删除Deployment会连带删除它管理的所有Pod。想保留Pod?用kubectl scale把副本数降到0。

3.4 Namespace:虚拟集群

Namespace是Kubernetes实现多租户隔离的基础。它把集群划分成多个虚拟空间,每个空间里的资源互不干扰。

Namespace的典型用途:

  • 环境隔离:dev、test、prod各一个Namespace
  • 团队隔离:不同团队用不同Namespace
  • 资源配额:通过ResourceQuota限制每个Namespace的资源上限

你想想看,如果没有Namespace,所有Pod、Service都混在一起,命名冲突是迟早的事。我见过一个项目,两个团队都创建了名为redis的Service,结果互相覆盖,排查了整整一天。

常用Namespace操作:

# 创建Namespace
kubectl create namespace my-namespace

# 在指定Namespace下创建资源
kubectl apply -f deployment.yaml -n my-namespace

# 查看所有Namespace
kubectl get namespaces

建议:每个项目至少分三个Namespace:dev、staging、prod。资源配额一定要设,不然某个团队可能把集群资源吃光。

3.5 ConfigMap与Secret:配置管理

应用配置不应该硬编码在镜像里。ConfigMap和Secret就是Kubernetes用来管理配置的两种资源。

ConfigMap:明文配置

ConfigMap用来存储非敏感配置,比如环境变量、配置文件内容。

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: production
  APP_DEBUG: "false"
  app.properties: |
    db.host=localhost
    db.port=3306

在Pod里引用ConfigMap:

spec:
  containers:
  - name: my-app
    envFrom:
    - configMapRef:
        name: app-config

Secret:敏感信息

Secret和ConfigMap很像,但它的值是Base64编码的(注意,不是加密,只是编码)。适合存密码、API密钥、证书等。

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

ConfigMap vs Secret:

特性 ConfigMap Secret
数据格式 明文 Base64编码
用途 非敏感配置 敏感信息
大小限制 1MB 1MB
加密支持 支持etcd加密

避坑指南:我曾经把数据库密码直接写在ConfigMap里,结果被安全审计打了个大大的红叉。记住,密码、密钥、Token一定要用Secret。另外,Secret的Base64编码不是真正的加密,生产环境务必开启etcd加密存储。

嗯,到这里Kubernetes的六大核心概念就讲完了。Pod是基础单元,Service提供稳定网络,Deployment管理应用生命周期,Namespace做隔离,ConfigMap和Secret管配置。这几个概念搞明白了,K8s的大门就算真正推开了。

下一章咱们聊聊更高级的控制器——StatefulSet和DaemonSet,看看有状态应用和守护进程在K8s里怎么玩。