1.Kubernetes简介

1.1 Kubernetes和微服务

在介绍Kubernetes之前,我们先来了解一下云原生架构。 云原生的概念最早在2013年由Pivotal的Matt Stine提出。 经过社区不断完善, 包括Agile Infrastructure, Continuous Delivery, DevOps, Microservices, 12 Factor App等几大主题 。 这几大主题都是一些理论或实践方法,伴随着这些理论和实践必然存在一系列的平台和工具。

下面我们着重关注一下微服务。随着技术的发展,后端的架构已经由原来的单体架构演化现在的微服务架构。 我们在实现一个微服务平台时会有如下的愿景:我们不想关心服务器、负载均衡、监控、部署这些东西,而是希望有一个平台或工具帮助我们自动完成。

例如,下面的图中一个应用是有3个服务组成,根据容量评估,Service1和Service3需要部署3个实例,Service2需要部署4个实例,希望有一个平台帮助实现这10个实例的分布式部署,并且持续监控它们,当某个服务器宕机或者某个服务实例故障时,这个平台可以做自我修复,从而保证在任何时刻运行的服务实例数量都是预期,这样我们只需关注每个服务本身的开发,无须再基础设施和运维监控的事情头疼。

microservice-vision.png

现在有一个平台实现了我们前面的愿景,它就是Kubernetes。Kubernetes出身名门,它来自Google,用Go语言开发,是云原生计算基金会CNCF的最重开源项目, 也是Google内部大规模容器集群管理系统Borg的开源版本。

Kubernetes支持在多种环境部署,包括各种公有云、私有云以及本地服务器。 我们注意到Kubernetes的logo是一个轮船的舵,在希腊语里Kubernetes就是舵手意思。 从这点可以看出,Kubernetes在容器云技术里就是要控制一切。

microservice-k8s.png

1.2 Kubernetes的主要功能

Kubernetes的主要功能如下:

  • 基于容器的应用部署、维护和滚动升级
  • 内置了负载均衡和服务发现
  • 可以实现容器应用的自动伸缩
  • 在Kubernetes上可以部署无状态服务和有状态服务
  • 提供了广泛的Volume支持
  • 插件机制保证扩展性
  • 跨机器和跨地区的集群调度

1.3 Kubernetes和Docker

Docker刚出现时几乎是容器技术的代名词,Docker最初的重点是运行容器,而Kubernetes的重点是管理容器。 Kubernetes在容器运行时之上实现了容器的集群化和高可用。

k8s-and-docker

后来Docker新版本的Swarm“高仿”了Kubernetes,和Kubernetes是产生竞争的关系,而Kubernetes的容器运行时也不再限于docker,比如还可以是rtk。 但是Kubernetes发展非常迅速,已经成为容器编排领域的领导者。

2. Kubernetes集群的组成

一个Kubernetes集群是由一堆服务器组成的,这堆服务器可以是公有云、私有云,也可以是本地的服务器或虚拟机集群。 下图中的Master和Node就是Kubernetes里服务器节点(Node)的概念。

k8s-cluster

从Master和Node字面上的意思可以看出,Kubernetes实际上是主从架构,Master节点负责集群的控制和调度,Node节点负责运行工作负载,即可以跑我们的微服务。

Kubernetes自己本身就是一个分布式系统,例如上图中Master节点中红色方框kube-apiserver,kube-controller-manager,kube-scheduler和Node节点中的绿色方框kubelet,kube-proxy都是单独运行的进程,每个进程都是用Go语言写的一个程序,实际部署Kubernetes集群就是部署这些程序。

从上图还要注意到每个Node节点里的Pod和Pod里的容器就是我们运行的应用,应用是以Pod的形式跑在Kubernetes上。也就是说并不存在某台具体服务运行应用,而全部由Kubernetes进行资源分配和调度。

2.1 Master节点的核心组件

Master节点是Kubernetes集群的管理和控制节点。Master节点由如下4个进程组成:

k8s-master

  • apiserver:提供Restful API,是整个集群管理和控制的入口。apiserver封装了资源对象的CRUD操作并持久化到etcd中,REST API提供给外部客户端和内部组件调用。
  • scheduler:是调度器,主要负责Pod调度,每个Pod最终被调度到哪台服务器上是由Scheduler决定的
  • controller-manager:是比较关键的组件,是Kubernetes集群中所有资源的自动化控制中心
  • etcd: etcd是一个分布式的键值存储,它实际上保存整个Kubernetes集群各种资源和状态,可以它理解成Kubernetes集群的数据库。

scheduler和controller-manager都是通过apiserver从etcd中获取各种资源的状态,进行相应的调度和控制操作。

2.2 Node节点的组件

Node节点是Kubernetes集群的工作负载节点,我们的服务实例是跑在多个Node节点上。Node节点上主要有如下组件:

  • kubelet:主要负责本节点Pod的生命周期管理,定期向Master上报本节点及Pod的基本信息。kubelet会从apiserver接收Pod的创建请求,启动和停止Pod。
  • kube-proxy: 实现Kubernetes上Service的通信及负载均衡。kuer-proxy目前有userspace和iptables两种实现方式。userspace是在用户空间,通过kuber-proxy实现负载均衡的代理服务。这个是kube-proxy的最初的版本,较为稳定,但是效率不太高。另外一种方式是iptables的方式,在内核空间,是纯采用iptables来实现LB,是Kubernetes目前默认的方式。

k8s-node

2.3 Kubernetes集群的高可用

一个可以用于生产环境的Kubernetes集群必须实现高可用,也就是要实现Master节点及其核心组件的高可用,如果Master节点出现问题的话,那整个集群就失去了控制。 下面这张图是Kubernetes官方文档中给出的一种Kubernetes HA部署方案。

kubernetes-ha

  • 部署了3个Master节点,每个Master节点的etcd组成集群
  • 3个Master节点上的APIServer的前面放一个负载均衡器,工作节点和客户端通过这个负载均衡器和APIServer进行通信
  • scheduler和controller-manager支持leader选举,能保证在集群中多个实例只有一个工作,其他为备用

3.Kubernetes的资源对象

3.1 自动化资源控制系统

Kubernetes实际上一个高度自动化的资源控制系统,Kubernetes将其管理的一切抽象为资源对象,大到服务器Node节点,小到服务实例Pod。

Kubernetes的资源控制是一种声明+引擎的理念,我们对集群中的某种资源对象作出声明,Kubernetes的自动化资源控制系统会一直尝试将该资源对象维持在我们声明的状态下。

3.2 部署服务相关的资源

  • Pod:Kubernetes的基本管理单元
    • 一个Pod中可以运行多个容器
    • 通过Deployment可以部署Pod
  • Deployment:表示部署,支持滚动升级
    • 在部署Pod的时候会创建一个ReplicaSet,来控制Pod实例的数量
  • Service: Service就是微服务架构中微服务
    • 每个Service分配一个固定不变的虚拟IP即ClusterIP
    • 一个Service后边可以有一个或多个Pod。
    • Service将客户端请求转发到后边的某个Pod上,实现负载均衡
  • Label: Label是联系各种k8s资源的纽带
    • 一个Service通过Label关联到后端的Pod上
    • Service定义一个Pod的label选择器,具备这个Label的Pod就会为此Service效力

3.3 其他资源对象

  • Namespace: 用于实现多租户的逻辑隔离
  • PV和PVC: 持久卷和持久卷请求提供集群的持久存储抽象
  • DaemonSet: 在集群中的每个Node上启动一个守护进程Pod
  • Job和Schedued Job
  • Ingress: 将集群外部流量接入到集群内
  • ConfigMap和Secret: 集中配置中心
  • Horizontal Pod Autoscaler: 根据负载实现Pod自动弹性伸缩 ……