Kubernetes
Kubernetes(通常缩写为 K8s)是一个开源的容器编排平台,用于自动化容器应用的部署、扩展和管理。它最初是由 Google 设计并开发,并于 2014 年开源,现在由 Cloud Native Computing Foundation(CNCF)管理。

查看更多相关内容
Kubernetes Ingress 是什么?它如何实现外部访问集群内服务?Kubernetes Ingress 是一种 API 对象,用于管理外部访问集群内服务的规则,通常是 HTTP 和 HTTPS 路由。Ingress 提供了基于域名和路径的路由、TLS 终止等功能。
## Ingress 的作用
1. **路由规则**:根据域名和路径将流量路由到不同的 Service
2. **负载均衡**:在多个 Service 实例之间分发流量
3. **SSL/TLS 终止**:在 Ingress 层面处理 HTTPS,简化后端配置
4. **基于名称的虚拟主机**:支持多个域名指向同一个集群
5. **路径重写**:支持 URL 路径重写
## Ingress Controller
Ingress Controller 是实现 Ingress 功能的组件,它监听 Ingress 资源的变化并配置负载均衡器。
### 常见的 Ingress Controller
1. **NGINX Ingress Controller**:
- 最流行的 Ingress Controller
- 基于 NGINX/OpenResty
- 功能丰富,性能优秀
- 支持高级路由、限流、认证等
2. **Traefik**:
- 云原生设计
- 自动服务发现
- 支持 Let's Encrypt 自动证书
- 配置简单
3. **HAProxy Ingress**:
- 基于 HAProxy
- 高性能
- 支持高级负载均衡算法
4. **Istio Gateway**:
- 服务网格的一部分
- 支持高级流量管理
- 集成 mTLS、流量镜像等
5. **AWS ALB Ingress Controller**:
- 专门为 AWS 设计
- 使用 AWS Application Load Balancer
- 原生集成 AWS 服务
## Ingress 资源示例
### 基本路由
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- path: /app2
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
```
### TLS 配置
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
tls:
- hosts:
- secure.example.com
secretName: tls-secret
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-service
port:
number: 443
```
### 默认后端
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: default-backend-ingress
spec:
defaultBackend:
service:
name: default-service
port:
number: 80
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
```
## Ingress 注解(Annotations)
注解用于配置 Ingress Controller 的特定行为。
### NGINX Ingress Controller 常用注解
1. **重写路径**:
```yaml
nginx.ingress.kubernetes.io/rewrite-target: /$2
```
2. **启用 SSL 重定向**:
```yaml
nginx.ingress.kubernetes.io/ssl-redirect: "true"
```
3. **限流配置**:
```yaml
nginx.ingress.kubernetes.io/limit-rps: "10"
nginx.ingress.kubernetes.io/limit-connections: "5"
```
4. **CORS 配置**:
```yaml
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
```
5. **认证配置**:
```yaml
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
```
6. **自定义错误页面**:
```yaml
nginx.ingress.kubernetes.io/custom-http-errors: "404,503"
```
## Ingress vs Service
| 特性 | Ingress | Service |
|------|---------|---------|
| 协议 | HTTP/HTTPS | TCP/UDP |
| 路由 | 基于域名和路径 | 基于端口 |
| 负载均衡 | L7(应用层) | L4(传输层) |
| SSL 终止 | 支持 | 不支持 |
| 使用场景 | Web 应用 | 通用服务 |
## Ingress vs LoadBalancer
| 特性 | Ingress | LoadBalancer |
|------|---------|--------------|
| 成本 | 低(共享 IP) | 高(每个 Service 一个 IP) |
| 路由能力 | 强(域名、路径) | 弱(仅端口) |
| SSL 终止 | 支持 | 部分支持 |
| 适用场景 | 多个 HTTP/HTTPS 服务 | 少量服务或非 HTTP 服务 |
## 部署 Ingress Controller
### 部署 NGINX Ingress Controller
```bash
# 添加 Helm 仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# 安装
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace
```
### 验证安装
```bash
kubectl get pods -n ingress-nginx
kubectl get svc -n ingress-nginx
```
## 最佳实践
1. **使用命名空间隔离**:将 Ingress Controller 部署在独立的命名空间
2. **配置资源限制**:为 Ingress Controller 设置合理的 CPU 和内存限制
3. **启用监控**:监控 Ingress Controller 的性能指标
4. **使用 TLS**:为生产环境配置 TLS 证书
5. **配置健康检查**:确保后端 Service 的健康检查正常
6. **使用注解优化**:根据应用需求配置合适的注解
7. **备份配置**:定期备份 Ingress 配置
8. **版本管理**:跟踪 Ingress Controller 的版本更新
## 故障排查
1. **查看 Ingress 状态**:
```bash
kubectl get ingress
kubectl describe ingress <ingress-name>
```
2. **查看 Ingress Controller 日志**:
```bash
kubectl logs -n ingress-nginx <pod-name>
```
3. **测试 DNS 解析**:
```bash
nslookup example.com
```
4. **检查 Service 和 Endpoint**:
```bash
kubectl get svc
kubectl get endpoints
```
5. **验证证书**:
```bash
kubectl get secret tls-secret -o yaml
```
服务端 · 2月21日 15:53
Kubernetes Deployment 的作用是什么?它如何实现滚动更新和回滚?Kubernetes Deployment 是用于管理 Pod 和 ReplicaSet 的声明式更新控制器,它提供了声明式的应用部署和更新能力。
## Deployment 的核心功能
1. **声明式管理**:通过 YAML 文件定义期望状态,Kubernetes 自动实现当前状态到期望状态的转换。
2. **滚动更新**:支持零停机时间的应用更新,逐步替换旧版本的 Pod。
3. **回滚能力**:可以轻松回滚到之前的版本,支持查看更新历史。
4. **自动扩缩容**:支持手动或自动调整 Pod 的副本数量。
5. **自愈能力**:当 Pod 故障或被删除时,自动创建新的 Pod 以维持期望的副本数。
## Deployment 的工作原理
Deployment 通过 **ReplicaSet** 管理 Pod:
1. **ReplicaSet**:确保指定数量的 Pod 副本始终运行。
2. **Pod 模板**:定义 Pod 的规格,包括容器镜像、资源限制等。
3. **更新策略**:控制滚动更新的行为,如最大不可用 Pod 数量、最大激增 Pod 数量。
## Deployment 的 YAML 示例
```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.14.2
ports:
- containerPort: 80
```
## 更新策略
Deployment 支持两种更新策略:
1. **RollingUpdate**(默认):
- 逐步替换 Pod,确保始终有可用 Pod
- 可配置 maxUnavailable 和 maxSurge
- 适用于大多数应用
2. **Recreate**:
- 先删除所有旧 Pod,再创建新 Pod
- 会导致短暂的服务中断
- 适用于无法同时运行新旧版本的应用
## 滚动更新参数
- **maxUnavailable**:更新过程中最多允许多少个 Pod 不可用(默认 25%)
- **maxSurge**:更新过程中最多允许多少个额外的 Pod(默认 25%)
## 回滚操作
查看更新历史:
```bash
kubectl rollout history deployment/nginx-deployment
```
回滚到上一个版本:
```bash
kubectl rollout undo deployment/nginx-deployment
```
回滚到指定版本:
```bash
kubectl rollout undo deployment/nginx-deployment --to-revision=2
```
## 扩缩容
手动扩缩容:
```bash
kubectl scale deployment/nginx-deployment --replicas=5
```
自动扩缩容(HPA):
```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
```
## Deployment 与其他控制器的区别
1. **vs ReplicaSet**:
- Deployment 是 ReplicaSet 的上层控制器
- Deployment 提供更新和回滚能力,ReplicaSet 只能维持副本数
2. **vs StatefulSet**:
- Deployment 适用于无状态应用
- StatefulSet 适用于有状态应用,提供稳定的网络标识和持久化存储
3. **vs DaemonSet**:
- Deployment 可以在任意节点运行指定数量的 Pod
- DaemonSet 确保在每个节点上运行一个 Pod 副本
## 最佳实践
1. **使用声明式配置**:始终使用 YAML 文件定义 Deployment,而不是命令式命令。
2. **设置合理的资源限制**:为容器设置 CPU 和内存的 requests 和 limits。
3. **配置健康检查**:使用 livenessProbe 和 readinessProbe 确保应用健康。
4. **使用多阶段构建**:优化镜像大小,提高部署速度。
5. **设置适当的更新策略**:根据应用特性选择 RollingUpdate 或 Recreate。
6. **使用标签和注解**:为 Deployment 添加有意义的标签和注解,便于管理和追踪。
7. **监控更新过程**:使用 `kubectl rollout status` 监控更新进度。
服务端 · 2月21日 15:53
Kubernetes ConfigMap 和 Secret 的区别是什么?如何使用它们管理应用配置?Kubernetes ConfigMap 和 Secret 是用于管理配置数据的两种重要资源,它们允许将配置与容器镜像分离,提高应用的可移植性和安全性。
## ConfigMap
ConfigMap 用于存储非敏感的配置数据,如应用配置文件、命令行参数、环境变量等。
### ConfigMap 的创建方式
1. **从字面值创建**:
```bash
kubectl create configmap my-config --from-literal=key1=value1 --from-literal=key2=value2
```
2. **从文件创建**:
```bash
kubectl create configmap my-config --from-file=config.properties
```
3. **从目录创建**:
```bash
kubectl create configmap my-config --from-file=./config-dir/
```
4. **从 YAML 文件创建**:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
key1: value1
key2: value2
app.properties: |
server.port=8080
database.url=jdbc:mysql://localhost:3306/mydb
```
### ConfigMap 的使用方式
1. **作为环境变量**:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
env:
- name: KEY1
valueFrom:
configMapKeyRef:
name: my-config
key: key1
```
2. **作为命令行参数**:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
command: ["/bin/sh", "-c"]
args: ["echo $(KEY1)"]
env:
- name: KEY1
valueFrom:
configMapKeyRef:
name: my-config
key: key1
```
3. **挂载为文件**:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-config
```
## Secret
Secret 用于存储敏感信息,如密码、OAuth 令牌、SSH 密钥、证书等。
### Secret 的类型
1. **Opaque**:默认类型,用于存储任意用户数据
2. **kubernetes.io/service-account-token**:用于存储 Service Account 令牌
3. **kubernetes.io/dockercfg**:用于存储 Docker registry 凭据
4. **kubernetes.io/dockerconfigjson**:用于存储 Docker registry JSON 配置
5. **kubernetes.io/basic-auth**:用于存储基本认证凭据
6. **kubernetes.io/ssh-auth**:用于存储 SSH 认证凭据
7. **kubernetes.io/tls**:用于存储 TLS 证书
### Secret 的创建方式
1. **从字面值创建**:
```bash
kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=secret123
```
2. **从文件创建**:
```bash
kubectl create secret generic my-secret --from-file=./username.txt --from-file=./password.txt
```
3. **从 YAML 文件创建**:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: YWRtaW4=
password: c2VjcmV0MTIz
```
注意:Secret 的 data 字段中的值必须是 Base64 编码的。
4. **使用 stringData**:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
stringData:
username: admin
password: secret123
```
stringData 会自动进行 Base64 编码。
### Secret 的使用方式
Secret 的使用方式与 ConfigMap 类似:
1. **作为环境变量**:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: my-secret
key: username
```
2. **挂载为文件**:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
volumes:
- name: secret-volume
secret:
secretName: my-secret
```
3. **拉取镜像**:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: my-private-registry/my-image
imagePullSecrets:
- name: registry-secret
```
## ConfigMap 与 Secret 的区别
| 特性 | ConfigMap | Secret |
|------|-----------|--------|
| 数据类型 | 非敏感数据 | 敏感数据 |
| 存储方式 | 明文存储 | Base64 编码(非加密) |
| 访问控制 | 普通 RBAC | 更严格的 RBAC |
| 大小限制 | 1 MiB | 1 MiB |
| 挂载方式 | 文件、环境变量 | 文件、环境变量 |
## 安全最佳实践
1. **使用 Secret 存储敏感数据**:永远不要将密码、密钥等敏感信息存储在 ConfigMap 中。
2. **启用 Secret 加密**:使用 KMS(Key Management Service)对 etcd 中的 Secret 进行加密。
3. **限制 Secret 访问**:使用 RBAC 限制对 Secret 的访问权限。
4. **使用临时文件**:将 Secret 挂载为临时文件(tmpfs),避免持久化到磁盘。
5. **定期轮换密钥**:定期更新 Secret 中的敏感信息。
6. **使用外部密钥管理**:对于高安全性要求,考虑使用外部密钥管理系统(如 HashiCorp Vault)。
7. **审计 Secret 访问**:启用审计日志,记录对 Secret 的访问。
## 注意事项
1. **Base64 不是加密**:Secret 中的数据只是 Base64 编码,不是加密,需要额外的安全措施。
2. **大小限制**:ConfigMap 和 Secret 都有 1 MiB 的大小限制,超出限制需要拆分。
3. **版本管理**:ConfigMap 和 Secret 的更新不会自动触发 Pod 重启,需要使用 Deployment 的滚动更新或手动重启。
4. **不可变性**:可以将 ConfigMap 和 Secret 设置为不可变(immutable),提高性能和安全性。
服务端 · 2月21日 15:53
Kubernetes 污点(Taints)和容忍度(Tolerations)是什么?如何使用它们控制 Pod 调度?Kubernetes 污点(Taints)和容忍度(Tolerations)是用于控制 Pod 调度的机制,它们允许节点拒绝(或接受)具有特定容忍度的 Pod。
## 污点(Taints)
污点是应用于节点上的键值对,用于阻止 Pod 调度到该节点,除非 Pod 具有匹配的容忍度。
### 污点的组成
每个污点包含三个部分:
1. **Key**:污点的键(必需)
2. **Value**:污点的值(可选)
3. **Effect**:污点的影响(必需)
### 污点的影响类型
1. **NoSchedule**:
- 不会调度新的 Pod 到该节点
- 已存在的 Pod 不受影响
- 适用于专用节点(如 GPU 节点)
2. **PreferNoSchedule**:
- 尽量不调度新的 Pod 到该节点
- 但如果没有其他可用节点,仍可能调度
- 适用于软性限制
3. **NoExecute**:
- 不会调度新的 Pod 到该节点
- 已存在的 Pod 如果没有匹配的容忍度,将被驱逐
- 适用于节点维护或故障场景
### 添加污点
```bash
# 添加 NoSchedule 污点
kubectl taint nodes node1 key=value:NoSchedule
# 添加 NoExecute 污点
kubectl taint nodes node1 key=value:NoExecute
# 添加没有值的污点
kubectl taint nodes node1 key:NoSchedule
```
### 查看污点
```bash
# 查看节点的污点
kubectl describe node node1 | grep Taint
# 查看所有节点的污点
kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
```
### 删除污点
```bash
# 删除指定污点
kubectl taint nodes node1 key:NoSchedule-
# 删除所有指定键的污点
kubectl taint nodes node1 key-
```
## 容忍度(Tolerations)
容忍度是应用于 Pod 上的配置,允许 Pod 调度到具有匹配污点的节点。
### 容忍度的组成
容忍度包含以下字段:
1. **Key**:要容忍的污点键
2. **Operator**:操作符(Equal 或 Exists)
3. **Value**:要容忍的污点值(当 Operator 为 Equal 时需要)
4. **Effect**:要容忍的污点影响
5. **TolerationSeconds**:容忍时间(仅适用于 NoExecute)
### 容忍度操作符
1. **Equal**:
- 键和值都必须匹配
- 需要指定 Value
2. **Exists**:
- 只需要键匹配
- 不需要指定 Value
### 添加容忍度
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
containers:
- name: my-container
image: nginx
```
### 容忍度示例
1. **容忍特定污点**:
```yaml
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
```
2. **容忍所有具有特定键的污点**:
```yaml
tolerations:
- key: "dedicated"
operator: "Exists"
```
3. **容忍所有污点**:
```yaml
tolerations:
- operator: "Exists"
```
4. **容忍 NoExecute 污点并设置容忍时间**:
```yaml
tolerations:
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
```
## 污点和容忍度的匹配规则
1. **键匹配**:
- 如果容忍度的键为空,则匹配所有污点
- 如果污点的键为空,则不能被任何容忍度匹配
2. **操作符匹配**:
- Equal:键和值都必须匹配
- Exists:只需要键匹配
3. **影响匹配**:
- 如果容忍度的影响为空,则匹配所有影响
- 否则,影响必须匹配
## 常见使用场景
### 1. 专用节点
为特定用途的节点添加污点,确保只有特定的 Pod 可以调度到这些节点。
```bash
# 为 GPU 节点添加污点
kubectl taint nodes gpu-node dedicated=gpu:NoSchedule
```
```yaml
# 只有 GPU Pod 可以调度到 GPU 节点
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
containers:
- name: gpu-container
image: nvidia/cuda:11.0.3-base-ubuntu20.04
```
### 2. 节点维护
使用 NoExecute 污点驱逐 Pod,进行节点维护。
```bash
# 标记节点为维护状态
kubectl taint nodes node1 maintenance:NoExecute
```
### 3. 特殊硬件节点
为具有特殊硬件的节点添加污点,确保只有需要这些硬件的 Pod 可以调度。
```bash
# 为 SSD 节点添加污点
kubectl taint nodes ssd-node disktype=ssd:NoSchedule
```
### 4. 故障节点
Kubernetes 自动为故障节点添加污点,驱逐 Pod。
```yaml
# Pod 容忍节点故障
tolerations:
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
```
## 污点和容忍度 vs 亲和性
| 特性 | 污点和容忍度 | 亲和性 |
|------|-------------|--------|
| 作用对象 | 节点和 Pod | 节点和 Pod |
| 作用方向 | 节点拒绝 Pod | Pod 选择节点 |
| 灵活性 | 较低 | 较高 |
| 使用场景 | 专用节点、节点维护 | 性能优化、高可用性 |
## 最佳实践
1. **合理使用污点**:避免过度使用污点,可能导致调度失败
2. **为专用节点添加污点**:确保只有特定的 Pod 可以调度到专用节点
3. **设置合理的容忍时间**:为 NoExecute 污点设置合理的容忍时间,避免频繁驱逐
4. **结合亲和性使用**:结合使用污点/容忍度和亲和性,实现更精细的调度控制
5. **监控节点状态**:监控节点的污点状态,及时处理故障节点
6. **文档化污点策略**:记录污点和容忍度的使用策略,便于团队协作
7. **测试容忍度配置**:在非生产环境测试容忍度配置,确保正确性
## 故障排查
1. **查看节点污点**:
```bash
kubectl describe node <node-name>
```
2. **查看 Pod 容忍度**:
```bash
kubectl describe pod <pod-name>
```
3. **检查调度失败原因**:
```bash
kubectl describe pod <pod-name> | grep -A 10 Events
```
4. **查看调度器日志**:
```bash
kubectl logs -n kube-system <scheduler-pod-name>
```
## 示例:多节点类型集群
```yaml
# Master 节点
apiVersion: v1
kind: Node
metadata:
name: master-node
spec:
taints:
- key: "node-role.kubernetes.io/master"
effect: "NoSchedule"
# GPU 节点
apiVersion: v1
kind: Node
metadata:
name: gpu-node
spec:
taints:
- key: "dedicated"
value: "gpu"
effect: "NoSchedule"
# 普通 Pod(可以调度到普通节点)
apiVersion: v1
kind: Pod
metadata:
name: normal-pod
spec:
containers:
- name: nginx
image: nginx
# GPU Pod(只能调度到 GPU 节点)
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
containers:
- name: gpu-app
image: nvidia/cuda:11.0.3-base-ubuntu20.04
```
服务端 · 2月21日 15:53
什么是 Kubernetes?它的核心概念和工作原理是什么?Kubernetes 是一个开源的容器编排平台,用于自动化容器应用的部署、扩展和管理。它最初由 Google 设计并开发,于 2014 年开源,现在由 Cloud Native Computing Foundation(CNCF)管理。
## 核心概念
Kubernetes 的核心概念包括:
1. **Pod**:Kubernetes 中最小的可部署单元,一个 Pod 可以包含一个或多个容器,这些容器共享网络和存储资源。
2. **Node**:集群中的工作机器,可以是物理机或虚拟机。每个 Node 都运行着容器运行时(如 Docker)、kubelet 和 kube-proxy。
3. **Cluster**:由多个 Node 组成的集合,是 Kubernetes 管理的计算资源池。
4. **Service**:定义一组 Pod 的访问策略,提供稳定的网络端点,即使 Pod 的 IP 地址发生变化。
5. **Deployment**:管理 Pod 和 ReplicaSet 的声明式更新,支持滚动更新和回滚。
6. **ConfigMap**:用于存储非敏感的配置数据,可以挂载到 Pod 中或作为环境变量使用。
7. **Secret**:用于存储敏感信息,如密码、OAuth 令牌和 SSH 密钥。
8. **Namespace**:用于在同一个集群中创建多个虚拟集群,实现资源隔离。
## 工作原理
Kubernetes 采用主从架构:
- **Control Plane(控制平面)**:负责集群的决策和响应,包括 API Server、Scheduler、Controller Manager 和 etcd。
- **Worker Node(工作节点)**:运行容器化应用,包括 kubelet、kube-proxy 和容器运行时。
## 主要特性
- **自动化部署和回滚**:支持声明式配置,自动实现应用的部署和更新。
- **服务发现和负载均衡**:自动为容器分配 IP 和 DNS 名称,实现负载均衡。
- **自动扩缩容**:根据 CPU 使用率或其他指标自动调整 Pod 数量。
- **自愈能力**:自动重启失败的容器、替换节点、重新调度 Pod。
- **存储编排**:自动挂载存储系统,如本地存储、云存储等。
## 应用场景
Kubernetes 广泛应用于微服务架构、CI/CD 流水线、大数据处理、机器学习等场景,是云原生应用的标准平台。
服务端 · 2月21日 15:53
Kubernetes 工作节点(Worker Node)包含哪些组件?它们的作用是什么?Kubernetes 工作节点(Worker Node)是集群中运行容器化应用的工作机器,可以是物理机或虚拟机。每个工作节点都运行着必要的组件来管理和运行 Pod。
## 工作节点组件
### 1. kubelet
kubelet 是工作节点上的主要代理,负责与控制平面通信并管理 Pod。
**主要职责**:
- 监听 API Server,获取 Pod 的期望状态
- 确保容器按照 Pod 规范运行
- 定期向控制平面报告节点和 Pod 的状态
- 处理容器的生命周期(创建、启动、停止、删除)
- 挂载和卸载存储卷
- 运行健康检查(livenessProbe、readinessProbe、startupProbe)
**工作原理**:
1. kubelet 从 API Server 获取分配到该节点的 Pod 规范
2. 通过容器运行时接口(CRI)与容器运行时交互
3. 使用容器运行时创建和管理容器
4. 定期向 API Server 汇报节点和 Pod 状态
**配置文件**:`/var/lib/kubelet/config.yaml`
**默认端口**:10250(HTTPS)、10248(健康检查)、10255(只读 HTTP)
### 2. kube-proxy
kube-proxy 负责维护节点上的网络规则,实现 Service 的负载均衡和服务发现。
**主要职责**:
- 监听 API Server 的 Service 和 Endpoint 变化
- 维护网络规则(iptables 或 IPVS)
- 将流量转发到后端 Pod
- 实现 Service 的负载均衡
**工作模式**:
1. **iptables 模式**(默认):
- 使用 iptables 规则实现流量转发
- 性能较好,但规则更新有延迟
- 不支持复杂的负载均衡算法
2. **ipvs 模式**:
- 使用 Linux IPVS 实现负载均衡
- 支持多种负载均衡算法(轮询、最少连接、源地址哈希等)
- 性能更高,适合大规模集群
- 需要加载 ipvs 内核模块
3. **userspace 模式**(已废弃):
- 在用户空间实现负载均衡
- 性能较差,已不再推荐使用
**配置示例**:
```yaml
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
```
### 3. 容器运行时(Container Runtime)
容器运行时负责运行容器的核心组件。Kubernetes 使用容器运行时接口(CRI)与容器运行时交互。
**支持的容器运行时**:
1. **containerd**(推荐):
- CNCF 毕业项目
- 轻量级、高性能
- Docker 的底层运行时
2. **CRI-O**:
- 专为 Kubernetes 设计
- 轻量级、安全
- OCI 兼容
3. **Docker Engine**(通过 dockershim,已废弃):
- Kubernetes 1.24+ 已移除 dockershim
- 不再推荐使用
**CRI 工作流程**:
1. kubelet 通过 CRI 接口调用容器运行时
2. 容器运行时创建和管理容器
3. 容器运行时返回容器状态信息
## 节点状态
### 节点条件(Conditions)
节点条件描述节点的健康状态:
1. **Ready**:节点是否健康并可以运行 Pod
- True:节点健康
- False:节点不健康
- Unknown:节点控制器无法获取节点状态
2. **MemoryPressure**:节点内存压力
- True:节点内存不足
3. **DiskPressure**:节点磁盘压力
- True:节点磁盘空间不足
4. **PIDPressure**:节点进程压力
- True:节点进程数过多
5. **NetworkUnavailable**:节点网络不可用
- True:节点网络配置有问题
### 节点容量和可分配资源
- **Capacity**:节点的总资源(CPU、内存、存储)
- **Allocatable**:节点可分配给 Pod 的资源(扣除系统预留)
### 节点信息
- **OS Image**:操作系统镜像
- **Kernel Version**:内核版本
- **Kubelet Version**:kubelet 版本
- **Container Runtime Version**:容器运行时版本
## 节点管理
### 节点维护
1. **安全驱逐 Pod**:
```bash
kubectl drain <node-name> --ignore-daemonsets
```
2. **标记节点为不可调度**:
```bash
kubectl cordon <node-name>
```
3. **取消节点不可调度标记**:
```bash
kubectl uncordon <node-name>
```
### 节点污点(Taints)
污点用于阻止 Pod 调度到特定节点:
```bash
# 添加污点
kubectl taint nodes <node-name> key=value:NoSchedule
# 查看污点
kubectl describe node <node-name> | grep Taint
# 删除污点
kubectl taint nodes <node-name> key:NoSchedule-
```
污点类型:
- **NoSchedule**:不调度新 Pod,已有 Pod 不受影响
- **PreferNoSchedule**:尽量不调度,但不是强制
- **NoExecute**:不调度新 Pod,已有 Pod 会被驱逐(除非有容忍度)
### 节点标签(Labels)
标签用于组织和选择节点:
```bash
# 添加标签
kubectl label nodes <node-name> disktype=ssd
# 查看标签
kubectl get nodes --show-labels
# 删除标签
kubectl label nodes <node-name> disktype-
```
## 节点健康检查
kubelet 定期执行健康检查:
1. **节点状态检查**:检查节点资源是否充足
2. **容器健康检查**:执行 livenessProbe 和 readinessProbe
3. **镜像拉取检查**:检查镜像是否可用
## 最佳实践
1. **资源预留**:为系统进程和 kubelet 预留足够的 CPU 和内存
2. **监控节点**:监控节点的 CPU、内存、磁盘和网络使用情况
3. **日志收集**:收集 kubelet 和容器运行时的日志
4. **安全加固**:
- 使用 TLS 加密通信
- 限制 kubelet API 访问
- 定期更新组件版本
5. **节点维护**:使用 drain 命令安全维护节点
6. **自动扩缩容**:使用 Cluster Autoscaler 自动调整节点数量
7. **污点和容忍度**:合理使用污点和容忍度控制 Pod 调度
8. **节点亲和性**:使用节点亲和性优化 Pod 分配
## 故障排查
1. **查看节点状态**:
```bash
kubectl describe node <node-name>
```
2. **查看 kubelet 日志**:
```bash
journalctl -u kubelet
```
3. **查看容器运行时日志**:
```bash
journalctl -u containerd
```
4. **检查节点资源**:
```bash
kubectl top nodes
```
服务端 · 2月21日 15:53
Kubernetes 亲和性(Affinity)和反亲和性(Anti-Affinity)是什么?如何使用它们控制 Pod 调度?Kubernetes 亲和性(Affinity)和反亲和性(Anti-Affinity)是用于控制 Pod 调度的机制,它们允许用户定义 Pod 与节点或其他 Pod 之间的关系,从而影响调度决策。
## 亲和性类型
### 1. 节点亲和性(Node Affinity)
节点亲和性用于控制 Pod 调度到哪些节点上。
#### requiredDuringSchedulingIgnoredDuringExecution
硬性要求,Pod 必须调度到满足条件的节点上,否则调度失败。
```yaml
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- us-west-1a
containers:
- name: my-container
image: nginx
```
#### preferredDuringSchedulingIgnoredDuringExecution
软性偏好,调度器优先选择满足条件的节点,但如果没有满足条件的节点,也可以调度到其他节点。
```yaml
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: my-container
image: nginx
```
### 2. Pod 亲和性(Pod Affinity)
Pod 亲和性用于控制 Pod 调度到哪些节点上,基于已经运行在该节点上的 Pod。
#### requiredDuringSchedulingIgnoredDuringExecution
```yaml
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: topology.kubernetes.io/zone
containers:
- name: my-container
image: nginx
```
#### preferredDuringSchedulingIgnoredDuringExecution
```yaml
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: topology.kubernetes.io/zone
containers:
- name: my-container
image: nginx
```
### 3. Pod 反亲和性(Pod Anti-Affinity)
Pod 反亲和性用于控制 Pod 不调度到哪些节点上,基于已经运行在该节点上的 Pod。
#### requiredDuringSchedulingIgnoredDuringExecution
```yaml
apiVersion: v1
kind: Pod
metadata:
name: with-pod-antiaffinity
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname
containers:
- name: my-container
image: nginx
```
#### preferredDuringSchedulingIgnoredDuringExecution
```yaml
apiVersion: v1
kind: Pod
metadata:
name: with-pod-antiaffinity
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname
containers:
- name: my-container
image: nginx
```
## 操作符类型
1. **In**:标签的值在给定的列表中
2. **NotIn**:标签的值不在给定的列表中
3. **Exists**:标签存在
4. **DoesNotExist**:标签不存在
5. **Gt**:标签的值大于给定值(仅适用于数值)
6. **Lt**:标签的值小于给定值(仅适用于数值)
## 拓扑域键(Topology Key)
拓扑域键用于定义节点的分组方式,常见的拓扑域键包括:
1. **kubernetes.io/hostname**:按主机名分组
2. **topology.kubernetes.io/zone**:按可用区分组
3. **topology.kubernetes.io/region**:按区域分组
4. **node.kubernetes.io/instance-type**:按实例类型分组
## 亲和性规则的行为
### 调度阶段(During Scheduling)
- **required**:硬性要求,必须满足
- **preferred**:软性偏好,优先满足
### 执行阶段(During Execution)
- **Ignored**:Pod 运行后,如果条件不再满足,不影响已运行的 Pod
- **Required**:Pod 运行后,如果条件不再满足,需要驱逐 Pod(目前不支持)
## 亲和性 vs nodeSelector
| 特性 | nodeSelector | 节点亲和性 |
|------|--------------|-----------|
| 复杂度 | 简单 | 复杂 |
| 灵活性 | 低 | 高 |
| 支持的操作符 | 等值 | 多种操作符 |
| 优先级 | 无 | 支持权重 |
## 使用场景
### 节点亲和性使用场景
1. **硬件要求**:将 Pod 调度到具有特定硬件的节点(如 GPU、SSD)
2. **区域要求**:将 Pod 调度到特定区域或可用区
3. **操作系统要求**:将 Pod 调度到运行特定操作系统的节点
### Pod 亲和性使用场景
1. **通信优化**:将需要频繁通信的 Pod 调度到同一节点,减少网络延迟
2. **依赖关系**:将依赖的 Pod 调度到同一节点,提高性能
3. **数据局部性**:将 Pod 调度到存储数据的节点附近
### Pod 反亲和性使用场景
1. **高可用性**:将相同应用的 Pod 分散到不同节点,避免单点故障
2. **资源竞争**:避免资源密集型 Pod 调度到同一节点
3. **故障隔离**:将不同应用的 Pod 分散到不同节点,减少故障影响范围
## 最佳实践
1. **合理使用硬性要求**:避免过度使用 required 规则,可能导致调度失败
2. **设置合理的权重**:为 preferred 规则设置合适的权重,影响调度决策
3. **使用标签和注解**:为节点和 Pod 添加有意义的标签,便于使用亲和性规则
4. **监控调度结果**:监控 Pod 的调度情况,确保亲和性规则按预期工作
5. **结合污点和容忍度**:结合使用亲和性和污点/容忍度,实现更精细的调度控制
6. **避免过度复杂**:避免创建过于复杂的亲和性规则,影响调度性能
7. **测试规则**:在非生产环境测试亲和性规则,确保正确性
## 示例:高可用 Web 应用
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: kubernetes.io/hostname
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: web
image: nginx
ports:
- containerPort: 80
```
这个示例确保:
1. 每个 Web Pod 调度到不同的节点(高可用性)
2. 优先选择具有 SSD 的节点(性能优化)
服务端 · 2月21日 15:53
Kubernetes 中 Pod 的概念是什么?它的生命周期和重启策略有哪些?Kubernetes 中的 Pod 是最小的可部署单元,它包含一个或多个紧密相关的容器,这些容器共享网络和存储资源。
## Pod 的特点
1. **共享网络命名空间**:同一个 Pod 中的容器共享同一个 IP 地址和端口空间,可以通过 localhost 相互通信。
2. **共享存储卷**:Pod 中的容器可以共享挂载的存储卷,实现数据共享和持久化。
3. **原子性调度**:Pod 作为一个整体被调度到同一个 Node 上运行。
4. **临时性**:Pod 是临时的、可替换的,当 Pod 被删除或 Node 发生故障时,Pod 不会自动恢复。
## Pod 的生命周期
Pod 的生命周期包括以下阶段:
1. **Pending**:Pod 已被创建,但容器尚未启动,可能是因为镜像下载中或资源不足。
2. **Running**:Pod 中的所有容器都已创建,至少有一个容器正在运行。
3. **Succeeded**:Pod 中的所有容器都已成功终止。
4. **Failed**:Pod 中的所有容器都已终止,但至少有一个容器以失败状态终止。
5. **Unknown**:无法获取 Pod 的状态,通常是因为与 Pod 所在的 Node 通信失败。
## Pod 的重启策略
Kubernetes 支持三种 Pod 重启策略:
1. **Always**:容器失败时总是重启,这是默认策略。
2. **OnFailure**:只有在容器以非零退出码失败时才重启。
3. **Never**:容器失败时不重启。
## Pod 与容器的关系
Pod 是容器的封装,一个 Pod 可以包含:
- 单个主容器(最常见)
- 一个主容器加一个或多个辅助容器(Sidecar 模式)
- 多个协作的容器
## 最佳实践
1. **一个 Pod 一个容器**:对于大多数应用,建议一个 Pod 只包含一个容器,这样可以更好地管理和扩展。
2. **使用 Sidecar 模式**:当需要多个紧密协作的容器时,可以使用 Sidecar 模式,例如日志收集、监控代理等。
3. **避免在 Pod 中运行多个不相关的容器**:这会增加管理的复杂性,不利于扩展和故障排查。
4. **合理设置资源限制**:为 Pod 设置 CPU 和内存的 requests 和 limits,避免资源争用。
5. **使用健康检查**:配置 livenessProbe 和 readinessProbe,确保 Pod 的健康状态。
服务端 · 2月21日 15:53
Kubernetes Service 的作用是什么?有哪些类型?它们之间有什么区别?Kubernetes Service 是定义一组 Pod 的访问策略的抽象,它为 Pod 提供稳定的网络端点,即使 Pod 的 IP 地址发生变化,Service 也能保证服务的可访问性。
## Service 的作用
1. **服务发现**:Service 为一组 Pod 提供统一的访问入口,客户端不需要知道具体的 Pod IP 地址。
2. **负载均衡**:Service 自动将流量分发到后端的多个 Pod,实现负载均衡。
3. **稳定的网络标识**:Service 拥有固定的 IP 地址和 DNS 名称,即使 Pod 重新创建,Service 的地址也不会改变。
## Service 的类型
Kubernetes 支持四种 Service 类型:
1. **ClusterIP**(默认):
- 在集群内部暴露服务
- 只能从集群内部访问
- 适合内部服务之间的通信
2. **NodePort**:
- 在每个 Node 上开放一个端口
- 可以通过 NodeIP:Port 从外部访问
- 端口范围:30000-32767
3. **LoadBalancer**:
- 在云提供商处创建外部负载均衡器
- 自动将流量分发到 NodePort
- 需要云提供商支持
4. **ExternalName**:
- 将服务映射到外部 DNS 名称
- 不创建代理或负载均衡器
- 适用于访问外部服务
## Service 的工作原理
Service 通过 **kube-proxy** 实现:
1. **iptables 模式**(默认):
- kube-proxy 监听 API Server 的 Service 和 Endpoint 变化
- 使用 iptables 规则将流量转发到后端 Pod
- 性能较好,但更新规则时会有延迟
2. **IPVS 模式**:
- 使用 Linux IPVS(IP Virtual Server)实现负载均衡
- 支持多种负载均衡算法(轮询、最少连接等)
- 性能更高,适合大规模集群
## Service 的选择器
Service 通过 **selector** 选择要代理的 Pod:
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
```
## Endpoint
Service 的后端由 **Endpoint** 对象维护,Endpoint 包含所有匹配 selector 的 Pod 的 IP 地址和端口。
## 无选择器的 Service
Service 可以不指定 selector,此时需要手动创建 Endpoint 对象,用于:
- 访问集群外部的服务
- 访问其他命名空间的服务
- 访问外部数据库等
## 最佳实践
1. **使用 ClusterIP 作为默认类型**:除非需要外部访问,否则使用 ClusterIP 以提高安全性。
2. **合理设置 sessionAffinity**:对于有状态的应用,可以设置 sessionAffinity 为 ClientIP,实现会话保持。
3. **使用 Headless Service**:对于需要直接访问 Pod 的场景(如 StatefulSet),可以使用 Headless Service(ClusterIP: None)。
4. **监控 Service 的健康状态**:定期检查 Endpoint 的状态,确保后端 Pod 正常。
5. **使用 Ingress 替代 LoadBalancer**:对于 HTTP/HTTPS 服务,使用 Ingress 可以更灵活地管理路由和 SSL。
服务端 · 2月21日 15:53
Kubernetes PersistentVolume 和 PersistentVolumeClaim 的区别是什么?如何使用它们管理存储?Kubernetes PersistentVolume(PV)和 PersistentVolumeClaim(PVC)是用于管理存储的两种重要资源,它们实现了存储资源的声明式管理和动态分配。
## PersistentVolume(PV)
PersistentVolume 是集群中的一块存储,由管理员预先配置或通过存储类动态创建。PV 是集群级别的资源,独立于 Pod 的生命周期。
### PV 的生命周期
1. **Provisioning(配置)**:
- 静态配置:管理员手动创建 PV
- 动态配置:通过 StorageClass 自动创建
2. **Binding(绑定)**:
- PVC 请求存储时,控制器将 PVC 绑定到合适的 PV
- 绑定是一对一的,一旦绑定,PV 就专属于该 PVC
3. **Using(使用)**:
- Pod 通过 PVC 使用存储
- 存储可以挂载到 Pod 的指定路径
4. **Releasing(释放)**:
- PVC 删除后,PV 进入 Released 状态
- PV 中的数据仍然保留
5. **Reclaiming(回收)**:
- Retain(保留):手动回收
- Recycle(回收):已废弃,使用动态配置替代
- Delete(删除):自动删除 PV 和底层存储
### PV 的访问模式
1. **ReadWriteOnce(RWO)**:
- 卷可以被单个节点以读写模式挂载
- 适用于块存储
2. **ReadOnlyMany(ROX)**:
- 卷可以被多个节点以只读模式挂载
- 适用于共享只读数据
3. **ReadWriteMany(RWX)**:
- 卷可以被多个节点以读写模式挂载
- 适用于文件系统(如 NFS)
4. **ReadWriteOncePod(RWOP)**:
- 卷可以被单个 Pod 以读写模式挂载
- 确保同一时间只有一个 Pod 访问
### PV 的状态
1. **Available**:可用,未绑定到任何 PVC
2. **Bound**:已绑定到 PVC
3. **Released**:PVC 已删除,但资源尚未被集群回收
4. **Failed**:自动回收失败
## PersistentVolumeClaim(PVC)
PVC 是用户对存储的请求,类似于 Pod 对计算资源的请求。PVC 是命名空间级别的资源。
### PVC 的配置
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
selector:
matchLabels:
environment: production
```
### PVC 的使用
1. **在 Pod 中使用 PVC**:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: my-volume
mountPath: /data
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: my-pvc
```
2. **在 Deployment 中使用 PVC**:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: my-pvc
containers:
- name: my-container
image: nginx
volumeMounts:
- name: my-volume
mountPath: /data
```
## StorageClass
StorageClass 定义了不同类型的存储,支持动态配置 PV。
### StorageClass 的配置
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
iopsPerGB: "10"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
```
### 常见的 Provisioner
1. **kubernetes.io/aws-ebs**:AWS EBS 块存储
2. **kubernetes.io/gce-pd**:GCE 持久化磁盘
3. **kubernetes.io/azure-disk**:Azure 磁盘
4. **kubernetes.io/azure-file**:Azure 文件存储
5. **kubernetes.io/cinder**:OpenStack Cinder
6. **kubernetes.io/nfs**:NFS 存储
7. **rancher.io/local-path**:本地路径存储
### StorageClass 参数
1. **provisioner**:存储提供者
2. **parameters**:存储提供者特定的参数
3. **reclaimPolicy**:回收策略(Delete 或 Retain)
4. **volumeBindingMode**:
- Immediate:立即绑定
- WaitForFirstConsumer:等待第一个消费者
5. **allowVolumeExpansion**:是否允许卷扩展
## 动态配置
动态配置允许根据 PVC 自动创建 PV,无需管理员手动创建。
### 动态配置流程
1. 用户创建 PVC,指定 StorageClass
2. PersistentVolumeController 监听到 PVC
3. 控制器调用 StorageClass 的 provisioner 创建 PV
4. PV 绑定到 PVC
5. Pod 可以使用 PVC
### 动态配置示例
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: fast
```
## 静态配置
静态配置需要管理员手动创建 PV,适用于特定的存储需求。
### 静态 PV 示例
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: manual-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /mnt/data
```
## PV 和 PVC 的区别
| 特性 | PV | PVC |
|------|----|-----|
| 作用域 | 集群级别 | 命名空间级别 |
| 创建者 | 管理员或动态配置 | 用户 |
| 用途 | 提供存储资源 | 请求存储资源 |
| 生命周期 | 独立于 Pod | 依赖于 Pod |
## 最佳实践
1. **使用动态配置**:优先使用 StorageClass 动态配置,减少手动管理
2. **设置合理的回收策略**:生产环境使用 Retain,测试环境使用 Delete
3. **使用访问模式**:根据应用需求选择合适的访问模式
4. **监控存储使用**:监控 PV 和 PVC 的使用情况
5. **备份重要数据**:定期备份 PV 中的重要数据
6. **使用标签和注解**:为 PV 和 PVC 添加有意义的标签和注解
7. **设置资源限制**:为 PVC 设置合理的存储请求
8. **使用存储类**:为不同的应用需求创建不同的 StorageClass
## 故障排查
1. **查看 PV 状态**:
```bash
kubectl get pv
kubectl describe pv <pv-name>
```
2. **查看 PVC 状态**:
```bash
kubectl get pvc
kubectl describe pvc <pvc-name>
```
3. **查看 StorageClass**:
```bash
kubectl get storageclass
kubectl describe storageclass <sc-name>
```
4. **查看 Pod 挂载情况**:
```bash
kubectl describe pod <pod-name>
```
5. **查看事件**:
```bash
kubectl get events --sort-by=.metadata.creationTimestamp
```
服务端 · 2月21日 15:53