kubernetes与web集群

k8s架构


Kubernetes最初源于谷歌内部的Borg,提供了面向应用的容器集群部署和管理系统。Kubernetes借鉴了Borg的设计理念,比如Pod、Service、Labels和单Pod单IP等。

乍一看Kubernetes的架构图会觉得有点晕

kubernetes与web集群

网上好多关于k8s的介绍都是从大讲到小,从master节点讲到pod。可是对于我这种对集群的理解不是很深的人,我看了好几遍都是一知半解。于是我决定从小往大扩展讲起。

pod

上次我们使用docker搭建了一个web集群(原文链接https://my.oschina.net/daba0007/blog/1605365)

kubernetes与web集群

我们就从这个集群开始讲起。docker十分成功的把开发环境打包到一个个容器中,对外看来它只是一个个服务,迁移也十分简单,写成镜像就可以带走了。我们部署的web集群,其实就是四个服务:

  • nginx服务

  • web服务

  • redis缓存服务

  • mysql存储服务

在k8s中,最基础、最小的原件就是pod。一个pod代表着集群中运行的一个进程。在一个pod中可以运行一个或多个容器,即它就是一个单位。对于我们的web集群来说,我们可以把它变成三个pod

  • redis

  • mysql

  • nginx和web(这两个放一起,因为它们共享着数据卷)

kubernetes与web集群

对于pod来说,它们可以共享两种资源:网络和存储

  • 网络:每个Pod都会被分配一个唯一的IP地址。Pod中的所有容器共享网络空间,包括IP地址和端口。Pod内部的容器可以使用localhost互相通信。Pod中的容器与外界通信时,必须分配共享网络资源(例如使用宿主机的端口映射)。【比如pod:redis共享了ip:dabaredis和port:6379,pod:mysql共享了ip:dabamysql和port:3306】

  • 存储:Pod可以指定多个共享的Volume。Pod中的所有容器都可以访问共享的volume。Volume也可以用来持久化Pod中的存储资源,以防容器重启后文件丢失。【比如pod:N&W共享了volume:dabadjango】

不过我们很少直接在kubernetes中创建单个Pod。因为Pod的生命周期是短暂的,用后即焚的实体。当Pod被创建后(不论是由你直接创建还是被其他Controller),都会被Kuberentes调度到集群的节点上。直到Pod的进程终止、被删掉、因为缺少资源而被驱逐、或者Node故障之前这个Pod都会一直保持在那个Node上。Pod不会自愈。如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除。同样的,如果Pod所在Node缺少资源或者Pod处于维护状态,Pod也会被驱逐。

Kubernetes使用更高级的称为Controller的抽象层,来管理Pod实例。

ReplicationController(rc)

rc是Kubernetes系统中最有用的功能,实现复制多个Pod副本,往往一个应用需要多个Pod来支撑,并且可以保证其复制的副本数,即使副本所调度分配的宿主机出现异常,通过Replication Controller可以保证在其它主宿机启用同等数量的Pod。当某一个pod出现故障down掉的时候,rc会为我们马上再生成一个pod来保持pod的数量。

然而,每个pod都会获取它自己的ip地址,即使这些ip地址不总是稳定可依赖的。这会导致一个问题:在 Kubernetes 集群中,如果一组 Pod为其它 Pod 提供备份,那么那些备份该如何发现,并连接到这组 Pod 中的哪些备份呢?

Service(svc)

Service 定义了这样一种抽象:一个Pod的逻辑分组,一种可以访问它们的策略——通常称为微服务。

当外界有请求服务的时候(比如web请求数据时),它将会向redis和mysql同时请求数据,这时候web就会请求dabaredis或dabamysql服务,通过service将会把指派redis或pod的一个pod的ip给web。(支持TCP和UDP协议,默认TCP)

kubernetes与web集群

但是有很多Service需要暴露多个端口(比如Service:N&W需要暴露12000,8888等),Kubernetes 支持在Service对象中定义多个端口。当使用多个端口时,必须给出所有的端口的名称(name),这样 Endpoint 就不会产生歧义

k8s的serviceTypes允许指定一个需要的类型:

  • ClusterIP:通过集群的内部IP暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的ServiceType。

  • NodePort:通过每个Node上的IP和静态端口(NodePort)暴露服务。NodePort服务会路由到ClusterIP服务,这个ClusterIP服务会自动创建。通过请求 <NodeIP>:<NodePort>,可以从集群的外部访问一个 NodePort 服务。

  • LoadBalancer:使用云提供商的负载均衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。

  • ExternalName:通过返回CNAME和它的值,可以将服务映射到externalName字段的内容(例如,foo.bar.example.com)。没有任何类型代理被创建,这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。

当然,Pod 想要能够被Service访问到,通常是通过Label Selector实现的。

kube-proxy

在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP)的形式。

Proxy不但解决了同一主宿机相同服务端口冲突的问题,还提供了Service转发服务端口对外提供服务的能力,Proxy后端使用了随机、轮循负载均衡算法。

kubernetes与web集群

节点介绍

接下来是一些节点功能的介绍:

  1. etcd

    它是用于共享配置和服务发现的分布式、一致性的KV存储系统

  2. apiserver

    apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、api注册和发现等机制。

  3. controller manager

    controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;

  4. scheduler

    scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;

  5. kubelet

    kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;

  6. Container runtime

    Container runtime负责镜像管理以及Pod和容器的真正运行(CRI)

集群

我们再回到之前我们的集群

kubernetes与web集群

这时候我们就可以使用k8s的服务概念来实现这个集群了

kubernetes与web集群

而对于每一个服务(svc),都会有应用控制器(rc)来保证其具有足够的数量来跑pod

kubernetes与web集群

这样就实现了LB和HA。一个比较可靠的服务集群就这样搭建起来。如果服务需要扩展,我们只需要增加节点(新加进一台主机)即可。

本文转移开源中国-kubernetes与web集群

上一篇:DataWorks百问百答19:数据质量出现校验异常如何查看?


下一篇:DataWorks百问百答17:如何排查周期任务取不到数据(产出数据为空)的问题?