Kubernetes 概述
Kubernetes(简称 K8s)是云原生部署的核心平台,起源于谷歌的 Borg 系统,后由 Go 语言重写并开源。它专注于微服务的自动化管理,提供自愈、伸缩、调度、监控等能力,使开发者无需关注底层基础设施,专注于业务逻辑实现。
核心功能
- 容器编排:跨主机调度容器,优化资源利用率。
- 自动化运维:支持滚动更新、回滚、自我修复(如节点故障时自动重启容器)。
- 服务发现与负载均衡:自动管理容器 IP 和流量分发。
- 存储与配置管理:支持外部存储挂载和集中化配置。
- 弹性伸缩:根据 CPU 负载或手动指令动态调整实例数量。
解决的问题
- 裸跑 Docker 的集群管理难题(如单机限制、高管理成本)。
- 缺乏容灾、生命周期管理、统一配置工具等痛点。
关键特性
- 声明式管理:通过 YAML 文件定义应用状态,K8s 自动实现预期状态。
- 批处理任务:支持定时任务和一次性任务,适合数据分析场景。
Kubernetes 架构与组件
采用 Master/Worker 架构,核心组件分工明确:
Master 节点组件
Kube-apiserver
- 集群的入口,提供 RESTful API 处理所有资源操作(增删改查)。
- 接收 CLI 或 UI 请求,协调其他组件执行任务。
Kube-controller-manager
- 运行控制器(如 Node Controller、Deployment Controller),监控集群状态并确保符合预期。
- 例如:节点宕机时自动替换 Pod,维持副本数。
Worker 节点组件
Kubelet
- 节点上的代理,负责与 Master 通信并管理容器生命周期。
Kube-proxy
- 实现服务发现和负载均衡,维护网络规则。
其他核心组件
Etcd
- 分布式键值存储,保存集群所有配置和状态数据。
Scheduler
- 根据资源需求调度 Pod 到合适的 Worker 节点。
示例:部署应用
定义 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:latest
ports:
- containerPort: 80
通过以下命令部署:
bash
kubectl apply -f nginx-deployment.yaml
K8s 将自动创建 3 个 Nginx Pod,并确保它们持续运行。
学习资源
- 官网文档 :kubernetes.io
- GitHub 仓库 :github.com/kubernetes
- CNCF 社区:提供认证(如 CKA)和实战教程。
| 控制器类型 | 作用 |
|---|---|
| Node Controller(节点控制器) | 负责在节点出现故障时发现和响应。 |
| Replication Controller(副本控制器) | 负责保证集群中一个 RC(资源对象 Replication Controller)所关联的 Pod 副本数始终保持预设值。可以理解成确保集群中有且仅有 N 个 Pod 实例,N 是 RC 中定义的 Pod 副本数量。 |
| EndpointsController(端点控制器) | 填充端点对象(即连接 Services 和 Pods),负责监听 Service 和对应的 Pod副本的变化。 可以理解端点是一个服务暴露出来的访问点,如果需要访问一个服务,则必须知道它的 endpoint。 |
| Service Account & Token Controllers(服务帐户和令牌控制器) | 为新的命名空间创建默认帐户和 API 访问令牌。 |
| ResourceQuota Controller(资源配额控制器) | 确保指定的资源对象在任何时候都不会超量占用系统物理资源。 |
| Namespace Controller(命名空间控制器) | 管理 namespace 的生命周期。 |
| Service Controller(服务控制器) | 属于 K8S 集群与外部的云平台之间的一个接口控制器。 |
Kube-scheduler
Kube-scheduler是Kubernetes集群中负责资源调度的核心组件,其主要功能是根据预定义的调度算法为新创建的Pod选择合适的Node节点。该组件可视为整个集群的调度器,确保资源合理分配。
预选策略(predicate)用于过滤不符合条件的节点,例如资源不足或节点标签不匹配。优选策略(priorities)则对通过预选的节点进行打分,选择最优节点。
etcd
etcd是Kubernetes的分布式键值存储系统,用于存储集群的关键配置和用户数据。只有API Server具备直接读写权限,其他组件需通过API Server的接口访问数据,确保数据一致性和安全性。
Node节点组件
每个Worker Node上运行的组件负责与Master节点协作,管理本地资源。Kubelet作为核心组件,处理Master下发的任务并监控Pod及容器状态。
Kubelet
Kubelet是Node节点的监视器,定期向API Server汇报资源使用情况,并通过cAdvisor监控容器。其职责包括:
- 从Master获取Pod期望状态,与容器引擎交互实现生命周期管理
- 确保节点上Pod状态与期望状态一致,调用容器平台接口进行调整
- 管理镜像和容器清理,防止磁盘和资源占用过高
Kube-Proxy
Kube-Proxy实现Pod网络代理和负载均衡,维护网络规则。其核心功能包括:
- 维护虚拟Pod集群网络,非直接提供Pod网络
- 通过iptables或ipvs实现服务映射访问
- 响应API Server对Service的更新,维护端点信息
- 作为集群内部微服务的分布式负载均衡器运行
Container Runtime
容器引擎(如Docker、containerd)负责本机容器管理:
- 根据kubelet指令启动特定容器
- 拉取镜像、启停容器等常规操作
- 所有操作由自动化系统控制,非手动干预
Pod
Pod是Kubernetes的基本调度单位,代表集群中运行的进程。其特点包括:
- 可包含一个或多个紧密关联的容器
- 同一Pod内容器共享网络和存储空间
- 生产环境通常为单容器或强关联多容器组成
- 类比为豌豆荚,容器为内部豌豆
三、K8S核心概念
| 概念 | 作用 |
|---|---|
| cluster | 集群,Cluster指的是由Kubernetes管理的一组节点和资源池。 由Master和多个Worker节点组成,Master用于集群管理和控制,而Worker节点用于运行应用程序和Pod。提供了一种可扩展的、弹性的平台,用于分布式应用程序和容器的部署和管理。 |
| node | 节点,是集群中的工作节点,用于运行Pod和容器。 是物理或虚拟机器,具有足够的资源(CPU、内存、存储)来运行容器化的应用。Kubernetes会自动将Pod调度到可用的节点上,以实现负载均衡和高可用性。 |
| Container | 容器, 容器是一种轻量级的虚拟化技术,用于隔离和运行应用程序及其依赖项。将应用程序与其运行时环境进行隔离,并提供了一个独立的运行空间,使得应用程序可以在不同的环境中移植和部署。 |
| Namespace | 命名空间, Namespace用于在Kubernetes集群中划分虚拟的资源隔离区域。 可用于组织和管理资源,以及为不同的团队、项目或环境提供逻辑分离。 在一个集群中,可以有多个命名空间,每个命名空间都有自己的一组资源和访问策略。 |
| Pod | 容器组,Kubernetes基本调度单位,可以包含一个或多个容器。这些容器共享相同的网络和存储资源,并运行在同一主机上。 提供了一个隔离的运行环境,为容器提供了共享的IP地址和端口空间。 通常,Pod用于运行关联的容器,例如共享相同的资源和上下文的应用程序。 |
| Service | 服务, Service定义了一组Pod的稳定网络终点,通过标签选择器与这些Pod进行关联。充当入口和负载均衡器,封装了一组Pod,并提供一个持久的访问地址(Cluster IP或Node IP)。 还支持内部服务发现和跨集群通信。 |
| ReplicaSet | 副本集,ReplicaSet用于定义Pod的副本数量和在集群中的运行策略,确保指定的Pod副本数始终运行,并根据需要进行自动扩展或收缩。当Pod由于故障或节点故障而终止时,ReplicaSet会自动重新启动新的Pod副本。 |
| Deployment | 部署,Deployment是一种用于声明化管理Pod和ReplicaSet的资源对象。可以定义Pod的期望状态,自动创建和更新ReplicaSet,并实现滚动升级和回滚策略,以确保无缝的应用程序更新。 |
| ConfigMap | 配置映射,ConfigMap是一种存储配置数据的资源对象,用于将配置参数传递给应用程序。可以存储环境变量、配置文件、命令行参数等。 可以与Pod或容器相关联,并在容器启动时注入相关的配置信息。 |
| Secrets | 密钥用于安全地存储和管理敏感信息,如密码、凭证等。 -Kuberentes中的Secret是一种资源对象,用于存储和传递加密的数据。 -密钥可以被挂载到容器中,用于应用程序的配置文件或认证凭证。 |
| DaemonSet | DaemonSet是Kubernetes中的一个重要概念,提供了一种简单且可靠的方式来在集群的所有节点上运行相同的Pod,适用于许多系统级任务和后台进程的部署场景。 1.每个节点一个Pod副本:DaemonSet会在集群的每个节点上启动一个Pod副本,以确保每个节点都有该Pod的运行实例。 2. 系统级任务和守护进程:DaemonSet通常用于运行系统级任务和守护进程,例如日志收集器、监控代理和网络代理等。这些任务通常需要在每个节点上运行,并且要与节点的生命周期同步。 3. 自动扩缩容:当有新节点加入集群或某个节点从集群中移除时,DaemonSet会自动检测节点的状态变化,并相应地启动或终止Pod副本。 4. 节点亲和性规则:可以通过节点亲和性规则来选择在哪些节点上运行DaemonSet的Pod。这允许你将特定的任务或服务与特定类型的节点关联起来。 5. 资源限制和调度约束:可为DaemonSet中的Pod指定资源限制和调度约束,以确保它们在节点上均匀分布并满足资源需求。 |
四、Kubetnetes 涉及的端口
| 角色 | 协议 | 方向 | 端口范围 | 组件 | 使用者 |
|---|---|---|---|---|---|
| master | TCP | 入站 | 6443 | kube-apiserver | 所有 |
| TCP | 入站 | 2379~2380 | etcd | kube-apiserver | |
| TCP | 入站 | 10250 | kubelet | kube-apiserver,自身 | |
| TCP | 入站 | 10259 | kube-scheduler | 自身 | |
| TCP | 入站 | 10257 | kube-controller-manager | 自身 | |
| node | TCP | 入站 | 10250 | kubelet | kube-apiserver |
| TCP | 入站 | 30000~32767 | Service NodePort | 自身 |
Kubernetes核心组件详解
Kubernetes采用模块化设计,核心组件各司其职,通过API Server实现协同工作。以下是核心组件的功能分解:
etcd
分布式键值存储数据库,保存集群所有配置数据和状态信息,如Pod、Service等对象的元数据。采用Raft协议保证数据一致性和高可用性。
kube-apiserver
集群的中央管理枢纽,所有组件和外部请求必须通过其REST API进行交互。实现身份认证(X509/TLS、Bearer Tokens)、RBAC授权、准入控制(Admission Control)及API版本管理。
kube-controller-manager
运行多种控制器的主进程,包括:
- 节点控制器(Node Controller):监控节点健康状态
- 副本控制器(Replication Controller):确保Pod副本数符合预期
- 端点控制器(Endpoints Controller):维护Service与Pod的映射关系
- 服务账户控制器(Service Account Controller):管理命名空间的默认账户
kube-scheduler
根据资源需求(CPU/Memory)、亲和性规则(Affinity/Anti-affinity)、数据本地化等因素,将未绑定的Pod分配到合适的工作节点。支持自定义调度策略插件。
kubelet
节点代理组件,功能包括:
- 通过CRI(Container Runtime Interface)管理容器生命周期
- 通过CNI(Container Network Interface)配置容器网络
- 通过CSI(Container Storage Interface)挂载存储卷
- 定期向API Server报告节点状态
Container Runtime
实际运行容器的底层软件,如Docker、containerd或CRI-O。需实现CRI接口规范,支持镜像拉取、容器启停等操作。
kube-proxy
维护节点上的网络规则,通过iptables/IPVS实现Service的虚拟IP负载均衡和服务发现。
关键通信流程示例
Pod创建过程
- 用户通过kubectl提交Pod配置到API Server
- API Server验证请求并将配置写入etcd
- Scheduler检测到未调度的Pod,根据策略选择目标节点并更新Pod绑定信息
- 目标节点的kubelet通过Watch机制获取新Pod定义
- kubelet调用容器运行时创建容器,并持续监控状态
- kube-proxy根据Service定义配置负载均衡规则
组件交互模式
- 控制平面组件(如Controller Manager)通过List-Watch机制监听API Server的资源变更
- kubelet定期向API Server发送节点状态心跳(--node-status-update-frequency默认10秒)
- 水平扩展时,HPA控制器通过Metrics API获取资源使用率并调整副本数
附加组件功能
网络插件
Calico/Flannel等实现Pod跨节点通信,需满足:
- 所有Pod可以不经过NAT直接通信
- 节点与Pod可以不经过NAT直接通信
- Pod看到的自身IP与其他Pod看到的该Pod IP一致
存储方案
PersistentVolume子系统支持动态供给(Dynamic Provisioning),通过StorageClass定义存储后端类型(如AWS EBS、Ceph RBD)。
该架构设计使得Kubernetes既能处理无状态Web服务,也能支持有状态应用如数据库,同时保持扩展灵活性。
Pod 创建与生命周期管理流程
REST API 创建 Pod 流程 用户通过 kubectl 或其他客户端向 API Server 发送创建 Pod 的请求,API Server 验证请求合法性后将 Pod 配置信息写入 etcd 存储。
调度阶段 Scheduler 持续监听 API Server,发现未绑定 Node 的 Pod 后,根据资源需求、节点亲和性等策略选择合适节点,并通过 API Server 更新 Pod 的 Node 绑定字段。
节点执行阶段 目标节点上的 Kubelet 通过 Watch 机制感知到新调度的 Pod,调用 Container Runtime(如 Docker)启动容器。Kubelet 持续监控容器状态,并将实时状态同步至 API Server 存储到 etcd。
Pod 分类与控制器
自主式 Pod
- 直接由用户创建,无控制器管理
- 节点故障时 Pod 不可恢复
- 适用于临时性任务调试,生产环境不推荐
控制器管理 Pod
- ReplicaSet:确保指定数量的 Pod 副本运行,支持滚动更新
- Deployment:管理无状态应用,提供版本控制和回滚能力
- StatefulSet:为有状态应用提供持久存储和有序部署
- DaemonSet:确保每个节点运行指定 Pod(如日志收集组件)
- Job/CronJob:执行一次性任务或定时任务
核心组件交互
主节点组件
- API Server:集群唯一入口,处理 REST 请求并维护 etcd 数据
- Controller Manager:运行各种控制器实现集群状态维护
- Scheduler:决策 Pod 与节点的绑定关系
工作节点组件
- Kubelet:节点代理,管理 Pod 生命周期和资源监控
- Container Runtime:实际运行容器的引擎(如 Docker)
- kube-proxy:维护节点网络规则,实现服务发现和负载均衡
Pod 状态机
- Pending:已调度但容器未完全启动
- Running:所有容器正常运行
- Succeeded:任务型 Pod 成功终止
- Failed:至少一个容器异常退出
- Unknown:无法获取 Pod 状态(通常因节点失联)
状态转换示例 当 Pod 从 Pending 进入 Running 状态后,若主容器退出码为 0 则转为 Succeeded,非零则转为 Failed。控制器会根据状态触发重建或扩容等操作。
创建 Pod 的流程分析
API Server 在接收到创建 Pod 的请求后,会进行一系列验证和初始化操作。验证包括检查命名空间匹配性、注入系统数据、检查必需字段是否为空。通过验证后,API Server 将 Pod 对象持久化到 etcd 中,并返回响应。此时 Pod 处于 Pending 状态,等待调度器进一步处理。
调度器通过 watch 机制监听到 etcd 中的 Pod 信息后,开始调度流程。调度分为预选、优选和最终选择三个阶段。预选阶段过滤掉不符合条件的节点,优选阶段对剩余节点进行优先级排序,最终选择优先级最高的节点运行 Pod。如果节点不满足条件,Pod 会持续处于 Pending 状态。
节点预选规则
预选阶段使用多种规则过滤节点,确保 Pod 能够正常运行。常见的预选规则包括:
- PodFitsResources:检查节点是否有足够的资源(CPU、内存)运行 Pod。
- MatchNodeSelector:检查节点标签是否匹配 Pod 的节点选择器。
- MatchInterPodAffinity:检查 Pod 与其他 Pod 的亲和性或反亲和性要求。
- PodToleratesNodeTaints:检查 Pod 是否容忍节点的污点。
如果没有任何节点通过预选规则,Pod 会一直处于 Pending 状态,直到有符合条件的节点出现。
调度器优选策略
优选阶段对通过预选的节点进行优先级评分,常见策略包括:
- LeastRequestedPriority:优先选择资源利用率较低的节点。
- BalancedResourceAllocation:优先选择资源分配均衡的节点。
- NodeAffinityPriority:优先选择与 Pod 亲和性要求匹配的节点。
- TaintTolerationPriority:优先选择 Pod 能够容忍污点的节点。
调度器最终选择优先级最高的节点运行 Pod。如果多个节点评分相同,随机选择一个。
Kubelet 启动 Pod 流程
Kubelet 通过 API Server 监听 etcd 中的 Pod 列表变化。当发现新的 Pod 绑定到本节点时,执行以下操作:
- 读取 Pod 配置信息,包括容器镜像、资源限制、卷挂载等。
- 下载所需的容器镜像。
- 创建并启动容器,配置网络和存储。
- 监控容器状态,定期向 API Server 汇报。
如果 Pod 配置发生更新,Kubelet 会根据更新内容调整容器运行状态,例如重启容器或更新资源限制。
bash
1.为该 pod 创建一个数据目录
2.从 API Server 读取该 pod 清单
3.为该 pod 挂载外部卷
4.下载 pod 所需的 Secret
5.检查已经运行在节点中 pod,如果该 pod 没有容器或者 Pause 容器没有启动,则先停止pod里所有的容器进程。
6.使用 pause 镜像为每个pod创建一个容器,该容器用于接管 Pod 中所有其他容器的网络。
7.为 pod 中的每个容器做如下处理:1.为容器计算一个 hash 值,然后用容器的名字去查询对于 docker 容器的 hash 值。若查找到容器,且两者的 hash 值不同,则停止 docker 中容器中进程,并停止与之关联的 pause 容器,若相同,则不做处理。若容器被终止了,且容器没有指定的重启策略,则不做任何处理调用 docker client 下载容器镜像,并启动容器。
Kubernetes 网络模型与组件交互
Kubernetes 网络模型的核心是确保 Pod 间通信的透明性和一致性。每个 Pod 拥有独立 IP(IP-per-Pod),所有 Pod 处于扁平网络空间,无需 NAT 即可直接通信。Controller-manager 负责维护 Pod 的期望状态,kube-proxy 则通过 iptables 或 IPVS 实现 Service 的虚拟 IP 到后端 Pod 的负载均衡。
- Pod IP:实际分配给 Pod 网卡的地址,确保容器间直接通信。
- Service Cluster IP:虚拟 IP,由 kube-proxy 通过规则重定向到后端 Pod。
- 扁平网络空间:消除跨节点通信的复杂性,节点和容器间无需 NAT。
Docker 网络基础与组件
Kubernetes 底层依赖 Docker 的网络模型,关键组件包括:
- 网络命名空间:隔离网络协议栈,实现容器间网络隔离。
- Veth 设备对:连接不同命名空间,允许跨命名空间通信。
- Iptables/Netfilter:Netfilter 处理内核规则,iptables 管理规则表,共同实现数据包过滤和转发。
- 网桥:二层设备,连接多个端口,实现类似交换机的多对多通信。
- 路由:Linux 路由表决定数据包转发路径。
Kubernetes 网络设计原则
- IP-per-Pod:每个 Pod 拥有唯一 IP,简化服务发现和通信。
- 无 NAT 通信:容器间、节点与容器间直接通信,避免地址转换。
- 服务透明性:用户无需手动管理端口映射或连接配置。
组件协同示例
- kube-proxy:监听 Service 变化,更新 iptables 规则,将 Service IP 流量转发到 Pod。
- Controller-manager:监控 Pod 状态,确保副本数与用户声明一致。
- CNI 插件:实现 Pod IP 分配和网络配置(如 Calico、Flannel)。
关键命令与配置
bash
# 查看 Pod IP
kubectl get pods -o wide
# 检查 Service 的 Endpoints
kubectl describe service <service-name>
通过上述机制,Kubernetes 构建了一个高效、透明的网络层,支撑应用的高可用和弹性扩展。
Docker网络实现
单机网络模式
Bridge模式
默认网络模式,通过docker0网桥实现容器间通信。容器通过veth pair连接到网桥,分配独立IP,并通过NAT与外部通信。
Host模式
容器直接共享宿主机的网络命名空间,使用宿主机IP和端口,性能高但隔离性差。
Container模式
新容器共享指定容器的网络命名空间,适合需要紧密通信的容器组。
None模式
不配置任何网络,需手动自定义网络栈,适用于高度定制化场景。
多机网络模式
Libnetwork原生支持
Docker 1.9+通过Libnetwork提供跨节点网络,内置Overlay驱动实现VXLAN隧道。
第三方插件
- Flannel:基于Overlay或主机路由,提供简单的子网分配和跨节点通信。
- Calico:基于BGP协议实现纯三层网络,高性能且支持网络策略。
Kubernetes网络基础
容器间通信
同一Pod内的容器共享网络命名空间,通过localhost和容器端口直接通信,依赖lo回环接口。
同一Node中Pod间通信
Pod通过CNI插件(如docker0或cni网桥)连接到同一网桥,IP同网段可直接通信,数据包由网桥转发。
不同Node中Pod间通信
需满足:
- Pod IP全局唯一;
- 通过网络插件(如Flannel/Calico)建立节点间路由或隧道,将Pod IP与Node IP关联。
Service机制
功能
Service作为Pod组的负载均衡抽象,提供稳定的ClusterIP,流量分发至后端Pod。
Pod与Service通信
- iptables:默认方式,通过规则实现NAT和负载均衡,支持复杂网络策略。
- ipvs:基于内核级负载均衡,性能更高,但依赖iptables完成NAT转换。
Kube-proxy实现
userspace模式
早期方案,代理工作在用户空间,稳定性高但性能较低。
iptables模式
当前默认方式,完全通过iptables规则实现Service路由和LB,适合中小规模集群。
ipvs模式
利用内核IPVS模块高效处理LB,结合iptables完成NAT,适用于大规模高并发场景。
kube-proxy 的工作原理与 iptables 模式
kube-proxy 在 iptables 模式下通过监视 Kubernetes 控制平面的服务和端点对象动态更新 iptables 规则。当服务或端点发生变化时,kube-proxy 会立即调整规则以反映这些变化。
服务流量通过 ClusterIP 和端口被 iptables 规则捕获,并重定向到后端 Pod。每个端点对象对应一组 Pod,kube-proxy 会为这些 Pod 设置选择规则。流量分发默认采用随机策略,但可通过设置 service.spec.sessionAffinity 为 ClientIP 实现基于客户端 IP 的会话保持。
与用户空间代理相比,iptables 模式性能更高且更可靠,但不具备自动重试机制。若所选 Pod 无响应,连接将失败,因此需依赖就绪探针确保后端可用性。
Kubernetes 网络核心组件与技术术语
IPAM
负责集群内容器 IP 地址分配,主流方法包括基于 CIDR 的段分配或精确分配,确保全局唯一性。
Overlay 网络
在现有网络层上构建独立网络,拥有专属 IP 空间。常见实现包括 VXLAN(解决 VLAN 数量限制)和 IPSec(加密通信)。
Linux Bridge
如 Docker0 网桥,用于连接容器与主机网络。
BGP
自治网络间路由协议,应用于 Calico 等方案实现跨主机路由。
SDN 与 OpenFlow
通过流表分离控制平面与数据平面,实现灵活的网络策略管理。
容器网络方案分类与特点
隧道方案(Overlay)
- Flannel:支持 UDP 广播和 VXLAN,简单易用但大规模集群时排查复杂。
- Weave:基于 UDP 和 PCAP 互通,适合中小规模部署。
- OVS:依赖 VXLAN/GRE,性能损耗显著。
路由方案
- Calico:基于 BGP 的三层路由,支持精细 ACL,混合云兼容性好。
- Macvlan:二层隔离性能最优,但需云服务商支持二层网络。
Flannel 的核心功能与设计目标
Flannel 为 Kubernetes 集群提供以下能力:
- 为每个节点的 Docker 容器分配不冲突的虚拟 IP。
- 通过覆盖网络(如 VXLAN 或 UDP)实现跨节点容器直接通信。
其设计解决了默认 Docker IP 分配导致的地址冲突问题,使不同节点容器如同处于同一内网。数据转发支持多种方式,默认使用 UDP 封装。