共计 4770 个字符,预计需要花费 12 分钟才能阅读完成。
今天就跟大家聊聊有关怎样体会 Kubernetes 内容器的高可用性和弹性伸缩,可能很多人都不太了解,为了让大家更加了解,丸趣 TV 小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
丸趣 TV 小编将会介绍如何在 Kubernetes 里运行这个 docker 镜像。
在 Kubernetes 上运行我们的应用,有什么收益?根据 Jerry 这十多天有限的时间里对 Kubernetes 的学习,我的理解是,Kubernetes 可以帮助应用开发人员确保其开发出的应用程序以一种高可用的、可伸缩和容错的方式进行部署和运行,应用开发人员无需花费大量时间和精力去学习 Kubernetes 底层细节。
换句话说,Kubernetes 环境的搭建,系统的配置,可以全部交给 Kubernetes 的管理员,而应用开发人员作为 Kubernetes 的消费者,只需要记住几个简单的 kubectl 命令,就能够轻松完成应用程序到 Kubernetes 上的部署,几乎不需付出额外的代价就能享受到 Kubernetes 作为一个平台给应用程序带来的上述非功能性的提升。
我们继续用前一篇文章使用到的 UI5 应用进行讲解。
Jerry 很穷,没有钱购买额外的服务器自己搭建 Kubernetes 集群环境。幸运的是,Kubernetes 并没有抛弃我们这些贫穷的程序员,我们还可以选择 Kubernetes Clusters as a Service 这种解决方案。
我在 SAP 内部的 Gardener 上创建一个基于 Google Cloud Platform 的 Kubernetes 集群,取名 jerry1204:
可以看到这个创建好的集群上的 Kubernetes 版本还是比较新的, 1.12.3 仅仅低于 12 月 3 日刚刚发布的 1.13 版。
点击上图 Access 标签页里的 Dashboard(控制台)超链接,即可对这个 Kubernetes 集群进行操作。当然像 SAP 上海研究院 Kubernetes 培训课程上讲课的那些老司机们更喜欢用命令行。
因为是免费的集群,只分配了一个工作节点:
控制台里看到的 Kubernetes 集群工作节点信息和命令行 kubectl get node -o wide 看到的一致:
Kubernetes 里的两个重要概念:pod 和 deployment
下面我们使用命令行来消费我们前一篇文章上传到 Docker Hub 上的镜像 i042416/ui5-nginx:
kubectl run jerry-ui5 –image=i042416/ui5-nginx
这个命令行背后发生了很多事情。
首先,运行在 Kubernetes 上的应用程序,其高可用性,可伸缩性和容错性到底是通过 Kubernetes 什么机制保证的?
答案是 pod。请单击上面 Kubernetes 的架构图,然后放大,能看到 node(节点)里包含了多个 pod,每个 pod 里又包含了多个容器。像它的中文含义 (豆荚,飞机,航天器或船只上可与主体分离的分离仓) 暗示的一样,pod 就是应用程序运行的载体,是 Kubernetes 的基本操作单元。整套 Kubernetes 系统的设计都是围绕着 pod 展开,例如 pod 的部署和运行,如何保证处于运行状态的 pod 总数量等于一个恒定值,如何将 pod 里应用提供的服务暴露给外部访问等等。
回到我们之前的命令行,我们试着执行另一个命令 kubectl get pod,果然发现了一个 pod 被创建出来,诞生已经 40 秒了(Age = 40s)。
用 describe 命令查看这个 pod 的明细:
kubectl describe pod jerry-ui5-6ffd46bb95-6bgpg
下图 Container ID 后面的 docker:// 说明这是一个 docker 容器,当然并不意味着 Kubernetes 只支持 Docker 这一种容器技术,比如 Kubernetes 还支持 CoreOS 的 Rocket。
describe 命名输出的 Events 区域揭示了一个 pod 从诞生到开始服役的生命周期状态跳转:
Scheduled- Pulling- Pulled- Created- Started
image.gif
从每个状态的 from 字段也能看出很多信息。
Scheduled 状态的 from: default-scheduler。Scheduler 是 Kubernetes 的组件之一,负责调度 pod 到合适的节点上。具体什么样的节点算合适,取决于 Kubernetes Scheduler 调度算法的实现,Jerry 没有研究过。如果把 Scheduler 看成一个黑匣子,那么它的输入是 pod 和由多个节点组成的列表,输出是 Pod 和一个匹配节点的绑定。这个状态 message 显示的内容 Successfully assigned XXX to shoot–jerrytest-jerry1204-worker-yamer-z1-XXX 后面这个 shoot–jerrytest 开头的字符串就是 pod 被分配到的节点的名称。
后面几个状态的 from 字段都是 kubelet,shoot–jerrytest-jerry1204-worker-yamer-z1-XXX,其中 kubelet 是 Kubernetes 节点上一个重要的模块,负责维护和管理运行于该节点上的所有容器,确保 pod 的运行状态与使用者期望一致。
在 Kubernetes web 控制台里也一样能看到这个处于运行状态的 pod:
除了 pod 之外,Kubernetes 第二个重要的概念就是 deployment。
执行另一个命令 kubectl get deploy,发现 kubectl run 命令除了生成一个 pod 外,还生成了一个 deployment。从这个命令输出的 Desired, Current 和 Up-to-Date, Available 下面的数字,结合前面提到的 Kubernetes 里几乎所有的设计都是围绕着 pod 来展开这一指导思想,我们不难猜测出,这个生成的 deployment 也是为 pod 服务的。
实际上,Kubernetes 的初学者可以把 deployment 的主要职责理解成是保证 pod 的数量和健康。
在前面的文章里,我们已经知道了怎样使用 docker run 启动一个 docker 镜像。然而在 Kubernetes 的世界里,我们不会直接和运行在 pod 里的 docker 容器打交道,而是通过 Kubernetes service 将 pod 里的应用提供的服务暴露给外界消费。
到目前为止,Kubernetes 集群上还没有任何和应用程序相关的 service 生成。命令 kubectl get svc 只返回了一个 Kubernetes 的标准服务。
因此我们使用命令 kubectl expose 基于刚刚使用 kubectl run 生成的 deployment 创建一个 service:
kubectl expose deployment jerry-ui5 –type=LoadBalancer –port=80 –target-port=80
image.gif
一旦 expose 命令执行后,get svc 命令这次就返回了一个和 deployment 同名的 service,暴露给外界访问的 IP 地址为 35.205.230.209:
于是,使用 url 35.205.230.209/webapp 就能访问运行在 Kubernetes pod 里的 SAP UI5 了:
Kubernetes 保证应用程序高可用性和伸缩性的一些体验
到目前为止我们的 SAP UI5 应用仅仅运行在 Kubernetes 集群上的一个工作节点的单个 pod 里,还没有感受到这个应用运行时的表现和之前运行在 Docker 容器里有什么差异。
我们现在就来尝试下 Kubernetes deployment 的水平扩展功能。在 Kubernetes 操作台里选中 deployment,从菜单里执行 Scale 命令,
设定新的 pod 的数量:下面截图的 3,意思是告诉这个 deployment,在命令执行完毕后,它必须要努力保证,在任何时候由它控制和监控的 pod 个数必须等于 3。
当然这个控制台上的图形菜单在命令行里也存在对应的命令,我们后面会用到。
上图 OK 按钮点击后,再次执行 kubectl get pod, 能观察到水平扩展执行之后,生成了两个新的 deployment,所以这次 get pod 命令总共返回了 3 个 pod,其中后两个 pod 从 Age 能看出是水平扩展执行之后刚刚创建的。
使用 kubectl describe 命令查看 deployment 的明细,在 Replicas 这个字段里看到这个 deployment 控制的 pod 的运行时明细:
3 desired | 3 updated | 3 total | 3 available | 0 unavailable
我们现在故意用 kubectl delete 删除一个 pod,再次查看,发生一个新的 pod 瞬间就自动生成了,处于运行状态的 pod 总数仍然为 3。
Kubernetes 滚动升级 (Rolling Update) 特性体验
滚动升级是 Kubernetes 一大特色,顾名思义,这是一种平滑过渡的升级方式,通过逐个容器替代升级的方式,来实现无中断的服务升级。下图 deployment 的 describe 命令的输出,其中字段 StrategyType 字段表明 kubectl run 创建的 deployment 默认的升级方式就是滚动升级。
我设计了这样一个简单的升级场景:我的 SAP UI5 应用 1.0 版本同时运行在一个 Kubernetes 节点的 10 个 pod 上。在整个应用不中断的前提下,通过滚动升级的方式升级到 2.0 版本。
由于上一篇文章我上传到 Docker Hub 上的镜像的标签为默认的 latest,所以我需要在 Docker Hub 上分别制造两个标签为 v1.0 和 v2.0 的镜像。
下面的命令行推送一个标签为 v1.0 的镜像到 Docker Hub:
修改 UI5 应用明细页面的标题,在文字后加上一个(v2.0), 用来表示这一版的应用为 2.0 版本:
同样将这个 2.0 版本的镜像推送到 Docker Hub 上:
Docker Hub 上两个版本的镜像都就绪了:
首先使用 1.0 版本的镜像,启动单个 pod 去执行 SAP UI5 应用:
kubectl run jerry-ui5 –image=i042416/ui5-nginx:v1.0
使用 scale 命令将单个 pod 水平扩展到 10 个 pod:
kubectl scale –replicas=10 deployment/jerry-ui5
上图看出 kubectl get pod 返回 10 个处于运行状态的 pod。
使用下面的命令触发滚动升级,把名为 jerry-ui5 的 deployent 基于的镜像从 v1.0 升级到 v2.0:
kubectl set image deployment/jerry-ui5 i042416/ui5-nginx=i042416/ui5-nginx:v2.0
使用 kubectl rollout status deployment/jerry-ui5 查看滚动升级的实时进展情况。上图显示的日志表明,在某个时间点,有多少个旧版本的 pod 正等待被终止,有多少个新版本的 pod 已经处于可用状态。
X old replicas are pending termination
X of Y updated replicas are available
任意点开一个 pod 查看明细,发现其使用的 docker 镜像已经是 v2.0 版本了:
最后在浏览器里看到订单明细页面的标题,后面已经出现(v2.0), 再次确认了滚动升级已经成功结束了。
本文介绍的只是 Kubernetes 特性的冰山一角,更多细节,有待我们去学习,毕竟 SAP 云平台即将支持 Kubernetes 环境了。感谢阅读。
看完上述内容,你们对怎样体会 Kubernetes 内容器的高可用性和弹性伸缩有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注丸趣 TV 行业资讯频道,感谢大家的支持。