一、核心概念理解
1. 什么是Kubernetes?它解决了什么问题?
答案:
Kubernetes(K8S)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。
解决的核心问题:
- 服务发现与负载均衡:自动分配IP地址和DNS名称,实现流量负载均衡
- 自动化部署与回滚:声明式配置,支持滚动更新和快速回滚
- 自动装箱:根据资源需求和约束自动调度容器到最优节点
- 自我修复:自动重启失败容器,替换不健康节点上的容器
- 配置管理:集中管理敏感信息和配置数据
- 水平扩展:通过简单命令或UI实现应用的自动扩缩容
深入理解:
在微服务架构下,传统的部署方式面临诸多挑战:服务实例众多、部署复杂、资源利用率低、故障恢复困难。K8S通过容器编排技术,将基础设施抽象化,让开发者专注于业务逻辑而非底层运维。
2. 请详细解释K8S的架构组件
答案:
Kubernetes采用Master-Worker架构,分为控制平面和数据平面。
控制平面组件(Master Node):
API Server (kube-apiserver)
- 集群的统一入口,所有操作都通过RESTful API进行
- 负责认证、授权、准入控制
- 是唯一直接操作etcd的组件
- 支持水平扩展以提高可用性
etcd
- 分布式键值存储,保存集群所有数据
- 使用Raft协议保证数据一致性
- 是集群状态的唯一数据源(Single Source of Truth)
- 建议部署奇数个节点(3/5/7)保证高可用
Controller Manager (kube-controller-manager)
- 运行控制器进程的守护进程
- 包含多个控制器:Node Controller、Replication Controller、Endpoints Controller、Service Account Controller等
- 通过控制循环监控集群状态,确保实际状态与期望状态一致
Scheduler (kube-scheduler)
- 负责Pod调度决策
- 根据资源需求、亲和性规则、污点容忍等因素选择最优节点
- 调度过程分为预选(Predicates)和优选(Priorities)两个阶段
数据平面组件(Worker Node):
Kubelet
- 运行在每个节点上的主要代理
- 负责维护Pod生命周期,确保容器运行在Pod中
- 向API Server报告节点和Pod状态
- 执行容器健康检查
Kube-proxy
- 维护节点上的网络规则
- 实现Service的虚拟IP功能
- 支持三种代理模式:userspace、iptables、IPVS
Container Runtime
- 负责运行容器的软件
- 支持CRI(Container Runtime Interface)标准
- 常见实现:containerd、CRI-O、Docker(通过dockershim,已废弃)
3. Pod是什么?为什么需要Pod而不是直接使用容器?
答案:
Pod是Kubernetes中最小的可部署单元,是一个或多个容器的集合。
设计理念:
共享网络命名空间
- Pod内所有容器共享同一个网络栈
- 通过localhost相互通信,简化容器间通信
- 共享相同的IP地址和端口空间
共享存储卷
- Pod可以定义一组共享的Volume
- 容器可以挂载这些Volume实现数据共享
- 适合需要紧密协作的容器组合
生命周期管理单元
- Pod作为调度、部署、扩缩容的原子单位
- 简化了管理复杂度
- 保证了容器组的一致性
典型使用场景:
yaml
# Sidecar模式示例
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: web-server
image: nginx:1.21
ports:
- containerPort: 80
- name: log-collector
image: fluent/fluent-bit:1.8
volumeMounts:
- name: logs
mountPath: /var/log/nginx
volumes:
- name: logs
emptyDir: {}
为什么不直接使用容器?
- 容器是进程级别的隔离,Pod提供了更高层次的抽象
- 多容器协作场景下,Pod确保它们始终调度到同一节点
- Pod提供了统一的生命周期管理和资源配额
- 符合云原生的最佳实践,支持微服务架构
4. Namespace的作用是什么?
答案:
Namespace是Kubernetes用于实现多租户资源隔离的机制。
核心功能:
逻辑隔离
- 将集群资源划分为多个逻辑组
- 不同团队或项目使用独立的命名空间
- 避免资源命名冲突
资源配额管理
- 通过ResourceQuota限制命名空间的资源使用
- 防止某个团队占用过多集群资源
- 实现资源的公平分配
访问控制
- 结合RBAC实现细粒度权限控制
- 用户只能访问授权的命名空间
- 提高集群安全性
默认命名空间:
- default:默认命名空间,未指定时使用
- kube-system:K8S系统组件使用
- kube-public:所有用户可读,通常用于集群信息
- kube-node-lease:节点心跳信息,提高性能
实践示例:
yaml
# 创建命名空间并设置资源配额
apiVersion: v1
kind: Namespace
metadata:
name: dev-team
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: dev-team
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
pods: "50"
最佳实践:
- 按环境划分:dev、staging、production
- 按团队划分:team-a、team-b、team-c
- 按应用划分:app1、app2、app3
- 避免过度细分,增加管理复杂度
5. Label和Selector的作用机制是什么?
答案:
Label是附加到Kubernetes对象上的键值对,Selector用于筛选具有特定Label的对象。
Label设计原则:
灵活性
- 键值对形式,支持多维度标记
- 可以随时添加、修改、删除
- 不影响对象的核心功能
标识信息
- 环境标识:env=production、env=dev
- 版本标识:version=v1.2.3
- 层级标识:tier=frontend、tier=backend
- 团队标识:team=platform、team=business
Selector类型:
基于等值的Selector
yaml
selector:
env: production
tier: frontend
基于集合的Selector
yaml
selector:
matchLabels:
app: nginx
matchExpressions:
- key: env
operator: In
values:
- production
- staging
- key: tier
operator: NotIn
values:
- cache
实际应用场景:
yaml
# Service通过Selector选择Pod
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
tier: frontend
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
# Deployment管理具有特定Label的Pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 3
selector:
matchLabels:
app: web
tier: frontend
template:
metadata:
labels:
app: web
tier: frontend
version: v2.0
spec:
containers:
- name: nginx
image: nginx:1.21
最佳实践:
- 使用有意义的标签键名,遵循命名规范
- 关键标签应该稳定,避免频繁变更
- 组合使用多个标签实现精确筛选
- 预留扩展标签,支持未来需求变化
二、对象与资源管理
6. Deployment、ReplicaSet、Pod之间的关系是什么?
答案:
三者形成层级管理关系,Deployment管理ReplicaSet,ReplicaSet管理Pod。
关系图解:
Deployment
├── ReplicaSet (version 1)
│ ├── Pod 1
│ ├── Pod 2
│ └── Pod 3
└── ReplicaSet (version 2) - 滚动更新时创建
├── Pod 4
├── Pod 5
└── Pod 6
各自职责:
Pod
- 最小部署单元
- 封装容器、存储、网络配置
- 短暂的,可替换的
ReplicaSet
- 确保指定数量的Pod副本运行
- 通过Label Selector识别管理的Pod
- 自动替换失败的Pod
- 支持Pod模板定义
Deployment
- 声明式更新ReplicaSet和Pod
- 支持滚动更新和回滚
- 管理多个ReplicaSet版本
- 提供发布策略控制
滚动更新过程:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 超出期望Pod数的最大值
maxUnavailable: 1 # 不可用Pod的最大数量
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
版本管理示例:
bash
# 查看滚动更新状态
kubectl rollout status deployment/nginx-deployment
# 查看历史版本
kubectl rollout history deployment/nginx-deployment
# 回滚到上一版本
kubectl rollout undo deployment/nginx-deployment
# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2
使用建议:
- 生产环境优先使用Deployment,不直接创建ReplicaSet
- Deployment提供了完整的版本控制和发布管理
- ReplicaSet主要由Deployment自动管理
- 直接操作Pod仅用于调试和临时任务
7. StatefulSet和Deployment的区别是什么?
答案:
StatefulSet用于管理有状态应用,Deployment用于管理无状态应用。
核心差异对比:
| 特性 | StatefulSet | Deployment |
|---|---|---|
| Pod命名 | 有序且稳定(pod-0, pod-1) | 随机生成 |
| 网络标识 | 稳定的网络ID | 动态分配 |
| 存储 | 稳定的持久化存储 | 通常使用临时存储 |
| 启动顺序 | 有序创建和删除 | 并行创建和删除 |
| 更新策略 | 支持分区更新 | 支持滚动更新 |
| 使用场景 | 数据库、消息队列 | Web应用、API服务 |
StatefulSet关键特性:
稳定的网络标识符
yaml
# 每个Pod获得稳定的DNS名称
<pod-name>.<service-name>.<namespace>.svc.cluster.local
# 示例:mysql-0.mysql-service.default.svc.cluster.local
有序部署和扩缩容
- Pod按顺序创建:0, 1, 2, ...
- 必须等待前一个Pod Ready才创建下一个
- 删除时逆序进行:..., 2, 1, 0
持久化存储绑定
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-service
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumeClaimTemplates: # 每个Pod独立的PVC
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
典型应用场景:
StatefulSet适用于:
- 数据库:MySQL、PostgreSQL、MongoDB
- 分布式系统:ZooKeeper、Kafka、Elasticsearch
- 需要稳定网络标识的应用
Deployment适用于:
- 无状态Web应用
- 微服务API
- 批处理任务
- 可以随时替换的服务
最佳实践:
- 为StatefulSet创建Headless Service实现稳定网络
- 使用volumeClaimTemplates自动创建PVC
- 设置合理的更新策略(RollingUpdate或OnDelete)
- 谨慎处理StatefulSet的删除,避免数据丢失
8. DaemonSet的使用场景有哪些?
答案:
DaemonSet确保所有(或某些)节点上运行一个Pod副本,主要用于集群级别的系统服务。
典型使用场景:
日志收集
yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: kube-system
spec:
selector:
matchLabels:
name: fluentd
template:
metadata:
labels:
name: fluentd
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
监控代理
- Prometheus Node Exporter:采集节点指标
- Datadog Agent:性能监控
- 每个节点运行监控Agent收集本地数据
网络插件
- Calico、Flannel、Weave Net
- 为每个节点配置网络策略
- 实现跨节点Pod通信
存储插件
- Ceph、GlusterFS客户端
- 在每个节点上挂载分布式存储
- 为Pod提供持久化存储能力
节点选择与调度:
yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: monitoring-agent
spec:
selector:
matchLabels:
app: monitoring
template:
metadata:
labels:
app: monitoring
spec:
nodeSelector:
monitoring: "true" # 仅在标记的节点运行
containers:
- name: agent
image: monitoring-agent:latest
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
更新策略:
yaml
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 逐个更新节点上的Pod
关键特性:
- 自动在新节点上部署Pod
- 节点删除时自动清理Pod
- 可通过nodeSelector或nodeAffinity控制部署范围
- 支持滚动更新策略
三、总结
本文档涵盖了Kubernetes基础概念的核心面试问题,包括:
- K8S的本质、架构和组件
- Pod、Namespace、Label等基础对象
- Deployment、StatefulSet、DaemonSet等控制器
掌握这些基础概念是深入学习K8S的前提,建议结合实际操作加深理解。