咱们从 pod 一直分享到最近的 Statefulset 资源,到现在好像我们只是知道如何使用 k8s,如何按照 k8s 设计好的规则去应用,去玩 k8s
仔细想想,对于 k8s 自身的内在原理,我们好像还不是很清楚,对于每一个资源背后是如何实现的,我们好像也不得而知
或许也就只知道 k8s 是 golang 写的吧
我认为咱们学习一项技能,一项知识点的学习顺序应该是
- 学习如何应用,培养自己感觉和兴趣
- 学习应用背后的内在原理,知晓其细节
- 能够对其原有功能做二次开发,加入自己的理解
前面基本分享了所有资源的使用方式以及实战,今天开始,我们来逐步了解和分享 k8s 内在自身原理
k8s 基本架构
学习 k8s 的时候,若一开始就学 k8s 的架构和组成,其实吸收的东西会比较少,自己的对于这项技术也没有啥概念,当然这也是一个熟悉的过程,慢慢学着会使用了,再来了解和学习他的原理,效果会更好
k8s 中分为 主节点 master 和 工作节点 worker
我们可以是 1 个 master ,也可以是多 master 的
一般 master 节点会有如下 4 个核心组件:
- etcd ,用作持久化存储
- Api Server,提供各种 Restful Api
- sheduler 调度器
- controller manager 控制器管理器
woker 节点一般会放这几个组件:
- kube-proxy kubelet 服务代理
- kubelet
- 实际的服务对应的容器
从上图我们就可以知道,k8s 中所有的主控都是 master 节点来进行控制的,实际运行的容器是运行在工作节点上面的
通过上图我们还可以知道,对于 访问和修改 etcd,只有 Api Server 才能够直接去交互,其他的组件都是不能直接访问的
如何在 k8s 中查看上述组件的状态呢?
我们可以使用 kubectl get componentstatuses
即可查看到 k8s 集群中的组件状态,我们也可以写缩写,例如 kubectl get cs
我的当前环境是 minikube,可以暂时可以先不用关注截图中的 error 信息
是不是会有点纳闷,说好的这么多组件,咋没有看到 ApiServer 呢?
都在下面了,我们可以使用 kubetl get po -n kube-system
查看 kube-system 命名空间下的 pod,我们就可以看到关于 apiserver,etcd,controller-manager,kube-proxy,scheduler 等信息了
同样的,我们也可以把这些当成普通的 pod 一样,咱还是可以使用 kubectl describe
或者 kubectl edit
等指令来操作他们
例如:
我们可以尝试命令kubectl edit po etcd-minikube -n kube-system
,来查看到 etcd-minikube 的信息
注意,这里一定需要加上 -n kube-system
指定命名空间 ,因为当前我们默认的 命名空间是 default ,如果不在命令中指令命名空间,则 k8s 会去默认的命名空间查找 pod
如果不指定命名空间,那么 k8s 在 default 默认命名空间中找不到 etcd-minikube 这个 pod
我们可以看到,系统组件 etcd,其实在 k8s 运行环境中也是一个正常的 Pod ,我们可以从 pod 清单中可以看到 kind: Pod
spec 中具体的定义,使用了 k8s.gcr.io/etcd:3.5.0.0-0 版本的镜像,以及 启动 改容器,需要自行的命令和参数等等
那么 k8s 的 etcd 是干啥的?
还记得 etcd 我们在微服务开发时候,仅仅是用于存放 key-value 键值对的,那么 k8s 里面又是如何使用 etcd 的呢?
k8s 中的 etcd,是环境中唯一存储集群状态和元数据的地方,相当重要哦
k8s 中的 etcd 是用来存储 k8s 中每个资源清单信息的,例如 pod,RC,Service,私钥,持久化方式等等,呈现方式也是 键值对
并且在 k8s ,如果 1 个 etcd 不够用了,我们也是可以横向扩容,运行多个 etcd 的实例就可以了
前面我们也提到了,在 k8s 中的各个系统组件,只能通过 ApiServer 进行通信,另外 ApiServer 是和 etcd 通信的唯一组件,也就是说 ApiServer 是 etcd 的唯一客户端,其他的组件是没有办法修改 etcd 里面的数据的
这是为什么呢?所有组件都要通过 ApiServer 才能访问和 修改 etcd,这样做是有啥好处呢?
好处 1 :
可以增强 k8s 验证系统的健壮性,来源只有 1 个,简单清晰
好处 2 :
就只有 etcd 和 Apiserver 交互,不存在其他组件的耦合,那么替换存储机制也是比较方便的
好处 3 :
k8s 中多 master 的时候,仍然适用于 控制平台操作存储模块的时候,同样是需要通过和 ApiServer 交互,这样咱们的 k8s 集群状态才会总是一致的
k8s 的 Apiserver 具体是做了哪些事情呢?
简单来说 Apiserver 组件主要就是提供 RESTful API ,接收其他组件的请求,对请求的数据做校验,并将请求给到 etcd
例如,查询集群状态,修改 pod ,删除 RS ,创建指定资源等等
细心的 xdm 应该就可以发现,我们是如何访问 ApiServer 的呢?ApiServer 的客户端又是谁呢?
是滴,就是我们一直都在使用的 kubectl,一直以来,我们都在使用 kubectl 来和 ApiServer 进行通信,那么是否会有这样的疑问:
我多开几个 master 的窗口,同时使用 kubectl 创建会有冲突的资源,那么 ApiServer 会如何处理呢?
这一点,xdm 大可放心, ApiServer 自身会有一致性的机制,
第一,就是 ApiServer 是唯一和 etcd 通信的客户端
第二,ApiServer 自身还会处理乐观锁,会保证最终一致性,在并发更新资源的情况下,A 对对象做的更改不会去覆盖 B 对对象做的更改
那么其他组件访问 ApiServer 的时候,ApiServer 内部处理流程是什么样的呢?
- ApiServer 会去校验客户端是否通过认证
- ApiServer 会去校验客户端是否通过授权
- ApiServer 会去校验客户端是否通过准入插件的验证(对资源进行创建,删除,编辑的时候会校验)
- 若以上都通过了,那么 ApiServer 会将数据给到 etcd,并给客户端做响应
用一个图展示,可以是这样的:
那么 ApiServer 又是如何通知 客户端资源变更的?
你可能会认为是 ApiServer 自己去控制和通知具体的控制器去做事情,并不是的,其实是通过 k8s 内部的监听机制,如图:
当 ApiServer 收到客户端的请求时,ApiServer 校验完成后去更新 etcd,最终会启动对应的控制器,客户端自己会做监听,收到监听的变更信息之后,就会去对应的更新对象了
今天就到这里,学习所得,若有偏差,还请斧正
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~
更多的可以查看 零声每晚八点直播:https://ke.qq.com/course/417774