阅读本文前请先参考【系统三智能运维实践】系列文章前两篇
前文已经介绍过目前系统三团队的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以后,提升了系统三微服务的扩展、故障处理、日常变更、版本更新等运维管理能力,节约了大量人力,提升了不少效率。
领取专属 10元无门槛券
私享最新 技术干货