Kubernetes
自动化容器编排平台,基于容器的部署,弹性,管理做操作。
功能:
1. 调度:让容器去到其任意node节点进行工作。
2. 自动恢复:k8s有节点检查功能,当节点出现故障时,会自动将容器调度到其他正常节点运行。
3. 水平伸缩:当k8s检测到业务在节点上的占用率过高,就会将业务水平伸缩,扩展成多份,让其运行在不同的node节点上,达到负载均衡的效果。
K8s架构:二层架构.通过master对所有node节点进行操作。
Master的主要组件:
API Server:用于处理API操作,所有组件都依赖于API Server进行通信。
Controller(控制器):用于对集群状态的管理
Scheduler(调度器):用于完成调度操作。
Etcd:一个分布式存储系统。集群中的所有对象信息都以键值对的形式存储在etcd中。
Node:
在node里,可以运行多个pod,而pod中可以运行一个或者多个容器。
Node通过kubelet对pod进行管理,它通过API Server获取pod状态,然后提交到Container Runtime组件中,然后在OS上真正创建环境并且运行容器。
通过Storage Plugin来对存储进行操作,Network Plugin来对网络进行操作。
利用Kube-proxy来搭建组网。
例:用户提交pod,通过uri或者cri提交给API Server,然后会将信息写入etcd,然后会通过Scheduler进行调度决策,然后再通过APIserver将结果写到etcd中,然后才会通知节点进行真正的启动。
Pod:最小的调度以及资源单元
由一个或者多个容器组成
定义了容器的运行方式
提供给容器共享的运行环境
volume:
声明在pod中的容器可访问的文件目录。
可以被挂载在Pod中的一个容器的指定路径下。
支持多种后端存储的抽象。(本地,分布式,云存储)
Deployment
定义一组Pod的副本数,版本。
通过控制器(controller)维持Pod数目。还可以自动恢复失败的Pod
通过以指定的策略控制版本。例如滚动升级,重新升级,回滚等。
Service
提供一个或者多个Pod实例的稳定访问地址。
ClusterIP(仅限集群内部) NodePort(集群内外部) LoadBlancer(公网 / 外部网络)
Namespaces:一个集群内部的逻辑隔离机制。
同一个那么space中的资源命名唯一,不同可重名。
API相关基础:
HTTP+JSON/YAML
apiVersion: apps/v1 # 1API 版本:指定使用的 API 组及版本
kind: Deployment # 资源类型:定义要创建的资源对象是 Deployment
metadata: # 元数据:描述资源的身份信息
name: nginx-deployment # - 名称:该 Deployment 的唯一标识
labels: # - 标签:用于组织和选择资源的键值对
app: nginx
spec: # 期望状态 (Spec):你告诉 K8s "你想要什么"
replicas: 3 # - 副本数:期望运行 3 个 Pod 实例
selector: # - 选择器:决定哪些 Pod 受此 Deployment 管理
matchLabels:
app: nginx
template: # - Pod 模板:定义如何创建新的 Pod
metadata:
labels:
app: nginx # 这里的标签必须与上面的 selector 匹配
spec: # - Pod 的规格定义
containers:
- name: nginx # - 容器名称
image: nginx:1.14.2 # - 镜像:指定要运行的容器镜像
ports: # - 端口:容器暴露的端口
- containerPort: 80
总结:typeMeta:声明对象使用哪个API版本,哪个类型的对象
objectMeta:包括对象名称,使用的标签(metadata)
Spec:对象的期望状态,有对象的名称,使用的标签等。
Status:对象的状态,在对象被创建后可以看到,无需指定
API-labels:一组键值对。可以被select 所查询,资源集合的默认表达形式。
K8s可以看作操作系统,容器就相当于进程,pod就为进程组。
当一个程序由四个进程组成时,如何用容器跑起来?
在一个容器中启动四个进程,就会导致除开PID=1的进程外的三个进程会没有管理,在PID=1的进程错误退出后,其余三个进程无法被操作。
可以将PID=1的进程改为systemd,但这样也会造成应用无法被管理,应用挂掉无法得知情况。
使用POD作为原子调度单位,是因为当多个强相关容器启动时,遇到某一个节点无法全部部署,就会出现调度问题,导致应用启动失败。而POD对容器直接管理,就可以避免因节点内存限制的无法部署问题。
共享网络:
当一个pod产生时,就会有一个infra容器被创建,用作Pod内部的网络通信。
对K8s进行分层,可以通过组件:
在控制面上(Master):Etcd:作为保存集群的的后台数据库,支持watch,可以快速的到变化从而响应和协调工作。
Kube-apiserver:提供k8s的API,提供对pods,services等对象的CRUD处理REST操作。
Kube-scheduler:(通过binding API)负责pods在各个节点上的分配。由于时插件式的,可以自定义。
kube-controller-manager:控制器循环监听集群资源状态,将对应资源牵引成期望状态。
节点上(Node):kubelet:管理pods和他们的容器,镜像,卷等。
Kube-proxy:简单的网络代理及负载均衡器。
用户通过kubectl命令提交期望状态,kubectl解析yaml,发给API server,API server做认证,授权,校验,然后创建对象,API server同时也将Deployment的期望存入etcd,Controller Manager创建ReplicaSet(副本数)。Scheduler调度Pod到节点。kubectl创建并启动pod。
Api-server通过Master节点上的kube-apiserver进程提供服务,是各个功能模块之间数据交换和通信的中心枢纽。API server的性能决定了集群的性能。
Etcd是一个分布式字典类的存储系统,提供原始数据的存储。拥有接口简单(客户端或者http访问),数据表示简单,方便数据订阅(watch)。
Controller Manager主要提供一个分发事件的能力,在k8s中每个controller是一个控制回路,通过APi server监视资源状态,确保与spec的期望接近。通过实现方式分为:内置,外置控制器。不同的controller只需要注册对应的Handler来等待接受和处理时间。(contoller manager的职责就是把所有controller聚合起来。)
Schduler是默认调度器,把创建的pod调度到具体的工作节点上。具体工作流程为,infomer组件watch APiserver,同步etcd中的pod信息变化,将未调度的pod信息加入队列中,同时更新scheduler cache缓存,获取node列表。预选阶段,针对pod和node列表执行predicate算法,过滤掉不合适的节点。优选阶段,针对pod和node列表执行Priority算法,计算得分最高节点,当调度器选择了一个合适的节点,通过Bind将pod进行绑定。
Kubelet用于处理master节点下发到本节点的任务。管理pod以及pod中的容器。核心就是一个控制循环
Kube-proxy是一个简单的网络代理组件,他的作用主要是负责service的实现。原理是,每个节点运行一个kube-proxy服务,监听API server中的service,endpoint(访问地址),node变化情况。Kube-proxy可以根据监听资源的变化,操作后端服务来为服务配置负载均衡。模式有iptables/ipvs。
List-watch(异步消息处理机制)机制的作用是减少请求,降低压力。List主要用于查询(http短链接),watch用于监听(http长连接)。可以保证消息可靠性(将查询的资源状态与预期进行对比),实时性(资源状态改变就会推送消息),顺序性(通过resourceVersion的递增来确认顺序),以及高性能(异步)。
Watch通过http长连接收发资源来变更事件,利用分块传输编码来实现。将数据分解成一个或多个块发送。普通的长连接需要知道发送了多长的数据来判断何时可以断开链接。在动态生成的情况下,总大小不知,所以拆分成一块一块的,有就发。客户端会先收到一个块大小的消息,然后才会收到数据。直到块大小为零才会结束。
控制器架构流程:kubectl创建Deployment,APIserver将Deployment存入Etcd,APIserver上报Deployment creat事件。Deployment控制器通过list-watch收到事件。Deployment控制器创建ReplicaSet,APIserver将Replicaset存入Etcd。APIserver上报上报ReplicaSet creat事件。ReplicaSet控制器通过list-watch收到事件。Replicaset控制器创建pod。APIserver将pod存入Etcd,APIserver上报Pod craet事件。Scheduler通过通过list-watch收到事件。Scheduler更新pod,绑定目标节点。APIserver同步更新pod到etcd,APIserver上报Pod Bound事件。
目标节点的kubelet通过list-watch收到事件。
K8s笔记
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法