4. Kubernetes核心概念:Pod、Service、Deployment、Namespace、ConfigMap、Secret等核心资源对象
聊到Kubernetes,很多人第一反应就是“编排”。但说白了,K8s的核心就是一堆资源对象。你把这些对象定义好,它就能帮你把应用跑起来、管起来。今天我就带你过一遍最常用的那几个——Pod、Service、Deployment、Namespace、ConfigMap、Secret。这些都是我每天打交道的东西,踩过的坑也不少,咱们一个一个说。
4.1 Pod:最小的调度单元
Pod是K8s里最小的部署单元。一个Pod可以包含一个或多个容器。为什么要有Pod?因为有些容器需要共享网络和存储,比如一个日志采集容器和一个业务容器,它们得待在一起。
我个人习惯,一个Pod里只放一个主容器。除非有明确的“边车模式”需求,比如加个Envoy代理或者日志采集器。否则,别把一堆不相干的容器塞进一个Pod,那是给自己找麻烦。
核心要点:
- Pod内的容器共享同一个网络命名空间(IP和端口)
- Pod内的容器共享存储卷(Volume)
- Pod是短暂的,随时可能被销毁重建
举个例子,一个简单的Nginx Pod定义长这样:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
嗯,这里要注意:Pod的IP是动态分配的。你没法保证它重启后IP不变。所以,直接访问Pod IP是不靠谱的。那怎么办?用Service。
4.2 Service:稳定的访问入口
Service解决了Pod IP不固定的问题。它提供一个稳定的虚拟IP(ClusterIP),背后代理一组Pod。你访问Service,它帮你把请求转发到某个Pod上。
我在项目中遇到过一个问题:有个同事直接写死了Pod IP,结果Pod一重启,整个服务就挂了。后来改成Service,再也没出过事。说白了,Service就是K8s里的“负载均衡器”。
Service的类型有几种:
| 类型 | 说明 | 使用场景 |
|---|---|---|
| ClusterIP | 集群内部可访问,外部不可达 | 内部服务调用 |
| NodePort | 在每个节点上开放一个端口,外部可通过节点IP+端口访问 | 开发测试环境 |
| LoadBalancer | 云厂商提供的外部负载均衡器 | 生产环境对外暴露服务 |
一个简单的Service定义:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIP
注意看selector字段,它通过标签选择Pod。只要Pod的标签匹配,Service就会自动把流量转发过去。
4.3 Deployment:声明式更新与扩缩容
Deployment是我用得最多的资源。它管理Pod的副本数、滚动更新、回滚等。你想想看,如果手动管理Pod,扩缩容得一个个删、一个个建,多麻烦。Deployment把这些都自动化了。
我曾经在生产环境遇到过一个问题:更新镜像时,新版本有Bug,导致Pod启动失败。Deployment自动触发了回滚策略,把Pod恢复到了上一个版本。整个过程我没做任何操作,它自己就搞定了。这就是声明式的好处——你告诉它“我要什么状态”,它自己想办法达成。
一个典型的Deployment定义:
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
避坑指南:我曾经把replicas设成0,结果Pod全被删了。后来才意识到,Deployment会严格按照你定义的副本数来管理。所以,改副本数之前,先想清楚。
4.4 Namespace:逻辑隔离
Namespace用来做逻辑隔离。一个集群里可以划分多个Namespace,每个Namespace里的资源互不干扰。比如,开发环境用dev命名空间,生产环境用prod命名空间。
我个人习惯,每个项目单独一个Namespace。这样资源管理起来清晰,权限控制也方便。你想想看,如果所有Pod都堆在default命名空间里,时间长了根本分不清谁是谁。
创建Namespace很简单:
apiVersion: v1
kind: Namespace
metadata:
name: my-project
然后在其他资源里指定namespace: my-project即可。
4.5 ConfigMap与Secret:配置管理
这两个资源都是用来管理配置的。区别在于:ConfigMap存明文配置,Secret存敏感信息(密码、密钥等)。
ConfigMap的例子:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.properties: |
db.host=localhost
db.port=3306
Secret的例子:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
password: bXlwYXNzd29yZA== # base64编码后的密码
注意:Secret的data字段要求base64编码,但这只是简单的编码,不是加密。别把真正的敏感信息直接写进YAML文件里。我建议用外部密钥管理工具(比如Vault)来管理Secret。
在Pod里使用ConfigMap或Secret,有两种方式:
- 环境变量注入:把配置项变成容器的环境变量
- 挂载成文件:把配置项挂载到容器的文件系统里
我个人更推荐挂载成文件的方式。因为环境变量在Pod运行期间无法动态更新,而挂载的文件可以热更新(虽然需要应用自己监听文件变化)。
知识体系总览
下面这张图,我把这几个核心资源的关系画出来了。你看一眼就能明白它们是怎么配合的:
从图里能看出来:Deployment管理Pod,Pod通过Service对外暴露,ConfigMap和Secret给Pod注入配置。Namespace把这一切都包在里面,实现隔离。
好了,这几个核心资源就聊到这儿。记住一句话:Pod是基础,Service是入口,Deployment是管家,Namespace是隔间,ConfigMap和Secret是配置中心。把这几个玩明白了,K8s就算入门了。
公众号:蓝海资料掘金营,微信deep3321