文章

K8s——自动化部署、扩缩和管理容器化应用

K8s——自动化部署、扩缩和管理容器化应用

引言

Kubernetes是一个开源的容器编排引擎,用来对容器化应用进行自动化部署、扩缩和管理。此开源项目由云原生计算基金会(CNCF)托管。
– 来自K8s官网

Kubernetes的前身是Google十余年大规模容器调度管理技术Borg20146月由谷歌宣布开源;20157月发布1.0正式版,并交由CNCF托管,20183月顺利从CNCF正式毕业,成长速度极快,是首个CNCF项目,如今已是行业主流容器编排标准。它能够自动化管控应用全生命周期,实现应用快速部署、弹性扩缩、迭代更新,同时合理调配硬件资源,提升资源利用率。

Kubernetes是什么意思?K8s
Kubernetes的名字来自希腊语,意思是舵手,或领航员。K8s是将8个字母ubernete替换为8的缩写。
– 来自K8s社区

使用Kubernetes能做什么?
– 来自K8s社区

可以在物理或虚拟机的Kubernetes集群上运行容器化应用,Kubernetes能提供一个以容器为中心的基础架构,满足在生产环境中运行应用的一些常见需求,比如,

  • 多个进程(作为容器运行)协同工作。(Pod
  • 存储系统挂载
  • Distributing secrets
  • 应用健康检测
  • 应用实例的复制
  • Pod自动伸缩/扩展
  • Naming and discovering
  • 负载均衡
  • 滚动更新
  • 资源监控
  • 日志访问
  • 调试应用程序
  • 提供认证和授权

Kubernetes不是什么?
– 来自K8s社区

Kubernetes并不是传统的PaaS(平台即服务)系统。

  • Kubernetes不限制支持应用的类型,不限制应用框架。不限制受支持的语言runtimes(例如, Java, Python, Ruby),满足12-factor applications。不区分apps或者servicesKubernetes支持不同负载应用,包括有状态、无状态、数据处理类型的应用。只要这个应用可以在容器里运行,那么就能很好的运行在Kubernetes上。
  • Kubernetes不提供中间件(如message buses)、数据处理框架(如Spark)、数据库(如Mysql)或者集群存储系统(如Ceph)作为内置服务。但这些应用都可以运行在Kubernetes上面。
  • Kubernetes不部署源码不编译应用。持续集成的(CI)工作流方面,不同的用户有不同的需求和偏好的区域,因此,我们提供分层的CI工作流,但并不定义它应该如何工作。
  • Kubernetes允许用户选择自己的日志、监控和报警系统。
  • Kubernetes不提供或授权一个全面的应用程序配置 语言/系统(例如,jsonnet)。
  • Kubernetes不提供任何机器配置、维护、管理或者自修复系统。

另一方面,大量的Paas系统都可以运行在Kubernetes上,比如OpenshiftDeisGondor。可以构建自己的Paas平台,与自己选择的CI系统集成。

由于Kubernetes运行在应用级别而不是硬件级,因此提供了普通的Paas平台提供的一些通用功能,比如部署,扩展,负载均衡,日志,监控等。这些默认功能是可选的。

另外,Kubernetes不仅仅是一个编排系统;它消除了编排的需要。编排的定义是指执行一个预定的工作流:先执行A,之B,然C。相反,Kubernetes由一组独立的可组合控制进程组成。怎么样从AC并不重要,达到目的就好。当然集中控制也是必不可少,方法更像排舞的过程。这使得系统更加易用、强大、弹性和可扩展。

Kubernetes在整个云原生方法论中的定位,详细参见附录部分(云原生的发展)。

K8s里有什么?

了解Kubernetes里边有什么之后,才能理解Kubernetes提供的解决方案。

Kubernetes中,Service是分布式集群架构的核心。一个Service对象拥有如下关键特征,

  • 拥有唯一指定的名称(比如MyApp);
  • 拥有一个虚拟IP地址(ClusterIP地址)和端口号;
  • 能够提供某种远程服务能力;
  • 能够将客户端对服务的访问请求转发到一组容器应用上。

Service的服务进程通常基于Socket通信方式对外提供服务,比如RedisMemcachedMySQLWeb Server,或者是实现了某个具体业务的特定TCP Server进程。虽然一个Service通常由多个相关的服务进程提供服务,每个服务进程都有一个独立的EndpointIP+Port)访问点,但Kubernetes能够让我们通过ServiceClusterIP+Service Port)连接指定的服务。有了Kubernetes内建的透明负载均衡和故障恢复机制,不管后端有多少个具体的服务进程,也不管某个服务进程是否由于发生故障而被重新部署到其他机器,都不会影响对服务的正常调用。更重要的是,这个Service本身一旦创建就不再变化,这意味着我们再也不用为Kubernetes集群中应用服务进程IP地址变来变去的问题头疼了。

容器提供了强大的隔离功能,所以我们有必要把为Service提供服务的这组进程放入容器中进行隔离。为此,Kubernetes设计了Pod对象,将每个服务进程都包装到相应的Pod中,使其成为在Pod中运行的一个容器(Container)。为了建立ServicePod间的关联关系,Kubernetes首先给每个Pod都贴上一个标签(Label),比如给运行MySQLPod贴上name=mysql标签,给运行PHPPod贴上name=php标签,然后给相应的Service定义标签选择器(Label Selector),例如,MySQL Service的标签选择器的选择条件为name=mysql,意为该Service要作用于所有包含name=mysql标签的Pod。这样一来,就巧妙解决了ServicePod的关联问题。

先简单介绍Pod的概念。首先,Pod运行在一个被称为节点(Node)的环境中,这个节点既可以是物理机,也可以是私有云或者公有云中的一个虚拟机,在一个节点上能够运行多个Pod;其次,在每个Pod中都运行着一个特殊的被称为Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷,因此它们之间的通信和数据交换更为高效,在设计时我们可以充分利用这一特性将一组密切相关的服务进程放入同一个Pod中;最后,需要注意的是,并不是每个Pod和它里面运行的容器都能被映射到一个Service上,只有提供服务(无论是对内还是对外)的那组Pod才会被映射为一个服务。

Desktop View Service、Endpoints与Pod的关系

在集群管理方面,Kubernetes将集群中的机器划分为一个Master和一些Node。在Master上运行着集群管理相关的一些进程:kube‑apiserverkube‑controller‑managerkube‑scheduler,这些进程实现了整个集群的资源管理、Pod调度、弹性伸缩、安全控制、系统监控和纠错等管理功能,并且都是自动完成的。Node作为集群中的工作节点,其上运行着真正的应用程序。在Node上,Kubernetes管理的最小运行单元是Pod。在Node上运行着Kuberneteskubelet(容器管理)、kube‑proxy(流量负载均衡)服务进程,这些服务进程负责Pod的创建、启动、监控、重启、销毁,以及实现软件模式的负载均衡器。

Desktop View K8s内部组件架构:Master控制面 + Node节点组件通信协作

整体划分为两大块,

  • Master控制平面(管控集群全局):etcdAPI Server、认证鉴权准入、DashboardSchedulerController Manager
  • Node工作节点(执行业务容器):kubeletcAdvisorkube-proxy、容器运行时;

整体通信原则:所有组件只和API Server交互,不直接互相调用,依托etcd做数据持久化,以声明式API + 消息通知完成协同。

外部客户端:kubectl命令行、浏览器访问Dashboard

Master控制面组件

etcd(集群唯一数据存储)

作为K8s集群的分布式键值数据库,把集群所有资源状态(PodDeploymentService、配置、密钥、节点信息)唯一持久化存储,保证集群数据一致性、高可用,集群重启后所有资源数据从etcd恢复。

在通信链路上,仅接收API Server的读写请求,其余任何组件(调度器、控制器、kubelet)都禁止直连etcdAPI Server把接收到的资源配置、集群状态落地写入etcd,同时从etcd读取最新集群数据。

API Server(整个集群的唯一网关、核心中枢)

全集群所有组件、客户端的统一接入入口,是整套架构的通信枢纽,所有交互必经此处。接入方一般有以下几种,

  1. 外部客户端
    • kubectl:命令行提交创建/删除/更新资源请求(create deploymentget pods),发HTTP请求到API Server
    • Web浏览器:访问K8s Dashboard可视化面板,Dashboard内部调用API Server REST接口;
  2. Master内部组件:SchedulerController Manager
  3. 所有Node节点组件:kubeletkube-proxy

API Server对请求的处理流程,采用了类似责任链模式的架构,由很多的处理器组成,内部前置流程有Authentication(认证)、Authorization(授权)、Admission Control(准入控制器)等,三层校验全部放行后,API Server才会把资源数据写入etcd,同时对外暴露资源变更事件。

  • 认证:校验访问者身份(证书、token、账号密码),确认你是谁;
  • 授权:校验该身份是否有权限执行当前操作(RBAC权限控制);
  • 准入控制:资源写入etcd前的校验/修改,比如校验镜像仓库合法性、自动给Pod注入Sidecar、资源配额校验。

两大核心工作模式如下,

  1. 同步读写:处理客户端增删改查请求,落地etcd
  2. Watch长轮询机制:向集群内所有组件推送资源变更事件(这是组件协同的核心)。

SchedulerController Managerkubeletkube-proxy都会和API Server建立长连接Watch订阅关心的资源,资源一旦在etcd更新,API Server立刻推送事件给对应组件,实现实时感知集群变化。 Desktop View K8s Pod调度时的List Watch机制

Controller Manager(控制器管理器)

内部运行着一系列控制器,包括DeploymentControllerNodeControllerReplicaSetControllerServiceController等,每个控制器负责一类资源的调谐(Reconcile)逻辑。工作流程如下,

  1. API Server建立Watch长连接,持续监听对应资源的期望状态(例如Deployment声明要3Pod副本);
  2. 对比期望状态(etcd中用户定义)和实际集群当前状态
    • 比如用户提交Deployment声明3副本,API Server写入etcdController Manager监听到Deployment变更;
    • 发现当前集群Pod数量不足3个,就调用API Server发起创建Pod的请求;
    • API Server校验后将Pod资源写入etcd
  3. 全程不会直接操作kubeletetcd,所有指令都通过API Server中转。

简单理解:集群的运维大脑,不停把集群现状修正为用户声明的目标状态。

Scheduler(调度器)

为新创建的未绑定节点的Pod,挑选最优Node节点。完整协作流程如下,

  1. 通过Watch监听API Server中未调度(nodeName为空)的Pod事件;
  2. 执行调度算法
    • 预选(Predicate):过滤不符合硬性条件的节点(资源不足、节点污点、亲和性规则不满足);
    • 优选(Priority):对剩余节点打分,选出最合适的一台Node
  3. 调用API Server发起绑定请求,把PodnodeName字段更新为选中节点;
  4. API Server更新这条Pod数据写入etcd
  5. 对应节点上的kubelet通过Watch感知到自己节点绑定了新Pod,开始拉起容器。

关键点:调度器只做选节点+打标记,不会直接下发指令给kubelet

Dashboard

可视化Web控制台,本质是API Server的前端封装,浏览器操作Dashboard页面,Dashboard后端组装API请求,调用API Server完成集群操作,结果回显到页面。

Node工作节点组件

每个Node上固定运行三大核心组件:kubeletkube-proxycAdvisor,依托本地容器运行时管理容器。

kubelet(节点管家,Node上最核心组件)

主动和API Server建立双向长连接Watch,不接收Master主动推送,所有动作由自身监听事件驱动。完整工作链路如下,

  1. 监听自身节点绑定的Pod
    • Scheduler完成Pod节点绑定后,API Server更新Pod归属节点;该节点kubelet通过Watch捕获到属于自己的Pod配置;
  2. 和本地Docker交互:拉取镜像、创建容器、启停容器、配置网络/存储卷;
  3. 持续采集容器实际运行状态,定期上报给API ServerAPI Server同步更新到etcd
    • 容器存活状态、资源占用、运行日志;
    • 节点整机状态:节点CPU/内存压力、节点是否健康;
  4. 执行生命周期管理:Pod就绪探针、存活探针检测;容器异常崩溃时重启容器;Pod被删除时销毁本地容器;
  5. cAdvisor内嵌在kubelet中:采集节点上所有容器的CPU、内存、磁盘、网络监控指标,kubelet汇总后上报API Server,供监控系统采集。

kubelet还支持节点心跳机制,定时向API Server上报节点心跳,标记节点Ready就绪状态;若长时间失联,MasterNodeController会判定节点失联,自动驱逐该节点上的Pod到其他健康节点。

kube-proxy(集群Service网络代理)

维护节点上Service对应的转发规则(iptables/IPVS),支撑图中的ClusterIP(Virtual Server)虚拟服务,实现集群内Service负载均衡。协作流程如下,

  1. API Server建立Watch,持续监听集群内Service资源、Endpoint资源的变更;
    • Service:服务访问入口ClusterIP、端口、负载均衡策略;
    • EndpointService后端对应的真实PodIP+端口列表;
  2. 一旦ServiceEndpoint发生变化(Pod扩容缩容、Service新建删除),kube-proxy实时在当前节点内核层面刷新转发规则;
  3. 节点内部容器访问Service ClusterIP时,流量会被内核规则转发到后端正常运行的Pod
  4. 图中外部Client访问集群服务,流量最终会经由节点Proxy转发到后端容器;
  5. Master主动下发指令,全靠本地监听API Server事件自动更新网络规则。

ClusterIP(Virtual Server)Service的集群内部虚拟IP,并非实体进程,是kube-proxy依托内核规则虚拟出来的统一访问入口,

  • 集群内部Pod可稳定访问该固定IP,无需关心后端Pod IP频繁变化;
  • kube-proxy持续同步后端Pod列表,保证流量始终路由到健康运行的容器。

容器运行时CRI

Docker为例,kubelet通过CRI接口调用Docker,仅负责容器生命周期的底层创建、销毁、镜像管理,完全由kubelet管控,不会和集群其他组件直接通信。

整条业务完整端到端协作链路

以创建Deployment为例,

  1. 用户执行 kubectl apply -f deployment.yaml
  2. kubectl封装HTTP请求发送至API Server;经过认证、授权、准入校验后,API ServerDeployment数据存入etcd
  3. Controller Manager中的Deployment控制器WatchDeployment新增事件:计算期望副本数,发现缺少Pod,调用API Server创建对应数量的Pod资源写入etcd;此时Pod还未分配节点;
  4. Scheduler Watch到未绑定节点的Pod,调度筛选最优Node,调用API Server更新Pod绑定节点,写入etcd
  5. 目标节点上的kubelet Watch到归属自身的Pod配置:调用Docker拉取业务镜像、创建容器、挂载存储、配置网络;容器启动成功后,kubelet上报Pod就绪状态至API Server,更新etcd
  6. 创建对应Service资源存入etcd,生成ClusterIP虚拟服务,节点上所有kube-proxy监听ServiceEndpoint变更,刷新节点转发规则,Service可以正常将流量路由至该Pod
  7. 集群内部Pod或外部Client访问ClusterIP,流量经由节点Proxy的内核规则负载均衡分发至后端业务容器;
  8. 期间cAdvisor采集容器监控数据,kubelet持续上报运行状态;全程控制器持续调谐,比如容器崩溃自动重启、节点故障自动漂移Pod、副本数不足自动新建Pod,始终维持用户定义的期望状态。

这里再看下传统IT系统中服务扩容和服务升级这两个难题,以及Kubernetes所提供的全新解决思路。服务的扩容涉及资源分配(选择哪个节点进行扩容)、实例部署和启动等环节。在一个复杂的业务系统中,这两个难题基本上要靠人工一步步操作才能得以解决,费时费力又难以保证实施质量。

Kubernetes集群中,只需为需要扩容的Service关联的Pod创建一个Deployment对象,服务扩容以至服务升级等令人头疼的问题就都迎刃而解了。在一个Deployment定义文件中包括以下3个关键信息。

  • 目标Pod的定义。
  • 目标Pod需要运行的副本数量(Replicas)。
  • 要监控的目标Pod的标签。

Desktop View K8s 资源对象之间的组合关系

在创建好Deployment之后,Kubernetes会根据这一定义创建符合要求的Pod,并且通过在Deployment中定义的Label筛选出对应的Pod实例并实时监控其状态和数量。如果实例数量少于定义的副本数量,则会根据在Deployment对象中定义的Pod模板创建一个新的Pod,然后将此Pod调度到合适的Node上启动运行,直到Pod实例的数量达到预定目标。这个过程完全是自动化的,无须人工干预。有了Deployment,服务扩容就变成一个纯粹的简单数字游戏了,只需修改Deployment中的副本数量即可。后续的服务升级也将通过修改Deployment来自动完成。

各组件关键通信细节

  1. API ServerController Manager
    • CM持续Watch各类资源,发现状态不匹配就调用API Server发起增删改请求,CM本身不存储任何集群数据。
  2. API ServerScheduler
    • 调度器只看未绑定Pod,完成节点选择后仅通过API Server修改PodnodeName字段,无直连节点动作。
  3. API Serverkubelet
    • kubelet只拉取本节点相关资源,主动上报状态与心跳,是主动拉取模型,Master不会主动连接节点下发命令。
  4. API Serverkube-proxy
    • 全集群所有节点proxy同步监听ServiceEndpoint,各自本地刷新转发规则,去中心化完成Service负载均衡。
  5. 所有组件与etcd
    • API Server外,其余组件零直接交互etcd,保证数据入口唯一、安全可控。

核心通信设计优势

  1. 解耦设计:所有组件只依赖API Server,组件之间零直连,新增组件只需要对接API Server Watch即可接入集群;
  2. 数据集中管控:唯一数据源etcd,保证集群状态一致性,避免多组件各自存储数据导致数据错乱;
  3. 事件驱动异步协同:依托API Server Watch机制,组件被动监听变更执行任务,无需轮询巡检,性能高效;
  4. 权限统一收口:所有访问、修改集群资源的动作都经过API Server三层鉴权,集群安全可控;
  5. 控制面只负责定义目标状态,节点本地组件自主执行落地,Master不需要维护海量节点长连接下发指令,集群横向扩容能力极强。

搭建K8s测试环境

K8s有多种部署方式,目前主流的方式有3种,分别是minikubekubeadm、二进制部署。

  • minikube:一个用于在单个虚拟机/容器内快速搭建一套完整的单节点Kubernetes集群的工具;
  • kubeadm:一个用于快速搭建Kubernetes集群的工具,适合中小型运维搭建标准高可用集群,进行企业正式生产环境私有化部署;
  • 二进制包:从官网下载每个组件的二进制包,依次去安装,此方式对于理解kubernetes组件更加有效。

三种方式的具体区别参见附录部分(K8s三种主流部署方案对比:kubeadmminikube、二进制部署)。

Kubernetes系统由一组可执行程序组成,一般可以通过KubernetesGitHub的项目网站下载编译好的二进制文件或镜像文件,或者下载源码并自行将其编译为二进制文件。

对于旧版K8s≤1.23),安装Kubernetes对软件和硬件的系统要求如下所示,

软硬件最低配置推荐配置
主机资源集群规模为15个节点时,要求如下。
Master:至少1 core CPU2GB内存。
Node:至少1 core CPU1GB内存。
随着集群规模的增大,应相应增加主机的配置。大规模集群的硬件配置可以参考Kubernetes官网给出的建议
Master4 core CPU16GB内存。
Node:根据需要运行的容器数量进行配置
Linux操作系统各种Linux发行版,包括Red Hat LinuxCentOSFedoraUbuntuDebian等,Kernel版本要求在3.10及以上CentOS 7.8
etcdv3版本及以上
下载和安装说明见etcd官网的说明
v3
DockerKubernetes支持的Docker版本包括1.13.117.0317.0617.0918.0618.09,推荐使用19.03版本。
下载和安装说明见Docker官网的说明
19.03

针对现在主流K8s1.24+、当前最新版v1.35.1,截止时间20260803),相较于旧版,核心变更要点如下,

  1. 彻底移除Docker,替换为官方原生CRI运行时containerd
  2. 内核最低标准抬高,CentOS 7老旧内核不再推荐;
  3. etcd、机器硬件规格结合新版生产最佳实践升级;
  4. 删掉废弃的dockershim相关兼容逻辑。

新版K8s对软件和硬件的系统要求如下所示,

软硬件最低配置推荐生产配置
主机硬件资源
15节点小规模集群)
Master节点:1 core CPU2GB内存
Worker Node节点:1 core CPU1GB内存
集群节点变多、业务负载上涨时同步扩容硬件,超大集群参照K8s官方硬件规划方案
Master控制面:4 core CPU16GB内存(多Master高可用部署)
Worker节点:依据业务容器数量、QPS、内存缓存需求弹性配置,常规业务起步4C8G
Linux操作系统主流Linux发行版:UbuntuDebianRocky LinuxAlmaLinuxOpenEulerAnolis OS
Linux内核最低4.14+(必须开启cgroup v1/v2ipvsoverlayip_tables等内核模块)
Rocky Linux 9.x / Ubuntu 22.04 LTS / Debian 12
内核5.4及以上,优先开启cgroup v2,系统生命周期长、安全补丁维护完善;不再推荐CentOS 7.x(生命周期终止、内核老旧兼容性差)
etcdetcd v3.4及以上版本(K8s 1.24最低要求etcd3.4etcd v3.5.x稳定版,K8s官方标配版本,稳定性、性能、故障自愈能力更强;生产务必独立磁盘挂载etcd数据目录
容器运行时CRI弃用Docker,使用官方原生containerd
最低兼容版本:containerd 1.6+
containerd 1.7.x LTS长期支持版,K8s官方默认标准运行时;无需Docker、无需cri-dockerd转接,原生CRI对接kubelet;配套runc稳定版本

Kubernetes需要容器运行时(Container Runtime InterfaceCRI)的支持,目前官方支持的容器运行时包括DockerContainerdCRI-Ofrakti等。

需要注意的是,如果宿主机操作系统默认启动了防火墙服务(firewalld.service),而KubernetesMaster与工作Node之间会有大量的网络通信。安全的做法是在防火墙上配置各组件需要相互通信的端口号,具体要配置的端口号如下表所示,

组件默认端口号
API Server8080HTTP非安全端口号)
6443HTTPS安全端口号)
Controller Manager10252
Scheduler10251
kubelet10250
10255(只读端口号)
etcd2379(供客户端访问)
2380(供etcd集群内部节点之间访问)
集群DNS服务53UDP
53TCP

其他组件可能还需要开通某些端口号,例如CNI网络插件calico需要179端口号;镜像库需要5000端口号等,需要根据系统要求逐个在防火墙服务上配置网络策略。

在安全的网络环境中,可以简单地关闭防火墙服务,

1
2
systemctl disable firewalld
systemctl stop firewalld

另外,建议在主机上禁用SELinux(修改文件/etc/sysconfig/selinux,将SELINUX=enforcing修改为SELINUX=disabled),让容器可以读取主机文件系统。随着KubernetesSELinux支持的增强,可以逐步启用SELinux机制,并通过Kubernetes设置容器的安全机制。

而对于kubeadmKubernetes 1.4版本以Alpha形态引入,用于简化集群部署;在1.13版本中,kubeadm核心集群初始化、节点加入等基础功能正式GA

  1. Kubernetes 1.4引入kubeadm
    • K8s 1.420169月)正式新增kubeadm,初始状态为Alpha预览阶段,定位就是简化集群一键初始化、节点接入,替代繁杂手工部署各控制面组件。
  2. Kubernetes 1.13版本kubeadm核心能力正式GA
    • kubeadm initkubeadm join、命令行交互、基础集群引导流程、CLI使用规范、组件自动化部署等核心主体功能毕业至GA(正式可用、生产级稳定);
    • 仅高可用部署、配置文件API、部分进阶能力当时仍为Beta/Alpha,行业内公认kubeadm1.13起具备上生产的正式资质。

接下来,这里聚焦使用minikube在单机环境下快速搭建可用的K8s集群实操,对K8s进行测试和本地开发。

Minikube

安装引导

minikube是本地Kubernetes,优点是快速启动,消耗机器资源较少,非常适合新手体验与开发。如果徒手用二进制包部署搭建过K8s就会深有感触,其中复杂的认证,配置环节繁琐,出错率也相当高,而minikube就是为解决这个问题而衍生出来的工具,它基于Go语言开发(minikube github),易于在本地运行Kubernetes,只需要Docker或者虚拟机环境,便可以快速创建启动单机版Kubernetes集群。

What you’ll need?

  • 2 CPUs or more
  • 2GB of free memory
  • 20GB of free disk space
  • Internet connection
  • Container or virtual machine manager, such as: Docker, QEMU, Hyperkit, Hyper-V, KVM, Parallels, Podman, VirtualBox, or VMware Fusion/Workstation

Minikube主打轻量化本地部署,小而美,单二进制可执行文件不足100MB,基础运行镜像(kicbase)约1GB;内置完整标准Kubernetes核心组件,具备容器编排绝大部分原生能力(仅缺失大规模集群专属的分布式调度、多机房容灾、生产级高可用这类重型能力),同时提供DashboardIngressGPUKongIstio、本地镜像仓库等一键开启的官方附加插件(minikube addons),非常适合本地学习与开发调试。

通常情况下,一套完整标准的Kubernetes集群至少需要包括Master节点和Node节点,Master节点一般是独立的,用于协调调试其它节点,而容器都是实际运行在Node节点上,kubectl位于Master节点。从宏观组件角度出发,标准的K8s集群架构如下所示,

Desktop View K8s标准架构

Minikube的架构,从下图可以看出,Master节点和其它节点合为一体,而整体则通过宿主机上的kubectl进行管理,这样可以更加节省资源。

Desktop View minikube单机架构

两种架构的详细对比数据,参见附录部分(标准K8s集群架构 vs Minikube一体化架构)。

开始部署

开始之前,请确保安装了docker,这是minikube的驱动程序(Driver)。

--driver指定Minikube用哪种底层环境来承载整个K8s集群,--driver=docker就是让Minikube借助本机Docker,拉起一个特殊容器,在容器内部运行一整套完整K8s单节点集群,轻量化、免虚拟化、上手最简单,是日常学习调试最常用的驱动模式。

安装minikube

开始安装minikube,如果你的主机是Mac,可以直接执行下面命令,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ brew install minikube

==> Downloading https://formulae.brew.sh/api/formula.jws.json
==> Downloading https://formulae.brew.sh/api/cask.jws.json
==> Downloading https://ghcr.io/v2/homebrew/core/minikube/manifests/1.38.1
Already downloaded: /Users/lordrings/Library/Caches/Homebrew/downloads/adbc572c811d95cfe36536099900dd96d7b29a994a214656403dba59ce9af75b--minikube-1.38.1.bottle_manifest.json
==> Fetching dependencies for minikube: kubernetes-cli
==> Downloading https://ghcr.io/v2/homebrew/core/kubernetes-cli/manifests/1.36.3
Already downloaded: /Users/lordrings/Library/Caches/Homebrew/downloads/102c66915b3657c66a94835711ac244968bd5df7ec82813ee61c2bf828b132aa--kubernetes-cli-1.36.3.bottle_manifest.json
==> Fetching kubernetes-cli
==> Downloading https://ghcr.io/v2/homebrew/core/kubernetes-cli/blobs/sha256:0f5a4e32b0c07cef0211c98caaa69e3ba9552d21e3a0878b9325d9e7ebe8cbbc
Already downloaded: /Users/lordrings/Library/Caches/Homebrew/downloads/2f99aceeeec4af8276782b32c0a461e2dd3d6a82be2d7676f7d4e2924c0e0261--kubernetes-cli--1.36.3.arm64_sequoia.bottle.tar.gz
==> Fetching minikube
==> Downloading https://ghcr.io/v2/homebrew/core/minikube/blobs/sha256:80690c46408b61a2073e533325cf16cdaf4777c66eec5c2e3a87b983615d1e1b
######################################################################################################################################################################################################################################################### 100.0%
==> Installing dependencies for minikube: kubernetes-cli
==> Installing minikube dependency: kubernetes-cli
==> Downloading https://ghcr.io/v2/homebrew/core/kubernetes-cli/manifests/1.36.3
Already downloaded: /Users/lordrings/Library/Caches/Homebrew/downloads/102c66915b3657c66a94835711ac244968bd5df7ec82813ee61c2bf828b132aa--kubernetes-cli-1.36.3.bottle_manifest.json
==> Pouring kubernetes-cli--1.36.3.arm64_sequoia.bottle.tar.gz
🍺  /opt/homebrew/Cellar/kubernetes-cli/1.36.3: 261 files, 59.6MB
==> Installing minikube
==> Pouring minikube--1.38.1.arm64_sequoia.bottle.tar.gz
🍺  /opt/homebrew/Cellar/minikube/1.38.1: 11 files, 129.4MB
==> Running `brew cleanup minikube`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> Caveats
zsh completions have been installed to:
  /opt/homebrew/share/zsh/site-functions

也可以手动下载二进制文件安装,需要注意,如果是M系列芯片的Mac,需要把amd换成arm

1
2
3
4
5
6
#阿里云镜像,
curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.38.1/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

#官方二进制包下载
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

安装完成后,查看版本,正常输出表示安装成功。

1
2
3
$ minikube version
minikube version: v1.38.1
commit: c93a4cb9311efc66b90d33ea03f75f2c4120e9b0
启动minikube集群

直接按照访问Google Container Registry启动,国内环境很可能会因为访问ghcr.io超时导致失败,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ minikube start --driver=docker

😄  Darwin 15.5 (arm64) 上的 minikube v1.38.1
✨  根据用户配置使用 docker 驱动程序
❗  Starting v1.39.0, minikube will default to "containerd" container runtime. See #21973 for more info.
📌  使用具有 root 权限的 Docker Desktop 驱动程序
👍  在集群中 "minikube" 启动节点 "minikube" primary control-plane
🚜  正在拉取基础镜像 v0.0.50 ...
💾  正在下载 Kubernetes v1.35.1 的预加载文件...
    > preloaded-images-k8s-v18-v1...:  243.95 MiB / 243.95 MiB  100.00% 8.52 Mi
❗  minikube cannot pull kicbase image from any docker registry, and is trying to download kicbase tarball from github release page via HTTP.
❗  您很有可能遇到了网络问题。请确保您至少可以通过 HTTP(直连或代理)访问互联网。当前您的代理配置为:

    > kicbase-v0.0.50-arm64.tar:  2.82 MiB / 1.26 GiB  0.22% 8.40 KiB p/s ETA 4^C

那就换一种方式,国内环境直接指定阿里云镜像源,再试一次,可以看到拉镜像的速度确实提升了很多,运气好的话直接就成功了,但博主在启动时还是报错了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$ minikube start --driver=docker --image-mirror-country=cn --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers

😄  Darwin 15.5 (arm64) 上的 minikube v1.38.1
E0802 13:51:03.725304    7520 start.go:846] api.Load failed for minikube: filestore "minikube": Docker machine "minikube" does not exist. Use "docker-machine ls" to list machines. Use "docker-machine create" to add a new one.
E0802 13:51:03.725441    7520 start.go:846] api.Load failed for minikube: filestore "minikube": Docker machine "minikube" does not exist. Use "docker-machine ls" to list machines. Use "docker-machine create" to add a new one.
✨  根据现有的配置文件使用 docker 驱动程序
👍  在集群中 "minikube" 启动节点 "minikube" primary control-plane
🚜  正在拉取基础镜像 v0.0.50 ...
❗  minikube cannot pull kicbase image from any docker registry, and is trying to download kicbase tarball from github release page via HTTP.
❗  您很有可能遇到了网络问题。请确保您至少可以通过 HTTP(直连或代理)访问互联网。当前您的代理配置为:

    > kicbase-v0.0.50-arm64.tar:  210.00 MiB / 1.26 GiB  16.24% 104.44 KiB p/s
E0802 14:28:30.356626    7520 cache.go:239] Error downloading kic artifacts:  failed to download kic base image or any fallback image
🔥  创建 docker container(CPU=2,内存=6100MB)...
🤦  StartHost 失败,将要重试: creating host: create host timed out in 360.000000 seconds
🤷  docker "minikube" 缺失 container,将重新创建。
🔥  创建 docker container(CPU=2,内存=6100MB)...
😿  启动 docker container 失败。运行 "minikube delete" 可能需要修复它: recreate: creating host: create: creating: setting up container node: preparing volume for minikube container: docker run --rm --name minikube-preload-sidecar --label created_by.minikube.sigs.k8s.io=true --label name.minikube.sigs.k8s.io=minikube --entrypoint /usr/bin/test -v minikube:/var gcr.io/k8s-minikube/kicbase:v0.0.50@sha256:eb4fec00e8ad70adf8e6436f195cc429825ffb85f95afcdb5d8d9deb576f3e93 -d /var/lib: exit status 125
stdout:

stderr:
Unable to find image 'gcr.io/k8s-minikube/kicbase:v0.0.50@sha256:eb4fec00e8ad70adf8e6436f195cc429825ffb85f95afcdb5d8d9deb576f3e93' locally
docker: Error response from daemon: failed to resolve reference "gcr.io/k8s-minikube/kicbase@sha256:eb4fec00e8ad70adf8e6436f195cc429825ffb85f95afcdb5d8d9deb576f3e93": failed to do request: Head "https://gcr.io/v2/k8s-minikube/kicbase/manifests/sha256:eb4fec00e8ad70adf8e6436f195cc429825ffb85f95afcdb5d8d9deb576f3e93": context deadline exceeded

Run 'docker run --help' for more information


❌  因 GUEST_PROVISION 错误而退出:error provisioning guest: Failed to start host: recreate: creating host: create: creating: setting up container node: preparing volume for minikube container: docker run --rm --name minikube-preload-sidecar --label created_by.minikube.sigs.k8s.io=true --label name.minikube.sigs.k8s.io=minikube --entrypoint /usr/bin/test -v minikube:/var gcr.io/k8s-minikube/kicbase:v0.0.50@sha256:eb4fec00e8ad70adf8e6436f195cc429825ffb85f95afcdb5d8d9deb576f3e93 -d /var/lib: exit status 125
stdout:

stderr:
Unable to find image 'gcr.io/k8s-minikube/kicbase:v0.0.50@sha256:eb4fec00e8ad70adf8e6436f195cc429825ffb85f95afcdb5d8d9deb576f3e93' locally
docker: Error response from daemon: failed to resolve reference "gcr.io/k8s-minikube/kicbase@sha256:eb4fec00e8ad70adf8e6436f195cc429825ffb85f95afcdb5d8d9deb576f3e93": failed to do request: Head "https://gcr.io/v2/k8s-minikube/kicbase/manifests/sha256:eb4fec00e8ad70adf8e6436f195cc429825ffb85f95afcdb5d8d9deb576f3e93": context deadline exceeded

Run 'docker run --help' for more information


╭─────────────────────────────────────────────────────────────────────────────────────────────────╮
│                                                                                                 │
│    😿  如果上述建议无法帮助解决问题,请告知我们:                                               │
│    👉  https://github.com/kubernetes/minikube/issues/new/choose                                 │
│                                                                                                 │
│    请运行 minikube logs --file=logs.txt 命令,并将生成的 logs.txt 文件附加到 GitHub 问题中。    │
│                                                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯

这个时候需要清空环境,换源重来,

1
2
3
4
5
$ minikube delete --all
🔥  正在删除 docker 中的“minikube”…
🔥  正在移除 /Users/lordrings/.minikube/machines/minikube…
💀  已删除所有关于 "minikube" 集群的痕迹。
🔥  成功删除所有配置文件

手动拉镜像,然后改tag,把老tag删掉,

1
2
3
docker pull registry.aliyuncs.com/google_containers/kicbase:v0.0.50
docker tag registry.aliyuncs.com/google_containers/kicbase:v0.0.50 registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.50
docker rmi registry.aliyuncs.com/google_containers/kicbase:v0.0.50

因为是手动拉的镜像,启动时就得指定镜像源了,手动下载后,打tag后,还有验证环节,因为registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.50自动下载,sha校验失败,导致无法启动集群。通过–base-image参数指定镜像,忽略SHA校验,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ minikube start  --kubernetes-version=v1.35.1  --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://bjtzu1jb.mirror.aliyuncs.com'  --image-mirror-country='cn'   --force --driver=docker  --base-image="registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.50"

😄  Darwin 15.5 (arm64) 上的 minikube v1.38.1
❗  当提供 --force 参数时,minikube 将跳过各种验证,这可能会导致意外行为
✨  根据用户配置使用 docker 驱动程序
❗  Starting v1.39.0, minikube will default to "containerd" container runtime. See #21973 for more info.
✅  正在使用镜像存储库 registry.cn-hangzhou.aliyuncs.com/google_containers
📌  使用具有 root 权限的 Docker Desktop 驱动程序
👍  在集群中 "minikube" 启动节点 "minikube" primary control-plane
🚜  正在拉取基础镜像 v0.0.50 ...
🔥  创建 docker container(CPU=2,内存=6100MB)...
🐳  正在 Docker 29.2.1 中准备 Kubernetes v1.35.1…
🔗  配置 bridge CNI (Container Networking Interface) ...
🔎  正在验证 Kubernetes 组件...
    ▪ 正在使用镜像 registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v5
🌟  启用插件: storage-provisioner, default-storageclass
🏄  完成!kubectl 现在已配置,默认使用"minikube"集群和"default"命名空间

如果启动失败,就增加指定镜像加速器后,重新启动对应pod

1
minikube start  --kubernetes-version=v1.35.1 --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' --registry-mirror='https://bjtzu1jb.mirror.aliyuncs.com' --registry-mirror='https://docker.xuanyuan.me' --registry-mirror='https://docker.1ms.run' --registry-mirror='https://docker.m.daocloud.io' --registry-mirror='https://docker.1panel.live' --registry-mirror='https://docker.jsdelivr.fyi' --registry-mirror='https://dockertest.jsdelivr.fyi' --registry-mirror='https://hub.rat.dev' --registry-mirror='https://docker.rainbond.cc' --registry-mirror='https://dockerproxy.com' --image-mirror-country='cn'   --force --driver=docker  --base-image="registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.50"
启动minikube addons部分官方附加插件

启动kubernetes-dashboarddashboard-metrics-scrapermetrics-server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ minikube addons enable dashboard

💡  dashboard 是由 Kubernetes 维护的插件。如有任何问题,请在 GitHub 上联系 minikube。
您可以在以下链接查看 minikube 的维护者列表:https://github.com/kubernetes/minikube/blob/master/OWNERS
    ▪ 正在使用镜像 docker.io/kubernetesui/dashboard:v2.7.0
    ▪ 正在使用镜像 docker.io/kubernetesui/metrics-scraper:v1.0.8
💡  某些仪表板功能需要 metrics-server 插件。要启用所有功能,请运行:

	minikube addons enable metrics-server

🌟  启动 'dashboard' 插件

$ minikube addons enable metrics-server

💡  metrics-server 是由 Kubernetes 维护的插件。如有任何问题,请在 GitHub 上联系 minikube。
您可以在以下链接查看 minikube 的维护者列表:https://github.com/kubernetes/minikube/blob/master/OWNERS
    ▪ 正在使用镜像 registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.8.1
🌟  启动 'metrics-server' 插件

$ minikube dashboard

查看nodepod,可以看到基础镜像对应的容器都运行起来了,但dashboardmetric对应的容器报错了,不过不着急,排查定位下怎么回事,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ kubectl get nodes
NAME       STATUS   ROLES           AGE    VERSION
minikube   Ready    control-plane   3m8s   v1.35.1

$ kubectl get pods -A
NAMESPACE              NAME                                         READY   STATUS             RESTARTS   AGE
kube-system            coredns-764897d7b-79t22                      1/1     Running            0          30m
kube-system            etcd-minikube                                1/1     Running            0          30m
kube-system            kube-apiserver-minikube                      1/1     Running            0          30m
kube-system            kube-controller-manager-minikube             1/1     Running            0          30m
kube-system            kube-proxy-7qfqd                             1/1     Running            0          30m
kube-system            kube-scheduler-minikube                      1/1     Running            0          30m
kube-system            metrics-server-5c7d84f46b-b6zh8              0/1     ImagePullBackOff   0          16m
kube-system            storage-provisioner                          1/1     Running            0          30m
kubernetes-dashboard   dashboard-metrics-scraper-5565989548-c4wkx   0/1     ImagePullBackOff   0          26m
kubernetes-dashboard   kubernetes-dashboard-b84665fb8-p8l8g         0/1     ImagePullBackOff   0          26m

查看Pod的详细运行时诊断信息,发现拉镜像失败,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
$ kubectl describe pod kubernetes-dashboard-b84665fb8-p8l8g  -n kubernetes-dashboard

Name:             kubernetes-dashboard-b84665fb8-p8l8g
Namespace:        kubernetes-dashboard
Priority:         0
Service Account:  kubernetes-dashboard
Node:             minikube/192.168.49.2
Start Time:       Sun, 02 Aug 2026 15:51:08 +0800
Labels:           gcp-auth-skip-secret=true
                  k8s-app=kubernetes-dashboard
                  pod-template-hash=b84665fb8
Annotations:      <none>
Status:           Pending
IP:               10.244.0.4
IPs:
  IP:           10.244.0.4
Controlled By:  ReplicaSet/kubernetes-dashboard-b84665fb8
Containers:
  kubernetes-dashboard:
    Container ID:
    Image:         docker.io/kubernetesui/dashboard:v2.7.0@sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93
    Image ID:
    Port:          9090/TCP
    Host Port:     0/TCP
    Args:
      --namespace=kubernetes-dashboard
      --enable-skip-login
      --disable-settings-authorizer
    State:          Waiting
      Reason:       ImagePullBackOff
    Ready:          False
    Restart Count:  0
    Liveness:       http-get http://:9090/ delay=30s timeout=30s period=10s #success=1 #failure=3
    Environment:    <none>
    Mounts:
      /tmp from tmp-volume (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-cvg5t (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True
  Initialized                 True
  Ready                       False
  ContainersReady             False
  PodScheduled                True
Volumes:
  tmp-volume:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>
  kube-api-access-cvg5t:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    Optional:                false
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              kubernetes.io/os=linux
Tolerations:                 node-role.kubernetes.io/master:NoSchedule
                             node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason     Age                   From               Message
  ----     ------     ----                  ----               -------
  Normal   Scheduled  22m                   default-scheduler  Successfully assigned kubernetes-dashboard/kubernetes-dashboard-b84665fb8-p8l8g to minikube
  Warning  Failed     21m                   kubelet            spec.containers{kubernetes-dashboard}: Failed to pull image "docker.io/kubernetesui/dashboard:v2.7.0@sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93": Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
  Normal   Pulling    18m (x5 over 22m)     kubelet            spec.containers{kubernetes-dashboard}: Pulling image "docker.io/kubernetesui/dashboard:v2.7.0@sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93"
  Warning  Failed     18m (x4 over 22m)     kubelet            spec.containers{kubernetes-dashboard}: Failed to pull image "docker.io/kubernetesui/dashboard:v2.7.0@sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93": Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
  Warning  Failed     18m (x5 over 22m)     kubelet            spec.containers{kubernetes-dashboard}: Error: ErrImagePull
  Normal   BackOff    2m22s (x74 over 22m)  kubelet            spec.containers{kubernetes-dashboard}: Back-off pulling image "docker.io/kubernetesui/dashboard:v2.7.0@sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93"
  Warning  Failed     117s (x76 over 22m)   kubelet            spec.containers{kubernetes-dashboard}: Error: ImagePullBackOff

获取该Pod完整原生YAML资源定义文件,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
$ kubectl get pod kubernetes-dashboard-b84665fb8-p8l8g  -n kubernetes-dashboard -o yaml

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2026-08-02T07:51:08Z"
  generateName: kubernetes-dashboard-b84665fb8-
  generation: 1
  labels:
    gcp-auth-skip-secret: "true"
    k8s-app: kubernetes-dashboard
    pod-template-hash: b84665fb8
  name: kubernetes-dashboard-b84665fb8-p8l8g
  namespace: kubernetes-dashboard
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: kubernetes-dashboard-b84665fb8
    uid: 4aea788e-d421-41ed-9d71-8d0ec5919ec7
  resourceVersion: "2109"
  uid: cfbb7ec9-6af8-4baf-a7c7-0f704e0586cc
spec:
  containers:
  - args:
    - --namespace=kubernetes-dashboard
    - --enable-skip-login
    - --disable-settings-authorizer
    image: docker.io/kubernetesui/dashboard:v2.7.0@sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93
    imagePullPolicy: IfNotPresent
    livenessProbe:
      failureThreshold: 3
      httpGet:
        path: /
        port: 9090
        scheme: HTTP
      initialDelaySeconds: 30
      periodSeconds: 10
      successThreshold: 1
      timeoutSeconds: 30
    name: kubernetes-dashboard
    ports:
    - containerPort: 9090
      protocol: TCP
    resources: {}
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      runAsGroup: 2001
      runAsUser: 1001
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /tmp
      name: tmp-volume
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-cvg5t
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: minikube
  nodeSelector:
    kubernetes.io/os: linux
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: kubernetes-dashboard
  serviceAccountName: kubernetes-dashboard
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - emptyDir: {}
    name: tmp-volume
  - name: kube-api-access-cvg5t
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2026-08-02T07:51:23Z"
    observedGeneration: 1
    status: "True"
    type: PodReadyToStartContainers
  - lastProbeTime: null
    lastTransitionTime: "2026-08-02T07:51:08Z"
    observedGeneration: 1
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2026-08-02T07:51:08Z"
    message: 'containers with unready status: [kubernetes-dashboard]'
    observedGeneration: 1
    reason: ContainersNotReady
    status: "False"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2026-08-02T07:51:08Z"
    message: 'containers with unready status: [kubernetes-dashboard]'
    observedGeneration: 1
    reason: ContainersNotReady
    status: "False"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2026-08-02T07:51:08Z"
    observedGeneration: 1
    status: "True"
    type: PodScheduled
  containerStatuses:
  - image: docker.io/kubernetesui/dashboard:v2.7.0@sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93
    imageID: ""
    lastState: {}
    name: kubernetes-dashboard
    ready: false
    restartCount: 0
    started: false
    state:
      waiting:
        message: 'Back-off pulling image "docker.io/kubernetesui/dashboard:v2.7.0@sha256:2e500d29e9d5f4a086b908eb8dfe7ecac57d2ab09d65b24f588b1d449841ef93":
          ErrImagePull: Error response from daemon: Get "https://registry-1.docker.io/v2/":
          EOF'
        reason: ImagePullBackOff
    volumeMounts:
    - mountPath: /tmp
      name: tmp-volume
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-cvg5t
      readOnly: true
      recursiveReadOnly: Disabled
  hostIP: 192.168.49.2
  hostIPs:
  - ip: 192.168.49.2
  observedGeneration: 1
  phase: Pending
  podIP: 10.244.0.4
  podIPs:
  - ip: 10.244.0.4
  qosClass: BestEffort
  startTime: "2026-08-02T07:51:08Z"

删除报错的pod容器,进到minikube里手动拉对应镜像,重新启动对应pod

1
2
3
$ kubectl delete deployment -n kubernetes-dashboard kubernetes-dashboard dashboard-metrics-scraper
$ kubectl delete service -n kubernetes-dashboard kubernetes-dashboard dashboard-metrics-scraper
$ kubectl delete deployment -n kube-system metrics-server
1
2
3
4
$ minikube ssh
$ docker pull kubernetesui/dashboard:v2.7.0
$ docker pull kubernetesui/metrics-scraper:v1.0.8
$ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.8.1

现在kubernetes-dashboard下面的pod启动成功了,但metrics-server依然报错,

1
2
3
4
5
6
7
8
9
10
11
12
$ kubectl get pods -A
NAMESPACE              NAME                                         READY   STATUS             RESTARTS        AGE
kube-system            coredns-764897d7b-vn644                      1/1     Running            0               5m59s
kube-system            etcd-minikube                                1/1     Running            0               6m5s
kube-system            kube-apiserver-minikube                      1/1     Running            0               6m5s
kube-system            kube-controller-manager-minikube             1/1     Running            0               6m5s
kube-system            kube-proxy-8dp7q                             1/1     Running            0               5m59s
kube-system            kube-scheduler-minikube                      1/1     Running            0               6m5s
kube-system            metrics-server-5c7d84f46b-s96qz              0/1     ImagePullBackOff   0               4m32s
kube-system            storage-provisioner                          1/1     Running            1 (5m58s ago)   6m3s
kubernetes-dashboard   dashboard-metrics-scraper-5565989548-tl57k   1/1     Running            0               7s
kubernetes-dashboard   kubernetes-dashboard-b84665fb8-tpflm         1/1     Running            0               7s

进入minikube,查看registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.8.1,镜像也确实拉取成功了,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
IMAGE                                                                                ID             DISK USAGE   CONTENT SIZE   EXTRA
gcr.io/k8s-minikube/storage-provisioner:v5                                           ba04bb24b957         29MB             0B
kubernetesui/dashboard:v2.7.0                                                        20b332c9a70d        244MB             0B
kubernetesui/metrics-scraper:v1.0.8                                                  a422e0e98235       42.3MB             0B
registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.13.1                  e08f4d9d2e6e       73.4MB             0B    U
registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.6.6-0                     271e49a0ebc5       59.8MB             0B    U
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.35.1           7459ea001763       83.9MB             0B    U
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.35.1  464c974e702e       71.1MB             0B    U
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.35.1               2d611d040292       72.5MB             0B    U
registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.35.1           4cad4f996631       48.7MB             0B    U
registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.8.1            b39bceeb0c59       79.9MB             0B
registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1                     d7b100cd9a77        514kB             0B    U
registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v5           66749159455b         29MB             0B    U
registry.k8s.io/coredns/coredns:v1.13.1                                              e08f4d9d2e6e       73.4MB             0B    U
registry.k8s.io/etcd:3.6.6-0                                                         271e49a0ebc5       59.8MB             0B    U
registry.k8s.io/kube-apiserver:v1.35.1                                               7459ea001763       83.9MB             0B    U
registry.k8s.io/kube-controller-manager:v1.35.1                                      464c974e702e       71.1MB             0B    U
registry.k8s.io/kube-proxy:v1.35.1                                                   2d611d040292       72.5MB             0B    U
registry.k8s.io/kube-scheduler:v1.35.1                                               4cad4f996631       48.7MB             0B    U
registry.k8s.io/pause:3.10.1                                                         d7b100cd9a77        514kB             0B    U

查看容器运行状态,发现仅拉起了pause容器,业务容器迟迟无法启动,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CONTAINER ID   IMAGE                                                              COMMAND                  CREATED          STATUS          PORTS     NAMES
dc6c8137f850   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1   "/pause"                 17 seconds ago   Up 17 seconds             k8s_POD_metrics-server-5c7d84f46b-q9smn_kube-system_3303e2f3-07a8-45ff-b192-a30d2840a48d_0
96bd4d869a6c   a422e0e98235                                                       "/metrics-sidecar"       31 seconds ago   Up 30 seconds             k8s_dashboard-metrics-scraper_dashboard-metrics-scraper-5565989548-w2879_kubernetes-dashboard_cca4a3f8-d284-43b0-9ca3-d5a2a99967d1_0
31d037bb6f8b   20b332c9a70d                                                       "/dashboard --insecu…"   31 seconds ago   Up 30 seconds             k8s_kubernetes-dashboard_kubernetes-dashboard-b84665fb8-xkh44_kubernetes-dashboard_82055dbd-6d20-4b95-b933-47a0cb86e4f0_0
64fef38840c8   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1   "/pause"                 31 seconds ago   Up 30 seconds             k8s_POD_kubernetes-dashboard-b84665fb8-xkh44_kubernetes-dashboard_82055dbd-6d20-4b95-b933-47a0cb86e4f0_0
6b361cb24a75   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1   "/pause"                 31 seconds ago   Up 30 seconds             k8s_POD_dashboard-metrics-scraper-5565989548-w2879_kubernetes-dashboard_cca4a3f8-d284-43b0-9ca3-d5a2a99967d1_0
ab1932bb52e8   66749159455b                                                       "/storage-provisioner"   16 minutes ago   Up 16 minutes             k8s_storage-provisioner_storage-provisioner_kube-system_256c421f-72f2-4623-bc29-8c21573e9ba7_1
bf44a0991559   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1   "/pause"                 16 minutes ago   Up 16 minutes             k8s_POD_storage-provisioner_kube-system_256c421f-72f2-4623-bc29-8c21573e9ba7_0
50de67f88b45   2d611d040292                                                       "/usr/local/bin/kube…"   16 minutes ago   Up 16 minutes             k8s_kube-proxy_kube-proxy-8dp7q_kube-system_1ef4a448-fa2e-4dd1-b94e-2a52757f7f73_0
b969eb02de7c   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1   "/pause"                 16 minutes ago   Up 16 minutes             k8s_POD_kube-proxy-8dp7q_kube-system_1ef4a448-fa2e-4dd1-b94e-2a52757f7f73_0
0f6a576fc2f8   e08f4d9d2e6e                                                       "/coredns -conf /etc…"   16 minutes ago   Up 16 minutes             k8s_coredns_coredns-764897d7b-vn644_kube-system_1024c2c9-c131-44b7-ac36-77822fb0d1c0_0
359a101a5cbc   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1   "/pause"                 16 minutes ago   Up 16 minutes             k8s_POD_coredns-764897d7b-vn644_kube-system_1024c2c9-c131-44b7-ac36-77822fb0d1c0_0
a5529c63b222   464c974e702e                                                       "kube-controller-man…"   17 minutes ago   Up 17 minutes             k8s_kube-controller-manager_kube-controller-manager-minikube_kube-system_19b427e1d37b9fd0d882f76e62a66b84_0
e7ec047e966d   4cad4f996631                                                       "kube-scheduler --au…"   17 minutes ago   Up 17 minutes             k8s_kube-scheduler_kube-scheduler-minikube_kube-system_086eaeec51b433affd8333b1d43aa0a8_0
3301066256de   271e49a0ebc5                                                       "etcd --advertise-cl…"   17 minutes ago   Up 17 minutes             k8s_etcd_etcd-minikube_kube-system_aaa7ce2eca00c4a1cf9be34bd747dbcb_0
2d6941017bdc   7459ea001763                                                       "kube-apiserver --ad…"   17 minutes ago   Up 17 minutes             k8s_kube-apiserver_kube-apiserver-minikube_kube-system_e2613938d4b5914ecd776a117abab97f_0
1d3c7674dbb4   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1   "/pause"                 17 minutes ago   Up 17 minutes             k8s_POD_kube-scheduler-minikube_kube-system_086eaeec51b433affd8333b1d43aa0a8_0
96e0eb4ca5b7   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1   "/pause"                 17 minutes ago   Up 17 minutes             k8s_POD_etcd-minikube_kube-system_aaa7ce2eca00c4a1cf9be34bd747dbcb_0
bfd08d3dd6bd   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1   "/pause"                 17 minutes ago   Up 17 minutes             k8s_POD_kube-controller-manager-minikube_kube-system_19b427e1d37b9fd0d882f76e62a66b84_0
d4677ac113d2   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.10.1   "/pause"                 17 minutes ago   Up 17 minutes             k8s_POD_kube-apiserver-minikube_kube-system_e2613938d4b5914ecd776a117abab97f_0

对比SHA值发现,镜像配置写死了完整哈希,和pull下来的镜像SHA值不一致,

1
$ kubectl edit deployment metrics-server -n kube-system

Desktop View 镜像配置里的SHA

Desktop View 本地镜像的SHA

K8s会严格校验本地镜像的sha256指纹,本地拉的同名镜像哈希不一致,即便tag一样,kubelet依旧判定镜像不匹配,强行尝试拉取远端校验,进而报拉取异常。

解决方案1:去掉镜像配置后面的sha256校验(最简单修复)

编辑deployment

1
kubectl edit deployment metrics-server -n kube-system

把这一行

1
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.8.1@sha256:b2d2eaf5ac3b366ed0f839d2412a2c4279d4fc2a2a733f12c52133faed36c41

精简为不带哈希,

1
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.8.1

保存退出,Deployment自动重建PodIfNotPresent直接使用本地tag匹配的镜像,跳过sha强校验。

解决方案2:本地镜像重新打标对齐sha校验(不修改yaml)。

进入minikube节点,重新拉取带该sha的镜像保证指纹一致,

1
2
minikube ssh
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.8.1@sha256:b2d2eaf5ac3b366ed0f839d2412a2c4279d4fc2a2a733f12c52133faed36c41

拉完退出,重启metrics-server,这里不要删pod重新拉起,这样配置文件会重新加载不匹配的SHA

1
2
3
$ kubectl rollout restart deployment metrics-server -n kube-system

deployment.apps/metrics-server restarted

当前所有期望的pod都能成功运行起来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ kubectl get pods -A
NAMESPACE              NAME                                         READY   STATUS        RESTARTS      AGE
kube-system            coredns-764897d7b-vn644                      1/1     Running       0             33m
kube-system            etcd-minikube                                1/1     Running       0             33m
kube-system            kube-apiserver-minikube                      1/1     Running       0             33m
kube-system            kube-controller-manager-minikube             1/1     Running       0             33m
kube-system            kube-proxy-8dp7q                             1/1     Running       0             33m
kube-system            kube-scheduler-minikube                      1/1     Running       0             33m
kube-system            metrics-server-564f44f5d7-sjcdx              1/1     Terminating   0             16s
kube-system            metrics-server-7c8fd4b889-clc9m              1/1     Running       0             3s
kube-system            storage-provisioner                          1/1     Running       0             33m
kubernetes-dashboard   dashboard-metrics-scraper-5565989548-p7j8p   1/1     Running       0             47s
kubernetes-dashboard   kubernetes-dashboard-b84665fb8-sxj5h         1/1     Running       0             47s

$ kubectl get pods -A
NAMESPACE              NAME                                         READY   STATUS    RESTARTS      AGE
kube-system            coredns-764897d7b-vn644                      1/1     Running   0             33m
kube-system            etcd-minikube                                1/1     Running   0             33m
kube-system            kube-apiserver-minikube                      1/1     Running   0             33m
kube-system            kube-controller-manager-minikube             1/1     Running   0             33m
kube-system            kube-proxy-8dp7q                             1/1     Running   0             33m
kube-system            kube-scheduler-minikube                      1/1     Running   0             33m
kube-system            metrics-server-7c8fd4b889-clc9m              1/1     Running   0             4s
kube-system            storage-provisioner                          1/1     Running   0             33m
kubernetes-dashboard   dashboard-metrics-scraper-5565989548-p7j8p   1/1     Running   0             48s
kubernetes-dashboard   kubernetes-dashboard-b84665fb8-sxj5h         1/1     Running   0             48s
查看Dashboard

执行命令,或者直接输入url,可以直接打开Dashboard控制面板,

1
2
3
4
5
$ minikube dashboard
🤔  正在验证 dashboard 运行情况 ...
🚀  正在启动代理...
🤔  正在验证 proxy 运行状况 ...
🎉  正在使用默认浏览器打开 http://127.0.0.1:60471/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ ...

Desktop View K8s控制面板

hello world测试

新建hello.yaml,如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-nginx
  template:
    metadata:
      labels:
        app: hello-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: hello-nginx
spec:
  type: NodePort
  selector:
    app: hello-nginx
  ports:
  - port: 80
    targetPort: 80

yaml内包含两类资源:DeploymentService,应用配置文件会有以下操作,

  1. 创建名为hello-nginxDeployment
    • 拉起1个运行nginx镜像的Pod,标签为app:hello-nginx
  2. 创建名为hello-nginxNodePort类型Service
    • 通过标签匹配选中上述Nginx Pod,内部端口80暴露至集群,同时开放宿主机NodePort端口供外部访问。

应用配置文件命令如下,

1
kubectl apply -f hello.yaml

dashboard看下效果,pending为创建中,running表示创建成功。

Desktop View hello case pending

Desktop View hello case running

Desktop View hello case pod

minikube可以自动唤起浏览器打开hello world页面,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ minikube service hello-nginx
┌───────────┬─────────────┬─────────────┬───────────────────────────┐
│ NAMESPACE │    NAME     │ TARGET PORT │            URL            │
├───────────┼─────────────┼─────────────┼───────────────────────────┤
│ default   │ hello-nginx │ 80          │ http://192.168.49.2:31738 │
└───────────┴─────────────┴─────────────┴───────────────────────────┘
🔗  为服务 hello-nginx 启动隧道。
┌───────────┬─────────────┬─────────────┬────────────────────────┐
│ NAMESPACE │    NAME     │ TARGET PORT │          URL           │
├───────────┼─────────────┼─────────────┼────────────────────────┤
│ default   │ hello-nginx │             │ http://127.0.0.1:55043 │
└───────────┴─────────────┴─────────────┴────────────────────────┘
🎉  正通过默认浏览器打开服务 default/hello-nginx...
❗  因为你正在使用 darwin 上的 Docker 驱动程序,所以需要打开终端才能运行它。

也可以手动获取地址访问,

1
2
3
4
# 查看访问地址与端口
minikube service hello-nginx --url
# curl 命令访问测试
curl $(minikube service hello-nginx --url)

在浏览器打开url,看到下面效果,说明hello world资源测试成功。

Desktop View hello case web view

附录

云原生的发展

概念萌芽期(2010-2013):云原生名词诞生,容器技术落地

  1. 概念首次提出

    2010年,Paul Fremantle最早在博客提出Cloud Native一词,用来描述适配云计算环境的应用设计思路,但未形成完整体系;

    2013年,Pivotal公司Matt Stine正式普及云原生概念,在行业内大范围传播;

    2015年,《迁移到云原生架构》一书给出初代五大特征:12因素应用、面向微服务、自敏捷架构、基于API协作、抗脆弱性。

  2. 容器技术迎来拐点

    20133月,Docker正式开源发布,彻底降低容器使用门槛,解决环境不一致难题,让打包、分发、跨环境运行标准化,为云原生打下最核心载体基础。

    此时行业还停留在单体应用虚拟化阶段:所有业务耦合在一套程序,部署在物理机/虚拟机,扩容、发布、故障恢复全靠人工,运维成本极高。

微服务与容器编排起步期(2014-2015):架构第一次进化

  1. 单体架构→微服务架构演进

    早期单体所有功能耦合,一处故障全站宕机、迭代必须全量发布;互联网大厂开始垂直拆分业务,拆分为独立微服务(用户、订单、支付等),每个服务独立开发、部署、扩容。

    但原生微服务存在致命痛点:Spring Cloud这类框架代码侵入式,业务代码要嵌入注册中心、负载均衡、熔断SDK,多语言场景维护成本极高,为后续Service Mesh埋下需求伏笔。

  2. 容器编排群雄争霸,K8s登场

    20146月,Google开源Kubernetes,脱胎内部十年容器调度系统Borg,目标统一大规模容器管理;同期Docker推出ComposeSwarmMesos+Marathon并行竞争编排市场。

    20157月,Google联合Linux基金会成立CNCF云原生计算基金会,将K8s捐赠为首个旗舰孵化项目,初代CNCF云原生定义出炉:容器化、微服务、动态编排调度三大核心支柱。

  3. 微服务通信Sidecar思想出现

    行业开始思考:把网络治理(负载、限流、服务发现)从业务代码剥离,独立为Sidecar边车进程,和业务容器同Pod部署,实现无侵入治理,这是Service Mesh的核心雏形。

Service Mesh诞生,生态扩张期(2016-2017):云原生进入第二阶段

  1. 首个服务网格Linkerd问世

    20161月,Linkerd开源,首次创造Service Mesh(服务网格)名词,纯Sidecar架构接管服务间全部流量,实现无侵入微服务治理;

    2017年,Linkerd加入CNCF、发布1.0生产可用版本。

  2. 高性能代理Envoy开源

    20169月,Lyft开源C++编写Envoy代理,性能、可观测性远超Linkerd初代,后续成为IstioLinkerd v2数据平面标准底座,同年加入CNCF

  3. K8s确立编排标准

    2017年,K8s在容器编排竞争中全面胜出,各大云厂商全线支持;CNCF孵化Prometheus(监控)、Jaeger(链路追踪)、gRPCRPC)、CoreDNS等配套云原生工具,完整技术生态成型。

CNCF重新定义云原生(2018):里程碑式概念升级

20186月,CNCF发布新版云原生官方定义,彻底扩充技术边界,新增三大核心支柱:服务网格、不可变基础设施、声明式API

至此云原生五大代表技术定型,
容器、微服务、服务网格、不可变基础设施、声明式API

新增三大核心概念解读
  1. 服务网格(Service Mesh

    独立于业务的基础设施流量治理层,拆分数据面(Sidecar代理)+控制面(统一配置下发),完全消除微服务框架代码侵入,多语言、无改造即可实现灰度、限流、熔断、mTLS加密。

  2. 不可变基础设施

    服务器/容器一旦部署完成不再现场修改,变更直接重建全新实例替换旧节点,杜绝环境漂移、配置不一致,故障可快速回滚。

  3. 声明式API

    YAML声明期望状态,由平台自动协调达成目标(K8s资源体系为典型代表),区别于逐条执行的命令式操作,容错、自动化能力大幅提升。

    同年,Google+IBM+Lyft联合发布Istio,整合Envoy数据面与完整控制平面,提供全链路流量治理、安全、可观测,成为主流企业级服务网格方案。

国内云原生跟进与生产落地期(2019-2023)

  1. 国内大厂自研服务网格:蚂蚁SOFA Mesh、腾讯TSM、华为CSE Mesher,适配Java微服务、国产化基础设施,补充Istio落地短板。
  2. K8s持续迭代:1.24版本彻底移除dockershim,废弃Docker原生支持,containerd成为默认容器运行时,云原生运行时标准统一;
  3. 完整生产链路成型:K8s+Harbor镜像仓库+Jenkins CI/CD+Ingress灰度+Prometheus监控+HPA自动扩缩容成为企业标准云原生落地方案;
  4. CNCF毕业项目持续扩容:containerdEnvoyJaegerHelm等工具全部完成毕业,技术标准完全稳定可靠。

近年演进(2024至今):云原生下沉、AI原生融合

  1. Serverless、云原生函数持续普及,弱化集群运维成本;
  2. 平台工程(Platform Engineering)兴起,基于K8s打造企业内部统一开发平台;
  3. AI原生成为新趋势:基于K8s调度大模型训练、推理任务,云原生成为AI算力标准底座;
  4. 国产化云原生生态完善:openEuler、麒麟系统适配K8s,国产容器运行时、服务网格大规模商用。

整体阶段演进总结

  1. 2010-2013:概念萌芽 + Docker容器普及,解决环境一致性;
  2. 2014-2015:微服务拆分 + K8s诞生,解决资源调度、分布式部署;
  3. 2016-2017Service Mesh诞生,解决微服务代码侵入、流量治理;
  4. 2018CNCF重新定义云原生,确立五大核心技术体系;
  5. 2019-2023:企业大规模生产落地,完整DevOps+K8s链路标准化;
  6. 2024至今:平台工程、AI原生融合,云原生覆盖算力全场景。

K8s三种主流部署方案对比:kubeadm、minikube、二进制部署

整体定位总览

部署方式核心定位适用集群规模上手难度学习价值生产适用性
minikube单机轻量化体验版K8s单节点本地测试集群极低基础入门完全不适合生产
kubeadm官方标准化集群部署工具Master、多Master高可用正式集群中等中等,理解整体调度流程官方主推生产部署方案
二进制手动部署纯原生组件分步安装任意架构集群极高最高,吃透K8s底层架构资深运维定制化生产部署

minikube

工作原理

minikube会在本机(Windows/macOS/Linux)拉起一套虚拟化环境(VirtualBoxHyper-VDockerPodmanKVM),在单个虚拟机/容器内部署一套完整的单节点Kubernetes集群。

内置全套组件:etcdkube-apiserverkube-controller-managerkube-schedulerkubeletcontainer runtimeCoreDNS,所有控制平面组件与Node节点全部挤在同一实例内。

核心特点
  1. 开箱即用

    一条命令即可拉起集群,

    1
    
     minikube start --driver=docker
    

    自动处理镜像拉取、证书签发、网络插件、kubeconfig配置,全程无需手动配置证书、网络、存储。

  2. 资源轻量化

    默认仅分配2C2G,仅用于本地开发调试、验证yaml、学习基础命令、简单控制器测试(DeploymentServiceIngress)。

  3. 配套便捷工具:内置镜像仓库挂载、本地端口转发、dashboard一键开启、内置addoningressmetrics-serverregistry等)。

优势
  1. 零复杂环境配置,新手零门槛接触K8s
  2. 不污染本机环境,集群销毁一键执行minikube delete
  3. 适配本地开发,开发者把服务打包镜像直接推送到minikube内置仓库测试。
短板与局限
  1. 仅单节点,无集群高可用,没有MasterNode分离架构;
  2. 架构做了高度封装,看不到组件启动流程、证书签发逻辑、组件之间通信细节;
  3. 性能弱,不支持大规模压测、正式业务运行;
  4. 网络、存储都是minikube封装的简易方案,和线上标准集群差异较大。
适用场景
  1. K8s零基础入门练习kubectl命令;
  2. 本地开发验证业务yaml配置、调试控制器逻辑;
  3. 课程实验、临时验证小功能,不做任何线上环境参考。

kubeadm(官方主流工业化部署工具)

工作原理

kubeadmKubernetes官方原生提供的集群引导工具,只负责集群初始化、证书签发、组件编排、控制平面引导,不安装容器运行时(containerd/docker)、系统依赖,运维提前装好基础环境后,两条核心命令完成集群构建。

  1. kubeadm init:初始化Master控制平面,自动:
    • 生成CA根证书、各个组件客户端/服务端证书;
    • 部署etcd(单节点内嵌etcdHA模式外置独立etcd);
    • 启动 apiservercontroller-managerscheduler
    • 生成管理员kubeconfig
    • 输出Node节点加入集群的join指令。
  2. kubeadm joinNode节点携带tokenhash校验接入集群,kubelet自动向apiserver完成注册。

配套需要手动补充:容器运行时、CNI网络插件(CalicoFlannel)、系统内核参数优化、内核模块、ipvssysctl等。

架构支持
  1. Master单节点集群(测试环境);
  2. Master高可用集群(生产主流:负载均衡+3Master+独立etcd集群),是企业生产环境最普遍的部署方式。
优势
  1. 官方标准规范,集群架构完全贴合K8s原生设计,升级、降级、证书轮换、版本迁移官方全流程支持;
  2. 自动化处理最繁琐的证书体系,K8s安全核心的双向TLS认证无需手动签发;
  3. 运维工作量适中,兼顾效率与可控性,是云厂商自建K8s、企业私有化部署首选;
  4. 生态配套完善:kubeadm配置文件固化部署参数,可批量脚本自动化装机。
短板
  1. 对底层组件细节屏蔽较多:看不到apiservercontroller-manager配置文件完整构建过程,新手难以理解组件启动参数、证书签发全流程;
  2. 基础环境(内核、运行时、网络前置配置)仍需要运维自行适配;
  3. 高度依赖kubeadm版本对齐,跨大版本升级需要遵循官方严格流程。
适用场景
  1. 企业正式生产环境私有化部署K8s
  2. 中小型运维搭建标准高可用集群;
  3. 学习标准集群运维、集群升级、故障排查、日常运维最佳实践。

二进制包手动部署(原生裸装)

工作原理

完全脱离任何封装工具,从K8s官方发布页下载每一个组件独立二进制可执行文件。 kube-apiserverkube-controller-managerkube-scheduleretcdkubeletkube-proxy,分步全手动操作,

  1. 搭建基础系统环境、内核优化、关闭防火墙/selinux、配置时间同步;
  2. 自行搭建CA证书体系,使用openssl签发全套证书(CA根证书、apiserver证书、kubelet证书、etcd证书、管理员证书等);
  3. 依次部署etcd集群,配置etcd证书认证、数据目录、启动服务;
  4. 逐个编写systemd服务文件,按依赖顺序启动 apiservercontroller-managerscheduler
  5. 配置kubelet证书、授权规则,节点注册;
  6. 手动配置kube-proxy、部署CNI网络插件、初始化RBAC权限、bootstrap认证等。

全程没有自动化步骤,每一个配置项、证书、启动参数都由人工定义。

优势
  1. 学习价值天花板:完整吃透K8s底层运行机制,
    • 理解各组件之间调用关系:kubeletapiserveretcd
    • 吃透K8s整个TLS证书安全体系、RBAC授权流程;
    • 清楚每个组件启动参数的作用、关键配置项含义;
    • 理解集群启动依赖顺序,排查底层组件异常时得心应手。
  2. 极致自定义:可以任意裁剪组件、定制启动参数、做深度安全加固、特殊架构改造,不受kubeadm固化逻辑限制;
  3. 无第三方封装,集群完全自主可控,不存在工具黑盒。
致命短板
  1. 部署极其繁琐、步骤极多,一套三Master高可用集群完整部署耗时大半天;
  2. 容错率极低,证书配置错误、systemd参数写错、权限配置失误都会直接导致集群无法启动;
  3. 集群升级极其麻烦,需要逐个替换二进制文件、更新证书、滚动重启组件,没有自动化方案;
  4. 对运维功底要求极高,新手极易踩坑。
适用场景
  1. 资深运维深耕K8s底层原理、面试深度原理学习;
  2. 高度定制化私有化场景,需要极致安全加固、特殊改造;
  3. 云厂商自研K8s发行版前期底层架构打磨;
  4. 几乎不会作为常规企业日常生产首选部署方式,维护成本太高。

三者核心关键维度横向对比

证书管理
  1. minikube:全自动生成、自动续期,用户无感知;
  2. kubeadm:自动化签发、一键证书轮换更新;
  3. 二进制:openssl手写脚本签发、手动续期,工作量最大。
集群升级
  1. minikube:直接重建集群为主,几乎不做原地升级;
  2. kubeadm:官方标准化分步升级kubeadm upgrade,流程稳定可靠;
  3. 二进制:手动替换二进制、修改配置、滚动重启,风险高。
网络与存储
  1. 三者都需要额外部署CNI网络插件;
  2. minikube内置简易存储;kubeadm、二进制完全自主对接CSI存储。
学习路线推荐
  1. 零基础入门:minikube,先熟悉kubectl、资源对象;
  2. 进阶运维实战:kubeadm,搭建标准集群,掌握企业日常运维;
  3. 深挖底层原理:二进制手动部署吃透架构本质。

总结选型建议

  1. 个人学习练手、本地开发测试,选minikube
  2. 企业正式生产、私有化稳定集群,选kubeadm(行业最优解);
  3. 钻研底层原理、深度定制改造、技术深耕,二进制手动部署。

标准K8s集群架构 vs Minikube一体化架构

架构基础形态

标准生产K8s架构(Master与Node物理/逻辑分离)

整体分层

  • 控制平面(Master节点):承担集群调度、管控、数据存储,不运行业务容器;
  • 工作节点(Node):kubelet接收调度指令,真正拉起Pod、执行业务负载。
  • 典型高可用部署:3台独立Master + N台业务Nodeetcd独立集群部署。

Master核心组件(控制平面)

  1. kube-apiserver:集群唯一入口,鉴权、数据CURD、所有组件交互中枢;
  2. etcd:分布式键值数据库,持久化集群全量元数据;
  3. kube-controller-manager:各类控制器闭环调谐(节点控制器、Deployment控制器等);
  4. kube-scheduler:为新建Pod筛选最优Node节点完成调度绑定;

配套辅助:CoreDNS、认证授权体系、审计日志、准入控制器。

Node工作节点组件

  1. kubelet:和apiserver通信,管理本机Pod生命周期、容器运行时;
  2. kube-proxy:维护节点Service网络代理规则;
  3. 容器运行时(containerd)、CNI网络插件、本地存储;

业务Pod全部运行在Node节点。

客户端入口

  • 宿主机/本地电脑的 kubectl,依靠kubeconfig证书配置远程对接集群apiserver
Minikube一体化单实例架构

本质:把整套控制平面 + 单个工作节点打包在一台虚拟机/容器内部,架构上不存在物理分离的MasterNode

  1. 虚拟机/容器内部同时运行:apiserveretcdcontroller-managerscheduler(控制平面全套组件)+ kubeletkube-proxy(工作节点组件);
  2. 内部kubelet直接对接本机的apiserver,调度出来的Pod也运行在当前这一套环境里;
  3. 外部本机的kubectl做客户端,通过端口转发映射连接minikube内部apiserver
  4. 资源高度收拢:一套进程包揽管控+执行业务,无节点间网络通信开销。

节点架构拓扑

标准K8s

  1. 物理/逻辑解耦:MasterNode是独立主机,网络互通;
  2. 职责严格隔离:Master只做管控调度,禁止运行业务Pod
  3. 支持横向扩展:新增Node节点执行kubeadm join即可扩容算力;Master可多实例部署实现高可用;
  4. 多节点分布式架构,具备完整集群拓扑。

Minikube

  1. 单体融合架构:控制平面与工作节点同进程环境,不分独立节点;
  2. 所有组件运行在同一个隔离环境(Docker容器/KVM虚拟机);
  3. 永远只有逻辑上单节点集群,无法新增独立Node节点;
  4. 不存在分布式集群拓扑,本质是K8s环境模拟器。

组件运行模式与通信链路

标准K8s

  1. 组件跨节点通信:kubeletNode)远程请求apiserverMaster),组件之间依靠TLS证书双向认证;
  2. etcd独立部署,apiserver通过网络访问etcd
  3. 调度流程:schedulerMaster选定节点 → apiserver写入etcd → 对应节点kubelet拉取任务创建Pod
  4. 节点间通信:PodNode互通依赖CNI分布式网络。

Minikube

  1. 全部组件本地回环通信,组件之间走内网127.0.0.1通信,简化证书与网络配置;
  2. 内置单实例嵌入式etcd,无分布式数据同步;
  3. scheduler分配节点只能选自身这唯一节点,调度逻辑被极大简化;
  4. CNI是轻量化适配版本,仅保证单机内部Pod互通,没有跨节点网络场景。

资源占用与资源调度

标准K8s

  1. Master需要独立CPU、内存资源保障集群稳定性,高可用场景3Master需要独占服务器资源;
  2. Node节点按需分配算力,业务负载不会抢占控制平面资源;
  3. 具备完整的资源配额、驱逐策略,当节点资源不足时kubelet驱逐低优先级Pod,保护集群基础组件。

Minikube

  1. 整体资源按需分配(默认22G),一套资源既要跑apiserveretcd等管控组件,又要运行业务Pod
  2. 管控组件和业务Pod争抢CPU、内存,资源紧张时很容易出现apiserver卡顿、集群卡死;
  3. 没有严格的资源隔离优先级,专为轻量化本地测试设计。

高可用与容错能力

标准K8s

  1. Master多副本:apiserver负载均衡、多套controller-manager/scheduler选主机制;
  2. etcd三副本数据冗余,单Master、单etcd节点宕机集群依旧可用;
  3. Node节点故障后,控制器自动将故障节点上的Pod重新调度到健康节点;
  4. 具备生产级容灾自愈能力。

Minikube

  1. 无任何高可用设计,内部任意核心组件异常,整套集群直接失效;
  2. 不存在节点故障转移,一旦minikube实例崩溃,所有数据、Pod全部销毁;
  3. 仅本地临时运行,不具备容灾、自愈。

证书、安全体系

标准K8s,完整企业级安全体系,

  1. 独立CA签发全套组件证书,各组件之间双向TLS加密认证;
  2. RBAC精细化权限划分,区分管理员、普通用户、服务账号权限;
  3. 网络策略、准入控制、审计日志、秘钥加密等完整安全能力。

Minikube,自动一键生成整套证书,封装简化安全逻辑,

  1. 证书对用户透明,无需手动配置;
  2. RBAC默认宽松配置,弱化权限管控;
  3. 安全策略仅满足基础测试,不具备线上安全加固价值。

网络架构

标准K8s

  1. CNICalicoFlannel)实现跨节点Pod互通、网络策略隔离;
  2. ServiceIngress面向多节点集群设计,支持集群内负载均衡、外部流量接入;
  3. 支持NodePortLoadBalancerIngress多层流量转发。

Minikube内置极简网络方案,

  1. 仅单机内部Pod互通,无跨节点网络场景;
  2. minikube service本地端口映射来访问集群内服务,替代正式环境IngressLoadBalancer
  3. 网络模型阉割,无法验证复杂多节点网络场景。

运维生命周期(部署、升级、维护)

标准K8s

  1. 支持滚动升级MasterNode组件,官方标准化升级流程;
  2. 证书轮换、etcd备份恢复、集群监控告警、日志收集整套运维体系;
  3. 支持长期稳定运行,可做持续迭代运维。

Minikube

  1. 几乎不支持原地精细化升级,最优方案直接minikube delete重建集群;
  2. 无常态化备份、监控运维设计,用完即删,生命周期以临时测试为主。

kubectl工作方式

标准K8s集群

  • 本地kubectl通过公网/内网网络远程访问Masterapiserver,依靠kubeconfig里的证书、地址完成鉴权访问,客户端和集群可以跨机器部署。

Minikube

  • 本地kubectl通过宿主机与minikube虚拟机的端口转发连接内部apiserver
  • kubeconfigminikube自动注入本机,客户端和集群强绑定在同一台宿主机。

核心优劣势总结

标准分离式K8s架构

优势

  1. 职责解耦,集群稳定性高,支持高可用、横向扩容;
  2. 架构是K8s原生标准形态,和线上生产环境完全一致;
  3. 完整的调度、网络、安全、自愈能力,承载正式业务;

劣势

  • 资源开销大,部署复杂,前期环境准备、运维成本高,个人学习搭建门槛高。
Minikube一体化架构

优势

  1. 部署极简,一键启停,资源占用极低;
  2. 环境隔离,不会污染宿主机系统,一键销毁清理;
  3. 对新手友好,快速上手kubectl、基础资源编排;

劣势

  • 架构是阉割版K8s,缺失分布式集群核心特性,无法体验多节点调度、故障转移、高可用、跨节点网络等核心能力,不能作为正式环境。

kubectl apply -f hello.yaml 完整执行逻辑

基础定义

kubectl apply是声明式资源创建/更新命令,核心逻辑:对比集群当前状态 + yaml文件期望状态,按需增量变更资源,不会暴力删除重建无关资源。

-f hello.yaml:读取本地hello.yaml文件内编写的K8s资源清单(上面示例里包含Deployment + Service)。

整体执行全流程

步骤1:本地解析校验

  1. kubectl读取本地hello.yaml文件;
  2. 校验YAML语法格式、缩进、API版本、字段合法性;语法错误、字段写错会直接就地报错,不会下发到集群。

步骤2:将资源请求发送至kube-apiserver

  1. kubectl携带认证凭证连接集群apiserver,把解析后的资源JSON请求提交。
  2. apiserver依次做,
    • 身份权限鉴权:校验当前账号有没有创建DeploymentService的权限;
    • 合法性准入校验(准入控制器);
    • 数据格式化校验。

步骤3:写入etcd持久化存储

  • apiserver校验无误后,把这份资源的期望状态持久存入集群数据库etcd,集群正式记录:我需要保持这套资源一直处于yaml定义的样子。

步骤4:集群控制器异步调谐(Reconcile reconcile 循环)

  1. Deployment控制器,监测到etcd新增hello-nginx Deployment,根据副本数、Pod模板配置,
    • 创建对应的ReplicaSet
    • ReplicaSet保证指定数量的Pod实例;
    • kube-scheduler调度器把Pod调度到集群某个节点;
    • 对应节点上的kubelet监听到本机需要创建Pod,调用容器运行时(containerd/docker)拉取Nginx镜像、创建网络、挂载目录、启动容器,直到Pod变为 Running
  2. Service控制器
    • 创建Service对象,分配固定ClusterIP,配置后端Endpoints,自动绑定上前面启动的Nginx Pod
    • 若是NodePort类型,会分配宿主机端口,实现集群外部可访问。

步骤5:后续持续运维调谐

控制器会持续循环对比:当前集群真实状态、yaml里定义的期望状态。

  • Pod意外崩溃退出:Deployment会自动拉起新Pod
  • 手动删掉其中一个Pod:控制器立刻新建补齐副本数量;
  • 后续修改hello.yaml重新执行kubectl apply -f hello.yaml:只会增量更新改动部分,不会全量销毁重建。

结合上面那份hello.yaml具体做的事情

yaml内包含两类资源:Deployment + Service

  1. 创建名称为hello-nginxDeployment
    • 拉起1个运行nginx镜像的Pod,标签为app:hello-nginx
  2. 创建名称为hello-nginxNodePort类型Service
    • 通过标签匹配选中上述Nginx Pod,内部端口80暴露至集群,同时开放宿主机NodePort端口供外部访问。

和kubectl create -f xxx.yaml的区别

  1. kubectl create:只能新建资源,资源已存在时直接报错;
  2. kubectl apply
    • 资源不存在 → 创建;
    • 资源已存在且配置一致 → 无动作;
    • 资源配置有改动 → 滚动更新变更;

生产环境标准推荐使用 apply

配套常用查看命令验证执行结果

1
2
3
4
5
6
# 查看部署
kubectl get deploy hello-nginx
# 查看运行中的Pod
kubectl get pods
# 查看service
kubectl get svc hello-nginx

反向清理

读取同一份yaml,删除里面定义的全部资源。

1
kubectl delete -f hello.yaml

Envoy网关核心设计思想

Envoy定位是云原生高性能数据平面代理,核心目标是为现代分布式微服务、服务网格(Service Mesh)提供通用、可观测、可编程、零侵入的流量治理底座。

核心纲领:单一职责数据平面 + 解耦控制平面;全链路可观测;面向云原生动态配置;高性能异步非阻塞架构;全方位流量安全与治理。

顶层核心设计理念

控制平面与数据平面彻底分离(最标志性设计)

  1. 数据平面(Envoy本体) 只负责实际流量转发、编解码、限流、熔断、重试、负载均衡、TLS卸载等数据面运算;本身不内置服务发现、配置管理、策略决策逻辑,不做复杂业务决策。
  2. 控制平面(独立组件:Istio PilotConsulNacos、自研xDS Server) 统一管理集群拓扑、路由规则、认证策略、限流阈值、证书配置,通过标准化xDS API动态下发配置给所有Envoy实例。
  3. 价值:
    • 网关/sidecar无需重启、不中断连接即可热更新全部配置;
    • 海量节点统一管控,适合大规模服务网格集群;
    • 数据面极致轻量化,专注转发性能。

配套标准:全套xDS动态配置协议

xDS 协议作用
LDS监听器配置(监听端口、绑定地址)
RDSHTTP路由规则、路径匹配、重写、重定向
CDS后端服务集群、负载均衡策略、健康检查
EDS集群后端实例地址列表(服务发现)
SDS证书、密钥动态下发,证书热加载
HDS健康检查配置

高性能底层架构:基于异步事件驱动模型

核心线程模型:单进程多工作线程(Worker

  1. 主线程(Main Thread):负责配置解析、xDS订阅、管理Worker生命周期、监控、日志聚合,不处理业务流量;
  2. NWorker工作线程:每个线程独立运行一套完整的事件循环(libevent/libuv风格),独立监听端口、处理连接、编解码、转发;
  3. 连接绑定机制:一条TCP连接自始至终固定交由同一个Worker处理,无线程间频繁争抢锁,极大降低锁竞争开销;
  4. 无阻塞IO:全链路异步读写,没有同步阻塞等待,高并发下CPU利用率平滑。

分层网络抽象架构(模块化过滤器链):Envoy采用分层过滤器架构,流量按层级依次经过插件化过滤器,这是它扩展性极强的根基。

  1. Network Filter(网络层过滤器,L4) 作用于TCP原始连接:TCP限流、代理协议解析、TLS握手卸载、IP黑白名单、连接劫持、TCP路由;
  2. HTTP Filter(应用层过滤器,L7HTTP完整生命周期拦截:鉴权、限流、日志、链路追踪、请求改写、熔断重试、WAF、灰度发布;
  3. Listener Filter:连接建立初期预处理,连接创建阶段做拦截;
  4. Access Log FilterRate Limit Filter等独立功能插件。

设计优势:

  • 功能插拔式组装,不需要的过滤器直接关闭,减少性能损耗;
  • 支持C++原生开发高性能过滤器,也支持WASM轻量级扩展(WebAssembly),业务逻辑热插拔、无需重新编译Envoy

极致可观测性(Envoy第一优先级设计目标之一)
设计初衷:分布式系统排查问题最大痛点是流量黑盒,Envoy把观测嵌入流量全生命周期。

  1. 四大基础观测能力原生内置
    • 访问日志AccessLog:全量请求耗时、状态码、上下游节点、请求体元数据、错误原因;
    • Metrics指标:QPS、延迟分位数(p50/p90/p99)、连接数、熔断触发次数、重试次数、TLS握手失败数;对接PrometheusStatsd
    • 分布式追踪Tracing:原生对接JaegerZipkinSkyWalking,自动解析trace-id,自动埋点上下游调用链路;
    • 热重载、实时调试:admin管理端口,在线查看当前配置、连接池状态、后端健康实例、动态调试流量。
  2. 设计思想:所有流量行为可量化、可溯源、可告警,运维无需改造业务代码即可拿到完整调用观测数据。

面向分布式场景的流量治理原生内置,专为微服务跨节点调用问题设计,所有能力下沉到代理层,业务代码零改造(Sidecar模式核心价值)。

  1. 负载均衡(LB)多策略内置 轮询、最小请求数、加权轮询、一致性哈希、子集负载均衡、区域就近调度(同城优先调用本地节点);
  2. 故障容错体系
    • 自动健康检查:主动+被动健康检查,摘除故障节点;
    • 熔断Circuit Breaker:后端服务雪崩时自动熔断异常实例,防止级联故障;
    • 自动重试、超时控制、请求重试防风暴(重试预算);
    • 延迟注入、故障注入(测试系统容错性);
  3. 高级流量调度 基于header、权重、灰度蓝绿发布、流量镜像、流量劫持、地域分流;
  4. 连接池精细化管理 对每个后端集群维护独立连接池,复用TCP长连接,减少握手开销;限制单实例最大并发连接,防后端打满。

安全设计内嵌于流程,而非外挂

  1. TLS全链路统一卸载与加密 入口网关做下游TLS解密,上游调用自动TLS加密;SDS动态下发证书,证书自动轮换,避免硬编码证书;支持mTLS双向认证(服务网格节点之间身份认证);
  2. 网络安全防护 L4 IP封禁、连接速率限制、HTTP协议校验(拦截畸形恶意请求)、请求大小限制、防止慢速攻击;
  3. 授权鉴权架构 内置全局鉴权过滤器(ExtAuthz),将鉴权请求异步转发外部鉴权服务,统一收口鉴权逻辑,不用每个业务服务重复开发鉴权。

两种部署形态一体支撑:边缘网关 + Sidecar
Envoy架构天然适配两种典型部署模式,底层同一套代码无差异化。设计上没有架构割裂,仅仅是监听器、路由、集群配置不同。

  1. 边缘网关模式(独立部署) 集群入口网关,承接外部公网流量,做路由、限流、SSL卸载、安全防护;对应APISIXKongNginx网关场景;
  2. Sidecar 边车模式(服务网格主流) 每个业务容器同节点部署一个Envoy,接管该服务所有进出流量,实现服务间无侵入治理、mTLS、链路追踪、就近调度;

扩展体系:WASM可编程生态
早期只能C++开发内置过滤器,现在主推WASM扩展。核心思想:通用底座标准化,业务差异化逻辑通过安全沙箱化扩展实现,兼顾性能与灵活性。

  1. 无需编译Envoy本体,WASM字节码动态加载;
  2. Go/Rust/C++/AssemblyScript编写业务逻辑;
  3. 配置热更新加载WASM插件,不停机上线自定义逻辑;

对比Nginx理解Envoy设计取舍,Nginx多进程worker模型侧重隔离,Envoy单进程多worker侧重低锁竞争与精细化集群管控。

  1. Nginx:主打高性能静态转发,配置静态为主,适合边缘简单流量;
  2. Envoy:天生为分布式集群动态治理而生,强可观测、动态配置、服务网格适配,架构更偏向分布式软件设计;

总结Envoy整体设计

  1. 数据面专心转发,控制面专心决策,xDS标准化解耦;
  2. 异步无锁线程模型保证高吞吐低延迟,模块化过滤器实现功能按需组装;
  3. 观测左移,流量全链路埋点,分布式问题看得见、查得清;
  4. 把微服务最通用的流量容错、安全、调度能力下沉到代理层,业务只专注业务逻辑。

Envoy与Istio

二者关系

Envoy是高性能L4/L7网络代理(数据平面底座);Istio是完整服务网格平台,把Envoy作为唯一默认数据平面Sidecar代理,Istio控制平面通过xDS协议统一管控全网所有Envoy

经典分层架构:

  • 数据平面(干活转发流量):无数个Envoy Sidecar
  • 控制平面(下发规则、全局治理):IstiodIstio一体化控制面)

基础定义

Envoy

  • Lyft开源、CNCF毕业、C++开发的独立高性能四层/七层可编程网络代理。
  • 核心能力:流量转发、负载均衡、熔断重试、健康检查、TLS加解密、链路埋点、动态配置(xDS API)、可插拔过滤器。
  • 定位:单纯的流量执行器,本身没有全局调度、策略管理、证书自动化、可视化治理能力,必须外部控制面下发规则才能规模化组网。

Istio

  • 谷歌+IBM主导的企业级完整服务网格解决方案,一整套分布式微服务治理体系,覆盖流量治理、安全、可观测、策略管控、多集群管理全生命周期能力。
  • Istio自身不处理实际数据包转发,所有流量规则最终都由Envoy落地执行。

从属架构关系

  1. Sidecar模式:Istio自动注入Envoy和业务容器同Pod部署,劫持服务全部入站/出站流量,业务零代码改造实现网络治理;
  2. 通信协议:xDSIstiod通过标准xDS系列APICDS/RDS/LDS/EDS/ADS)动态向Envoy推送集群、路由、监听、后端节点配置,无需重启Envoy即可热更新规则;
  3. 能力分工
    • Istio:定义治理规则(VirtualService路由、灰度发布、限流策略、mTLS证书签发、访问权限)、对接K8s服务发现、聚合监控链路日志;
    • Envoy:忠实执行路由转发、限流拦截、加密解密、采集指标上报给Istio汇总;
  4. 生态绑定
    • Istio深度定制增强版Envoy,新增Istio专属过滤器、协议适配;Envoy也可脱离Istio独立部署,Istio几乎无法脱离Envoy做标准Sidecar网格。

关键维度对比

对比维度EnvoyIstio
产品定位单机分布式代理、流量执行组件完整服务网格管控平台(控制面+配套生态)
运行角色数据平面,真正收发、转发数据包控制平面,只做配置分发、策略决策,不碰业务流量
独立部署可单独部署:Ingress网关、单机负载均衡、独立Sidecar无法脱离数据面代理单独实现网格流量治理,必须绑定Envoy等代理
配置方式原生yaml静态配置,或第三方控制面通过xDS下发用户编写CRD资源(VirtualService/DestinationRule),Istio自动转译为Envoy识别的xDS配置
安全能力仅基础TLS终止、单向加密;无证书自动签发轮换、全局身份认证自动签发mTLS证书、服务身份认证、细粒度授权策略、全局加密组网
流量治理基础负载均衡、熔断、重试、简单路由;无灰度、蓝绿、故障注入、流量镜像等高阶能力一站式灰度发布、流量镜像、超时精细化管控、故障注入、流量切分、全链路灰度
服务发现需要外部数据源(文件/etcd/k8s)接入,自身无服务注册中心集成原生对接K8sConsul等注册中心,自动同步服务实例列表下发给Envoy
可观测性采集单节点日志、指标、链路数据,无聚合分析统一采集全网Envoy数据,对接Prometheus/Jaeger/Grafana做全局监控、链路追踪、大盘可视化
策略管控自身无配额限流、黑白名单等全局策略能力全局速率限制、访问ACL、灰度权重策略、业务级准入控制
多集群单实例视角,无跨集群调度能力原生支持多集群网格统一管控、跨集群服务通信
上手成本需自行搭建服务发现、配置推送体系,运维复杂开箱即用CRD声明式配置,屏蔽xDS底层细节,运维门槛更低
编程语言C++,高性能低延迟Go编写控制面,面向运维侧管理逻辑

两种典型使用场景区分

场景1:只用Envoy(不用Istio

  1. 作为K8s Ingress网关、内部独立负载均衡;
  2. 简单固定Sidecar,手动写静态配置做基础熔断重试;
  3. 搭配自研轻量化控制面、Consul Connect小规模组网。

场景2Istio+Envoy标准组合(主流)

  • 大规模K8s微服务集群:灰度发布、全链路mTLS加密、精细化流量治理、统一监控告警、全局安全策略、多集群统一治理。

简单数据流示例

  1. 运维编写Istio CRDVirtualService配置90%流量打正式环境,10%流量灰度版本;
  2. Istiod解析CRD,转换成Envoy可识别的RDS路由配置;
  3. 通过xDS长连接推送到对应Pod内的Envoy
  4. 业务服务发起请求,Envoy拦截流量,按照下发的权重规则转发至对应后端实例;
  5. Envoy采集本次请求耗时、状态码上报Istio,汇总至监控系统展示灰度流量占比。

总结

  1. Envoy是手脚,Istio是大脑;Envoy负责干活转发流量,Istio负责全局指挥调度;
  2. Envoy是通用基础设施代理,Istio是基于Envoy构建的一站式服务网格解决方案;
  3. 二者通过标准化xDS解耦,Envoy可以脱离IstioIstio默认强依赖Envoy作为数据平面。

Apache APISIX vs Envoy

一句话总结,

  • Envoy:通用高性能L4/L7数据平面代理(CNCF毕业),本身只是转发底座,无内置控制面,主打服务网格Sidecar
  • APISIX:开箱即用的一站式南北向API网关(ASF顶级项目),基于Nginx/OpenResty+LuaJIT构建,自带完整控制面、管理API、插件生态,主打边缘入口网关。

共性设计理念(云原生同源)

  1. 动态配置、无停机热更新 Envoy依靠xDS协议动态推送配置;APISIX依托etcd订阅监听,毫秒级同步路由、限流、鉴权规则,全程不重启进程、不中断连接,摒弃Nginx传统reload
  2. 分层流量拦截、插件化扩展 EnvoyNetwork Filter + HTTP Filter链式处理; APISIX:请求全生命周期Lua插件钩子(rewrite/access/header_filter/log等);二者都是在流量链路中按需插入自定义逻辑。
  3. 统一云原生观测体系 原生支持MetricsAccessLog、分布式TracingJaeger/Zipkin/SkyWalking)、健康检查、熔断、重试、负载均衡、TLS/mTLS、限流、流量灰度等微服务标配能力。
  4. WASM统一扩展生态 两者都支持WebAssembly沙箱插件,不用编译内核即可热加载自定义逻辑,实现跨语言安全扩展。
  5. 经典组合部署架构(最主流协作方式)
    1
    2
    3
    
     公网流量 → APISIX(边缘入口网关:鉴权、限流、SSL卸载、API路由、WAF)
                 ↓ 内网服务调用
             → 业务服务 + Envoy Sidecar(服务网格内部东西向治理:mTLS、就近调度、故障熔断、链路追踪)
    

    APISIX承接南北向入口,Envoy负责集群内部服务间流量治理,各司其职、优势互补。

  6. 少量互通能力 APISIX可对接xDS服务发现、对接Istio体系;Envoy之上封装控制面(GlooContourHigress)也能做成API网关形态。

无底层血缘关系

  • EnvoyC++自研内核;
  • APISIX基于Nginx事件驱动内核+OpenResty LuaJIT运行时;
  • 代码、线程模型、网络引擎完全独立,不存在谁基于谁编译。

核心维度对比

底层技术栈与线程模型

Envoy

  • 语言:纯C++独立开发;
  • 线程模型:单进程多Worker线程,每个Worker独立事件循环,TCP连接永久绑定单个Worker,锁竞争极少;
  • IO:自研异步事件驱动,细粒度内存调度,长连接海量并发表现极强。

APISIX

  • 底座:Nginx epoll事件驱动 + OpenResty LuaJIT
  • 线程模型:Nginx经典多Worker进程模型,Lua逻辑运行在Worker内部;
  • 优势:Nginx久经验证的网络层稳定性,LuaJIT极高执行效率,短连接API场景内存占用更低。
控制面架构(最本质分水岭)

Envoy

  1. 天生数据面、控制面彻底分离;
  2. 配置方式:
    • 静态bootstrap基础配置;
    • 动态全量配置依赖外部独立xDS控制面(Istio PilotConsul、自研xDS ServerGlooContour);
  3. 没有内置Admin管理API、控制台、租户、消费者体系,裸Envoy无法直接上线做网关。

APISIX

  1. 数据面+轻量化内置控制面一体化交付;
  2. 架构:Admin API(控制台/SDK调用)→ 写入etcd全局配置中心 → 所有APISIX节点watch etcd自动同步配置;
  3. 开箱即用:路由、上游、限流、鉴权、消费者、证书、监控全链路管控,部署后立刻可用,无需额外搭建控制面。
典型部署形态

Envoy

  1. 主流:Service Mesh Sidecar(每个业务容器配套一个Envoy,接管东西向流量);
  2. 次要:搭配商用控制面做Ingress网关(GlooHigress);
  3. 极少裸机独立部署。

APISIX

  1. 主流:边缘Ingress网关、API统一入口、中台网关、API治理平台(南北向流量);
  2. 次要:轻量级Sidecar(不推荐,资源与架构不如原生Envoy适配)。
扩展体系与开发门槛

Envoy

  1. 原生扩展:C++编写Filter,性能最强,门槛极高;
  2. 轻量化:WASM插件(Rust/Go/AssemblyScript);
  3. 优势:底层可编程性极强,可深度改造协议解析、连接调度;
  4. 劣势:普通运维/后端工程师难以快速开发业务插件。

APISIX

  1. 主力:Lua原生插件,上手简单、开发调试便捷,官方内置100+成熟开箱插件(JWTOAuth2、限流、WAF、灰度、监控、协议转换、AI网关等);
  2. 多语言:Go/Java/Python通过独立进程RPC插件执行、WASM
  3. 优势:业务级定制成本极低,开启插件即生效,运维友好;
  4. 劣势:无法像Envoy一样深度修改TCP层、协议内核逻辑。
负载均衡、故障治理细节差异

Envoy强项

  • 精细化区域就近调度、子集负载均衡、精准异常实例驱逐、细粒度熔断阈值、重试预算防雪崩、高级连接池管控;
  • 专为大规模集群内部东西向调用优化,mTLS全链路加密、证书SDS动态轮换业界标杆。

APISIX强项

  • 面向API网关场景的权重路由、按Header/Cookie灰度分流、多环境蓝绿发布、接口级限流、IP黑白名单、API签名鉴权、协议转换(HTTP/Dubbo/gRPC/MQTT);
  • 对接Nacos/Eureka/Consul/K8s等国内主流服务发现更便捷。
资源开销与性能特征
  1. 长连接海量并发:Envoy占优,C++内存管理高效,百万级长连接内存控制更好;
  2. 短连接高频API接口:APISIXLuaJIT+Nginx)内存占用更低,单核QPS持平甚至小幅领先,延迟更平稳;
  3. 内存:同等并发下Envoy单连接内存开销略高于APISIX
运维复杂度

Envoy高:需要维护xDS控制面、理解整套xDS协议体系、调试链路复杂,适合专职云原生团队深度运维;

APISIX低:可视化控制台、简单RESTful Admin API、配置可视化校验、告警体系完善,中小团队可快速上手运维。

选型决策标准

Envoy的场景

  1. 落地Istio/Linkerd等服务网格,业务内部东西向流量治理;
  2. 需要深度自定义网络底层逻辑、自研云原生流量平台;
  3. 全栈统一数据面,边缘+网格全部基于Envoy生态;
  4. 海量长连接、gRPC为主的内部服务通信。

APISIX的场景

  1. 公网API入口、Ingress网关、统一API治理、南北向流量收口;
  2. 快速落地限流、鉴权、WAF、灰度、API全生命周期管理,不想搭建独立控制面;
  3. 国内生态适配(NacosDubboSentinelSkyWalking);
  4. 团队无专职C++云原生底层开发,希望低成本二次开发插件。

极简对照表

对比项Apache APISIXEnvoy Proxy
定位一站式API网关(南北向)通用数据面代理(侧重东西向Sidecar
内核Nginx+LuaJIT自研C++
控制面内置(AdminAPI+etcd无内置,依赖外部xDS控制面
扩展方式Lua优先,开箱即用插件多C++ Filter/WASM,开发门槛高
最佳部署边缘IngressAPI网关Service Mesh边车
上手成本
核心优势开箱即用API治理、国内生态友好底层极致可编程、mesh原生适配、mTLS顶尖
典型搭档后端业务服务、内网注册中心IstioPilot、服务网格体系

总结

  1. 二者不是替代关系,主流架构是互补搭档:APISIX守门,Envoy管内网;
  2. Envoy是高性能轮子,需要自己组装车架(控制面)才能变成整车网关;
  3. APISIX是整装成品车,开箱即用专注API网关业务场景,不用从零搭建管控体系。

K8s Ingress Controller 本质到底是什么?

一句话总结,
Ingress只是K8s的配置资源(yaml规则,存etcd,本身不干活);Ingress Controller才是真正的七层反向代理网关程序,把Ingress规则翻译成真实代理配置,驱动代理对外接收流量。

Desktop View k8s ingress controller

Ingress(资源对象,只是规则),就是一段yaml,定义

  • 访问 shturl.cc/HDu → 转发给 service‑a
  • 访问 shturl.cc → 转发给 service‑b

它仅仅存在k8s etcd数据库,本身不会处理任何网络流量,没有监听端口。

Ingress Controller(控制器 + 真实网关,干活的实体),本质 = 控制器业务逻辑 + 高性能反向代理

  • 控制器部分:watch API Server,监听IngressServiceSecret资源变化;
  • Ingress的域名、path、证书、权重、限流规则,动态生成代理配置;
  • 热更新底层代理(Nginx / Envoy / APISIX),真正监听80/443端口,接收外部HTTP/HTTPS流量。

市面上常见实现,

  • ingress‑nginxNginx作为数据面
  • Higress/APISIX‑IngressAPISIX(OpenResty)做数据面
  • Istio GatewayEnvoy做数据面
  • ContourEnvoy做数据面

NodePort/LoadBalancer的区别

  • NodePort:每个Service占一批宿主机端口,适合四层;域名、路径路由能力弱。
  • LoadBalancer:云厂商四层负载均衡。
  • Ingress Controller = K8s集群内部的七层API网关,统一入口,实现域名、路径、证书、灰度、限流,只暴露少数80/443端口。

Ingress Controller原生只解决普通HTTP七层转发;原生Ingress能力不足以做AI网关,

  1. 原生没有Token粒度限流、SSE流式链路特殊处理、LLM计量计费、模型权重路由;
  2. 很多AI网关方案,是复用Ingress Controller框架,扩展自定义插件(Higress就是Envoy Ingress,新增大量AI插件:token限流、llm‑routekey鉴权);
  3. Envoy + K8s CRD/Operator + Ingress体系之上构建AI网关的技术栈为例,结合Ingress控制器、CRD、OperatorAI网关本质就是在Envoy的数据面写插件,控制面通过K8s CRD做配置下发。可以做到自定义CRD扩展出AI网关的资源;Controller监听CRD,生成Envoy配置,驱动数据面执行AI网关逻辑。

通俗类比

  • Ingress:给交警一张纸质交通指挥说明书(规则)
  • Ingress‑Controller:交警本人,拿着说明书,指挥车辆通行(真正代理流量)。没有交警,说明书废纸一张。

QIngress ControllerDeployment还是DaemonSet
大多部署为Deployment,可以多副本高可用;对外通过LoadBalancer类型Service暴露80/443
部分实现也可以DaemonSet每个节点部署实例。

Q:Ingress不能做TCP四层代理吗?
标准Ingress资源只定义HTTP/HTTPS七层;TCP/UDP需要各个controller自己扩展CRD

Q:Ingress ControllerService Mesh(Istio) Gateway区别

  1. Ingress‑Controller:集群入口网关,南北向流量(外部 →集群内部)
  2. ServiceMesh(Istio sidecar):东西向(pod‑pod之间内部调用);Istio Gateway CR也可以做南北向,底层依然是Envoy

K8s CRD 与 Operator

原生K8s自带资源:PodDeploymentServiceIngressSecretCRD就是允许你自己新增资源,例如ApisixRouteEtcdClusterRedisCluster

  • CRD(CustomResourceDefinition):自定义资源定义,给K8s新增一种API类型,让你可以写自己的YAML资源;只负责定义数据模型,不干活。
  • Operator = CRD + 自定义控制器(Controller);监听CRD自定义资源,根据yaml声明,自动完成复杂业务逻辑,把人工运维操作代码化。

Desktop View K8s CRD 与 Operator

CRD(CustomResourceDefinition)

作用:向K8s API Server注册新的资源类型,扩展K8sAPI

  • 安装CRD之后,kubectl api-resources就能看到你新增的资源;
  • 你就可以kubectl apply -f xxx.yaml创建该自定义对象,数据存储在K8setcd,和PodDeployment一样。

举个例子,ApisixRoute就是一个CRD

1
2
3
4
5
6
7
apiVersion: apisix.apache.org/v2
kind: ApisixRoute  # 这就是CRD注册出来的Kind
metadata:
  name: demo
spec:
  http:
  - match: {hosts: ["a.test.com"]}

没有CRDK8s根本不认识ApisixRoute这个Kindapply会直接报错。

CRD仅仅是数据schemaapply一个ApisixRoute,只是把配置存进etcd,不会自动创建路由,必须有控制器(Apisix Ingress Controllerwatch这个CR,做业务处理。

CRD能干什么/不能干什么

  • 扩展k8s API,自定义spec/status结构;
  • 支持校验(OpenAPI schema),写错字段kubectl直接报错;
  • 支持subresource status,控制器可以回写状态到资源的.status
  • CRD本身没有业务逻辑,不会自动创建Pod、不会做任何动作。

Operator模式

Operator = CRD + 自定义Controller,是CoreOS提出的运维模式。

思想就是,把运维专家的知识编码进控制器程序。比如部署一个高可用ETCD集群,

  • 手动流程:创建StatefulSet、配置Service、备份、故障节点重建、版本升级、扩缩容。
  • Operator做法:用户只提交一份简短的EtcdCluster CR yamlOperator控制器watch这个资源,自动完成上面全部运维动作。

Operator完整工作闭环

  1. 先安装CRD到集群,注册自定义资源(例如EtcdCluster
  2. 用户提交CR实例,描述期望状态:3副本、版本3.5、开启备份
  3. Operator程序(Deployment运行)通过APIServer watchCR资源的增/改/删事件
  4. 调谐逻辑(Reconcile):对比用户期望spec和集群当前实际状态,如果实际不符合期望,调用K8s API创建/更新/删除StatefulSet/Pod/Service/ConfigMap
  5. 把运行情况回写到CR.status字段;kubectl get etcdcluster xxx -o yaml 可以看到集群状态。

调谐ReconcileOperator的灵魂:无限循环,持续逼近用户声明的期望状态,和Deployment控制器原理一模一样。

原生Deployment控制器本质就是内置Operator

  • Deployment是内置资源(相当于内置CRD
  • K8s控制器管理器内部的Deployment Controller就是Operator控制器,不断调谐,维护ReplicaSetPod

Operator两种开发方式

  1. Operator SDK / KubebuilderGo,主流生产)
    • 生成脚手架,写Reconcile调谐逻辑,最终产出Operator镜像。
  2. Ansible Operator / Helm Operator:封装helm chartansible playbook,快速做简单Operator,复杂场景性能差。

拿APISIX Ingress Controller举例,理解CRD & Operator

  1. 部署Apisix Ingress的时候,首先安装一批CRDApisixRouteApisixUpstreamApisixTls
  2. 用户写ApisixRoute CR提交到K8s
  3. Apisix Ingress Controller(自定义控制器)watch这些CR资源;
  4. Reconcile逻辑:把ApisixRoute翻译成APISIX网关配置,调用AdminAPI下发;
  5. 将同步情况回写到ApisixRoute.status

Apisix Ingress Controller本质就是一个Operator风格的控制器,只不过它最终不是创建Pod,而是调用外部组件Admin API

对比真正的数据库Operatoretcd‑operatorredis‑operator),它们的Reconcile逻辑是去创建StatefulSet/PodApisix Ingress reconcile输出是调用第三方网关的API

CRD/OperatorIngress Controller的关系

  1. IngressK8s内置CRDK8s集群默认自带;
  2. Nginx Ingress Controller / Apisix Ingress Controller就是监听Ingress(内置CRD)的控制器;
  3. 能力不够用时,项目再新增自己的自定义CRDApisixRoute),实现原生Ingress做不到的能力。

QCRDOperator区别?

  • CRD:元数据定义,扩展API,只有数据没有逻辑。
  • OperatorCRD + 控制器程序,包含业务调谐逻辑,驱动真实资源变化。
  • CRD是表单模板,Operator是干活的工人。

Q:删除CR资源会发生什么?
Operator会收到delete事件,在Reconcile做清理逻辑;如果没有实现清理逻辑,底层Pod/Service就会残留(僵尸资源)。

Q:status字段的作用?

  • .spec:用户填写,期望状态
  • .status:控制器回写,实际当前状态,对外暴露就绪、副本数、错误信息。用户不应该手动修改status

Q:OperatorHelm区别?

  • Helm:模板渲染,一次性apply一堆yaml;后续不会持续巡检状态。改CR后不会自动更新已有资源。
  • Operator:持续Reconcile循环,实时调谐状态,支持升级、故障自愈、扩缩容,适合有状态服务(数据库、缓存集群)。

Q:CRD资源存在哪里?
全部存在K8setcd,不是外部存储。

典型现实例子

  1. etcd‑operatorCRD EtcdCluster,自动部署etcd集群、故障恢复
  2. prometheus‑operatorCRD Prometheus/ServiceMonitor,管理Prometheus实例
  3. apisix‑ingressCRD ApisixRoute,扩展网关路由能力
  4. istio:大量CRD(VirtualService/DestinationRule),istiod作为Operator控制器

APISIX Ingress Controller vs Apache APISIX

APISIX Ingress Controller不是APISIX网关本身,它只是K8sAPISIX之间的翻译桥梁。

  • Apache APISIX:数据面(网关本身),真正接收流量、代理、执行插件;监听9080/9443,处理HTTP请求。
  • APISIX Ingress Controller:控制面适配器,本身不处理业务流量;专门watch K8s API,把K8s Ingress/CRD翻译成APISIX的配置,调用APISIX Admin API推送配置。

Desktop View APISIX ingress controller

项目APISIX Ingress ControllerApache APISIX
角色K8s控制面适配器(翻译层)七层网关数据面,真正处理流量
是否接收业务流量不处理用户HTTP流量接收80/443业务流量
存储K8s etcd;自身不存网关配置网关配置存储在APISIX自己的etcd(独立于K8s etcd
核心工作Watch IngressApisixRouteApisixUpstreamSecret;转换成APISIXRoute/Upstream/Plugin;调用Admin API推送给APISIX执行路由匹配、负载均衡、鉴权、限流、日志、各类插件;转发请求到后端Pod
部署形态Deployment,一般单/双副本Deployment/DaemonSet,多副本做网关高可用
对外暴露不需要暴露业务端口;只需要能访问APISIX Admin API通过LoadBalancer/NodePort对外暴露80/443

注意:K8setcdAPISIX使用的etcd是两套完全独立的etcd集群,

  • K8s‑etcd:存IngressPodService
  • APISIX‑etcd:存网关路由、上游、插件规则
  • APISIX Ingress Controller充当搬运工,把K8s资源同步到APISIXetcd

完整协作流程

  1. 用户编写资源

    两种输入来源,

    • 标准K8s Ingress资源;
    • APISIX自定义CRDApisixRoute/ApisixUpstream/ ApisixTls(能力比原生Ingress强,支持限流、改写、插件),提交到K8s
  2. apisix‑ingress‑controller watch k8s apiserver

    持续监听IngressCRDSecretService的新增/修改/删除事件。

  3. 资源转换(翻译)

    K8s语义翻译成APISIX模型,

    • Ingress.host/pathAPISIX Route
    • k8s Service + endpointsAPISIX Upstream(后端节点列表)
    • Secret证书 → APISIX SSL
    • ApisixRoute里的插件配置 → APISIX Route上绑定plugin
  4. 推送配置给APISIX

    Controller通过APISIX Admin API,把生成的RouteUpstreamSSL配置提交给Apache APISIX

    APISIX收到请求后,把配置写入自己的etcd;所有APISIX网关副本自动热加载生效,无需重启网关。

  5. 流量走APISIX数据面

    外部请求到达APISIX网关,APISIX读取自身etcd的路由配置,匹配路由,负载均衡转发到对应Pod

注意,APISIX Ingress Controller不会直接写APISIXetcd;它调用Admin API,由APISIX服务端写入APISIX etcd

两种部署模式

模式1:分离部署(最常用生产模式)

  • Apisix Ingress Controller独立Deployment
  • Apache APISIX网关是另一套Deployment
  • controller通过service访问APISIX Admin API
  • APISIX使用自己独立etcd实例。

模式2All‑in‑oneHelm一键demo

  • Helm安装Apisix Ingress的时候,可以一套pod里面跑:Apisix + Ingress Controller,只是容器在同一个Pod,逻辑职责依然严格分开。

Nginx Ingress的本质区别

  • Nginx Ingress ControllercontrollerNginx代理进程在同一个Pod内部,controller直接写本地nginx.conf,本地Nginx处理流量,共享同一个Pod
  • Apisix Ingress ControllercontrollerAPISIX网关可以完全拆分成不同Deployment,通过网络调用AdminAPI下发配置;APISIX集群可以多组网关实例共用一套controller

Q:修改ApisixRoute之后,流程是什么?

  1. apply ApisixRoutek8s etcd更新;
  2. Ingress Controller watch到变更;
  3. 转为APISIX Route对象;
  4. POST Admin APIAPISIX
  5. APISIX写入自身etcd;全部APISIX实例热更新;
  6. 业务流量立刻生效。

Q:如果Apisix Ingress Controller挂掉,网关还能不能正常工作?
网关流量不受影响。已经推送到APISIX etcd的配置会一直保留;只是K8s新的Ingress/CRD变更不会同步到网关。网关继续按旧配置处理流量。
对比Nginx Ingress Controller挂掉,Nginx还能跑旧配置,只是无法更新规则。

Q:能不能绕过Ingress Controller,直接调用APISIX Admin API配置网关?
可以。Apisix Ingress Controller只是同步工具;你可以直接调用Admin API写路由,但配置不会和K8s资源对齐,K8s层面删除Service,网关路由不会自动清理,会产生僵尸路由,不推荐混合使用。

Q:ApisixRoute CRD和原生Ingress怎么选?
原生Ingress能力有限,复杂场景(限流、重写、认证、AI插件)优先使用ApisixRoute CRD

有兴趣的话,可以对比下APISIX Ingress vs HigressHigress本质是把ControllerEnvoy数据面做深度耦合,和APISIX架构思路不一样。

参考

K8s官网

K8s官网 - 中文文档

K8中文社区

K8中文社区 - 中文文档

Kubernetes API 规约

Kubernetes kubectl 命令表

云原生计算基金会 - CNCF

K8s官网 - 你好,Minikube

使用Minikube集群

minikube github

minikube社区文档

本文由作者按照 CC BY 4.0 进行授权

© ManShouyuan. 保留部分权利。

本站总访问量 本站访客数人次

🚩🚩🚩🚩🚩🚩