Kubernetes简介
随着容器化技术,越来越多的企业和开发者都开始使用微服务和容器化技术来构建自己的服务和应用程序。
容器化的优点非常多,比如可以更加快速和高效地开发和部署应用程序,还可以提高应用程序的可用性稳定性,最重要也帮助企业提高了资源的利用效率,降低了成本
除了上面说的这些优点,当然也带来了一些新的问题,这里面最突出的一个问题就是容器的数量会变得非常非常多,架构也越来越复杂,如何管理和维护就成为非常大的问题和挑战
容器数量少的话可用使用一些shell脚本来管理,但是当容器数量达到一定规模,比如成百上千,甚至数以万计的时候,使用脚本来管理就会变得非常困难,而Kubernetes就是为了解决这个问题而生的
它可以帮助我们优雅的管理容器化的应用程序和服务,Kubernetes是由Google开源的容器编排引擎,它可以帮助我们管理容器化的应用程序和服务
Kubernetes提供了容器编排的功能,可以通过一些配置文件来定义应用程序的部署方式,让容器的创建、维护和管理变得更加简单和高效
高可用是指系统可以在长时间内持续正常地运行,并不会因为某一组件或者服务的故障而导致整个系统不可用这样的情况发生,Kubernetes提供了很多高可用的特性:比如自动重启、自动重建、自我修复等,这些特性可以帮助我们提供集群的可用性,从而让用户可以在任何时间内都能正常地使用系统。
可扩展性是指系统可以根据负载的变化来动态的扩展或者缩减系统的资源,从而来提供系统的性能和资源的利用率
Kubernetes组件
Node节点:一个节点就是一个物理机或者虚拟机
Pod容器组:Pod是Kubernetes的最小调度单元,一个Pod就是一个或者多个应用容器的组合(一般情况我们建议一个Pod只运行一个容器,或者可以放高度耦合的容器Sidecar
Service服务:内部服务和外部服务,Pod与Pod之间的通讯,Node:Prot(它会在节点上开放一个端口,然后将这个端口映射到Service的IP地址和端口上)
Ingress路由:Ingress是用来管理从集群外部访问集群内部服务的入口和方式的,可以通过Ingress来配置不同的转发规则,从而根据不同的规则来访问集群内部不同的Service以及Service所对应的后端Pod,还可以通过Ingress来配置域名,这样就可以将使用IP地址和端口号的方式转换成使用域名的方式来访问Service了
应用程序和数据库之间的耦合问题,比如我们的应用程序需要访问数据库的话,通常的做法是把数据库的地址和端口等连接信息写到配置文件或者环境变量中,然后在应用程序中读取这些配置信息,但是这样的配置信息就和应用程序耦合在一起了,一旦数据库的地址或者端口发生了变化,那么我们就需要重新编译应用程序,然后再重新部署到集群中,这样不但非常麻烦,而且还会造成应用程序的停机时间,这对于一些需要7×24小时不间断运行的系统或服务来说,显然是不能接受的,为了解决这个问题,Kubernetes提供了ConfigMap的组件
ConfigMap配置:它可以将一些配置信息封装起来,然后就可以在应用程序中读取和使用了,当数据库的地址和端口发生变化的时候,我们也只需要修改ConfigMap对象中的配置信息,然后重新加载Pod就可以了,不需要重新编译和部署应用程序,这样就实现了应用程序和数据库的解耦
Secret保密字典:如果在ConfigMap中有着一些敏感信息就可以使用Secret,它可以将一些敏感封装起来,然后就可以在应用程序中读取和使用了,需要注意的是这些敏感信息虽然不是以明文的形式来存储的,但是也只是做了一层Base64的编码而已,还需要配合一些其他的手段来提高安全性,比如Kubernetes提供了包括网络安全、访问控制、身份认证等安全机制
Volume存储:当容器被销毁或重启时,容器中的数据也会跟着消失,这对于一些需要持久化存储的应用程序,比如数据库来说显然是不行的,为了解决这个问题Kubernetes提供了一个叫做Volume的组件,它可以将一些持久化存储的资源挂载到集群中的本地磁盘上,或者挂载到集群外部的远程存储中,这样即使容器被销毁或者重启这些数据也不会丢失,也就是实现了容器中数据的持久化存储
Deployment无状态:它可以定义和管理应用程序的副本数量以及应用程序的更新策略,可以简化应用程序的部署和更新操作,将一个或多个pod组合在一起,并且还具有副本控制、滚动更新、自动扩缩容等高级特性和功能
StatefulSet有状态:数据库的多副本实现,保证每个副本都有自己的网络标识符和持久化存储,像数据库、缓存、消息队列等等以及一些保留了会话状态的应用程序都使用StatefulSet。 一种更加通用和简单的方式是把数据库这种有状态的应用程序从Kubernetes集群中剥离出来,在集群外单独部署
Kubernetes架构
Kubernetes是一个典型的Master-Worker架构,Master-Node负责管理整个集群,Worker-Node负责运行应用程序和服务
为了能够对外提供服务,每个Node上都会包含三个组件:Kubelet、kube-proxy、container runtimes
容器运行时(Container Runtimes):
- Docker-Engine
- Containerd
- CRI-O
- Mirantis Container Runtime
Kubelet负责管理和维护每个节点上的Pod并确保它们按照预期运行,它也会定期从api-server组件接受新的或者修改后的Pod规范,同时它也会监控工作节点的运行情况然后将这些信息汇报给apiserver
Kube-Proxy是工作节点的另一个核心组件负责为Pod对象提供网络代理和负载均衡服务,通常情况下Kubernetes集群可能包含多个节点,这些节点之间通过Service来进行通信,这就需要一个负载均衡来接受请求,然后再将请求发送到不同的节点上,来完成负载均衡的功能,Kube-Proxy就是负责这个功能的组件,它会在每个Node上启动一个网络代理,使发往Service的流量以一种高效的方式路由到正确的后端Pod中,比如我们的应用程序要访问数据库的时候,它的访问并不会被随机路由到任意一个节点上,而会被路由到和应用程序在同一个节点上的那个数据库的Pod上
Master节点上的组件:
Master节点上有四个基本组件:Kube-apiserver、etcd、ControllerManager和Scheduler
- Kube-apiserver:它负责提供Kubernetes集群的API接口服务,所有的组件都会通过这个接口来进行通信,比如你作为一个用户需要在集群中部署一个新的应用的时候,就需要通过一些客户端(Kubectl)来与apiserver进行交互,apiserver就像是一个集群的网关是整个系统的入口,所有的请求都会先经过它,然后再由它分发给不同的组件进行处理,比如一些创建、更新、删除Pod的请求,或者是一些查询集群状态的命令都会先经过apiserver,再转发给相应的组件来处理。除了提供API接口服务之外,apiserver还负责对所有资源对象的增删改查等操作进行认证、授权和访问控制,确保只有经过认证和授权的用户才能够访问到集群中的资源对象,这样就提高了整个集群系统的安全性
- Scheduler调度器:它负责监控集群中所有节点的资源使用情况,然后根据一些调度策略将Pod调度到合适的节点上运行,比如当我们新增一个Pod的时候,如果第一个节点上的资源占用了80%,而第二个节点上的资源只占用了20%,那么这个Pod就会被智能地调度到第二个节点上,这样就可以更加合理地利用集群中的各种资源
- ControllerManager控制器管理器:它负责管理集群中各种资源对象的状态,比如当集群中任何一个节点上的Pod发生故障的时候,必须要有一种机制来监控和检测到这个故障,然后尽可能快地对这个故障进行处理,比如重新启动这个Pod或者使用其他Pod来代替它,这个就是ControllerManager要做的事情,它会监控集群中各种资源对象的状态,比如Pod Node Service等等,然后根据这些状态来做出相应的响应,确保集群中的各种资源对象都处于我们预期的状态。
- etcd:它是一个高可用的键-值存储系统,etcd和redis比较类似也是一个键-值存储系统,用来存储集群中所有资源对象的状态信息,比如某一个Pod挂掉崩溃了,或者增加了一个新的Pod等等,这些信息都会被记录到etcd中,可用把他理解为一个集群的大脑,是整个集群的数据存储中心,很多功能都是依赖它来实现的,比如我们使用命令行或者UI界面来查询整个集群的状态,这些信息都是从etcd中获取的,这里需要注意的一点是etcd中一般只存储集群中各种资源对象的状态信息。而应用程序中的数据,比如我们数据库中的数据一般是不会存储在etcd中的。
- Cloud Controller Manager云控制器管理器:如果你使用的是云服务商,那么还会有一个额外的组件,它是一个云平台相关的控制器,负责与云平台的API进行交互,并且可用提供一致的管理接口使得用户可用更加方便地在不同的云平台中运行和管理他们的应用程序