Table of contents
思维导图
思维导图只是提供简单的大致轮廓,虽然给每个分支加了笔记,但是建议和该文档一起看比较好,因为有一些细节或者其他内容,在笔记里并不完整。
思维导图下载链接:Kubernetes基础.xmind
简介
Kubernetes 用于管理云平台中多个主机上的容器化的应用。
Kubernetes 目标是让部署容器化的应用简单并且高效。
Kubernetes 提供了应用部署,规划,更新,维护的强大和灵活的机制。
Kubernetes 一个核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着。用户可以运行一个微型服务,让规划器来找到合适的位置节点,后续用户不需要关心怎么去做,Kubernetes 会自动去监控,然后去重启,新建等,总之让应用可以一直提供服务,同时,Kubernetes 提供了人性化的相关工具,可以让用户能够方便的部署自己的应用。
特性
自动化上线和回滚
Kubernetes 会分步骤地将针对应用或其配置的更改上线,同时监视应用程序运行状况以确保你不会同时终止所有实例。如果出现问题,Kubernetes 会为你回滚所作更改。你应该充分利用不断成长的部署方案生态系统。
服务发现与负载均衡
无需修改你的应用程序即可使用陌生的服务发现机制。Kubernetes 为容器提供了自己的 IP 地址和一个DNS 名称,并且可以在它们之间实现负载均衡。
存储编排
自动挂载所选存储系统,包括本地存储、诸如 GCP 或 AWS 之类公有云提供商所提供的存储或者诸如NFS、iSCSI、Gluster、Ceph、Cinder 或 Flocker 这类网络存储系统。
水平扩缩
使用一个简单的命令、一个 UI 或基于 CPU 使用情况自动对应用程序进行扩缩。
自我修复
重新启动失败的容器,在节点死亡时替换并重新调度容器,杀死不响应用户定义的健康检查的容器,并且在它们准备好服务之前不会将它们公布给客户端。
为扩展性设计
无需更改上游源码即可扩展你的 Kubernetes 集群。
自动装箱
根据资源需求和其他约束自动放置容器,同时避免影响可用性。 将关键性的和尽力而为性质的工作负载进行混合放置,以提高资源利用率并节省更多资源。
批量执行
除了服务之外,Kubernetes 还可以管理你的批处理和 CI 工作负载,在期望时替换掉失效的容器。
IPv4/IPv6 双协议栈
为 Pod 和 Service 分配 IPv4 和 IPv6 地址。
Secret 和配置管理
部署和更新 Secret 和应用程序的配置而不必重新构建容器镜像, 且不必将软件堆栈配置中的秘密信息暴露出来。
架构
参考链接:https://www.kubernetes.org.cn/kubernetes设计架构
Kubernetes 是一个分布式系统,由很多主机节点组成,且各个节点的分工不同。
主机节点主要由两种类型,如下:
-
master 节点
管理(控制)节点,主要由 API server、controller-manager、scheduler 三个组件,以及一个用于存储集群状态的 etcd 存储服务组成(有时候 etcd 也可以单独出来,不放在 master 节点上,有特别高的性能要求时使用)。
-
worker 节点
主要包含 kubelet、kube proxy 、容器运行时(如 docker)三个组件,它们承载运行各类应用容器。
节点运行逻辑:
- kubernetes 将所有 worker 节点的资源集结在一起形成一台逻辑更加强大的“服务器”
- 计算和存储接口通过 master 之上的 api server 暴露
- 客户端通过 api 提交应用程序的运行请求,而后由 master 通过调度算法将其自动指派至某特定的 worker 节点,以 pod 对象的形式运行
- master 会自动处理因 worker 节点的添加、故障、移除等变动对 pod 的影响
组件
control plane components 控制平台组件
控制平面的组件做出有关集群的全局决策(例如,调度),以及检测和响应集群事件(例如,当部署的 replicas 无法达到要求时,自动启动新的Pod)。Control Plane 组件可以在集群中的任何计算机上运行。但是,为简单起见,通常在同一台计算机上启动所有Control Plane 组件,并且不在该计算机上运行用户容器(即 master 节点运行)。
kube-apiserver
该组件是整个集群的访问入口,为 api 对象验证并配置数据,包括 pods、services、replication controllers 和其他 api 对象,api server 提供 rest 操作和到集群共享状态的前端,所有其他组件通过它进行交互。
默认利用 6443/tcp 端口对外提供服务。
客户端和 api server 需要通过基于 https 协议链接,如果使用前端使用LB,需要使用四层负载均衡。
注意: api server 本身无状态,集群数据存储在 etcd 中。
kube-controller-manager
Controller Manager作为集群内部的管理控制中心,负责集群内的 Node、Pod副本、服务端点( Endpoint)、命名空间(Namespace)、 服务账号( ServiceAccount)、资源定额(ResourceQuota)的管理,当某个 Node 异常宕机时, Controller Manager 会及时发现并执行自动化修复流程,确保 kubernetes 集群尽可以处于预期的工作状态。
Controller Manager 负责实现客户端通过API提交的终态声明,由相关代码通过一系列步骤驱动API对象的“实际状态”接近或等同“期望状态”
Controller Manager 对应的程序为 kube-controller-manager
Kubernetes 控制器管理器是一个守护进程,内嵌随 Kubernetes 一起发布的核心控制回路。 在机器人和自动化的应用中,控制回路是一个永不休止的循环,用于调节系统状态。 在 Kubernetes 中,每个控制器是一个控制回路,通过 API 服务器监视集群的共享状态, 并尝试进行更改以将当前状态转为期望状态。 目前,Kubernetes 自带的控制器例子包括副本控制器、节点控制器、命名空间控制器和服务账号控制器等。
Controller Manager 管理 kubernetes 所有资源。
kube-scheduler
调度器,负责为 pod 挑选处评估这一时刻相应的最合适的运行节点。
简单调度流程:
- 根据 pod 的资源需求,筛选出符合条件的 worker 节点。
- 调度程序根据放置 pod 后所剩资源对节点进行排名,使用优先级函数将分数分配给节点。
可以自定义调度程序,后续将会详细说明。
cluster store (etcd)
Kubernetes 需要使用 key/value数据存储系统 Clustrer Store, 用于保存所有集群状态数据, 支持分布式集群功能。
通常为奇数个节点实现,如3,5,7等,节点间通过 raft 协议进行选举。
Kubernetes 当前使用etcd来实现集群数据存储功能,生产环境使用时需要为 etcd数据提供定期备份机制。
etcd 由CoreOS公司用GO语言开发,仅会同API Server交互。
master 多节点原因是因为etcd需要半数以上的节点正常才能运行,如3、5、7
etcd 资源要求参考:https://etcd.io/docs/v3.5/op-guide/hardware/
注意: 如果 etcd 单独出来,master 节点理论上可以不强制奇数。
cloud-controller-manager
cloud-controller-manager运行与基础云提供商交互的控制器。
cloud-controller-manager二进制文件是Kubernetes 1.6版中引入的alpha功能。
cloud-controller-manager允许云供应商的代码和Kubernetes代码彼此独立地发展。在以前的版本中,核心的Kubernetes代码依赖于特定于云提供商的代码来实现功能。在将来的版本中,云供应商专用的代码应由云供应商自己维护,并在运行Kubernetes时链接到云控制器管理器。
以下控制器具有云提供程序依赖性:
节点控制器:用于检查云提供程序以确定节点停止响应后是否已在云中删除该节点
路由控制器:用于在基础云基础架构中设置路由
服务控制器:用于创建,更新和删除云提供商负载平衡器
卷控制器:用于创建,附加和安装卷,以及与云提供商交互以编排卷
worker 组件(工作平面组件)
worker 组件在每个 worker 节点上运行,维护运行中的 pod ,并提供 kubernetes 运行时环境。
kubelet
kubelet 是运行 worker 节点的集群代理。
它会监视已分配给worker 节点的 pod,主要负责监听节点上 Pod 的状态,同时负责上报节点和节点上面Pod的状态。
负责与Master节点通信,并管理节点上面的Pod。
具体功能如下:
- 向 master 节点报告 worker 节点的状态
- 接受 master 的指令并在 pod 中创建容器
- 在 worker 节点执行容器的健康性检查
- 返回 pod 运行状态
- 准备 pod 所需的数据卷
kubelet 支持三个主要标准接口
- CRI:Container Runtime Interface,当前使用 Containerd 实现容器管理。
- CNI:Container Network Interface,Network Plugin通过此接口提供Pod 网络功能。
- CSI:Container Storage Interface,提供存储服务标准接口。
kube-proxy
kube-proxy 是运行在每个 worker 上的集群的网络代理,通过在主机上维护网络规则并执行连接转发来实现 Kubernetes 服务访问。
kube-proxy 专用于负责将Service资源的定义转为node本地的实现,是打通Pod网络在Service网络的关 键所在。
Kube-proxy 即负责Pod之间的通信和负载均衡,将指定的流量分发到后端正确的机器
有两种模式实现
- iptables模式:将Service资源的定义转为适配当前节点视角的iptables规则
- ipvs模式:将Service资源的定义转为适配当前节点视角的ipvs和少量iptables规则
范例:查看当前的模式
curl 127.0.0.1:10249/proxyMode
注意: 当使用了 Cilium 网络插件,kube-proxy 可以不需要了
Container Runtime
容器运行时是负责运行容器的软件
Kubernetes支持几种容器运行时:Docker, containerd,CRI-O专为Kubernetes以及Kubernetes CRI(容器运行时接口)的任何实现而设计的轻量级容器运行时。
附件 Addons
network 附件
网络插件,经由CNI(Container Network Interface)接口,负责为Pod提供专用的通信网络。
当前网络插件有多种实现,目前常用的CNI网络插件有calico和flannel,以及一个新的 Cilium 。
DNS 域名解析
虽然并非严格要求其他附加组件,但是所有Kubernetes群集都应具有群集DNS,因为许多示例都依赖 它。
除了传统IT环境中的DNS服务器之外,Kubernetes集群DNS 也是一个专用DNS服务器,它为 Kubernetes服务提供DNS记录。
由Kubernetes启动的容器会在其DNS搜索中自动包括此DNS服务器,目前常用DNS应用:CoreDNS,kube-dns。
外网入口
为服务提供外网入口,如:Ingress Controller,nginx,Contour,等
Web UI(Dashboard)
Dashboard仪表板是Kubernetes集群的通用基于Web的UI。它允许用户管理集群中运行的应用程序以及集群本身并进行故障排除。
组件间的安全通信
Kubernetes集群中有三套CA机制
- etcd-ca:ETCD集群内部的 TLS 通信
- kubernetes-ca:kubernetes集群内部节点间的双向 TLS 通信
- front-proxy-ca:Kubernetes集群与外部扩展服务简单双向 TLS 通信
相关名词
Pod
Pod是其运行应用及应用调度的最小逻辑单元、
本质上是共享Network、IPC和UTS名称空间以及存储资源的容器集
可将其想象成一台物理机或虚拟机,各容器就是该主机上的进程
各容器共享网络协议栈、网络设备、路由、IP地址和端口等,但Mount、PID和USER仍隔离
每个Pod上还可附加一个存储卷(Volume)作为该主机的外部存储,独立于Pod的生命周期,可由Pod内的各容器共享
模拟“不可变基础设施”,删除后可通过资源清单重建
具有动态性,可容忍误删除或主机故障等异常
存储卷可以确保数据能超越Pod的生命周期
在设计上,仅应该将具有“超亲密”关系的应用分别以不同容器的形式运行于同一Pod内部
Service
Pod具有动态性,其IP地址也会在基于配置清单重构后重新进行分配,因而需要服务发现机制的支撑
Kubernetes使用Service资源和DNS服务(CoreDNS)进行服务发现
Service能够为一组提供了相同服务的Pod提供负载均衡机制,其IP地址(Service IP,也称为Cluster IP)即为客户端流量入口
一个Service对象存在于集群中的各节点之上,不会因个别节点故障而丢失,可为Pod提供固定的前端入口
Service使用标签选择器(Label Selector)筛选并匹配Pod对象上的标签(Label),从而发现Pod仅具有符合其标签选择器筛选条件的标签的Pod才可
由Service对象作为后端端点使用
Workloads
Pod虽然是运行应用的原子单元,并不需要我们直接管理每个 Pod。
可以使用负载资源 workload resources 来替你管理一组 Pods。 这些资源配置 控制器 来确保合适类型的、处于运行状态的 Pod 个数是正确的,与你所指定的状态相一致。
其生命周期管理和健康状态监测由kubelet负责完成,而诸如更新、扩缩容和重建等应用编排功能需要由专用的控制器实现,这类控制器即工作负载型控制器
Kubernetes 提供若干种内置的工作负载资源:
- ReplicaSet和Deployment
- DaemonSet
- StatefulSet
- Job和CronJob
工作负载型控制器也通过标签选择器筛选Pod标签从而完成关联
工作负载型控制器的主要功能
- 确保选定的Pod精确符合期望的数量,数量不足时依据Pod模板创建,超出时销毁多余的对象
- 按配置定义进行扩容和缩容
- 依照策略和配置进行应用更新
Network model
- Kubernetes集群上默认会存在三个分别用于Node、Pod和Service的网络
- 三个网络 于worker节点上完成交汇
- 由node内核中的路由模块,以及iptables/netfilter和ipvs等完成网络间的流量转发
- 安装Kubernetes时,需要分别指定三个网络的网段地址
三个网络功能
-
节点网络
集群节点间的通信网络,并负责打通与集群外部端点间的通信
节点网络的IP地址配置在集群节点主机的物理接口上
网络及各节点地址需要于Kubernetes部署前完成配置,非由Kubernetes管理
因而,需要由管理员或借助于主机虚拟化管理程序实现
-
Pod网络
为集群上的Pod对象提供的网络
Pod网络 IP地址配置在Pod的虚拟网络接口上
每个pod 从此网络动态获取地址,且每次重启pod后IP地址可能会变化
虚拟网络,需要经由CNI网络插件实现,例如Flannel、Calico、Cilium等
使用某此CNI插件也可以支持和节点网络使用相同的网络
-
Service网络
主要用于解决 pod 使用动态地址问题
在部署Kubernetes集群时指定,各Service对象使用的地址将从该网络中分配
Service网络的IP地址并不配置在任何物理接口,而是存在于每个节点内核中其相关的iptables或ipvs规则中
由Kubernetes集群自行管理
Kubernetes网络中主要存在4种类型的通信流量
- 同一Pod内的容器间通信
- Pod间的通信
- Pod与Service间的通信
- 集群外部流量与Service间的通信
Pod网络需要借助于第三方兼容CNI规范的网络插件完成,这些插件需要满足以下功能要求
- 所有Pod间均可不经NAT机制而直接通信
- 所有节点均可不经NAT机制直接与所有Pod通信
- 所有Pod对象都位于同一平面网络中
分层架构
Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示
- 核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
- 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)
- 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)
- 接口层:kubectl命令行工具、客户端SDK以及集群联邦
- 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
- Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等
- Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等
扩展接口
Kubernetes 提供了三个特定功能的接口,kubernetes 通过调用这几个接口,来完成相应的功能。
-
容器运行时接口CRI: Container Runtime Interface
CRI 首次发布于2016年12月的Kubernetes 1.5 版本。
在此版本之前,Kubernetes 直接与 Docker 通信,没有标准化的接口。
从 Kubernetes 1.5 开始,CRI 成为 Kubernetes 与容器运行时交互的标准接口,使得 Kubernetes可以与各种容器运行时进行通信,从而增加了灵活性和可移植性。
kubernetes 对于容器的解决方案,只是预留了容器接口,只要符合CRI标准的解决方案都可以使用
-
容器网络接口CNI: Container Network Interface
kubernetes 对于网络的解决方案,只是预留了网络接口,只要符合CNI标准的解决方案都可以使用
-
容器存储接口CSI: Container Storage Interface kubernetes 对于存储的解决方案,只是预留了存储接口,只要符合CSI标准的解决方案都可以使用
此接口非必须