k8s 是什么?
k8s 介于应用和服务器之间,能够通过配置协调多个应用服务。使用者通过配置 yaml
文件来将多个服务自动部署应用到各个服务器上,实现服务的自动扩缩容,并且具有高可用性(某台机器上服务宕机后,自动在另外的服务器上部署应用)。
k8s 架构原理
k8s 整体分为控制平面和运行节点,控制平台负责控制和管理各个 Node,Node 负责实际运行各个应用服务。
控制平面内部结构
API-Server
:提供给用户操作的 API 接口;Scheduler
:根据各服务器的负载情况,选择合适的 Node 节点部署应用;Controller Manager
:启动/关闭应用服务;etcd
:存储上述操作过程中的应用数据;
Node 内部结构
Node 可以是单独的应用服务器或者虚拟机,单个 Node 上可以运行多个应用服务,多个应用服务共享 Node 的内存和 CPU 等计算资源。
部署应用时,只需要将应用程序打包成容器镜像(镜像可以理解为应用代码+依赖的操作系统环境)。在任意一台机器上解压该压缩包就可以部署该服务。
container Runtime
:容器运行时组件;log container
:搭配容器使用,日志收集;monitor container
:监控采集器;kubelet
:管理和监控 Pod;kube Proxy
:网络通信功能,使得外部请求能够转发到 Pod 中;
上述多个容器组成一个 Pod,Pod 运行在 Node 上。K8s 可以将一个 Pod 从一个 Node 迁移到另外一个 Node 中实现 Node 间的负载均衡。Pod 是 K8s 中最小的调度单位。
Cluster 集群
控制平台和多个 Node 共同构成了一个集群,我们一般会构建多个集群(比如生产集群和测试集群)。同时为了将集群内部服务暴露给外部服务,还会提供一个 Ingress
控制器,它可以提供一个入口,让集群外部服务访问内部服务。
服务部署全过程
kubectl
:部署服务时不需要用户再手动编写代码,而是通过kubectl
命令行工具调用 k8s 内部 API。
服务部署步骤:
- 编写
YAML
文件,内容包括部署哪些镜像,每个镜像占用的内存和 CPU 等信息。
- 使用
kubectl
工具部署,命令为kubectl apply -f xxx.yaml
;kubectl 将解析 yaml 文件,并将解析后的对象发送给k8s-ApiServer
,ApiServer
会驱使Scheduler
通过etcd
提供的数据寻找合适的 Node; - 寻找到合适的 Node 后,再向 Node 内部的
kubelet
发送命令请求,kubelet
收到请求后驱使内部的container Runtime
去拉去镜像创建容器,最终完成 Pod 的创建。
服务调用全过程
- 用户访问外部 http 浏览器;
- 请求打到
Ingress控制器
,请求打到某个 Node 的kube-Proxy
上然后转发到 Pod 的内部服务中; - 随后处理结果原路返回,完成一次服务调用。
kubernetes 核心组件
node
:k8s 中一个节点(node
可以是物理机或虚拟机),一个 node 包含一个或多个 pod;pod
:是 K8s 的最小调度单元,是一个或多个容器的组合。它创建了容器的运行环境,在环境中容器可以共享资源(网络/存储/文件)。我们常说的边车模式sidecar
就是将应用容器和一些辅助容器(日志收集、服务监控)放到一个 pod 中。
- pod 不是稳定的,如果某个 pod 出现故障,k8s 会自动删除销毁该 pod。为了解决这个问题,引入了 svc,应用程序容器直接请求 svc 获取服务IP地址,由 svc 实现反向代理,即使某 service 出现故障,svc 的地址也不会改变,svc 会自动将请求转发到健康的 pod 上。
Service
:将一组 pod 封装为一个服务,并提供统一的入口来访问这个服务。服务分为内部服务和外部服务,内部服务指不暴露给外部的服务(MySQL、MQ、Redis...),可以通过node:port
将 node 节点端口映射到 ServiceIP、ServicePort 上,这样通过节点来访问服务。但是实际生产环境下不能这样使用,需要另一个组件Ingress
。Ingress
:路由转发请求,将请求转发到集群内部的Service
上,它配置了不同的转发规则进行请求转发,这样就能通过域名访问不同 Service 的后端不同 Pod;
ConfigMap
:应用程序和其依赖组件存在配置上的耦合,比如我们在应用程序中定义配置文件,那么当配置文件修改时需要重新启动部署应用程序,对于一些不能下线的业务显然是不行的。k8s 引入了ConfigMap
结构,该结构定义了应用程序的配置信息。配置更改时只需要更新ConfigMap
结构,然后重新加载 pod 即可,不需要重新编译和部署应用程序。实现了应用程序和依赖组件间的解耦操作。
-
Volumes
:持久化存储容器数据到磁盘等设备。 -
Deployment
:为保证服务高可用,将整体服务部署到多个节点上,利用Depolyment
组件实现多副本服务的复制和管理;而数据库等组件不使用Depolyment
组件来实现多副本,因为这些组件涉及到多副本之间数据的一致性等问题,一般使用sts(StatefulSet)
组件来管理 。 -
StatefulSet
:部署有状态服务应用程序,管理其副本,将一个或多个 pod 集中在一起,并且具有副本控制、滚动更新、自动扩缩容等特性。 -
api-server
:接收客户端请求,对请求者身份等信息验证,转发请求到具体 Node处理; -
Scheduler
:监控集群中所有节点的资源使用情况,根据一些调度策略,将 Pod 调度到合适的节点上运行。比如新增一个 Pod,调度器会优先将 Pod 加入到资源最多的节点上; -
Controller Manager
:控制器管理器,负责管理集群中各资源对象的状态。 -
etcd
:存储集群中所有资源的数据、状态,但是它一般不存储应用程序中的数据(比如 Mysql数据)。
kubernetes 架构
工作节点 worknode
一般包含以下组件:
cotainer-runtime
:容器运行时,处理容器初始化、镜像拉取、启动停止容器;- 常见的
container-runtime
有:Docker-Engine
;Containerd
;CRI-O
;Mirantis Container Runtime
;
- 常见的
kubelet
:管理并维护每个 pod,定期接收新的或修改后的 Pod 规范;监视容器运行情况,并定期汇报给api-server
;kube-proxy
:为 pod 提供网络代理、负载均衡服务;通过负载均衡策略将请求转发到具体的 Node 节点上,Node 再定位到具体的 Service,Service 请求具体 Pod 开始处理。