【K8s笔记】kubernetes的基本概念
architecture
**Monolithic Architecture(单体架构)和Microservices Architecture(微服务架构)**是两种常见的软件架构模式。下面从多个维度进行对比:
¶1. 定义
¶单体架构(Monolithic Architecture)
- 特点:所有功能模块都集成在一个整体应用中,作为一个单独的部署单元运行。
- 例子:传统的 Spring MVC Web 应用,所有业务逻辑、数据访问、UI 都在一个项目里。
¶微服务架构(Microservices Architecture)
- 特点:将应用拆分为一组小的、独立部署的服务,每个服务实现特定业务功能,服务之间通过 API(如 REST、gRPC)通信。
- 例子:电商系统中有用户服务、订单服务、商品服务等,每个服务单独部署。
¶2. 优缺点对比
维度 | 单体架构 Monolithic | 微服务架构 Microservices |
---|---|---|
开发难度 | 上手简单,项目结构清晰 | 复杂度高,需合理拆分服务 |
部署方式 | 整体打包,一次部署 | 每个服务独立部署、独立扩缩容 |
技术栈 | 一般使用统一技术栈 | 可根据服务选择不同技术栈 |
扩展性 | 整体扩容,资源利用率低 | 按需扩容,资源利用率高 |
维护性 | 项目变大后代码难维护 | 每个服务小巧,易于维护 |
容错性 | 一个模块崩溃影响整体 | 单个服务崩溃不会影响其他服务 |
团队协作 | 大团队协作冲突多 | 可分团队独立开发各自服务 |
测试难度 | 集成测试相对简单 | 需处理服务间通信、接口测试复杂 |
部署速度 | 变更需整体部署,慢 | 小服务可快速迭代、独立上线 |
¶3. 适用场景
-
单体架构适合:
- 小型项目、初创项目
- 团队规模较小
- 业务逻辑简单,变更不频繁
-
微服务架构适合:
- 大型、复杂项目
- 团队规模较大,分工明确
- 业务模块独立性强,变更频繁
- 需要高可用、高扩展性
¶4. 总结
- 单体架构优点是简单、易于开发和部署,缺点是后期维护、扩展困难。
- 微服务架构优点是灵活、可扩展、易于维护,但开发、运维、测试复杂度高。
container
container主要为这三个:CRI-O、Docker、containerd。这三个名字经常在 Kubernetes 圈子里出现,很多人刚入门时也会混淆。下面详细梳理一下它们的关系和区别,帮助你建立清晰的认知。
¶1. 背景:Kubernetes 需要什么?
Kubernetes(k8s)本身不会直接运行容器,它需要“容器运行时”(Container Runtime)来负责真正拉取镜像、创建、启动和管理容器。
Kubernetes 通过一个叫做 CRI(Container Runtime Interface) 的接口和各种容器运行时对接。
¶2. Docker 是什么?
- Docker 是最早流行起来的容器引擎(容器运行时),它集成了镜像管理、容器运行、网络、存储等一整套功能。
- Kubernetes 早期默认用 Docker 作为底层容器运行时。
但 Docker 其实是“全家桶”,里面有很多功能(比如 CLI、API、镜像构建、镜像分发等),k8s 只需要其中的“运行容器”这一部分。
¶3. containerd 是什么?
- containerd 是 Docker 项目里拆出来的专注于容器运行的核心组件。
- 它只负责拉取镜像、创建容器、管理容器生命周期,不包含 Docker CLI、Dockerfile 构建等功能。
- containerd 现在是 CNCF(云原生计算基金会)孵化的独立项目,也是 Kubernetes 官方推荐的容器运行时之一。
简单理解:
Docker = containerd + 其它功能(CLI、构建等)
containerd = 只做“运行容器”这件事
¶4. CRI-O 又是什么?
- CRI-O 是专门为了 Kubernetes 而开发的一个轻量级容器运行时。
- 它只实现了 Kubernetes 的 CRI 接口,目标是“只为 k8s 服务”,不用像 Docker/containerd 那样考虑其它场景。
- CRI-O 只支持 OCI 标准镜像和运行时(比如 runc),非常精简。
简单理解:
CRI-O = 只为 Kubernetes 打工的“容器运行时”
containerd = 通用的容器运行时,Kubernetes 也能用
¶5. 它们的关系图
1 |
|
- K8s v1.24 起,官方已不再支持 Docker 作为运行时,推荐用 containerd 或 CRI-O。
¶6. 总结对比表
名称 | 主要用途 | 是否专为K8s设计 | 是否支持OCI标准 | 说明 |
---|---|---|---|---|
Docker | 通用容器引擎 | 否 | 支持 | 功能多,k8s已不推荐直接用 |
containerd | 容器运行时 | 否 | 支持 | 轻量、通用,k8s主流推荐 |
CRI-O | 容器运行时 | 是 | 支持 | 只为k8s设计,更加精简 |
¶7. 生活比喻
- Docker:像是一个全能厨师,自己买菜、烧菜、端菜、收拾厨房全包了。
- containerd:像是专门烧菜的厨师,买菜和端菜交给别人,只负责炒菜。
- CRI-O:像是只为某家餐厅(K8s)服务的专职厨师,菜单和流程都为这家餐厅定制。
pod
- k8s的最小容器单位,一个pod里面可以有多个container
- pod有自己的共享卷,共享IP。
- pod至少属于一个namespace,如果一个pod没有被指定namespace那就是在
default
下 - 最常见的就是一个pod包含一个container。
- 一个pod只能在一个server上。
- pod可能随时被自动删除,移动到其他node等等,在设计程序的时候就要考虑到这一点
pause container
¶pause 容器的作用
pause 容器是 Kubernetes 每个 Pod 里自动创建的一个极其轻量级的“基础”容器。它的作用主要有:
¶1. 作为 Pod 的“基础容器”
- Pod 其实是一个共享网络、存储等资源的组。
- 这些共享资源(比如网络 namespace、IP、挂载卷)需要有“宿主”来维持。
- pause 容器就是这个宿主,它最早启动,其他业务容器都加入它的 namespace。
¶2. 维持 Pod 的网络和 IPC 命名空间
- Pod 里的所有容器(无论主业务还是 sidecar)都和 pause 容器处于同一个网络、同一个 IPC namespace。
- 只要 pause 容器在,Pod 的网络和 IPC 就不会被释放,业务容器即使重启也不会影响 Pod 的 IP 等。
¶3. 生命周期管理
- pause 容器的生命周期 = Pod 生命周期。
- 业务容器挂了可以重启,但 pause 容器一旦挂掉,整个 Pod 就会被销毁。
¶4. 极其轻量
- 它几乎什么都不做,只是执行一个
sleep
或/pause
命令,占用极少资源。
如果你用 docker inspect
或 crictl inspect
去看 Pod 的 namespace 信息,通常都能看到业务容器和 pause 容器的 network namespace 是一样的。
cluster & node
- 一个cluster有多个node,每个node指一个服务器,物理或者虚拟的。
- 一个node有多个pod,一个pod一般只有一个container。
- 同一个cluster里面的node通常在地理位置相近的位置,方便node之间协作
master node & worker node
master node 和 worker node 是 Kubernetes 集群中的两个核心角色,理解它们的关系非常重要。下面我用通俗易懂的方式详细解释:
¶1. 基本定义
角色 | 主要作用 |
---|---|
master node | 负责整个集群的“管理、调度和控制”,像“大脑” |
worker node | 负责实际运行用户的应用(Pod),像“工人” |
¶2. 详细说明
¶master node(控制节点)
-
主要负责:
- 集群的整体管理
- 资源调度
- 决定把哪个 Pod 放到哪个 worker node 上
- 维护集群状态
- 提供 API 接口供用户和运维人员操作
-
核心组件:
- kube-apiserver:集群对外的 API 服务
- etcd:保存集群所有数据的数据库
- kube-scheduler:负责调度 Pod 到具体的 worker node
- kube-controller-manager:负责各种控制器(副本数、节点状态等)
¶worker node(工作节点)
-
主要负责:
- 实际运行 Pod(容器)
- 把 master node 下发的任务执行好
-
核心组件:
- kubelet:负责和 master 通信,接收任务并管理本节点的 Pod
- kube-proxy:负责网络通信和服务转发
- 容器运行时(如 containerd、CRI-O):负责启动和管理容器
¶3. 它们的关系(类比)
- master node 像一个“调度中心”或“车间主任”,负责分配任务、监督进度、管理整体情况。
- worker node 像“工人”,负责实际干活,把任务完成。
- 用户提交任务(比如部署一个应用),master node 决定怎么分配,worker node 具体去执行。
¶4. 工作流程举例
- 用户通过 kubectl 或 API 提交一个部署请求。
- master node 接收请求,分析并决定把任务分配给哪些 worker node。
- worker node 接收到任务后,启动对应的 Pod(容器),并持续向 master node 汇报状态。
- master node 监控所有 worker node 的健康和任务完成情况。
¶5. 图解
pod & deployment
¶1. Pod 是什么?
- Pod 是 Kubernetes 里最小的调度和运行单元。
- 一个 Pod 通常包含一个或多个紧密协作的容器(最常见的是一个)。
- Pod 负责容器的网络、存储等资源的共享。
¶2. Deployment 是什么?
- Deployment 是一种更高层次的 Kubernetes 控制器(资源对象)。
- 它用来管理和维护一组 Pod,确保它们的副本数、滚动升级、回滚等。
- Deployment 会根据你的定义,自动创建、删除、更新 Pod。
¶3. 它们之间的关系
- Deployment 不直接创建 Pod,而是创建一种叫 ReplicaSet 的资源,ReplicaSet 再去创建和管理 Pod。
- 你只需要定义 Deployment,Kubernetes 会负责保证 Pod 的数量和健康。
¶关系图
1 |
|
¶举个例子
你写了一个 Deployment YAML,要求 3 个副本:
1 |
|
Kubernetes 会自动:
- 创建一个 ReplicaSet。
- ReplicaSet 创建 3 个 Pod。
- 如果有 Pod 挂了,ReplicaSet 会自动补上,始终保证有 3 个。
label & selector (deployment)
¶1. labels(标签)是什么?
labels 是一组键值对,用来给 Kubernetes 里的资源(比如 Pod、Deployment、Service 等)打标签。
- 作用:给资源“贴标签”,方便查找、筛选、分组和管理。
- 形式:
key: value
,比如1
2
3labels:
app: nginx
env: prod - 一个资源可以有多个 labels。
¶2. selector(选择器)是什么?
selector 是一种筛选机制,用来匹配拥有特定 labels 的资源。
- 作用:让 Deployment、Service 等控制器知道要“管理”哪些 Pod。
- 形式:通常是
matchLabels
,比如1
2
3selector:
matchLabels:
app: nginx - 意思是:选择所有带有
app: nginx
这个 label 的 Pod。
¶3. Deployment 里的 labels 和 selector 的关系
- Deployment 本身有 labels(给 Deployment 这个对象贴标签)。
- Deployment 的 Pod 模板(template 里的 metadata.labels)也有 labels(给将来创建的 Pod 贴标签)。
- selector 决定 Deployment 认为哪些 Pod 属于自己(通常和 Pod 模板里的 labels 匹配)。
¶举个例子
1 |
|
- Deployment 对象的 labels:
project: demo
(只是给 Deployment 资源本身做标记) - Pod 模板的 labels:
app: nginx, env: prod
(这些标签会贴在所有由这个 Deployment 管理的 Pod 上) - selector:
app: nginx
(Deployment 只会管理带有app: nginx
这个标签的 Pod)
ReplicaSet
¶1. ReplicaSet 是什么?
ReplicaSet 是 Kubernetes 里的一个控制器,主要作用是确保指定数量的 Pod 副本一直在运行。
- 简单来说:保证有 N 个一模一样的 Pod 在集群里活着。
- 比如你设置副本数为 3,ReplicaSet 就会确保始终有 3 个对应的 Pod 在运行。如果有 Pod 挂了,它会自动补上。
¶2. ReplicaSet 的核心作用
- 自动补齐 Pod 数量:如果有 Pod 挂了或被删了,ReplicaSet 会自动创建新的 Pod 补齐数量。
- 根据标签选择 Pod:ReplicaSet 通过 selector(选择器)找到属于自己的 Pod。
- 不负责升级和滚动更新:ReplicaSet 只负责数量,不负责版本升级。升级 Pod 用 Deployment。
¶3. 和 Deployment 的关系
- Deployment 是用来管理应用的生命周期(包括升级、回滚等)。
- Deployment 底层其实就是自动创建和管理 ReplicaSet。
- 你通常不会直接用 ReplicaSet,而是用 Deployment。Deployment 提供了更高级的功能(比如滚动升级),但它内部就是靠 ReplicaSet 保证 Pod 数量的。
¶简单示意图
1 |
|
Deployment 负责升级和版本管理,ReplicaSet 负责具体的副本数量。
Service
Kubernetes 中的 Service(服务) 是一个非常核心的概念。
¶1. Service 是什么?
Service 是 Kubernetes 中用来暴露一组 Pod 的访问入口的抽象资源。
- 简单理解: Service 就像是集群内部或外部访问 Pod 的“门牌号”或“网关”。
- 它为一组 Pod(通常是同一个应用的副本)提供一个固定的访问地址,即使这些 Pod 动态增删,Service 的地址不会变。
¶2. 为什么需要 Service?
- Pod 的 IP 不固定:Pod 随时可能被重建,IP 会变化,直接访问 Pod 不可靠。
- 负载均衡:Service 可以自动把流量分发到后端多个 Pod 上,实现负载均衡。
- 服务发现:Service 会在集群内自动注册 DNS 名称,方便其他服务访问。
¶3. Service 的类型
Kubernetes 支持多种 Service 类型,常见的有:
- ClusterIP(默认):
- 只在集群内部可访问,为一组 Pod 分配一个虚拟 IP。
- NodePort:
- 在每个节点开放一个端口,通过节点 IP + 端口号访问 Service。
- LoadBalancer:
- 云环境下自动申请云负载均衡器,外部可以直接访问。
- ExternalName:
- 把 Service 映射到外部 DNS 名称。
¶4. Service 的工作原理
- Service 通过 标签选择器(selector) 选定一组 Pod。
- Service 会分配一个虚拟 IP(ClusterIP),所有访问 Service 的流量会自动转发到后端 Pod 上。
- Service 负责负载均衡和服务发现。
¶示意图
1 |
|
用户只需要访问 Service 的 IP/端口,Service 会自动把请求转发到后端的 Pod 上。
¶5. Service 的 YAML 示例
1 |
|
- 这个 Service 会把集群内访问
my-service:80
的流量,转发到所有带有app: my-app
标签的 Pod 的8080
端口上。 - 也可以使用
kubectl expose
来直接暴露一个pod的端口,这会自动创建一个Service
Cluster IP
¶1. ClusterIP 是什么?
ClusterIP 是 Kubernetes Service 的默认类型。
它会为一组 Pod 分配一个集群内部可访问的虚拟 IP 地址。
- 只能在 Kubernetes 集群内部访问,集群外部无法直接访问。
- 适用于服务之间的内部通信,比如前端服务访问后端服务,或者微服务之间的调用。
¶2. 工作原理
- 当你创建一个
type: ClusterIP
的 Service,Kubernetes 会分配一个虚拟 IP(比如 10.96.0.1)。 - 集群内的其它 Pod 或 Service,可以通过这个虚拟 IP 或 Service 名称访问对应的服务。
- Service 会自动把流量转发到后端对应的 Pod 上,实现负载均衡。
¶3. 使用场景举例
- 微服务内部调用(前端访问后端、A 服务访问 B 服务)
- 数据库服务(只允许集群内访问,不允许外部访问)
- 集群内通信(如 metrics、日志收集等)
¶4. 示例 YAML
1 |
|
- 这个 Service 会为所有有
app: backend
标签的 Pod 提供一个集群内部的访问入口(比如 my-backend:80)。
¶5. 如何访问 ClusterIP 服务?
- 集群内部的 Pod 可以通过
my-backend:80
或者 ClusterIP 地址(如 10.96.0.1:80)访问。 - 集群外部(比如你的本地电脑、外部网络)无法直接访问。
其他IP种类
IP 类型 | 说明 | 作用范围 | 典型举例 |
---|---|---|---|
Pod IP | 分配给每个 Pod 的 IP,由 CNI 插件(如 Flannel、Calico)分配 | 单个 Pod | 10.244.1.5 |
ClusterIP | 分配给 Service(type: ClusterIP)的虚拟 IP,由 kube-apiserver 分配 | 集群内部通信 | 10.96.0.1 |
Node IP | 每个 Node(节点)的主机 IP,一般是云主机或物理机的内网 IP | 节点级别 | 192.168.1.10 |
External IP | 云厂商/管理员分配给 Node 的公网 IP 或外部访问 IP | 集群外部 | 8.8.8.8 |
LoadBalancer IP | 云负载均衡器分配的 IP,Service (type: LoadBalancer) 获得 | 集群外部 | 47.xx.xx.xx |
NodePort IP | 实际是 Node IP,通过 NodePort 端口访问服务 | 集群外部 | 192.168.1.10:30080 |
ExternalName | 不是 IP,而是 DNS 名称,Service (type: ExternalName) 指向外部服务 | 集群外部 | mysql.example.com |
¶详细解释
¶1. Pod IP
- 每个 Pod 启动时,CNI 网络插件分配的 IP。
- 只在集群内部有效,Pod 重启后 IP 可能变化。
- 例:
10.244.1.5
¶2. ClusterIP
- Service 的默认类型,分配一个虚拟 IP,集群内部通信用。
- 例:
10.96.0.1
¶3. Node IP
- 每台 Node(物理机/虚拟机)的主机 IP。
- 通常是内网 IP,有时也有公网 IP。
- 例:
192.168.1.10
¶4. External IP
- 云厂商或管理员为 Node 分配的公网 IP。
- 通过 NodePort 或自定义方式暴露服务时可用。
- 例:
8.8.8.8
¶5. LoadBalancer IP
- 云平台自动为 Service (type: LoadBalancer) 分配的公网或内网 IP。
- 例:
47.XX.XX.XX
¶6. NodePort IP
- 其实就是 Node IP + NodePort 端口号。
- 通过
NodeIP:NodePort
可以从集群外访问对应服务。 - 例:
192.168.1.10:30080
¶7. ExternalName
- 不是 IP,是 DNS 名称。
- Service (type: ExternalName) 只做 DNS 解析,把服务名解析成外部的 DNS。
- 例:
mysql.example.com
兼容性
¶1. 镜像格式
- Docker 镜像实际上是 OCI 镜像规范(Open Container Initiative)的实现。
- CRI-O 和 containerd 都支持 OCI 镜像规范。
- Docker 镜像和 OCI 镜像高度兼容,绝大多数情况下二者可以互换。
¶2. 实际兼容性
- 你用
docker build
构建出来的镜像,推到镜像仓库(如 Docker Hub、Harbor、阿里云、Google Container Registry 等), - 用 CRI-O 或 containerd 拉取这个镜像,它们能直接识别和运行。
¶3. 运行原理
- Kubernetes 通过 CRI(Container Runtime Interface)和底层 runtime(如 CRI-O、containerd)交互。
- 不管你用哪个 runtime,只要是标准的 Docker 镜像,都能拉取并运行。
¶4. 注意事项
- 极少数情况下,如果你的镜像用了非常老的、非标准的 Docker 特性,可能有兼容性问题,但这种情况极少见。
- 镜像仓库认证、私有仓库拉取权限等问题,与 runtime 相关,但与镜像格式无关。
¶5. 总结
- Docker 镜像可以直接在 CRI-O 和 containerd 上运行。
- 这是 Kubernetes 社区的主流方式,不需要做任何特殊转换。
一些零散的知识点
- yaml配置文件中,cpu限制
xxxm
表示使用千分之几个cpu核心的资源 - 一个node内service的名字就是其dns的解析的名字