前言
现在提起"云计算""云原生",很多人可能觉得是高大上的技术名词,离自己很远。但其实,我们每天用的购物APP、刷的短视频、查的天气软件,背后都可能藏着这些技术的身影。
简单说,云原生就是让应用在"云"里跑得更顺畅、更灵活的一套技术体系,而Kubernetes(简称K8S)就是这套体系里的"核心工具"------它像个"智能管家",帮我们管好一堆运行应用的"小容器",解决了传统部署中"环境不一致""扩容麻烦""故障难恢复"等一堆头疼问题。
这篇文章就从基础开始,用大白话带你搞懂云原生和K8S的核心逻辑,不管你是刚接触的开发者,还是想了解技术趋势的运维同学,都能轻松get重点。
一、云原生基础概述
1.1 云原生的发展历程
云原生不是突然出现的,而是一步步迭代来的,咱们用"时间线+大白话"梳理关键节点:
- 2004年:Google内部就开始大规模用"容器"装应用了,相当于提前踩坑,积累了很多实战经验;
- 2008年:Google把"Cgroups"技术捐给了Linux内核------这东西解决了"容器之间抢资源"的问题,比如A容器不会把B容器的内存占光,为后续技术打了基础;
- 2013年:Docker正式发布!以前容器技术只有大公司会用,Docker把它变得简单易用,就像"打包工具",把应用和它需要的环境一起打包,普通人也能轻松上手;
- 2014年:K8S登场!容器多了之后,手动管理太麻烦(比如启动、扩容、故障重启),K8S正好解决"容器编排"的问题,慢慢成了行业标准;
- 2015年:Google、微软这些大厂联合成立了CNCF(云原生计算基金会),就像"云原生技术联盟",推动技术标准化,让更多人参与进来;
- 2017-2018年:云原生生态爆发,除了容器编排,还延伸到服务治理、无服务器等场景,越来越多企业开始用。
1.2 云原生的定义与部署模式
云原生的核心目标很简单:让应用在"云"里能灵活扩展、稳定运行,而且不管是公有云、私有云,还是两者结合的混合云,都能适配。这三种云部署模式,用"办公室"比喻一下就懂了:
1.2.1 公有云
相当于"共享办公室"------由阿里云、AWS、微软Azure这些服务商搭建好基础设施,你不用买服务器、不用管维护,按需租用就行,比如业务忙的时候多租几台,闲的时候退掉,按使用量付费。
适用场景:中小企业创业(省钱省精力)、电商大促(突发流量需要快速扩容)、非敏感业务(比如展示型官网)。
1.2.2 私有云
相当于"自己买的办公室"------企业在自己的数据中心里搭建专属的云计算平台,完全自己掌控。安全性高、能定制,比如金融行业的交易系统、医疗行业的患者隐私数据,都需要这种模式。
适用场景:核心业务(比如银行的转账系统)、敏感数据存储、对合规要求极高的场景。
1.2.3 混合云
相当于"自己的办公室+共享办公室"------敏感数据放在私有云(比如用户支付信息),非敏感业务放在公有云(比如商品展示、营销活动),大促时用公有云扩容。既安全又灵活,是很多企业的选择。
比如某电商平台:支付数据存在私有云保安全,商品页面部署在公有云,大促时自动扩缩容应对流量高峰。
1.3 云原生技术栈
云原生不是单一技术,而是一套"组合工具",就像做饭需要锅、铲、调料,云原生也需要多个组件配合:
1.3.1 核心技术组件
- 容器化(代表:Docker、containerd):核心是"一次打包,到处跑"。以前开发环境能跑的应用,到生产环境就报错,因为环境不一样;容器把应用和它需要的依赖(比如软件版本、配置)打包成一个"镜像",不管在哪个服务器上,只要有容器引擎,就能正常运行,解决了"环境不一致"的痛点。
- 微服务架构:把传统的"大应用"拆成多个"小服务",每个服务只做一件事。比如电商APP拆成"用户服务"(管登录注册)、"订单服务"(管下单支付)、"商品服务"(管商品展示),每个服务能独立部署、升级,不会因为一个服务出问题影响整体。
- 服务网格(代表:Istio):相当于"服务之间的通信管家"。微服务多了之后,服务之间怎么通信、怎么加密、怎么监控,不用改业务代码,服务网格帮你搞定,比如实现"灰度发布"(先给部分用户用新功能)。
- 不可变基础设施:服务部署后,不直接修改容器里的内容(比如不在容器里手动装软件),要更新就重新做一个镜像,确保每个环境都一样,回滚也方便。
- 声明式API:你只需要告诉系统"我想要什么状态"(比如"我要3个Nginx应用在运行"),系统自己会想办法实现,不用手动一步步操作(比如"先启动1个,再启动2个")。
1.3.2 云原生技术栈公式
简单记:云原生 = 容器化(Docker+K8S)+ 微服务 + Serverless + DevOps + 服务网格 + 云
- 容器化:微服务的"载体",帮微服务落地部署;
- 微服务:业务拆分的"思路",让应用更灵活;
- Serverless:"不用管服务器",开发者只写业务代码,服务器的扩容、维护都交给云厂商;
- DevOps:"开发和运维一起干活",通过自动化工具实现快速迭代(比如代码提交后自动测试、自动部署);
- 服务网格:"服务通信管家",解决微服务间的复杂问题;
- 云:所有技术的"基础底座",提供服务器、存储等资源。
1.4 云原生的核心特征
1.4.1 核心特征
- 符合12因素应用:云原生应用的"设计说明书",确保应用可扩展、好维护;
- 面向微服务:拆成小服务,独立部署升级;
- 自服务敏捷架构:开发者自己能申请资源(比如一键创建应用),不用等运维帮忙;
- 基于API协作:服务之间通过标准接口通信,不管用什么语言开发,都能互相调用;
- 抗脆弱性:不是"避免故障",而是"故障后能自动恢复",比如应用崩溃了自动重启,节点坏了自动迁移。
1.4.2 12因素应用原则(通俗详解)
这12条是云原生应用的"设计准则",每条都用大白话解释:
- 基准代码:一个应用只有一个代码库(比如一个Git仓库),开发、测试、生产环境都用这个代码,避免多个代码库导致混乱;
- 依赖管理:明确告诉应用"需要什么帮手"(比如Java需要的jar包、Python需要的库),写在配置文件里(如pom.xml、requirements.txt),避免"我电脑上能跑,你电脑上不行";
- 配置管理:配置项(比如数据库地址、API密钥)不写死在代码里,放在环境变量或配置中心,换环境时不用改代码,改配置就行;
- 后端服务:把数据库、缓存这些外部服务当"附件",通过配置关联,比如从MySQL换成PostgreSQL,不用改应用代码;
- 构建、发布、运行分离:"构建"是做镜像,"发布"是把镜像和配置结合,"运行"是启动容器,三者分开,避免运行时修改镜像;
- 无状态进程:应用不存数据(比如用户登录会话),数据存在外部服务(如Redis),这样能多开几个应用实例,支持水平扩展;
- 端口绑定:应用自己通过端口提供服务(比如Nginx监听80端口),不用依赖其他程序帮忙转发;
- 并发处理:通过多开进程/线程提高处理能力,不用靠升级服务器硬件;
- 快速启动与优雅终止:启动快(方便快速扩容),关闭时能处理完剩余请求(比如用户正在下单,不会突然中断);
- 开发环境与生产环境一致:尽量让开发、测试、生产环境一样(比如都用Docker镜像),减少"开发能跑,生产报错";
- 日志管理:应用只打印日志,不自己存日志,由外部系统(如ELK)收集分析,方便查问题;
- 管理进程:备份数据、迁移数据库这些管理任务,和业务应用用相同环境,避免手动执行脚本导致环境不一致。
二、Kubernetes(K8S)核心认知
2.1 什么是Kubernetes(K8S)?
2.1.1 基本定义与起源
Kubernetes简称K8S(因为"K"和"S"之间有8个字母),简单说就是"容器集群的操作系统"------如果把容器比作"应用盒子",K8S就是管理这些盒子的"管家",负责调度盒子到合适的服务器、分配资源、处理故障、自动扩容等。
K8S的"爸爸"是Google:Google内部有个叫Borg的系统,专门管理海量容器,后来Google把Borg的经验总结出来,2014年开源了K8S,之后捐给了CNCF,成为CNCF第一个"毕业项目",现在是容器编排的行业标准。K8S用Go语言开发,特点是高可用、可扩展、跨平台。
以前还有个编排工具叫Mesos+Marathon,2019年就没人用了,现在大家基本都选K8S。
2.1.2 版本节奏与官网
K8S每年大概发4个版本(比如1.24、1.28、1.30),每个版本会加新功能、修bug,还会告诉大家哪些功能要淘汰。
官网:英文https://kubernetes.io,中文https://kubernetes.io/zh-cn/docs,想查详细文档可以去这里。
2.1.3 K8S与Docker的支持变动
很多人会问:K8S和Docker是什么关系?以前K8S用Docker当"容器运行时"(就是启动容器的工具),但后来K8S推出了自己的接口(CRI),支持更多运行时,2022年K8S 1.24版本后,就不再支持Docker当运行时了。
但不用慌:Docker打包的镜像还能在K8S里用(因为镜像符合标准),只是不能用Docker引擎来启动容器了,现在主流用containerd(Docker的核心组件,更轻量、性能更好)。
2.2 为什么要用K8S?
2.2.1 解决传统部署痛点
以前部署应用有很多麻烦:
- 扩展难:业务忙的时候要手动买服务器、装环境、启动应用,慢得很;
- 运维重:应用崩溃了要手动重启,服务器坏了要手动迁移应用;
- 容错弱:一个服务器坏了,应用就停了,单点故障导致服务中断。
K8S就是为了解决这些问题而生的,让部署和运维自动化、智能化。
2.2.2 K8S核心优势
- 自动化运维:一条命令就能搞定部署、扩容、更新。比如想把Nginx应用从3个扩到5个,执行
kubectl scale deployment nginx --replicas=5就行,不用手动操作每个容器; - 弹性伸缩:根据负载自动调整。比如CPU使用率超过80%,自动多开几个应用实例;低于20%,自动关掉多余的,避免资源浪费;
- 容灾与自愈:"故障自动恢复"。比如某个服务器坏了,K8S会把上面的应用自动迁移到其他健康服务器;容器崩溃了,自动重启,确保应用一直运行;
- 服务发现与负载均衡:应用实例的IP会变(比如重启后),K8S通过Service提供固定的访问地址,不管实例怎么变,都能访问到;还能把请求均匀分给多个实例,避免单个实例压力太大;
- 滚动升级与回滚:更新应用时不中断服务。比如更新Nginx版本,先启动1个新实例,确认正常后再关掉1个旧实例,依次类推;如果更新出错,一键就能回滚到上一个正常版本;
- 集中配置与密钥管理:普通配置(如数据库地址)存在ConfigMap里,敏感数据(如密码、证书)存在Secret里,修改配置不用重新做镜像,而且Secret会加密存储,更安全;
- 存储编排:支持对接各种存储(如NFS、云存储),开发者只需要申请存储(PVC),不用管底层怎么实现,K8S会自动匹配合适的存储资源(PV);
- 批处理与定时任务:支持一次性任务(如数据备份)和定时任务(如每天凌晨2点清理日志),不用手动写脚本、设定时。
三、K8S集群架构与核心组件
K8S集群就像一个"团队",分"管理层"(控制平面)和"执行层"(工作节点),各司其职,协同工作。
3.1 架构概述
- 控制平面(Master):相当于"团队大脑",负责做决策------比如接收用户的部署请求、选择哪个服务器运行应用、监控集群状态是否符合期望;
- 工作节点(Node):相当于"团队手脚",负责执行任务------启动/停止容器、汇报自己的状态给控制平面;
- 通信逻辑:所有请求(比如创建应用)都先发给控制平面的API Server,控制平面处理后,把任务下发给工作节点,工作节点执行后再汇报状态。
3.2 控制平面(Master / Control Plane)组件
控制平面有4个核心组件,就像"大脑的不同部门":
| 组件 | 核心职责(大白话) |
|---|---|
| kube-apiserver | 集群的"总入口",所有请求都要经过它,还要校验请求是否合法;其他组件之间也通过它通信 |
| kube-controller-manager | 集群的"监督员",运行各种控制器,确保集群状态符合期望。比如"副本控制器"确保应用实例数够,"节点控制器"监控服务器状态 |
| kube-scheduler | 集群的"调度员",给新创建的应用实例(Pod)找合适的服务器(Node)。比如看哪个服务器有足够的CPU、内存,负载最低 |
| etcd | 集群的"数据库",存储所有集群状态数据(比如应用配置、服务规则),是集群的"唯一数据来源" |
生产环境建议:控制平面组件要部署多个实例(比如3个API Server、3个etcd),避免一个组件坏了导致整个集群瘫痪。
3.3 工作节点(Node / Worker)组件
工作节点是运行应用的"载体",核心组件如下:
| 组件 | 核心职责(大白话) |
|---|---|
| kubelet | 节点的"代理",每个工作节点都有一个,负责接收控制平面的任务,启动/停止容器,监控容器状态,定期汇报给控制平面 |
| kube-proxy | 节点的"网络代理",负责配置网络规则,把外部请求转发到对应的应用实例,实现负载均衡和服务发现 |
| Container Runtime | 容器的"发动机",负责拉取镜像、启动容器、资源隔离等底层操作。K8S 1.24以上版本必须用支持CRI的运行时,主流是containerd |
举个例子:你想创建一个Nginx应用,流程是这样的:
- 你发送请求给kube-apiserver;
- kube-apiserver把请求存到etcd;
- kube-scheduler选一个合适的工作节点;
- 该节点的kubelet收到任务,通过containerd拉取Nginx镜像,启动容器;
- kube-proxy配置网络规则,让外部能访问这个Nginx应用。
3.4 Docker / dockershim 与containerd的过渡说明
- Docker引擎:以前是K8S的运行时,但因为不支持CRI接口,K8S 1.24后不再支持;但Docker打包的镜像还能用,因为镜像符合标准;
- containerd:原本是Docker引擎的核心组件,后来被单独剥离出来,更轻量、性能更好,而且原生支持CRI,现在是K8S的主流运行时;
- 版本建议:如果用K8S 1.28及以上版本,直接选containerd或CRI-O,不用再考虑Docker引擎。
四、K8S核心概念与资源对象
K8S里有很多"资源对象",其实就是描述集群中各种实体的"配置文件",掌握这些基础概念,就能开始用K8S了:
| 概念/资源 | 含义与用途(大白话) |
|---|---|
| Pod | K8S中最小的部署单位,相当于"容器的房子",里面可以住1个或多个容器(比如1个Nginx容器+1个日志收集容器)。同一"房子"里的容器共享IP和存储,不能单独扩容,要靠控制器管理 |
| 控制器(Controller) | 管理Pod的"管家",确保Pod按期望运行: - Deployment:管无状态应用(如Web服务),支持滚动更新、回滚; - ReplicaSet:确保Pod实例数够(Deployment底层靠它); - StatefulSet:管有状态应用(如数据库),确保Pod名称、IP、存储稳定; - DaemonSet:每个工作节点上跑1个Pod(如日志收集、监控代理); - Job/CronJob:Job是一次性任务(如数据导入),CronJob是定时任务(如定时备份) |
| Service | 给一组Pod提供"稳定访问地址"。Pod的IP会变(比如重启后),Service通过"标签"找到对应的Pod,提供固定的地址,还能把请求分给多个Pod,实现负载均衡 |
| Ingress | 管理外部访问的"域名管家"。Service的访问端口是随机的(30000-32767),而且不能处理域名、SSL证书;Ingress可以通过域名(如www.xxx.com)把流量转发到不同Service,还能处理SSL加密、路径匹配(如/api路径转发到API服务) |
| Label/Annotation/Selector | - Label:资源的"标签"(如app=nginx、env=prod),用来分组资源,比如给所有Nginx Pod打app=nginx标签; - Annotation:存"描述信息"(如应用版本、构建时间),不用于分组; - Selector:根据Label筛选资源,比如Service通过app=nginx找到对应的Pod |
| Namespace(命名空间) | 集群的"隔离空间",把集群分成多个独立环境(如dev开发环境、test测试环境、prod生产环境)。不同空间的资源名称可以重复,还能控制权限(比如开发人员只能访问dev空间) |
| 资源定义结构 | K8S资源通常用YAML文件定义,核心字段: - apiVersion:资源的API版本(如apps/v1对应Deployment); - kind:资源类型(如Deployment、Service); - metadata:资源元数据(名称、Namespace、Label); - spec:期望状态(如Deployment要3个实例); - status:实际状态(K8S自动维护,不用手动改) |
五、K8S核心能力与特性
K8S的核心能力都围绕"自动化、高可用、可扩展",覆盖应用从部署到运维的全生命周期:
1. 自动伸缩
- 水平伸缩(HPA):根据CPU、内存或请求量,自动增加或减少Pod实例数(比如请求量多了,自动多开几个Pod);
- 垂直伸缩(VPA):自动调整Pod的CPU/内存配额(比如从1核2G调到2核4G),适合不能水平扩展的应用(如单机数据库)。
2. 服务发现与负载均衡
- 服务发现:不用记Pod的IP,通过Service的固定地址或域名就能访问,Pod变了也不影响;
- 负载均衡:把请求均匀分给多个Pod,还能设置"会话亲和性"(比如同一用户的请求一直发到同一个Pod)。
3. 滚动更新与回滚
- 滚动更新:更新应用时不中断服务,通过控制"最大不可用Pod数"和"最大额外Pod数",慢慢替换旧实例;
- 回滚:如果更新出错,能查看历史版本,一键回滚到上一个正常版本(比如
kubectl rollout undo deployment nginx)。
4. 容错与自愈
- 节点自愈:服务器坏了,K8S把上面的Pod迁移到其他健康服务器;
- Pod自愈:通过"存活探针"检测容器是否正常,比如Nginx崩溃了,探针发现后自动重启;
- 就绪探针:确保Pod准备好后才接收请求(比如数据库连接成功后,再对外提供服务)。
5. 集中配置与密钥管理
- ConfigMap:存普通配置(如数据库地址),可以注入到容器的环境变量,或挂载成文件,修改配置不用改镜像;
- Secret:存敏感数据(如密码、证书),会用base64编码存储,生产环境还能加密,更安全。
6. 存储编排与持久化存储
- PV(持久化卷):管理员创建的集群级存储资源(如100G的NFS存储);
- PVC(持久化卷声明):开发者申请存储的"申请单"(如申请50G存储),K8S自动匹配合适的PV;
- StorageClass:动态创建PV,不用管理员手动创建,比如申请"快速存储",自动创建云存储卷。
7. 资源隔离与配额
- ResourceQuota:给命名空间设资源上限(如dev空间最多用10核CPU、20G内存),避免资源滥用;
- LimitRange:给Pod设默认资源配额(如每个Pod默认0.5核CPU、1G内存),限制单个Pod的最大/最小资源。
8. 安全管理机制
- RBAC:基于角色的访问控制,比如给开发人员"只能看Pod"的权限,给管理员"能创建/删除资源"的权限,实现细粒度控制;
- NetworkPolicy:定义Pod间的网络访问规则(如只允许前端Pod访问后端Pod的8080端口),实现网络隔离;
- Pod安全准入:限制Pod的权限(如禁止使用特权容器),避免安全风险。
六、K8S常见部署方案
不同场景选不同的部署方式,不用盲目追求复杂:
| 部署方式 | 适用场景 | 核心特点(大白话) |
|---|---|---|
| Minikube | 本地学习、实验、演示(比如开发人员验证配置) | 单节点集群,资源占用低(默认1核2G),一键启动(minikube start)、停止,不用复杂配置,不能用于生产 |
| kubeadm | 中小型集群(测试环境、企业非核心业务) | 官方推荐工具,部署简单,一键初始化控制平面(kubeadm init)、加入节点(kubeadm join),自动生成证书,支持高可用,需要手动装网络插件(如Calico)、存储等 |
| 二进制/源码部署 | 生产环境(核心业务)、对可控性要求高的场景 | 手动下载组件二进制文件,手动配置证书、服务,高度可控,能定制化(如修改组件参数),但部署复杂,需要懂K8S原理 |
| 云托管服务(如GKE/EKS/ACK) | 企业生产环境、追求运维效率 | 云厂商管控制平面(比如阿里云ACK自动维护API Server、etcd),用户只需要管工作节点,一键扩容、升级,集成监控,省心但要花钱,依赖云厂商 |
推荐选择:
- 学习/实验:用Minikube,简单快捷;
- 测试环境/中小型生产集群:用kubeadm+containerd,兼顾效率和学习价值;
- 大型生产集群:选云托管服务(如阿里云ACK)或二进制部署,稳定可靠。
总结
云原生和K8S的核心价值,就是"解放开发者,稳定运行应用"------让开发者不用再操心服务器、环境配置这些底层问题,聚焦于业务逻辑;同时通过自动化、自愈、弹性伸缩等特性,让应用在动态环境中稳定运行。