之前了解了k8s到底是什么,接下来看看k8s的组成。
一、Kubernetes架构
学习k8s,最终目的是为了部署应用,部署一个完整的k8s, 就要知道k8s的组成。k8s主要包含两大部分: 中间包含三个绿色包的是master服务器. 下面是node节点.
1、Master节点
master中有哪些东西?
1)api server
api server是所有服务访问的统一入口(所有请求的统一的入口).就是一起访问的入口. 从上图可以看出. Master中scheduler需要和api server交互, rc要和api server交互, kubectl(客户端)也要和api sever交互, web UI也要和api server交互, etcd也要和api server交互. apiserver是非常繁忙的.
api server采用的是无状态http请求,所以,他不会记录任何数据,所有数据都存储在etcd上。
Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver 设计上考虑了水平伸缩,也就是说,我们可以通过部署多个实例进行伸缩。 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。
2)scheduler
scheduler是任务调度器, 负责调度任务, 选择合适的节点来执行任务. 当用户下达资源请求的时候,任务调度器会把任务分配给后端的多个node节点上,要基于一定的原则,公平的,快速的分发。也就是说,保证每个节点都有事做,不要浪费资源,做到资源利用最大化。所以,scheduler调度区非常关键,他是保证整个集群资源利用高不高的核心组件。
举个例子,一个任务来了, 要部署一个应用,到底应该部署在哪个节点上呢? 这个过程就是通过scheduler进行任务调度的。有的机器繁忙,有的机器空闲,scheduler会找一台空闲的机器进行部署。通过scheduler进行任务调度分发至不同的node.
scheduler会将任务交给api server, 由api server将任务写入到etcd, 也就是说scheduler不会直接和etcd交互。
3)controller-manager
controller-manager: 控制器, 处理集群中常规后台任务,一个资源对应一个控制器。
举例来说,有一个订单服务,我们要部署这个服务,首先是交给任务调度器,任务调度器调用api server,将信息保存到etcd,etcd会创建一个controller-manager来专门管理这个订单服务。通常来说,一个资源对应一个控制器。
4)etcd:
etcd是键值对数据库, 存储K8s集群的所有重要信息(持久化). 在Kubernetes集群中起到的了持久化的作用. 对于etcd有两点说明:
- etcd官方将其定位为一个可信赖的分布式****键值存储服务, 它能够为整个分布式集群存储一些关键数据, 协助分布式集群的正常运转.
- etcd的版本
etcd现在有两个版本, v2和v3版本, v2版本将数据保存到内存, v3版本将数据保存到数据库. 正常我们都选择使用v3版本, 但Kubernetes v1.11版本之前使用的是v2版本.
- etcd内部架构图
- http Server: 这里采用的是使用http进行构建的c/s服务, k8s也是采用的http协议进行c/s服务的开发. 为什么要这么做呢? 因为http天生支持一系列的操作. 例如: get ,post, put, delete, 授权认证等. 所以, 没有必要再去采用标准的tcp协议. 开发一系列的认证流程, 所以, 直接采用http协议即可.
- Raft:共识算法,或者叫最终一致算法。比如:有3台etcd机器在运行的过程中,突然停了,那么3台etcd中的配置可能是不一样的,但是,一旦运行起来,经过一段时间,最终会达到一致。每一个Raft集群都包含多个服务器,在任意时刻,每一台服务器只可能处于Leader(主节点)、Follower(跟随者)、Candidater(竞选者)三种状态中的一种。在处于正常状态(可访问)时,集群中只会存在一个Leader,其余的服务器都是Follower。
是读写的信息, 所有的读写信息都被存在Raft里面, 而且, 为了防止这些信息出现损坏, 他还有一个WAL预写日志 - WAL: 预写日志, 吸入到数据库之前,先保存到日志里。如果要对数据进行更改, 那么先写入一条日志, 然后定时的对日志进行完整的备份. 也就是完整+临时. 比如: 我先备份一个大版本, 备份以后, 还会有1个子版本, 两个子版本....., 然后将这些版本再次进行一个完整备份,把它变成一个大版本. 这样做的好处, 我们不能始终进行完整备份, 因为消耗的数据量太大. 为什么还要在一定时间内进行完整的备份呢?防止增量备份太多, 还原的时候太费事. 并且, Raft还会实时的把这些数据和日志存入到本地磁盘进行持久化.
- Store: 试试把WAL中的日志和数据, 写入磁盘进行持久化.
5)kubectl
命令行管理工具。这个工具我们可以安装在任何节点上。通常,我们将其安装在master节点上。可以安装在安卓手机上,苹果手机上,windows电脑上,只要能够通过网络连接到api server,就能下发请求。
2、Node节点
从图中可以看出, Node节点包含三个组件 ,kubelet, kube proxy, 以及container. 也就是说我们在node节点需要安装三个软件: kebelet, kebu proxy, docker
1)kubelet的作用:
pod中安装的是docker容器,外层环境是k8s,docker和k8s能直接交互么?不能,一个是外国人,只会说英语,一个是中国人,只会说汉语。那如何让外国人和中国人交流呢?翻译呗。kubelet的作用就是连接k8s和docker的。kubelet监听api server,api server下发命令以后,kubelet要去调用docker,去执行指令,比如容器的创建。
直接跟容器交互, 实现容器的生命周期管理.他会和CRI, C是容器, R是runtime, I是interface. CRI就是docker的操作形式. kubelet会和docker交互, 创建需要的容器. kubelet会维持Pod的生命周期.
2)kube proxy的作用:
kube proxy监听者api server,api server发出请求以后,会调用linux的内核接口,叫做net link接口,这个接口允许我们通过接口调用的方式实现IPVS的创建,实现netfire的管控,就是IPVS和防火墙的管控。负载均衡和数据的转发都是基于kube proxy组件实现的。
负责写入规则至IPTABLES, IPVS实现服务映射访问. 之前说过svc, 可以进行负载操作, 负责的操作就是通过kube proxy完成的. 怎么实现Pod与Pod之间的访问, 以及负载均衡. 默认操作是操作防火墙, 去实现Pod的映射. 新版本还支持IPVS.
3、其他重要的插件
1)Web UI
Dashboard是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身并进行故障排除。
2) COREDNS
可以为集群中的SVC创建一个域名IP对应的关系解析. 也就是说,我们在集群中访问其他Pod的时候, 完全不需要通过Pod的ip地址, 通过CoreDns给他生成的域名去实现访问. 他是集群中的重要重要组件, 也是实现负载均衡的其中一项功能.
3)DASHBOARD
给K8S集群提供一个 B/S结构访问体系.
4)Ingress Controller
官方只为我们实现了四层代理. Ingress可以实现七层代理, 也就是可以根据组件名和域名进行负载均衡.
5)Federation
提供一个可以跨集群中心多K8s统一集群管理功能.
6)Prometheus(普罗米修斯)
提供K8S集群的监控能力.
7)ELK
提供k8s集群日志统一接入平台
二、K8S和docker的关系
为什么会说k8s和docker的关系呢?这还要源于k8s发布的一则消息,在后续版本将不再增加垫片这个组件。导致很多人觉得docker不行了,很可能会被k8s遗弃,为什么这个垫片会有这么大的影响呢?这就要从CRI和O-CRI说起了。
先来看看容器是如何创建的?
kubelet监听了server api,有任何的变化都会下发命令给docker,然后docker操作容器。那么,kubelet调用docker的时候,是使用命令还是调用接口呢?
肯定是直接调用接口。因为调用命令最终也是去执行接口,中间还转一步,效率太低了。
但是,kubelet能直接调用docker接口么?
我们知道docker采用的是CRI容器运行时接口,
而k8s是google的产品,现在是CNCF云容器基金会的产品,这是一个开源镜像,k8s会直接对接到CRI这样一个私有协议么?我是公共使用的,所以肯定不会对接到私有协议接口。那么,我会对接到O-CRI接口,这时一个共有协议接口。问题来了,docker是CRI私有协议接口,k8s是O-CRI共有协议接口,对接不过去啊。所以,怎么办?再加一层转换,这层转换的作用是承上启下,上面承的是O-CRI,下面承的是CRI。这个转换是在kubectl实现的。这一层被叫做垫片。承上启下用的。
最开始,Docker的名气要比k8s大的多得多,所以,k8s就承接了垫片的任务。而如今,k8s的名气已经很大了,它不再需要依赖于docker,于是他要去掉垫片。并且发了公告。
那么docker是不是就完蛋了,k8s没有垫片做转换了,就不能调用docker接口了。docker也很机智,随即发布消息,他会增加垫片功能。这样k8s依然可以调用docker容器。但是,我们要知道,docker就重了,k8s减负了,k8s可以兼容任何容器,现在市面上有好几款容器,他不是飞docker不可的了。