云原生学习路线导航页(持续更新中)
- kubernetes学习系列快捷链接
- Kubernetes架构原则和对象设计(一)
- Kubernetes常见问题解答
本文从云计算架构发展入手,详细分析了kubernetes的生态系统、设计理念、分层架构、API设计原则、架构设计原则等,并介绍了使用kubelet+staticPod拉起集群的过程
1.云计算的传统分类
- 云计算出现之前,对于任何企业,想要搭建自己的服务,需要管理所有内容
- 基础架构层:网络、存储、 服务器。有了服务器,可能需要进一步做虚拟化,分成很多个虚拟机
- 支撑服务层:虚拟机上安装操作系统O/S,中间件、各种运行时。
- 应用层:应用、应用产生的数据
- 后来出现了云计算的思想,传统分类中将云计算分为以下几种
- Issa:云厂商提供基础架构层,其余的客户自己负责
- Pass:云厂商提供基础架构层+支撑服务层,其余的客户自己负责
- Saas:云厂商提供基础架构层+支撑服务层+应用层,客户只需要使用就好
- 比如 Oracle、一些ERP软件、腾讯会议软件等,都属于Saas产品,某个公司直接买了软件,给你账号密码,就可以直接用了,其他不用管
- Kubernetes出现之后,云计算的各个层次 不再有这么清晰的界限
- kubernetes提供了一套统一的API,这套API既有 基础架构的运维,又有应用软件的接入,因此模糊了层次间的界限
- 容器提供Dockerfile让应用接入,Kubernetes提供所有自动化的操作,二者可以认为是Pass
2.Kubernetes生态系统
- 基础架构管理
- 要有集群,肯定要先有主机,因此涉及到主机上架
- 机器有了,要安装和管理OS,管理安全、网络、运行时等
- 集群管理
- 基础架构层面能管理了,就需要把机器构建成集群,因此有了集群的安装、节点管理、认证授权、网络存储等等的管理
- 控制平面
- kubernetes的管控面组件:master上的、node上的、插件等
- 数据平面
- kubernetes面向应用的各种API对象,供用户来跑应用,API对象创建出来后,由管控面来管理
- kubernetes的两个视角
- 集群管理员:
- 负责控制面组件的稳定性、可用性
- 负责提供具备各种特性的服务,供应用开发者使用,比如提供日志、监控、告警等能力、统一的镜像仓库、网络管理、dns、流水线等
- 应用开发者
- 关注自己所要开发的代码,代码开发完要有自动化流水线打包镜像,进行持续集成,有镜像仓库存储镜像,有部署流水线做部署
- 应用部署时,需要应用开发者关注部署时的一些参数
- 应用的资源需求:多少cpu、mem、几个实例、带宽多少
- 应用的高可用:跨地域、跨az部署等
- 微服务世界里,可能还涉及多个服务之间的依赖关系
- 服务的扩缩容,服务发现、服务发布等等
- 集群管理员:
3.Kubernetes设计理念
- 高可用
- 应用高可用:应用最根本的就是高可用,尤其对于在线服务,因此kubernetes提供了大量的API对象来确保应用高可用。包括 replicaset、statefulset等
- kubernetes组件自身高可用:通过一些机制保证每个组件都支持高可用
-
- 安全性
- 通信加密:TLS协议
- 灵活的认证鉴权 : 对于kubernetes内部有系统账户SA,对于外部系统有user,支持基于SA和User的认证鉴权
- 良好的隔离性:基于namespace隔离,并支持针对不同namespace的权限控制,谁能访问该ns下对象,能如何访问,都可以控制
- 数据加密:secret
- 数据面安全保证:
- 通过Taints将不同node做隔离,可以让不同应用在物理机层面做隔离
- psp:Pod Security Policies,可以设置以什么样的权限运行这个pod
- Pod Security Policies官方文档:kubernetes1.21中弃用了
- Pod Security Policies基础使用
- networkPolicy:可以控制a可以访问b的哪个端口…
- 安全性
-
- 可移植性
-
- 可扩展性
4.Kubernetes的分层架构
kubernetes的分层架构确保了它的扩展性,确保了它的江湖地位
- 核心层:提供核心API,提供插件扩展能力
- 应用层:提供针对不同应用的各种特性,提供路由能力,服务发现、负载均衡等
- 管理层:为应用提供更高级的隔离性、安全性、资源配额等特性
- 接口层:供其他系统的对接
- 生态系统:针对不同层次,都形成了相应的生态系统
- 针对核心层的下层,有各种Plugin形成的生态系统
- CRI:docker、containerd等
- CNI:calico、flannel、cilium等
- CSI:localDisk、networkDisk、nfs等
- 针对核心层和应用层,也形成了以Operator为中心的生态系统,并支持Istio、addon扩展等
- 针对上层,有Helm工具、Kompose、Cabin等形成的生态系统
- 针对核心层的下层,有各种Plugin形成的生态系统
5.API设计原则
- 声明式API 允许重复操作:比如网络抖动,上次处理了一半,下次还可以再处理一次,最终处理结果是一致的,这对分布式太重要了
- API彼此互补和可组合:这个就解答了为什么Deployment不直接管理pod,而是通过ReplicaSet管理,二者负责的功能特性不同
- 高层API以业务为出发点进行设计,底层API是为了满足某个或某些高层API而设计
- 避免简单封装,一个API对象要有自己确定的含义,不要通过代码逻辑让他具备完全不同的两种功能
6.Kubernetes对象之间的组合关系
- Kubernetes如何通过对象的组合完成业务描述
- 只要业务有持续的发布和更新行为,就应该使用deployment,而不是直接使用replicaset
- 如上图,不同对象的组合方式,可以分成三种
- 引用依赖:比如pod中有一个属性的值,指向了某个对象。比如pod的nodeName,声明了它要调度到的node;ingress中有个serviceName指向某个service
- 基于命名规范:比如deployment和replicas的名字,是deploymentName+hash值的关系,这种关系写在代码程序里。这种规范要非常小心,如果这段代码有变更,有一定风险打破原来的命名规范,造成致命bug
- 基于标签:比如ReplicaSet和pod之间的关联关系,是通过
selector.matchLabels
做关联的。Service和pod的关联关系也是这种方式。
7.架构设计原则
- 所有组件都在内存中维护状态,指的是 组件应该自己维护一份缓存,通过watch维护缓存数据的一致性,不要任何数据都去请求apiserver。比如calico没有遵循这个规范,在数据量很大的集群中,就有可能把apiserver打挂
8.Kubernetes集群搭建的设计:引导原则
- Selft-hosting:即自己能够管理自己,没有外部依赖,不过很难做到,这是一个系统的设计目标
- kubernetes 管控组件,其实都将自身容器化,用pod运行来保证自身的高可用。实际上也是实现了自己管自己
- 在kube-system ns下,可以看到 控制平面的
etcd、apiserver、controller-manager、schedule
组件都是用 pod 运行的
- 实现方式:
- kubelet本身是不能容器化的,因为它要作为kubernetes的初始化系统,负责把master上管控组件拉起来。启动pod方式:staticPod
- 查看kubelet的配置文件,其中有
staticPod的路径
,kubelet除了会从apiserver处得知要启动的pod,还会监听staticPod路径
下所有文件,将其拉起为pod
- 因此,实践中一般将kubelet配置为systemd,即守护进程。然后由kubelet将 kubernetes的管控组件拉起来。
- 我们经常使用 kubeadm 搭建一个kubernetes集群,其实就是使用了Static pod
- staticpod不依赖完整的kubernetes集群,只需要有kubelet+容器运行时,就可以在所在节点,把容器运行起来,因此staticpod最经典的场景就是 作为kubernetes集群的bootstrap
- 在kube-system ns下,可以看到 控制平面的