Kubernetes --- 详细介绍和架构详解

Kubernetes是一个跨主机集群的开源的容器调度平台,它可以自动化应用容器的部署,扩展和操作,提供以容器为中心的基础架构


目录
一. Kubernetes用途
二. Kubernetes特点
三. 介绍容器技术
四. Kubernetes能做什么?
五. 使用Kubernetes的好处
六. 了解架构


一. Kubernetes用途

Kubernetes是容器集群管理系统,是一个开源的平台,可以实现容器集群的自动化部署,自动扩缩容,维护等功能

  • 快速部署应用
  • 快速扩展应用
  • 无缝对接新的应用功能
  • 节省资源,优化硬件资源的使用

二. Kubernetes特点

  • 可移植 : 支持公有云,私有云,混合云,多重云
  • 可扩展 : 模块化,插件化,可挂载,可组合,支持各种形式的扩展
  • 自动化 : 自动部署,自动重启,自动复制,自动伸缩/扩展,通过声明式语法提供了强大的自修复能力

Kubernetes是Google2014年创建管理的,是Google10多年大规模容器管理技术Borg的开源版本

三. 介绍容器技术

Kubernetes使用Linux容器技术来提供应用的隔离,如Docker或者rkt

容器允许你在同一台机器上运行多个服务,不仅提供不同的环境给每个服务,而且将它们互相隔离,容器类似于虚拟机,但开销小很多

一个容器仅仅是运行在宿主机上被隔离的单个进程,仅消耗应用容器消耗的资源,不会有其他进程的开销

容器都是调用同一个内核,自然会有安全隐患

容器实现隔离机制介绍

有两个机制可用 :
第一个是Linux命名空间,它使每个进程只能看到它自己的系统视图(文件,进程,网络接口,主机名等)
第二个是Linux控制组(cgroups),它限制了进程能使用的资源量(CPU,内存,网络带宽等)

Docker容器镜像层

容器镜像层是只读的,容器运行时,一个新的可写层在镜像层之上被创建容器中进程写入位于底层的一个文件时,此文件的一个拷贝在顶层被创建,进程写得此时拷贝

容器镜像可移植性的限制

一个在特定硬件架构之上编译的容器化应用,只能在有相同硬件架构的机器上运行

容器优点
  • 敏捷的应用程序创建和部署 : 与虚拟机镜像相比,容器镜像更容器创建,提升了硬件的使用效率
  • 持续开发,集成和部署 : 提供可靠与频繁的容器镜像构建和部署,可以很方便及快速的回滚(由于镜像不可变性)
  • 关注开发与运维的分离 : 在构建/发布时创建应用程序容器镜像,从而将应用程序和基础架构分离
  • 开发,测试和生产环境的一致性 : 在笔记本电脑上运行与云中一样
  • 云和操作系统的可移植性 : 可运行在Ubuntu,RHEL,CoreOS,内部部署,Google 容器引擎和其他任何地方
  • 以应用为中心的管理 : 提升了操作系统的抽象级别,以便在使用逻辑资源的操作系统上运行应用程序
  • 松耦合,分布式,弹性伸缩,微服务 : 应用程序被分成更小,更独立的部分,可以动态部署和管理,而不是巨型单体应用运行在专用的大型机上
  • 资源隔离 : 通过对应用进行资源隔离,可以很容易的预测应用程序性能
  • 资源利用 : 高效率和高密度

四. Kubernetes能做什么?

最基础的,Kubernetes可以在物理或虚拟机集群上调度和运行应用程序容器.然而,Kubernetes还允许开发人员从物理和虚拟机'脱离',从以主机为中心的基础架构转移到以容器为中心的基础架构,这样可以提供容器固有的全部优点和益处.Kubernetes提供了基础设施来构建一个真正以容器为中心的开发环境

Kubernetes满足了生产中运行应用程序的许多常见的需求
  • Pod提供复合应用并保留一个应用一个容器的容器模型
  • 挂载外部存储
  • Secret管理
  • 应用健康检查
  • 副本应用实例
  • 横向自动扩缩容
  • 服务发现
  • 负载均衡
  • 滚动更新
  • 资源监测
  • 日志采集和存储
  • 支持自检和调试
  • 认证和鉴权

这提供了平台即服务(PAAS)的简单性以及基础架构即服务(IAAS)的灵活性,并促进跨基础设施供应商的可移植性

五. 使用Kubernetes的好处

  • 简化应用程序部署
  • 更好的利用硬件
  • 健康检查和自修复
  • 自动扩容
  • 简化应用部署

六. 了解架构

Kubernetes集群分为两部分 :

  • Kubernetes控制平面
  • (工作)节点

控制平面的组件 :

  • etcd分布式持久化存储
  • API服务器
  • 调度器
  • 控制器管理器

这些组件用来存储,管理集群状态,但它们不是运行应用的容器

工作节点上运行的组件 :

  • Kubelet
  • Kubelet服务代理(kube-proxy)
  • 容器进行时(Docker,rkt或者其他)

附加组件 :

  • Kubernetes DNS服务器
  • 仪表板
  • Ingress控制器
  • Heapster(容器集群监控)
  • 容器网络接口插件
etcd

创建的所有对象 - pod,ReplicationController,服务和私密凭据等,需要以持久化方式存储到某个地方,这样它们的manifest在API服务器重启和失败的时候才不会丢失.为此,Kubernetes使用了etcd

etcd是一个响应快,分布式,一致的Key-value存储.因为它是分布式的,故可以运行多个etcd实例来获取高可用性和更好的性能

唯一能直接和etcd通信的是Kubernetes的API服务器.所有其他组件通过API服务器间接地读取,写入数据到etcd.这带来一些好处,其中之一就是增强乐观锁系统,验证系统的健壮性;并且,通过把实际存储机制从其他组件抽离,未来替换起来也更容易.值得强调的是,etcd是Kubernetes存储集群状态和元数据的唯一的地方

API服务器

Kubernetes API服务器作为中心组件,其他组件或者客户端都会去调用它.以RESTful API的形式提供了可以查询,修改集群状态的CRUD(Create,Read,Update,Delete)接口.他将状态存储到etcd中

API服务器除了提供一种一致的方式将对象存储到etcd,也对这些对象做校验,这样客户端就无法存入非法的对象(直接写入存储的话是有可能的).除了检验,还会处理乐观锁,这样对于并发更新的情况,对对象做更改就不会被其他客户端覆盖

API服务器的客户端之一就是使用的命令行工具kubectl,也支持监听资源

调度器

通常不会去指定pod应该运行在哪个集群节点上,这项工作交给调度器.宏观来看,调度器的操作比较简单.就是利用API服务器的监听机制等待新创建的pod,然后给每个新的,没有节点集的pod分配节点

调度器不会命令选中的节点去运行pod.调度器做的就是通过API服务器更新pod的定义.然后API服务器再去通知Kubelet该pod已经被调度过.当目标节点上的Kubelet发现该pod被调度到本节点,他就会创建并且运行pod的容器

尽管宏观上调度的过程看起来比较简单,但实际上为pod选择最佳节点的任务并不简单.当然,最简单的调度方式是不关心节点上已经运行的pod,随机选择一个节点.另一方面,调度器可以利用高级技术,例如机器学习,来预测接下来几分钟或几小时哪种类型的pod将会被调度,然后以最大的硬件利用率,无须重新调度已运行pod的方式来调度.Kubernetes的默认调度器实现方式处于最简单和最复杂程度之间

控制器管理器

API服务器只做了存储资源到etcd和通知客户端有变更的工作.调度器则只是给pod分配节点,所以需要有活跃的组件确保系统真实状态朝API服务器定义的期望的状态收敛.这个工作由控制器管理器里的控制器来实现

单个控制器,管理器进程当前组合了多个执行不同非冲突任务的控制器.这些控制器最终会被分解到不同的进程,如果需要的话,我们能够用自定义实现替换它们每一个

控制器包括 :

  • Replication管理器(ReplicationController资源的管理器)
  • ReplicaSet,DaemonSet以及Job控制器
  • Deployment控制器
  • StatefulSet控制器
  • Node控制器
  • Service控制器
  • Endpoints控制器
  • Namespace控制器
  • PersistentVolume控制器
  • 其他
Kubelet

Kubelet就是负责所有运行在工作节点上内容的组件.它第一个任务就是在API服务器中创建一个Node资源来注册该节点.然后需要持续监控API服务器是否把该节点分配给pod,然后启动pod容器.具体实现方式是告知配置好的容器进行时来从特定容器镜像运行容器,Kubelet随后持续监控运行的容器,向API服务器报告他们的状态,事件和资源消耗

Kubelet也是运行容器存活探针的组件,当探针报错时它会重启容器.最后一点,当pod从API服务器删除时,Kubelet终止容器,并通知服务器pod已经被终止了

kube-proxy

每个工作节点都会运行kube-proxy,用于确保客户端可以通过Kubernetes API连接到你定义的服务

kube-proxy确保对服务IP和端口的连接最终能到达支持服务的某个pod处.如果有多个pod支撑一个服务,那么代理会发挥对pod的负载均衡作用

Kubernetes插件
DNS服务器

集群中的所有pod默认配置使用集群内部DNS服务器.这使得pod能够轻松地通过名称查询到服务,甚至是无头服务pod的IP地址

DNS服务pod通过kube-dns服务对外暴露,使得该pod能够像其他pod一样在集群中移动.服务的IP地址在集群每个容器的/etc/reslv.conf文件的nameserver中定义.kube-dns pod利用API服务器的监控机制来订阅Service和Endpoint的变动,以及DNS记录的变更,是的其客户端总是能够获取到最新的DNS信息.客观的说,在Service和Endpoint资源发生变化到DNS pod收到订阅通知时间点之间,DNS记录可能会无效

Ingress控制器

Ingress控制器运行一个反向代理服务器,根据集群中定义的Ingress,service以及Endpoint资源来配置该控制器.所以需要订阅这些资源,然后每次其中一个发生变化则更新代理服务器的配置

尽管Ingress资源的定义指向一个Service,Ingress控制器会直接将流量转到服务的pod而不经过服务IP.当外部客户端通过Ingress控制器连接时,会对客户端IP进行保存,这使得在某些用例中,控制器比Service更受欢迎

其他插件都需要监听集群状态,当有变更时执行相应动作

我每天会写文章记录K8S学习之路,另外我自己整理了些云计算的学习资料,目前全部放在我的公众号"SmallBird技术分享",加入我们一起学习交流,并且回复’分享’会有大数据,云计算资源惊喜等着你~

posted @ 2019-09-12 15:44  BirdieGarden  阅读(1792)  评论(0编辑  收藏  举报