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里怎么玩。