fix broken links
parent
d6f088726e
commit
78ca17b2d4
|
@ -42,7 +42,7 @@ Kubernetes 的架构做的足够开放,通过系列的接口,如 CRI(Conta
|
|||
|
||||
- 2017 年 6 月 19 日 - 20 日,北京,[L3 大会](https://www.bagevent.com/event/561769)(LinuxCon+ContainerCon+CloudOpen China)。CNCF(Cloud Native Computing Foundation)作为云原生应用的联合推广团体,也是由 Google 一手培植起来的强大 “市场媒体”(Kubernetes 是第一个入选该基金会的项目),第一次进入中国,华为、Google、Rancher、红帽等公司分别做了关于 Kubernetes 及 Cloud Native 的演讲。
|
||||
- 2017 年 7 月 25 日,北京、上海,[k8smeetup](http://www.k8smeetup.com/),Kubernetes 二周年北京 - 上海 Meetup 双城庆生。
|
||||
- 2017 年 9 月 12 日,北京,[T11 大会](https://www.talkingdata.com/activity/T11-2017/index.html),前 Pivotal 技术专家,现 CapitalOne 高级专家 Kevin Hoffman 做了 [High Level Cloud Native Concepts](https://jimmysong.io/posts/high-level-cloud-native-from-kevin-hoffman/) 的演讲。
|
||||
- 2017 年 9 月 12 日,北京,T11 大会,前 Pivotal 技术专家,现 CapitalOne 高级专家 Kevin Hoffman 做了 [High Level Cloud Native Concepts](https://jimmysong.io/posts/high-level-cloud-native-from-kevin-hoffman/) 的演讲。
|
||||
- 2017 年 10 月 15 日,杭州,[KEUC 2017- Kubernetes 中国用户大会](https://www.bagevent.com/event/827437)。由才云科技(Caicloud)、美国 The Linux Foundation 基金会旗下 Cloud Native Computing Foundation (CNCF)、「K8sMeetup 中国社区」联合主办的聚焦 Kubernetes 中国行业应用与技术落地的盛会。
|
||||
- 2017 年 12 月 13 日 - 15 日,杭州,[云原生技术大会 ——CNTC](https://www.huodongjia.com/event-5854212.html)。这次会议由谐云科技与网易云共同主办,主要探讨云原生技术与应用,同时还进行了云原生集训。
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# Kubernetes与云原生应用概览
|
||||
# Kubernetes 与云原生应用概览
|
||||
|
||||
2017年9月,Mesos宣布支持Kubernetes,而在2017年10月份的DockerCon EU上,Docker公司宣布官方同时支持Swarm和Kubernetes容器编排,Kubernetes已然成为容器编排调度的标准。
|
||||
2017 年 9 月,Mesos 宣布支持 Kubernetes,而在 2017 年 10 月份的 DockerCon EU 上,Docker 公司宣布官方同时支持 Swarm 和 Kubernetes 容器编排,Kubernetes 已然成为容器编排调度的标准。
|
||||
|
||||
作为全书的开头,首先从历史、生态和应用角度介绍一下Kubernetes与云原生应用,深入浅出,高屋建瓴,没有深入到具体细节,主要是为了给初次接触Kubernetes的小白扫盲,具体细节请参考链接。
|
||||
作为全书的开头,首先从历史、生态和应用角度介绍一下 Kubernetes 与云原生应用,深入浅出,高屋建瓴,没有深入到具体细节,主要是为了给初次接触 Kubernetes 的小白扫盲,具体细节请参考链接。
|
||||
|
||||
## 从云计算到微服务再到云原生计算
|
||||
|
||||
|
@ -10,31 +10,31 @@
|
|||
|
||||
![云计算演进历程](../images/cloud-computing-evolution-road.jpg)
|
||||
|
||||
云原生应用到2020年将比目前至少翻一番,下图是Marc Wilczek的调查报告。
|
||||
云原生应用到 2020 年将比目前至少翻一番,下图是 Marc Wilczek 的调查报告。
|
||||
|
||||
![来自Twitter @MarcWilczek](../images/cloud-native-comes-of-age.jpg)
|
||||
![来自 Twitter @MarcWilczek](../images/cloud-native-comes-of-age.jpg)
|
||||
|
||||
### 云计算介绍
|
||||
|
||||
云计算包含的内容十分繁杂,也有很多技术和公司牵强附会说自己是云计算公司,说自己是做云的,实际上可能风马牛不相及。说白了,云计算就是一种配置资源的方式,根据资源配置方式的不同我们可以把云计算从宏观上分为以下三种类型:
|
||||
|
||||
* IaaS:这是为了想要建立自己的商业模式并进行自定义的客户,例如亚马逊的EC2、S3存储、Rackspace虚拟机等都是IaaS。
|
||||
* PaaS:工具和服务的集合,对于想用它来构建自己的应用程序或者想快速得将应用程序部署到生产环境而不必关心底层硬件的用户和开发者来说是特别有用的,比如Cloud Foundry、Google App Engine、Heroku等。
|
||||
* SaaS:终端用户可以直接使用的应用程序。这个就太多,我们生活中用到的很多软件都是SaaS服务,只要基于互联网来提供的服务基本都是SaaS服务,有的服务是免费的,比如Google Docs,还有更多的是根据我们购买的Plan和使用量付费,比如GitHub、各种云存储。
|
||||
* IaaS:这是为了想要建立自己的商业模式并进行自定义的客户,例如亚马逊的 EC2、S3 存储、Rackspace 虚拟机等都是 IaaS。
|
||||
* PaaS:工具和服务的集合,对于想用它来构建自己的应用程序或者想快速得将应用程序部署到生产环境而不必关心底层硬件的用户和开发者来说是特别有用的,比如 Cloud Foundry、Google App Engine、Heroku 等。
|
||||
* SaaS:终端用户可以直接使用的应用程序。这个就太多,我们生活中用到的很多软件都是 SaaS 服务,只要基于互联网来提供的服务基本都是 SaaS 服务,有的服务是免费的,比如 Google Docs,还有更多的是根据我们购买的 Plan 和使用量付费,比如 GitHub、各种云存储。
|
||||
|
||||
### 微服务介绍
|
||||
|
||||
微服务(Microservices)这个词比较新颖,但是其实这种架构设计理念早就有了。微服务是一种分布式架构设计理念,为了推动细粒度服务的使用,这些服务要能协同工作,每个服务都有自己的生命周期。一个微服务就是一个独立的实体,可以独立的部署在PAAS平台上,也可以作为一个独立的进程在主机中运行。服务之间通过API访问,修改一个服务不会影响其它服务。
|
||||
微服务(Microservices)这个词比较新颖,但是其实这种架构设计理念早就有了。微服务是一种分布式架构设计理念,为了推动细粒度服务的使用,这些服务要能协同工作,每个服务都有自己的生命周期。一个微服务就是一个独立的实体,可以独立的部署在 PAAS 平台上,也可以作为一个独立的进程在主机中运行。服务之间通过 API 访问,修改一个服务不会影响其它服务。
|
||||
|
||||
要想了解微服务的详细内容推荐阅读《微服务设计》(Sam Newman著),我写过这本书的读书笔记 - [微服务设计读书笔记](https://jimmysong.io/posts/microservice-reading-notes/)。
|
||||
要想了解微服务的详细内容推荐阅读《微服务设计》(Sam Newman 著),我写过这本书的读书笔记 - [微服务设计读书笔记](https://jimmysong.io/posts/microservice-reading-notes/)。
|
||||
|
||||
下文中会谈到Kubernetes与微服务的关系,其中Kubernetes的service天生就适合于微服务。
|
||||
下文中会谈到 Kubernetes 与微服务的关系,其中 Kubernetes 的 service 天生就适合于微服务。
|
||||
|
||||
### 云原生概念介绍
|
||||
|
||||
下面是Cloud Native概念思维导图
|
||||
下面是云原生概念思维导图
|
||||
|
||||
![Cloud native思维导图](../images/cloud-native-architecutre-mindnode.jpg)
|
||||
![云原生思维导图](../images/cloud-native-architecutre-mindnode.jpg)
|
||||
|
||||
云原生准确来说是一种文化,更是一种潮流,它是云计算的一个必然导向。它的意义在于让云成为云化战略成功的基石,而不是阻碍,如果业务应用上云之后开发和运维人员比原先还痛苦,成本还高的话,这样的云我们宁愿不上。
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
|||
|
||||
为了解决传统应用升级缓慢、架构臃肿、不能快速迭代、故障不能快速定位、问题无法快速解决等问题,云原生这一概念横空出世。云原生可以改进应用开发的效率,改变企业的组织结构,甚至会在文化层面上直接影响一个公司的决策。
|
||||
|
||||
另外,云原生也很好地解释了云上运行的应用应该具备什么样的架构特性——敏捷性、可扩展性、故障可恢复性。
|
||||
另外,云原生也很好地解释了云上运行的应用应该具备什么样的架构特性 —— 敏捷性、可扩展性、故障可恢复性。
|
||||
|
||||
综上所述,云原生应用应该具备以下几个关键词:
|
||||
|
||||
|
@ -57,82 +57,82 @@
|
|||
|
||||
从宏观概念上讲,云原生是不同思想的集合,集目前各种热门技术之大成,具体包括如下图所示的几个部分。
|
||||
|
||||
## Kubernetes与云原生的关系
|
||||
## Kubernetes 与云原生的关系
|
||||
|
||||
Kuberentes可以说是乘着Docker和微服务的东风,一经推出便迅速蹿红,它的很多设计思想都契合了微服务和云原生应用的设计法则,这其中最著名的就是开发了[Heroku](https://www.heroku.com) PaaS平台的工程师们总结的 [Twelve-factor App](https://12factor.net/)了。
|
||||
Kuberentes 可以说是乘着 Docker 和微服务的东风,一经推出便迅速蹿红,它的很多设计思想都契合了微服务和云原生应用的设计法则,这其中最著名的就是开发了 [Heroku](https://www.heroku.com) PaaS 平台的工程师们总结的 [Twelve-factor App](https://12factor.net/) 了。
|
||||
|
||||
下面我将讲解Kubernetes设计时是如何按照了十二因素应用法则,并给出Kubernetes中的应用示例,并附上一句话简短的介绍。
|
||||
下面我将讲解 Kubernetes 设计时是如何按照了十二因素应用法则,并给出 Kubernetes 中的应用示例,并附上一句话简短的介绍。
|
||||
|
||||
### Kubernetes介绍
|
||||
### Kubernetes 介绍
|
||||
|
||||
[Kubernetes](http://kubernetes.io)是Google基于[Borg](https://research.google.com/pubs/pub43438.html)开源的容器编排调度引擎,作为[CNCF](http://cncf.io)(Cloud Native Computing Foundation)最重要的组件之一,它的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,定义服务的最终状态,Kubernetes可以帮你将系统自动得达到和维持在这个状态。
|
||||
[Kubernetes](http://kubernetes.io) 是 Google 基于 [Borg](https://research.google.com/pubs/pub43438.html) 开源的容器编排调度引擎,作为 [CNCF](http://cncf.io)(Cloud Native Computing Foundation)最重要的组件之一,它的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,定义服务的最终状态,Kubernetes 可以帮你将系统自动得达到和维持在这个状态。
|
||||
|
||||
更直白的说,Kubernetes用户可以通过编写一个yaml或者json格式的配置文件,也可以通过工具/代码生成或直接请求Kubernetes API创建应用,该配置文件中包含了用户想要应用程序保持的状态,不论整个Kubernetes集群中的个别主机发生什么问题,都不会影响应用程序的状态,你还可以通过改变该配置文件或请求Kubernetes API来改变应用程序的状态。
|
||||
更直白的说,Kubernetes 用户可以通过编写一个 YAML 或者 json 格式的配置文件,也可以通过工具 / 代码生成或直接请求 Kubernetes API 创建应用,该配置文件中包含了用户想要应用程序保持的状态,不论整个 Kubernetes 集群中的个别主机发生什么问题,都不会影响应用程序的状态,你还可以通过改变该配置文件或请求 Kubernetes API 来改变应用程序的状态。
|
||||
|
||||
### 12因素应用
|
||||
### 12 因素应用
|
||||
|
||||
12因素应用提出已经有几年的时间了,每个人对其可能都有自己的理解,切不可生搬硬套,也不一定所有云原生应用都必须符合这12条法则,其中有几条法则可能还有点争议,有人对其的解释和看法不同。
|
||||
12 因素应用提出已经有几年的时间了,每个人对其可能都有自己的理解,切不可生搬硬套,也不一定所有云原生应用都必须符合这 12 条法则,其中有几条法则可能还有点争议,有人对其的解释和看法不同。
|
||||
|
||||
大家不要孤立的来看这每一个因素,将其与自己软件开发流程联系起来,这12个因素大致就是按照软件从开发到交付的流程顺序来写的。
|
||||
大家不要孤立的来看这每一个因素,将其与自己软件开发流程联系起来,这 12 个因素大致就是按照软件从开发到交付的流程顺序来写的。
|
||||
|
||||
![十二因素应用](../images/12-factor-app.png)
|
||||
|
||||
**1.基准代码**
|
||||
**1. 基准代码 **
|
||||
|
||||
每个代码仓库(repo)都生成docker image保存到镜像仓库中,并使用唯一的ID管理,在Jenkins中使用编译时的ID。
|
||||
每个代码仓库(repo)都生成 docker image 保存到镜像仓库中,并使用唯一的 ID 管理,在 Jenkins 中使用编译时的 ID。
|
||||
|
||||
**2.依赖**
|
||||
**2. 依赖 **
|
||||
|
||||
显式的声明代码中的依赖,使用软件包管理工具声明,比如Go中的Glide。
|
||||
显式的声明代码中的依赖,使用软件包管理工具声明,比如 Go 中的 Glide。
|
||||
|
||||
**3.配置**
|
||||
**3. 配置 **
|
||||
|
||||
将配置与代码分离,应用部署到Kubernetes中可以使用容器的环境变量或ConfigMap挂载到容器中。
|
||||
将配置与代码分离,应用部署到 Kubernetes 中可以使用容器的环境变量或 ConfigMap 挂载到容器中。
|
||||
|
||||
**4.后端服务**
|
||||
**4. 后端服务 **
|
||||
|
||||
把后端服务当作附加资源,实质上是计算存储分离和降低服务耦合,分解单体应用。
|
||||
|
||||
**5.构建、发布、运行**
|
||||
**5. 构建、发布、运行 **
|
||||
|
||||
严格分离构建和运行,每次修改代码生成新的镜像,重新发布,不能直接修改运行时的代码和配置。
|
||||
|
||||
**6.进程**
|
||||
**6. 进程 **
|
||||
|
||||
应用程序进程应该是无状态的,这意味着再次重启后还可以计算出原先的状态。
|
||||
|
||||
**7.端口绑定**
|
||||
**7. 端口绑定 **
|
||||
|
||||
在Kubernetes中每个Pod都有独立的IP,每个运行在Pod中的应用不必关心端口是否重复,只需在service中指定端口,集群内的service通过配置互相发现。
|
||||
在 Kubernetes 中每个 Pod 都有独立的 IP,每个运行在 Pod 中的应用不必关心端口是否重复,只需在 service 中指定端口,集群内的 service 通过配置互相发现。
|
||||
|
||||
**8.并发**
|
||||
**8. 并发 **
|
||||
|
||||
每个容器都是一个进程,通过增加容器的副本数实现并发。
|
||||
|
||||
**9.易处理**
|
||||
**9. 易处理 **
|
||||
|
||||
快速启动和优雅终止可最大化健壮性,Kuberentes优秀的[Pod生存周期控制](https://jimmysong.io/posts/pod-lifecycle/)。
|
||||
快速启动和优雅终止可最大化健壮性,Kuberentes 优秀的 [Pod 生存周期控制](https://jimmysong.io/posts/pod-lifecycle/)。
|
||||
|
||||
**10.开发环境与线上环境等价**
|
||||
**10. 开发环境与线上环境等价 **
|
||||
|
||||
在Kubernetes中可以创建多个namespace,使用相同的镜像可以很方便的复制一套环境出来,镜像的使用可以很方便的部署一个后端服务。
|
||||
在 Kubernetes 中可以创建多个 namespace,使用相同的镜像可以很方便的复制一套环境出来,镜像的使用可以很方便的部署一个后端服务。
|
||||
|
||||
**11.日志**
|
||||
**11. 日志 **
|
||||
|
||||
把日志当作事件流,使用stdout输出并收集汇聚起来,例如到ES中统一查看。
|
||||
把日志当作事件流,使用 stdout 输出并收集汇聚起来,例如到 ES 中统一查看。
|
||||
|
||||
**12.管理进程**
|
||||
**12. 管理进程 **
|
||||
|
||||
后台管理任务当作一次性进程运行,`kubectl exec`进入容器内部操作。
|
||||
后台管理任务当作一次性进程运行,`kubectl exec` 进入容器内部操作。
|
||||
|
||||
另外,[Cloud Native Go](https://jimmysong.io/cloud-native-go) 这本书的作者,CapitalOne公司的Kevin Hoffman在TalkingData T11峰会上的[High Level Cloud Native](https://jimmysong.io/posts/high-level-cloud-native-from-kevin-hoffman/)的演讲中讲述了云原生应用的15个因素,在原先的12因素应用的基础上又增加了如下三个因素:
|
||||
另外,[Cloud Native Go](https://jimmysong.io/cloud-native-go) 这本书的作者,CapitalOne 公司的 Kevin Hoffman 在 TalkingData T11 峰会上的 [High Level Cloud Native](https://jimmysong.io/blog/high-level-cloud-native-from-kevin-hoffman/) 的演讲中讲述了云原生应用的 15 个因素,在原先的 12 因素应用的基础上又增加了如下三个因素:
|
||||
|
||||
**API优先**
|
||||
**API 优先 **
|
||||
|
||||
* 服务间的合约
|
||||
* 团队协作的规约
|
||||
* 文档化、规范化
|
||||
* RESTful或RPC
|
||||
* RESTful 或 RPC
|
||||
|
||||
**监控**
|
||||
|
||||
|
@ -140,30 +140,28 @@ Kuberentes可以说是乘着Docker和微服务的东风,一经推出便迅速
|
|||
* 应用性能监控(APM)
|
||||
* 应用健康监控
|
||||
* 系统日志
|
||||
* 不建议在线Debug
|
||||
* 不建议在线 Debug
|
||||
|
||||
**认证授权**
|
||||
|
||||
* 不要等最后才去考虑应用的安全性
|
||||
* 详细设计、明确声明、文档化
|
||||
* Bearer token、OAuth、OIDC认证
|
||||
* Bearer token、OAuth、OIDC 认证
|
||||
* 操作审计
|
||||
|
||||
详见[High Level Cloud Native From Kevin Hoffman](https://jimmysong.io/posts/high-level-cloud-native-from-kevin-hoffman/)。
|
||||
## Kubernetes 中的资源管理与容器设计模式
|
||||
|
||||
## Kubernetes中的资源管理与容器设计模式
|
||||
|
||||
Kubernetes通过声明式配置,真正让开发人员能够理解应用的状态,并通过同一份配置可以立马启动一个一模一样的环境,大大提高了应用开发和部署的效率,其中Kubernetes设计的多种资源类型可以帮助我们定义应用的运行状态,并使用资源配置来细粒度的明确限制应用的资源使用。
|
||||
Kubernetes 通过声明式配置,真正让开发人员能够理解应用的状态,并通过同一份配置可以立马启动一个一模一样的环境,大大提高了应用开发和部署的效率,其中 Kubernetes 设计的多种资源类型可以帮助我们定义应用的运行状态,并使用资源配置来细粒度的明确限制应用的资源使用。
|
||||
|
||||
而容器生态的成熟是 Kubernetes 诞生的前提,在谈到容器的设计模式之前我们先来了解下容器生态,请看下图:
|
||||
|
||||
![容器生态](../images/container-ecosystem.png)
|
||||
|
||||
关于 Docker 容器的更多内容请参考 [Docker最佳实践](../appendix/docker-best-practice.md)。
|
||||
关于 Docker 容器的更多内容请参考 [Docker 最佳实践](../appendix/docker-best-practice.md)。
|
||||
|
||||
### 容器的设计模式
|
||||
|
||||
Kubernetes提供了多种资源对象,用户可以根据自己应用的特性加以选择。这些对象有:
|
||||
Kubernetes 提供了多种资源对象,用户可以根据自己应用的特性加以选择。这些对象有:
|
||||
|
||||
| 类别 | 名称 |
|
||||
| :--- | --- |
|
||||
|
@ -178,129 +176,129 @@ Kubernetes提供了多种资源对象,用户可以根据自己应用的特性
|
|||
* 可以被应用使用的资源
|
||||
* 关于应用如何表现的策略,比如重启策略、升级策略,以及容错策略
|
||||
|
||||
Kubernetes 对象是 “目标性记录” —— 一旦创建对象,Kubernetes 系统将持续工作以确保对象存在。通过创建对象,可以有效地告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样子的,这就是 Kubernetes 集群的 **期望状态**。
|
||||
Kubernetes 对象是 “目标性记录” —— 一旦创建对象,Kubernetes 系统将持续工作以确保对象存在。通过创建对象,可以有效地告知 Kubernetes 系统,所需要的集群工作负载看起来是什么样子的,这就是 Kubernetes 集群的 ** 期望状态 **。
|
||||
|
||||
详见[Kubernetes Handbook - Objects](https://jimmysong.io/kubernetes-handbook/concepts/objects.html)。
|
||||
详见 [Kubernetes Handbook - Objects](https://jimmysong.io/kubernetes-handbook/concepts/objects.html)。
|
||||
|
||||
### 资源限制与配额
|
||||
|
||||
两层的资源限制与配置
|
||||
|
||||
* Pod级别,最小的资源调度单位
|
||||
* Namespace级别,限制资源配额和每个Pod的资源使用区间
|
||||
* Pod 级别,最小的资源调度单位
|
||||
* Namespace 级别,限制资源配额和每个 Pod 的资源使用区间
|
||||
|
||||
请参考[Kubernetes中的ResourceQuota和LimitRange配置资源限额](https://jimmysong.io/posts/kubernetes-resourcequota-limitrange-management/)
|
||||
请参考 [Kubernetes 中的 ResourceQuota 和 LimitRange 配置资源限额](https://jimmysong.io/posts/kubernetes-resourcequota-limitrange-management/)
|
||||
|
||||
## 管理Kubernetes集群
|
||||
## 管理 Kubernetes 集群
|
||||
|
||||
手工部署Kubernetes是一个很艰巨的活,你需要了解网络配置、Docker的安装与使用、镜像仓库的构建、角色证书的创建、Kubernetes的基本原理和构成、Kubernetes应用程序的yaml文件编写等。
|
||||
手工部署 Kubernetes 是一个很艰巨的活,你需要了解网络配置、Docker 的安装与使用、镜像仓库的构建、角色证书的创建、Kubernetes 的基本原理和构成、Kubernetes 应用程序的 yaml 文件编写等。
|
||||
|
||||
我编写了一本[kubernetes-handbook](https://jimmysong.io/kubernetes-handbook/)可供大家免费阅读,该书记录了本人从零开始学习和使用Kubernetes的心路历程,着重于经验分享和总结,同时也会有相关的概念解析,希望能够帮助大家少踩坑,少走弯路。
|
||||
我编写了一本 [kubernetes-handbook](https://jimmysong.io/kubernetes-handbook/) 可供大家免费阅读,该书记录了本人从零开始学习和使用 Kubernetes 的心路历程,着重于经验分享和总结,同时也会有相关的概念解析,希望能够帮助大家少踩坑,少走弯路。
|
||||
|
||||
### 部署Kubernetes集群
|
||||
### 部署 Kubernetes 集群
|
||||
|
||||
使用二进制部署 `kubernetes` 集群的所有组件和插件,而不是使用 `kubeadm` 等自动化方式来部署集群,同时开启了集群的TLS安全认证,这样可以帮助我们了解系统各组件的交互原理,进而能快速解决实际问题。详见[在CentOS上部署Kubernetes集群](../practice/install-kubernetes-on-centos.md)。
|
||||
使用二进制部署 `kubernetes` 集群的所有组件和插件,而不是使用 `kubeadm` 等自动化方式来部署集群,同时开启了集群的 TLS 安全认证,这样可以帮助我们了解系统各组件的交互原理,进而能快速解决实际问题。详见 [在 CentOS 上部署 Kubernetes 集群](../practice/install-kubernetes-on-centos.md)。
|
||||
|
||||
**集群详情**
|
||||
|
||||
* Kubernetes 1.6.0
|
||||
* Docker 1.12.5(使用yum安装)
|
||||
* Docker 1.12.5(使用 yum 安装)
|
||||
* Etcd 3.1.5
|
||||
* Flanneld 0.7 vxlan 网络
|
||||
* TLS 认证通信 \(所有组件,如 etcd、kubernetes master 和 node\)
|
||||
* RBAC 授权
|
||||
* kubelet TLS BootStrapping
|
||||
* kubedns、dashboard、heapster\(influxdb、grafana\)、EFK\(elasticsearch、fluentd、kibana\) 集群插件
|
||||
* 私有Docker镜像仓库[Harbor](https://github.com/goharbor/harbor)(请自行部署,Harbor提供离线安装包,直接使用docker-compose启动即可)
|
||||
* 私有 Docker 镜像仓库 [Harbor](https://github.com/goharbor/harbor)(请自行部署,Harbor 提供离线安装包,直接使用 docker-compose 启动即可)
|
||||
|
||||
**步骤介绍**
|
||||
|
||||
1. [创建 TLS 证书和秘钥](../practice/create-tls-and-secret-key.md)
|
||||
2. [创建kubeconfig文件](../practice/create-kubeconfig.md)
|
||||
3. [创建高可用etcd集群](../practice/etcd-cluster-installation.md)
|
||||
4. [安装kubectl命令行工具](../practice/kubectl-installation.md)
|
||||
5. [部署master节点](../practice/master-installation.md)
|
||||
6. [安装flannel网络插件](../practice/flannel-installation.md)
|
||||
7. [部署node节点](../practice/node-installation.md)
|
||||
8. [安装kubedns插件](../practice/kubedns-addon-installation.md)
|
||||
9. [安装dashboard插件](../practice/dashboard-addon-installation.md)
|
||||
10. [安装heapster插件](../practice/heapster-addon-installation.md)
|
||||
11. [安装EFK插件](../practice/efk-addon-installation.md)
|
||||
2. [创建 kubeconfig 文件](../practice/create-kubeconfig.md)
|
||||
3. [创建高可用 etcd 集群](../practice/etcd-cluster-installation.md)
|
||||
4. [安装 kubectl 命令行工具](../practice/kubectl-installation.md)
|
||||
5. [部署 master 节点](../practice/master-installation.md)
|
||||
6. [安装 flannel 网络插件](../practice/flannel-installation.md)
|
||||
7. [部署 node 节点](../practice/node-installation.md)
|
||||
8. [安装 kubedns 插件](../practice/kubedns-addon-installation.md)
|
||||
9. [安装 dashboard 插件](../practice/dashboard-addon-installation.md)
|
||||
10. [安装 heapster 插件](../practice/heapster-addon-installation.md)
|
||||
11. [安装 EFK 插件](../practice/efk-addon-installation.md)
|
||||
|
||||
### 服务发现与负载均衡
|
||||
|
||||
Kubernetes在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了Service资源,并通过kube-proxy配合cloud provider来适应不同的应用场景。随着Kubernetes用户的激增,用户场景的不断丰富,又产生了一些新的负载均衡机制。目前,Kubernetes中的负载均衡大致可以分为以下几种机制,每种机制都有其特定的应用场景:
|
||||
Kubernetes 在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了 Service 资源,并通过 kube-proxy 配合 cloud provider 来适应不同的应用场景。随着 Kubernetes 用户的激增,用户场景的不断丰富,又产生了一些新的负载均衡机制。目前,Kubernetes 中的负载均衡大致可以分为以下几种机制,每种机制都有其特定的应用场景:
|
||||
|
||||
* **Service**:直接用Service提供cluster内部的负载均衡,并借助cloud provider提供的LB提供外部访问
|
||||
* **Ingress**:还是用Service提供cluster内部的负载均衡,但是通过自定义LB提供外部访问
|
||||
* **Service Load Balancer**:把load balancer直接跑在容器中,实现Bare Metal的Service Load Balancer
|
||||
* **Custom Load Balancer**:自定义负载均衡,并替代kube-proxy,一般在物理部署Kubernetes时使用,方便接入公司已有的外部服务
|
||||
* **Service**:直接用 Service 提供 cluster 内部的负载均衡,并借助 cloud provider 提供的 LB 提供外部访问
|
||||
* **Ingress**:还是用 Service 提供 cluster 内部的负载均衡,但是通过自定义 LB 提供外部访问
|
||||
* **Service Load Balancer**:把 load balancer 直接跑在容器中,实现 Bare Metal 的 Service Load Balancer
|
||||
* **Custom Load Balancer**:自定义负载均衡,并替代 kube-proxy,一般在物理部署 Kubernetes 时使用,方便接入公司已有的外部服务
|
||||
|
||||
详见[Kubernetes Handbook - 服务发现与负载均衡](https://jimmysong.io/kubernetes-handbook/practice/service-discovery-and-loadbalancing.html)。
|
||||
详见 [Kubernetes Handbook - 服务发现与负载均衡](https://jimmysong.io/kubernetes-handbook/practice/service-discovery-and-loadbalancing.html)。
|
||||
|
||||
### 持续集成与发布
|
||||
|
||||
![使用Jenkins进行持续集成与发布流程图](../images/kubernetes-jenkins-ci-cd.png)
|
||||
![使用 Jenkins 进行持续集成与发布流程图](../images/kubernetes-jenkins-ci-cd.png)
|
||||
|
||||
应用构建和发布流程说明:
|
||||
|
||||
1. 用户向Gitlab提交代码,代码中必须包含`Dockerfile`
|
||||
1. 用户向 Gitlab 提交代码,代码中必须包含 `Dockerfile`
|
||||
2. 将代码提交到远程仓库
|
||||
3. 用户在发布应用时需要填写git仓库地址和分支、服务类型、服务名称、资源数量、实例个数,确定后触发Jenkins自动构建
|
||||
4. Jenkins的CI流水线自动编译代码并打包成Docker镜像推送到Harbor镜像仓库
|
||||
5. Jenkins的CI流水线中包括了自定义脚本,根据我们已准备好的Kubernetes的YAML模板,将其中的变量替换成用户输入的选项
|
||||
6. 生成应用的Kubernetes YAML配置文件
|
||||
7. 更新Ingress的配置,根据新部署的应用的名称,在Ingress的配置文件中增加一条路由信息
|
||||
8. 更新PowerDNS,向其中插入一条DNS记录,IP地址是边缘节点的IP地址。关于边缘节点,请查看[边缘节点配置](https://jimmysong.io/kubernetes-handbook/practice/edge-node-configuration.html)
|
||||
9. Jenkins调用Kubernetes的API,部署应用
|
||||
3. 用户在发布应用时需要填写 git 仓库地址和分支、服务类型、服务名称、资源数量、实例个数,确定后触发 Jenkins 自动构建
|
||||
4. Jenkins 的 CI 流水线自动编译代码并打包成 Docker 镜像推送到 Harbor 镜像仓库
|
||||
5. Jenkins 的 CI 流水线中包括了自定义脚本,根据我们已准备好的 Kubernetes 的 YAML 模板,将其中的变量替换成用户输入的选项
|
||||
6. 生成应用的 Kubernetes YAML 配置文件
|
||||
7. 更新 Ingress 的配置,根据新部署的应用的名称,在 Ingress 的配置文件中增加一条路由信息
|
||||
8. 更新 PowerDNS,向其中插入一条 DNS 记录,IP 地址是边缘节点的 IP 地址。关于边缘节点,请查看 [边缘节点配置](https://jimmysong.io/kubernetes-handbook/practice/edge-node-configuration.html)
|
||||
9. Jenkins 调用 Kubernetes 的 API,部署应用
|
||||
|
||||
### 日志收集与监控
|
||||
|
||||
基于现有的ELK日志收集方案,稍作改造,选用[filebeat](https://www.elastic.co/products/beats/filebeat)来收集日志,可以作为sidecar的形式跟应用运行在同一个Pod中,比较轻量级消耗资源比较少。
|
||||
基于现有的 ELK 日志收集方案,稍作改造,选用 [filebeat](https://www.elastic.co/products/beats/filebeat) 来收集日志,可以作为 sidecar 的形式跟应用运行在同一个 Pod 中,比较轻量级消耗资源比较少。
|
||||
|
||||
![filebeat日志收集架构图](../images/filebeat-log-collector-arch.png)
|
||||
![filebeat 日志收集架构图](../images/filebeat-log-collector-arch.png)
|
||||
|
||||
详见[Kubernetes Handbook - 应用日志收集](https://jimmysong.io/kubernetes-handbook/practice/app-log-collection.html)。
|
||||
详见 [Kubernetes Handbook - 应用日志收集](https://jimmysong.io/kubernetes-handbook/practice/app-log-collection.html)。
|
||||
|
||||
### 安全性与权限管理
|
||||
|
||||
Kubernetes是一个多租户的云平台,因此必须对用户的权限加以限制,对用户空间进行隔离。Kubernetes中的隔离主要包括这几种:
|
||||
Kubernetes 是一个多租户的云平台,因此必须对用户的权限加以限制,对用户空间进行隔离。Kubernetes 中的隔离主要包括这几种:
|
||||
|
||||
* 网络隔离:需要使用网络插件,比如[flannel](https://coreos.com/flannel/), [calico](https://www.projectcalico.org/)。
|
||||
* 资源隔离:kubernetes原生支持资源隔离,pod就是资源隔离和调度的最小单位,同时使用[namespace](https://jimmysong.io/kubernetes-handbook/concepts/namespace.html)限制用户空间和资源限额。
|
||||
* 身份隔离:使用[RBAC-基于角色的访问控制](https://jimmysong.io/kubernetes-handbook/guide/rbac.html),多租户的身份认证和权限控制。
|
||||
* 网络隔离:需要使用网络插件,比如 [flannel](https://coreos.com/flannel/), [calico](https://www.projectcalico.org/)。
|
||||
* 资源隔离:kubernetes 原生支持资源隔离,pod 就是资源隔离和调度的最小单位,同时使用 [namespace](https://jimmysong.io/kubernetes-handbook/concepts/namespace.html) 限制用户空间和资源限额。
|
||||
* 身份隔离:使用 [RBAC - 基于角色的访问控制](https://jimmysong.io/kubernetes-handbook/guide/rbac.html),多租户的身份认证和权限控制。
|
||||
|
||||
## 如何开发Kubernetes原生应用步骤介绍
|
||||
## 如何开发 Kubernetes 原生应用步骤介绍
|
||||
|
||||
当我们有了一个kubernetes集群后,如何在上面开发和部署应用,应该遵循怎样的流程?下面我将展示如何使用go语言开发和部署一个Kubernetes native应用,使用wercker进行持续集成与持续发布,我将以一个很简单的前后端访问,获取伪造数据并展示的例子来说明。
|
||||
当我们有了一个 kubernetes 集群后,如何在上面开发和部署应用,应该遵循怎样的流程?下面我将展示如何使用 go 语言开发和部署一个 Kubernetes native 应用,使用 wercker 进行持续集成与持续发布,我将以一个很简单的前后端访问,获取伪造数据并展示的例子来说明。
|
||||
|
||||
### 云原生应用开发示例
|
||||
|
||||
我们将按照如下步骤来开发部署一个Kubernetes原生应用并将它部署到Kubernetes集群上开放给集群外访问:
|
||||
我们将按照如下步骤来开发部署一个 Kubernetes 原生应用并将它部署到 Kubernetes 集群上开放给集群外访问:
|
||||
|
||||
1. 服务API的定义
|
||||
2. 使用Go语言开发Kubernetes原生应用
|
||||
1. 服务 API 的定义
|
||||
2. 使用 Go 语言开发 Kubernetes 原生应用
|
||||
3. 一个持续构建与发布工具与环境
|
||||
4. 使用traefik和VIP做边缘节点提供外部访问路由
|
||||
4. 使用 traefik 和 VIP 做边缘节点提供外部访问路由
|
||||
|
||||
我写了两个示例用于演示,开发部署一个伪造的 metric 并显示在 web 页面上,包括两个service:
|
||||
我写了两个示例用于演示,开发部署一个伪造的 metric 并显示在 web 页面上,包括两个 service:
|
||||
|
||||
* [k8s-app-monitor-test](https://github.com/rootsongjc/k8s-app-monitor-test):生成模拟的监控数据,发送http请求,获取json返回值
|
||||
* [k8s-app-monitor-test](https://github.com/rootsongjc/k8s-app-monitor-test):生成模拟的监控数据,发送 http 请求,获取 json 返回值
|
||||
* [K8s-app-monitor-agent](https://github.com/rootsongjc/k8s-app-monitor-agent):获取监控数据并绘图,访问浏览器获取图表
|
||||
|
||||
**定义API生成API文档**
|
||||
**定义 API 生成 API文档 **
|
||||
|
||||
使用`API blueprint`格式,定义API文档,格式类似于markdown,再使用[aglio](https://github.com/danielgtaylor/aglio)生成HTML文档。
|
||||
使用 `API blueprint` 格式,定义 API 文档,格式类似于 markdown,再使用 [aglio](https://github.com/danielgtaylor/aglio) 生成 HTML 文档。
|
||||
|
||||
![API文档](../images/k8s-app-monitor-test-api-doc.jpg)
|
||||
![API 文档](../images/k8s-app-monitor-test-api-doc.jpg)
|
||||
|
||||
详见:[如何开发部署Kubernetes Native应用](https://jimmysong.io/posts/creating-cloud-native-app-with-kubernetes/)。
|
||||
详见:[如何开发部署 Kubernetes Native 应用](https://jimmysong.io/posts/creating-cloud-native-app-with-kubernetes/)。
|
||||
|
||||
## 如何迁移到云原生应用架构
|
||||
|
||||
Pivotal(后被 VMware 收购)是云原生应用的提出者,并推出了 [Pivotal Cloud Foundry](https://pivotal.io/platform) 云原生应用平台和 [Spring](https://spring.io/) 开源 Java 开发框架,成为云原生应用架构中先驱者和探路者。
|
||||
Pivotal(后被 VMware 收购)是云原生应用的提出者,并推出了 Pivotal Cloud Foundry 云原生应用平台和 [Spring](https://spring.io/) 开源 Java 开发框架,成为云原生应用架构中先驱者和探路者。
|
||||
|
||||
原书作于2015年,其中的示例主要针对 Java 应用,实际上也适用于任何应用类型,云原生应用架构适用于异构语言的程序开发,不仅仅是针对 Java 语言的程序开发。截止到本人翻译本书时,云原生应用生态系统已经初具规模,[CNCF](https://cncf.io/) 成员不断发展壮大,基于 Cloud Native 的创业公司不断涌现,[kubernetes](https://kubernetes.io/) 引领容器编排潮流,和 Service Mesh 技术(如 [Linkerd](https://linkerd.io/) 和 [Istio](https://istio.io/)) 的出现,Go 语言的兴起(参考另一本书 [Cloud Native Go](http://rootsongjc.github.io/cloud-native-go))等为我们将应用迁移到云原生架构的提供了更多的方案选择。
|
||||
原书作于 2015 年,其中的示例主要针对 Java 应用,实际上也适用于任何应用类型,云原生应用架构适用于异构语言的程序开发,不仅仅是针对 Java 语言的程序开发。截止到本人翻译本书时,云原生应用生态系统已经初具规模,[CNCF](https://cncf.io/) 成员不断发展壮大,基于云原生的创业公司不断涌现,[Kubernetes](https://kubernetes.io/) 引领容器编排潮流,和 Service Mesh 技术(如 [Linkerd](https://linkerd.io/) 和 [Istio](https://istio.io/)) 的出现,Go 语言的兴起(参考另一本书 [Cloud Native Go](http://rootsongjc.github.io/cloud-native-go))等为我们将应用迁移到云原生架构的提供了更多的方案选择。
|
||||
|
||||
### 迁移到云原生应用架构指南
|
||||
|
||||
|
@ -311,10 +309,10 @@ Pivotal(后被 VMware 收购)是云原生应用的提出者,并推出了 [
|
|||
* 十二因素应用程序:云原生应用程序架构模式的集合
|
||||
* 微服务:独立部署的服务,只做一件事情
|
||||
* 自助服务的敏捷基础设施:快速,可重复和一致地提供应用环境和后台服务的平台
|
||||
* 基于API的协作:发布和版本化的API,允许在云原生应用程序架构中的服务之间进行交互
|
||||
* 基于 API 的协作:发布和版本化的 API,允许在云原生应用程序架构中的服务之间进行交互
|
||||
* 抗压性:根据压力变强的系统
|
||||
|
||||
详见:[迁移到云原生应用架构](https://jimmysong.io/migrating-to-cloud-native-application-architectures/)
|
||||
详见:[迁移到云原生应用架构](https://jimmysong.io/migrating-to-cloud-native-application-architectures/)。
|
||||
|
||||
### 迁移案例解析
|
||||
|
||||
|
@ -325,113 +323,101 @@ Pivotal(后被 VMware 收购)是云原生应用的提出者,并推出了 [
|
|||
步骤说明:
|
||||
|
||||
1. 将原有应用拆解为服务
|
||||
2. 定义服务的接口/API通信方式
|
||||
2. 定义服务的接口 / API 通信方式
|
||||
3. 编写启动脚本作为容器的进程入口
|
||||
4. 准备应用配置文件
|
||||
5. 容器化、制作镜像
|
||||
6. 准备Kubernetes YAML文件
|
||||
7. 如果有外置配置文件需要创建ConfigMap或Secret存储
|
||||
6. 准备 Kubernetes YAML 文件
|
||||
7. 如果有外置配置文件需要创建 ConfigMap 或 Secret 存储
|
||||
|
||||
详见:[迁移传统应用到Kubernetes步骤详解——以Hadoop YARN为例](https://jimmysong.io/posts/migrating-hadoop-yarn-to-kubernetes/)。
|
||||
详见:[迁移传统应用到 Kubernetes 步骤详解 —— 以 Hadoop YARN 为例](https://jimmysong.io/posts/migrating-hadoop-yarn-to-kubernetes/)。
|
||||
|
||||
## Service Mesh基本原理和示例介绍
|
||||
## Service Mesh 基本原理和示例介绍
|
||||
|
||||
Service Mesh现在一般被翻译作服务网格,目前主流的Service Mesh有如下几款:
|
||||
Service Mesh 现在一般被翻译作服务网格,目前主流的 Service Mesh 有如下几款:
|
||||
|
||||
* [Istio](https://istio.io):IBM、Google、Lyft共同开源,详细文档见[Istio官方文档](https://istio.io)
|
||||
* [Linkerd](https://linkerd.io):原Twitter工程师开发,现为[CNCF](https://cncf.io)中的项目之一
|
||||
* [Envoy](https://www.envoyproxy.io/):Lyft开源的,可以在Istio中使用Sidecar模式运行
|
||||
* [Conduit](https://conduit.io):同样由Buoyant开源的轻量级的基于Kubernetes的Service Mesh
|
||||
* [Istio](https://istio.io):IBM、Google、Lyft 共同开源,详细文档见 [Istio 官方文档](https://istio.io)
|
||||
* [Linkerd](https://linkerd.io):原 Twitter 工程师开发,现为 [CNCF](https://cncf.io) 中的项目之一
|
||||
* [Envoy](https://www.envoyproxy.io/):Lyft 开源的,可以在 Istio 中使用 Sidecar 模式运行
|
||||
|
||||
此外还有很多其它的Service Mesh鱼贯而出,请参考[awesome-cloud-native](https://jimmysong.io/awesome-cloud-native)。
|
||||
此外还有很多其它的 Service Mesh 鱼贯而出,请参考 [awesome-cloud-native](https://jimmysong.io/awesome-cloud-native)。
|
||||
|
||||
### 什么是Service Mesh
|
||||
### 什么是 Service Mesh
|
||||
|
||||
如果用一句话来解释什么是 Service Mesh,可以将它比作是应用程序或者说微服务间的 TCP/IP,负责服务之间的网络调用、限流、熔断和监控。对于编写应用程序来说一般无须关心 TCP/IP 这一层(比如通过 HTTP 协议的 RESTful 应用),同样使用 Service Mesh 也就无须关心服务之间的那些原来是通过应用程序或者其他框架实现的事情,比如 Spring Cloud、OSS,现在只要交给 Service Mesh 就可以了。
|
||||
|
||||
![service mesh架构图](../images/serivce-mesh-control-plane.png)
|
||||
![service mesh 架构图](../images/serivce-mesh-control-plane.png)
|
||||
|
||||
详见[什么是 Service Mesh - jimmysong.io](https://jimmysong.io/posts/what-is-a-service-mesh/)。
|
||||
|
||||
### Service Mesh使用指南
|
||||
|
||||
两款Service Mesh各有千秋,我分别写了他们的使用案例指南:
|
||||
|
||||
* [微服务管理框架Service Mesh——Linkerd安装试用笔记](https://jimmysong.io/posts/linkerd-user-guide/)
|
||||
* [微服务管理框架Service Mesh——Istio安装试用笔记](https://jimmysong.io/posts/istio-installation/)
|
||||
|
||||
更多关于 Service Mesh 的内容请访问 [ServiceMesher 社区网站](http://www.servicemesher.com)。
|
||||
详见 [什么是 Service Mesh - jimmysong.io](https://jimmysong.io/blog/what-is-a-service-mesh/)。
|
||||
|
||||
## 使用案例
|
||||
|
||||
Kubernetes作为云原生计算的基本组件之一,开源2年时间以来热度与日俱增,它可以跟我们的生产结合,擦出很多火花,比如FaaS和Serverless类应用,都很适合运行在kubernetes上。
|
||||
Kubernetes 作为云原生计算的基本组件之一,自开源以来热度与日俱增,它可以跟我们的生产结合,擦出很多火花,比如 FaaS 和 Serverless 类应用,都很适合运行在 Kubernetes 上。
|
||||
|
||||
关于Cloud Native开源软件生态请参考 [Awesome Cloud Native - jimmysong.io](https://jimmysong.io/awesome-cloud-native)。
|
||||
关于 Cloud Native 开源软件生态请参考 [Awesome Cloud Native - jimmysong.io](https://jimmysong.io/awesome-cloud-native)。
|
||||
|
||||
### DevOps
|
||||
|
||||
下面是社区中Kubernetes开源爱好者的分享内容,我觉得是对Kubernetes在DevOps中应用的很好的形式值得大家借鉴。
|
||||
下面是社区中 Kubernetes 开源爱好者的分享内容,我觉得是对 Kubernetes 在 DevOps 中应用的很好的形式值得大家借鉴。
|
||||
|
||||
真正践行DevOps,让开发人员在掌握自己的开发和测试环境,让环境一致,让开发效率提升,让运维没有堆积如山的tickets,让监控更加精准,从Kubernetes平台开始。
|
||||
真正践行 DevOps,让开发人员在掌握自己的开发和测试环境,让环境一致,让开发效率提升,让运维没有堆积如山的 tickets,让监控更加精准,从 Kubernetes 平台开始。
|
||||
|
||||
**行动指南**
|
||||
|
||||
1. 根据环境(比如开发、测试、生产)划分`namespace`,也可以根据项目来划分
|
||||
2. 再为每个用户划分一个`namespace`、创建一个`serviceaccount`和`kubeconfig`文件,不同`namespace`间的资源隔离,目前不隔离网络,不同`namespace`间的服务可以互相访问
|
||||
3. 创建yaml模板,降低编写Kubernetes yaml文件编写难度
|
||||
4. 在`kubectl`命令上再封装一层,增加用户身份设置和环境初始化操作,简化`kubectl`命令和常用功能
|
||||
5. 管理员通过dashboard查看不同`namespace`的状态,也可以使用它来使操作更便捷
|
||||
6. 所有应用的日志统一收集到ElasticSearch中,统一日志访问入口
|
||||
7. 可以通过Grafana查看所有namespace中的应用的状态和kubernetes集群本身的状态
|
||||
8. 需要持久化的数据保存在分布式存储中,例如GlusterFS或Ceph中
|
||||
1. 根据环境(比如开发、测试、生产)划分 `namespace`,也可以根据项目来划分
|
||||
2. 再为每个用户划分一个 `namespace`、创建一个 `serviceaccount` 和 `kubeconfig` 文件,不同 `namespace` 间的资源隔离,目前不隔离网络,不同 `namespace` 间的服务可以互相访问
|
||||
3. 创建 YAML 模板,降低编写 Kubernetes YAML 文件编写难度
|
||||
4. 在 `kubectl` 命令上再封装一层,增加用户身份设置和环境初始化操作,简化 `kubectl` 命令和常用功能
|
||||
5. 管理员通过 dashboard 查看不同 `namespace` 的状态,也可以使用它来使操作更便捷
|
||||
6. 所有应用的日志统一收集到 ElasticSearch 中,统一日志访问入口
|
||||
7. 可以通过 Grafana 查看所有 namespace 中的应用的状态和 kubernetes 集群本身的状态
|
||||
8. 需要持久化的数据保存在分布式存储中,例如 GlusterFS 或 Ceph 中
|
||||
|
||||
**使用Kibana查看日志**
|
||||
**使用 Kibana 查看日志**
|
||||
|
||||
日志字段中包括了应用的标签、容器名称、主机名称、宿主机名称、IP地址、时间。
|
||||
日志字段中包括了应用的标签、容器名称、主机名称、宿主机名称、IP 地址、时间。
|
||||
|
||||
![kibana界面](../images/filebeat-docker-test.jpg)
|
||||
![kibana 界面](../images/filebeat-docker-test.jpg)
|
||||
|
||||
**使用Grafana查看应用状态**
|
||||
**使用 Grafana 查看应用状态**
|
||||
|
||||
**注**:感谢【K8S🤘Cloud Native实战群】尊贵的黄金会员小刚同学提供下面的Grafana监控图🙏
|
||||
**注**:以下监控图片由云原生社区涂小刚提供
|
||||
|
||||
监控分类示意图:
|
||||
|
||||
![Grafana界面示意图1](../images/kubernetes-devops-example-grafana-1.png)
|
||||
![Grafana 界面示意图 1](../images/kubernetes-devops-example-grafana-1.png)
|
||||
|
||||
Kubernetes集群全局监控图1
|
||||
Kubernetes 集群全局监控图 1
|
||||
|
||||
该监控图可以看到集群硬件使用情况。
|
||||
|
||||
![Grafana界面示意图2](../images/kubernetes-devops-example-grafana-2.png)
|
||||
![Grafana 界面示意图 2](../images/kubernetes-devops-example-grafana-2.png)
|
||||
|
||||
Kubernetes全局监控图2
|
||||
Kubernetes 全局监控图 2
|
||||
|
||||
该监控可以看到单个用户的namespace下的所有资源的使用情况。
|
||||
该监控可以看到单个用户的 namespace 下的所有资源的使用情况。
|
||||
|
||||
![Grafana界面示意图3](../images/kubernetes-devops-example-grafana-3.png)
|
||||
![Grafana 界面示意图 3](../images/kubernetes-devops-example-grafana-3.png)
|
||||
|
||||
### Spark on Kubernetes
|
||||
|
||||
TL;DR [https://jimmysong.io/spark-on-k8s](https://jimmysong.io/spark-on-k8s)
|
||||
Spark 原生支持 Standalone、Mesos 和 YARN 资源调度,现已支持 Kubernetes 原生调度,详见 [Spark on Kubernetes](https://jimmysong.io/spark-on-k8s)。
|
||||
|
||||
Spark原生支持standalone、mesos和YARN资源调度,现已支持Kubernetes原生调度,详见[运行支持Kubernetes原生调度的spark程序-Spark on Kubernetes](https://jimmysong.io/posts/running-spark-with-kubernetes-native-scheduler/)。
|
||||
**为何要使用 Spark on Kubernetes**
|
||||
|
||||
**为何要使用spark on kubernetes**
|
||||
使用 Kubernetes 原生调度的 Spark on Kubernetes 是对原先的 Spark on YARN 和 YARN on Docker 的改变是革命性的,主要表现在以下几点:
|
||||
|
||||
使用Kubernetes原生调度的spark on kubernetes是对原先的spark on yarn和yarn on docker的改变是革命性的,主要表现在以下几点:
|
||||
|
||||
1. **Kubernetes原生调度**:不再需要二层调度,直接使用Kubernetes的资源调度功能,跟其他应用共用整个kubernetes管理的资源池;
|
||||
2. **资源隔离,粒度更细**:原先yarn中的queue在spark on kubernetes中已不存在,取而代之的是kubernetes中原生的namespace,可以为每个用户分别指定一个namespace,限制用户的资源quota;
|
||||
3. **细粒度的资源分配**:可以给每个spark任务指定资源限制,实际指定多少资源就使用多少资源,因为没有了像yarn那样的二层调度(圈地式的),所以可以更高效和细粒度的使用资源;
|
||||
4. **监控的变革**:因为做到了细粒度的资源分配,所以可以对用户提交的每一个任务做到资源使用的监控,从而判断用户的资源使用情况,所有的metric都记录在数据库中,甚至可以为每个用户的每次任务提交计量;
|
||||
5. **日志的变革**:用户不再通过yarn的web页面来查看任务状态,而是通过pod的log来查看,可将所有的kuberentes中的应用的日志等同看待收集起来,然后可以根据标签查看对应应用的日志;
|
||||
1. **Kubernetes 原生调度 **:不再需要二层调度,直接使用 Kubernetes 的资源调度功能,跟其他应用共用整个 Kubernetes 管理的资源池;
|
||||
2. **资源隔离,粒度更细**:原先 YARN 中的 queue 在 Spark on Kubernetes 中已不存在,取而代之的是 Kubernetes 中原生的 namespace,可以为每个用户分别指定一个 namespace,限制用户的资源 quota;
|
||||
3. **细粒度的资源分配 **:可以给每个 spark 任务指定资源限制,实际指定多少资源就使用多少资源,因为没有了像 YARN那样的二层调度(圈地式的),所以可以更高效和细粒度的使用资源;
|
||||
4. **监控的变革**:因为做到了细粒度的资源分配,所以可以对用户提交的每一个任务做到资源使用的监控,从而判断用户的资源使用情况,所有的 metric 都记录在数据库中,甚至可以为每个用户的每次任务提交计量;
|
||||
5. **日志的变革**:用户不再通过 YARN 的 web 页面来查看任务状态,而是通过 pod 的 log 来查看,可将所有的 Kuberentes 中的应用的日志等同看待收集起来,然后可以根据标签查看对应应用的日志;
|
||||
|
||||
**如何提交任务**
|
||||
|
||||
仍然使用`spark-submit`提交spark任务,可以直接指定Kubernetes API server地址,下面的命令提交本地jar包到Kubernetes集群上运行,同时指定了运行任务的用户、提交命名的用户、运行的excutor实例数、driver和executor的资源限制、使用的spark版本等信息。
|
||||
仍然使用 `spark-submit` 提交 spark 任务,可以直接指定 Kubernetes API server 地址,下面的命令提交本地 jar 包到 Kubernetes 集群上运行,同时指定了运行任务的用户、提交命名的用户、运行的 excutor 实例数、driver 和 executor 的资源限制、使用的 spark 版本等信息。
|
||||
|
||||
详细使用说明见[Apache Spark on Kubernetes用户指南 - jimmysong.io](https://jimmysong.io/spark-on-k8s/user-guide.html)。
|
||||
详细使用说明见 [Apache Spark on Kubernetes 用户指南 - jimmysong.io](https://jimmysong.io/spark-on-k8s/user-guide.html)。
|
||||
|
||||
```bash
|
||||
./spark-submit \
|
||||
|
@ -463,11 +449,11 @@ Spark原生支持standalone、mesos和YARN资源调度,现已支持Kubernetes
|
|||
|
||||
**监控**
|
||||
|
||||
下图是从Kubernetes dashboard上看到的spark-cluster这个namespace上运行的应用情况。
|
||||
下图是从 Kubernetes dashboard 上看到的 spark-cluster 这个 namespace 上运行的应用情况。
|
||||
|
||||
![dashboard](../images/spark-job-on-kubernetes-example-1.jpg)
|
||||
|
||||
下图是从Grafana监控页面上查看到的某个executor资源占用情况。
|
||||
下图是从 Grafana 监控页面上查看到的某个 executor 资源占用情况。
|
||||
|
||||
![Grafana](../images/spark-job-on-kubernetes-example-2.jpg)
|
||||
|
||||
|
@ -476,4 +462,4 @@ Spark原生支持standalone、mesos和YARN资源调度,现已支持Kubernetes
|
|||
* [迁移到云原生应用架构指南 - jimmysong.io](https://jimmysong.io/migrating-to-cloud-native-application-architectures)
|
||||
* [Cloud Native Go - jimmysong.io](https://jimmysong.io/book/cloud-native-go/)
|
||||
* [Cloud Native Python - jimmysong.io](https://jimmysong.io/book/cloud-native-python/)
|
||||
* [Istio 官方文档(中文)- istio.io](https://istio.io/zh/)
|
||||
* [Istio 官方文档(中文)- istio.io](https://istio.io/latest/zh/)
|
|
@ -1,35 +1,35 @@
|
|||
# 自定义指标HPA
|
||||
# 自定义指标 HPA
|
||||
|
||||
Kubernetes中不仅支持CPU、内存为指标的HPA,还支持自定义指标的HPA,例如QPS。
|
||||
Kubernetes 中不仅支持 CPU、内存为指标的 HPA,还支持自定义指标的 HPA,例如 QPS。
|
||||
|
||||
本文中使用的yaml文件见[manifests/HPA](https://github.com/rootsongjc/kubernetes-handbook/tree/master/manifests/HPA)。
|
||||
本文中使用的 yaml 文件见 [manifests/HPA](https://github.com/rootsongjc/kubernetes-handbook/tree/master/manifests/HPA)。
|
||||
|
||||
## 设置自定义指标
|
||||
|
||||
**kubernetes1.6**
|
||||
|
||||
> 在kubernetes1.6集群中配置自定义指标的HPA的说明已废弃。
|
||||
> 在 kubernetes1.6 集群中配置自定义指标的 HPA 的说明已废弃。
|
||||
|
||||
在设置定义指标HPA之前需要先进行如下配置:
|
||||
在设置定义指标 HPA 之前需要先进行如下配置:
|
||||
|
||||
- 将heapster的启动参数 `--api-server` 设置为 true
|
||||
- 将 heapster 的启动参数 `--api-server` 设置为 true
|
||||
|
||||
|
||||
- 启用custom metric API
|
||||
- 将kube-controller-manager的启动参数中`--horizontal-pod-autoscaler-use-rest-clients`设置为true,并指定`--master`为API server地址,如`--master=http://172.20.0.113:8080`
|
||||
- 启用 custom metric API
|
||||
- 将 kube-controller-manager 的启动参数中 `--horizontal-pod-autoscaler-use-rest-clients` 设置为 true,并指定 `--master` 为 API server 地址,如 `--master=http://172.20.0.113:8080`
|
||||
|
||||
在kubernetes1.5以前很容易设置,参考[1.6以前版本的kubernetes中开启自定义HPA](https://medium.com/@marko.luksa/kubernetes-autoscaling-based-on-custom-metrics-without-using-a-host-port-b783ed6241ac),而在1.6中因为取消了原来的annotation方式设置custom metric,只能通过API server和kube-aggregator来获取custom metric,因为只有两种方式来设置了,一是直接通过API server获取heapster的metrics,二是部署[kube-aggragator](https://github.com/kubernetes/kube-aggregator)来实现。
|
||||
在 kubernetes1.5 以前很容易设置,参考 [1.6 以前版本的 kubernetes 中开启自定义 HPA](https://medium.com/@marko.luksa/kubernetes-autoscaling-based-on-custom-metrics-without-using-a-host-port-b783ed6241ac),而在 1.6 中因为取消了原来的 annotation 方式设置 custom metric,只能通过 API server 和 kube-aggregator 来获取 custom metric,因为只有两种方式来设置了,一是直接通过 API server 获取 heapster 的 metrics,二是部署 [kube-aggragator](https://github.com/kubernetes/kube-aggregator) 来实现。
|
||||
|
||||
我们将在kubernetes1.8版本的kubernetes中,使用聚合的API server来实现自定义指标的HPA。
|
||||
我们将在 kubernetes1.8 版本的 kubernetes 中,使用聚合的 API server 来实现自定义指标的 HPA。
|
||||
|
||||
**kuberentes1.7+**
|
||||
|
||||
确认您的kubernetes版本在1.7或以上,修改以下配置:
|
||||
确认您的 kubernetes 版本在 1.7 或以上,修改以下配置:
|
||||
|
||||
- 将kube-controller-manager的启动参数中`--horizontal-pod-autoscaler-use-rest-clients`设置为true,并指定`--master`为API server地址,如`--master=http://172.20.0.113:8080`
|
||||
- 修改kube-apiserver的配置文件apiserver,增加一条配置`--requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem --requestheader-allowed-names=aggregator --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --proxy-client-cert-file=/etc/kubernetes/ssl/kubernetes.pem --proxy-client-key-file=/etc/kubernetes/ssl/kubernetes-key.pem`,用来配置aggregator的CA证书。
|
||||
- 将 kube-controller-manager 的启动参数中 `--horizontal-pod-autoscaler-use-rest-clients` 设置为 true,并指定 `--master` 为 API server 地址,如 `--master=http://172.20.0.113:8080`
|
||||
- 修改 kube-apiserver 的配置文件 apiserver,增加一条配置 `--requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem --requestheader-allowed-names=aggregator --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --proxy-client-cert-file=/etc/kubernetes/ssl/kubernetes.pem --proxy-client-key-file=/etc/kubernetes/ssl/kubernetes-key.pem`,用来配置 aggregator 的 CA 证书。
|
||||
|
||||
已经内置了`apiregistration.k8s.io/v1beta1` API,可以直接定义APIService,如:
|
||||
已经内置了 `apiregistration.k8s.io/v1beta1` API,可以直接定义 APIService,如:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiregistration.k8s.io/v1
|
||||
|
@ -47,13 +47,13 @@ spec:
|
|||
version: v1alpha1
|
||||
```
|
||||
|
||||
**部署Prometheus**
|
||||
**部署 Prometheus**
|
||||
|
||||
使用[prometheus-operator.yaml](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/HPA/prometheus-operator.yaml)文件部署Prometheus operator。
|
||||
使用 [prometheus-operator.yaml](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/HPA/prometheus-operator.yaml) 文件部署 Prometheus operator。
|
||||
|
||||
**注意:**将镜像修改为你自己的镜像仓库地址。
|
||||
**注意:** 将镜像修改为你自己的镜像仓库地址。
|
||||
|
||||
这产生一个自定义的API:<http://172.20.0.113:8080/apis/custom-metrics.metrics.k8s.io/v1alpha1>,可以通过浏览器访问,还可以使用下面的命令可以检查该API:
|
||||
这产生一个自定义的 API:<http://172.20.0.113:8080/apis/custom-metrics.metrics.k8s.io/v1alpha1>,可以通过浏览器访问,还可以使用下面的命令可以检查该 API:
|
||||
|
||||
```bash
|
||||
$ kubectl get --raw=apis/custom-metrics.metrics.k8s.io/v1alpha1
|
||||
|
@ -62,8 +62,7 @@ $ kubectl get --raw=apis/custom-metrics.metrics.k8s.io/v1alpha1
|
|||
|
||||
## 参考
|
||||
|
||||
- [1.6以前版本的kubernetes中开启自定义HPA](https://medium.com/@marko.luksa/kubernetes-autoscaling-based-on-custom-metrics-without-using-a-host-port-b783ed6241ac)
|
||||
- [1.7版本的kubernetes中启用自定义HPA](https://docs.bitnami.com/kubernetes/how-to/configure-autoscaling-custom-metrics/)
|
||||
- [Horizontal Pod Autoscaler Walkthrough](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/)
|
||||
- [Kubernetes 1.8: Now with 100% Daily Value of Custom Metrics](https://blog.openshift.com/kubernetes-1-8-now-custom-metrics/)
|
||||
- [Arbitrary/Custom Metrics in the Horizontal Pod Autoscaler#117](https://github.com/kubernetes/features/issues/117)
|
||||
- [1.6 以前版本的 kubernetes 中开启自定义 HPA - medium.com](https://medium.com/@marko.luksa/kubernetes-autoscaling-based-on-custom-metrics-without-using-a-host-port-b783ed6241ac)
|
||||
- [Horizontal Pod Autoscaler Walkthrough - kubernetes.io](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/)
|
||||
- [Kubernetes 1.8: Now with 100% Daily Value of Custom Metrics - blog.openshift.com](https://blog.openshift.com/kubernetes-1-8-now-custom-metrics/)
|
||||
- [Arbitrary/Custom Metrics in the Horizontal Pod Autoscaler#117 - github.com](https://github.com/kubernetes/features/issues/117)
|
||||
|
|
|
@ -764,7 +764,7 @@ $ echo $?
|
|||
|
||||
#### Rolling Update Deployment
|
||||
|
||||
`.spec.strategy.type==RollingUpdate` 时,Deployment 使用 [rolling update](https://kubernetes.io/docs/tasks/run-application/rolling-update-replication-controller) 的方式更新 Pod 。您可以指定 `maxUnavailable` 和 `maxSurge` 来控制 rolling update 进程。
|
||||
`.spec.strategy.type==RollingUpdate` 时,Deployment 使用 Rolling Update 的方式更新 Pod 。您可以指定 `maxUnavailable` 和 `maxSurge` 来控制 rolling update 进程。
|
||||
|
||||
##### Max Unavailable
|
||||
|
||||
|
|
|
@ -41,7 +41,3 @@ Kubernetes 提供了一个准入控制器(`PodPreset`),当其启用时,P
|
|||
1. 您已启用 `settings.k8s.io/v1alpha1/podpreset` API 类型。例如,可以通过在 API server 的 `--runtime-config` 选项中包含 `settings.k8s.io/v1alpha1=true` 来完成此操作。
|
||||
2. 您已启用 `PodPreset` 准入控制器。 一种方法是将 `PodPreset` 包含在为 API server 指定的 `--admission-control` 选项值中。
|
||||
3. 您已经在要使用的命名空间中通过创建 `PodPreset` 对象来定义 `PodPreset`。
|
||||
|
||||
## 更多资料
|
||||
|
||||
- [使用 PodPreset 向 Pod 中注入数据](https://kubernetes.io/docs/tasks/inject-data-application/podpreset)
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
- Taint(污点)和 Toleration(容忍):这些为节点“吸引”或“排斥” Pod 提供了一种方法。当需要将应用程序部署到特定硬件(例如用于科学计算的 GPU)时,经常使用它们。[阅读更多](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/)。
|
||||
- **向下 API**:这允许您的容器使用有关自己或集群的信息,而不会过度耦合到 Kubernetes API server。这可以通过[环境变量](https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/) 或者 [DownwardAPIVolumeFiles](https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/)。
|
||||
- **Pod 预设**:通常,要将运行时需求(例如环境变量、ConfigMap 和 Secret)安装到资源中,可以在资源的配置文件中指定它们。PodPresets 允许您在创建资源时动态注入这些需求。例如,这允许团队 A 将任意数量的新Secret 安装到团队 B 和 C 创建的资源中,而不需要 B 和 C 的操作。[请参阅示例](https://kubernetes.io/docs/tasks/inject-data-application/podpreset/)。
|
||||
- **Pod 预设**:通常,要将运行时需求(例如环境变量、ConfigMap 和 Secret)安装到资源中,可以在资源的配置文件中指定它们。PodPresets 允许您在创建资源时动态注入这些需求。例如,这允许团队 A 将任意数量的新Secret 安装到团队 B 和 C 创建的资源中,而不需要 B 和 C 的操作。
|
||||
|
||||
#### 其他 API 对象
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
## Kubernetes 加固指南
|
||||
|
||||
*Kubernetes Hardening Guidance*([查看英文原版 PDF](https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES HARDENING GUIDANCE.PDF)) 是由美国国家安全局(NSA)于 2021 年 8 月发布的,详见[出版信息](https://jimmysong.io/kubernetes-hardening-guidance/publication-infomation.md)。其中文版《Kubernetes 加固指南》(或译作《Kubernetes 强化指南》)是由 [Jimmy Song](https://jimmysong.i/) 翻译,[点击在线阅读](https://jimmysong.io/kubernetes-hardening-guidance),如您发现错误,欢迎在 [GitHub](https://github.com/rootsongjc/kubernetes-hardening-guidance) 上提交勘误(已知[勘误](https://jimmysong.io/kubernetes-hardening-guidance/corrigendum.html))。
|
||||
*Kubernetes Hardening Guidance*([查看英文原版 PDF](https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES HARDENING GUIDANCE.PDF)) 是由美国国家安全局(NSA)于 2021 年 8 月发布的,详见[出版信息](https://jimmysong.io/kubernetes-hardening-guidance/publication-infomation.md)。其中文版《Kubernetes 加固指南》(或译作《Kubernetes 强化指南》),可[在线阅读](https://jimmysong.io/kubernetes-hardening-guidance)。
|
||||
|
||||
## 参考
|
||||
|
||||
|
|
|
@ -335,7 +335,7 @@ imagePullSecret 的使用在 [镜像文档](https://kubernetes.io/docs/concepts/
|
|||
|
||||
#### 自动挂载手动创建的 Secret
|
||||
|
||||
手动创建的 secret(例如包含用于访问 github 帐户的令牌)可以根据其服务帐户自动附加到 pod。请参阅 [使用 PodPreset 向 Pod 中注入信息](https://kubernetes.io/docs/tasks/run-application/podpreset) 以获取该进程的详细说明。
|
||||
手动创建的 secret(例如包含用于访问 github 帐户的令牌)可以根据其服务帐户自动附加到 pod。
|
||||
|
||||
## 详细
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## TLS Bootstrap
|
||||
# TLS Bootstrap
|
||||
|
||||
本文档介绍如何为 kubelet 设置 TLS 客户端证书引导(bootstrap)。
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
|
@ -1,4 +1,6 @@
|
|||
# Kubernetes网络和集群性能测试
|
||||
# Kubernetes 网络和集群性能测试
|
||||
|
||||
本节将通过构建一个 Kubernetes 测试环境,来测试其网络和集群性能。
|
||||
|
||||
## 准备
|
||||
|
||||
|
@ -6,9 +8,9 @@
|
|||
|
||||
在以下几种环境下进行测试:
|
||||
|
||||
- Kubernetes集群node节点上通过Cluster IP方式访问
|
||||
- Kubernetes集群内部通过service访问
|
||||
- Kubernetes集群外部通过traefik ingress暴露的地址访问
|
||||
- Kubernetes 集群 node 节点上通过 Cluster IP 方式访问
|
||||
- Kubernetes 集群内部通过 service 访问
|
||||
- Kubernetes 集群外部通过 traefik ingress 暴露的地址访问
|
||||
|
||||
**测试地址**
|
||||
|
||||
|
@ -20,14 +22,14 @@ Ingress Host:traefik.sample-webapp.io
|
|||
|
||||
**测试工具**
|
||||
|
||||
- [Locust](http://locust.io):一个简单易用的用户负载测试工具,用来测试web或其他系统能够同时处理的并发用户数。
|
||||
- [Locust](http://locust.io/):一个简单易用的用户负载测试工具,用来测试 web 或其他系统能够同时处理的并发用户数。
|
||||
- curl
|
||||
- [kubemark](https://github.com/kubernetes/kubernetes/tree/master/test/e2e)
|
||||
- 测试程序:sample-webapp,源码见Github [kubernetes的分布式负载测试](https://github.com/rootsongjc/distributed-load-testing-using-kubernetes)
|
||||
- 测试程序:sample-webapp,源码见 Github [kubernetes 的分布式负载测试](https://github.com/rootsongjc/distributed-load-testing-using-kubernetes)
|
||||
|
||||
**测试说明**
|
||||
|
||||
通过向`sample-webapp`发送curl请求获取响应时间,直接curl后的结果为:
|
||||
通过向 `sample-webapp` 发送 curl 请求获取响应时间,直接 curl 后的结果为:
|
||||
|
||||
```bash
|
||||
$ curl "http://10.254.149.31:8000/"
|
||||
|
@ -36,7 +38,7 @@ Welcome to the "Distributed Load Testing Using Kubernetes" sample web app
|
|||
|
||||
## 网络延迟测试
|
||||
|
||||
### 场景一、 Kubernetes集群node节点上通过Cluster IP访问
|
||||
### 场景一、 Kubernetes 集群 node 节点上通过 Cluster IP 访问
|
||||
|
||||
**测试命令**
|
||||
|
||||
|
@ -44,7 +46,7 @@ Welcome to the "Distributed Load Testing Using Kubernetes" sample web app
|
|||
curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}' "http://10.254.149.31:8000/"
|
||||
```
|
||||
|
||||
**10组测试结果**
|
||||
**10 组测试结果**
|
||||
|
||||
| No | time_connect | time_starttransfer | time_total |
|
||||
| ---- | ------------ | ------------------ | ---------- |
|
||||
|
@ -71,7 +73,7 @@ time_starttransfer:在发出请求之后,Web 服务器返回数据的第一
|
|||
|
||||
time_total:完成请求所用的时间
|
||||
|
||||
### 场景二、Kubernetes集群内部通过service访问
|
||||
### 场景二、Kubernetes 集群内部通过 service 访问
|
||||
|
||||
**测试命令**
|
||||
|
||||
|
@ -79,7 +81,7 @@ time_total:完成请求所用的时间
|
|||
curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}' "http://sample-webapp:8000/"
|
||||
```
|
||||
|
||||
**10组测试结果**
|
||||
**10 组测试结果**
|
||||
|
||||
| No | time_connect | time_starttransfer | time_total |
|
||||
| ---- | ------------ | ------------------ | ---------- |
|
||||
|
@ -96,7 +98,7 @@ curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}' "h
|
|||
|
||||
**平均响应时间:6ms**
|
||||
|
||||
### 场景三、在公网上通过traefik ingress访问
|
||||
### 场景三、在公网上通过 traefik ingress 访问
|
||||
|
||||
**测试命令**
|
||||
|
||||
|
@ -104,7 +106,7 @@ curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}' "h
|
|||
curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}' "http://traefik.sample-webapp.io" >>result
|
||||
```
|
||||
|
||||
**10组测试结果**
|
||||
**10 组测试结果**
|
||||
|
||||
| No | time_connect | time_starttransfer | time_total |
|
||||
| ---- | ------------ | ------------------ | ---------- |
|
||||
|
@ -125,17 +127,17 @@ curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}' "h
|
|||
|
||||
在这三种场景下的响应时间测试结果如下:
|
||||
|
||||
- Kubernetes集群node节点上通过Cluster IP方式访问:2ms
|
||||
- Kubernetes集群内部通过service访问:6ms
|
||||
- Kubernetes集群外部通过traefik ingress暴露的地址访问:110ms
|
||||
- Kubernetes 集群 node 节点上通过 Cluster IP 方式访问:2ms
|
||||
- Kubernetes 集群内部通过 service 访问:6ms
|
||||
- Kubernetes 集群外部通过 traefik ingress 暴露的地址访问:110ms
|
||||
|
||||
*注意:执行测试的node节点/Pod与serivce所在的pod的距离(是否在同一台主机上),对前两个场景可以能会有一定影响。*
|
||||
*注意:执行测试的 node 节点 / Pod 与 serivce 所在的 pod 的距离(是否在同一台主机上),对前两个场景可以能会有一定影响。*
|
||||
|
||||
## 网络性能测试
|
||||
|
||||
网络使用flannel的vxlan模式。
|
||||
网络使用 flannel 的 vxlan 模式。
|
||||
|
||||
使用iperf进行测试。
|
||||
使用 iperf 进行测试。
|
||||
|
||||
服务端命令:
|
||||
|
||||
|
@ -166,7 +168,7 @@ iperf -c ${server-ip} -p 12345 -i 1 -t 10 -w 20K
|
|||
[ 3] 0.0-10.0 sec 6.25 GBytes 5.37 Gbits/sec
|
||||
```
|
||||
|
||||
### 场景二、不同主机的Pod之间(使用flannel的vxlan模式)
|
||||
### 场景二、不同主机的 Pod 之间 (使用 flannel 的 vxlan 模式)
|
||||
|
||||
```
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
|
@ -183,7 +185,7 @@ iperf -c ${server-ip} -p 12345 -i 1 -t 10 -w 20K
|
|||
[ 3] 0.0-10.0 sec 3.85 GBytes 3.30 Gbits/sec
|
||||
```
|
||||
|
||||
### 场景三、Node与非同主机的Pod之间(使用flannel的vxlan模式)
|
||||
### 场景三、Node 与非同主机的 Pod 之间(使用 flannel 的 vxlan 模式)
|
||||
|
||||
```
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
|
@ -200,7 +202,7 @@ iperf -c ${server-ip} -p 12345 -i 1 -t 10 -w 20K
|
|||
[ 3] 0.0-10.0 sec 3.98 GBytes 3.42 Gbits/sec
|
||||
```
|
||||
|
||||
### 场景四、不同主机的Pod之间(使用flannel的host-gw模式)
|
||||
### 场景四、不同主机的 Pod 之间(使用 flannel 的 host-gw 模式)
|
||||
|
||||
```
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
|
@ -217,7 +219,7 @@ iperf -c ${server-ip} -p 12345 -i 1 -t 10 -w 20K
|
|||
[ 5] 0.0-10.0 sec 5.68 GBytes 4.88 Gbits/sec
|
||||
```
|
||||
|
||||
### 场景五、Node与非同主机的Pod之间(使用flannel的host-gw模式)
|
||||
### 场景五、Node 与非同主机的 Pod 之间(使用 flannel 的 host-gw 模式)
|
||||
|
||||
```
|
||||
[ ID] Interval Transfer Bandwidth
|
||||
|
@ -236,15 +238,17 @@ iperf -c ${server-ip} -p 12345 -i 1 -t 10 -w 20K
|
|||
|
||||
### 网络性能对比综述
|
||||
|
||||
使用Flannel的**vxlan**模式实现每个pod一个IP的方式,会比宿主机直接互联的网络性能损耗30%~40%,符合网上流传的测试结论。而flannel的host-gw模式比起宿主机互连的网络性能损耗大约是10%。
|
||||
使用 Flannel 的 **vxlan** 模式实现每个 pod 一个 IP 的方式,会比宿主机直接互联的网络性能损耗 30%~40%,符合网上流传的测试结论。而 flannel 的 host-gw 模式比起宿主机互连的网络性能损耗大约是 10%。
|
||||
|
||||
Vxlan会有一个封包解包的过程,所以会对网络性能造成较大的损耗,而host-gw模式是直接使用路由信息,网络损耗小。
|
||||
Vxlan 会有一个封包解包的过程,所以会对网络性能造成较大的损耗,而 host-gw 模式是直接使用路由信息,网络损耗小。
|
||||
|
||||
## Kubernete的性能测试
|
||||
|
||||
参考[Kubernetes集群性能测试](https://supereagle.github.io/2017/03/09/kubemark/)中的步骤,对kubernetes的性能进行测试。
|
||||
## Kubernete 的性能测试
|
||||
|
||||
我的集群版本是Kubernetes1.6.0,首先克隆代码,将kubernetes目录复制到`$GOPATH/src/k8s.io/`下然后执行:
|
||||
参考 [Kubernetes 集群性能测试](https://supereagle.github.io/2017/03/09/kubemark/)中的步骤,对 kubernetes 的性能进行测试。
|
||||
|
||||
我的集群版本是 Kubernetes1.6.0,首先克隆代码,将 kubernetes 目录复制到 `$GOPATH/src/k8s.io/` 下然后执行:
|
||||
|
||||
```bash
|
||||
$ ./hack/generate-bindata.sh
|
||||
|
@ -328,11 +332,11 @@ Ginkgo ran 1 suite in 4m28.667870101s
|
|||
Test Suite Passed
|
||||
```
|
||||
|
||||
从kubemark输出的日志中可以看到**API calls latencies**和**Performance**。
|
||||
从 kubemark 输出的日志中可以看到 **API calls latencies** 和 **Performance**。
|
||||
|
||||
**日志里显示,创建90个pod用时40秒以内,平均创建每个pod耗时0.44秒。**
|
||||
**日志里显示,创建 90 个 pod 用时 40 秒以内,平均创建每个 pod 耗时 0.44 秒。**
|
||||
|
||||
### 不同type的资源类型API请求耗时分布
|
||||
### 不同 type 的资源类型 API 请求耗时分布
|
||||
|
||||
| Resource | Verb | 50% | 90% | 99% |
|
||||
| --------- | ------ | ------- | -------- | -------- |
|
||||
|
@ -342,20 +346,22 @@ Test Suite Passed
|
|||
| nodes | PATCH | 4.245ms | 11.117ms | 18.63ms |
|
||||
| pods | PUT | 2.193ms | 2.619ms | 17.285ms |
|
||||
|
||||
从`log.txt`日志中还可以看到更多详细请求的测试指标。
|
||||
从 `log.txt` 日志中还可以看到更多详细请求的测试指标。
|
||||
|
||||
![kubernetes-dashboard](../images/kubenetes-e2e-test.jpg)
|
||||
![Kubernetes dashboard](../images/kubenetes-e2e-test.jpg)
|
||||
|
||||
### 注意事项
|
||||
|
||||
测试过程中需要用到docker镜像存储在GCE中,需要翻墙下载,我没看到哪里配置这个镜像的地址。该镜像副本已上传时速云:
|
||||
### 注意事项
|
||||
|
||||
测试过程中需要用到 docker 镜像存储在 GCE 中,需要翻墙下载,我没看到哪里配置这个镜像的地址。该镜像副本已上传时速云:
|
||||
|
||||
用到的镜像有如下两个:
|
||||
|
||||
- gcr.io/google_containers/pause-amd64:3.0
|
||||
- gcr.io/google_containers/serve_hostname:v1.4
|
||||
|
||||
## Locust测试
|
||||
## Locust 测试
|
||||
|
||||
请求统计
|
||||
|
||||
|
@ -373,20 +379,18 @@ Test Suite Passed
|
|||
| POST /metrics | 5114993 | 63000 | 127000 | 142000 | 149000 | 160000 | 166000 | 172000 | 176000 | 331330 |
|
||||
| None Total | 5120063 | 63000 | 127000 | 142000 | 149000 | 160000 | 166000 | 172000 | 176000 | 331330 |
|
||||
|
||||
以上两个表格都是瞬时值。请求失败率在2%左右。
|
||||
以上两个表格都是瞬时值。请求失败率在 2% 左右。
|
||||
|
||||
Sample-webapp起了48个pod。
|
||||
Sample-webapp 起了 48 个 pod。
|
||||
|
||||
Locust模拟10万用户,每秒增长100个。
|
||||
Locust 模拟 10 万用户,每秒增长 100 个。
|
||||
|
||||
![locust测试页面](../images/kubernetes-locust-test.jpg)
|
||||
|
||||
关于Locust的使用请参考Github:https://github.com/rootsongjc/distributed-load-testing-using-kubernetes
|
||||
关于 Locust 的使用请参考 [Github](https://github.com/rootsongjc/distributed-load-testing-using-kubernetes)。
|
||||
|
||||
## 参考
|
||||
|
||||
- [基于 Python 的性能测试工具 locust (与 LR 的简单对比)](https://testerhome.com/topics/4839)
|
||||
- [Locust docs](http://docs.locust.io/en/latest/what-is-locust.html)
|
||||
- [Kubernetes集群性能测试](https://supereagle.github.io/2017/03/09/kubemark/)
|
||||
- [CoreOS是如何将Kubernetes的性能提高10倍的](http://dockone.io/article/1050)
|
||||
- [运用Kubernetes进行分布式负载测试](http://www.csdn.net/article/2015-07-07/2825155)
|
||||
- [Locust 文档 - docs.locust.io](http://docs.locust.io/en/latest/what-is-locust.html)
|
||||
- [Kubernetes 集群性能测试 - supereagle.github.io](https://supereagle.github.io/2017/03/09/kubemark/)
|
||||
- [CoreOS 是如何将 Kubernetes 的性能提高 10 倍的 - dockone.io](http://dockone.io/article/1050)
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
# Rook
|
||||
|
||||
[Rook](https://github.com/rook/rook)是一款云原生环境下的开源分布式存储编排系统,目前已进入CNCF孵化。Rook的官方网站是<https://rook.io>。
|
||||
[Rook](https://github.com/rook/rook) 是一款云原生环境下的开源分布式存储编排系统,目前已进入 CNCF 孵化。Rook 的官方网站是 [https://rook.io](https://rook.io/)。
|
||||
|
||||
## Rook是什么?
|
||||
## Rook 是什么?
|
||||
|
||||
Rook将分布式存储软件转变为自我管理,自我缩放和自我修复的存储服务。它通过自动化部署,引导、配置、供应、扩展、升级、迁移、灾难恢复、监控和资源管理来实现。 Rook使用基础的云原生容器管理、调度和编排平台提供的功能来履行其职责。
|
||||
Rook 将分布式存储软件转变为自我管理,自我缩放和自我修复的存储服务。它通过自动化部署,引导、配置、供应、扩展、升级、迁移、灾难恢复、监控和资源管理来实现。 Rook 使用基础的云原生容器管理、调度和编排平台提供的功能来履行其职责。
|
||||
|
||||
Rook利用扩展点深入融入云原生环境,为调度、生命周期管理、资源管理、安全性、监控和用户体验提供无缝体验。
|
||||
Rook 利用扩展点深入融入云原生环境,为调度、生命周期管理、资源管理、安全性、监控和用户体验提供无缝体验。
|
||||
|
||||
Rook现在处于alpha状态,并且最初专注于在Kubernetes之上运行Ceph。Ceph是一个分布式存储系统,提供文件、数据块和对象存储,可以部署在大型生产集群中。Rook计划在未来的版本中增加对除Ceph之外的其他存储系统以及Kubernetes之外的其他云原生环境的支持。
|
||||
Rook 现在处于 alpha 状态,并且最初专注于在 Kubernetes 之上运行 Ceph。Ceph 是一个分布式存储系统,提供文件、数据块和对象存储,可以部署在大型生产集群中。Rook 计划在未来的版本中增加对除 Ceph 之外的其他存储系统以及 Kubernetes 之外的其他云原生环境的支持。
|
||||
|
||||
## 部署
|
||||
|
||||
可以使用helm或直接用yaml文件两种方式来部署rook operator。
|
||||
可以使用 helm 或直接用 yaml 文件两种方式来部署 rook operator。
|
||||
|
||||
**使用helm部署**
|
||||
**使用 helm 部署**
|
||||
|
||||
```bash
|
||||
helm init -i jimmysong/kubernetes-helm-tiller:v2.8.1
|
||||
|
@ -22,15 +22,15 @@ helm repo add rook-alpha https://charts.rook.io/alpha
|
|||
helm install rook-alpha/rook --name rook --namespace rook-system
|
||||
```
|
||||
|
||||
**直接使用yaml文件部署**
|
||||
**直接使用 yaml 文件部署**
|
||||
|
||||
```bash
|
||||
kubectl apply -f rook-operator.yaml
|
||||
```
|
||||
|
||||
不论使用那种方式部署的rook operator,都会在rook-agent中看到rook-agent用户无法列出集群中某些资源的错误,可以通过为rook-agent的分配`cluster-admin`权限临时解决,详见[Issue 1472](https://github.com/rook/rook/issues/1472)。
|
||||
不论使用那种方式部署的 rook operator,都会在 rook-agent 中看到 rook-agent 用户无法列出集群中某些资源的错误,可以通过为 rook-agent 的分配 `cluster-admin` 权限临时解决,详见 [Issue 1472](https://github.com/rook/rook/issues/1472)。
|
||||
|
||||
使用如下yanl文件创建一个`ClusterRoleBinding`并应用到集群中。
|
||||
使用如下 yanl 文件创建一个 `ClusterRoleBinding` 并应用到集群中。
|
||||
|
||||
```yaml
|
||||
kind: ClusterRoleBinding
|
||||
|
@ -47,11 +47,11 @@ roleRef:
|
|||
apiGroup: ""
|
||||
```
|
||||
|
||||
**部署rook cluster**
|
||||
**部署 rook cluster**
|
||||
|
||||
创建完rook operator后,我们再部署rook cluster。
|
||||
创建完 rook operator 后,我们再部署 rook cluster。
|
||||
|
||||
`rook-cluster.yaml`配置如下:
|
||||
`rook-cluster.yaml` 配置如下:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
|
@ -76,15 +76,15 @@ spec:
|
|||
journalSizeMB: 1024
|
||||
```
|
||||
|
||||
**注意**:需要手动指定`versionTag`,因为该镜像repo中没有`latest`标签,如不指定的话Pod将出现镜像拉取错误。
|
||||
**注意**:需要手动指定 `versionTag`,因为该镜像 repo 中没有 `latest` 标签,如不指定的话 Pod 将出现镜像拉取错误。
|
||||
|
||||
执行下面的命令部署rook集群。
|
||||
执行下面的命令部署 rook 集群。
|
||||
|
||||
```bash
|
||||
kubectl apply -f rook-cluster.yaml
|
||||
```
|
||||
|
||||
rook集群运行在`rook` namespace下,查看rook集群中的pod:
|
||||
rook 集群运行在`rook` namespace 下,查看 rook 集群中的 pod:
|
||||
|
||||
```bash
|
||||
$ kubectl -n rook get pod
|
||||
|
@ -100,9 +100,9 @@ rook-ceph-osd-zf7rg 1/1 Running 1 4m
|
|||
rook-tools 1/1 Running 0 2m
|
||||
```
|
||||
|
||||
**部署StorageClass**
|
||||
**部署 StorageClass**
|
||||
|
||||
StorageClass rook-block的yaml文件(rook-storage.yaml)如下:
|
||||
StorageClass rook-block 的 yaml 文件(rook-storage.yaml)如下:
|
||||
|
||||
```yaml
|
||||
apiVersion: rook.io/v1alpha1
|
||||
|
@ -134,11 +134,11 @@ parameters:
|
|||
# fstype: ext4
|
||||
```
|
||||
|
||||
我们在下面的示例中将使用rook-block这个StorageClass来创建PV。
|
||||
我们在下面的示例中将使用 rook-block 这个 StorageClass 来创建 PV。
|
||||
|
||||
## 工具
|
||||
|
||||
部署rook操作工具pod,该工具pod的yaml文件(rook-tools.yaml)如下:
|
||||
部署 Rook 操作工具 pod,该工具 pod 的 yaml 文件(rook-tools.yaml)如下:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
|
@ -189,21 +189,21 @@ spec:
|
|||
path: mon-endpoints
|
||||
```
|
||||
|
||||
`ConfigMap`和`Secret`中的配置项内容是自定义的。
|
||||
`ConfigMap` 和 `Secret` 中的配置项内容是自定义的。
|
||||
|
||||
使用下面的命令部署工具pod:
|
||||
使用下面的命令部署工具 pod:
|
||||
|
||||
```bash
|
||||
kubectl apply -f rook-tools.yaml
|
||||
```
|
||||
|
||||
这是一个独立的pod,没有使用其他高级的controller来管理,我们将它部署在`rook-system`的namespace下。
|
||||
这是一个独立的 pod,没有使用其他高级的 controller 来管理,我们将它部署在 `rook-system` 的 namespace 下。
|
||||
|
||||
```bash
|
||||
kubectl -n rook exec -it rook-tools bash
|
||||
```
|
||||
|
||||
使用下面的命令查看rook集群状态。
|
||||
使用下面的命令查看 rook 集群状态。
|
||||
|
||||
```bash
|
||||
$ rookctl status
|
||||
|
@ -239,29 +239,28 @@ POOLS:
|
|||
|
||||
## 示例
|
||||
|
||||
官方提供了使用rook作为典型的LAMP(Linux + Apache + MySQL + PHP)应用Wordpress的存储后端的示例的yaml文件`mysql.yaml`和`wordpress.yaml`,使用下面的命令创建。
|
||||
官方提供了使用 Rook 作为典型的 LAMP(Linux + Apache + MySQL + PHP)应用 Wordpress 的存储后端的示例的 yaml 文件 `mysql.yaml` 和 `wordpress.yaml`,使用下面的命令创建。
|
||||
|
||||
```bash
|
||||
kubectl apply -f mysql.yaml
|
||||
kubectl apply -f wordpress.yaml
|
||||
```
|
||||
|
||||
Wordpress要依赖于MySQL,所以要先创建MySQL。
|
||||
Wordpress 要依赖于 MySQL,所以要先创建 MySQL。
|
||||
|
||||
在创建wordpress的时候可能遇到该错误[rook flexvolume failing to attach volumes #1147](https://github.com/rook/rook/issues/1147),该问题尚未解决。
|
||||
在创建 wordpress 的时候可能遇到该错误 [rook flexvolume failing to attach volumes #1147](https://github.com/rook/rook/issues/1147),该问题尚未解决。
|
||||
|
||||
## 清理
|
||||
|
||||
如果使用helm部署,则执行下面的命令:
|
||||
如果使用 helm 部署,则执行下面的命令:
|
||||
|
||||
```bash
|
||||
helm delete --purge rook
|
||||
helm delete daemonset rook-agent
|
||||
```
|
||||
|
||||
如果使用yaml文件直接部署,则使用`kubectl delete -f `加当初使用的yaml文件即可删除集群。
|
||||
如果使用 yaml 文件直接部署,则使用 `kubectl delete -f` 加当初使用的 yaml 文件即可删除集群。
|
||||
|
||||
## 参考
|
||||
|
||||
- [Operator Helm Chart](https://rook.io/docs/rook/master/helm-operator.html)
|
||||
- [Creating Rook Clusters](https://rook.io/docs/rook/v0.6/cluster-crd.html)
|
||||
- [Creating Rook Clusters - rook.io](https://rook.io/docs/rook/v0.6/cluster-crd.html)
|
||||
|
|
|
@ -1,33 +1,20 @@
|
|||
# 在OpenShift中使用GlusterFS做持久化存储
|
||||
# 在 OpenShift 中使用 GlusterFS 做持久化存储
|
||||
|
||||
### 概述
|
||||
在本文中,我们将介绍容器存储的首选以及如何部署它。 Kusternet 和 OpenShift 支持 GlusterFS 已经有一段时间了。 GlusterFS 的适用性很好,可用于所有的部署场景:裸机、虚拟机、内部部署和公共云。 在容器中运行 GlusterFS 的新特性将在本系列后面讨论。
|
||||
|
||||
本文由Daniel Messer(Technical Marketing Manager Storage @RedHat)和Keith Tenzer(Solutions Architect @RedHat)共同撰写。
|
||||
GlusterFS 是一个分布式文件系统,内置了原生协议(GlusterFS)和各种其他协议(NFS,SMB,...)。 为了与 OpenShift 集成,节点将通过 FUSE 使用原生协议,将 GlusterFS 卷挂在到节点本身上,然后将它们绑定到目标容器中。 OpenShift / Kubernetes 具有实现请求、释放和挂载、卸载 GlusterFS 卷的原生程序。
|
||||
|
||||
- [Storage for Containers Overview – Part I](https://keithtenzer.com/2017/03/07/storage-for-containers-overview-part-i/)
|
||||
- [Storage for Containers using Gluster – Part II](https://keithtenzer.com/2017/03/24/storage-for-containers-using-gluster-part-ii/)
|
||||
- [Storage for Containers using Container Native Storage – Part III](https://keithtenzer.com/2017/03/29/storage-for-containers-using-container-native-storage-part-iii/)
|
||||
- [Storage for Containers using Ceph – Part IV](https://keithtenzer.com/2017/04/07/storage-for-containers-using-ceph-rbd-part-iv/)
|
||||
- [Storage for Containers using NetApp ONTAP NAS – Part V](https://keithtenzer.com/2017/04/05/storage-for-containers-using-netapp-ontap-nas-part-v/)
|
||||
- [Storage for Containers using NetApp SolidFire – Part VI](https://keithtenzer.com/2017/04/05/storage-for-containers-using-netapp-solidfire-part-vi/)
|
||||
### CRS 概述
|
||||
|
||||
### Gluster作为Container-Ready Storage(CRS)
|
||||
在存储方面,根据 OpenShift / Kubernetes 的要求,还有一个额外的组件管理集群,称为 “heketi”。 这实际上是一个用于 GlusterFS 的 REST API,它还提供 CLI 版本。 在以下步骤中,我们将在 3 个 GlusterFS 节点中部署 heketi,使用它来部署 GlusterFS 存储池,将其连接到 OpenShift,并使用它来通过 PersistentVolumeClaims 为容器配置存储。 我们将总共部署 4 台虚拟机。 一个用于 OpenShift(实验室设置),另一个用于 GlusterFS。
|
||||
|
||||
在本文中,我们将介绍容器存储的首选以及如何部署它。 Kusternet和OpenShift支持GlusterFS已经有一段时间了。 GlusterFS的适用性很好,可用于所有的部署场景:裸机、虚拟机、内部部署和公共云。 在容器中运行GlusterFS的新特性将在本系列后面讨论。
|
||||
注意:您的系统应至少需要有四核 CPU,16GB RAM 和 20 GB 可用磁盘空间。
|
||||
|
||||
GlusterFS是一个分布式文件系统,内置了原生协议(GlusterFS)和各种其他协议(NFS,SMB,...)。 为了与OpenShift集成,节点将通过FUSE使用原生协议,将GlusterFS卷挂在到节点本身上,然后将它们绑定到目标容器中。 OpenShift / Kubernetes具有实现请求、释放和挂载、卸载GlusterFS卷的原生程序。
|
||||
### 部署 OpenShift
|
||||
|
||||
### CRS概述
|
||||
首先你需要先部署 OpenShift。最有效率的方式是直接在虚拟机中部署一个 All-in-One 环境,部署指南见 [the “OpenShift Enterprise 3.4 all-in-one Lab Environment” article.](https://keithtenzer.com/2017/03/13/openshift-enterprise-3-4-all-in-one-lab-environment/)。
|
||||
|
||||
在存储方面,根据OpenShift / Kubernetes的要求,还有一个额外的组件管理集群,称为“heketi”。 这实际上是一个用于GlusterFS的REST API,它还提供CLI版本。 在以下步骤中,我们将在3个GlusterFS节点中部署heketi,使用它来部署GlusterFS存储池,将其连接到OpenShift,并使用它来通过PersistentVolumeClaims为容器配置存储。 我们将总共部署4台虚拟机。 一个用于OpenShift(实验室设置),另一个用于GlusterFS。
|
||||
|
||||
注意:您的系统应至少需要有四核CPU,16GB RAM和20 GB可用磁盘空间。
|
||||
|
||||
### 部署OpenShift
|
||||
|
||||
首先你需要先部署OpenShift。最有效率的方式是直接在虚拟机中部署一个All-in-One环境,部署指南见 [the “OpenShift Enterprise 3.4 all-in-one Lab Environment” article.](https://keithtenzer.com/2017/03/13/openshift-enterprise-3-4-all-in-one-lab-environment/)。
|
||||
|
||||
确保你的OpenShift虚拟机可以解析外部域名。编辑`/etc/dnsmasq.conf`文件,增加下面的Google DNS:
|
||||
确保你的 OpenShift 虚拟机可以解析外部域名。编辑 `/etc/dnsmasq.conf` 文件,增加下面的 Google DNS:
|
||||
|
||||
```ini
|
||||
server=8.8.8.8
|
||||
|
@ -40,17 +27,17 @@ server=8.8.8.8
|
|||
# ping -c1 google.com
|
||||
```
|
||||
|
||||
### 部署Gluster
|
||||
### 部署 Gluster
|
||||
|
||||
GlusterFS至少需要有以下配置的3台虚拟机:
|
||||
GlusterFS 至少需要有以下配置的 3 台虚拟机:
|
||||
|
||||
- RHEL 7.3
|
||||
- 2 CPUs
|
||||
- 2 GB内存
|
||||
- 30 GB磁盘存储给操作系统
|
||||
- 10 GB磁盘存储给GlusterFS bricks
|
||||
- 2 GB 内存
|
||||
- 30 GB 磁盘存储给操作系统
|
||||
- 10 GB 磁盘存储给 GlusterFS bricks
|
||||
|
||||
修改/etc/hosts文件,定义三台虚拟机的主机名。
|
||||
修改 /etc/hosts 文件,定义三台虚拟机的主机名。
|
||||
|
||||
例如(主机名可以根据你自己的环境自由调整)
|
||||
|
||||
|
@ -64,23 +51,23 @@ GlusterFS至少需要有以下配置的3台虚拟机:
|
|||
172.16.128.9 crs-node3.lab crs-node3
|
||||
```
|
||||
|
||||
**在3台GlusterFS虚拟机上都执行以下步骤**:
|
||||
**在 3 台 GlusterFS 虚拟机上都执行以下步骤**:
|
||||
|
||||
```bash
|
||||
# subscription-manager repos --disable="*"
|
||||
# subscription-manager repos --enable=rhel-7-server-rpms
|
||||
```
|
||||
|
||||
如果你已经订阅了GlusterFS那么可以直接使用,开启`rh-gluster-3-for-rhel-7-server-rpms`的yum源。
|
||||
如果你已经订阅了 GlusterFS 那么可以直接使用,开启 `rh-gluster-3-for-rhel-7-server-rpms` 的 yum 源。
|
||||
|
||||
如果你没有的话,那么可以通过EPEL使用非官方支持的GlusterFS的社区源。
|
||||
如果你没有的话,那么可以通过 EPEL 使用非官方支持的 GlusterFS 的社区源。
|
||||
|
||||
```bash
|
||||
# yum -y install http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
|
||||
# rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
|
||||
```
|
||||
|
||||
在`/etc/yum.repos.d/`目录下创建`glusterfs-3.10.repo`文件:
|
||||
在 `/etc/yum.repos.d/` 目录下创建 `glusterfs-3.10.repo` 文件:
|
||||
|
||||
```ini
|
||||
[glusterfs-3.10]
|
||||
|
@ -97,37 +84,37 @@ enabled=1
|
|||
# yum repolist
|
||||
```
|
||||
|
||||
现在可以开始安装GlusterFS了。
|
||||
现在可以开始安装 GlusterFS 了。
|
||||
|
||||
```bash
|
||||
# yum -y install glusterfs-server
|
||||
```
|
||||
|
||||
需要为GlusterFS peers打开几个基本TCP端口,以便与OpenShift进行通信并提供存储:
|
||||
需要为 GlusterFS peers 打开几个基本 TCP 端口,以便与 OpenShift 进行通信并提供存储:
|
||||
|
||||
```bash
|
||||
# firewall-cmd --add-port=24007-24008/tcp --add-port=49152-49664/tcp --add-port=2222/tcp
|
||||
# firewall-cmd --runtime-to-permanent
|
||||
```
|
||||
|
||||
现在我们可以启动GlusterFS的daemon进程了:
|
||||
现在我们可以启动 GlusterFS 的 daemon 进程了:
|
||||
|
||||
```bash
|
||||
# systemctl enable glusterd
|
||||
# systemctl start glusterd
|
||||
```
|
||||
|
||||
完成。GlusterFS已经启动并正在运行。其他配置将通过heketi完成。
|
||||
完成。GlusterFS 已经启动并正在运行。其他配置将通过 heketi 完成。
|
||||
|
||||
**在GlusterFS的一台虚拟机上安装heketi**
|
||||
**在 GlusterFS 的一台虚拟机上安装 heketi**
|
||||
|
||||
```bash
|
||||
[root@crs-node1 ~]# yum -y install heketi heketi-client
|
||||
```
|
||||
|
||||
### 更新EPEL
|
||||
### 更新 EPEL
|
||||
|
||||
如果你没有Red Hat Gluster Storage订阅的话,你可以从EPEL中获取heketi。 在撰写本文时,2016年10月那时候还是3.0.0-1.el7版本,它不适用于OpenShift 3.4。 你将需要更新到更新的版本:
|
||||
如果你没有 Red Hat Gluster Storage 订阅的话,你可以从 EPEL 中获取 heketi。 在撰写本文时,2016 年 10 月那时候还是 3.0.0-1.el7 版本,它不适用于 OpenShift 3.4。 你将需要更新到更新的版本:
|
||||
|
||||
```bash
|
||||
[root@crs-node1 ~]# yum -y install wget
|
||||
|
@ -138,7 +125,7 @@ enabled=1
|
|||
[root@crs-node1 ~]# chown heketi:heketi /usr/bin/heketi*
|
||||
```
|
||||
|
||||
在`/etc/systemd/system/heketi.service`中创建v4版本的heketi二进制文件的更新语法文件:
|
||||
在 `/etc/systemd/system/heketi.service` 中创建 v4 版本的 heketi 二进制文件的更新语法文件:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
|
@ -156,14 +143,11 @@ StandardError=syslog
|
|||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
[root@crs-node1 ~]# systemctl daemon-reload
|
||||
[root@crs-node1 ~]# systemctl start heketi
|
||||
```
|
||||
|
||||
Heketi使用SSH来配置GlusterFS的所有节点。创建SSH密钥对,将公钥拷贝到所有3个节点上(包括你登陆的第一个节点):
|
||||
Heketi 使用 SSH 来配置 GlusterFS 的所有节点。创建 SSH 密钥对,将公钥拷贝到所有 3 个节点上(包括你登陆的第一个节点):
|
||||
|
||||
```bash
|
||||
[root@crs-node1 ~]# ssh-keygen -f /etc/heketi/heketi_key -t rsa -N ''
|
||||
|
@ -173,7 +157,7 @@ Heketi使用SSH来配置GlusterFS的所有节点。创建SSH密钥对,将公
|
|||
[root@crs-node1 ~]# chown heketi:heketi /etc/heketi/heketi_key*
|
||||
```
|
||||
|
||||
剩下唯一要做的事情就是配置heketi来使用SSH。 编辑`/etc/heketi/heketi.json`文件使它看起来像下面这个样子(改变的部分突出显示下划线):
|
||||
剩下唯一要做的事情就是配置 heketi 来使用 SSH。 编辑 `/etc/heketi/heketi.json` 文件使它看起来像下面这个样子(改变的部分突出显示下划线):
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -233,14 +217,14 @@ Heketi使用SSH来配置GlusterFS的所有节点。创建SSH密钥对,将公
|
|||
}
|
||||
```
|
||||
|
||||
完成。heketi将监听8080端口,我们来确认下防火墙规则允许它监听该端口:
|
||||
完成。heketi 将监听 8080 端口,我们来确认下防火墙规则允许它监听该端口:
|
||||
|
||||
```bash
|
||||
# firewall-cmd --add-port=8080/tcp
|
||||
# firewall-cmd --runtime-to-permanent
|
||||
```
|
||||
|
||||
重启heketi:
|
||||
重启 heketi:
|
||||
|
||||
```bash
|
||||
# systemctl enable heketi
|
||||
|
@ -254,7 +238,7 @@ Heketi使用SSH来配置GlusterFS的所有节点。创建SSH密钥对,将公
|
|||
Hello from Heketi
|
||||
```
|
||||
|
||||
很好。heketi上场的时候到了。 我们将使用它来配置我们的GlusterFS存储池。 该软件已经在我们所有的虚拟机上运行,但并未被配置。 要将其改造为满足我们需求的存储系统,需要在拓扑文件中描述我们所需的GlusterFS存储池,如下所示:
|
||||
很好。heketi 上场的时候到了。 我们将使用它来配置我们的 GlusterFS 存储池。 该软件已经在我们所有的虚拟机上运行,但并未被配置。 要将其改造为满足我们需求的存储系统,需要在拓扑文件中描述我们所需的 GlusterFS 存储池,如下所示:
|
||||
|
||||
```bash
|
||||
# vi topology.json
|
||||
|
@ -316,9 +300,9 @@ Hello from Heketi
|
|||
}
|
||||
```
|
||||
|
||||
该文件格式比较简单,基本上是告诉heketi要创建一个3节点的集群,其中每个节点包含的配置有FQDN,IP地址以及至少一个将用作GlusterFS块的备用块设备。
|
||||
该文件格式比较简单,基本上是告诉 heketi 要创建一个 3 节点的集群,其中每个节点包含的配置有 FQDN,IP 地址以及至少一个将用作 GlusterFS 块的备用块设备。
|
||||
|
||||
现在将该文件发送给heketi:
|
||||
现在将该文件发送给 heketi:
|
||||
|
||||
```bash
|
||||
# export HEKETI_CLI_SERVER=http://crs-node1.lab:8080
|
||||
|
@ -332,7 +316,7 @@ Creating cluster ... ID: 78cdb57aa362f5284bc95b2549bc7e7d
|
|||
Adding device /dev/sdb ... OK
|
||||
```
|
||||
|
||||
现在heketi已经配置了3个节点的GlusterFS存储池。很简单!你现在可以看到3个虚拟机都已经成功构成了GlusterFS中的可信存储池(Trusted Stroage Pool)。
|
||||
现在 heketi 已经配置了 3 个节点的 GlusterFS 存储池。很简单!你现在可以看到 3 个虚拟机都已经成功构成了 GlusterFS 中的可信存储池(Trusted Stroage Pool)。
|
||||
|
||||
```bash
|
||||
[root@crs-node1 ~]# gluster peer status
|
||||
|
@ -349,13 +333,13 @@ Uuid: e3c1f9b0-be97-42e5-beda-f70fc05f47ea
|
|||
State: Peer in Cluster (Connected)
|
||||
```
|
||||
|
||||
现在回到OpenShift!
|
||||
现在回到 OpenShift!
|
||||
|
||||
### 将Gluster与OpenShift集成
|
||||
### 将 Gluster 与 OpenShift 集成
|
||||
|
||||
为了集成OpenShift,需要两样东西:一个动态的Kubernetes Storage Provisioner和一个StorageClass。 Provisioner在OpenShift中开箱即用。 实际上关键的是如何将存储挂载到容器上。 StorageClass是OpenShift中的用户可以用来实现的PersistentVolumeClaims的实体,它反过来能够触发一个Provisioner实现实际的配置,并将结果表示为Kubernetes PersistentVolume(PV)。
|
||||
为了集成 OpenShift,需要两样东西:一个动态的 Kubernetes Storage Provisioner 和一个 StorageClass。 Provisioner 在 OpenShift 中开箱即用。 实际上关键的是如何将存储挂载到容器上。 StorageClass 是 OpenShift 中的用户可以用来实现的 PersistentVolumeClaims 的实体,它反过来能够触发一个 Provisioner 实现实际的配置,并将结果表示为 Kubernetes PersistentVolume(PV)。
|
||||
|
||||
就像OpenShift中的其他组件一样,StorageClass也简单的用YAML文件定义:
|
||||
就像 OpenShift 中的其他组件一样,StorageClass 也简单的用 YAML 文件定义:
|
||||
|
||||
```bash
|
||||
# cat crs-storageclass.yaml
|
||||
|
@ -371,23 +355,23 @@ parameters:
|
|||
restauthenabled: "false"
|
||||
```
|
||||
|
||||
我们的provisioner是kubernetes.io/glusterfs,将它指向我们的heketi实例。 我们将类命名为“container-ready-storage”,同时使其成为所有没有显示指定StorageClass的PersistentVolumeClaim的默认StorageClass。
|
||||
我们的 provisioner 是 kubernetes.io/glusterfs,将它指向我们的 heketi 实例。 我们将类命名为 “container-ready-storage”,同时使其成为所有没有显示指定 StorageClass 的 PersistentVolumeClaim 的默认 StorageClass。
|
||||
|
||||
为你的GlusterFS池创建StorageClass:
|
||||
为你的 GlusterFS 池创建 StorageClass:
|
||||
|
||||
```bash
|
||||
# oc create -f crs-storageclass.yaml
|
||||
```
|
||||
|
||||
### 在OpenShift中使用Gluster
|
||||
### 在 OpenShift 中使用 Gluster
|
||||
|
||||
我们来看下如何在OpenShift中使用GlusterFS。首先在OpenShift虚拟机中创建一个测试项目。
|
||||
我们来看下如何在 OpenShift 中使用 GlusterFS。首先在 OpenShift 虚拟机中创建一个测试项目。
|
||||
|
||||
```bash
|
||||
# oc new-project crs-storage --display-name="Container-Ready Storage"
|
||||
```
|
||||
|
||||
这会向Kubernetes/OpenShift发出storage请求,请求一个PersistentVolumeClaim(PVC)。 这是一个简单的对象,它描述最少需要多少容量和应该提供哪种访问模式(非共享,共享,只读)。 它通常是应用程序模板的一部分,但我们只需创建一个独立的PVC:
|
||||
这会向 Kubernetes/OpenShift 发出 storage 请求,请求一个 PersistentVolumeClaim(PVC)。 这是一个简单的对象,它描述最少需要多少容量和应该提供哪种访问模式(非共享,共享,只读)。 它通常是应用程序模板的一部分,但我们只需创建一个独立的 PVC:
|
||||
|
||||
```bash
|
||||
# cat crs-claim.yaml
|
||||
|
@ -410,7 +394,7 @@ spec:
|
|||
# oc create -f crs-claim.yaml
|
||||
```
|
||||
|
||||
观察在OpenShfit中,PVC正在以动态创建volume的方式实现:
|
||||
观察在 OpenShfit 中,PVC 正在以动态创建 volume 的方式实现:
|
||||
|
||||
```bash
|
||||
# oc get pvc
|
||||
|
@ -418,31 +402,29 @@ NAME STATUS VOLUME CAPACITY
|
|||
my-crs-storage Bound pvc-41ad5adb-107c-11e7-afae-000c2949cce7 1Gi RWO 58s
|
||||
```
|
||||
|
||||
太棒了! 你现在可以在OpenShift中使用存储容量,而不需要直接与存储系统进行任何交互。 我们来看看创建的volume:
|
||||
太棒了! 你现在可以在 OpenShift 中使用存储容量,而不需要直接与存储系统进行任何交互。 我们来看看创建的 volume:
|
||||
|
||||
```bash
|
||||
# oc get pv/pvc-41ad5adb-107c-11e7-afae-000c2949cce7
|
||||
Name: pvc-41ad5adb-107c-11e7-afae-000c2949cce7
|
||||
Labels:
|
||||
StorageClass: container-ready-storage
|
||||
Status: Bound
|
||||
Claim: crs-storage/my-crs-storage
|
||||
Reclaim Policy: Delete
|
||||
Access Modes: RWO
|
||||
Capacity: 1Gi
|
||||
Name: pvc-41ad5adb-107c-11e7-afae-000c2949cce7
|
||||
Labels:
|
||||
StorageClass: container-ready-storage
|
||||
Status: Bound
|
||||
Claim: crs-storage/my-crs-storage
|
||||
Reclaim Policy: Delete
|
||||
Access Modes: RWO
|
||||
Capacity: 1Gi
|
||||
Message:
|
||||
Source:
|
||||
Type: Glusterfs (a Glusterfs mount on the host that shares a pod's lifetime)
|
||||
EndpointsName: gluster-dynamic-my-crs-storage
|
||||
Path: vol_85e444ee3bc154de084976a9aef16025
|
||||
ReadOnly: false
|
||||
Type: Glusterfs (a Glusterfs mount on the host that shares a pod's lifetime)
|
||||
EndpointsName: gluster-dynamic-my-crs-storage
|
||||
Path: vol_85e444ee3bc154de084976a9aef16025
|
||||
ReadOnly: false
|
||||
```
|
||||
|
||||
What happened in the background was that when the PVC reached the system, our default StorageClass reached out to the GlusterFS Provisioner with the volume specs from the PVC. The provisioner in turn communicates with our heketi instance which facilitates the creation of the GlusterFS volume, which we can trace in it’s log messages:
|
||||
该 volume 是根据 PVC 中的定义特别创建的。 在 PVC 中,我们没有明确指定要使用哪个 StorageClass,因为 heketi 的 GlusterFS StorageClass 已经被定义为系统范围的默认值。
|
||||
|
||||
该volume是根据PVC中的定义特别创建的。 在PVC中,我们没有明确指定要使用哪个StorageClass,因为heketi的GlusterFS StorageClass已经被定义为系统范围的默认值。
|
||||
|
||||
在后台发生的情况是,当PVC到达系统时,默认的StorageClass请求具有该PVC中volume声明规格的GlusterFS Provisioner。 Provisioner又与我们的heketi实例通信,这有助于创建GlusterFS volume,我们可以在其日志消息中追踪:
|
||||
在后台发生的情况是,当 PVC 到达系统时,默认的 StorageClass 请求具有该 PVC 中 volume 声明规格的 GlusterFS Provisioner。 Provisioner 又与我们的 heketi 实例通信,这有助于创建 GlusterFS volume,我们可以在其日志消息中追踪:
|
||||
|
||||
```bash
|
||||
[root@crs-node1 ~]# journalctl -l -u heketi.service
|
||||
|
@ -462,9 +444,9 @@ Mar 24 11:25:55 crs-node1.lab heketi[2598]: [asynchttp] INFO 2017/03/24 11:25:55
|
|||
...
|
||||
```
|
||||
|
||||
成功! 大约用了3秒钟,GlusterFS池就配置完成了,并配置了一个volume。 默认值是replica 3,这意味着数据将被复制到3个不同节点的3个块上(用GlusterFS作为后端存储)。 该过程是通过Heketi在OpenShift进行编排的。
|
||||
成功! 大约用了 3 秒钟,GlusterFS 池就配置完成了,并配置了一个 volume。 默认值是 replica 3,这意味着数据将被复制到 3 个不同节点的 3 个块上(用 GlusterFS 作为后端存储)。 该过程是通过 Heketi 在 OpenShift 进行编排的。
|
||||
|
||||
你也可以从GlusterFS的角度看到有关volume的信息:
|
||||
你也可以从 GlusterFS 的角度看到有关 volume 的信息:
|
||||
|
||||
```bash
|
||||
[root@crs-node1 ~]# gluster volume list
|
||||
|
@ -487,31 +469,31 @@ transport.address-family: inet
|
|||
nfs.disable: on
|
||||
```
|
||||
|
||||
请注意,GlusterFS中的卷名称如何对应于OpenShift中Kubernetes Persistent Volume的“路径”。
|
||||
请注意,GlusterFS 中的卷名称如何对应于 OpenShift 中 Kubernetes Persistent Volume 的 “路径”。
|
||||
|
||||
或者,你也可以使用OpenShift UI来配置存储,这样可以很方便地在系统中的所有已知的StorageClasses中进行选择:
|
||||
或者,你也可以使用 OpenShift UI 来配置存储,这样可以很方便地在系统中的所有已知的 StorageClasses 中进行选择:
|
||||
|
||||
![创建存储](../images/create-gluster-storage.png)
|
||||
|
||||
![Screen Shot 2017-03-24 at 11.09.34.png](https://keithtenzer.files.wordpress.com/2017/03/screen-shot-2017-03-24-at-11-09-341.png?w=440)
|
||||
![容器存储](../images/container-storage.png)
|
||||
|
||||
让我们做点更有趣的事情,在OpenShift中运行工作负载。
|
||||
让我们做点更有趣的事情,在 OpenShift 中运行工作负载。
|
||||
|
||||
在仍运行着crs-storage项目的OpenShift虚拟机中执行:
|
||||
在仍运行着 crs-storage 项目的 OpenShift 虚拟机中执行:
|
||||
|
||||
```bash
|
||||
# oc get templates -n openshift
|
||||
```
|
||||
|
||||
你应该可以看到一个应用程序和数据库模板列表,这个列表将方便你更轻松的使用OpenShift来部署你的应用程序项目。
|
||||
你应该可以看到一个应用程序和数据库模板列表,这个列表将方便你更轻松的使用 OpenShift 来部署你的应用程序项目。
|
||||
|
||||
我们将使用MySQL来演示如何在OpenShift上部署具有持久化和弹性存储的有状态应用程序。 Mysql-persistent模板包含一个用于MySQL数据库目录的1G空间的PVC。 为了演示目的,可以直接使用默认值。
|
||||
我们将使用 MySQL 来演示如何在 OpenShift 上部署具有持久化和弹性存储的有状态应用程序。 Mysql-persistent 模板包含一个用于 MySQL 数据库目录的 1G 空间的 PVC。 为了演示目的,可以直接使用默认值。
|
||||
|
||||
```bash
|
||||
# oc process mysql-persistent -n openshift | oc create -f -
|
||||
```
|
||||
|
||||
等待部署完成。你可以通过UI或者命令行观察部署进度:
|
||||
等待部署完成。你可以通过 UI 或者命令行观察部署进度:
|
||||
|
||||
```bash
|
||||
# oc get pods
|
||||
|
@ -519,19 +501,19 @@ NAME READY STATUS RESTARTS AGE
|
|||
mysql-1-h4afb 1/1 Running 0 2m
|
||||
```
|
||||
|
||||
好了。我们已经使用这个模板创建了一个service,secrets、PVC和pod。我们来使用它(你的pod名字将跟我的不同):
|
||||
好了。我们已经使用这个模板创建了一个 service,secrets、PVC 和 pod。我们来使用它(你的 pod 名字将跟我的不同):
|
||||
|
||||
```bash
|
||||
# oc rsh mysql-1-h4afb
|
||||
```
|
||||
|
||||
你已经成功的将它挂载到MySQL的pod上。我们连接一下数据库试试:
|
||||
你已经成功的将它挂载到 MySQL 的 pod 上。我们连接一下数据库试试:
|
||||
|
||||
```bash
|
||||
sh-4.2$ mysql -u $MYSQL_USER -p$MYSQL_PASSWORD -h $HOSTNAME $MYSQL_DATABASE
|
||||
```
|
||||
|
||||
这点很方便,所有重要的配置,如MySQL凭据,数据库名称等都是pod模板中的环境变量的一部分,因此可以在pod中作为shell的环境变量。 我们来创建一些数据:
|
||||
这点很方便,所有重要的配置,如 MySQL 凭据,数据库名称等都是 pod 模板中的环境变量的一部分,因此可以在 pod 中作为 shell 的环境变量。 我们来创建一些数据:
|
||||
|
||||
```bash
|
||||
mysql> show databases;
|
||||
|
@ -572,30 +554,30 @@ mysql> SELECT * FROM equipment;
|
|||
|
||||
很好,数据库运行正常。
|
||||
|
||||
你想看下数据存储在哪里吗?很简单!查看刚使用模板创建的mysql volume:
|
||||
你想看下数据存储在哪里吗?很简单!查看刚使用模板创建的 mysql volume:
|
||||
|
||||
```bash
|
||||
# oc get pvc/mysql
|
||||
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
|
||||
mysql Bound pvc-a678b583-1082-11e7-afae-000c2949cce7 1Gi RWO 11m
|
||||
# oc describe pv/pvc-a678b583-1082-11e7-afae-000c2949cce7
|
||||
Name: pvc-a678b583-1082-11e7-afae-000c2949cce7
|
||||
Labels:
|
||||
StorageClass: container-ready-storage
|
||||
Status: Bound
|
||||
Claim: crs-storage/mysql
|
||||
Reclaim Policy: Delete
|
||||
Access Modes: RWO
|
||||
Capacity: 1Gi
|
||||
Name: pvc-a678b583-1082-11e7-afae-000c2949cce7
|
||||
Labels:
|
||||
StorageClass: container-ready-storage
|
||||
Status: Bound
|
||||
Claim: crs-storage/mysql
|
||||
Reclaim Policy: Delete
|
||||
Access Modes: RWO
|
||||
Capacity: 1Gi
|
||||
Message:
|
||||
Source:
|
||||
Type: Glusterfs (a Glusterfs mount on the host that shares a pod's lifetime)
|
||||
EndpointsName: gluster-dynamic-mysql
|
||||
Path: vol_6299fc74eee513119dafd43f8a438db1
|
||||
ReadOnly: false
|
||||
Type: Glusterfs (a Glusterfs mount on the host that shares a pod's lifetime)
|
||||
EndpointsName: gluster-dynamic-mysql
|
||||
Path: vol_6299fc74eee513119dafd43f8a438db1
|
||||
ReadOnly: false
|
||||
```
|
||||
|
||||
GlusterFS的volume名字是vol_6299fc74eee513119dafd43f8a438db1。回到你的GlusterFS虚拟机中,输入:
|
||||
GlusterFS 的 volume 名字是 vol_6299fc74eee513119dafd43f8a438db1。回到你的 GlusterFS 虚拟机中,输入:
|
||||
|
||||
```bash
|
||||
# gluster volume info vol_6299fc74eee513119dafd43f8a438db
|
||||
|
@ -616,7 +598,7 @@ transport.address-family: inet
|
|||
nfs.disable: on
|
||||
```
|
||||
|
||||
你可以看到数据是如何被复制到3个GlusterFS块的。我们从中挑一个(最好挑选你刚登陆的那台虚拟机并查看目录):
|
||||
你可以看到数据是如何被复制到 3 个 GlusterFS 块的。我们从中挑一个(最好挑选你刚登陆的那台虚拟机并查看目录):
|
||||
|
||||
```bash
|
||||
# ll /var/lib/heketi/mounts/vg_67314f879686de975f9b8936ae43c5c5/brick_f264a47aa32be5d595f83477572becf8/brick
|
||||
|
@ -642,18 +624,16 @@ drwxr-s---. 2 1000070000 2001 62 Mar 24 12:20 sampledb
|
|||
drwxr-s---. 2 1000070000 2001 8192 Mar 24 12:12 sys
|
||||
```
|
||||
|
||||
你可以在这里看到MySQL数据库目录。 它使用GlusterFS作为后端存储,并作为绑定挂载给MySQL容器使用。 如果你检查OpenShift VM上的mount表,你将会看到GlusterFS的mount。
|
||||
你可以在这里看到 MySQL 数据库目录。 它使用 GlusterFS 作为后端存储,并作为绑定挂载给 MySQL 容器使用。 如果你检查 OpenShift VM 上的 mount 表,你将会看到 GlusterFS 的 mount。
|
||||
|
||||
### 总结
|
||||
|
||||
在这里我们是在OpenShift之外创建了一个简单但功能强大的GlusterFS存储池。 该池可以独立于应用程序扩展和收缩。 该池的整个生命周期由一个简单的称为heketi的前端管理,你只需要在部署增长时进行手动干预。 对于日常配置操作,使用它的API与OpenShifts动态配置器交互,无需开发人员直接与基础架构团队进行交互。
|
||||
在这里我们是在 OpenShift 之外创建了一个简单但功能强大的 GlusterFS 存储池。 该池可以独立于应用程序扩展和收缩。 该池的整个生命周期由一个简单的称为 heketi 的前端管理,你只需要在部署增长时进行手动干预。 对于日常配置操作,使用它的 API 与 OpenShifts 动态配置器交互,无需开发人员直接与基础架构团队进行交互。
|
||||
|
||||
o这就是我们如何将存储带入DevOps世界 - 无痛苦,并在OpenShift PaaS系统的开发人员工具中直接提供。
|
||||
o 这就是我们如何将存储带入 DevOps 世界 - 无痛苦,并在 OpenShift PaaS 系统的开发人员工具中直接提供。
|
||||
|
||||
GlusterFS和OpenShift可跨越所有环境:裸机,虚拟机,私有和公共云(Azure,Google Cloud,AWS ...),确保应用程序可移植性,并避免云供应商锁定。
|
||||
GlusterFS 和 OpenShift 可跨越所有环境:裸机,虚拟机,私有和公共云(Azure,Google Cloud,AWS ...),确保应用程序可移植性,并避免云供应商锁定。
|
||||
|
||||
祝你愉快在容器中使用GlusterFS!
|
||||
---
|
||||
|
||||
(c) 2017 Keith Tenzer
|
||||
|
||||
原文链接:https://keithtenzer.com/2017/03/24/storage-for-containers-using-gluster-part-ii/
|
||||
本文由译自 Daniel Messer(Technical Marketing Manager Storage @RedHat)和Keith Tenzer(Solutions Architect @RedHat)共同撰写文章,原文已无法访问。
|
||||
|
|
|
@ -19,11 +19,11 @@ Envoy 官方提供了以下打包用例:
|
|||
- [Jaeger Tracing](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/jaeger_tracing)
|
||||
- [gRPC Bridge](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/grpc_bridge)
|
||||
|
||||
全部可以使用 `docker-compose` 运行,代码可以在 https://github.com/envoyproxy/envoy/tree/master/examples 找到。
|
||||
全部可以使用 `docker-compose` 运行,代码可以在 [GitHub](https://github.com/envoyproxy/envoy/tree/master/examples) 找到。
|
||||
|
||||
## Front proxy
|
||||
|
||||
Envoy 在 envoymesh 的边缘做反向代理,详细使用方式见 <https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/front_proxy>,在此我将解说下以下问题:
|
||||
Envoy 在 Envoy mesh 的边缘做反向代理,详细使用方式见 [Envoy 文档](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/front_proxy),在此我将解说下以下问题:
|
||||
|
||||
- Envoy 是如何作为进程外架构运行的?
|
||||
- 为何说 Envoy 是无侵入式架构?
|
||||
|
@ -292,8 +292,8 @@ Hello from behind Envoy (service 1)! hostname: c5b9f1289e0f resolvedhostname: 17
|
|||
| /stats | 打印服务器状态统计信息 |
|
||||
| /stats/prometheus | 打印 prometheus 格式的服务器状态统计信息 |
|
||||
|
||||
Envoy 提供了 API 管理端点,可以对 Envoy 进行动态配置,参考 [v2 API reference](https://www.envoyproxy.io/docs/envoy/latest/api-v2/api)。
|
||||
Envoy 提供了 API 管理端点,可以对 Envoy 进行动态配置。
|
||||
|
||||
## 参考
|
||||
|
||||
- [Front proxy](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/front_proxy)
|
||||
- [Front proxy - envoyproxy.io](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/front_proxy)
|
||||
|
|
|
@ -32,7 +32,7 @@ Istio 社区和 [Tetrate](https://www.tetrate.io/) 在 Istio 对虚拟机的支
|
|||
|
||||
## Demo
|
||||
|
||||
在下面这个 demo 中我们将使在 GKE 中部署 Istio 并运行 bookinfo 示例,其中 ratings 服务的后端使用的是部署在虚拟机上的 MySQL,该示例可以在 [Istio 官方文档](https://istio.io/latest/docs/examples/virtual-machines/bookinfo/)中找到,我作出了部分改动,最终的流量路由如下图所示。
|
||||
在下面这个 demo 中我们将使在 GKE 中部署 Istio 并运行 bookinfo 示例,其中 ratings 服务的后端使用的是部署在虚拟机上的 MySQL,流量路由如下图所示。
|
||||
|
||||
![Bookinfo 示例中的流量示意图](../images/istio-bookinfo-vm-traffic.jpg)
|
||||
|
||||
|
@ -56,6 +56,5 @@ Istio 社区和 [Tetrate](https://www.tetrate.io/) 在 Istio 对虚拟机的支
|
|||
## 参考阅读
|
||||
|
||||
- [Virtual Machine Installation - istio.io](https://istio.io/latest/docs/setup/install/virtual-machine/)
|
||||
- [Virtual Machines in Single-Network Meshes - istio.io](https://istio.io/latest/docs/examples/virtual-machines/single-network/)
|
||||
- [Istio: Bringing VMs into the Mesh (with Cynthia Coan) - tetrate.io](https://www.tetrate.io/blog/istio-bringing-vms-into-the-mesh-with-cynthia-coan/)
|
||||
- [Bridging Traditional and Modern Workloads - tetrate.io](https://www.tetrate.io/blog/bridging-traditional-and-modern-workloads/)
|
|
@ -1,4 +1,4 @@
|
|||
# Serverless架构
|
||||
# Serverless 架构
|
||||
|
||||
就像无线互联网实际有的地方也需要用到有线连接一样,无服务器架构仍然在某处有服务器。Serverless(无服务器架构)指的是由开发者实现的服务端逻辑运行在无状态的计算容器中,它由事件触发, 完全被第三方管理,其业务层面的状态则被开发者使用的数据库和存储资源所记录。
|
||||
|
||||
|
@ -36,7 +36,7 @@ Serverless架构明显比其他架构更简单。更少的组件,就意味着
|
|||
|
||||
按照《福布斯》杂志的统计,在商业和企业数据中心的典型服务器仅提供5%~15%的平均最大处理能力的输出。这无疑是一种资源的巨大浪费。随着Serverless架构的出现,让服务提供商提供我们的计算能力最大限度满足实时需求。这将使我们更有效地利用计算资源。
|
||||
|
||||
## Kubernetes上的serverless 架构
|
||||
## Kubernetes 上的 serverless 架构
|
||||
|
||||
目前已经有一批优秀的基于 kubernetes 的 serverless 架构(FaaS)开源项目如下:
|
||||
|
||||
|
@ -50,7 +50,7 @@ Serverless架构明显比其他架构更简单。更少的组件,就意味着
|
|||
- [kubeless](https://github.com/kubeless/kubeless) - Kubernetes Native Serverless Framework [http://kubeless.io](http://kubeless.io/)
|
||||
- [OpenWhisk](http://openwhisk.incubator.apache.org/) - Apache OpenWhisk (Incubating) is a serverless, open source cloud platform that executes functions in response to events at any scale.
|
||||
|
||||
以上项目收录于 [awsome-cloud-native](https://github.com/rootsongjc/awesome-cloud-native)。
|
||||
更多 Serverless 项目请见 [awsome-cloud-native](https://github.com/rootsongjc/awesome-cloud-native)。
|
||||
|
||||
## FaaS
|
||||
|
||||
|
@ -60,9 +60,8 @@ Function-as-a-Service景观图(图片来自`https://github.com/amyers1793/Func
|
|||
|
||||
## 参考
|
||||
|
||||
- [Why Serverless? - serverless.com](https://serverless.com/learn/)
|
||||
- [Serverless Architectures - Martin Fowler](https://martinfowler.com/articles/serverless.html)
|
||||
- [Serverless架构综述](http://dockone.io/article/1460)
|
||||
- [2017年会是Serverless爆发之年吗?](http://www.infoq.com/cn/news/2017/04/2017-Serverless)
|
||||
- [从IaaS到FaaS—— Serverless架构的前世今生](https://aws.amazon.com/cn/blogs/china/iaas-faas-serverless/)
|
||||
- [Introducing Redpoint's FaaS Landscape](https://medium.com/memory-leak/this-year-gartner-added-serverless-to-its-hype-cycle-of-emerging-technologies-reflecting-the-5dfe43d818f0)
|
||||
- [Serverless Architectures - martinfowler.com](https://martinfowler.com/articles/serverless.html)
|
||||
- [Serverless 架构综述 - dockone.io](http://dockone.io/article/1460)
|
||||
- [2017 年会是 Serverless 爆发之年吗?- infoq.cn](https://www.infoq.cn/news/2017/04/2017-Serverless/)
|
||||
- [从 IaaS 到 FaaS—— Serverless 架构的前世今生 - aws.amazon.com](https://aws.amazon.com/cn/blogs/china/iaas-faas-serverless/)
|
||||
- [Introducing Redpoint's FaaS Landscape - medium.com](https://medium.com/memory-leak/this-year-gartner-added-serverless-to-its-hype-cycle-of-emerging-technologies-reflecting-the-5dfe43d818f0)
|
||||
|
|
|
@ -9,13 +9,6 @@
|
|||
- Sidecar proxy 是如何做透明流量劫持的?
|
||||
- 流量是如何路由到 upstream 的?
|
||||
|
||||
在此之前我曾写过基于 Istio 1.1 版本的[理解 Istio Service Mesh 中 Envoy 代理 Sidecar 注入及流量劫持](/blog/envoy-sidecar-injection-in-istio-service-mesh-deep-dive/),Istio 1.5 与 Istio 1.1 中的 sidecar 注入和流量劫持环节最大的变化是:
|
||||
|
||||
- iptables 改用命令行工具,不再使用 shell 脚本。
|
||||
- sidecar inbound 和 outbound 分别指定了端口,而之前是使用同一个端口(15001)。
|
||||
|
||||
注:本文中部分内容收录于 ServiceMesher 社区出品的 [Istio Handbook](https://www.servicemesher.com/istio-handbook/)。
|
||||
|
||||
## Sidecar 模式
|
||||
|
||||
将应用程序的功能划分为单独的进程运行在同一个最小调度单元中(例如 Kubernetes 中的 Pod)可以被视为 **sidecar 模式**。如下图所示,sidecar 模式允许您在应用程序旁边添加更多功能,而无需额外第三方组件配置或修改应用程序代码。
|
||||
|
@ -402,8 +395,6 @@ Init 容器中使用的的 iptables 版本是 `v1.6.0`,共包含 5 张表:
|
|||
| POSTROUTING | | | ✓ | ✓ | |
|
||||
| FORWARD | ✓ | ✓ | | ✓ | ✓ |
|
||||
|
||||
关于 iptables 的详细介绍请参考[常见 iptables 使用规则场景整理](https://www.aliang.org/Linux/iptables.html)。
|
||||
|
||||
### 理解 iptables 规则
|
||||
|
||||
查看 `istio-proxy` 容器中的默认的 iptables 规则,默认查看的是 filter 表中的规则。
|
||||
|
@ -438,8 +429,6 @@ Chain OUTPUT (policy ACCEPT 18M packets, 1916M bytes)
|
|||
|
||||
还有一列没有表头,显示在最后,表示规则的选项,作为规则的扩展匹配条件,用来补充前面的几列中的配置。`prot`、`opt`、`in`、`out`、`source` 和 `destination` 和显示在 `destination` 后面的没有表头的一列扩展条件共同组成匹配规则。当流量匹配这些规则后就会执行 `target`。
|
||||
|
||||
关于 iptables 规则请参考[常见 iptables 使用规则场景整理](https://www.aliang.org/Linux/iptables.html)。
|
||||
|
||||
**target 支持的类型**
|
||||
|
||||
`target` 类型包括 ACCEPT`、REJECT`、`DROP`、`LOG` 、`SNAT`、`MASQUERADE`、`DNAT`、`REDIRECT`、`RETURN` 或者跳转到其他规则等。只要执行到某一条链中只有按照顺序有一条规则匹配后就可以确定报文的去向了,除了 `RETURN` 类型,类似编程语言中的 `return` 语句,返回到它的调用点,继续执行下一条规则。`target` 支持的配置详解请参考 [iptables 详解(1):iptables 概念](http://www.zsythink.net/archives/1199)。
|
||||
|
|
Loading…
Reference in New Issue