Skip to content

Kubernetes简介

Kubernetes(常简称为K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它最初由Google开发,基于其内部Borg系统的经验,于2014年开源并捐赠给云原生计算基金会(CNCF)

基本概念

Kubernetes的核心功能是管理容器化应用的生命周期,包括:

  • 自动化部署和扩展:根据应用程序需求自动部署和调整容器数量
  • 服务发现与负载均衡:内置机制使应用间通信更便捷
  • 自我修复:自动重启失败容器,确保应用高可用性
  • 配置与存储管理:灵活管理应用配置和存储卷
  • 跨平台支持:可在公有云、私有云和混合云环境运行

Kubernetes与Docker的关系

虽然Kubernetes常与Docker一起提及,但两者扮演不同角色:

  • Docker:提供容器运行时环境,负责镜像构建和单机容器管理
  • Kubernetes:编排管理分布式环境中的多个容器,处理跨主机通信、调度等复杂问题

Kubernetes可以管理Docker创建的容器,但同时也支持其他容器运行时如containerd、CRI-O等

核心优势

Kubernetes的主要优势包括:

  • 自动化运维:减少人工干预,降低人为错误
  • 高可用性:通过自动重启、复制机制确保应用持续可用
  • 弹性扩展:根据负载自动调整资源,优化成本
  • 开发效率:开发者可专注于应用开发,减少部署工作量
  • 丰富的生态系统:拥有大量扩展工具如Helm、Istio、Prometheus等

Kubernetes架构原理

控制平面组件(Master节点)

控制平面组件构成了Kubernetes集群的"大脑",负责集群的全局决策和管理

API Server (kube-apiserver)

  • 集群管理的唯一入口,提供RESTful API接口
  • 处理认证、授权、访问控制和API注册发现机制
  • 所有组件都通过API Server进行通信,不直接相互调用

etcd

etcd是分布式键值存储系统,作为Kubernetes的"记忆中心",保存整个k8s集群的核心数据:

  • 分布式键值存储数据库,保存整个集群的状态和配置数据
  • 是Kubernetes集群中唯一有状态的组件
  • 存储所有资源对象(Pod、Service、Deployment等)的信息

Controller Manager (kube-controller-manager)

Controller Manager(kube-controller-manager)是集群的"自动修复系统",管理中心,负则k8s集群的指令管理发出。

  • 运行各种控制器,确保集群实际状态与期望状态一致
  • 实现故障检测、自动扩展、滚动更新等功能

控制器包括

  • Deployment Controller:确保Deployment定义的Pod副本数符合预期
  • ReplicaSet Controller:管理Pod副本数量
  • Node Controller:监控节点状态,处理节点故障
  • Service Controller:创建和更新Service资源
  • Namespace Controller:管理命名空间生命周期

kubectl

kubectl 是 Kubernetes 的标准命令行工具,用于与集群交互,管理资源(如 Pod、Deployment、Service 等)。开发者或运维人员通过它执行日常操作,例如部署应用、查看日志、调试问题等。

kubeadm

kubeadm 是官方提供的集群生命周期管理工具,专注于快速初始化和升级 Kubernetes 集群。它简化了主节点(Master)和工作节点(Worker)的部署流程。

Scheduler (kube-scheduler)

Scheduler(kube-scheduler)是集群的"调度中心",负责:

  • Pod的调度,根据资源需求、亲和性等策略选择合适节点
  • 通过Watch机制监听未绑定的Pod,进行调度决策

Cloud Controller Manager (可选)

  • 在公有云环境中管理与云提供商相关的资源

  • 处理负载均衡器、云盘等云服务的创建和配置

工作节点组件(Node节点)

工作节点是实际运行容器化应用的"四肢",执行控制平面的指令

Kubelet

Kubelet是节点上的"Pod管家",负责接收来自controller-manager的指令具体执行资源的启停任务,功能包括:

  • 节点代理,管理Pod的生命周期
  • 与容器运行时(如Docker)交互,执行容器的创建、启动和停止
  • 监控节点资源使用情况并上报给API Server

Kube Proxy

Kube Proxy是集群的"网络代理",负责k8s 中整个集群中各种资源之间的通信代理,实现:

  • 实现Service的负载均衡和网络代理功能
  • 通过维护iptables或IPVS规则实现流量转发
  • 为Pod提供集群内部的服务发现

扩展组件(Add-ons)

CoreDNS

CoreDNS是Kubernetes集群中负责DNS解析的核心组件,自Kubernetes 1.13版本起成为默认的DNS服务器,取代了早期的kube-dns。作为CNCF毕业项目,CoreDNS以其插件化架构、高性能和灵活性成为云原生环境下DNS解析的成熟解决方案。

  • 服务发现:将Kubernetes服务(如my-svc.default.svc.cluster.local)解析为ClusterIP或Pod IP,实现应用间通信
  • Pod域名解析:为每个Pod提供基于其IP地址的域名解析
  • 外部域名解析:将集群内的DNS请求转发到外部DNS服务器,解析外部域名(如www.example.com)
  • 自定义域名解析:通过Corefile配置文件支持自定义域名解析规则
  • 负载均衡:内置loadbalance插件,默认采用轮询策略分发流量至后端Pod
  • 反向DNS解析:支持IP地址到域名的反向解析(in-addr.arpa和ip6.arpa)

Calico

Calico采用纯三层网络模型,避免了传统Overlay网络的额外开销。每个Pod获得全局唯一、可路由的IP地址,通信就像在同一个局域网中的物理机一样直接高效。

  • Pod创建:kubelet调用Calico CNI插件,为Pod分配IP并创建veth pair设备(一端在Pod内为eth0,一端在主机上为caliXXXXX)。
  • 路由传播:BIRD通过BGP协议将Pod IP路由信息广播给其他节点。
  • 跨节点通信:根据配置的网络模式(BGP/IPIP/VXLAN)实现Pod间通信。
  • 策略实施:Felix将NetworkPolicy转换为iptables/eBPF规则,实施访问控制

Ingress Controller

  • 提供HTTP/HTTPS路由、负载均衡和SSL终止
  • 将外部请求路由到集群内部服务

K8S资源分类

  • 工作负载:是指k8s集群中具体负责接受用户请求任务的应用

  • pod:k8s中的基本资源调度单位,k8s中一切活动都是pod为基本单位,它是一个容器的集合。

  • deployment:是pod集合,主要是运行无状态pod(web),可以通过副本集控制pod的数量

  • statefulset: 是pod集群是有状态的pod集合(mysql),可以通过副本集控制pod的数量

  • daemonset: 是pod集合。确保每个Node运行一个指定的Pod(如日志收集Agent)

  • job: Linux中的一次性定时任务

  • cronjob: Linux中的周期性定时任务

  • conifimap:记录工作负载配置信息,明文记录

  • secret:记录工作负载配置信息,记录敏感性,通过base64码转化记录

  • pv:存储卷

  • pvc:存储卷申请

  • service:Linux中四层代理,可实现各个资源负载均衡(代理proxy)

  • ingress:Linux中七层代理 (底层用的就是nginx)

  • rbac:权限的设置

组件协作流程

以下是Kubernetes组件协作流程的Mermaid图表示,展示从创建Deployment到Pod运行的完整流程

mermaid
sequenceDiagram
    participant User as 用户(kubectl)
    participant API as API Server
    participant etcd as etcd
    participant CM as Controller Manager
    participant Scheduler as Scheduler
    participant Kubelet as Kubelet
    participant Runtime as 容器运行时
    participant KProxy as kube-proxy

    Note over User, KProxy: 创建Deployment流程
    User->>API: kubectl create deployment
    API->>etcd: 存储Deployment配置
    CM->>API: Watch到Deployment创建
    CM->>API: 创建对应的ReplicaSet
    API->>etcd: 存储ReplicaSet配置
    CM->>API: 确保Pod数量符合预期
    API->>etcd: 存储Pod配置
    
    Note over Scheduler, Runtime: 调度与运行阶段
    Scheduler->>API: Watch到未绑定Pod
    Scheduler->>API: 绑定Pod到合适节点
    API->>etcd: 更新Pod绑定信息
    Kubelet->>API: Watch到分配给本节点的Pod
    Kubelet->>Runtime: 创建容器
    Runtime->>Kubelet: 返回容器状态
    Kubelet->>API: 更新Pod状态
    API->>etcd: 存储Pod状态
    
    Note over KProxy, KProxy: 服务暴露阶段
    KProxy->>API: Watch到Service/Pod变化
    KProxy->>KProxy: 更新iptables/IPVS规则
  1. 用户请求阶段
    • 用户通过kubectl提交Deployment创建请求
    • API Server接收请求并持久化到etcd
  2. 控制循环阶段
    • Controller Manager检测并创建ReplicaSet
    • 确保实际Pod数量与期望状态一致
  3. 调度阶段
    • Scheduler为Pod选择合适节点
    • 更新Pod的节点绑定信息
  4. 运行阶段
    • 目标节点的kubelet创建容器
    • 容器运行时实际启动容器
    • 状态回馈到控制平面
  5. 网络配置阶段
    • kube-proxy监听变化并更新网络规则
    • 建立Service到Pod的流量转发路径

Kubernetes通过这种松耦合的组件架构,实现了高度可扩展和灵活的容器编排能力,能够适应从开发测试到大规模生产环境的各种需求。

Kubernetes配置文件目录解析

/etc/kubernetes/ - 主配置目录

这是Kubernetes集群的核心配置目录,包含控制平面组件和节点代理的关键配置文件

bash
/etc/kubernetes/
├── admin.conf            # 集群管理员kubeconfig文件,包含管理员凭证和集群信息
├── controller-manager.conf  # 控制器管理器的kubeconfig文件
├── kubelet.conf          # kubelet组件的kubeconfig文件
├── scheduler.conf        # 调度器组件的kubeconfig文件
├── manifests/           # 静态Pod清单目录
   ├── etcd.yaml        # etcd集群清单
   ├── kube-apiserver.yaml  # API服务器清单
   ├── kube-controller-manager.yaml  # 控制器管理器清单
   ├── kube-scheduler.yaml  # 调度器清单
   └── kube-proxy.yaml   # kube-proxy清单
└── pki/                 # PKI证书目录
    ├── ca.crt           # 集群CA证书
    ├── ca.key           # 集群CA私钥
    ├── apiserver.crt    # API服务器证书
    ├── apiserver.key    # API服务器私钥
    ├── front-proxy-ca.crt  # 前端代理CA证书
    ├── front-proxy-ca.key  # 前端代理CA私钥
    ├── sa.pub           # ServiceAccount公钥
    └── sa.key           # ServiceAccount私钥**关键文件说明**:
  • admin.conf:包含集群管理员凭证,用于通过kubectl管理集群
  • manifests/目录中的YAML文件定义了作为静态Pod运行的控制平面组件
  • pki/目录存储集群的TLS证书和密钥,用于组件间安全通信

/var/lib/kubelet/ - Kubelet工作目录

kubelet的工作目录包含Pod相关数据和配置

tex
/var/lib/kubelet/
├── config.yaml          # kubelet的配置文件
├── pods/                # 运行中Pod的数据目录
├── plugins/             # 卷插件相关文件
├── pki/                 # kubelet的PKI文件
│   ├── kubelet.crt      # kubelet客户端证书
│   └── kubelet.key      # kubelet客户端私钥
└── device-plugins/      # 设备插件相关文件

关键功能

  • pods/目录存储Pod的卷挂载点和运行时数据
  • config.yaml定义kubelet的行为参数,如容器运行时、cgroup驱动等
  • 当Pod出现CrashLoopBackOff等状态时,检查此目录下的文件有助于诊断问题

/etc/cni/net.d/ - CNI插件配置

包含容器网络接口(CNI)插件的配置文件

tex
/etc/cni/net.d/
├── 10-calico.conflist   # Calico网络插件配置
└── 99-loopback.conf     # 回环网络配置

当Pod网络通信出现问题时,检查此目录下的配置文件是首要步骤

/opt/cni/bin/ - CNI插件二进制文件

存放CNI插件的可执行二进制文件,如calico、flannel等网络插件的实现

/var/lib/etcd/ - etcd数据目录

存储etcd的持久化数据,包含整个集群的状态信息:

  • 重要性:此目录数据丢失将导致集群状态丢失,必须定期备份
  • 恢复案例:某生产环境因etcd数据损坏,通过备份恢复此目录使集群恢复正常

/var/log/ - 日志目录

存储各组件的日志文件,对故障排查至关重要

tex
/var/log/
├── kubelet.log          # kubelet日志
├── docker.log           # Docker容器运行时日志
└── containers/          # 容器标准输出日志

/etc/systemd/system/ - systemd服务单元

包含Kubernetes相关服务的systemd单元文件

tex
/etc/systemd/system/
└── kubelet.service.d/
    └── 10-kubeadm.conf  # kubelet的systemd配置

可通过修改这些文件调整组件的内存限制等参数

Kubernetes 资源类型

Kuberentes抽象出多种概念来描述应用程序及其周边组件,如Pod、Deployment、Service等,这些概念被统称为资源。而对象则是“资源”的实例,如具体的某个Pod、具体的某个Service。在日常语境中,我们通常不会特意区分资源和对象,可以使用”资源“、“资源对象”来泛指某类资源的实例,也即是对象。

Namespace(命名空间)

Kubernetes集群中Namespace也是用于隔离,它提供了一种对集群中的对象进行分组和隔离的机制。使用Namespace可以将不同应用程序或不同团队的资源进行隔离,从而防止资源冲突和应用程序之间的相互影响。

default

如果您没有指定namespace,Kubernetes会将资源分配到此namespace中。

kube-system

用于放置Kubernetes的系统组件(如kube-apiserver、kube-proxy、CoreDNS等)。这些组件用于支持集群的基本功能,因此不建议在此namespace放置其他无关资源。

kube-public

此namespace中的资源可以被任何人(包括匿名用户)查看。通常用于存储公共信息,以供集群内部和外部使用。

kube-node-lease

此namespace用于存储每个节点的租约信息,这些信息指示节点是否处于活动状态,并在集群中进行调度和管理时使用。

Pod

Pod 是 Kubernetes 中最小的部署单元,可以包含一个或多个容器。每个 Pod 都有一个唯一的 IP 地址,并且内部容器可以共享网络栈、存储等。Pod 提供了一种轻量级的方式来部署容器,可以实现高效地资源利用。每个Pod都有一个唯一的IP地址,该地址由集群分配,可用于与其他Pod通信。不管它们是否运行在同一个Node节点上,Pod之间都可以通过IP地址互相访问,中间不需要经过任何NAT转换。

Pod的生命周期包含从最初的创建,运行、再到最终退出的整个过程。Kubernetes为这个过程定义了五个阶段,分别是:

Pending(等待)

当您创建一个Pod并提交给K8s集群时,它会进入等待状态,即Pending阶段。此时Pod相关信息已生成被存入到Etcd中,但还有容器尚未创建完成,这可能是由于还在找寻合适的调度节点,或者下载容器的过程中。

Running(运行中)

一旦Pod被调度到节点并且所有容器都已经启动成功,它会进入Running阶段。在这个阶段,Pod中的容器会在其所在的节点上运行,并且可以正常响应请求。这是Pod正常工作的阶段。

Successed(已成功)

当Pod中的所有容器成功执行完任务后,Pod会进入Succeeded阶段。这可能发生在一次性任务完成后,比如在CronJob中运行的作业。在这个阶段,Pod将保持在Succeeded状态,直到被删除。

Failed(已失败)

如果Pod中的容器在运行时发生了错误,或者未能达到预期的状态,Pod会进入Failed阶段。这可能是容器崩溃、配置问题或依赖资源不足等原因造成的。在这个阶段,Pod将保持在Failed状态,需要进一步排查问题并进行适当的修复。

Unknown(未知)

在某些情况下,Kubernetes无法确定Pod的状态,比如无法与Pod通信。这可能是由于网络故障、节点问题或其他未知因素引起的。在这种情况下,Pod将被标记为Unknown状态,需要进一步调查问题的根本原因。

Deployment

Deployment 用于管理 Pod 的部署和更新的控制器,可以通过指定副本数和容器镜像来定义 Pod 模、板。Deployment 可以自动检测并处理 Pod 的故障,保证应用程序的高可用性,通常用于部署无状态的服务。

StatefulSet

功能与Deployment类似,但适用于部署有状态的应用服务。StatefulSet能够为每个Pod创建一个独特的标识,并会保证Pod之间的启动顺序。通常用于部署数据库等应用服务。

DaemonSet

用于确保在集群中每个节点上运行一个Pod副本,通常用于部署一些系统级别的守护进程服务,如agent、网络插件等。

Service

Service 是一种抽象的对象,用于暴露 Pod 的网络服务。Service 可以将一组 Pod 组合在一起,并使用一个唯一的 DNS 名称和虚拟 IP 地址,提供负载均衡服务。Service 还可以定义访问控制策略,用于提高应用程序的可用性和安全性。

Ingress

Ingress 是 Kubernetes 中用于管理 HTTP 和 HTTPS 流量的对象。它允许外部流量进入集群,并将流量路由到不同的 Service 上。

ConfigMap

ConfigMaps 用于在 Kubernetes 中存储配置数据,它们可以用于存储键值对、文件或目录。

ConfigMaps 作为 Kubernetes 对象创建,并可在容器中作为卷或环境变量进行挂载。ConfigMaps 的好处在于可以将配置数据与应用程序代码分离,使得配置数据更易于管理和更新。

Secret

Secrets 类似于 ConfigMaps,但用于存储敏感信息,例如密码、API 密钥和证书。与 ConfigMaps 一样,Secrets 可以在容器中作为卷或环境变量进行挂载。Secrets 的数据是加密,并且只有经过授权的用户访问时才会解密。

Job

短暂运行的任务,一旦完成就会终止,常用于批处理任务、数据处理等场景。

CronJob

基于时间的作业调度,类似于Linux中的cron,可以按照预定时间或周期执行作业。

PersistentVolumes (PV)

PV 是集群中独立的存储Volume,可以是物理存储设备(如:磁盘)、网络存储设备(如,Nas)或者是分布式存储 系统(如GlusterFS、Ceph等)。

PersistentVolumeClaims(PVC)

PVC 是用于申请PV资源的对象。创建 PVC 时会指定存储的大小和资源,Kubernetes 将查找与请求匹配的可用 PV 并将它们绑定在一起。然后用户可以使用 PVC 访问存储。