kubernetes简介

k8s简介

​ Kubernetes是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。Kubernetes拥有一个庞大且快速增长的生态系统。Kubernetes的服务、支持和工具广泛可用。

一、k8s简介

    Kubernetes是一个全新的基于容器技术的分布式领先方案。简称:K8S。它是Google开源的容器集群管理系统,它的设计灵感来自于Google内部的一个叫作Borg的容器管理系统。继承了Google十余年的容器集群使用经验。它为容器化的应用提供了部署运行、资源调度、服务发现和动态伸缩等一些列完整的功能,极大地提高了大规模容器集群管理的便捷性。
    kubernetes是一个完备的分布式系统支撑平台。具有完备的集群管理能力,多扩多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和发现机制、內建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制以及多粒度的资源配额管理能力。
    在集群管理方面,Kubernetes将集群中的机器划分为一个Master节点和一群工作节点Node,其中,在Master节点运行着集群管理相关的一组进程kube-apiserver、kube-controller-manager和kube-scheduler,这些进程实现了整个集群的资源管理、Pod调度、弹性伸缩、安全控制、系统监控和纠错等管理能力,并且都是全自动完成的。Node作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的kubelet、kube-proxy服务进程,这些服务进程负责Pod的创建、启动、监控、重启、销毁以及实现软件模式的负载均衡器。
    在Kubernetes集群中,它解决了传统IT系统中服务扩容和升级的两大难题。如果今天的软件并不是特别复杂并且需要承载的峰值流量不是特别多,那么后端项目的部署其实也只需要在虚拟机上安装一些简单的依赖,将需要部署的项目编译后运行就可以了。但是随着软件变得越来越复杂,一个完整的后端服务不再是单体服务,而是由多个职责和功能不同的服务组成,服务之间复杂的拓扑关系以及单机已经无法满足的性能需求使得软件的部署和运维工作变得非常复杂,这也就使得部署和运维大型集群变成了非常迫切的需求。
    Kubernetes的出现不仅主宰了容器编排的市场,更改变了过去的运维方式,不仅将开发与运维之间边界变得更加模糊,而且让DevOps这一角色变得更加清晰,每一个软件工程师都可以通过Kubernetes来定义服务之间的拓扑关系、线上的节点个数、资源使用量并且能够快速实现水平扩容、蓝绿部署等在过去复杂的运维操作。

1、架构

    Kubernetes遵循非常传统的客户端服务端架构,客户端通过RESTful接口或者直接使用kubectl与Kubernetes集群进行通信,这两者在实际上并没有太多的区别,后者也只是对Kubernetes提供的RESTfulAPI进行封装并提供出来。每一个Kubernetes集群都由一组Master节点和一系列的Worker节点组成,其中Master节点主要负责存储集群的状态并为Kubernetes对象分配和调度资源.

1)Master

​ 它主要负责接收客户端的请求,安排容器的执行并且运行控制循环,将集群的状态向目标状态进行迁移,Master节点内部由三个组件构成:

① API Server
    负责处理来自用户的请求,其主要作用就是对外提供RESTful的接口,包括用于查看集群状态的读请求以及改变集群状态的写请求,也是唯一一个与etcd集群通信的组件。
②ControllerManager
    管理器运行了一系列的控制器进程,这些进程会按照用户的期望状态在后台不断地调节整个集群中的对象,当服务的状态发生了改变,控制器就会发现这个改变并且开始向目标状态迁移。
③Scheduler
    调度器其实为Kubernetes中运行的Pod选择部署的Worker节点,它会根据用户的需要选择最能满足请求的节点来运行Pod,它会在每次需要调度Pod时执行。

2)Node节点

    Node节点实现相对简单一点,主要是由kubelet和kube-proxy两部分组成:

    kubelet是一个节点上的主要服务,它周期性地从APIServer接受新的或者修改的Pod规范并且保证节点上的Pod和其中容器的正常运行,还会保证节点会向目标状态迁移,该节点仍然会向Master节点发送宿主机的健康状况。

    kube-proxy负责宿主机的子网管理,同时也能将服务暴露给外部,其原理就是在多个隔离的网络中把请求转发给正确的Pod或者容器。

3)架构图

flannel网络图

功能:
    让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。但在默认的Docker配置中,每个Node的Docker服务会分别负责所在节点容器的IP分配。Node内部得容器之间可以相互访问,但是跨主机(Node)网络相互间是不能通信。Flannel设计目的就是为集群中所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得"同属一个内网"且"不重复的"IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。

原理:
    Flannel 使用etcd存储配置数据和子网分配信息。flannel 启动之后,后台进程首先检索配置和正在使用的子网列表,然后选择一个可用的子网,然后尝试去注册它。etcd也存储这个每个主机对应的ip。flannel 使用etcd的watch机制监视/coreos.com/network/subnets下面所有元素的变化信息,并且根据它来维护一个路由表。为了提高性能,flannel优化了Universal TAP/TUN设备,对TUN和UDP之间的ip分片做了代理。

工作流程:
    1、数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。

    2、Flannel通过Etcd服务维护了一张节点间的路由表,该张表里保存了各个节点主机的子网网段信息。

    3、源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一样的由docker0路由到达目标容器。

核心组件介绍

Master节点

组件名称 作用
apiserver(资源操作调度中心) 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
etcd(数据存储) 保存了整个集群的状态;
schedule(资源调度器) 负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
controller manager(控制管理器) 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;

Node节点

组件名称 作用
kubelet(部署、监控、维护容器) 负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
kube-proxy(负载、网络、服务发现) 负责为Service提供cluster内部的服务发现和负载均衡;

其他组件

组件名称 作用
flannerl 提供了集群间的网络
kube-dns 负责为整个集群提供DNS服务
lngress Controller 为服务提供外网入口
Heapster 提供资源监控
Dashboard 提供GUI
Federation 提供跨可用区的集群
Fluentd-elasticsearch 提供集群日志采集、存储与查询
rancher k8s管理工具

4)命令运行过程

1、kubectl发送了一个部署nginx的任务
2、进入Master节点,进行安全认证,
3、认证通过后,APIserver接受指令
4、将部署的命令数据记录到etcd中
5、APIserver再读取etcd中的命令数据
6、APIserver找到scheduler(调度器),说要部署nginx
7、scheduler(调度器)找APIserver调取工作节点数据。
8、APIserver调取etcd中存储的数据,并将数据发给scheduler。
9、scheduler通过计算,比较找到适合部署nginx的最佳节点是node1,发送给APIserver。
10、APIserver将要部署在node1的计划存储到etcd中。
11、APIserver读取etcd中的部署计划,通知node1节点的kubelet部署容器
12、kubelet根据指令部署nginx容器,kube-proxy为nginx容器创建网桥
13、容器网桥部署完成后,kubelet通知APIserver部署工作完成。
14、APIserver将部署状态存储到etcd当中,同时通知controller manager(控制器)有新活了
15、controller manager向APIserver要需要监控容器的数据
16、APIserver找etcd读取相应数据,同时通知kubelet要源源不断发送监控的数据
17、APIserver将kubelet发送来的数据存储到etcd当中
18、APIserver将etcd的数据返回给controller manager
19、controller manager根据数据计算判断容器是否存在或健康

二、kubernetes带来的变革

1、对于开发人员

    由于公司业务多,开发环境、测试环境、预生产环境和生产环境都是隔离的,而且除了生产环境,为了节省成本,其他环境可能是没有日志收集的,在没有用k8s的时候,查看线下测试的日志,需要开发或者测试人员,找到对应的机器,在找到对应的容器,然后才能查看日志,在用了k8s之后,开发和测试可以直接在k8s的dashboard到对应的namespace,即可定位到业务的容器,然后可以直接通过控制台查看到对应的日志,大大降低了操作时间。

    把应用部署到k8s之后,代码的发布、回滚,以及蓝绿发布、金丝雀发布等都变得特别简单,不仅加快了业务代码迭代的速度,而且全程无需人工干预。目前我们使用jenkins、gitrunner进行发版或者回滚等,从开发环境到测试环境,到生产环境,完全遵守一次构建,多集群、多环境部署,通过不同的启动参数、不同的环境变量、不同的配置文件实现区分不同的环境。目前已经实现Python、Java、PHP、NodeJS、Go、.NETCore、Python等多种语言的一键式发版、一键式回滚,大大提高了开发人员的开发效率。

    在使用服务网格后,开发人员在开发应用的过程中,不用再关心代码的网络部分,这些功能都被服务网格实现,让开发人员可以只关心代码逻辑部分,即可实现网络部分的功能,比如:断流、分流、路由、负载均衡、限速和触发故障等功能。

    测试过程中,可能同时多套环境,当然也会需要再创建一套测试环境,之前测试环境的创建,需要找运维或者自行手工搭建。在迁移至k8s集群后,只需要在jenkins上点点鼠标即可在k8s集群上创建一套新的测试环境。

2、对于运维人员

    如果你是一名运维人员,可能经常因为一些重复、繁琐的工作感觉厌倦。比如:这个需要一套新的测试环境,那个需要一套新的测试环境,之前可能需要装系统、装依赖环境、开通权限等等。而如今,可以直接用镜像直接部署一套新的测试环境,甚至全程无需自己干预,开发人员通过jenkins或者自动化运维平台即可一键式创建,大大降低了运维成本

    一开始,公司业务故障,可能是因为基础环境不一致、依赖不一致、端口冲突等等问题,现在实现Docker镜像部署,k8s编排,所有的依赖、基础都是一样的,并且环境的自动化扩容、健康检查、容灾、恢复都是全自动的,大大减少了因为这类基础问题引发的故障。也有可能公司业务是由于服务器宕机、网络等问题,造成服务不可用,此类情况均需要运维人员及时去修复,而如今,可能在你收到告警信息的时候,k8s已经帮你恢复了

    在没有使用k8s时,业务应用的扩容和缩容,都需要人工去处理,从采购服务器、上架、到部署依赖环境,不仅需要大量的人力物力,而且非常容易在中间过程出现问题,又要花费大量的时间去查找问题。成功上架后,还需要在前端反代端添加或该服务器,而如今,可以利用k8s的弹性计算,一键式进行扩容和缩容,不仅大大提高了运维效率,而且还节省了不少的服务器资源,提高了资源利用率。

    对于反代配置方面,比如可能你并不会,或者对nginx的配置规则并不熟悉,一些高级的功能你也不会实现,而如今,利用k8s的ingress即可简单的实现那些复杂的逻辑。并且也不会在遇到nginx少加一个斜杠和多加一个斜杠的问题。

    对于负载均衡方面,之前负载均衡可能是Nginx、LVS、HAProxy、F5等,云上可能是云服务商提供的不在均衡机制。每次添加删除节点时,都需要手动去配置前端负载均衡,手动去匹配后端节点,而如今,使用k8s内部的service可以动态发现实现自动管理节点,并且支持自动扩容缩容。之前遇到高峰流量时,经常服务器性能不够,需要临时加服务器面对高峰流量,而如今对于高性能k8s集群加上serverless,基本实现无需管理,自动扩容。

    对于高可用方面,k8s天生的高可用功能,彻底释放了双手,无需再去创建各类高可用工具、检测检查脚本。k8s支持进程接口级别的健康检查,如发现接口超时或者返回值不正确,会自动处理该问题。

    对于中间件搭建方面,根据定义好的资源文件,可以实现秒级搭建各类中间件高可用集群,并且支持一键式扩缩容,如Redis、RabbitMQ、Zookeeper等,并且大大减少了出错的概率。

    对于应用端口方面,传统行业中,一个服务器可能跑了很多进程,每个进程都有一个端口,需要人为的去配置端口,并且还需要考虑端口冲突的问题,如果有防火墙的话,还需要配置防火墙,在k8s中,端口统一管理,统一配置,每个应用的端口都可设置成一样的,之后通过service进行负载均衡,大大降低了端口管理的复杂度和端口冲突

    无论是对于开发人员、测试人员还是运维人员,k8s的诞生,不仅减少了工作的复杂性,还减少了各种成本。上述带来的变革只是其中比较小的一部分,更多优点只有用了才能体会到。

三、kubernetes带来的挑战

    首先是对于k8s的学习本身就是很难的,概念太多,无从入手,可能学习了一个月也无法入门,甚至连集群也搭建不出来,使人望而却步。并且k8s对运维的技术能力要求比较高,已经不仅仅局限于传统运维,有时候你可能要修改业务代码等。并且需要掌握的知识也需要很多,你可能需要掌握公司所有使用到的代码,比如代码是如何进行编译的、如何正确发布、如何修改代码配置文件等,这对于运维人员,也是一种挑战。Kubernetes之所以被叫做k8s,业界有两种说法,通俗的说法是k和s之间有8个字母,另一种比较说法是k8s集群至少需要搭建8遍才能搭建成功。当然,在实际使用时,可能不止8遍。k8s的诞生,把运维从传统转变到了DevOps方向,需要面临的问题会更多,需要面临的新技术也有很多,但是当你掌握到了k8s的核心使用,就会受益终身。
上一篇
下一篇
Copyright © 2022 Egon的技术星球 egonlin.com 版权所有 帮助IT小伙伴学到真正的技术