2. Kubernetes核心概念:Pod、Service、Deployment、Namespace、ConfigMap与Secret
好,咱们正式开始聊Kubernetes的核心概念。说实话,很多初学者一上来就被这些名词搞懵了。Pod是什么?Service又是干嘛的?Deployment和Pod有啥关系?
别急,我带你一个一个捋清楚。这些概念,说白了就是Kubernetes世界里最基础的“积木块”。你只要理解了它们,后面搭建任何复杂的系统都会轻松很多。
2.1 Pod:最小的调度单元
Pod是Kubernetes里你能创建和管理的最小单位。很多人第一反应是“这不就是容器吗?”——嗯,不完全对。
Pod可以包含一个或多个容器。这些容器共享同一个网络命名空间、存储卷,还有IP地址。它们就像住在同一个房间里,可以通过localhost互相通信。
核心要点:Pod是“逻辑主机”,容器是“进程”。一个Pod里的容器,共享资源,协同工作。
我在项目中遇到过一种场景:一个Pod里放了一个Nginx和一个日志收集器。Nginx处理请求,日志收集器实时读取Nginx的日志文件并发送到中央日志系统。这两个容器配合得天衣无缝,因为它们共享了同一个存储卷。
# 一个简单的Pod定义
apiVersion: v1
kind: Pod
metadata:
name: my-nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
我的建议:生产环境中,尽量一个Pod只放一个主容器。除非你有明确的“边车模式”需求,比如日志收集、代理等。否则,多容器Pod会增加调试复杂度。
2.2 Service:稳定的网络入口
Pod是有生命周期的。它可能因为故障、更新、扩缩容而被销毁和重建。每次重建,Pod的IP都会变。那问题来了——谁来记住这些变化的IP?
答案就是Service。
Service为一组Pod提供了一个稳定的虚拟IP和DNS名称。客户端只需要访问这个Service,Kubernetes会自动把请求转发到后端的某个Pod上。
# 一个Service定义
apiVersion: v1
kind: Service
metadata:
name: my-nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
你想想看,如果没有Service,每次Pod重启你都得手动更新IP地址——那简直是噩梦。我个人习惯是,只要暴露网络服务,就一定配上Service。哪怕只是内部调用,也建议用Service名而不是IP。
避坑指南:我曾经犯过一个错误——在代码里硬编码了Pod的IP。结果Pod一重启,整个服务就挂了。后来我改用Service的DNS名称,再也没出过这种问题。
2.3 Deployment:声明式的应用管理
Deployment,说白了就是“Pod的管理员”。你告诉它“我要运行3个Nginx副本”,Deployment就会帮你创建3个Pod,并持续监控它们的状态。
如果某个Pod挂了,Deployment会自动重建一个。如果你想升级版本,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
我记得有一次线上需要紧急回滚。Deployment的rollback功能帮了大忙——一条命令就回到了上一个稳定版本,整个过程不到10秒。如果是手动操作,估计得折腾半小时。
核心要点:永远不要直接创建Pod。用Deployment来管理Pod的生命周期。这是Kubernetes的最佳实践。
2.4 Namespace:虚拟集群的划分
Namespace,就是Kubernetes里的“虚拟墙”。它可以把一个物理集群划分成多个虚拟集群。不同Namespace里的资源是隔离的,你可以给每个Namespace设置独立的资源配额和权限。
我一般这样划分:
dev:开发环境test:测试环境prod:生产环境
每个团队只操作自己的Namespace,互不干扰。这样既节省了集群资源,又保证了安全性。
# 创建一个Namespace
kubectl create namespace dev
我的建议:小团队可以不用Namespace,但一旦超过5个人,或者有多个环境,一定要用Namespace来隔离。否则,你可能会不小心删掉别人的Pod。
2.5 ConfigMap与Secret:配置与敏感信息的管理
应用通常需要配置——数据库地址、日志级别、API密钥等等。把这些配置硬编码在镜像里?那每次改配置都得重新构建镜像,太麻烦了。
ConfigMap就是用来管理非敏感配置的。Secret则是用来管理敏感信息的,比如密码、Token。它们都可以被挂载到Pod里,或者通过环境变量注入。
# ConfigMap示例
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DB_HOST: "mysql-service"
LOG_LEVEL: "info"
# Secret示例
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
DB_PASSWORD: cGFzc3dvcmQxMjM= # base64编码
在Pod里使用它们:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: my-app:latest
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: DB_HOST
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
避坑指南:我曾经把数据库密码直接写在了ConfigMap里——结果所有人都能看到。后来我改成了Secret,并且用外部密钥管理服务(如Vault)来轮换密码。记住,Secret只是做了base64编码,不是加密。真正敏感的数据,建议用外部工具加密后再存储。
2.6 它们如何协同工作?
咱们来捋一下这些概念的关系:
- Deployment 管理 Pod 的副本数和生命周期。
- Pod 运行容器,容器里跑你的应用。
- Service 为 Pod 提供稳定的网络入口。
- Namespace 把资源隔离在不同的虚拟集群里。
- ConfigMap 和 Secret 为 Pod 提供配置和敏感信息。
你想想看,一个典型的微服务架构就是这样搭建的:每个服务一个Deployment,每个Deployment管理多个Pod副本,每个Pod前面挂一个Service,所有配置放在ConfigMap和Secret里,不同环境用Namespace隔离。
总结:掌握了这六个核心概念,你就掌握了Kubernetes的“骨架”。后面的章节,我们会在这个基础上,深入弹性伸缩、资源管理、监控告警等实战内容。
嗯,今天就先聊到这里。下一章,咱们会深入Pod的调度策略和资源限制——这可是弹性伸缩的基础。到时候见。