Kubernetes1.3新特性:rktnetes

(一)  背景资料

对于Kubernetes来说,从架构设计上就是支持Docker和CoreOS rkt两种容器的,在1.2版本中,最低支持CoreOS rkt 0.13.0版本,这个rkt版本算是一个开发测试版本。CoreOS rkt在2016年正式发布了1.0,rkt从1.0开始算是一个正式生产版本了,Kubernetes在1.3中最低支持CoreOS rkt 1.9.1。由于Kubernetes支持了CoreOS rkt正式生产版本,也就意味着Kubernetes真正可以在生产环境中同时实现对Docker和CoreOS rkt的支持,所以把”在Kubernetes中使用rkt“又称作”rktnetes“,用来突出rkt在Kubernetes中的作用。

(二)  CoreOS rkt同Docker对比

Docker需要有一个后台运行的Daemon,命令都是通过Docker Daemon进行执行,如果Daemon没有在后台运行,那么就无法执行Docker命令,而且应用容器的虚拟网络也可能会依赖于Daemon的虚拟网络。CoreOS rkt主要采用命令行直接执行,不需要后台运行的Daemon。

在对Docker进行升级时,至少需要升级Docker Engine daemon,如果应用容器的虚拟网络正在通过Docker Engine daemon进行通讯,那么此时应用容器上业务就会受到影响,但是对CoreOS rkt进行升级更新的时候,并不会影响已经运行的应用容器,但是因为应用容器的网络并不是通过Daemon的虚拟网络进行通讯的。

下面是CoreOS rkt同Docker处理模型对比图:


从图中可以看到:

1)       当在rkt1.0及以后版本上运行redis容器时,通过命令行执行一次类似“rkt run redis”的命令就可以启动application应用;

2)       当在Docker1.11以前版本运行redis容器时,执行类似“Docker run redis”的命令后,实际上是同Docker Engine进行通讯,由Docker Engine来启动application应用;

3)       当在Docker1.11及以后版本上运行redis容器时,执行类似“Docker run redis”的命令后,先同Docker Engine进行通讯,接着由Docker Engine同containerd进行通讯,然后由containerd同runC进行通讯,最后由runC来启动application应用。

根据对比至少可以分析出CoreOS rkt在启动的时候比Docker更简单,这种简单的好处在于遇到问题的时候可以快速的进行排查。同时还可以看出来,CoreOS rkt的这种设计更加遵循linux/unix架构的最佳实践,因为应用容器都是直接可以被操作系统systemd核心进程直接进行控制的,但是Docker中应用容器都是被Docker Engine这个进程控制的,操作系统systemd核心进程只是直接控制Docker Engine进程。

这里并不是说Docker架构设计不好,Docker采用Docker Engine这种中心化架构设计其实也是有优势的,其中包括这种设计更适合开发,因为Docker Engine提供了对外统一的API接口,所以开发人员直接可以使用这些API接口进行开发。

下面是CoreOS rkt同Docker在linux权限模型上的对比图:

Kubernetes1.3新特性:rktnetes_第1张图片

从图中可以看到:

1)       docker dasemon需要root用户权限,也就是说操作系统必须为Docker开放一个最高级别权限;

2)       CoreOS rkt不需要root用户权限,可以完全按照linux/unix权限方案来使用;

根据对比可以可以分析出:CoreOS rkt设计上就是使用标准的linux/unix权限方案,可以利用linux/unix操作系统自带的权限方案在不同操作之间进行权限控制,但是Docker不是,因为Docker必须使用草系统最高级别权限。

(三)  K8S中使用CoreOS rkt

1)       前置条件

  • 需要在Kubernetes1.3管理的计算节点上安装linux操作系统,并且操作系统中systemd最低版本是219,这个版本的systemd要求Linux kernel>= 3.7,是2015年2月份发布的版本。
  • 需要在Kubernetes1.3管理的节点上安装CoreOSrkt,并且最低版本是1.9.1,是2016年6月份发布的版本。
  • 需要在Kubernetes1.3管理的节点上安装rktapi-service,版本是v1alpha,rkt api-service默认监听端口15441,所以需要保证这个端口可以被访问。这个api-service的作用在于从rkt容器中收集监控信息,包括节点上运行的rkt pod数量、每个rkt pod名称和网络设置、rkt pod详细配置信息、资源配额等数据,更形象的说就是在执行kubectl describe命令时显示的内容就是从rkt api-service获取的。

2)       配置kubelet参数

  • 配置参数“--container-runtime=rkt”,表示在这个节点上使用CoreOSrkt容器
  • 配置参数“rkt-api-endpoint=HOST:PORT”,表示rktapi-service入口,默认是localhost:15441
  • 配置参数“--rkt-path=PATH_TO_RKT_BINARY”,表示rkt命令所在路径,这是一个可选的配置参数,如果为空的话,kubelet会从操作系统$PATH中查找rkt命令
  • 配置参数“--rkt-stage1-image=STAGE1”,按照CoreOS rkt的stage1方式来使用容器镜像,在将来kubernetes版本中会把这个参数删除掉,因为可以通过rkt配置文件来配置,具体可以参考https://github.com/coreos/rkt/blob/master/Documentation/configuration.md。

3)       Kubelet使用CoreOS rkt流程


  • 容器生命周期管理流程:使用systemd来调度和管理容器运行环境,CoreOS rkt遵循AppC(应用容器规范),而AppC规范定义基本执行单元是POD。涉及生命周期管理的操作,均是kubelet通过systemd来实现,这些操作包括启动POD、停止POD、重启POD、杀掉结束的进程等
  • 信息收集:从rkt容器中收集监控信息,包括节点上运行的rkt pod数量、每个rkt pod名称和网络设置、rkt pod详细配置信息、资源配额等数据,另外也通过api-service收集POD日志信息

4)       CoreOS rkt限制

  • 挂载卷的路径不存在时会报错

当创建POD时,如果挂载到POD中的路径在节点上不存在的时候,如果容器运行环境是rkt,那么会报错,但是如果容器运行环境是Docker的时候,会创建一个空目录,不会报错。比如按照下面配置文件来创建POD,如果容器运行环境是rkt,那么就会报错。

apiVersion: v1
kind: Pod
metadata:
  labels:
    name: mount-dne
  name: mount-dne
spec:
  volumes:
  - name: does-not-exist
    hostPath:
      path: /does/not/exist
  containers:
    - name: exit
      image: busybox
      command:["sh", "-c", "ls /test; sleep 60"]
      volumeMounts:
      - mountPath: /test
        name:does-not-exist
  • 不支持的kubectl命令

kubectl是操作kubernetes集群的命令行工具,kubectl语法如下:

kubectl [command] [TYPE] [NAME] [flags]

如果容器运行环境使用的是CoreOSrkt,那么下面kubectl参数是不被支持的:

•       --attach=true

•       --leave-stdin-open=true

•       --rm=true

  • 不支持初始化容器

在kubernetes1.3的POD中,有两类容器,一类是系统容器(POD Container),一类是用户容器(User Container),在用户容器中,现在又分成两类容器,一类是初始化容器(Init Container),一类是应用容器(App Container),其中应用容器包含卷容器(Volume Container)。POD同初始化容器之间的对应关系是从0到N,POD同应用容器之间的对应关系是从1到N。

Kubernetes1.3新特性:rktnetes_第2张图片

如果使用的是CoreOSrkt容器运行环境,那么是无法使用kubernetes1.3的初始化容器这个新功能的。

  • 不支持Nvidia品牌GPU

在kubernetes1.3中提供了对Nvidia品牌GPU的支持,在kubernetes管理的集群中每个节点上,通过将原有的Capacity和Allocatable变量进行扩展,增加了一个针对Nvidia品牌GPU的α特性:alpha.kubernetes.io/nvidia-gpu。其中Capacity变量表示每个节点中实际的资源容量,包括cpu、memory、storage、alpha.kubernetes.io/nvidia-gpu,而Allocatable变量表示每个节点中已经分配的资源容量,同样包括包括cpu、memory、storage、alpha.kubernetes.io/nvidia-gpu。

Kubernetes1.3新特性:rktnetes_第3张图片

如果使用的是CoreOSrkt容器运行环境,那么是无法使用kubernetes1.3对Nvidia品牌GPU支持这个新功能的。

  • 不支持容器的OOM(Out of Memory)分数值调整

对于kubernetes来说,如果容器运行环境使用的是Docker,那么通过cgroup就可以给POD设置QoS级别,当资源不够使用时,先kill优先级低的POD,在实际使用时,是通过OOM(Out of Memory)分数值来实现的,OOM分数值从0到1000。OOM分数值是根据OOM_ADJ参数计算出来的,对于Guaranteed级别的POD,OOM_ADJ参数设置成了-998,对于BestEffort级别的POD,OOM_ADJ参数设置成了1000,对于Burstable级别的POD,OOM_ADJ参数取值从2到999,对于kube保留的资源,比如kubelet,OOM_ADJ参数设置成了-999。OOM_ADJ参数设置的越大,通过OOM_ADJ参数计算出来的OOM分数越高,OOM分数越高,这个POD的优先级就越低,在出现资源竞争的时候,就越早被kill掉,对于OOM_ADJ参数是-999的代表kubernetes永远不会因为OOM而被kill掉。如下图所示:

Kubernetes1.3新特性:rktnetes_第4张图片

如果使用的是CoreOSrkt容器运行环境,那么就不会对OOM(Out of Memory)分数值进行调整。

(四)  rktnetes总结

在kubernete1.3中,把”在Kubernetes中使用rkt“又称作”rktnetes“,用来突出rkt在Kubernetes中的作用,可以推断出在kubernetes开源项目发展过程中CoreOS团队起到了很重要的作用。在Docker1.12版本以后融合入swarm编排功能后,kubernetes更需要一个纯粹的容器运行环境来支撑,而CoreOS rkt就是一个专注性强的容器运行环境,并不涉及集群编排和节点管理,所以在1.13版本中突出了一个单词”rktnetes“很有象征意义。

不可否认,CoreOS rkt是按照unix/linux使用最佳实践来架构设计的,所以就像是在前面“CoreOS rkt同Docker对比“中介绍过的那样,rktnetes具有下面两项优势:

  • 安全性高:CoreOSrkt可以不使用root权限运行,这样就避免不必要的操作获取root权限问题,不会被第三方获取root权限,从而保证容器运行环境和操作系统整体安全,例如rkt不允许以root权限执行容器发现与检索,从而解决容器执行默认要求root权限的难题。
  • 容易集成:CoreOSrkt按照unix/linux使用最佳实践来架构设计,力求将rkt体现为一个操作系统命令,不需要长期运行的后台守护进程,rkt采用的无守护程序模式意味着其能够轻松与操作系统标准init系统相集成,例如systemd与upstart。此外由于CoreOS rkt遵循AppC(应用容器规范),而AppC规范定义基本执行单元是POD,一个POD就是一组应用容器镜像,POD中的容器共享相同的进程上下文,比如共享相同的网络,这种设计同kubernetes的POD如出一辙,所以CoreOS rkt很容易同Kubernetes进行集成。

你可能感兴趣的:(云计算,docker,KUBERNETES,CoreOS,rkt)