系统三智能运维实践之二——基于Kubernetes的容器集群与微服务管理

阅读本文前请先参考【系统三智能运维实践】系列文章前两篇

前文已经介绍过目前系统三团队的7e底层微服务是跑在一堆docker上的,但是是跑得裸docker,没有用任何集群编排与管理工具,使用裸docker会有下面几个问题:

容器的启动、停止、销毁都必须手动执行docker run/stop/rm命令,扩展一个相同容器也必须这样操作,非常繁琐

同一个微服务的两个容器都映射了本地的目录,做代码更新的时候需要更新两个宿主机节点,而实际却经常只更新一个忘了另一个,造成版本不同步

不用集群管理的话,裸docker的网络管理,特别是不同宿主机之间的docker之间网络互通是个大问题,目前只能通过映射宿主机端口这种简陋方式,不利于扩展,也不安全,相当于每个服务都对外暴露了端口

具有相互依赖关系的一组容器,启停管理等都需要一定的顺序,目前只能使用docker-compose这种简陋方式操作

经过调研分析,我们在Kubernetes、Mesos、Swarm之间选择了Kubernetes作为我们的容器集群管理工具。

什么是Kubernetes

Kubernetes(k8s)是是由谷歌开源的自动化容器编排工具与容器管理平台,包括容器部署、调度和节点集群间扩展。使用Kubernetes可以为系统三的微服务与容器管理带来如下好处:

容器的自动化部署和复制,定义好资源后直接上传Yaml文件就可完成部署

随时扩展或收缩容器规模,只需修改deployment里面的replica参数即可,缩扩容后,负载均衡自动更新,无需人工干预。通过k8s的api将其和监控对接,可实现业务的变化关联容器动态伸缩等智能场景

将容器组织成组,通过将具有紧密相关性的一组容器放在一个Pod可以整体管理、迁移、扩展

很容易的升级应用程序容器的新版本,或者回退到指定版本

通过网络插件可轻松实现容器间的网络通信,通过ClusterIP、NodePort等方式实现集群内部、外部的网络访问

Kubernetes的Volumn可以通过对接NFS或者Ceph/GlusterFS实现容器之间的共享存储,解决多地部署代码的问题

……

Kubernetes集群架构

Kubernetes集群主要包括三部分:Etcd节点、Master节点、Node节点,如下图所示:

Etcd节点:一个分布式强一致性的key/value存储,类似zookeeper,用来存储k8s的集群缘数据信息。

Master节点运行三个组件

kube-apiserver:作为kubernetes系统的入口进程,封装了核心对象的增删改查操作,以Restful接口方式提供给外部系统和内部组件调用,它维护的对象持久化到etcd里

kube-scheduler:负责集群的资源调度,为新建的pod分配机器,该部分可以替换成其它的调度器

kube-controller-manager:负责执行各种控制器,目前有两类:endpoint-controller,定期关联service和pod,保证service到pod的映射总是最新的;replication-controller,保证replicationController定义的副本数量与实际的pod数量一致

Node节点(也叫Minions)运行三个关键组件进程

kubelet:负责管控pod对应容器的创建、启停、监控运行状态等。它会定期从etcd获取分配到本机的pod,同时也会接收apiserver的HTTP请求,汇报pod的运行状态

kube-proxy:负责为pod提供代理,实现service到pod的映射与负载均衡。当某个pod要访问其它pod时,访问请求会经过本机proxy做转发

Docker-engine:docker引擎

Kubernetes相关的其它组件对象,如下图:

kubectl是Kubernetes的命令行客户端,它和apiserver通信,用于各类资源的增删改查

Pod是kubernetes里最重要也是最基本的概念,Pod里运行一个或者一组容器(一般情况下具有紧密相关性的一组容器可以放在一个Pod,比如一个web+一个app+一个db)。每个Pod里有一个特殊的被称为“根容器”的Pause容器,它的镜像叫做gcr.io/google_containers/pause-amd64(当然这个镜像在私有部署时需要放在我们的私有镜像仓库里)。同一个Pod里的容器共享同一个网络命名空间,它们之间互相访问通过localhost+port。Pod是短暂的,不是持续性实体,Pod里的容器需要通过volumn进行持久化

Kubernetes集群部署规划

系统三在部署k8s集群时采用3节点Master+3节点Etcd+多节点Node的架构,其中Etcd和Master公用节点。Kubernetes需要使用网络插件进行网络配置,本集群选择flannel,因此Master和Node上还需要部署flannel和haproxy。

下图是部署好整个集群以后,kubernetes-dashboard展示的Node信息:

下面给出一个简单的微服务部署方法。编写deployment.yaml文件(一个deployment是指一个应用部署资源定义),这是一个Python实现的人脸识别微服务:

使用kubectl或者kubernetes-dashboard创建该deployment,如:

下面编写service.yaml文件(一个service是对一个deployment的负载均衡访问)

使用kubectl或者kubernetes-dashboard创建该service,如:

创建完成后service会在pod所在Node上启一个高位端口(如37260),外部系统通过NodeIP+NodePort即可访问该微服务。现在修改我们的微服务网关KONG,将对应的微服务endpoint改成微服务新的NodeIP和NodePort,即可完成替换。

下图是目前我们在kubernetes上部署的所有deployment,目前有24个微服务,已经将所有微服务从原来的裸docker迁移到kubernetes了。通过Kubernetes的replicationController可以控制当其中有宿主机Node挂了以后,自动将其上运行的Pod迁移到其它Node。或者某个Pod挂了以后,自动在另外的Node上重启一个Pod,以补齐deployment中定义的replia数目。

使用了kubernetes以后,提升了系统三微服务的扩展、故障处理、日常变更、版本更新等运维管理能力,节约了大量人力,提升了不少效率。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180111G0KHVK00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券