4. Kubernetes核心概念:Pod、Service、Deployment、StatefulSet、ConfigMap、Secret、Namespace、RBAC权限控制

好,咱们进入Kubernetes的核心概念部分。说实话,K8s刚出来那会儿,我第一反应是「这玩意儿也太复杂了」。但用久了你会发现,它的设计其实很优雅——每个概念都解决一个具体问题。今天我就把这些核心概念掰开揉碎了讲给你听。

4.1 Pod:最小的调度单元

Pod是Kubernetes里最小的部署单元。你可以把它理解成「一组容器的集合」。为什么要有Pod?因为有些容器需要共享网络和存储,比如一个日志收集容器和一个业务容器,它们得待在一起。

核心要点:Pod内的容器共享同一个网络命名空间和存储卷。它们可以通过localhost互相访问。

我在项目中遇到过一个问题:两个容器需要共享一个临时目录来交换数据。如果不用Pod,你得自己配置网络和卷挂载,麻烦得很。用Pod就简单了——直接声明一个共享卷就行。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: app
    image: nginx
    ports:
    - containerPort: 80
  - name: sidecar
    image: busybox
    command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]

个人习惯:我一般不会直接创建Pod,而是通过Deployment或StatefulSet来管理。直接操作Pod就像手动部署应用——出了问题很难回滚。

4.2 Service:稳定的网络入口

Pod是动态的,随时可能被销毁重建。那问题来了——客户端怎么找到它?这就是Service的作用。

Service为一组Pod提供稳定的网络入口。它通过标签选择器(Label Selector)来匹配Pod。说白了,你给Pod打上标签,Service就自动发现它们。

Service类型 适用场景 访问方式
ClusterIP 集群内部访问 虚拟IP + 端口
NodePort 外部访问(开发测试) 节点IP + 固定端口
LoadBalancer 云环境外部访问 云负载均衡器

嗯,这里要注意:ClusterIP是默认类型,只能在集群内部用。如果你想让外部访问,得用NodePort或LoadBalancer。我曾经在生产环境里直接用NodePort暴露服务,结果端口冲突了——教训就是,生产环境还是用LoadBalancer或者Ingress吧。

4.3 Deployment:无状态应用的理想选择

Deployment是我用得最多的控制器。它管理Pod的声明式更新和回滚。你只需要告诉它「我要3个副本,镜像版本是v2」,剩下的它自己搞定。

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

避坑指南:我曾经在更新Deployment时忘了设置maxSurge和maxUnavailable,结果滚动更新期间服务中断了。建议生产环境至少保留一个Pod可用。

Deployment适合无状态应用——比如Web服务、API网关。为什么?因为它的Pod是无状态的,挂了就重建,数据丢了也不怕。

4.4 StatefulSet:有状态应用的救星

那有状态应用怎么办?比如数据库、消息队列。StatefulSet就是为这个设计的。

StatefulSet和Deployment最大的区别是:它给每个Pod一个稳定的网络标识和持久化存储。Pod的名字是有序的(比如db-0、db-1、db-2),重启后名字不变。

关键特性:StatefulSet的Pod是有序部署、有序缩容的。比如你要部署3个副本,它会先启动db-0,等它Ready了再启动db-1。

我记得有一次帮客户迁移数据库到K8s,他们一开始用Deployment部署MySQL,结果Pod重启后数据全丢了。后来换成StatefulSet,配合PersistentVolumeClaim,问题就解决了。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: mysql
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

4.5 ConfigMap与Secret:配置管理

应用配置怎么管理?硬编码在镜像里?那每次改配置都得重新构建镜像,太傻了。ConfigMap和Secret就是用来解耦配置和镜像的。

ConfigMap存明文配置,比如数据库地址、日志级别。Secret存敏感信息,比如密码、API密钥。Secret的数据是Base64编码的,但注意——这只是编码,不是加密。真要安全,得用外部密钥管理工具。

我的做法:ConfigMap用字面量创建,方便调试。Secret用文件创建,避免在命令行里暴露密码。

# 创建ConfigMap
kubectl create configmap app-config --from-literal=DB_HOST=localhost

# 创建Secret
kubectl create secret generic db-secret --from-file=./password.txt

你想想看,如果不用ConfigMap,每次改配置都得改YAML、重新部署。有了它,改个配置就一行命令的事。

4.6 Namespace:逻辑隔离

Namespace是Kubernetes里的虚拟集群。一个物理集群可以划分成多个Namespace,每个Namespace里的资源是隔离的。

我习惯按环境划分Namespace:dev、test、prod。这样开发人员只能在dev里折腾,不会影响到生产环境。

场景 推荐Namespace 说明
多环境 dev、test、prod 环境隔离,权限控制
多团队 team-a、team-b 资源配额,互不干扰
系统组件 kube-system K8s核心组件专用

注意:Namespace不是完全隔离的。比如Pod可以通过Service跨Namespace访问。要实现真正的网络隔离,得用NetworkPolicy。

4.7 RBAC权限控制

最后说说RBAC——基于角色的访问控制。说白了,就是谁可以干什么。

RBAC有四个核心概念:

  • User/ServiceAccount:谁在操作
  • Role/ClusterRole:能做什么(权限集合)
  • RoleBinding/ClusterRoleBinding:把角色绑定到用户

举个例子:给开发人员只读权限。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: dev
subjects:
- kind: User
  name: dev-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

我曾经犯过一个错:给一个ServiceAccount绑定了ClusterRole,结果它能在所有Namespace里删Pod。还好是在测试环境发现的。所以记住:权限最小化原则,给多少权限就够用多少。

总结一下:Pod是基础单元,Service提供稳定入口,Deployment管无状态应用,StatefulSet管有状态应用,ConfigMap和Secret管配置,Namespace做隔离,RBAC管权限。这些概念串起来,就是K8s的核心骨架。

嗯,今天就讲到这里。下一章咱们聊聊Kubernetes的网络模型和存储方案,那才是真正让人头疼的地方。