写在前面
在上一篇文章中,我们了解了Kubernetes的整体架构和环境搭建方法。现在,我们需要深入理解Kubernetes的核心对象------Pod和Label。Pod是Kubernetes中最小的调度单元,Label则是资源组织和管理的关键机制。理解这两个概念,是掌握Kubernetes的基础。
这篇文章将详细讲解Pod的概念、生命周期、多容器模式和Init容器,以及Label和Selector的使用方法,帮助你建立对Kubernetes核心对象的深入理解。
一、Pod:最小调度单元
1.1 Pod的概念
Pod是Kubernetes中最小的可部署单元,它封装了一个或多个容器、存储资源、网络IP地址以及控制容器运行方式的选项。可以把Pod理解为一组共享资源的"进程组"。
┌─────────────────────────────────────────────────────────────────────────┐
│ Pod结构示意图 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Pod │ │
│ │ ┌─────────────────────────────────────────────────────────────┐│ │
│ │ │ 共享资源层 ││ │
│ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││ │
│ │ │ │ 网络命名空间 │ │ IPC命名空间 │ │ 存储卷 │ ││ │
│ │ │ │ (Network) │ │ (IPC) │ │ (Volumes) │ ││ │
│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ ││ │
│ │ └─────────────────────────────────────────────────────────────┘│ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────────────────────────────────────────────┐│ │
│ │ │ 容器层 ││ │
│ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││ │
│ │ │ │ 容器A │ │ 容器B │ │ 容器C │ ││ │
│ │ │ │ (主容器) │ │ (Sidecar) │ │ (Sidecar) │ ││ │
│ │ │ │ │ │ │ │ │ ││ │
│ │ │ │ - 应用进程 │ │ - 日志收集 │ │ - 监控代理 │ ││ │
│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ ││ │
│ │ └─────────────────────────────────────────────────────────────┘│ │
│ │ │ │
│ │ Pod IP: 10.244.1.5 │ │
│ │ Pod名称: my-app-xxxxx-yyyyy │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Pod的核心特点:
共享网络命名空间:Pod内的所有容器共享同一个网络命名空间,它们可以通过localhost相互通信,共享同一个IP地址和端口空间。
共享存储卷:Pod内的容器可以共享存储卷,实现数据共享和持久化。
共享IPC命名空间:Pod内的容器可以通过IPC(进程间通信)机制进行通信。
原子性调度:Pod作为一个整体被调度到节点上,不会出现容器分散在不同节点的情况。
1.2 为什么需要Pod
你可能会问,为什么不直接调度容器,而要引入Pod这个概念?这涉及到容器编排的核心问题。
在容器化应用中,经常需要多个紧密协作的容器一起工作。例如:
- 主容器+日志收集器:主应用容器产生日志,Sidecar容器负责收集和发送日志
- 主容器+配置更新器:主应用容器读取配置,Sidecar容器负责监听配置变更
- 主容器+代理容器:主应用容器处理业务逻辑,Sidecar容器负责网络代理
这些容器需要紧密协作,它们应该作为一个整体被调度和管理。Pod正是为这种场景设计的------它将紧密协作的容器组合在一起,作为一个原子单元进行调度。
1.3 Pod的YAML定义
下面是一个完整的Pod YAML定义:
apiVersion: v1 # API版本
kind: Pod # 资源类型
metadata: # 元数据
name: my-app-pod # Pod名称
namespace: default # 命名空间
labels: # 标签
app: my-app
environment: production
annotations: # 注解
description: "This is my application pod"
spec: # 规格定义
containers: # 容器列表
- name: app-container # 容器名称
image: nginx:1.21 # 镜像
imagePullPolicy: IfNotPresent # 镜像拉取策略
ports: # 端口定义
- containerPort: 80
name: http
protocol: TCP
env: # 环境变量
- name: APP_ENV
value: "production"
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: db_host
resources: # 资源限制
requests: # 最小资源需求
memory: "128Mi"
cpu: "100m"
limits: # 最大资源限制
memory: "256Mi"
cpu: "200m"
volumeMounts: # 挂载卷
- name: app-data
mountPath: /data
- name: config-volume
mountPath: /etc/config
readOnly: true
livenessProbe: # 存活探针
httpGet:
path: /health
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe: # 就绪探针
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
volumes: # 卷定义
- name: app-data
emptyDir: {}
- name: config-volume
configMap:
name: app-config
restartPolicy: Always # 重启策略
nodeSelector: # 节点选择器
disktype: ssd
tolerations: # 容忍度
- key: "dedicated"
operator: "Equal"
value: "app"
effect: "NoSchedule"
1.4 Pod的生命周期
Pod的生命周期包含多个阶段,理解这些阶段对于调试和管理Pod至关重要。
┌─────────────────────────────────────────────────────────────────────────┐
│ Pod生命周期状态流转 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ Pending │ Pod已创建,等待调度到节点 │
│ └──────┬──────┘ │
│ │ 调度成功 │
│ ▼ │
│ ┌─────────────┐ │
│ │ Running │ Pod已绑定节点,容器正在运行 │
│ └──────┬──────┘ │
│ │ │
│ ├──────────────────────┬──────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Succeeded │ │ Failed │ │ Unknown │ │
│ │ 成功完成 │ │ 运行失败 │ │ 状态未知 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ 容器状态: │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Waiting │ │ Running │ │ Terminated │ │ Unknown │ │
│ │ 等待中 │ │ 运行中 │ │ 已终止 │ │ 未知 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Pod阶段(Phase):
|-----------|------------------------------------------|
| 阶段 | 说明 |
| Pending | Pod已被Kubernetes接受,但容器尚未创建。包括调度时间和下载镜像时间。 |
| Running | Pod已绑定到节点,所有容器都已创建,至少有一个容器正在运行。 |
| Succeeded | Pod中的所有容器都已成功终止,不会重启。 |
| Failed | Pod中的所有容器都已终止,至少有一个容器以失败状态终止。 |
| Unknown | 无法获取Pod状态,通常是与节点通信失败。 |
容器状态:
- Waiting:容器正在等待启动,可能正在拉取镜像或应用Secret
- Running:容器正在运行
- Terminated:容器已终止,可能是成功完成或失败退出
- Unknown:无法获取容器状态
查看Pod状态:
# 查看Pod状态
kubectl get pods
# 查看Pod详细信息
kubectl describe pod pod-name
# 查看Pod的YAML定义
kubectl get pod pod-name -o yaml
# 查看Pod状态(JSON格式)
kubectl get pod pod-name -o jsonpath='{.status.phase}'
1.5 Pod的重启策略
Pod的重启策略决定了容器退出后的行为:
|-----------|----------------|
| 策略 | 说明 |
| Always | 容器退出后总是重启(默认值) |
| OnFailure | 只有失败时才重启 |
| Never | 从不重启 |
apiVersion: v1
kind: Pod
metadata:
name: restart-demo
spec:
restartPolicy: OnFailure # 设置重启策略
containers:
- name: app
image: busybox
command: ["sh", "-c", "echo 'Hello' && exit 1"]
1.6 Pod的探针
探针是Kubernetes检测容器健康状态的机制,有三种类型:
存活探针(Liveness Probe):检测容器是否存活。如果探测失败,Kubernetes会重启容器。
就绪探针(Readiness Probe):检测容器是否准备好接收流量。如果探测失败,Service会将该Pod从Endpoints中移除。
启动探针(Startup Probe):检测容器是否已启动。对于启动时间较长的应用,可以避免被存活探针杀死。
apiVersion: v1
kind: Pod
metadata:
name: probe-demo
spec:
containers:
- name: app
image: nginx
# 存活探针
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 30 # 初始延迟
periodSeconds: 10 # 检测间隔
timeoutSeconds: 5 # 超时时间
failureThreshold: 3 # 失败阈值
# 就绪探针
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
# 启动探针
startupProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 0
periodSeconds: 10
failureThreshold: 30 # 允许失败30次(300秒)
探针的三种检测方式:
# HTTP GET探针
livenessProbe:
httpGet:
path: /health
port: 80
httpHeaders:
- name: Custom-Header
value: value
# TCP Socket探针
livenessProbe:
tcpSocket:
port: 80
# Exec探针(执行命令)
livenessProbe:
exec:
command:
- cat
- /tmp/health
二、多容器Pod模式
2.1 Sidecar模式
Sidecar模式是最常见的多容器模式,辅助容器与主容器协同工作。
┌─────────────────────────────────────────────────────────────────────────┐
│ Sidecar模式示意图 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Pod │ │
│ │ ┌─────────────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ 主容器 │ │ Sidecar容器 │ │ │
│ │ │ │ │ │ │ │
│ │ │ ┌─────────────────┐ │ │ ┌─────────────────┐ │ │ │
│ │ │ │ 应用进程 │ │ │ │ 日志收集器 │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ 写入日志文件 │───┼──┼─▶│ 读取日志文件 │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ └─────────────────┘ │ │ │ 发送到中心 │ │ │ │
│ │ │ │ │ └─────────────────┘ │ │ │
│ │ └─────────────────────────┘ └─────────────────────────┘ │ │
│ │ │ │ │ │
│ │ ▼ ▼ │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ 共享存储卷 │ │ │
│ │ │ /var/log/app │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Sidecar模式的典型应用场景:
- 日志收集:主容器写入日志文件,Sidecar容器收集并发送到日志系统
- 配置同步:Sidecar容器监听配置变更,更新主容器的配置文件
- 代理服务:Sidecar容器作为代理,处理网络通信
- 监控采集:Sidecar容器采集主容器的指标数据
Sidecar示例:
apiVersion: v1
kind: Pod
metadata:
name: sidecar-demo
spec:
containers:
# 主容器:Nginx
- name: nginx
image: nginx
volumeMounts:
- name: logs
mountPath: /var/log/nginx
# Sidecar容器:日志收集器
- name: log-collector
image: fluent/fluentd
volumeMounts:
- name: logs
mountPath: /var/log/nginx
readOnly: true
volumes:
- name: logs
emptyDir: {}
2.2 Ambassador模式
Ambassador模式中,辅助容器作为代理,代表主容器与外部服务通信。
┌─────────────────────────────────────────────────────────────────────────┐
│ Ambassador模式示意图 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Pod │ │
│ │ ┌─────────────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ 主容器 │ │ Ambassador容器 │ │ │
│ │ │ │ │ │ │ │
│ │ │ ┌─────────────────┐ │ │ ┌─────────────────┐ │ │ │
│ │ │ │ 应用进程 │ │ │ │ 代理服务 │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ 访问本地端口 │───┼──┼─▶│ 转发到外部服务 │───┼────┼──┼──▶ 外部服务
│ │ │ │ localhost:3306 │ │ │ │ │ │ │ │ │
│ │ │ └─────────────────┘ │ │ └─────────────────┘ │ │ │ │
│ │ │ │ │ │ │ │ │
│ │ └─────────────────────────┘ └─────────────────────────┘ │ │ │
│ │ │ │ │
│ │ 主容器通过localhost访问Ambassador,Ambassador代理到外部服务 │ │ │
│ │ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Ambassador示例:
apiVersion: v1
kind: Pod
metadata:
name: ambassador-demo
spec:
containers:
# 主容器:应用
- name: app
image: my-app
env:
- name: DB_HOST
value: "localhost" # 连接本地代理
- name: DB_PORT
value: "3306"
# Ambassador容器:数据库代理
- name: db-proxy
image: envoyproxy/envoy
ports:
- containerPort: 3306
volumeMounts:
- name: envoy-config
mountPath: /etc/envoy
volumes:
- name: envoy-config
configMap:
name: envoy-config
2.3 Adapter模式
Adapter模式中,辅助容器将主容器的输出转换为统一格式。
┌─────────────────────────────────────────────────────────────────────────┐
│ Adapter模式示意图 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Pod │ │
│ │ ┌─────────────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ 主容器 │ │ Adapter容器 │ │ │
│ │ │ │ │ │ │ │
│ │ │ ┌─────────────────┐ │ │ ┌─────────────────┐ │ │ │
│ │ │ │ 应用进程 │ │ │ │ 格式转换器 │ │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ │ 输出自定义格式 │───┼──┼─▶│ 转换为标准格式 │───┼────┼──┼──▶ 监控系统
│ │ │ │ │ │ │ │ │ │ │ │ │
│ │ │ └─────────────────┘ │ │ └─────────────────┘ │ │ │ │
│ │ │ │ │ │ │ │ │
│ │ └─────────────────────────┘ └─────────────────────────┘ │ │ │
│ │ │ │ │
│ │ Adapter将不同应用的输出转换为统一的监控格式 │ │ │
│ │ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Adapter示例:
apiVersion: v1
kind: Pod
metadata:
name: adapter-demo
spec:
containers:
# 主容器:应用
- name: app
image: my-app
volumeMounts:
- name: metrics
mountPath: /var/metrics
# Adapter容器:指标转换
- name: metrics-adapter
image: prom/statsd-exporter
volumeMounts:
- name: metrics
mountPath: /var/metrics
readOnly: true
volumes:
- name: metrics
emptyDir: {}
三、Init容器
3.1 Init容器的概念
Init容器是一种特殊容器,在Pod的主容器启动之前运行。Init容器必须成功完成,主容器才会启动。
┌─────────────────────────────────────────────────────────────────────────┐
│ Init容器执行流程 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 时间线 ────────────────────────────────────────────────────────────▶ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Init容器1 │ │ Init容器2 │ │ Init容器3 │ │ 主容器 │ │
│ │ │ │ │ │ │ │ │ │
│ │ 初始化数据库│ │ 下载配置 │ │ 等待依赖 │ │ 启动应用 │ │
│ │ │ │ │ │ │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ 成功完成 成功完成 成功完成 开始运行 │
│ │
│ 特点: │
│ - Init容器按顺序执行,前一个成功后才执行下一个 │
│ - Init容器失败会导致Pod重启,重新执行所有Init容器 │
│ - Init容器不支持探针 │
│ - Init容器与主容器共享存储卷和网络命名空间 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
3.2 Init容器的应用场景
- 等待依赖服务就绪:等待数据库、缓存等服务启动完成
- 初始化数据库:创建数据库表、导入初始数据
- 下载配置文件:从远程服务器下载配置
- 注册服务:向服务发现系统注册
3.3 Init容器示例
apiVersion: v1
kind: Pod
metadata:
name: init-demo
spec:
initContainers:
# Init容器1:等待数据库就绪
- name: wait-for-db
image: busybox
command: ['sh', '-c', 'until nc -z mysql-service 3306; do echo waiting for mysql; sleep 2; done;']
# Init容器2:初始化数据库
- name: init-db
image: mysql:5.7
command: ['sh', '-c', 'mysql -h mysql-service -u root -p$MYSQL_ROOT_PASSWORD < /init-scripts/init.sql']
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: root-password
volumeMounts:
- name: init-scripts
mountPath: /init-scripts
# Init容器3:下载配置
- name: download-config
image: busybox
command: ['sh', '-c', 'wget -O /config/app.conf http://config-server/app.conf']
volumeMounts:
- name: config
mountPath: /config
# 主容器
containers:
- name: app
image: my-app
volumeMounts:
- name: config
mountPath: /etc/app/config
volumes:
- name: init-scripts
configMap:
name: init-scripts
- name: config
emptyDir: {}
3.4 Init容器与普通容器的区别
|------|------------|---------|
| 特性 | Init容器 | 普通容器 |
| 执行时机 | 主容器启动前 | Pod运行期间 |
| 执行顺序 | 顺序执行 | 并行执行 |
| 重启条件 | 任何Init容器失败 | 根据重启策略 |
| 探针支持 | 不支持 | 支持 |
| 生命周期 | 一次性 | 持续运行 |
四、Label和Selector
4.1 Label的概念
Label是附加在Kubernetes对象上的键值对,用于组织和选择资源。Label是用户定义的标识,可以用于分组、查询和操作资源。
metadata:
labels:
app: my-app # 应用名称
environment: production # 环境标识
tier: frontend # 层级
version: v1.2.0 # 版本号
team: backend # 团队归属
Label的特点:
- 键值对形式:每个Label由键和值组成
- 可变性:Label可以在运行时添加、修改或删除
- 选择性:通过Selector选择具有特定Label的资源
- 命名空间作用域:Label只在同一命名空间内有效
4.2 Label的命名规范
Label的键和值有一定的命名规范:
键的格式 :[前缀/]名称
- 前缀:可选,必须是DNS子域名格式,最长253字符
- 名称:必须以字母或数字开头和结尾,可包含字母、数字、连字符、下划线和点,最长63字符
值的格式:
-
必须以字母或数字开头和结尾
-
可包含字母、数字、连字符、下划线和点
-
最长63字符
合法的Label
labels:
app: my-app
app.kubernetes.io/name: my-app
app.kubernetes.io/version: "1.0.0"
environment: production
tier: frontend推荐的Label前缀(Kubernetes官方推荐)
app.kubernetes.io/name: my-app
app.kubernetes.io/instance: my-app-abcxys
app.kubernetes.io/version: "1.0.0"
app.kubernetes.io/component: frontend
app.kubernetes.io/part-of: my-system
app.kubernetes.io/managed-by: helm
4.3 Selector的使用
Selector用于选择具有特定Label的资源,有两种类型:
等值Selector:匹配Label的值是否相等
# 选择app=my-app的Pod
kubectl get pods -l app=my-app
# 选择多个Label
kubectl get pods -l app=my-app,environment=production
# 选择不等于某个值
kubectl get pods -l app!=my-app
集合Selector:匹配Label的值是否在某个集合中
# 选择environment为production或staging的Pod
kubectl get pods -l 'environment in (production,staging)'
# 选择environment不在production的Pod
kubectl get pods -l 'environment notin (production)'
# 选择有某个Label的Pod
kubectl get pods -l 'app'
# 选择没有某个Label的Pod
kubectl get pods -l '!app'
4.4 在YAML中使用Selector
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
# 选择器:选择要管理的Pod
selector:
matchLabels: # 等值匹配
app: my-app
matchExpressions: # 表达式匹配
- key: environment
operator: In
values:
- production
- staging
- key: tier
operator: Exists # 存在性匹配
template:
metadata:
labels: # Pod模板的Label
app: my-app
environment: production
tier: frontend
spec:
containers:
- name: app
image: my-app:latest
Selector操作符:
|--------------|-----------|---------------------------------|
| 操作符 | 说明 | 示例 |
| In | 值在指定集合中 | environment in (prod,staging) |
| NotIn | 值不在指定集合中 | environment notin (dev) |
| Exists | 存在该Label | app |
| DoesNotExist | 不存在该Label | !app |
4.5 Label操作命令
# 添加Label
kubectl label pod my-pod app=my-app
# 修改Label
kubectl label pod my-pod app=my-new-app --overwrite
# 删除Label
kubectl label pod my-pod app-
# 查看Label
kubectl get pods --show-labels
# 按Label筛选
kubectl get pods -l app=my-app
# 按Label排序
kubectl get pods --sort-by=.metadata.labels.app
4.6 Label的最佳实践
使用标准Label前缀:
# Kubernetes推荐的Label
app.kubernetes.io/name: my-app # 应用名称
app.kubernetes.io/instance: my-app-xyz # 实例标识
app.kubernetes.io/version: "1.0.0" # 版本号
app.kubernetes.io/component: backend # 组件类型
app.kubernetes.io/part-of: my-system # 所属系统
app.kubernetes.io/managed-by: helm # 管理工具
保持Label的一致性:
# Deployment和Pod的Label应该一致
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app # 与selector匹配
使用有意义的Label:
labels:
# 应用相关
app: my-app
version: v1.0.0
# 环境相关
environment: production
region: cn-east-1
# 架构相关
tier: frontend
component: web
# 团队相关
team: platform
owner: backend-team
五、实战案例:部署多容器应用
让我们通过一个完整的案例,演示Pod、多容器模式和Label的综合应用。
5.1 应用场景
部署一个Web应用,包含:
- Nginx主容器:提供Web服务
- Fluentd Sidecar:收集日志
- Init容器:等待数据库就绪
5.2 完整YAML配置
apiVersion: v1
kind: Pod
metadata:
name: web-app
labels:
app: web-app
environment: production
tier: frontend
version: v1.0.0
spec:
# Init容器:等待数据库
initContainers:
- name: wait-for-db
image: busybox:1.35
command:
- sh
- -c
- |
echo "Waiting for database..."
until nc -z mysql-service 3306; do
echo "Database is not ready yet..."
sleep 2
done
echo "Database is ready!"
# 主容器
containers:
# Nginx容器
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
name: http
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
- name: logs
mountPath: /var/log/nginx
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
# Sidecar容器:日志收集
- name: fluentd
image: fluent/fluentd:v1.14
volumeMounts:
- name: logs
mountPath: /var/log/nginx
readOnly: true
- name: fluentd-config
mountPath: /fluentd/etc
resources:
requests:
memory: "32Mi"
cpu: "50m"
limits:
memory: "64Mi"
cpu: "100m"
# 存储卷
volumes:
- name: html
emptyDir: {}
- name: logs
emptyDir: {}
- name: fluentd-config
configMap:
name: fluentd-config
# 重启策略
restartPolicy: Always
# 节点选择
nodeSelector:
kubernetes.io/os: linux
5.3 部署和验证
# 创建ConfigMap
kubectl create configmap fluentd-config --from-file=fluent.conf
# 创建Pod
kubectl apply -f web-app.yaml
# 查看Pod状态
kubectl get pods -l app=web-app
# 查看Pod详情
kubectl describe pod web-app
# 查看Init容器日志
kubectl logs web-app -c wait-for-db
# 查看主容器日志
kubectl logs web-app -c nginx
# 查看Sidecar容器日志
kubectl logs web-app -c fluentd
# 进入主容器
kubectl exec -it web-app -c nginx -- /bin/bash
# 查看Label
kubectl get pods --show-labels
# 按Label筛选
kubectl get pods -l app=web-app,environment=production
总结
这篇文章详细讲解了Kubernetes的核心对象------Pod和Label,主要内容包括:
- Pod的概念:Pod是Kubernetes最小的调度单元,封装了容器和共享资源
- Pod的生命周期:理解Pod的阶段和容器状态,掌握重启策略和探针机制
- 多容器Pod模式:Sidecar、Ambassador、Adapter三种常见模式及应用场景
- Init容器:在主容器启动前执行初始化任务的特殊容器
- Label和Selector:资源组织和选择的关键机制
Pod和Label是Kubernetes的基础,理解它们对于后续学习Deployment、Service等高级对象至关重要。下一篇文章将继续讲解Kubernetes的核心对象------Deployment、Service和Namespace,深入理解Kubernetes如何管理无状态应用和实现服务发现。