闲谈Kubernetes 的主要特性和经验分享 - 时速云 王磊

jopen 9年前
 

大家好,我是时速云的王磊,目前主要负责时速云容器即服务平台的技术架构、设计和开发管理工作。很高兴今天有机会和大家一起聊一聊 Kubernetes 的一些主要特性和一些经验。

我们先从整体上看一下Kubernetes的⼀些理念和基本架构, 然后从网络、 资源管理、存储、服务发现、负载均衡、高可⽤、rolling upgrade、安全、监控等⽅面向⼤家简单介绍kubernetes的这些主要特性。

当然也会包括⼀些需要注意的问题。主要目的是帮助大家快速理解 Kubernetes的主要功能,今后在研究和使⽤用这个⼯具的时候有所参考和帮助。

  1. 先来随便看一下Kubernetes的一些理念:

1.1) 用户不需要关心需要多少台机器,只需要关心软件(服务)运行所需的环境。以服务为中心,你需要关心的是api,如何把大服务拆分成小服务,如何使用api去整合它们。

1.2) 保证系统总是按照用户指定的状态去运行

1.3)不仅仅提给你供容器服务,同样提供一种软件系统升级的方式;在保持HA的前提下去升级系统是很多用户最想要的功能,也是最难实现的。

1.4) 那些需要担心和不需要担心的事情

闲谈Kubernetes 的主要特性和经验分享 - 时速云 王磊

1.5)更好的支持微服务理念,划分、细分服务之间的边界,比如lablel、pod等概念的引入

对于Kubernetes的架构,可以参考下面的官方文档:

https://github.com/GoogleCloud ... re.md

大致由一些主要组件构成,包括Master节点上的kube-apiserver, kube-scheduler, kube-controller-manager, 控制组件kubectl,状态存储etcd,Slave节点上的kubelet, kube-proxy,以及底层的网络支持(可以用flannel, OpenVSwitch, Weave等)

看上去也是微服务的架构设计,不过目前还不能很好支持单个服务的横向伸缩,但这个会在 Kubernetes 的未来版本中解决。

  1. 接下来我们就进入Kubernetes的主要特性分享了

会从网络、服务发现、负载均衡、资源管理、⾼可用、存储、安全、监控等⽅⾯向⼤家简单介绍kubernetes的这些主要特性 -> 由于时间有限,只能简单一些了 :)

另外,对于服务发现、高可用和监控的一些更详细的介绍,感兴趣的朋友可以通过下面的链接了解:

http://www.csdn.net/article/2015-07-30/2825337

1) 网络

Kubernetes的网络方式主要解决以下几个问题:

a. 紧耦合的容器之间通信,通过 Pod 和 localhost 访问解决

b. Pod之间通信,建立通信子网,比如隧道、路由,Flannel、Open vSwitch、Weave

c. Pod和Service,以及外部系统和Service的通信,引入Service解决

Kubernetes的网络会给每个Pod分配一个IP地址,不需要在Pod之间建立链接,也基本不需要去处理容器和主机之间的端口映射。

注意:Pod重建后,IP会被重新分配,所以内网通信不要依赖Pod IP;通过Service环境变量或者DNS解决。

2) 服务发现及负载均衡

kube-proxy和DNS, 在v1之前,Service含有字段portalip 和publicIPs, 分别指定了服务的虚拟ip和服务的出口机ip,publicIPs可任意指定成集群中任意包含kube-proxy的节点,可多个。portalIp 通过NAT的方式跳转到container的内网地址。在v1版本中,publicIPS被约定废除,标记为deprecatedPublicIPs,仅 用作向后兼容,portalIp也改为ClusterIp, 而在service port 定义列表里,增加了nodePort项,即对应node上映射的服务端口。

dns服务以addon的方式,需要安装skydns和kube2dns。kube2dns会通过读取kubernetes API获取服务的clusterIP和port信息,同时以watch的方式检查service的变动,及时收集变动信息,并将对于的ip信息提交给 etcd存档,而skydns通过etcd内的dns记录信息,开启53端口对外提供服务。大概的dns的域名记录是 servicename.namespace.tenx.domain, "tenx.domain"是提前设置的主域名。

注意:kube-proxy 在集群规模较大以后,可能会有访问的性能问题,可以考虑用其他方式替换,比如HAProxy,直接导流到Service 的endpints 或者 Pods上。Kubernetes官方也在修复这个问题。

3)资源管理

有3 个层次的资源限制方式,分别在Container, Pod, Namespace 层次。Container层次主要利用容器本身的支持,比如Docker 对CPU, Memory, disk, network 等的支持;Pod方面可以限制系统内创建Pod的资源范围,比如最大或者最小的CPU、memory需求;Namespace层次就是对用户级别的资源限 额了,包括CPU、Memory,还可以限定Pod、rc、service的数量。

资源管理模型 -》 简单、通用、准确,并可扩展

目前的资源分配计算也相对简单,没有什么资源抢占之类的强大功能,通过每个节点上的资源总量、以及已经使用的各种资源加权和,来计算某个Pod优 先非配到哪些节点,还没有加入对节点实际可用资源的评估,需要自己的scheduler plugin来支持。其实kubelet已经可以拿到节点的资源,只要进行收集计算即可,相信Kubernetes的后续版本会有支持。

4)⾼可用

主要是指Master节点的 HA方式, 官方推荐 利用etcd实现master 选举,从多个Master中得到一个kube-apiserver, 保证至少有一个master可用,实现high availability。对外以loadbalancer的方式提供入口。这种方式可以用作ha,但仍未成熟,据了解,未来会更新升级ha的功能。

一张图帮助大家理解:

闲谈Kubernetes 的主要特性和经验分享 - 时速云 王磊

也就是在etcd集群背景下,存在多个kube-apiserver,并用pod-master保证仅是主master可用。同时kube- sheduller和kube-controller-manager也存在多个,而且伴随着kube-apiserver, 同一时间只能有一套运行。

5) rolling upgrade

RC 在开始的设计就是让rolling upgrade变的更容易,通过一个一个替换Pod来更新service,实现服务中断时间的最小化。基本思路是创建一个复本为1的新的rc,并逐步减少老的rc的复本、增加新的rc的复本,在老的rc数量为0时将其删除。

通过kubectl提供,可以指定更新的镜像、替换pod的时间间隔,也可以rollback 当前正在执行的upgrade操作。

同样, Kuberntes也支持多版本同时部署,并通过lable来进行区分,在service不变的情况下,调整支撑服务的Pod,测试、监控新Pod的工作情况。

闲谈Kubernetes 的主要特性和经验分享 - 时速云 王磊

6)存储

大家都知道容器本身一般不会对数据进行持久化处理,在Kubernetes中,容器异常退出,kubelet也只是简单的基于原有镜像重启一个新 的容器。另外,如果我们在同一个Pod中运行多个容器,经常会需要在这些容器之间进行共享一些数据。Kuberenetes 的 Volume就是主要来解决上面两个基础问题的。

Docker 也有Volume的概念,但是相对简单,而且目前的支持很有限,Kubernetes对Volume则有着清晰定义和广泛的支持。其中最核心的理 念:Volume只是一个目录,并可以被在同一个Pod中的所有容器访问。而这个目录会是什么样,后端用什么介质和里面的内容则由使用的特定Volume 类型决定。

创建一个带Volume的Pod:

闲谈Kubernetes 的主要特性和经验分享 - 时速云 王磊

spec.volumes 指定这个Pod需要的volume信息, spec.containers.volumeMounts 指定哪些container需要用到这个Volume, Kubernetes对Volume的支持非常广泛,有很多贡献者为其添加不同的存储支持,也反映出Kubernetes社区的活跃程度。

emptyDir 随Pod删除,适用于临时存储、灾难恢复、共享运行时数据,支持 RAM-backed filesystem

hostPath 类似于Docker的本地Volume, 用于访问一些本地资源(比如本地Docker)

gcePersistentDisk GCE disk - 只有在 Google Cloud Engine 平台上可用

awsElasticBlockStore 类似于GCE disk, 节点必须是 AWS EC2的实例

nfs - 支持网络文件系统

rbd - Rados Block Device - Ceph

secret 用来通过Kubernetes API 向Pod 传递敏感信息,使用 tmpfs (a RAM-backed filesystem)

persistentVolumeClaim - 从抽象的PV中申请资源,而无需关心存储的提供方

glusterfs

iscsi

gitRepo

根据自己的需求选择合适的存储类型,反正支持的够多,总用一款适合的 :)

7) 安全

一些主要原则

a. 基础设施模块应该通过API server交换数据、修改系统状态,而且只有API server可以访问后端存储(etcd)

b. 把用户分为不同的角色:Developers/Project Admins/Administrators

c. 允许Developers定义secrets 对象,并在pod启动时关联到相关容器

以secret 为例,如果kubelet要去pull 私有镜像,那么kubernetes支持以下方式:

1)通过docker login 生成 .dockercfg 文件,进行全局授权

2)通过在每个namespace上创建用户的secret对象,在创建Pod时指定 imagePullSecrets 属性(也可以统一设置在serviceAcouunt 上),进行授权

认证 (Authentication)

API server 支持证书、token、和基本信息三种认证方式

授权 (Authorization)

通过apiserver的安全端口,authorization会应用到所有http的请求上

AlwaysDeny、AlwaysAllow、ABAC三种模式,其他需求可以自己实现Authorizer接口

8) 监控

比较老的版本kubernetes需要外接cadvisor,主要功能是将node主机的container metrics抓取出来。在较新的版本里,cadvior功能被集成到了kubelet组件中,kubelet在与docker交互的同时,对外提供监控服务。

kubernetes集群范围内的监控主要由kubelet, heapster和storage backend(如influxdb)构建。Heapster可以在集群范围获取metrics和事件数据。它可以以pod的方式运行在k8s平台里,也 可以单独运行以standalone的方式。

注意: heapster目前未到1.0版本,对于小规模的集群监控比较方便。但对于较大规模的集群,heapster目前的cache方式会吃掉大量内存。因为 要定时获取整个集群的容器信息,信息在内存的临时存储成为问题,再加上heaspter要支持api获取临时metrics,如果将heapster以 pod方式运行,很容易出现OOM。所以目前建议关掉cache,并以standalone的方式独立出k8s平台。

今天的分享就到这里,感谢大家的参与,也希望大家多多贡献Kubernetes相关的技术话题,一起分享、共同进步。最后,感谢Dockone社区安排这次分享活动,谢谢!

整理一下会上的主要问题和解答:

1. kubelet本身也跑在pod里吗?

答:可以跑在容器里,也可以跑在host上,可以尝试hyperkube的集成工具

2. roollback的具体机制

答:感觉应该通过lablel,再一个个替换已经升级的pod,不过还没仔细研究过

3. mesos和kubernetes到底有什么区别?感觉有很多重合的地方

答:mesos和kubernetes侧重点不同,确实有一些重合的地方;mesos更擅长资源管理,支持上层framework,k8s原生为容器设计,更关注app相关的一些问题。

4. “比如用HAProxy,直接导流到service的endpoints或者Pods 上”,haproxy如何导流到Pod上,podIP不是不固定的吗?

答:可以通过watch etcd或者api server的方式,监听变化来更新haproxy;kubeproxy改用haproxy,只是external loadbalancer的方式;如果要替换,需要重新开发。

5. 有没有可以推荐的分布式Volume方案?你们使用起来性能如何?

答:分布式volume,可以尝试rbd,性能的话就需要自己多多测试,不断调优了;有用户提到在使用moosefs做存储,对glusterfs的支持也很多

6. k8s的插件规范吗?还是直接硬改?

答:有些还是比较规范的,可以plugin方式;有些还需要后续版本的调整,否则要动源码了

7. k8s 如何监听docker 的事件,比如:在意外退出前,想抛出一些额外的事件,通知lb如何做?

答:不确定这个是监听docker的哪些事件,再pod,rc层面可以进行watch。

8. k8s如何设置各个pod的依赖和启动顺序?

答:目前没看到很好的控制Pod的依赖和启动顺序的机制, 可以在应用层面避免这些依赖和顺序问题

9. 问一下k8s 集群内部容器间网络这块的解决方案有哪些,类似flannel这类方案的性能问题有什么好的解决方案?

答:目前flannel有其他的替代方案,但flannel部署比较方便,贴近kubernetes的整体工作模式;性能上,如果做联机内网,总 会有损耗,这个需要取舍了;有用户反映,华为的测试结果说ovs比flannel好,但是自己没有实际测试过;flannel的性能可以看coreos官 网的blog,上面有测试报告。

10. 先用容器做轻量级虚拟机,容器间可以通过hsotname访问,不知如何动手?

答:k8上的内网dns(kube2dns + skydns_ 应该可以满足需求,可以尝试一下

11. k8s的日志收集,有什么好的经验?

答:我们目前也在尝试一些工具和解决方案,用户也提到了logstash,fluent等,以后可以搞个专题分享一下

12. 有没有好的监控工具?

答:可以参考dockone上的另外一篇文章: http://dockone.io/article/397