3、Kubernetes核心概念:Pod、Service、Deployment、ConfigMap、Secret、Namespace
好,咱们进入正题。Kubernetes 的概念很多,但真正天天打交道的,其实就这几个。我刚开始学 K8s 的时候,也被各种术语搞得头晕。后来发现,你只要把 Pod、Service、Deployment 这几个搞明白,日常运维基本就够用了。
说白了,Kubernetes 就是一个「管家」。你告诉它你想跑什么、跑几个、怎么暴露出去,它帮你搞定。下面我一个个拆开讲。
3.1 Pod:最小的调度单元
Pod 是 K8s 里最小的部署单元。你可以把它理解成「一组容器的集合」。为什么不是单个容器?因为有些场景下,多个容器需要共享网络和存储,比如一个容器写日志,另一个容器读日志。
我个人习惯把 Pod 比作「豆荚」——里面包着几颗豆子(容器)。它们共享同一个 IP、同一个端口空间,可以通过 localhost 互相访问。
核心要点:
- 一个 Pod 可以包含 1 个或多个容器
- Pod 内的容器共享网络和存储卷
- Pod 是短暂的,随时可能被销毁重建
我在项目中遇到过一个问题:有个同事把两个需要独立扩缩容的服务放在同一个 Pod 里。结果一个服务负载高了,整个 Pod 都得扩容,另一个服务也跟着遭殃。嗯,这里要注意——只有那些「生死与共」的容器才适合放一起。
# 一个简单的 Pod 定义
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
labels:
app: my-app
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
- name: sidecar
image: busybox
command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
3.2 Deployment:声明式更新
你想想看,如果每次更新应用都要手动删 Pod、建 Pod,那得多累?Deployment 就是来解决这个问题的。
Deployment 让你「声明」你想要的状态——比如跑 3 个副本、用哪个镜像。然后 K8s 负责把当前状态变成你想要的状态。这就是所谓的「声明式管理」。
我记得有一次线上紧急回滚,我直接改了 Deployment 里的镜像版本,几秒钟就全部回退完了。要是没有 Deployment,我得一个个 Pod 去处理,想想都头大。
我的建议:生产环境永远不要直接操作 Pod,用 Deployment 来管理。Deployment 会帮你处理滚动更新、回滚、扩缩容这些脏活累活。
# Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:v2.0
ports:
- containerPort: 8080
3.3 Service:稳定的访问入口
Pod 是动态的,今天在这台机器上,明天可能就跑到另一台了。那客户端怎么找到它?Service 就是干这个的。
Service 给一组 Pod 提供一个固定的 IP 和 DNS 名称。不管 Pod 怎么变,客户端只要访问 Service 的地址就行。
说白了,Service 就是一个「负载均衡器 + 服务发现」的组合体。
| Service 类型 | 适用场景 |
|---|---|
| ClusterIP | 集群内部访问,默认类型 |
| NodePort | 通过节点 IP + 端口从外部访问 |
| LoadBalancer | 云厂商提供的负载均衡器 |
我曾经踩过一个坑:Service 的 selector 写错了标签,结果流量全打到了错误的 Pod 上。排查了半天才发现是标签不匹配。所以,标签的一致性是 Service 能正常工作的前提。
# Service 示例
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
3.4 ConfigMap 与 Secret:配置管理
应用配置怎么管理?硬编码在镜像里?那每次改配置都得重新构建镜像,太傻了。
ConfigMap 用来存非敏感配置,比如数据库地址、日志级别。Secret 用来存敏感信息,比如密码、API Key。它们都可以挂载到 Pod 里,或者通过环境变量注入。
注意:Secret 只是做了 Base64 编码,不是加密。如果你需要真正的加密,得用外部工具比如 Sealed Secrets 或者 Vault。
我习惯把配置和代码分离。这样同一个镜像,在开发、测试、生产环境用不同的 ConfigMap,省心又安全。
# ConfigMap 示例
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DB_HOST: "mysql-service"
LOG_LEVEL: "info"
# Secret 示例
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
DB_PASSWORD: cGFzc3dvcmQxMjM= # base64 编码后的值
3.5 Namespace:逻辑隔离
一个集群里可能有多个团队、多个项目。怎么隔离?Namespace 就是干这个的。
你可以把 Namespace 理解成「虚拟集群」。不同 Namespace 里的资源可以同名,互不干扰。比如 dev 环境和 prod 环境各用一个 Namespace,资源就分开了。
我个人习惯按环境划分 Namespace:dev、test、prod。再大一点的团队,还会按项目分。但要注意,Namespace 只是逻辑隔离,不是安全隔离——如果你需要严格的安全边界,还得配合 NetworkPolicy。
常用命令:
kubectl get ns— 查看所有 Namespacekubectl get pods -n dev— 查看 dev 命名空间的 Podkubectl create ns test— 创建名为 test 的 Namespace
小结
这几个概念是 K8s 的基石。Pod 是跑应用的,Deployment 是管 Pod 的,Service 是暴露 Pod 的,ConfigMap/Secret 是配应用的,Namespace 是隔离资源的。
你想想看,把这些组合起来,一个完整的应用部署就出来了:Deployment 管理 Pod 的生命周期,Service 提供稳定的访问入口,ConfigMap 和 Secret 注入配置,最后放到对应的 Namespace 里。
下一章咱们会把这些概念串起来,做一个完整的自动化测试流水线。到时候你就知道,这些概念不是孤立的,它们配合起来才能发挥真正的威力。