全球5000名开发者容器使用率,K8S继续领跑,Mesos只有3%,Serverless逐渐火热

中文社区阅读(995)评论(0)

从2017年9月开始,公有云服务商DigitalOcean开始每季发布开发者调查报告。每一季的报告,都会根据当时IT趋势而有所差异,像今年3月所发布的报告,就针对欧盟个资保护法GDPR,以及FCC决定废止网络中立性的政策,了解使用者的想法。这次该公司发布的使用者调查报告,访问了全球近5,000名开发者,了解各企业对容器、(无服务器)Serverless以及其他软件开发工具的使用趋势。

「容器技术的开发动能仍在增强」,DigitalOcean表示,随着容器技术、容器调度管理工具的快速进步,已经有49%的使用者开始利用容器技术,在软件开发上,容器技术已经可说是开发者必备的工具之一。相比之下,Serverless应用仍处于早期采用阶段,半数开发者对Serverless技术相当陌生。至于已经尝试使用该技术的开发者,「监控及除错是他们碰上最大的挑战。」

当Docker公司将容器技术热潮掀起时,Docker容器的快速开启、快速部署,以及高移植性等特性马上就受到开发者的热烈欢迎。调查报告显示,有39%的开发者认为,容器技术的高度扩充性是此技术带来最大的效益。而第二个受到使用者青睐的特质,就是让软件开发变得更简单(24%)。值得注意的是,容器技术的便捷性,能解决企业被特定厂商死锁的特质,也受到10%的开发者认同。

而利用容器技术镜像建立标准交付格式,也是开发圈加快应用交付的常见用法。在CI/CD流程与容器应用整合中,有42%的受访者表示,他们会结合持续整合、持续交付工具,加速容器应用生命周期的自动化。

在提到容器技术时,也一定会谈到容器调度工具的导入。当基础架构规格超过一定程度时,必须仰赖这些工具管理庞大的容器集群。果不其然,Kubernetes以42%的使用率拔得此份调查头筹。而Docker Swarm仍然有一定影响力,有35%的开发者仍继续使用该工具。而原本与Kubernetes、Docker Swarm三分天下的Mesos,仅剩3%的开发者使用。

不过,DigitalOcean表示,已经开始用容器的开发者,仍有52%还未导入容器调度平台。在调查容器调度工具议题中,DigitalOcean也发现几个有趣的结论。在1至5人的微型企业,Docker Swarm的使用率(41%)比Kubernetes(31%)还更高。而使用容器调度工具的开发者,超过半数(51%)每周都因此省下至少5小时的维运时间。

除了容器技术,Serverless应用也是这次DigitalOcean的调查重点。除云端容器服务,当今公有云厂商也开始建立Serverless应用平台,插入这块新市场。调查开始使用Serverless应用的用户群体中,结果显示,58%的用户导入了AWS Lambda作为Serverless应用执行平台,殿后的是Google Cloud Functions(23%),而微软Azure Functions则以10%拿下第三名。

比照容器技术调查,DigitalOcean也访问使用者,了解Serverless技术带来的优点。而该技术最受青睐的特色,就是省去使用者自行建立服务器的成本(33%),其次则是让开发者能花更多时间改善应用(28%)。再者是让应用能更快速部署(23%)。

而历经三五年酝酿的容器技术,在厂商、社群积极推广下已逐渐成熟。相比之下,Serverless应用还属于早期采用阶段。尚未熟悉该技术的开发者,有81%受访者表示,会在今年起深入了解研究。而已经导入Serverless应用的开发者,最多人碰上的挑战是该应用不易监控、除错(27%)。而当今Serverless应用也相当依赖公有云厂商服务,因此,其中有25%开发者担心被厂商绑定,20%更表示导入Serverless应用,得依赖第三方厂商提供的解决方案。

图片来源:DigitalOcean

有39%的开发者认为,容器技术的高度扩充性是此技术带来最大的效益。而第二个受到使用者青睐的特质,就是让软件开发变得更简单(24%)。

图片来源:DigitalOcean

Kubernetes以42%的使用率拔得此份调查头筹。而Docker Swarm仍然有一定影响力,有35%的开发者仍继续使用该工具。而原本与Kubernetes、Docker Swarm三分天下的Mesos,仅剩3%的开发者使用。

图片来源:DigitalOcean

开始应用Serverless技术的企业,58%的使用者导入了AWS Lambda作为Serverless应用执行平台,殿后的是Google Cloud Functions(23%),而微软Azure Functions则以10%拿下第三名。

 

图片来源:DigitalOcean

开发者使用容器搭配的程序语言,按照使用排名依序是JavaScript(57%)、Python(46%)、PHP(36%)、Go(28%)、Java(27%)等。

原文:https://www.ithome.com.tw/news/124290

Kubernetes 1.11发布:集群内负载均衡与CoreDNS插件正式上线

中文社区阅读(1991)评论(1)

今天,我们兴奋地公布Kubernetes 1.11版本——亦是2018年这一项目的第二个发布版本!

今天发布的版本旨在不断推进Kubernetes的成熟度、可扩展性与灵活性,同时亦标志着其研发团队在过去一年中的努力工作取得了重大进展。这一最新版本的主要亮点集中在网络层面,以beta测试形式开放来自SIG-API Machinery与SIG-Node的两项主要功能,同时进一步增强在此前两个版本中已经得到高度重视的存储功能。在这一最新版本中,用户将能够更轻松地将任意基础设施——无论云平台还是内部环境——接入Kubernetes当中。

本版本当中最值得关注的,是增加了两项备受期待的功能,分别为:基于IPVS的集群内负载均衡,以及将CoreDNS作为集群DNS的附加选项——这意味着生产应用的可扩展性与灵活性都将得到提升。

下面,我们将就最新版本的核心特性展开讨论:

基于IPVS的集群内服务负载均衡正式上线

在本次版本中,基于IPVS的集群内服务负载均衡功能已经趋于稳定。IPVS(即IP虚拟服务器)能够提供高性能内核负载均衡功能,且其编程接口较iptables更为简单。这一变化使得网络吞吐量更上一层楼、提供更低的编程延迟,同时亦使由Kubernetes Service模式组成的集群范围内分布式负载均衡器获得更高的可扩展性水平。目前IPVS仍不属于默认设置,但大家已经可以利用其处理生产流量。

CoreDNS正式上线

CoreDNS现在被正式作为集群DNS附加选项,且在用户使用kubeadm时默认生效。CoreDNS是一套灵活且可扩展的权威DNS服务器,可直接与Kubernetes API相集成。相较于原有DNS服务器,CoreDNS的移动部件更少——仅包含单一可执行文件与单一进程,且允许用户通过创建自定义DNS条目以支持更为灵活的用例。其同样使用Go语言编写而成,因此天然具备更理想的安全性水平。感兴趣的朋友可以点击此处参阅关于CoreDNS的更多细节信息。

动态Kubelet配置步入Beta测试阶段

通过这项改进,用户可以将新的Kubelet配置部署在运行中的集群之内。在此之前,Kubelet需要通过命令行标记进行配置,这导致我们很难对运行中的集群进行Kubelet配置更新。在此次beta功能的帮助下,用户将能够通过API服务器随时配置运行中集群内的Kubelet

定制化资源定义现在可定义多个版本

定制化资源定义不再局限于对单一版本的定制化资源作出定义。如今,利用此项beta测试功能,用户可以为资源定义多个版本。未来,其还将进一步扩展以支持版本间自动转换功能。目前,该功能允许定制化资源作者“以安全变更的方式实现版本升级,例如由v1beta1切换至v1”,并为发生变化的资源创建迁移路径。

定制化资源定义如今还能够支持“状态”与“规模”两类子资源,这些子资源可与各类监控与高可用性框架相集成。这两项变化显著提升了在生产环境中利用定制化资源定义运行云原生应用程序的能力。

CSI增强

容器存储接口(简称CSI)在之前的几个版本当中一直得到高度关注。在1.10版本以beta形式发布之后,1.11版本进一步增强了CSI功能。1.11版本为CSI带来了对原始数据块分卷的alph支持能力,将CSI与新的kubelet插件注册机制相集成,同时降低了向CSI插件传递秘密凭证的难度。

新的存储功能

对持久分卷进行在线大小调整已经以alpha测试功能的形式引入新版本。这意味着用户能够增加持久分卷的大小,而完全无需终止pod并卸载对应分卷。用户可以更新VPC以提交新的分卷大小请求,kubelet则负责完成文件系统的大小调整。

动态最大分卷数量以alpha测试版的形式加入新版本。这项新功能使得入树分卷插件能够指定可接入节点的最大分卷数量,且允许根据节点类型的区别设定不同最大分卷量。在此之前,这些限制需要通过硬编码形式或配置环境变量来实现。

StorageObjectInUseProtection功能目前已经迎来稳定版本,并可防止绑定至持久分卷声明的持久分卷以及由pod使用的持久分卷声明遭到删除。此项安全措施将有助于防止用户不小心删除绑定至运行中pod的PV或PVC。

社区中的各个特别兴趣小组(简称SIG)都将继续立足各自专业领域实现呼声最高的增强、修复与功能。关于SIG的完整内容列表,请点击此处参阅发行版说明。

正式上线

Kubernetes 1.11目前已经可通过GitHub进行下载。要开始使用Kubernetes,请点击此处参阅相关交互式教程。

您也可以利用Kubeadm安装1.11版本。1.11.0版本将以Deb与RPM软件包的形式提供,并于6月28日通过Kubeadm集群安装器进行安装。

原文链接:Kubernetes 1.11: In-Cluster Load Balancing and CoreDNS Plugin Graduate to General Availability

来源:http://www.dockone.io/article/6050

Kubernetes-基于Prometheus和Grafana进行性能监控

Daniel_Ji阅读(1647)评论(0)

1、Prometheus介绍和架构

1.1 Prometheus介绍

Prometheus是一个开源的系统监视和警报工具包,自2012成立以来,许多公司和组织采用了Prometheus。它现在是一个独立的开源项目,并独立于任何公司维护。在2016年,Prometheus加入云计算基金会作为Kubernetes之后的第二托管项目。
Prometheus的关键特性如下:

  • 由度量名和键值对标识的时间序列数据的多维数据模型
  • 灵活的查询语言
  • 不依赖于分布式存储;单服务器节点是自治的
  • 通过HTTP上的拉模型实现时间序列收集
  • 通过中间网关支持推送时间序列
  • 通过服务发现或静态配置发现目标
  • 图形和仪表板支持的多种模式

Prometheus的组件:

Prometheus生态由多个组件组成,并且这些组件大部分是可选的:

  • Prometheus服务器,用于获取和存储时间序列数据;
  • 仪表应用数据的客户端类库(Client Library)
  • 支持临时性工作的推网关(Push Gateway)
  • 特殊目的的输出者(Exporter),提供被监控组件信息的 HTTP 接口,例如HAProxy、StatsD、MySQL、Nginx和Graphite等服务都有现成的输出者接口
  • 处理告警的告警管理器(Alert Manager)
  • 其它支持工具

Prometheus的整体架构

Prometheus从jobs获取度量数据,也直接或通过推送网关获取临时jobs的度量数据。它在本地存储所有被获取的样本,并在这些数据运行规则,对现有数据进行聚合和记录新的时间序列,或生成警报。通过Grafana或其他API消费者,可以可视化的查看收集到的数据。下图显示了Pometheus的整体架构和生态组件:

Prometheus architecture

Prometheus的整体工作流程:

1)Prometheus 服务器定期从配置好的 jobs 或者 exporters 中获取度量数据;或者接收来自推送网关发送过来的 度量数据。

2)Prometheus 服务器在本地存储收集到的度量数据,并对这些数据进行聚合;

3)运行已定义好的 alert.rules,记录新的时间序列或者向告警管理器推送警报。

4)告警管理器根据配置文件,对接收到的警报进行处理,并通过email等途径发出告警。

5)Grafana等图形工具获取到监控数据,并以图形化的方式进行展示。

1.2 Prometheus关键概念

1.2.1 数据模型

Prometheus从根本上将所有数据存储为时间序列:属于相同度量标准和同一组标注尺寸的时间戳值流。除了存储的时间序列之外,普罗米修斯可能会生成临时派生时间序列作为查询的结果。

  • 度量名称和标签:每个时间序列都是由度量标准名称和一组键值对(也称为标签)组成唯一标识。度量名称指定被测量的系统的特征(例如:http_requests_total-接收到的HTTP请求的总数)。它可以包含ASCII字母和数字,以及下划线和冒号。它必须匹配正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*。标签启用Prometheus的维度数据模型:对于相同度量标准名称,任何给定的标签组合都标识该度量标准的特定维度实例。查询语言允许基于这些维度进行筛选和聚合。更改任何标签值(包括添加或删除标签)都会创建新的时间序列。标签名称可能包含ASCII字母,数字以及下划线。他们必须匹配正则表达式[a-zA-Z_][a-zA-Z0-9_]*。以__开始的标签名称保留给供内部使用。
  • 样本:实际的时间序列,每个序列包括:一个 float64 的值和一个毫秒级的时间戳。
  • 格式:给定度量标准名称和一组标签,时间序列通常使用以下格式来标识:

    <metric name>{<label name>=<label value>, ...}
    

    例如,时间序列的度量名称为api_http_requests_total,标签method=”POST”和handler=”/messages”,则标记为:

    api_http_requests_total{method="POST", handler="/messages"}

1.2.2 度量类型

Prometheus 客户端库主要提供Counter、Gauge、Histogram和Summery四种主要的 metric 类型:

  • Counter(计算器):Counter是一种累加的度量,它的值只能增加或在重新启动时重置为零。例如,您可以使用计数器来表示提供的请求数,已完成的任务或错误的数量。不要使用计数器来表达可减少的值。例如,不要使用Counter来计算当前正在运行的进程的数量,而是使用Gauge。
  • Gauge(测量):Gauge表示单个数值,表达可以任意地上升和下降的度量。Gauge通常用于测量值,例如温度或当前的内存使用情况,但也可以表达上升和下降的“计数”,如正在运行的goroutines的数量。
  • Histogram(直方图):Histogram样本观测(例如:请求持续时间或响应大小),并将它们计入配置的桶中。它也提供所有观测值的总和。具有<basename>基本度量标准名称的histogram的在获取数据期间会显示多个时间序列:
    • 观察桶的累计计数器,暴露为 <basename>_bucket{le=”<upper inclusive bound>”}
    • 所有观察值的总和,暴露为<basename>_sum
    • 已观察到的事件的计数,暴露为<basename>_count(等同于<basename>_bucket{le=”+Inf”})

    Summery类似于HistogramSummery样本观察(通常是请求持续时间和响应大小)。虽然它也提供观测总数和所有观测值的总和,但它计算滑动时间窗内的可配置分位数。在获取数据期间,具有<basename>基本度量标准名称的Summery会显示多个时间序列:

    • 流动φ分位数(0≤φ≤1)的观察事件,暴露为<basename>{quantile=”<φ>”}
    • 所有观察值的总和,暴露为<basename>_sum
    • 已经观察到的事件的计数,暴露为<basename>_count

1.2.3 工作和实例

按照Prometheus的说法,可以获取数据的端点被称为实例(instance),通常对应于一个单一的进程。具有相同目的的实例集合(例如为了可伸缩性或可靠性而复制的进程)称为作业(job)

例如,具有四个复制实例的API服务器作业:

  • 工作: api-server
    • 实例1: 1.2.3.4:5670
    • 实例2: 1.2.3.4:5671
    • 实例3: 5.6.7.8:5670
    • 实例4: 5.6.7.8:5671

自动生成标签和时间序列

当Prometheus获取目标时,它会自动附加一些标签到所获取的时间序列中,以识别获取目标:

  • job:目标所属的配置作业名称。
  • instance:<host>:<port>被抓取的目标网址部分。

如果这些标签中的任何一个已经存在于抓取的数据中,则行为取决于honor_labels配置选项。

对于每个实例抓取,Prometheus会在以下时间序列中存储一个样本:

  • up{job=”<job-name>”, instance=”<instance-id>”}:1 如果实例健康,即可达;或者0抓取失败。
  • scrape_duration_seconds{job=”<job-name>”, instance=”<instance-id>”}:抓取的持续时间。
  • scrape_samples_post_metric_relabeling{job=”<job-name>”, instance=”<instance-id>”}:应用度量标准重新标记后剩余的样本数。
  • scrape_samples_scraped{job=”<job-name>”, instance=”<instance-id>”}:目标暴露的样本数量。

up时间序列是实例可用性的监控。

1.3 使用Helm在Kubernetes中部署Prometheus

1.3.1 环境要求

1.3.2 Helm chart配置

下表列示了Prometheus chart的配置参数和默认值:

参数 描述 默认值
alertmanager.enabled 如果为true,创建告警管理器 true
alertmanager.name 告警管理器容器名称 alertmanager
alertmanager.image.repository 告警管理器容器镜像仓库 prom/alertmanager
alertmanager.image.tag 告警管理器容器镜像标记 v0.13.0
alertmanager.image.pullPolicy 告警管理器容器镜像拉取策略 IfNotPresent
alertmanager.prefixURL The prefix slug at which the server can be accessed
alertmanager.baseURL The external url at which the server can be accessed /
alertmanager.extraArgs 额外的告警管理器容器参数 {}
alertmanager.configMapOverrideName Prometheus alertmanager ConfigMap override where full-name is {{.Release.Name}}-{{.Values.alertmanager.configMapOverrideName}}and setting this value will prevent the default alertmanager ConfigMap from being generated ""
alertmanager.ingress.enabled If true, alertmanager Ingress will be created false
alertmanager.ingress.annotations 告警管理器Ingress注释 {}
alertmanager.ingress.extraLabels 警告管理器Ingress额外标签 {}
alertmanager.ingress.hosts 警告管理器Ingress主机名称 []
alertmanager.ingress.tls 警告管理器Ingress TLS配置(YAML) []
alertmanager.nodeSelector 用于警告管理器pod指派的node标签 {}
alertmanager.tolerations node玷污容忍 (requires Kubernetes >=1.6) []
alertmanager.schedulerName 警告管理器警告调度名称 nil
alertmanager.persistentVolume.enabled 如果为true,告警管理器江创建一个持久化存储卷声明 true
alertmanager.persistentVolume.accessModes 告警管理器数据持久化存储访问模式 [ReadWriteOnce]
alertmanager.persistentVolume.annotations 持久化存储卷声明注释 {}
alertmanager.persistentVolume.existingClaim 告警管理器数据持久化存储卷存在声明名称 ""
alertmanager.persistentVolume.mountPath 告警管理器数据持久化存储卷挂接根路径 /data
alertmanager.persistentVolume.size 告警数据持久化存储卷大小 2Gi
alertmanager.persistentVolume.storageClass 告警管理器数据持久化存储卷存储类 unset
alertmanager.persistentVolume.subPath Subdirectory of alertmanager data Persistent Volume to mount ""
alertmanager.podAnnotations 添加到告警管理器Pod中的注释 {}
alertmanager.replicaCount 告警管理器Pod的期望副本数量 1
alertmanager.resources 告警管理器Pod资源请求和限制 {}
alertmanager.securityContext 为告警管理器容器定制安全上下文 {}
alertmanager.service.annotations 告警管理器服务的注释 {}
alertmanager.service.clusterIP 内部的告警管理器集群服务IP ""
alertmanager.service.externalIPs 告警管理器服务外部IP地址 []
alertmanager.service.loadBalancerIP 指派给负载均衡器的IP地址 ""
alertmanager.service.loadBalancerSourceRanges list of IP CIDRs allowed access to load balancer (if supported) []
alertmanager.service.servicePort 告警管理器服务端口 80
alertmanager.service.type 告警管理器服务的类型 ClusterIP
alertmanagerFiles.alertmanager.yml Prometheus告警管理器配置 example configuration
configmapReload.name configmap-reload container name configmap-reload
configmapReload.image.repository configmap-reload container image repository jimmidyson/configmap-reload
configmapReload.image.tag configmap-reload container image tag v0.1
configmapReload.image.pullPolicy configmap-reload container image pull policy IfNotPresent
configmapReload.extraArgs Additional configmap-reload container arguments {}
configmapReload.extraConfigmapMounts Additional configmap-reload configMap mounts []
configmapReload.resources configmap-reload pod resource requests & limits {}
initChownData.enabled If false, don’t reset data ownership at startup true
initChownData.name init-chown-data container name init-chown-data
initChownData.image.repository init-chown-data container image repository busybox
initChownData.image.tag init-chown-data container image tag latest
initChownData.image.pullPolicy init-chown-data container image pull policy IfNotPresent
initChownData.resources init-chown-data pod resource requests & limits {}
kubeStateMetrics.enabled If true, create kube-state-metrics true
kubeStateMetrics.name kube-state-metrics容器名称 kube-state-metrics
kubeStateMetrics.image.repository kube-state-metrics容器镜像仓库 quay.io/coreos/kube-state-metrics
kubeStateMetrics.image.tag kube-state-metrics容器镜像版本 v1.3.1
kubeStateMetrics.image.pullPolicy kube-state-metrics容器镜像拉取策略 IfNotPresent
kubeStateMetrics.args kube-state-metrics容器参数 {}
kubeStateMetrics.nodeSelector node labels for kube-state-metrics pod assignment {}
kubeStateMetrics.podAnnotations annotations to be added to kube-state-metrics pods {}
kubeStateMetrics.tolerations node taints to tolerate (requires Kubernetes >=1.6) []
kubeStateMetrics.replicaCount kube-state-metrics Pod的期望副本数量 1
kubeStateMetrics.resources kube-state-metrics资源请求和限制(YAML) {}
kubeStateMetrics.securityContext 为kube-state-metrics容器定制安全上下文 {}
kubeStateMetrics.service.annotations kube-state-metrics服务的注释 {prometheus.io/scrape: "true"}
kubeStateMetrics.service.clusterIP 内部的kube-state-metrics集群服务IP None
kubeStateMetrics.service.externalIPs kube-state-metrics服务外部IP地址 []
kubeStateMetrics.service.loadBalancerIP 指派给负载均衡的IP地址(如果支持的话) ""
kubeStateMetrics.service.loadBalancerSourceRanges list of IP CIDRs allowed access to load balancer (if supported) []
kubeStateMetrics.service.servicePort kube-state-metrics服务端口 80
kubeStateMetrics.service.type type of kube-state-metrics service to create ClusterIP
nodeExporter.enabled 如果为true,则创建node-exporter true
nodeExporter.name node-exporter容器名称 node-exporter
nodeExporter.image.repository node-exporter容器镜像仓库 prom/node-exporter
nodeExporter.image.tag node-exporter容器镜像版本 v0.15.2
nodeExporter.image.pullPolicy node-exporter容器镜像拉取策略 IfNotPresent
nodeExporter.extraArgs 额外的node-exporter容器参数 {}
nodeExporter.extraHostPathMounts 额外的node-exporter hostPath 挂接 []
nodeExporter.extraConfigmapMounts Additional node-exporter configMap mounts []
nodeExporter.nodeSelector node labels for node-exporter pod assignment {}
nodeExporter.podAnnotations annotations to be added to node-exporter pods {}
nodeExporter.pod.labels labels to be added to node-exporter pods {}
nodeExporter.tolerations node taints to tolerate (requires Kubernetes >=1.6) []
nodeExporter.resources node-exporter resource requests and limits (YAML) {}
nodeExporter.securityContext securityContext for containers in pod {}
nodeExporter.service.annotations annotations for node-exporter service {prometheus.io/scrape: "true"}
nodeExporter.service.clusterIP internal node-exporter cluster service IP None
nodeExporter.service.externalIPs node-exporter service external IP addresses []
nodeExporter.service.loadBalancerIP IP address to assign to load balancer (if supported) ""
nodeExporter.service.loadBalancerSourceRanges list of IP CIDRs allowed access to load balancer (if supported) []
nodeExporter.service.servicePort node-exporter service port 9100
nodeExporter.service.type type of node-exporter service to create ClusterIP
pushgateway.enabled 如果为true,则创建推送网关 true
pushgateway.name 推送网关容器名称 pushgateway
pushgateway.image.repository pushgateway container image repository prom/pushgateway
pushgateway.image.tag pushgateway container image tag v0.5.1
pushgateway.image.pullPolicy pushgateway container image pull policy IfNotPresent
pushgateway.extraArgs Additional pushgateway container arguments {}
pushgateway.ingress.enabled If true, pushgateway Ingress will be created false
pushgateway.ingress.annotations pushgateway Ingress annotations {}
pushgateway.ingress.hosts pushgateway Ingress hostnames []
pushgateway.ingress.tls pushgateway Ingress TLS configuration (YAML) []
pushgateway.nodeSelector node labels for pushgateway pod assignment {}
pushgateway.podAnnotations annotations to be added to pushgateway pods {}
pushgateway.tolerations node taints to tolerate (requires Kubernetes >=1.6) []
pushgateway.replicaCount desired number of pushgateway pods 1
pushgateway.resources pushgateway pod resource requests & limits {}
pushgateway.service.annotations annotations for pushgateway service {}
pushgateway.service.clusterIP internal pushgateway cluster service IP ""
pushgateway.service.externalIPs pushgateway service external IP addresses []
pushgateway.service.loadBalancerIP IP address to assign to load balancer (if supported) ""
pushgateway.service.loadBalancerSourceRanges list of IP CIDRs allowed access to load balancer (if supported) []
pushgateway.service.servicePort pushgateway service port 9091
pushgateway.service.type type of pushgateway service to create ClusterIP
rbac.create If true, create & use RBAC resources true
server.name Prometheus服务器容器名称 server
server.image.repository Prometheus服务器容器镜像仓库 prom/prometheus
server.image.tag Prometheus服务器容器镜像版本 v2.1.0
server.image.pullPolicy Prometheus服务器容器镜像拉取策略 IfNotPresent
server.enableAdminApi If true, Prometheus administrative HTTP API will be enabled. Please note, that you should take care of administrative API access protection (ingress or some frontend Nginx with auth) before enabling it. false
server.global.scrape_interval How frequently to scrape targets by default 1m
server.global.scrape_timeout How long until a scrape request times out 10s
server.global.evaluation_interval How frequently to evaluate rules 1m
server.extraArgs Additional Prometheus server container arguments {}
server.prefixURL The prefix slug at which the server can be accessed
server.baseURL The external url at which the server can be accessed
server.extraHostPathMounts Additional Prometheus server hostPath mounts []
server.extraConfigmapMounts Additional Prometheus server configMap mounts []
server.extraSecretMounts Additional Prometheus server Secret mounts []
server.configMapOverrideName Prometheus server ConfigMap override where full-name is {{.Release.Name}}-{{.Values.server.configMapOverrideName}} and setting this value will prevent the default server ConfigMap from being generated ""
server.ingress.enabled If true, Prometheus server Ingress will be created false
server.ingress.annotations Prometheus server Ingress annotations []
server.ingress.extraLabels Prometheus服务器Ingress额外标签 {}
server.ingress.hosts Prometheus服务器Ingress主机名称 []
server.ingress.tls Prometheus服务器Ingress TLS配置

(YAML)

[]
server.nodeSelector node labels for Prometheus server pod assignment {}
server.tolerations node taints to tolerate (requires Kubernetes >=1.6) []
server.schedulerName Prometheus服务器告警调度器名称 nil
server.persistentVolume.enabled 如果为true,则为Prometheus服务器创建持久化卷声明 true
server.persistentVolume.accessModes Prometheus server data Persistent Volume access modes [ReadWriteOnce]
server.persistentVolume.annotations Prometheus server data Persistent Volume annotations {}
server.persistentVolume.existingClaim Prometheus server data Persistent Volume existing claim name ""
server.persistentVolume.mountPath Prometheus server data Persistent Volume mount root path /data
server.persistentVolume.size Prometheus服务器数据持久化卷大小 8Gi
server.persistentVolume.storageClass Prometheus服务器数据持久化卷存储类 unset
server.persistentVolume.subPath Subdirectory of Prometheus server data Persistent Volume to mount ""
server.podAnnotations 被添加至Prometheus服务器Pod的注释 {}
server.replicaCount Prometheus服务器Pod的期望副本数量 1
server.resources Prometheus服务器资源请求和限制 {}
server.securityContext 为服务器容器定制安全上下文 {}
server.service.annotations annotations for Prometheus server service {}
server.service.clusterIP internal Prometheus server cluster service IP ""
server.service.externalIPs Prometheus server service external IP addresses []
server.service.loadBalancerIP IP address to assign to load balancer (if supported) ""
server.service.loadBalancerSourceRanges list of IP CIDRs allowed access to load balancer (if supported) []
server.service.nodePort Port to be used as the service NodePort (ignored if server.service.type is not NodePort) 0
server.service.servicePort Prometheus服务器服务端口 80
server.service.type type of Prometheus server service to create ClusterIP
serviceAccounts.alertmanager.create If true, create the alertmanager service account true
serviceAccounts.alertmanager.name name of the alertmanager service account to use or create {{ prometheus.alertmanager.fullname }}
serviceAccounts.kubeStateMetrics.create If true, create the kubeStateMetrics service account true
serviceAccounts.kubeStateMetrics.name name of the kubeStateMetrics service account to use or create {{ prometheus.kubeStateMetrics.fullname }}
serviceAccounts.nodeExporter.create If true, create the nodeExporter service account true
serviceAccounts.nodeExporter.name name of the nodeExporter service account to use or create {{ prometheus.nodeExporter.fullname }}
serviceAccounts.pushgateway.create If true, create the pushgateway service account true
serviceAccounts.pushgateway.name name of the pushgateway service account to use or create {{ prometheus.pushgateway.fullname }}
serviceAccounts.server.create 如果为true,则创建服务器service account true
serviceAccounts.server.name name of the server service account to use or create {{ prometheus.server.fullname }}
server.terminationGracePeriodSeconds Prometheus服务器Pod终止优雅期 300
server.retention (可选) Prometheus数据保留 ""
serverFiles.alerts Prometheus服务器告警配置 {}
serverFiles.rules Prometheus服务器规则配置 {}
serverFiles.prometheus.yml Prometheus服务器抓取配置 example configuration
networkPolicy.enabled 是否启用NetworkPolicy false

1.3.3 通过Chart安装Prometheus

通过执行如下的命令,在Kubernetes中部署Prometheus:

$ helm install stable/prometheus --name=prometheus --namespace=kube-system

通过上述命令,将以默认的配置在Kubernetes中部署Prometheus。

2、Grafana介绍和部署

2.1 Grafana介绍

Grafana是一个开源的度量分析和可视化套件,它用于基础设施和应用分析的时间序列数据可视化。Grafana拥有种类丰富的图表,灵活的布局控制,强大的组织管理功能 (权限控制),支持多种数据库作为数据源。社区提供了丰富的插件和APP 进行功能扩展。Grafana的主要概念如下:

数据源(Data Souce)

Grafana为时间序列数据(数据源)提供多种不同的存储后端。每个数据源都有一个特定的查询编辑器,可根据特定数据源公开的功能进行自定义。目前官方支持以下数据源:Graphite,InfluxDB,OpenTSDB,Prometheus,Elasticsearch,CloudWatch和KairosDB。每个数据源的查询语言和功能显然会非常不同,但可以将来自多个数据源的数据组合到单个仪表板上,每个面板都绑定到属于特定组织的特定数据源。

组织(Oragnization)

Grafana支持多个组织,以支持各种各样的部署模型,包括使用单个Grafana实例为多个可能不受信任的组织提供服务。在很多情况下,Grafana将与单一组织一起部署。每个组织可以有一个或多个数据源。所有仪表板都由特定组织拥有。注意:大多数度量数据库不提供任何类型的用户认证。因此,在Grafana中,数据源和仪表板可供特定组织的所有用户使用。

用户(User)

用户是Grafana中的指定帐户。用户可以属于一个或多个组织,并且可以通过角色分配不同级别的权限。Grafana支持多种内部和外部认证方式来对用户进行身份验证。包括来自自身的集成数据库,来自外部SQL服务器或来自外部LDAP服务器。

行(Row)

行是仪表板内的逻辑分隔符,用于将面板组合在一起。行总是12“单位”宽,这些单位会根据浏览器的水平分辨率进行自动缩放。也可以通过设置自己的宽度来控制一行中面板的相对宽度。利用单位抽象,可以让Grafana适应所有小型和巨大的屏幕。注意:无论您的分辨率或时间范围如何,借助MaxDataPoint功能,Grafana都可以显示完美的数据点数量。

面板(Panel)

面板是Grafana中的基本可视化构建模块。每个面板都提供了一个查询编辑器(取决于在面板中选择的数据源),通过利用查询编辑器可以将数据以可视化方式的显示在面板上,面板提供了各种各样的样式和格式选项。面板可以在仪表板上拖放和重新排列,他们也可以调整大小。目前有四种面板类型:Graph,Singlestat,Dashlist,Table和Text。

查询编辑器(Query Editor)

查询编辑器提供暴露数据源的功能,通过查询编辑器能够查询度量信息。使用查询编辑器可以在时间序列数据库中构建一个或多个查询(针对一个或多个系列)。可以在查询本身的查询编辑器中使用模板变量,这正方式提供了一种基于Dashboard上选定的模板变量动态探索数据的强大方法。Grafana允许通过查询编辑器所在的行来引用查询。如果将第二个查询添加到图形中,则只需输入#A即可引用第一个查询。这为构建复合查询提供了一种简单方便的方法。

仪表板(Dashboard)

仪表板是聚集所有可视化信息的地方,仪表板可以被认为是组织和排列成一个或多个行的一组或多组面板的集合。仪表板的时间段可以通过仪表板右上角的仪表板时间选择器(Dashboard time picker)来控制。仪表板可以利用模板(Templating)使它们更具动态性和交互性。仪表板可以利用注释(Annotations)在面板上显示事件数据。这有助于将面板中的时间序列数据与其他事件相关联。仪表盘(或特定面板)可以通过多种方式轻松共享。可以发送一个链接给能够登录Grafana用户。可以使用快照功能将当前正在查看的所有数据编码为静态和交互式JSON文档。仪表板可以被标记,仪表板选择器可以快速,可搜索地访问特定组织中的所有仪表板。

2.2 基于Helm在Kubernetes中部署Grafana

2.2.1 环境要求

2.2.2 Helm chart配置

下表列示了Grafana chart的配置参数和默认值:

参数 描述 默认值
replicas 副本数量 1
deploymentStrategy 部署策略 RollingUpdate
image.repository 镜像仓库 grafana/grafana
image.tag 镜像版本(Must be >= 5.0.0) 5.0.4
image.pullPolicy 镜像拉取策略 IfNotPresent
service.type Kubernetes服务类型 ClusterIP
service.port 在Kubernetes中暴露的服务端口 9000
service.annotations 服务注释 80
service.labels 服务标签 {}
ingress.enabled 是否启用Ingress false
ingress.annotations Ingress注释 {}
ingress.labels Ingress定制标签 {}
ingress.hosts Ingress accepted hostnames []
ingress.tls Ingress TLS配置 []
resources CPU/Memory resource requests/limits {}
nodeSelector Node labels for pod assignment {}
tolerations Toleration labels for pod assignment []
affinity Affinity settings for pod assignment {}
persistence.enabled 是否使用持久化存储卷存储数据 false
persistence.size 持久化存储卷大小 10Gi
persistence.existingClaim 使用已存在的PVC持久化数据 nil
persistence.storageClassName 持久化存储卷声明类型 nil
persistence.accessModes 持久化访问模式 []
persistence.subPath Mount a sub directory of the persistent volume if set ""
schedulerName 告警调度器名称 nil
env Extra environment variables passed to pods {}
envFromSecret The name of a Kubenretes secret (must be manually created in the same namespace) containing values to be added to the environment ""
extraSecretMounts Additional grafana server secret mounts []
datasources Configure grafana datasources {}
dashboardProviders Configure grafana dashboard providers {}
dashboards Dashboards to import {}
grafana.ini Grafana’s primary configuration {}
ldap.existingSecret The name of an existing secret containing the ldap.toml file, this must have the key ldap-toml. ""
ldap.config Grafana’s LDAP configuration ""
annotations 部署注释 {}
podAnnotations Pod注释 {}
sidecar.dashboards.enabled Enabled the cluster wide search for dashboards and adds/updates/deletes them in grafana false
sidecar.dashboards.label Label that config maps with dashboards should have to be added false
sidecar.datasources.enabled Enabled the cluster wide search for datasources and adds/updates/deletes them in grafana false
sidecar.datasources.label Label that config maps with datasources should have to be added false
smtp.existingSecret The name of an existing secret containing the SMTP credentials, this must have the keys userand password. ""

2.2.3 通过Chart安装Grafana

通过执行如下的命令,在Kubernetes中部署Grafana:

$ helm install stable/grafana --name=grafana --namespace=kube-system

通过上述命令,将以默认的配置在Kubernetes中部署Grfana。

3、监控Kubernetes实践

3.1 监控Kubernetes内容分析

对于Kubernetes来说,需要对集群内容相关资源运行的性能和健康状态这两类指标需要监控,这些资源主要包括:

  • Node:主机节点
  • Container:应用运行的容器
  • Pod:一组容器的组合
  • Deployment:无状态的应用部署
  • StatefulSet:有状态的应用部署

3.2 在Grafana中配置数据源

登录Grafana,添加Prometheus类型的的数据源。登录Grafana的管理帐户为admin,密码从grafana保密字典的admin-password键的值中获取。其中,url地址:http://{prometheus_server}.{namespace}:80,Access模式:proxy。

3.3 监控实践

在此文中以监控Pod和应用性能指标为例,展示Prometheus和Grafana对Kubernetes的监控实践。

1)对于Pod性能指标进行监控

进入Grafana的dashboard页面导入Kubernetes Pod Metrics模板

导入Kubernetes Pod Metrics以后,就可以对Kubernetes中的Pod进行性能监控,包括网络I/O压力、CPU和内存使用情况等。

2)对于应用性能指标进行监控

进入Grafana的dashboard页面导入Kubernetes App Metrics模板

导入Kubernetes App Metrics以后,就可以对Kubernetes中的应用进行性能监控,包括请求率、反应时间、使用Pod的数量、Pod使用情况等指标。

参考资料

1.《Prometheus Overview》地址:https://prometheus.io/docs/introduction/overview/

2.《使用 Prometheus + Grafana 对 Kubernetes 进行性能监控的实践》作者: 付雅丹 地址:https://mp.weixin.qq.com/s/c2qH4ILq8-3Uuz2VrYKyBw

3.《最佳实践 | Prometheus在Kubernetes下的监控实践》作者:郑云龙,地址:http://dockone.io/article/2579

4.《prometheus》地址:https://hub.kubeapps.com/charts/stable/prometheus

5.《Prometheus 入门与实践》作者:吴 莉, 殷 一鸣, 和 蔡 林,地址:https://www.ibm.com/developerworks/cn/cloud/library/cl-lo-prometheus-getting-started-and-practice/index.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

5.《grafana》地址:https://hub.kubeapps.com/charts/stable/grafana

6.《kubernetes系列之十:使用prometheus和grafana对kubernetes的部署进行监控》地址:https://blog.csdn.net/cloudvtech/article/details/80215866

7.《实战 | 使用Prometheus监控Kubernetes集群和应用》地址:https://www.kancloud.cn/huyipow/kubernetes/531996

8.《Basic Concepts》地址:http://docs.grafana.org/v3.1/guides/basic_concepts/

作者简介:
季向远,北京神舟航天软件技术有限公司产品经理。本文版权归原作者所有。

微信:TheMind_sunshine

Kubernetes-持久化存储卷PersistentVolume

Daniel_Ji阅读(75)评论(0)

1、持久化存储卷和声明介绍

PersistentVolume(PV)用于为用户和管理员提供如何提供和消费存储的API,PV由管理员在集群中提供的存储。它就像Node一样是集群中的一种资源。PersistentVolume 也是和存储卷一样的一种插件,但其有着自己独立的生命周期。PersistentVolumeClaim (PVC)是用户对存储的请求,类似于Pod消费Node资源,PVC消费PV资源。Pod能够请求特定的资源(CPU和内存),声明请求特定的存储大小和访问模式。PV是一个系统的资源,因此没有所属的命名空间。

2、持久化存储卷和声明的生命周期

在Kubernetes集群中,PV 作为存储资源存在。PVC 是对PV资源的请求和使用,也是对PV存储资源的”提取证”,而Pod通过PVC来使用PV。PV 和 PVC 之间的交互过程有着自己的生命周期,这个生命周期分为5个阶段:

  • 供应(Provisioning):即PV的创建,可以直接创建PV(静态方式),也可以使用StorageClass动态创建
  • 绑定(Binding):将PV分配给PVC
  • 使用(Using):Pod通过PVC使用该Volume
  • 释放(Releasing):Pod释放Volume并删除PVC
  • 回收(Reclaiming):回收PV,可以保留PV以便下次使用,也可以直接从云存储中删除

根据上述的5个阶段,存储卷的存在下面的4种状态:

  • Available:可用状态,处于此状态表明PV以及准备就绪了,可以被PVC使用了。
  • Bound:绑定状态,表明PV已被分配给了PVC。
  • Released:释放状态,表明PVC解绑PV,但还未执行回收策略。
  • Failed:错误状态,表明PV发生错误。

2.1 供应(Provisioning

供应是为集群提供可用的存储卷,在Kubernetes中有两种持久化存储卷的提供方式:静态或者动态。

2.1.1 静态(Static)

PV是由Kubernetes的集群管理员创建的,PV代表真实的存储,PV提供的这些存储对于集群中所有的用户都是可用的。它们存在于Kubernetes API中,并可被Pod作为真实存储使用。在静态供应的情况下,由集群管理员预先创建PV,开发者创建PVC和Pod,Pod通过PVC使用PV提供的存储。静态供应方式的过程如下图所示:

2.1.2 动态(Dynamic

对于动态的提供方式,当管理员创建的静态PV都不能够匹配用户的PVC时,集群会尝试自动为PVC提供一个存储卷,这种提供方式基于StorageClass。在动态提供方向,PVC需要请求一个存储类,但此存储类必须有管理员预先创建和配置。集群管理员需要在API Server中启用DefaultStorageClass的接入控制器。动态供应过程如下图所示:

 

2.2 绑定

在Kubernetes中,会动态的将PVC与可用的PV的进行绑定。在kubernetes的Master中有一个控制回路,它将监控新的PVC,并为其查找匹配的PV(如果有),并把PVC和PV绑定在一起。如果一个PV曾经动态供给到了一个新的PVC,那么这个回路会一直绑定这个PV和PVC。另外,用户总是能得到它们所要求的存储,但是volume可能超过它们的请求。一旦绑定了,PVC绑定就是专属的,无论它们的绑定模式是什么。

如果没有匹配的PV,那么PVC会无限期的处于未绑定状态,一旦存在匹配的PV,PVC绑定此PV。比如,就算集群中存在很多的50G的PV,需要100G容量的PVC也不会匹配满足需求的PV。直到集群中有100G的PV时,PVC才会被绑定。PVC基于下面的条件绑定PV,如果下面的条件同时存在,则选择符合所有要求的PV进行绑定:

1)如果PVC指定了存储类,则只会绑定指定了同样存储类的PV;

2)如果PVC设置了选择器,则选择器去匹配符合的PV;

3)如果没有指定存储类和设置选取器,PVC会根据存储空间容量大小和访问模式匹配符合的PV。

2.3 使用

Pod把PVC作为卷来使用,Kubernetes集群会通过PVC查找绑定的PV,并将其挂接至Pod。对于支持多种访问方式的卷,用户在使用 PVC 作为卷时,可以指定需要的访问方式。一旦用户拥有了一个已经绑定的PVC,被绑定的PV就归该用户所有。用户能够通过在Pod的存储卷中包含的PVC,从而访问所占有的PV。

2.4释放

当用户完成对卷的使用时,就可以利用API删除PVC对象了,而且还可以重新申请。删除PVC后,对应的持久化存储卷被视为“被释放”,但这时还不能给其他的PVC使用。之前的PVC数据还保存在卷中,要根据策略来进行后续处理。

2.5 回收

PV的回收策略向集群阐述了在PVC释放卷时,应如何进行后续工作。目前可以采用三种策略:保留,回收或者删除。保留策略允许重新申请这一资源。在PVC能够支持的情况下,删除策略会同时删除卷以及AWS EBS/GCE PD或者Cinder卷中的存储内容。如果插件能够支持,回收策略会执行基础的擦除操作(rm -rf /thevolume/*),这一卷就能被重新申请了。

2.5.1 保留

保留回收策略允许手工回收资源。当PVC被删除,PV将仍然存储,存储卷被认为处于已释放的状态。但是,它对于其他的PVC是不可用的,因为以前的数据仍然保留在数据中。管理员能够通过下面的步骤手工回收存储卷:

1)删除PV:在PV被删除后,在外部设施中相关的存储资产仍然还在;

2)手工删除遗留在外部存储中的数据;

3)手工删除存储资产,如果需要重用这些存储资产,则需要创建新的PV。

2.5.2 循环

警告:此策略将会被遗弃。建议后续使用动态供应的模式。

循环回收会在存储卷上执行基本擦除命令:rm -rf /thevolume/*,使数据对于新的PVC可用。

2.5.3 删除

对于支持删除回收策略的存储卷插件,删除即会从Kubernetes中移除PV,也会从相关的外部设施中删除存储资产,例如AWS EBS, GCE PD, Azure Disk或者Cinder存储卷。

3、持久化存储卷

在Kubernetes中,PV通过各种插件进行实现,当前支持下面这些类型的插件:

  • GCEPersistentDisk
  • AWSElasticBlockStore
  • AzureFile
  • AzureDisk
  • FC (Fibre Channel)
  • FlexVolume
  • Flocker
  • NFS
  • iSCSI
  • RBD (Ceph Block Device)
  • CephFS
  • Cinder (OpenStack block storage)
  • Glusterfs
  • VsphereVolume
  • Quobyte Volumes
  • HostPath (Single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)
  • VMware Photon
  • Portworx Volumes
  • ScaleIO Volumes
  • StorageOS

持久化存储卷的可以通过YAML配置文件进行,并指定使用哪个插件类型,下面是一个持久化存储卷的YAML配置文件。在此配置文件中要求提供5Gi的存储空间,存储模式为Filesystem ,访问模式是ReadWriteOnce,通过Recycle回收策略进行持久化存储卷的回收,指定存储类为slow,使用nfs的插件类型。需要注意的是,nfs服务需要提供存在。

apiVersion:v1
kind:PersistentVolume
metadata:
  name:pv0003
spec:
  capacity: #容量
     storage:5Gi
  volumeMode:Filesystem #存储卷模式
  accessModes: #访问模式
  - ReadWriteOnce
  persistentVolumeReclaimPolicy:Recycle #持久化卷回收策略
  storageClassName:slow #存储类
  mountOptions: #挂接选项
   - hard
   - nfsvers=4.1
  nfs:
     path:/tmp
     server:172.17.0.2 

3.1 容量(Capacity

一般来说,PV会指定存储容量。这里通过使用PV的capcity属性进行设置。目前,capcity属性仅有storage(存储大小)这唯一一个资源需要被设置。

3.2 存储卷模式(Volume Mode

在kubernetes v1.9之前的版本,存储卷模式的默认值为filesystem,不需要指定。在v1.9版本,用户可以指定volumeMode的值,除了支持文件系统外(file system)也支持块设备(raw block devices)。volumeMode是一个可选的参数,如果不进行设定,则默认为Filesystem。

3.3 访问模式(Access Modes

只要资源提供者支持,持久卷能够通过任何方式加载到主机上。每种存储都会有不同的能力,每个PV的访问模式也会被设置成为该卷所支持的特定模式。例如NFS能够支持多个读写客户端,但某个NFS PV可能会在服务器上以只读方式使用。每个PV都有自己的一系列的访问模式,这些访问模式取决于PV的能力。

访问模式的可选范围如下:

  •   ReadWriteOnce:该卷能够以读写模式被加载到一个节点上。
  •   ReadOnlyMany:该卷能够以只读模式加载到多个节点上。
  •   ReadWriteMany:该卷能够以读写模式被多个节点同时加载。

在 CLI 下,访问模式缩写为:

  •   RWO:ReadWriteOnce
  •   ROX:ReadOnlyMany
  •   RWX:ReadWriteMany

一个卷不论支持多少种访问模式,同时只能以一种访问模式加载。例如一个 GCEPersistentDisk既能支持ReadWriteOnce,也能支持ReadOnlyMany。

存储卷插件

ReadWriteOnce

ReadOnlyMany

ReadWriteMany

AWSElasticBlockStore
AzureFile
AzureDisk
CephFS
Cinder
FC
FlexVolume
Flocker
GCEPersistentDisk
Glusterfs
HostPath
iSCSI
PhotonPersistentDisk
Quobyte
NFS
RBD
VsphereVolume – (works when pods are collocated)
PortworxVolume
ScaleIO
StorageOS

3.4 类(Class

在PV中可以指定存储类,通过设置storageClassName字段进行设置。如果设置了存储类,则此PV只能被绑定到也指定了此存储类的PVC。在以前的版本中,使用注释volume.beta.kubernetes.io/storage-class字段来指定存储类,而不是storageClassName字段来指定存储类。 此注释仍然可用,但是,在将来的版本中将会被废弃。

3.5 回收策略

当前的回收策略可选值包括:

  • Retain-持久化卷被释放后,需要手工进行回收操作。
  • Recycle-基础擦除(“rm-rf /thevolume/*”)
  • Delete-相关的存储资产,例如AWSEBS或GCE PD卷一并删除。

目前,只有NFS和HostPath支持Recycle策略,AWSEBS、GCE PD支持Delete策略。

3.6 挂接选项(Mount Options

当持久化卷被挂接至Pod上时,管理员能够指定额外的挂接选项。但不是所有的持久化卷类型都支持挂接选项,下面的存储卷类型支持挂接选项:

  • GCEPersistentDisk
  • AWSElasticBlockStore
  • AzureFile
  • AzureDisk
  • NFS
  • iSCSI
  • RBD (Ceph Block Device)
  • CephFS
  • Cinder (OpenStack block storage)
  • Glusterfs
  • VsphereVolume
  • Quobyte Volumes
  • VMware Photon

挂接选项不会进行验证,因此如果如果设置不正确,则会失败。在以前的版本中,使用volume.beta.kubernetes.io/mount-options注释指定挂接选项,而不是使用mountOptions字段。此注释仍然可用,但是在将来的版本中将会被废弃。

4、持久化卷声明

下面是一个名称为myclaim的PVC YAML配置文件,它的访问模式为ReadWriteOnce,存储卷模式是Filesystem,需要的存储空间大小为8Gi,指定的存储类为slow,并设置了标签选择器和匹配表达式。

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
spec:
  accessModes: #访问模式
    - ReadWriteOnce
  volumeMode: Filesystem #存储卷模式
  resources: #资源
    requests:
      storage: 8Gi
  storageClassName: slow #存储类
  selector: #选择器
    matchLabels:
      release: "stable"
    matchExpressions: #匹配表达式
      - {key: environment, operator: In, values: [dev]}

4.1 选择器

在PVC中,可以通过标签选择器来进一步的过滤PV。仅仅与选择器匹配的PV才会被绑定到PVC中。选择器的组成如下:

  • matchLabels: 只有存在与此处的标签一样的PV才会被PVC选中;
  • matchExpressions :匹配表达式由键、值和操作符组成,操作符包括In, NotIn, Exists和DoesNotExist,只有符合表达式的PV才能被选择。

如果同时设置了matchLabels和matchExpressions,则会进行求与,即只有同时满足上述匹配要求的PV才会被选择。

4.2 存储

如果PVC使用storageClassName字段指定一个存储类,那么只有指定了同样的存储类的PV才能被绑定到PVC上。对于PVC来说,存储类并不是必须的。依赖于安装方法,可以在安装过程中使用add-on管理器将默认的StorageClass部署至Kubernetes集群中。当PVC指定了选择器,并且指定了StorageClass,则在匹配PV时,取两者之间的与:即仅仅同时满足存储类和带有要求标签值的PV才能被匹配上。

4.3 PVC作为存储卷

Pod通过使用PVC来访问存储,而PVC必须和使用它的Pod在同一个命名空间中。Pod会同一个命名空间中选择一个合适的PVC,并使用PVC为其获取存储卷,并将PV挂接到主机和Pod上。

kind:Pod
apiVersion:v1
metadata:
  name:mypod
spec:
  containers:
  - name:myfrontend
    image:dockerfile/nginx
     volumeMounts: #挂接存储卷
     - mountPath:"/var/www/html" #挂接的路径
       name:mypd #所要挂接的存储卷的名称
 volumes: #定义存储卷
 - name:mypd
   persistentVolumeClaim: #所使用的持久化存储卷声明
     claimName:myclaim

 

参考资料

1.《Configure a Pod to Use a PersistentVolume for Storage》地址:https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/

2.《Persistent Volumes》地址:https://kubernetes.io/docs/concepts/storage/persistent-volumes/

3.《Persistent Storage》地址:https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/persistent-storage.md

4.《PersistentVolume v1 core》地址:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#persistentvolume-v1-core

作者简介:
季向远,北京神舟航天软件技术有限公司产品经理。本文版权归原作者所有。

Kubernetes-基于容器云构建devops平台

Daniel_Ji阅读(213)

1、基于kubernetes devops的整体方案

本文以Kubernetes为基础,为基于java语言研发团队提供一套完整的devops解决方案。在此方案中,开发人员基于eclipse集成开发环境进行代码;开发人员所开发的代码交由由gitlab进行托管、版本管理和分支管理;代码的依赖更新和构建工作由Maven进行处理;为了提升工作效率和代码质量,在devops中引入SonarQube进行代码检查;对于打包构建后代码,交由docker进行镜像构建,并在私有镜像仓库中对镜像进行管理;最后,devops会将自动从私有镜像仓库从拉取镜像,并在Rancher中进行部署。

基于此devops解决方案的整体工作过程如下所示:

1)开发人员基于eclipse集成开发环境镜像代码开发的,将代码到gitlab中进行托管;

2)jenkins从gitlab拉取代码;

3)jenkins调用Maven对代码进行打包构建;

4)jenkins调用docker构建镜像;

5)jenkins将构建好的镜像上传至基于Nexus的私有镜像仓库;

6)jenkins拉取镜像,并部署镜像至Rancher中。

 

2、组件安装部署

此部分描述需要为devops部署的组件,根据整体方案,devops需要使用gitlab、jenkins、nexus、maven、docker和kubernetes这些组件和系统。其中,gitlab、jenkins、nexus都在kubernetes中安装部署,在jenkins中包含了maven;docker直接在物理机提供,对于docker的部署不在此部分进行阐述。

2.1 代码托管工具-Gitlab

在本文的方案中,代码的托管基于Gitlab。下面是在Kubernetes中部署gitlab的YAML配置文件,在此文件中定义了gitlab部署和服务。gitlab部署使用的镜像为gitlab/gitlab-ce:latest,并暴露了443、80和22这三个端口,并通过NFS对配置文件、日志和数据进行持久化。在服务中,端口的类型为NodePort,即允许集群外的用户可以通过映射在主机节点上的端口对gitlab进行访问。

#------------------------定义代理服务-------------------------
apiVersion: v1
kind: Service
metadata:
  name: gitlab
spec:
  type: NodePort
  ports:
  # Port上的映射端口
  - port: 443
    targetPort: 443
    name: gitlab443
  - port: 80
    targetPort: 80
    name: gitlab80
  - port: 22
    targetPort: 22
    name: gitlab22
  selector:
    app: gitlab
---

# ------------------------定义Gitlab的部署 -----------------------

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: gitlab
spec:
  selector:
    matchLabels:
      app: gitlab
  revisionHistoryLimit: 2
  template:
    metadata:
      labels:
        app: gitlab
    spec:
      containers:
      # 应用的镜像
      - image: gitlab/gitlab-ce 
        name: gitlab
        imagePullPolicy: IfNotPresent
        # 应用的内部端口
        ports:
        - containerPort: 443
          name: gitlab443
        - containerPort: 80
          name: gitlab80
        - containerPort: 22
          name: gitlab22
        volumeMounts:
        # gitlab持久化
        - name: gitlab-persistent-config
          mountPath: /etc/gitlab
        - name: gitlab-persistent-logs
          mountPath: /var/log/gitlab
        - name: gitlab-persistent-data
          mountPath: /var/opt/gitlab
      imagePullSecrets:
      - name: devops-repo
      volumes:
      # 使用nfs互联网存储
      - name: gitlab-persistent-config
        nfs:
          server: 192.168.8.150
          path: /k8s-nfs/gitlab/config
      - name: gitlab-persistent-logs
        nfs:
          server: 192.168.8.150
          path: /k8s-nfs/gitlab/logs
      - name: gitlab-persistent-data
        nfs:
          server: 192.168.8.150
          path: /k8s-nfs/gitlab/data

通过kubectl命令工具,执行如下的命令,在kubernetes集群中部署gitlab:

$ kubectl create -f {path}/gitlab.yaml

2.2 镜像仓库-Nexus

在本文的devops方案中,采用Nexus作为docker私有镜像仓库和maven的远程仓库。下面是在Kubernetes中部署Nexus的YAML配置文件,在此文件中定义了Nexus部署和服务。Nexus部署使用的镜像为sonatype/nexus3:latest,并暴露了8081、5001这两个端口,并通过NFS对配置文件、日志和数据进行持久化。在服务中,端口的类型为NodePort,即允许集群外的用户可以通过映射在主机节点上的端口对nexus进行访问。其中,5001作为docker私有镜像仓库的端口。

#------------------------定义Nexus代理服务-------------------------
apiVersion: v1
kind: Service
metadata:
  name: nexus3
spec:
  type: NodePort
  ports:
  # Port上的映射端口
  - port: 8081
    targetPort: 8081
    name: nexus8081
  - port: 5001
    targetPort: 5001
    name: nexus5001
  selector:
    app: nexus3
---
#-----------------------定义Nexus部署-------------------------
apiVersion: apps/v1beta2
kind: Deployment
metadata:
   name: nexus3
   labels:
     app: nexus3
spec:
   replicas: 1 #副本数为3
   selector: #选择器
     matchLabels:
       app: nexus3 #部署通过app:nginx标签选择相关资源
   template: #Pod的模板规范
     metadata:
       labels:
         app: nexus3 #Pod的标签
     spec:
       imagePullSecrets:
       - name: devops-repo
       containers: #容器
       - name: nexus3
         image: sonatype/nexus3
         imagePullPolicy: IfNotPresent
         ports: #端口
         - containerPort: 8081
           name: nexus8081
         - containerPort: 5001
           name: nexus5001
         volumeMounts:
         - name: nexus-persistent-storage
           mountPath: /nexus-data
       volumes:
       # 宿主机上的目录
       - name: nexus-persistent-storage
         nfs:
           server: 192.168.8.150
           path: /k8s-nfs/nexus

通过kubectl命令工具,执行如下的命令,在kubernetes集群中部署nexus:

$ kubectl create -f {path}/nexus.yaml

2.3 流水线工具-Jenkins

2.3.1 jenkins安装部署

在本文的devops方案中,采用jenkins作为流水线工具。下面是在Kubernetes中部署jenkins的YAML配置文件,在此文件中定义了jenkins部署和服务。jenkins部署使用的镜像为lw96/java8-jenkins-maven-git-vim:latest,并暴露了8080这个端口,并通过NFS对配置文件和数据进行持久化。在服务中,端口的类型为NodePort,即允许集群外的用户可以通过映射在主机节点上的端口对jenkins进行访问。另外,在此镜像中也提供maven和java。

#------------------------定义代理服务-------------------------
apiVersion: v1
kind: Service
metadata:
  name: jenkins-devops
spec:
  type: NodePort
  ports:
  # Port上的映射端口 
  - port: 8080
    targetPort: 8080
    name: pipeline8080
  selector:
    app: jenkins-devops
---

# ------------------------定义mysql的部署 -----------------------
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: jenkins-devops
spec:
  selector:
    matchLabels:
      app: jenkins-devops
  revisionHistoryLimit: 2
  template:
    metadata:
      labels:
        app: jenkins-devops
    spec:
      containers:
      # 应用的镜像
      - image: 10.0.32.148:1008/lw96/java8-jenkins-maven-git-vim
        name: jenkins-devops
        imagePullPolicy: IfNotPresent
        # 应用的内部端口
        ports:
        - containerPort: 8080
          name: pipeline8080 
        volumeMounts:
        # jenkins-devops持久化
        - name: pipeline-persistent
          mountPath: /etc/localtime
        # jenkins-devops持久化
        - name: pipeline-persistent
          mountPath: /jenkins
        # jenkins-devops持久化
        - name: pipeline-persistent-repo
          mountPath: /root/.m2/repository
        - name: pipeline-persistent-mnt
          mountPath: /mnt
      volumes:
      # 使用nfs互联网存储
      - name: pipeline-persistent
        nfs:
          server: 192.168.8.150
          path: /k8s-nfs/jenkins-devops
      - name: pipeline-persistent-mnt
        nfs:
          server: 192.168.8.150
          path: /k8s-nfs/jenkins-devops/mnt
      - name: pipeline-persistent-repo
        nfs:
          server: 192.168.8.150
          path: /k8s-nfs/jenkins-devops/repo

通过kubectl命令工具,执行如下的命令,在kubernetes集群中部署jenkins:

$ kubectl create -f {path}/jenkins-devops.yaml

注意,后续将执行下面的操作:

  • 将Kubernetes集群的kubeconfig文件拷贝到192.168.8.150主机的/k8s-nfs/jenkins-devops/mnt目录下;
  • 将maven的settings.xml文件拷贝至到192.168.8.150主机的/k8s-nfs/jenkins-devops/repo目录下;
  • 将maven的依赖插件包拷贝至到192.168.8.150主机的/k8s-nfs/jenkins-devops/repo目录下。

3、 devops平台搭建

3.1 nexus设置

nexus在devops中承担两个功能,作为maven的远程仓库和作为docker的私有镜像仓库。

在本文中,使用nexus默认安装的maven-snapshots、maven-releases和maven-public这三个仓库。

并为docker创建一个名为registry的私有镜像仓库,其端口为5001:

3.2 maven设置

maven负责管理代码的依赖关系和构建。maven通过settings.xml文件设置运行环境,包括与远程仓库的连接。本文中的settings.xml如下所示,http://nexus3:8081中的nexus3是在kubernetes中的服务名称。将settings.xml拷贝至192.168.8.150机器的/k8s-nfs/jenkins-devops/repo目录下。

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <pluginGroups>
  </pluginGroups>
  <proxies>
  </proxies>
  <servers>
     <server>     
      <id>maven-release</id>     
      <username>admin</username>     
      <password>admin123</password>     
    </server>     
    <server>     
      <id>maven-snapshots</id>     
      <username>admin</username>     
      <password>admin123</password>     
    </server>     
  </servers>

  <mirrors>
    <mirror>        
     <id>nexus</id>         
     <url>http://nexus3:8081/repository/maven-public/</url>        
     <mirrorOf>*</mirrorOf>        
   </mirror>     
 </mirrors> 

  <profiles>
  <profile>
      <id>maven-release</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <repositories>
        <repository>
          <id>maven-release</id>
          <name>Repository for Release</name>
          <url>http://nexus3:8081/repository/maven-releases/</url>
     <releases>
     <enabled>false</enabled>
     </releases>
     <snapshots>
     <enabled>true</enabled>
     </snapshots>
        </repository>
      </repositories>
    </profile>

  <profile>
      <id>maven-snapshots</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <repositories>
        <repository>
          <id>maven-release</id>
          <name>Repository for Release</name>
          <url>http://nexus3:8081/repository/maven-snapshots/</url>
     <releases>
     <enabled>false</enabled>
     </releases>
     <snapshots>
     <enabled>true</enabled>
     </snapshots>
        </repository>
      </repositories>
    </profile>
  </profiles>
</settings>

3.3 docker设置

为了能够支持将远程提交的代码构建成镜像,以及将构建好的镜像上传至镜像仓库需要在/etc/docker/daemon.json的文件中添加下面的内容。其中,10.0.32.163:32476为镜像仓库的地址和端口,tcp://0.0.0.0:4243为对外暴露的地址和端口。

{
"hosts":["tcp://0.0.0.0:4243","unix:///var/run/docker.sock"],
"insecure-registries":["10.0.32.163:32476"]
}

并通过执行下面的命令重启docker服务:

$ systemctl daemon-reload
$ systemctl restart docker

3.4 jenkins设置

3.4.1 安装插件

jenkins作为devops平台的流程线工具,需要从gitlab中获取代码,并提交给maven进行构建;在代码构建成功后,调用docker构建镜像,并将上传至基于Nexus的私有镜像仓库;最终,在Kubernetes中部署和运行镜像。为了实现上述能力,需要在jenkins中安装如下插件:

  • git plugin:与gitlab集成的插件,用于获取代码;
  • maven plugin:与maven集成的插件,用于构建代码;
  • CloudBees Docker Build and Publish plugin:与docker集成的插件,用于构建docker镜像,并上传至镜像仓库;
  • Kubernetes Continuous Deploy Plugin:与kubernetes集成的插件,用于将镜像部署到kubernetes环境。

3.4.2 maven设置

在jenkins中的“全局工具配置”页面,设置maven的安装信息,name可以按照自己的喜好填写,MAVEN_HOME为maven的安装地址,此处为/opt/maven。

4、devops持续集成示例

1)安装git客户端和创建密钥

在工作计算上安装git客户端,并通过下面的命令创建ssh密钥:

ssh-keygen -t rsa -C "your.email@example.com" -b 4096

执行上述命令后,会在本地的~/.ssh目录创建id_rsa.pub(公钥)和id_rsa(私钥)。

2)在gitlab创建oms项目

进入gitlab,并创建一个名称为oms的项目。

在gitlab中添加所创建的公钥:

3)在eclipse中进行代码开发

在eclipse中创建类型为maven的oms项目,并进行代码开发。在完成代码开发后,将代码上传至gitlab中进行代码托管。

4)在jenkins中创建oms项目

进入jenkins,创建一个名称为oms的maven项目。

 

5)在jenkins中设置获取代码信息

在jenkins中,进入oms的配置页面,在源代码管理处设置获取源代码的相关信息。

  • Repository URL:项目在gitlab中的地址;
  • Credentials:访问gitlab的认证方式;
  • Branch Specifier:代码的分支。

此处访问gitlab的认证方式为“SSH Username with private key”,Private Key的值来自于~/.ssh目录下id_rsa(私钥)的内容。

6)在jenkins中设置构建和上传镜像信息

在oms项目的配置的“Docker Build and Publish”部分,填写如下的信息;

  • Repository Name:镜像的名称;
  • Tag:镜像的版本;
  • Docker Host URI:docker服务的地址和端口;
  • Docker registry URL:docker镜像仓库的地址;
  • Registry credentials:镜像仓库的认证方式。

7)在jenkins中设置部署容器信息

在oms项目的配置的“Deploy to Kubernetes”部分,填写如下的信息;

  • Kubernetes Cluster Credentials:Kubernetes集群的认证方式;
  • Path:kubeconfig文件的所在地址;
  • Config Files:构建YAML配置文件。

8)在jenkins中执行oms构建

在oms项目创建和设置完成后,可以对项目进行构建操作。通过一键操作,jenkins将会完成从构建、打包成镜像和部署的所有工作内容:

  • 从gitlab中获取oms的代码;
  • 提交给maven进行构建;
  • 调用docker构建镜像;
  • 上传镜像至Nexus的私有镜像仓库;
  • 部署镜像到kubernetes集群。

9)在kubernetes中查看部署情况

进入kubernetes(本文使用的为Rancher系统)界面,在default命名空间下,可以看到已部署的oms。

参考材料

1.《User documentation》地址:http://10.0.32.163:32269/help/user/index.md

2.《CloudBees Docker Build and Publish plugin》地址:https://wiki.jenkins.io/display/JENKINS/CloudBees+Docker+Build+and+Publish+plugin

3.《Kubernetes Continuous Deploy Plugin》地址:https://wiki.jenkins.io/display/JENKINS/Kubernetes+Continuous+Deploy+Plugin

作者简介:
季向远,北京神舟航天软件技术有限公司产品经理。本文版权归原作者所有。

微信公众号:ik8s

干货分享 | PaaS云平台在企业落地的 8 大关键点

时速云阅读(708)评论(0)

5月26日,时速云企业级容器 PaaS 技术沙龙第9期在深圳成功举办,时速云联合创始人兼技术总监杨乐就 PaaS 平台落地实施所关注的一些问题、Kubernetes 核心组件、Kubernetes 资源对象以及 Devops 体系、微服务治理等方面做出了深入的探讨和分享。

以下是本次分享的实录:

杨乐:非常感谢大家,在这个天气炎热的周六来到这里。在这里给大家带来的是关于 PaaS 云平台在企业中落地的经验分享,其中包括了生产环境中关注的问题,Kubernetes 的架构和资源对象的利用,以及我们在实际实施过程中遇到的一些问题。另外 PaaS 平台体系构建完成,是如何在容器云上进行的应用实践的,以及我们基于 Docker、Kubernetes 所构建 DevOps 体系持续集成,测试环境和生产环境是如何应用 Kubernetes 去构建运行使用的,我们还会介绍微服务治理相关的架构,以及我们部署架构的知识。

基于Docker和K8S的平台建设
1、PaaS 容器云平台落地实施关注的问题

在 PaaS 云平台落地的时候,会有一些关注点,我们在企业落地实施的过程中,首先关注架构运行的方式,也就是说我们最初架构的选型,以及它的核心组件,比如说我们的日志如何去收集,监控和报警组件是如何运行的。在 PaaS 平台上运行的应用,相关的应用服务是如何发布出去的,是以何种方式代理出去的。以及我们在落地实施的时候,平台自身的组件以及 Kubernetes 本身的组件如何实现它的高可用,真正实现生产运行体系。

为了运行有状态应用,需要分布式存储进行支持。如何构建集群的网络类型,如何将容器服务进行集群内的网络打通。持续集成体系是我们基于 Kubernetes 相关的资源对象去构建的开发测试运维一体化的子产品。而最终要去注重用户应用的发布、运行,同时需要以容器的方式在部署到 PaaS 平台,如何将应用容器进行互联。

我们会关注真正落地实施之后,从它的架构运营、高可用性,到最终成体系的构建、应用的部署。而这几个关键点,会在后面每一个对应到 Kubernetes 架构体系上,一一介绍。

在场的各位对 Docker 和 Kubernetes 有没有一些了解,Docker  是单机容器的运行引擎。而 Kubernetes 是将容器以及 Docker 做集群架构的体系,它的架构方式是 Master、Slave 的方式。也就是说 Master 作为中控调动中心,去控制我的 Slave 结点。而 Slave 节点上面,所有的这些结点去运行相关的容器。应用服务都会用容器的方式运行在 Slave 节点之上。而它的发布是通过 Service 以及外部代理的方式向外发布。而每一个容器可以通过设置后端存储的方式进行持久的存储。

在 Kubernetes 组件里,需要关注日志组件。当容器运行在 Kubernetes 架构体系的时候,我需要关心应用本身产生的日志有没有问题。测试和开发人员需要获取一些调试的信息,然后去判断它的问题在哪里。而运维人员也需要查看发生问题的应用,它的日志在哪里。

当容器的 CPU 或者是内存发生了一些变动,超出负载的阈值时,需要做及时的报警。在内网进行服务发现的时,需要一个 DNS 的配置,以此各个应用间可进行探测和调用。

我们后面会有一些存储和网络,网络需要支持我们整个集群之内所有的结点,容器之间需要网络的打通,可以让容器在内网之间做一个互联,做一个架构的连接。

2、Kubernetes核心组件

Kubernetes 核心组件包括日志、监控、kube-dns。从日志来说,Kubernetes 这些日志组件是从 ElsaticSearch 构建的。它会从节点里面收集相关的容器日志信息。会把这些信息发送到中控的 ElsaticSearch 组件里面去。当这些信息收集完了之后,会通过外部的 UI、开发的UI的组件或者是用 Kibana 展示组件去进行合理的展示。

运维人员和开发人员可以通过可视化的展示组件去检索对应的日志。对于日志来说,Docker logs 是默认的日志输出的位置。但是通过一些特定的设置,不单单可以收集 Docker logs 本身产生的日志,还能够指定应用所能够达到日志的位置,指定相关的目录,并能够随意收集容器内部日志的信息。

在监控体系方面,第一种方式,Kubernetes 本身是使用 Kubelet 以及 Heapster、Influxdb 构建的。Influxdb 会把相关监控信息存储起来,监控数据从kubelet中通过heapster远程获取的。通过 Grafana 去展示相关的监控信息。用户通过一个集中化监控展示平台,可以查看到指定的容器服务所用的 CPU、内存相关的监控信息。

第二种监控体系是使用 Prometheus 组件,这两种体系是分别独立的。它的方式也是通过收集每一个节点相关的 CPU、内存等等监控信息,存储到一个中心化存储体系里面去,然后再把相应的监控信息展示出来。

对于报警体系,可以通过 Prometheus 本身的一些规则的设置,可以设置达到我 CPU 预值20% 的时候会触发报警事件。它可以调用外部相关操作的动作,比如说调用我们的平台,调用我们平台 API 里面所集成的短信或者邮件 API。就可实现从我们平台发生的监控,比如说超过了预值的 CPU,自动发出报警给我们的管理员,管理员就可以在及时检测到CPU、容器以及节点它的问题所在。

Kubernetes 一个核心组件就是 kube-DNS,它是为 Kubernetes 内部应用之间做服务发现。什么是服务发现,当我们把我们的应用去运行到 Kubernetes 体系里面去的时候,每一个应用中需要有一定的机制发现对方。我需要知道我周围的这些应用运行的名字是什么,它的运行位置在哪里,它的 IP 是多少。我需要这样一套发现机制,而 Kubernetes 本身提供的一方面把每一个应用和容器的信息记录到 Master 里面去。同时用 Kubernetes DNS 的方式展现给其它的应用工具。

当用户创建应用后,会在内网 kube-dns 里面记录一个域名。 每一个域名对应我一个应用,当其它的应用容器想要连接指定的应用的时候,只需要通过 DNS 域名就可以连接到。DNS 的 Kubedns 组件,不停的跟 Master Apiserver 进行交互,实时获取所创建或者是删除的这些应用的状态,获取IP地址、名称,并记录在 DNS 存储空间里,形成一条条 DNS 记录。而 DNS 会把相应的记录信息整合成DNS的服务出口。这样其它的应用服务可以通过DNS的53端口,进行查询,和DNS记录检索。这样就实现在整个联网范围之内,通过DNS去查询到指定的应用服务的功能。

Kube-DNS 是可以应用到 Kubernetes 本身的编排体系里面去。也就是说当我们运行应用到Kubernetes 架构体系里面之后,它不单是一个应用,而是多应用需要编排在一起。编排在一起就需要每一个应用互相之间进行一个发现和连接,而连接就需要用IP地址或者是域名,这里面就是用域名的方式。

所以我在编排的时候,通过一个编排文件,把编排文件每一个应用之间,它是用域名的方式设计到里面去。通过编排文件它可以统一的创建所有的应用,让它同时去启动或者是顺序启动,进行一个架构的建设。

高可用性,高可用对于系统平台来说,包括 Kubernetes 本身的高可用,还有我们提供自身产品的高可用,还有各种其它组件和存储的高可用。Kubernetes 本身高可用提供的这种方式,首先 Master高可用,Master 高可用通过多个 Master 的方式让它多活,然后通过统一的 Keepalived 的方式跟 Service 进行一个互联。

而相应的服务对外发布出口的时候,需要有一个对外的出口。底层存储的方式是通过多活的方式进行高可用的设置。平台本身每一个涉及到单点故障问题的组件都设置了高可用性,这个也是在生产环境中必要考虑的。

3、Kubernetes的资源对象
Kubernetes 的一些资源对象, Kubernetes 的 Pod 的概念,对容器本身来说,一个 Pod 里面可以包含多个容器,而多个容器在同一个 Pod 里面是可以共享网络和存储的。这就实现了在多个容器进行编排的时候,每一个容器都可以进行非常紧密的连接。Deployment 可以对 Pod 进行副本的管理,或者是进行滚动升级的识别。

而 Service 这个概念就是一个抽象的服务出口,这就是为了将我的 Pod 或者是我的容器运行在 Kubernetes 之后,如何将它发布出去,如何让用户从外部进行一个访问,让 Service  做这件事情,它实际上是在我们的节点上做了一个负载均衡器。一个基于 IOS 一个负载均衡器。它会把用户外部访问的流量分发到内部多个 Pod 或者是容器上面进行一个负载均衡。

Labels 实际上是指在我 Kubernetes 本身资源对象里面作为一个标签,以及标签选择的方式。

ConfigMap 实际上是对数据的管理,我可以通过把我的一些外部配置信息放在 Kubernetes  存储里面的一种方式。然后去解决我在构建完我的容器进项之后,我希望把我的这些进项放在不同的环境里面,而不同的环境外部配置信息反而不一样。而我又不希望更改我容器里面的这些内容。那就用外部的方式,将外置的配置信息加载到容器里面。

而这个 ConfigMap 就起外部配置信息加载到容器里面的作用的。Secret 本身是解决密码以及 token 相关的问题。Job 是任务以及定时任务,我可以设置一个应用程序或者是一个进程让它运行一次,或者我可以设置定时进行。这些可以把它思考成一个 cronjob,也就是说一些定时任务会去做。

水平伸缩也就是说 HPA,在 Kubernetes 里面,它可以做到应用容器的一些自动伸缩。可以根据我们的 CPU 或者是内存、网络或者是磁盘 AIO,它的参数,进行一个实例的伸缩。如果我们设置了一个预值,如果 CPU 超过了 50%,那么我的容器自动扩展到 10 个或者是 20 个。当 CPU 低于百分之多少的时候,我可以让他自动回缩到指定的数量。这就是在负载变化的情况下,对实例伸缩的功能。

而下面的 Stateful、Volumes 以及 Ingress,Stateful 是为了解决有状态服务,以及可以做集群模式对象。Volumes 是为了解决相关磁盘存储,还有 Ingress 是 Kubernetes 本身指定的负载均衡代理。

对于 Kubernetes 资源对象 Stateful 首先是为了解决有状态存储的一些应用。如果需要手动设置多个 Pod 之间的存储配置,就会出现一个问题,Pod 重启之后就消失了。所以如果我们手动配置的话,就很难做到他们之间主从的配置

而 Stateful 是为了解决这个问题,Stateful 第一个特点是可以挂载相应的动态存储。第二他可以将起来的这些 Pod 进行有序的标号,也就是说普通的 Pod 的话,它的标号是随机的。但是这种 Stateful 是有序的,从 0 开始一直到 N 为止。也就是说这几个 Pod 之间是可以用有序的名字互相发现。这就带来一个可能,我在运行 Stateful 的时候,我可以设置一些参数或者是脚本,让他们按照这个名字互相发现。这样你通过互相发现的方式,再进行主从之间一些动态设置。这就可以实现我起了多个容器,通过 Stateful 进行一些动态设置。他们可以完成主从,进行集群的配置。也就是说 Stateful 可以实现各个需要进行主从配置应用软件的集群设置。

Ingress 我们之前提到作为一个服务出口,当我们的应用运行在 Kubernetes 的时候,我们需要把它进行对外的发布,发布的方式可以通过代理的方式,也可以通过 Ingress 的方式。

实际上 Ingress 对应的就是我们所关注的服务出口的问题,而 Ingress 是解决出口的方式之一,实际上还有其它很多种方式,也可以自研去做这个事情。

Volumes 是解决整个 PaaS 平台它的存储问题,我们应用容器在运行的时候,如果我们用过 Kubernetes,如果 Pod 起来以后,如果不进行持久化存储的话,重启以后很多内容丢失。为了防止关键信息丢失,我们需要挂在分部式的存储。

一种方式就是我们通过 PVC 的方式,挂在一些文件体系上面。这样 Pod 在进行迁移的时候,其中一个 Pod 在机器上挂掉以后。它的存储会跟随我们的 Pod 从另外一个可用的机器上起来。这样的话,它原来的内容可以在新的 Pod 里面读取到,这样就达到存储可用性的效果。

Kubernetes 网络类型也有很多种方式,现在我们常用或者是我们现在支持的方式就是包括让 Calico、Flannel、Weave 的方式。实际上一种是隧道的方式,或者是用路由的方式去实现。

4、Kubernetes生产环境的实施

从上图我们可以看到生产环境实施的整个架构模式图,首先对于 Kubernetes 来说,整个集群各个组件模块是需要多副本的,整个控制台对 API 调用的控制端需要多个节点,以及镜像仓库、文件存储,以及相关的 Slave 都是需要多节点的。

而在集群内部,需要一组服务出口。在应用的时候,持续集成所需要运行一组集群,这些都需要高可用去做。每一个功能组件,可以通过一种方式进行合理的分组。每种类型的组件或者应用,可以运行到指定的服务器节点上去。

容器云平台在企业中的应用场景
1、容器云平台功能体系
下面给大家介绍一下容器云平台在企业中应用场景,首先可以看一下整个容器云平台功能体系,首先是最基本的应用管理。可以通过 Kubernetes 去创建应用,去管理应用。可以通过 Kubernetes job 去实现持续集成的体系,包括代码仓库、镜像构建以及持续部署这些功能。微服务体系包括服务发现、负载均衡等,应用之间可以进行服务监控。可以通过Stateful 资源对象一键创建一套集群体系。包括我们分布式的存储,相应队列,大数据的一些组件等等。

 而 Kubernetes 本身部署起来,可以是虚拟机,也可以是物理机,也就是说它的底层架构可以是偶合的。

2、Devops体系

通过 Kubernetes job 的方式来进行持续集成,也就是说持续集成构建的框架。通过这个框架,我们启动我们的持续集成的时候,我们会调动 API。通过 job 的方式,启动多个构建服务,每一个 job 对应一个任务去完成它指定的工作。当它完成以后,会通过代码的构建以及镜像的生成。结束以后,它会把相应的镜像放在指定的镜像仓库里面去。。

通过对镜像仓库以及 API 的设置,它可以自动从镜像仓库里再次部署到 Kubernetes 的环境里面。

开发人员可以通过代码提交的方式去触发持续集成。同时进行单元测试。测试结束之后做一些审计,然后把这些结果发送。扫描结束之后会对它进行一个编辑,编译的结果会传到下一步里面,进行一个代码构建,代码构建会生成相应的镜像,它会推送到我的镜像中心,然后会接受一些安全扫描。扫描镜像里面是否存在一些安全风险,它有没有一些漏洞。在漏洞扫描结束之后,会经过部门的审批流程。如果部门审批流程通过,它就可以进行下一个镜像发布或者是发布到我们的平台,或者是让它上传到我们的应用商店里面。

这样当镜像进行一个发布之后,会运行到测试环境,可以交给测试团队进行一个部署的测试。当测试团队发现问题之后,会交给开发人员进行再一次迭代。这样就会形成从研发体系到代码提交到研发开发测试,到最终的部署运行以及再次回环的迭代,整个回环体系就构建起来了。

3、测试生产运行体系

这是测试环境以及生产环境的运行体系,在给客户部署实施的时候,一般情况下,很多用户都是按不同的部门或者是按不同的网络环境的多个集群。在这个图上可以看到左边是测试环境集群,也就是说这是一套独立的 Kubernetes 集群体系,右边是生产环境的一些集群。这里面是所有生产环境的应用都在运行。

从构建体系来说,持续集成体系可以在这里面跑。也就是说从代码的生成到持续集成部署到镜像生成,自动把业务应用上去,开发测试人员通过测试环境对它进行一个测试。最终当测试完毕之后,这些镜像可以通过定版的方式同步到生产环境的镜像中心里面。

然后再通过运维或者是项目经理的管理,进行一个生产环境的部署。这样的话它就形成整套从生产环境到测试环境整体的运维体系。当我们在真正生产运维的时候,可以通过生产环境中的日志管理、监控管理、审计系统,通过这些组件进行生产环境的运维。

4、微服务治理

微服务治理是基于 Kubernetes 的特性基础上,将 SpringCloud 架构结合在一起。集成了  SpringCloud 的服务发现、负载均衡、配置管理等组件,可以用容器的方式运行到  Kubernetes 平台里面。用户可以把基于 springboot 开发的应用运行到平台里面,运行上去之后,应用将注册到服务注册中心,并可使用 SpringCloud 的相关组件。

生产环境落地实施后,最终要实现的是用户的应用要上云,真正的部署上去。部署的环节需要首先把应用程序进行容器化。需要构建应用的生产环境,将应用程序进行打包,然后将应用的镜像部署到我们的 Kubernetes 里,让 Kubernetes 对应用程序进行生命周期的管理,当整个架构体系和服务体系上云以后,可以进行多个组件之间的编排,组件直接进行互联,并且通过配置管理进行相同应用多个环境的部署。

当涉及到数据库的存储时,需要使用 Stateful 对象进行管理。当应用架构部署完成以后,对外发布的时候,需要进行负载均衡出口的管理。最终以如图这种方式,通过负载均衡访问到 APP,以及数据存储通过存储块进行有状态保持,在运维的过程中,对其进行配置管理,以及监控、日志的查看、操作,这样一整套运维体系就可以构建起来。

Q&A

Q:用户隔离怎么做?

A:用户隔离是基于用户命名空间的体系做的网络隔离。Calico本身是负责网络隔离的,再就是一些用户体系的资源隔离,都可以通过kubernetes 的命名空间进行隔离。

Q:我刚才看有大数据相关的组件,我不知道你这边大数据有没有用到ES等性能要求比较高的应用。在这种情况下,你们的性能表现是什么样的。第二个问题是在Kubernetes有三种service模式,你这边是哪一种模式?

A:大数据相关的组件实际上如果你要运行的话,跟性能相关的,还是基于底层硬件体系。也就是说 Kubernetes 本身是需要架设在 IaaS 或者是物理基上的。如果说底层性能不够优的话,你构建那些 SDN 网络,它的性能也会受到连累。因为本身它访问的性能以及存储的性能,都是涉及到我用 ios 这种软件定义网络的方式去做的。最终是要打到物理环境里的。

第一建议网络做的比较优,再就是要用高性能,高 IO 的存储组件。

第二个问题是 Service,通过 Service nodeport 对外发布的时候,但是对于企业管理来说,你可能涉及到要发布到哪一个节点上,以及这些节点上的关口如何去管理。如果你这一套系统自用的话,这个方式是没有问题的。但是如果是一个企业或者是公有云,就会涉及到这些端口对于管理人员来说,管理起来是比较困难的。

所以最好集中的方式用这种指定节点,并且让它只是在几个节点上开端口的方式,或者是用 externalIP 这种方式做比较好。

Docker化应用有多少?5年350万个,2018年Docker使用率出炉

中文社区阅读(2367)评论(0)

历经5年发展,Docker公司揭露了今年最新的Docker年度数据报告,从2013年3月PyCon大会上,Docker首度亮相之后,至今在Docker上的容器镜像下载次数已经超过了370亿次,容器化的应用有高达350万个,目前在LinkedIn网站上的Docker相关职缺也有15,000个。全球活跃的Docker使用者社群已有200多个,包括台湾也有。全球使用企业版Docker EE的企业顾客目前则约有450家。

而过去一年,Docker功能的进展不多,主要有拥抱Kubernetes,在Docker产品中可以和Swarm并用。其次最重要的新功能是增加了RBAC角色存取控管机制,这也是企业最想要的安全机制。另外Docker也推出了传统应用MTA计划,提供一个企业将老旧应用容器化的建议方法。

Kubernetes 1.10发布:更趋稳定的存储、安全与网络功能

中文社区阅读(6103)评论(0)

我们今天兴奋地宣布,Kubernetes在2018年年内的第一个版本——1.10版已经正式发布!

此次新版本的推出不断提升Kubernetes的成熟度、可扩展性与可插入性。本次最新版本提升了三大关键性功能的稳定度,分别为存储、安全与网络。另外,此次新版本还引入了外部kubectl凭证提供程序(处于alpha测试阶段)、在安装时将DNS服务切换为CoreDNS(beta测试阶段)以及容器存储接口(简称CSI)与持久本地分卷的beta测试版。

下面,让我们深入探讨此次新版本中的几项核心特性:

存储——CSI与本地存储迎来beta测试版

这是存储特别兴趣小组(简称SIG)一次极具影响力的发布内容,标志着其在多种功能层面都已经真正实现成熟。容器存储接口(简称CSI)在Kubernetes中的实现方案终于迎来beta版本:如今,安装新的分卷插件就如同部署pod一样简单。这反过来又使得各第三方存储供应商能够在核心Kubernetes代码库之外独立开发自己的解决方案,从而进一步延续了Kubernetes生态系统的可扩展性。

在本版本中,持久(非共享)本地存储管理也迈向beta阶段,这意味着本地连接(非网络连接)存储可作为持久分卷源使用。如此一来,分布式文件系统与数据库的性能将进一步提升,而使用成本则有所降低。

此版本还包含对持久分卷的多项更新。Kubernetes如今可以自动防止某一pod正在使用的持久分卷声明遭到删除(beta阶段),同时亦可防止删除与持久分卷声明绑定的持久分卷(beta阶段)。这将有助于保证用户以正确的顺序删除存储API对象。

安全——外部凭证供应方(alpha阶段)

已经具备高度可扩展性的Kubenetes在1.10版本当中得以对接kubectl凭证提供程序(alpha阶段),从而进一步提升扩展性水平。各云服务供应商、厂商以及其他平台开发者现在能够发布二进制插件以处理特定云供应商IAM服务的身价验证,或者与Active Directory等并非天然受到支持的内部身份验证系统相集成。这一调整补充了1.9版本当中新增的云控制器管理器功能。

网络——利用CoreDNS作为DNS提供程序(beta阶段)

新版本允许您在安装过程中将DNS服务切换为CoreDNS,这一功能目前处于beta阶段。CoreDNS的移动部件更少——仅拥有单一可执行文件与单一进程,且可支持更多其它用例。

社区中的各个特别兴趣小组(特立独行SIG)继续面向各自专业领域提供增强贡献、修复与功能开发。关于SIG的完整内容列表,请点击此处参阅发行版说明。

推出时间

Kubernetes 1.10目前已经在GitHub上正式开放下载。若要开始使用Kubernetes,请点击此处查阅交互式教程。

两天功能博文系列

如果您有意深入探索这些新的功能特性,请关注我们将于下周发布的两天Kubernetes博文系列,其中将重点介绍以下内容:

  • 第一天——容器存储接口(简称CSI)迎来beta测试阶段。
  • 第二天——本地持久分卷迎来beta测试阶段。

发布团队

此次新版本的推出源自成千上万技术与非技术贡献者们的不懈努力。这里要特别感谢Kubernetes项目微软代表Jaice Singer DuMars领导的发布团队。该团队的十名优秀成员做出大量协调努力,包括说明文档、测试、验证以及功能完整性等等。

随着Kubernetes社区的不断壮大,我们的发布流程也代表着开源软件开发工作中的一轮重要合作。Kubernetes继续在快速发展当中持续吸引到新的用户,而这种增长也创造出积极的反馈周期,使得更多贡献者承诺加入进来以创建一个更具活力的生态系统。

项目推进速度

云原生计算基金会(简称CNCF)继续完善着这一雄心勃勃的项目,并着力为其带来无数贡献成果。K8s DevStats中展示了各主要企业贡献者的具体贡献情况,其中亦包含一系列关于个人贡献者及其pull请求生命周期的预配置报告。随着自动化程度的提升,发布末期的问题数量仅略高于初期阶段。这标志着问题的可管理性迎来了重大转变。凭借着75000多条评论,Kubernetes继续在GitHub上成为最具活力的项目之一。

用户亮点

根据CNCF方面发布的一项调查,超过49%的亚洲受访者利用Kubernetes进行实际生产,另外49%受访者则正在评估将其引入生产流程的可能性。目前众多大型全球性机构正大规模使用Kuberentes从事生产活动。近期公布的社区用户故事包括:

全球最大的电信设备制造商华为公司将其内部IT部门应用迁移至Kubernetes上运行,使得全球部署周期从原本的一周缩短到数分钟,应用交付效率因此提高十倍。

全球五大在线旅行社及酒店集团之一的锦江之星旅游公司利用Kuberntes将其软件发布时间由数小时缩短至数分钟,并利用Kubernetes提高在线工作负载的可扩展性与可用性。

来自德国的媒体与软件企业Haufe Group利用Kubernetes将新版本发布时间控制在半小时以内——而非原本的数天。此外,该公司还能够借此将夜间容量缩减至原本的一半,从而实现30%的硬件成本节约效果。

全球最大资产管理企业BlackRock得以利用Kubernetes实现运营效率提升,并在100天之内完成了一款投资者研究Web应用程序的开发与交付。

Kubernetes是否也给您的团队带来切实帮助?请点击此处与整个社区分享您的经历。

生态系统更新

CNCF正在扩展其认证产品规模,包括认证Kubernetes应用开发者考试(简称CKAD)。CKAD考试旨在证明个人在Kubernetes设计、构建、配置与面向Kubernetes发布云原生应用程序的能力。CNCF正在为这一新项目物色beta测试人员。感兴趣的朋友可以点击此处了解更多信息

Kubernetes说明文档如今提供用户旅程资料:基于读者的个人情况及希望达到的目标制定专门的发展路线。对入门者而言,如今Kubernetes的学习难度已经远低于以往,而更具经验的用户亦可找到专门针对集群管理员及应用程序开发者的高质量教程。

CNCF还提供在线培训,用于教授您创建并配置实际Kubernetes集群所必需的各类技能。

原文链接:http://blog.kubernetes.io/2018/03/kubernetes-1.10-stabilizing-storage-security-networking.html

译者:Andy,来源:DockOne

江湖路远,Kubernetes 版图扩张全记录

中文社区阅读(2899)评论(0)

今天的这个故事出自“江湖”,一半关于各路豪杰的江湖纷争、聚合反目;另一半关于 Kubernetes 从初出茅庐到异军突起走过的蜕变之路。

“ 如果有一个 workload 到了亚马逊那儿,你们就完了!” 2013 年,VMware 公司首席执行官 Pat Gelsinger 在公司的合作伙伴交流大会(Partner Exchange Conference)如是说。“现在到永远,我们都要拥有公司的 workload”。作为前英特尔资深经理, Gelsinger 的这些话对云计算五年前的情景作了很好的还原:彼时,VMware 还认为自己是宇宙的中心,并试图捍卫和巩固自己的地位。亚马逊正努力将数据中心迁移到自己的公有云领域。

那时的 Gelsinger 肯定没想到,四年后,他确实再也不用担心失去公司的 workload 了。一场让他意想不到的“江湖纷争”即将袭来,他要对付的可不仅仅是老对手 Amazon 了。

重新洗牌

VMware 一统江湖

“VMware” 中的 “VM” 代表虚拟机,它成为了组织在云平台上部署应用程序的第一个工具。虚拟机的出现引发了大众对“可移植性” (即在任何地方都能部署应用程序)的渴望。但是 VMware 聪明地通过部署和管理虚拟机的方式来保护自己的利益,使得 vSphere 成为所有入站道路的必须监督者。

理想的践行者 Docker

然后,Docker 出现了。它是第一个将“可移植性”赋予数据中心的工具。2013 年,Docker 开发了一个容器机制,将 workload 从笨重的操作系统中解救出来,来维护虚拟机。这样,他们就可以使用 Linux kernel 而不是虚拟机监视器来进行管理。这是当时众多组织触不可及的 “革命理想”,但只有 Docker 践行并实现了。

从出现伊始, Docker 就遭遇了来自企业的质疑目光。同时出现的还有一个广为流传的论断:一个新的市场即将围绕着 Docker 容器形成。套用 PC 世界的旧模板,软件市场当时也是围绕格式和兼容性形成的。推断下去,接下来将出现各大容器公司相互竞争的局面,然后是优胜劣汰,紧接着 Docker 或者其他更强大的竞争对手,会从对手的灰烬中取得最终胜利。

只有当“可移植性”无处不在时,才实现了真正的可移植。2015 年,Docker 放大胆子赌了一把,将整个容器 format 捐赠给了 Linux 基金会赞助的一个开源项目。这个项目现在被称为 Open Container Initiative(OCI)。彼时的 Docker 计划先行一步,放弃人人想要的“可移植性”,让容器 format 增值。Docker 捐赠了容器 format,让竞争对手再也找不到与之竞争的明确方向,Docker 笃定它的未来就在部署和维护容器 workload 的机制上。

Kubernetes 初出茅庐

就在同年,谷歌推动建立了一个独立基金会:Cloud Native Computing Foundation (CNCF)。 CNCF 与 OCI 有很多相同的成员,但 CNCF 专注于容器 workload 的成员们,试图在“部署和管理”方面寻找竞争优势。紧接着,CNCF 就推出了 Kubernetes,这个编排工具将谷歌工作workload staging 概念与 Docker 容器相结合(最初名为“Borg”)。

Red Hat 公司围绕 Kubernetes 重建了 OpenShift PaaS 平台,而 CoreOS 将其业务重点转向 Tectonic,即 Kubernetes 的商业实施。

Kubernetes 的野蛮生长

就像推倒了一块多米诺骨牌,容器领域的众多利益相关者在 2017 年一个接一个地将部署和管理战略倒向了 Kubernetes,包括 Docker 公司本身 :

  • 4 月,托管的 OpenStack 云管理服务提供商 Mirantis,宣布将 Kubernetes 集成到其云平台 1.0 中,并承诺将其 Staging 和配置机制的重点从以安装人员为中心模式,转向以 workload 为中心模式。
    同月,微软收购了基于 Kubernetes 的容器部署平台制造商 Deis,以前所未有的姿态向 Azure 开放平台迁移。紧接着 Deis 技术在 Azure 上出现。 ( 2016 年 6 月微软就已经从 Google 挖走了 Kubernetes 的创始人 Brendan Burns。)
  • 5 月,在波士顿举行的 OpenStack 峰会上,OpenStack 许多社区领导齐聚一堂,承认 Kubernetes 是其私有云模型中,容器 workload 的事实 staging 环境。当时还有一个亟待解决的问题:Kubernetes 或 OpenStack 究竟应该留在虚拟基础架构的最底层,还是应该针对每个客户的情况合理地解决这个问题?
    几乎在同时,IBM 推出了 Kubernetes 支持的云容器服务,向客户提供了一种无缝、即刻启动 Docker 容器的方法。
  • 6 月初,Oracle 在开源会议上承认 Kubernetes 是其新容器 Staging 策略的核心。作为 Docker 的竞争对手,CoreOS 自从平台成立以来就被称为 “Tectonic 的商用 Kubernetes 环境的生产者”。 CoreOS 把最小的 Linux kernel 贡献给 Oracle,Oracle 把自己的 Linux 踢到了一边。
  • 6 月末,在 Cloud Foundry 峰会上,Cloud Foundry 基金会发布了 Kubo,这是一种在传统机器内部 staging Kubernetes 的多个负载均衡实例的工具。这为 8 月份的VMware 和姊妹公司 Pivotal 与 Google 建立合作关系打下基础,并推出 Pivotal Container Service(PKS)。这个消息发布于 Amazon 与 VMware 建立合作伙伴关系一天后,当时 Kubo 已经为 Google 云平台定制进行了商业实施。值得注意的是,在整个 PKS 首次发布会期间,“Docker” 这个词一次也没被提过。(10 月份,Kubo 项目更名为 Cloud Foundry Container Runtime。)
  • 8 月初,亚马逊终于下了“赌注”,加入了 CNCF,并承诺做出实质性贡献。
  • 9 月中旬, Oracle 也正式加入了 CNCF。
  • 9 月中旬,Mesosphere 做出了一个相当惊人的举动,在 beta 版本中,加入了一种整合这两个平台的方法。其用户可以安装、扩展和升级多个生产级 Kubernetes 集群。
  • 10 月中旬,这场容器竞争战似乎发出了即将结束的信号。Docker 宣布拥抱 Kubernetes,Docker 的创始人 Solomon Hykes 在大会上宣布:下一个版本的 Docker 将支持两种编排平台—— Swarm 和 Kubernetes!
  • 10 月下旬,微软推出了一个专门 Azure 容器服务(AKS)预览版,这一次 Kubernetes 不仅站在了“舞台” 中央上,而且 “K” 还是最中间的字母。不久之后,该公司的市场营销和网站给出了它的 Kubernetes 平台的第一个版本,推出了基于 DC / OS 的容器 Staging 平台作为备选方案。
    在同一个月,思科在基于 ACI 的数据中心架构和谷歌云之间,通过 Kubernetes 宣布了一个名为 Goodzilla 的 Bridge。
  • 11 月底,亚马逊正式推出了自己的 AKS 容器服务,并把 AWS 云与 Google 和 Azure 相提并论。

此消彼长

从市场角度来看,所有这些发展都表明:谷歌已经成功地控制了所有通向数据中心容器化道路。众所周知,没有可移植性的容器是毫无意义的,对于数据中心的客户们来说,一个 Staging 和编排环境是远远不够的。

微软第一个证明,通过开源核心优势来迅速占领市场是个可行的办法。当年,它让 Internet Explorer 变得免费,逼得 Netscape 只能通过增加大量不必要的新功能慌张回击,最终还是落得失败下场。Docker 显然也知道这个道理,开源了容器 format,让同类产品不能与之争锋。

然而,Docker 还是没有如当日所愿,建立自己的增值路线——就是那个可以通过开源手段来占领市场的“大杀器”。有人可能觉得,Docker 的基于集群的编排平台 Swarm 还不“成熟”。可是 Kubernetes 在向 Docker 发起进攻的时候可能更“幼稚”,但它有自己的“杀手锏”:相关的容器可以分组到 pod 中。

Red Hat 第一个出来,利用 OpenShift 来展示这一“杀手锏”, 这使得众多开源贡献者都对 Kubernetes 魂牵梦绕。在 Docker 移动创建 OCI 之后, Google 几乎马上就允许 Linux 基金会建立 CNCF,他们的成员几乎是同一拨人,这确保 OCI 部分的设计不会让 CNCF 感到意外,同时也保证了 Kubernetes 在社区讨论桌上的好位置。

Kubernetes 正在进行时

以下是 Kubernetes 正在进行时,在 2018 年肯定会让 Kubernetes 受益:

  • CSI 项目:这个项目最近得到了戴尔技术公司(戴尔 EMC 的母公司)的支持,这个项目承诺,将通过与数据库和 Storage Volume 保持持久链接,提供微服务 。使用 CSI 接口,任何打开这种持久链接的 API 都可以通过三个主要容器编排平台:Kubernetes,Mesos(DC / OS)和 Swarm 进行同样寻址。它目前由 Moby 管理,而 Moby 却是由 Docker 原始的开放源代码产生的,但现在 Moby 有一个独立的方向。这对于 Kubernetes 而言非常有利,开源数据 Plugins 的主题再也不是 Docker 领地中的本地特性了。
  • CRI-O 项目:它利用 Kubernetes 的原生 Container Runtime Interface (CRI),使容器编排平台能够通过本地 API(一个称为“runtime”的可寻址组件)实例化一个容器。目前在许多数据中心,生产环境把 Docker Engine 作为 Orchestrator 和 Runtime 之间的中介; CRI-O 专门为 Kubernetes 提供让 Docker 完全隔离在生产环境的方法,让它只能出现在开发人员的工作台上。
  • Kata 项目:Kata 与 Docker 的竞争对手 Hyper 一同加入英特尔的 Clear Containers 项目中。Kata 可以为数据中心提供构建和部署 workload 的方法,Docker 将会完全被淘汰,同时还能够在基于容器的 workload 和第一代虚拟机之间共存。OpenStack 基金支持这个项目,它将利用 Kubernetes 作为其主要容器编排平台。

然而即便迎来了如此全胜局面,Kubernetes 仍然面临着巨大的挑战。具体来说,Kubernetes 可能变得如此无处不在,如此标准化,以至于任何供应商或开源贡献者都难以围绕它再创造竞争优势了。

路漫漫其修远兮

对于数据中心来说,Kubernetes 的突然出现意味着:过去基于公有云的 PaaS 平台,如 Heroku 和原来的 Windows Azure,只有使用它支持的资源和语言才可用。而现在,只要使用 Kubernetes,每个人的平台都支持容器内部,而不是外部。这有助于在一定程度上平衡服务提供商,因为他们现在都可以提供相同的界面来获取和托管客户的 workload。这也缩小了这些提供者在服务上彼此竞争的空间。规律如此,每当市场商品化,幸存者都是那些赢得价格战的人。

Kubernetes 可能已经在 2017 年完全超过了 Docker。但是市场瞬息万变,谁又能保证在 2018 年 Google 或其他任何人不会超过它呢,江湖路远,让我们拭目以待!

看后Kubernetes时代 – 容器生态2017

中文社区阅读(2902)评论(1)

如果说2017年的容器技术圈子只能用一个关键词来概括的话,那一定非“Kubernetes”莫属。

从2017年2月,“Kubernetes”开始频繁登上各大技术媒体头条,来自不同维度不同渠道的商业分析和技术文章也纷至沓来。有趣的是,无论是官方报道还是个人评述,无论是直接还是委婉,无一不在透露着一个同样的信息:“Kubernetes要赢!”

可是,描述这样一个连商业实体都没有的开源项目“要赢”,总是听起来有些奇怪。

“要赢谁?”

“为什么要赢?”

“赢了之后呢?”

我们不妨就从这个论断说起吧。

Kubernetes赢在何处

如果说错失了Big Data时代的Google实在令人扼腕,那么Container时代的Google终于靠开源社区打了个翻身仗。虽然在最初的lmctfy项目(Google自研容器)上依然栽了跟头,虽然同Docker公司共举容器编排大业的计划依然吃了闭门羹。但Google还是笑到了最后。

不过,Kubernetes项目的发展绝非一帆风顺。它的前期只有一篇不温不火的B类会议文章Borg来站台,远没有“三大paper”一举奠定大数据基石那么耀眼。而在它发布的之后,炙手可热Docker公司却始终拒绝同Google开展任何形式的合作。而与此同时,Mesos等一票老牌调度系统的阴影则从一开始就让Kubernetes团队心有芥蒂。种种不利因素,再加上当时Google在Kubernetes上投入资源时的捉肘见襟,无论再怎么乐观,这个“要赢”的论断恐怕都不容易成为现实,

当然,如果不是Google找到了一个靠谱的盟友的话。

这位盟友有多靠谱?它是这个世界上唯一一家年盈利超10亿美元的开源技术公司。

Kubernetes刚发起的时候,其核心的理念来自几位“Elder(元老)”的构想,他们大多是Borg和Omega项目的开发者或者架构师,一直专注于如何在没有cloud的场景下构建足够规模的通用Infrastructure Layer的实践,并且在这个领域摸索的过程中,这批技术人员也逐渐形成了一套创新性的设计理念,这些观点在Borg论文中曾经透露出了一些端倪,但真正全面揭晓还是依托于Kubernetes开源项目。所以如果大家回头去翻Kubernetes最早的一些Issue和Design,其实都是一篇篇“小论文”,思路严谨,论证充分(废话连篇),这跟大多数开源项目早期的头脑风暴,或者围绕一个核心设计逐渐展开的做法,是有很大不同的。

另一方面,彼时的RedHat正苦于自家OpenShift被竞争对手碾压的境况。经典PaaS不能破局的困难,反倒让RedHat对Docker这个有望颠覆PaaS的项目格外上心。这样一个在操作系统领域积累深厚、资源充足、并且蠢蠢欲动以求变革的开源巨头,碰上了满脑子Idea却对全面推进Kubernetes心有余而力不足的Google团队,可谓一拍即合。2014年12月,在Google正式发布Kubernetes项目不久,RedHat即官方宣布与Google开展战略合作,全面投入Kubernetes。在当时的一份官宣中,RedHat以非常自信的姿态表达了对容器的“颠覆性”创新的认可,并大胆预言Kubernetes会在2015年后取得应用编排与管理领域的统治地位:

……(RedHat的竞争对手们) 必须要认识到自研任何容器的局限性,尽早接纳Docker项目 ……

…… (RedHat的竞争对手们)必须要认识到没有人能够同Google在成规模的容器编排和管理领域里相抗衡 ……

谁曾想到,当年这套透露着几分“终于傍上大腿”的侥幸、甚至“托大”的说辞,现在看起来却几乎句句“实锤”。

这也是为何,Kubernetes虽一直大幅受益于Google的声誉和名望,还长期拥有Borg/Omega团队的技术加持,但如果从技术实现上来审视,这个项目却称得上是半个RedHat项目。也正是凭借最初阶段“Google赋予灵魂,RedHat赋予实体”的策略,Kubernetes才能够秉持着天马行空的设计思想的同时,稳扎稳打,然后一步步崛起于社区。

如今的Kubernetes,既赢得了GitHub等众多明星用户的青睐,也受到了全世界所有公有云巨头的热捧,还硬生生把Docker公司逼到改旗换帅、彻底摒弃了以往“暴力不合作”的路线,如果用一个“赢”字来描述它现在的情形,倒也并不为过。不过,这个“赢”字背后的原因,又在哪里呢?

Rancher的创始人梁胜博士最近有过一句评论,可谓道破天机:

时至今日,在容器技术领域依然有许多创新,只不过这些创新大多发生在Kubernetes以及CNCF生态系统中了

没错,容器技术圈的创新能力,在2015年后就已经逐渐转移到了Kubernetes生态,这是一个不争的事实,却也是一个曾经被忽视的变化。实际上,伴随着DockerCon越来越“boring”,Kubernetes的专属生态CNCF基金会却开始风生水起的原因也正在于此。

而从技术的角度上看,Kubernetes生态能取得这样的成功,依托的乃是一项其他竞争对手所不具备的核心能力:“使能用户二次创新“。

何谓“使能用户二次创新”?这其实是Kubernetes项目从开始设计之初就高度重视的一项关键诉求:

第一:从上层API到底层容器运行时,Kubernetes工作流中的每个环节,都希望具备完善的可扩展性。

第二:Kubernetes任何功能特性的设计和实现,都尽可能针对更通用的用户场景而非特定需求。

原生“使能二次创新”的技术基础,加上Google与生俱来的技术号召力,在加上CNCF基金会的整合和商业运作,以Kubernetes为核心所建立起来的这套容器编排生态,绝不比Docker公司最初建立起来的以容器为核心社区有任何逊色。再加上容器编排与管理的概念天生就更接近用户,Kubernetes的理念很快被社区接纳乃至追捧,也是情理之中。

一个直观的例子就是CoreOS的Operator项目。我们知道,在Kubernetes里部署任务,经常使用的是Deployment(Replication)来管理多个副本组成集群。但如果我们这次要部署的任务比较特殊,它的集群需要在增/删副本之后/之前做手动的运维操作呢?各种数据库集群就是最典型的例子。而Operator实际上是个用户自己编写的管理器,通过编程的方式把“运维”逻辑写进了管理器的代码当中。但关键在于,这个管理器的编写过程是完全“无脑”的,无非就是复制粘贴官方模板、然后填充自己的运维逻辑而已。这是因为Operator是构建于Kubernetes的CRD(自定义API资源)特性之上的,这个特性的目的就是允许并帮助用户自己编写一个可以与系统etcd交互的、Kubernetes风格的API资源管理器,并无缝地衔接到Kubernetes的核心API当中。

这个设计看起来很很直白,但是却解决了一个长期以来困扰系统级开源项目的难题:用户对项目的API不满意怎么办?

在过去的实践中,原封不动使用开源项目的场景是非常少见的,更常见的情况是用户把开源项目的API修改的面目全非。但在Kubernetes的场景下,用户的自定义API和原生API可以友好共处,统一对外服务,而且不会随着upstream变更而分家。这是保证Kubernetes社区完整性和被接纳程度的一个核心手段。

更为重要的是,有了这些标准化的扩展性API,用户就可以发挥自己的能动性,在Kubernetes之上构建出更多的扩展,甚至把这些扩展再交还给社区中的其他用户推广和使用。正如CoreOS的Operator,现在已经成为了社区运维有状态应用的一大法宝。

当然,“二次创新”的例子远不止于此。

2017年5月24日,Lyft,IBM联合Google共同宣布了Istio项目,一举撼动了微服务这个以往“光说不练”的“花架子”领域。Istio的核心思想,乃是借助一个proxy来接管容器里业务的进出流量,从而通过在proxy上的控制操作来完成应用流量的切分、访问授权、策略配置等一些列微服务治理功能。可以看到,这里有一个核心问题是:如何保证每一个需要治理的容器都绑定这样一个proxy呢?

解决这个问题的手段就是Pod。作为Kubernetes里的核心概念和原子调度单位,Pod是一组亲密耦合的容器集合,容器之间共享同一Network Namespace,显然,Istio框架中的proxy和业务容器正属于这样的耦合关系。但这还不是关键所在,这里最棘手的问题在于,Istio要做的是一个非侵入型的微服务框架,不可能要求用户在自己的部署文件中每次都额外定义一个proxy容器。怎么办?

答案还是借助Kubernetes。Kubernetes中有一个叫Initializer的扩展机制,允许用户在不修改业务Pod部署描述前提下,请求Kubernetes为业务Pod“自动注入”并启动一个预先定义号的容器。在Istio里,这个自动注入的容器正是前面不断提到的proxy:Envoy(Lyft自研的高性能服务代理)。

可以看到,通过组合Initializer等一系列Kubernetes标准API,用户可以优雅地实现很多以往繁琐或者困难的分布式系统的构建工作:就比如Istio里这套Spring AOP(面向切面编程)风格的组合方式。也正是因为有了这种标准化的实现手段,用户基于Kubernetes的“二次创新”才有可能再次交还给Kubernetes社区,从而碰撞出更多的创新火花和更新颖的用户案例。最终,不断激发出的创新开始吸引了更多人力和资本的进入,而资本与生俱来的促进作用就会推动这个社区的更强势的扩张。这种“开源-社区-商业”互相促进而构建出来的正向激励循环,正是Kubernetes生态在过去一年里“势不可挡”的重要原因。

回想在Kubernetes刚发布的时候,甚至在2017年初,Kubernetes的Pod以及Pod所体现出来的“解耦容器关系”的设计模式,依然时常被质疑为“用处不大”或者“过度设计”,然后现在回头来看Istio项目的炙手可热,我们确实要感慨“技术视野”的培育绝非一朝一夕。

从利用CNI、CRI等一系列良好设计的通用接口来实现不同类型、不同功能的网络和容器运行时,到使用API Aggregation扩展Kubernetes API Server从而支持自定义资源监控格式并以此来做Auto-Scaling,Kubernetes生态之中类似的“二次创新”的例子已然不胜枚举。依托于这种原生地鼓励用户发挥自己聪明才智的先进理念,在2018年,我们有足够的理由相信“二次创新”将继续成为Kubernetes生态中的一大关键词,各种基于Kubernetes可扩展能力的创新工作将成为社区的常态,甚至成为更多团队“一战成名”的不二法宝。

在未来,已经争取到领先地位的Kubernetes项目的进化重点,将逐步转移到安全性、稳定性、多租户能力、规模和性能优化、可扩展性设计等更多横向功能的升级上面。另外,将更多的非核心功能从主干代码中移除也将是未来一段时间Kubernetes社区的主要工作之一。2017年里,随client-go、apimachinery等API库的独立,已经为CRD等可扩展性功能的实现带来了极大的便利,而将来诸如部署工具kubeadm,内置的各种Cloud Provider,内置的rkt集成,各种各样的volume plugin等代码,也都将逐步迁移到它们单独的库中维护,这将有希望大大降低Kubernetes主库的复杂度和维护难度。

另一方面,Kubernetes可扩展性上的另一个重要设计CSI(Container Storage Interface)也已经发布。这意味着不久的将来,就如同容器运行时一样,容器持久化存储方案也将不必再跟Kubernetes的核心代码耦合,Kubernetes将使用统一的gRPC接口在完全独立的控制逻辑中维护容器存储卷(volume)生命周期。这个设计也很有可能会刺激容器存储领域更多的创新工作和更多的存储选择出现在Kubernetes社区当中。而包括KataContainers在内的虚拟化容器运行时,也将受益于存储解耦带来的、完全不同于现有容器存储设计的高性能的持久化存储方案。

在接下来的集群管理能力上,目前最大5000个节点的支持能力已经能够满足大多数用户的生产需求,而IPVS Service的引入也有很大希望能解决以往纯iptables Service引发的大规模集群中性能额外损耗问题。而在调度层面,默认调度器的可配置规则已经大幅增加,调度优先级和抢占技术也已经进入了默认调度器的alpha功能当中。而通过灵活配置亲密/反亲密关系、Taint/Toleration规则,Kubernetes的使用者已经能够解决绝大多数生产环境中的运维和调度需求。

在多租户与安全能力上,Kubernetes项目终于弥补上了这部分的短板。RBAC(基于角色的访问控制)功能目前已经成熟应用于很多基于CRD的Kubernetes外部扩展上面,Secret存储的加密也已经实现,集群部署中的节点通信加密配置也成为了默认功能。而在社区中,更完善的“强多租户”设计也第一次被提出,以便真正满足多租户环境下的集群管理需求。不过需要指出的是,Kubernetes的角色定位依然是Layer 0(Infrastructure Layer),更倾向于对上提供必要的多租户支持API和规范而不是实现完整的多租户模型。后者还是需要依靠Layer 1(Service Layer)来自己完成。

2017年也是人工智能技术席卷全球的一年,Kubernetes在其中也扮演了推波助澜的作用。在与之相对应的硬件加速器(Hardware Accelerator)功能的设计上,Kubernetes社区在Google,NVIDIA和Intel的牵头下发布了Device Plugin来允许用户自己编写自定义的、自发现的高性能硬件资源描述,并且以此为基础,将支持NUMA,InfinitiBand,FPGA等硬件框架的设计纳入了路线图。随着Kubeflow等项目的发布,不难预料到,Kubernetes在新的一年里会继续加大同人工智能社区合作,向成为机器学习领域支撑大规模分布式训练和AI服务的默认框架这一目标上不断挺进,而在此过程中,各家vendor在Kubernetes社区中进行技术上的角逐,亦将成为这个领域的主旋律之一。

随着Kubernetes项目的逐渐稳定,其开发迭代周期也将有所放缓,将目前每3个月一次release周期延长已经被提上讨论日程。与此同时,随着社区自动化管理能力(bot)的提高和SIG(Special Interest Group)组织的进一步完善,现有社区成员的写权限回收也是将来可能发生的大概率事件。这些都是Kubernetes社区逐步走向成熟的标志性里程碑。

容器运行时的二次繁荣

2017年,Kubernetes引领了容器编排与管理领域的蓬勃发展,而与此同时,另一个很有意思的现象则是容器运行时(Container Runtime)迎来了一次难得的二次繁荣。

一般来说,伴随着容器编排领域的迅速发展和成熟,容器运行时技术一定会因为被上层编排框架所屏蔽而逐渐淡出用户视野。事实上,这也正是Docker公司自成立以来的心病:光有一个容器运行时Docker,并不足以吸引用户真正投入到有价值的商业产品(比如PaaS)上来,更何况容器技术本身又是一个门槛相对不高的组合性创新成果,不能形成长期有效的技术壁垒。这个事实,也正是Docker公司一定要强推Swarm和SwarmKit等项目,以及Mesosphere曾短暂取得瞩目的一个主要原因。

当然,在Kubernetes依托社区和强大的创新能力崛起之后,容器运行时和它背后的主体的淡出便成了不可避免的宿命。这也是为什么我们会看到Docker公司会宣布将它的开源项目改名为Moby,这其实是它自己宣布将要放弃在开源社区中继续同Kubernetes和CNCF社区对抗的重要信号。这也是为什么我们会看到containerd和rkt被接连捐献给CNCF基金会:各类容器运行时的历史使命已经走向尾声了。

但是历史总有意外。Kubernetes的扩展性设计中一项核心功能的确立,却为容器运行时的创新者带来了新的机遇,这就是CRI(Container Runtime Interface)。

CRI的诞生还得追溯到容器运行时第一次繁荣、也就是容器理念第一次席卷技术圈的时候。彼时,Docker公司手持Docker项目大杀四方、是当之无愧的容器技术领导者。而CoreOS公司在选择拥抱Google和Kubernetes的同时,则发布了rkt以制衡Docker,以希望维护自己在容器技术上的话语权。这两位,再加上RedHat,他们在容器运行时领域的合作与竞争,直接推动了OCI这一容器技术标准的诞生。但实际上我们不难看到,Docker公司在容器运行时领域所占据的绝对主导地位,以及OCI本身对Docker公司商业利益的不友好意味,使得OCI长期以来并没能发挥出“标准”所应起到的推动和整合作用。

也正是在这个阶段,以Intel ClearContainer和Hyper为代表虚拟化容器技术,则开始从安全和多租户角度进入到开发者的视野。一时间,容器运行时领域可谓熙熙攘攘,不胜热闹。

而在Kubernetes发布之后,很多机敏的技术人员其实已经嗅到了其中的机遇。在Kubernetes未来有大概率会成功的前提下,谁能在Kubernetes内置的容器运行时中抢占到一个位置,谁才有可能在将来的容器技术圈子中争取到一席之地。所以很快,CoreOS公司通过政治和技术双管齐下的努力下,rkt成功跻身为Docker之后第二个被Kubernetes支持的容器运行时。但也正在这时,一些连锁反应式的问题也被激发出来。

一方面,彼时的Kubernetes羽翼未丰,并没有强势到能直接帮扶起rkt这个相对弱势的容器运行时的地步,更何况当时的Docker项目正突飞猛进,没有给同质的rkt留下任何喘息和反击的机会。所以虽然很早就进入了Kubernetes体系,rkt却一直处于少有用户问津的尴尬地位。

而另一方面,在当时快速迭代、完全没有稳定的Kubernetes尤其是kubelet组件中,额外引入的rkt运行时其实带来了大量的维护工作,并且这些工作很多时候还要依赖于CoreOS的介入才能解决,这无疑给Kubernetes团队带来了很大的压力。

与此同时,Kubernetes团队本身并不希望锁定在Docker容器之上。Docker公司不断推进Swarm项目的决心,很难让人对继续使用这样一个唯一的、不稳定的、将来甚至可能会变成一个PaaS的“容器”感到放心。

在这样的背景下,适逢Kubernetes团队也开始尝试逐步在项目中引入虚拟化容器技术,能不能提供一个通用的、与下层容器运行时无关的接入层来无缝对接上述所有容器运行时,就成为了当时Kubernetes能否更进一步关键所在。更重要的是,这也是Docker的软肋之一。由于显而易见的原因,Swarm体系并没有动力去支持任何非Docker之外的容器运行时,而另一方面,彼时的OCI话语权不济,并不能发挥对接其他容器运行时的作用,这就意味着Kubernetes项目会成为对接非Docker容器运行时的唯一出路。

就这样,一套由Google,Hyper和CoreOS共同主导的、以Kubernetes项目为核心的容器运行时接口的设计,应运而生。

CRI的及时发布,使得Kubernetes团队在后续SwarmKit等事件中可以处变不惊。而它的诞生,也直接推动了容器运行时这原本应该逐步淡化的领域焕发了第二次繁荣。

cri-o与cri-containerd

这次繁荣的第一个标志性的事件,是runC容器运行时cri-o的发布。

cri-o的初衷非常直白,既然现在Kubernetes可以借助CRI对接任何容器运行时甚至虚拟机,那么我们自然会想到,为什么不直接把runC封装成一个CRI的实现呢?这样不就可以绕过现有Docker容器的大部分机制而直接操作Linux容器了么?

所以,不同于Docker,除了用来响应CRI的gRPC server,cri-o并不需要额外的daemon组件来维护Linux容器。CRI的API调用在这里被直接翻译成对runC的操作命令,然后在宿主机上创建并启动runC容器。不难看出,这个工作流其实跟containerd的功能是基本一致的,但有意思的是,cri-o的发起者RedHat并没有使用containerd而是重新造了轮子。这其中,containerd的实际维护者是Docker公司恐怕是主要的考量因素之一。

实际上,在Docker公司决定打造自己的封闭生态之后,RedHat就跟Docker公司走向了对立的一面。毕竟相比Google专注于公有云业务而不太在意企业及市场,Docker公司随后发布的每一项产品(项目),却都在不同领域实实在在争抢着RedHat的蛋糕。作为曾经一起同推进容器技术的“兄弟”,如今“分手”后的RedHat对Docker公司的负面态度是可想而知的。所以,cri-o在某些实现细节上透露出来的一些偏执,也是这种思想指导下的必然产物。从最初放出言论要“fork Docker”,到现在cri-o的实际落地,RedHat在容器运行时领域的志向目前都压在这个项目之上。这也是为何RedHat的宣传机器在2017年 可谓开足了马力,连Kubernetes首席布道师Kelsey Hightower也曾短期被“攻陷”过。

然而,开源社区里最有意思的事情也莫过于此。就在cri-o几乎要以下一代Kubernetes默认容器运行时的身份粉墨登场之时,Google和IBM以及containerd的维护者们却默默的上线了cri-containerd项目。这个项目的思路更加显而易见:鉴于containerd已经捐给了CNCF,现在只要在其基础上略微封装,就可以为Kubernetes打造一个Docker native的、身份中立的CRI实现。相比cri-o每个release都要推广一番的风风火火,cri-containerd的进展可谓低调,仅在最近的DockerCon上小幅亮相了一次,并且期间一直与cri-o保持的良好的合作关系(比如共同维护lib)。但低调并不意味着不作为,2017年底,cri-containerd项目悄无声息地开始了与containerd项目的合并计划,这意味着很快containerd本身将会原生支持Kubernetes CRI。

CRI的成功我们有目共睹,但Kubernetes下一代默认容器运行时目前却尚无定论。Kelsey Hightower一向不太“待见”Docker,他的成名作“Kubernetes the Hard Way”在短暂试用cri-o后目前还是切换到了cri-containerd上。不过这也并不足以说明所有问题,至少在未来一段时间内,“No Default”还是可以继续作为这一领域的官方说辞。

不过,cri-o本身的崛起,侧面说明了“得编排者得天下”是目前容器运行时领域进一步发展的正确思路。CRI的及时发布,使得Kubernetes团队在后续SwarmKit等事件中可以处变不惊。而它的诞生,也直接推动了容器运行时这原本应该逐步淡化的领域焕发了第二次繁荣

Kata!Kata!

这个事件,正是Hyper runV同Intel ClearContainer的合并。合并之后的项目以KataContainers命名并托管于中立基金会,为虚拟化容器技术路线之争画上了句号。

实际上,在Hyper推出了runV技术之后,部分敏锐的技术人员就迅速开始了往Kubernetes推进基于runV的虚拟化容器技术的的集成工作。相比于Swarm体系的封闭和Mesos社区的后知后觉,Kubernetes项目从一开始就展现出来的技术远见,使得这个选择倒并不意外。而这次技术行为的直接结果,则是推动了CRI这一关键特性的诞生和落地:又是一个典型的社区“二次创新”然后再反哺社区的故事。在这个过程中,kubernetes/frakti项目作为虚拟化容器运行时的官方CRI实现,正是推动这项技术进入Kubernetes生态核心的关键一步。

不过,相比于Linux容器领域的Docker项目的一枝独秀,虚拟化容器技术则有一个困扰社区许久的问题,那就是几乎同期发布的Intel ClearContainer项目一直以来跟runV处于重合位置。尽管在项目的后期,Intel和Hyper团队已经开始共同维护很多公有的子项目,但开源社区的掣肘关系依然牵制了虚拟化容器技术进入容器生态核心的步伐。

不过,明智的是,runV并没有固执地在容器API层面同Intel开展类似Docker和rkt之间的竞争,而是把原生接入Kubernetes当成了第一要务,希望借助上层编排框架来为容器运行时发声。这个策略无疑改变了社区对虚拟化容器技术在整个生态中所处位置的看法。事实上,相比于我们所熟知的硬件级别隔离和容器安全这样的常识,虚拟化容器技术的独立内核特性为Kubernetes支持遗留应用和传统业务带来的巨大的想象空间,才是这种技术最大优势所在。尤其是伴随着2017年后期“强多租户”概念被引入到Kubernetes社区,能够从容器运行时层就开始进行租户隔离的设计已经成了一种刚性需求。没有虚拟化级别的隔离能力和独立内核来保证业务的多样性,“强多租户”基本无从谈起。试想一下,在一个真正的多租户云数据中心里,有的租户的应用是Windows的,有的是Linux的,除非做低效的静态划分,常规Linux容器又该如何应对这样的需求呢?

KataContainers项目的出现,把刚刚崭露头角的虚拟化容器技术推向了一个新的阶段。作为OpenStack基金会力图革新后发起的第一个项目,托管于该基金会下面的KataContainers却不必遵守OpenStack社区任何现有的规范,其自由度和改革力度,可见一斑。而这次合并的最终促成虽然被OpenStack基金会抢了先机,但CNCF基金会则开始从OCI入手,试图将KataContainers的运行时再纳入到OCI的范畴之中。我们有理由相信,在两大基金会的通力合作之下,KataContainers的前景非常光明。

不过,更为重要的是,以KataContainers为代表的虚拟化容器技术在云计算领域的探索,正有意无意地打开了公有云的一个新篇章。

ACI,Fargate与“Serverless容器云”

在runV容器发布之后,为了验证虚拟化容器对公有云带来的变化,一个名为hyper.sh服务同步上线并随后迅速霸榜了HackerNews头条。这个服务的创新之初在于,虽然它的整个技术栈都基于Kubernetes,但是它却不对外暴露任何Kubernetes API,也没有提供任何操作console,而是让用户用本地的“hyper run <IMAGE>”指令来在云端创建和启动容器。由于使用了虚拟化容器技术,这个工作流里完全不需要虚拟机的介入,所有租户的容器直接运行在裸物理机集群当中。

虽然看起来简单,但这个设计的本质,却提供了一种容器云的Serverless的设计思路。在这个“无服务器”云的设计中,云的用户完全不必学习任何Kubernetes或者云平台API或者文档,仅靠开发者所熟悉的本地容器操作就可以完成作业的云端部署,然后按秒计费。

而在2017年,这种颇有远见的容器云Serverless开始得到了公有云巨头的青睐。这一次的始作俑者正是近年来在云服务领域出手“稳”、“准”、“狠”的Microsoft。2017年7月26日,Microsoft Azure团队宣布了ACI(Azure Container Instance)服务的发布,其通过“az container create”创建容器的思路,与hyper.sh如出一辙,并且同样屏蔽了所有下层的PaaS和IaaS概念然后按秒计费。一石激起千层浪,国外容器技术圈子对这种服务的讨论迅速成为了当时的技术头条。有人说它是AWS Lamda的有力竞争者,也有人说这才是Serverless服务的终极形态。

紧接着,在2017年11月,堪称全球云计算技术风向标的AWS re:Invent 大会上,AWS高调宣布了同类型服务Fargate的诞生,把Serverless Container Cloud的理念推向了新的高潮。作为回应,Microsoft则联合Hyper发起了virtual-kubelet项目,旨在定制一套标准,允许云提供商把自己的Serverless Container Cloud,以kubelet API的方式接入到任意的Kubernetes集群中作为一个特殊的节点而存在,从而轻松实现一个基于Kubernetes的混合云。目前,AWS、甚至OpenStack都已经加入这个项目开始贡献自己的实现,对应的基金会和开源生态正迅速形成。不出意外,很快Google、国内的阿里云等巨头,也会推出类似的Serverless Container Cloud服务,并且加入到virtual-kubelet项目当中。

Serverless Container Cloud服务备受欢迎的本质,乃在于公有云计算所服务的用户,尤其是广大的开发者群体,对于追求“简单高效”的热情其实是非常高涨的。对于他们来说,在各种设计拙劣的云管理界面上进行凌乱的鼠标操作,绝对不如在键盘上敲打本地命令来的舒服。这种微妙的体验变化,正如同git对比SVN,Docker对比OpenStack。更为重要的是,这种服务形态也正符合了Kubernetes技术继续发展的正确路线:Kubernetes所要扮演的角色,乃是取代传统的Infrastructure Layer并鼓励技术人员进行上层的“二次创新”,而并不是直接面对最终用户(实际上Kubernetes本身的声明式API也是对运维而非开发友好的)。真正为最终用户提供云服务的,很大概率应该是构建于Kubernetes之上的、更加简洁高效的服务型API,而Serverless,尤其是Serverless Container Cloud的设计,正是这种需求下最为贴切的实现方式之一。

不难预料,在新的一年,基于Kubernetes之上构建出来的创新型Serverless服务(当然也包括OpenFaaS等优秀的Function),将会是大小云计算提供商进一步角逐的一个关键领域。相比之下,曾经在国内外普遍开花的、以直接售卖Kubernetes集群为核心的各种“CaaS”,将会沉寂许多。

Docker Inc的未来

毫无疑问,2017年的Docker公司依然是容器圈子里的主角。只不过这一次,波澜之中的Docker公司的确并不好过。

从2017年4月Docker项目毫无征兆地改名为Moby开始,Docker公司顶着巨大的争议,逐步完成了开源技术创新公司到商业公司的转变,也开始正视长期以来同Kubernetes社区竞争所带来的极其不利的商业局面:伴随着Kubernetes项目的成功,Swarm已成为明日黄花,曾一度承载着新希望的SwarmKit也渐渐淡出社区视野。2017年10月,在DockerCon EU上,Docker公司官方宣布下一版本的Docker EE中将全力拥抱Kubernetes,标志着持续了近三年之久的容器编排之争彻底落下帷幕。紧接着,所有纷争的始作俑者、曾经携Docker对抗整个容器社区的Solomon Hykes也宣布自己“角色转变”,不再负责Docker产品的具体技术事宜。

曾经纷纷扰扰的容器圈子,竟然一夜之间尘埃落定,个中滋味,不免让人心生惆怅。Docker公司和Solomon的经历可能不算是传奇,但也绝对能够在云计算历史中留下了浓墨重彩的一笔。我们甚至会不时想象,如果当初Solomon没有去做Swarm,而是选择同Google合作共举Kubernetes,如今的CoreOS还会不会活着?如今的Docker公司又是什么样子?

历史难做假设。

但是Docker公司的未来却依然是光明的。

在积极拥抱Kubernetes社区之后,Docker公司正走向正确的轨道。大家不要忘记,在迎合开发者社群和技术微创新这两个关键手段上,Docker公司的实力绝不容忽视。2018年初,Docker Mac集成Kubernetes的版本正式发布,并立刻在开发者群体中掀起了轩然大波。在Mac OS上如此流畅启动和运行Kubernetes的体验,在这么短的时间内就被Docker公司带到了开发者手里,这其中体现出来的技术能力与产品理念,正是将来Docker公司继续立足的核心所在。当然,Docker公司最终的成功,依然取决于其商业产品能否赢得重量级客户的青睐,在这一点上,Kubernetes的坚定盟友CoreOS已然占尽先机并且完成了转型。但是Docker公司在容器领域不俗的创新能力和产品积累其实是有增无减,其产品线也更完整,在开发者群体中的基础也更雄厚,这样一个人气与技术兼备的创业公司的未来,绝不见得会像某些文章中描述的那样一片哀鸿。这一点,我们不妨拭目以待。

国内

相比于过去默默无闻,2017年的国内容器技术玩家终于得意发声,而且“不鸣则已,一鸣惊人”。阿里集团在双11过后,高调发布了源自其内部容器T4的开源项目Pouch,并迅速成为了当时的技术热点。事实上,早在Docker和Kubernetes技术如火如荼的2015年,业界就发出过疑问:在此领域积累深厚(百度有Matrix,阿里有T4)的国内的互联网巨头为何迟迟不见动作?

好在厂商会迟到,但技术不会。Pouch的发布,也正是前面提到的“2017年容器运行时技术二次繁荣”的又一例证。在Docker公司逐渐式微、rkt几乎退役的档口,Kubernetes的崛起和CRI的成熟正在为所有的容器运行时玩家带来全新的机会。从代码上看,Pouch并非“Docker fork”,而是利用类似技术进行的全新实现。从功能上看,Pouch原生接入了runV来提供多样化的隔离机制,内置“富容器”能力以满足不同的业务场景,打包了Dragonfly来实现高效的镜像分发,这意味着这套技术栈从底自上有着同Docker整体不一样的业务考量。

但另一方面,如今的时间点不同与2015年,用户的关注点已经从容器运行时转移到了上层容器编排管理的服务能力。而作为近来Linux容器的第三个实现(cri-o只支持Kubernetes,不能算作完整的容器实现),尽管功能上有所差异,但Pouch仍然难免会陷入同质竞争的不利局面。不过需要指出的是,阿里集团接下来亦在酝酿其内部集群管理系统Sigma项目的开源工作,并且会积极地将Sigma纳入到Kubernetes的现有生态当中,这就为Pouch未来的前景增添了一层有趣的砝码。毕竟,Pouch本身在Docker的优势地位中突围可以说困难重重,但正如前面所提到过的,如果能够借助上层容器编排能力重新表达这一容器运行时的关键作用,那这套技术方案的应用前景和接纳难度很可能会发生变化。这也正回到了我们最开始谈到“Kubernetes赢在何处”时所作出的阐述:Kubernetes社区通过从技术和生态双重层面上使能用户二次创新的做法,必将推动这个生态走向一个更加繁荣而有意义的新阶段。

总结

“任何一个被浓厚的商业兴趣所充斥的开源社区,最后都难免走向有毒的方向”

— Solomon Hykes

2017年,曾经的弄潮儿Docker公司在巨大的争议中终于完成了向商业公司的重要转变,也宣告了由Kubernetes社区所主导的、全新的容器生态正式拉开序幕。在回顾Kubernetes如何赢得这次竞争的同时,我们应该意识到容器运行时“二次繁荣”的短暂窗口正在为我们带来新的机遇。与此同时,容器公有云的形态正在悄然发生变化,伴随着这次变革而存在的,固然有风险,但也有很可能会催生出新的云计算赢家甚至独角兽。最为重要的是,伴随着Kubernetes社区的日益壮大,如何避免这个生态陷入Solomon所警告的“有毒”陷阱,恐怕很快就会成为摆在这个社区所有参与者面前的一道难题。是的,是所有参与者都对此负有责任,而绝不仅仅是CNCF或者Google就有能力独自解决的一次危机。

作者

张磊,浙江大学博士研究员,Hyper项目成员,Kubernetes项目资深成员与社区维护者。长期专注并活跃于容器集群管理与云计算数据中心领域,连续多次被微软授予该领域“最有价值专家(MVP)”称号。

来源:infoq

http://www.infoq.com/cn/articles/2017-container-Kubernetes

2017Docker公司过的不容易

中文社区阅读(2244)评论(0)

编者话:本文来源云头条微信公众号,原标题,“Docker公司已死”,个人觉得此title太过标题党,索性改成“2017Docker公司过的不容易”似乎更贴切。

作者简介:Chris Short在IT行业有20多年的从业经历,他毕生坚定地提倡使用开源解决方案。他是身体部分残障的美国空军退伍老兵,现与妻子和儿子一起住在密歇根州大底特律都市区。

要说Docker在2017年的日子非常难过,那已经算是轻描淡写了。除了优步(Uber)外,我实在想不出还有哪一家更加被利用、被炒作、资金充裕的硅谷初创公司(仍在运营之中)像Docker在2017年那样步履维艰、糟糕透顶。回顾2017年,人们会记得在这一年,Docker这款优秀的软件完全毁于糟糕的经营方法,导致Docker公司在2018年寿终正寝。本文从局外人的视角回顾了Docker怎么出岔子,哪里出了岔子,以及为何说Docker现在试图解决问题为时太晚。

Docker是优秀软件

有一点很清楚,Docker帮助彻底改变了软件开发领域。拿来cgroups、命名空间和进程隔离等Linux基本元素,把它们做入到一个工具中,这本身就很了不起。2012年,我试图弄清楚开发环境如何可以更易于移植。 Docker的崛起使开发环境得以成为一个简单的、可版本控制的Dockerfile。工具形形色色,从Packer、Vagrant、VirtualBox和众多基础设施,到Docker,不一而足。Docker UI实际上也相当不错!这是一款用途广泛的优秀工具。Docker团队的成员应该为他们开发的工具感到自豪。

Docker是硅谷的宠儿

Docker早期的成功促使该公司围绕其产品建立起了一个庞大社区。而早期的这种成功让它融到了一轮又一轮的资金。像高盛、Greylock Partners、红杉资本和Insight Venture Partners这些大名鼎鼎的投资者竞相为Docker提供大把大把的资金。到目前为止,Docker筹集到的投资总额在2.42亿美元至逾2.5亿美元之间。

但是与2010年代大多数资金充裕、不计代价以求成功的初创公司一样,Docker也犯了人力资源方面的几个失误。Docker在崛起过程中竭力保护一些很蹩脚的货色。这导致我个人不喜欢这家公司的领导层。产品仍然是一流的,但这根本无法因此原谅该公司的行为。遗憾的是,硅谷的许多宠儿都是这样,这种情况需要有所改变。

Kubernetes对Docker造成了损害

Kubernetes的崛起更是加快了Docker的消亡。 Docker在处理Kubernetes方面并没有为它自己带来任何好处,而Kubernetes是开源社区青睐的容器编排工具。Docker的竞争产品Docker Swarm是Docker的头脑中唯一记挂的容器编排工具。尽管Kubernetes起初偏爱Docker容器,Docker还是做出了这个决定。这里捎带提一下,Docker Captains在2017年初证实,当初Docker对文章、聚会和会议上屡屡提到的Kubernetes根本就不感冒。

直到奥斯汀召开的dockercon17大会,Docker依然奉行无视Kubernetes的这种做法。然后在dockercon EU 17大会上,Docker几乎突然决定全身心地支持Kubernetes。这个突然的变化说明Docker显然承认了Kubernetes的强势崛起、即将成为市场的霸主。Docker成为KubeCon + CloudNativeCo北美2017年大会的赞助商,并且设有展台,更是彰显了这个事实。

Moby?

没有人了解Docker去年4月份在dockercon17上宣布Moby时做了什么。Moby被称为是Docker项目的新上游,但是没有提前宣布Moby的发布。所罗门•海克斯(Solomon Hykes)在dockercon17大会上发言时,GitHub上出现了一下子由Docker向Moby大转变这一幕,无数的人害怕地惊叫起来。这种突如其来、考虑欠周的变化需要 GitHub的工作人员直接干预。

不仅没有处理好这个变化,Docker所要传达的讯息也没有深思熟虑。这导致该公司对这一变化表示道歉,高层亲自出面解释。这让原本乱象丛生的容器领域和Docker(或者Moby?)生态系统更让人摸不着头脑了。处理Moby的发布继续困扰着那些从业人员。 Docker品牌可能因此受到了损害。

对Kubernetes态度冷淡

Docker在最后的时刻尴尬地拥抱Kubernetes是表明它即将崩溃的迹象。被问及Docker Swarm是否已经死亡时,所罗门•海克斯曾经发推文道:“Docker将继续支持Kubernetes和Swarm作为一等公民,并且鼓励交流和分享。开放性和灵活选择为每个人创造了一个更健康的生态系统。”这里的问题是,Docker Swarm并没有完全成熟,实际上离完全成熟相差甚远。Docker Swarm产品团队及其少数开源贡献者将跟不上Kubernetes社区的步伐。尽管Docker UI很优秀,但Kubernetes UI却出色得多。就好像Docker现在承认自己是容器领域的一家边缘化的咨询公司。

结束语

Docker的真正问题是缺乏连贯一致的领导团队。战略重心似乎就围绕这家公司的某一个人。这个人已经被越来越远离公司的核心,但他依然当权。公司已经过了重组,把重心转移到企业客户。这种转变对于Docker的投资者来说颇为明智(毕竟公司确实背负信托责任)。但是,这种转变会削弱该品牌的酷炫因素,而酷炫因素当初促使其大获成功。常言道:“伟大的文明不是被谋杀的,而是自杀的。”Docker就是这样一个活生生的例子。

阴谋论

针对Docker在2017年的尴尬时期,我在Twitter上倒是提出了一个观点。Docker可能知道公司本身已是穷途末路。由于组织变化表明即将退出(可能通过收购),该公司的技术核心优先考虑一些变化。将containerd捐赠给云原生计算基金会(CNCF),让Moby成为Docker的上游,并且拥抱Kubernetes,这些举措将使Docker的人员所做的好事被永载史册。这让像Oracle或微软这样的大企业得以过来收购这家公司,不必担心Docker的员工取得的技术进步被许可证牢牢束缚。这为软件团队和公司本身提供了两全其美的方法。不用说,2018年对于Docker来说将是值得关注的一年。

Kubernetes 1.9GA 版本最新发布 | 更新日志

中文社区阅读(4883)评论(0)

2017年12月15日,kubernetes1.9版本发布。Kubernetes依然按照每三个月一个大版本发布的速度稳定迭代,这是今年发布的第四个版本,也是今年的最后一个版本,该版本最大的改进是Apps Workloads API成为稳定版本,这消除了很多潜在用户对于该功能稳定性的担忧。还有一个重大更新,就是测试支持了Windows了,这打开了在kubernetes中运行Windows工作负载的大门。

Workloads API GA

apps/v1 Workloads API成为GA(General Availability),且默认启用。 Apps Workloads API将DaemonSetDeploymentReplicaSetStatefulSet API组合在一起,作为Kubernetes中长时间运行的无状态和有状态工作负载的基础。

Deployment和ReplicaSet是Kubernetes中最常用的两个对象,经过一年多的实际使用和反馈后,现在已经趋于稳定。SIG apps同时将这些经验应用到另外的两个对象上,使得DaemonSet和StatefulSet也能顺利毕业走向成熟。v1(GA)意味着已经生产可用,并保证长期的向后兼容。

Windows支持(beta)

Kubernetes最初是为Linux系统开发的,但是用户逐渐意识到容器编排的好处,我们看到有人需要在Kubernetes上运行Windows工作负载。在12个月前,我们开始认真考虑在Kubernetes上支持Windows Server的工作。 SIG-Windows现在已经将这个功能推广到beta版本,这意味着我们可以评估它的使用情况

增强存储

kubernetes从第一个版本开始就支持多种持久化数据存储,包括常用的NFS或iSCSI,以及对主要公共云和私有云提供商的存储解决方案的原生支持。随着项目和生态系统的发展,Kubernetes的存储选择越来越多。然而,为新的存储系统添加volume插件一直是一个挑战。

容器存储接口(CSI)是一个跨行业标准计划,旨在降低云原生存储开发的障碍并确保兼容性。 SIG-StorageCSI社区正在合作提供一个单一接口,用于配置、附着和挂载与Kubernetes兼容的存储。

Kubernetes 1.9引入了容器存储接口(CSI)的alpha实现,这将使挂载新的volume插件就像部署一个pod一样简单,并且第三方存储提供商在开发他们的解决方案时也无需修改kubernetes的核心代码。

由于该功能在1.9版本中为alpha,因此必须明确启用该功能,不建议用于生产使用,但它为更具扩展性和基于标准的Kubernetes存储生态系统提供了清晰的路线图。

其它功能

自定义资源定义(CRD)校验,现在已经成为beta,默认情况下已启用,可以用来帮助CRD作者对于无效对象定义给出清晰和即时的反馈。

SIG Node硬件加速器转向alpha,启用GPU,从而实现机器学习和其他高性能工作负载。

CoreDNS alpha可以使用标准工具来安装CoreDNS。

kube-proxy的IPVS模式进入beta版,为大型集群提供更好的可扩展性和性能。

社区中的每个特别兴趣小组(SIG)继续提供其所在领域的用户最迫切需要的功能。有关完整列表,请访问发行说明

获取

Kubernetes1.9已经可以通过GitHub下载

参考

Kubernetes 1.9: Apps Workloads GA and Expanded Ecosystem