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-ai、team-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 它们是怎么配合的?
说了这么多,咱们串起来看看。一个典型的应用部署流程是这样的:
- 用ConfigMap和Secret定义配置
- 用Deployment定义Pod模板,引用ConfigMap和Secret
- 用Service暴露Pod的访问入口
- 所有资源放在同一个Namespace里
你想想看,这套组合拳打下来,应用部署、配置管理、服务发现、扩缩容,全齐了。这就是Kubernetes的魅力所在——用几个核心概念,组合出强大的编排能力。
我的建议:刚开始学的时候,别急着搞太复杂。先玩明白Pod和Deployment,再慢慢加Service、ConfigMap。一步一个脚印,比什么都重要。
好了,这一章的核心概念就讲到这里。下一章咱们聊聊K8s的网络模型,那可是个有意思的话题。