"kubernetes基本概念"

  "kubernetes基础"

Posted by Xu on August 23, 2018

Kubernetes基础概念

POD

所有容器均在Pod中运行,一个Pod可以承载一个或者多个相关的容器:

  • 同一个POD中的容器部署在同一个物理机器上,并能够共享资源
  • 一个Pod可以包含0个或多个磁盘卷组(volumes),这些卷组可以提供给一个容器或者被多个容器共享

用户可以自己创建并管理Pod,k8s将这些操作简化为两个操作:

  • 基于相同的Pod配置文件部署多个Pod复制品,系统创建许多冗余,这些冗余的Pod组成了一个整个应用或服务
  • 一旦一个pod被创建,系统就会不停地监控Pod的健康情况以及Pod所在主机的健康情况,当一个Pod挂了或者机器挂了的时候,replication controller会自动在一个健康的机器上创建一个一摸一样的Pod,维持原Pod的冗余状态

k8s对Pod的管理

当我们要限制一组Pod的基本操作,或者查询某组Pod的状态:

  • 作为K8S的基本机制,用户可以给K8S Api 中的任何对象贴上一组key:value 的标签,然后通过标签来选择一组相关的K8S Api对象,去执行一些特定的操作
  • 每个资源额外拥有一组(很多)keys和values,外部的工具可以使用这些keys和values值进行对象检索,这些Map叫做annotations

POD 网络

K8S支持一种特殊的网络模型,K8S创建了一个地址空间,并且不动态的分配端口,可以允许用户选择任何想使用俄端口,所以它为每个Pod分配IP地址

K8S提供了服务的抽象,并提供了固定的IP地址和DNS名称,而这些与一系列Pod进行动态关联,也是通过标签来进行关联,关联到我们想关联的容器,当一个POD中的容器访问该地址时:

  • 首先该请求会被转发到本地代理kube proxy,每台机器上均有一个本地代理
  • 然后被转发到相关联的后端容器
  • 这些动态的Pod被替换的时候,Kube Proxy时刻追踪着,所以虽然Pod可能会动态变化,但服务的IP地址从来不变

POD的区分

K8S的资源,比如Pod,都是通过一个叫URI的东西来区分,这个URI有一个UID(唯一),URI的重要组成部分是:对象的类型(比如pod)+对象的名字+对象的命名空间

K8S架构

K8S集群包含有节点代理kubelet和Master组件(APIs,scheduler,etc)

k8sframework.png

在上面的架构图中,服务分为两种:

  • 运行在工作节点上的服务
  • 组成集群级别控制板的服务(像运行应用容器的必备的服务都是受Master控制的)

K8S组件

  • etcd:保存整个集群的状态
  • apiserver:提供资源操作的唯一入口,并提供认证,授权,访问控制,API注册和发现等机制
  • controller manager:负责维护集群的状态,比如故障检测,自动扩展,滚动更新等等
  • scheduler:负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上
  • kubelet:负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理
  • container runtime:负责镜像管理以及Pod和容器的真正运行(CRI)
  • kube-proxy:一个节点对应一个本地代理,负责为Service提供cluster内部的服务发现(路由代理和监控)和负载均衡

K8S的架构分层

  • 核心层:K8S最核心的功能,对外提供API构建高层应用,对内提供插件式(模块)应用执行环境
  • 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用)和路由(服务发现、DNS解析等)
  • 管理层:系统度量(基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision)以及策略管理(RBAC、Quota、PSP、NetworkPolicy)
  • 接口层:kublet命令行工具、客户端SDK以及集群联邦
  • 生态系统层:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
    • K8S外部:日志、监控、配置管理、CI、CD、Workflow Faas OTS应用 ChatOps等
    • K8S内部:CRI CNI CVI 镜像仓库 Cloud Provider 集群自身的配置和管理等

K8S的设计理念

API设计原则

  • 声明式API:隐藏实现细节,API仅仅依赖于声明
  • API互补而且可以组合:面向对象设计的要求,”高内聚,松耦合”
  • 高层API以操作意图为基础设计:高层设计要从业务出发,而不是过早的从技术实现出发
  • 底层API根据高层API设计:实现底层API是为了让高层API使用,考虑减少冗余,提高重用性的目的。
  • 尽量避免简单的封装:简单的封装,实际上没有提供新的功能,反而增加了对所封装的API的依赖性
  • API操作复杂度与对象数量成正比:O(N),如果复杂度高于O(N),则不具备水平伸缩性
  • API对象状态不能依赖于网络连接状态:在出现网络断开的时候时,保证API对象状态能应对网络的不稳定

API对象

API对象是K8S中的管理操作单元,K8S每支持一项新功能,引入一项新技术,都会引入对应的API对象。如Replica Set对应的API对象是RS

每个API对象包含三大类属性:

  • 元数据metadata:用来标示API对象的,每个对象至少有三个元数据
    • namespace
    • name
    • uid
    • labels:例如使用标签env来标识区分不同的服务部署环境,分别用env = dev,env = testing,env = production来标识开发、测试、生产的不同服务
  • 规范spec:描述了用户期望K8S集群中的分布式系统达到的理想状态,如通过复制控制器Replication Controller设置期望的Pod副本数为3
    • K8S中所有的配置都是通过API对象的spec去设置的
  • 状态status:描述系统实际当前达到的状态,例如系统实际的Pod副本数为2

Pod的设计理念

K8S中最重要也是最基础的微服务Pod,Pod是在K8S集群中运行部署应用或服务的最小单元,他是可以支持多容器的。

POD的设计理念是支持多个容器在一个POD中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的组合完成服务。(例如运行一个操作系统发行版的软件仓库,一个Nginx容器用来发布软件,另一个容器专门用来从源仓库做同步,不同的团队各自开发构建自己的容器镜像,共享软件仓库,部署时组合成一个微服务对外提供服务。)

复制控制器(Replication Controller ,RC)

RC是K8S集群中最早的保证Pod高可用的API对象,通过监控运行中的Pod来保证集群中运行指定数目 的POD副本。

副本集(Replica Set ,RS)

RS是新一代RC,提供同样的高可用能力,区别在于RS后来居上,能支持多种类的匹配模式。副本集对象一般不单独使用,而是作为Deployment的理想状态参数来使用

部署(Deployment)

部署表示用户对K8s集群的一次更新操作,它是一个比RS应用模式更广的API对象:

  • 创建一个新的服务
  • 更新一个新的服务
  • 滚动升级一个新的服务:创建一个新的RS,将旧的RS中的副本减少到0

服务(Service)

服务是针对客户端的API对象,每个Serive对象都会对应一个集群内部有效的虚拟IP,集群内部都会通过虚拟IP访问一个服务。

代理服务器(Kube-proxy)

在K8S集群中微服务的负载均衡是由Kube-Proxy实现的,它是一个分布式的代理服务器,在K8s的每一个节点上都有一个。这一设计体现了它的伸缩性优势,需要访问服务的节点越多Kube-proxy越多。

任务(Job)

Job是k8s用来控制批处理型任务的API对象。Job管理的Pod根据用户的设置把任务完成就退出了

有状态服务集(PetSet)

RC和RS控制无状态服务,一般不挂载存储或挂载共享存储,保存的是所有Pod共享的状态,对于PetSet中的Pod,每个Pod挂载自己独立的存储,如果一个Pod出现故障,从其他节点启动一个同样名字的Pod,要挂载原Pod的存储继续以他的状态提供服务

集群联邦(Federation)

在云环境环境中,服务的作用距离范围从近到远一般包括:同主机(Host,Node)、跨主机同可用区(Available Zone)、跨可用区同地区(Region)、跨地区同服务商(Cloud Service Provider)、跨云平台。

K8S的设计定位是单一集群在同一个地域内,因为同一个地区的网络性能才能满足K8s的调度和计算存储连接要求

存储卷(Volume)

类似于Docker的存储卷,只不过Docker的存储卷作用范围为一个容器,而K8S的存储卷作用范围是一个Pod,k8s支持的存储卷类型非常多:

  • 包括多种分布式存储GlusterFS和Ceph
  • 也支持容易使用的主机本地目录hostPath和NFS
  • 有关的存储实际技术的配置交给存储管理员通过Persistent Vloume来配置