英国DEVOXX。Kubernetes投入生产:蓝/绿部署,自动扩展和部署自动化。第2部分

Kubernetes是在集群生产环境中运行Docker容器的绝佳工具。但是,有些任务是Kubernetes无法解决的。由于在生产环境中进行频繁的部署,我们需要一个全自动的Blue / Green部署来避免此过程中的停机时间,这也需要外部HTTP请求和SSL上传。这需要与负载平衡器(例如ha-proxy)集成。另一个任务是在云中工作时Kubernetes集群本身的半自动扩展,例如,在晚上部分减少集群的规模。

尽管Kubernetes没有开箱即用的功能,但它提供了可用于解决此类问题的API。 Kubernetes集群自动蓝/绿部署和扩展工具是Cloud RTI开放源项目的一部分。

该视频记录本介绍了如何配置Kubernetes以及其他开放源代码组件,以实现生产就绪的环境,该环境可以接受git commit change commit中的代码而不会导致生产停机。



英国DEVOXX。 Kubernetes投入生产:蓝/绿部署,自动扩展和部署自动化。第1部分

因此,从外界访问您的应用程序之后,您可以开始完全配置自动化,即,将其带入可以执行git commit并确保该git commit在生产中结束的阶段。自然,在执行这些步骤时,在部署的实施中,我们不想面对停机时间。因此,Kubernetes中的任何自动化都始于API。



Kubernetes并不是可以有效地“开箱即用”使用的工具。当然,您可以执行此操作,使用kubectl等,但是API仍然是该平台上最有趣,最有用的功能。使用API​​作为功能集,您几乎可以访问Kubernetes中想要做的所有事情。 Kubectl本身也使用REST API。

这是REST,因此您可以使用任何语言和工具来使用此API,但是用户库将极大地方便您的生活。我的团队写了2个这样的库:一个用于Java / OSGi,一个用于Go。第二个并不经常使用,但是在任何情况下,这些有用的东西都可以使用。它们是部分许可的开源项目。有许多针对不同语言的此类库,因此您可以选择最合适的库。



因此,在着手进行部署自动化之前,您需要确保该过程不会造成任何停机。例如,我们的团队在一天中的大多数人都在充分利用其应用程序的情况下进行生产部署,因此避免此过程中的延迟非常重要。为了避免停机,使用了两种方法:蓝色/绿色部署或滚动更新滚动更新。在后一种情况下,如果您正在运行该应用程序的5个副本,则会逐个顺序更新它们。此方法效果很好,但是如果在部署过程中同时运行不同版本的应用程序,则此方法将无效。在这种情况下,您可以更新用户界面,而后端将使用旧版本,而应用程序将停止工作。因此,从编程的角度来看,在这样的条件下工作相当困难。

这是我们更喜欢使用蓝色/绿色部署来自动化应用程序部署的原因之一。使用这种方法,您必须确保在特定的时间点只有一个版本的应用程序处于活动状态。

蓝色/绿色部署机制如下。我们通过ha-proxy获得应用程序的流量,该流量将ha-proxy定向到正在运行的相同版本的应用程序副本。

进行新的部署时,我们使用随新组件一起提供的Deployer,它会部署新版本。部署应用程序的新版本意味着新的副本集正在“崛起”,此后,新版本的这些副本将在单独的新容器中启动。但是,ha-proxy对它们一无所知,到目前为止,还没有向他们发送任何工作量。

因此,首先,有必要检查新版本的运行状况检查的运行状况,以确保副本已准备好服务于负载。



所有部署组件都必须支持某种形式的运行状况检查。当您收到状态码为200的代码时,这可以是一个非常简单的HTTP检查,也可以是调用,或者是更深入的检查,其中您检查副本与数据库和其他服务的连接,动态环境的连接稳定性,是否一切正常启动和工作正常。这个过程可能非常复杂。



系统验证所有更新的副本均正常运行后,Deployer将更新配置并传递正确的confd,该配置将重新配置ha-proxy。



只有在此之后,流量才会通过新版本的副本定向到下面,而旧版本的副本将消失。



该机制不是Kubernetes的功能。蓝色/绿色部署概念已经存在了很长一段时间,并且一直使用负载平衡器。首先,将所有流量定向到该应用程序的旧版本,然后在升级后,将其完全传输到新版本。该原理不仅在Kubernetes中使用。

现在,我将向您介绍一个新的部署组件-Deployer,该组件将执行运行状况检查,重新配置代理等等。这个概念不适用于外部世界,存在于Kubernetes内部。我将展示如何使用开源工具创建自己的Deployer概念。

因此,Deployer要做的第一件事是使用Kubernetes API创建RC复制控制器。该API创建了Pod和服务以进行进一步的部署,也就是说,它为我们的应用程序创建了一个全新的集群。 RC验证副本已启动后,它将检查其运行状况检查。为此,Deployer使用GET / health命令。它启动相应的验证组件,并验证确保集群运行的所有元素。



在所有Pod报告其“运行状况”之后,Deployer将创建一个新的配置项目-分布式存储etcd,该配置项在Kubernetes内部使用,包括存储负载均衡器配置。我们将数据写入etcd,并使用小型工具confd监视etcd中的新数据。

如果发现对初始配置有任何更改,他将生成一个新的设置文件,并将其传递给ha-proxy。在这种情况下,ha-proxy会重新启动而不会丢失任何连接,并使用提供我们应用程序新版本的新服务来解决负载问题。



如您所见,尽管组件很多,但没有什么复杂的。您只需要更加注意API和etcd。我想告诉您我们自己使用的开源部署程序-这是Amdatu Kubernetes Deployer。



这是具有以下功能的Kubernetes部署流程工具:

  • 蓝色/绿色部署
  • 设置一个外部负载均衡器;
  • 部署描述符管理
  • 实际部署管理
  • 部署期间的运行状况检查
  • 在Pod中执行环境变量。

在Kubernetes API的基础上创建的此部署程序提供了一个REST API,用于管理描述符和部署,以及一个Websocket API,用于在部署期间进行流日志。

它将负载均衡器配置数据放入etcd中,因此不能在“开箱即用”支持下使用ha-proxy,但是使用自己的均衡器配置文件很容易。就像Kubernetes本身一样,Amdatu Deployer用Go编写,并由Apache许可。

在使用此版本的部署程序之前,我使用了以下部署描述符,该描述符指定了我需要的参数。



该代码的重要参数之一是启用“ useHealthCheck”标志。我们需要指出在部署过程中需要运行状况检查。当部署使用不需要验证的第三方容器时,可以关闭此选项。此描述符还指示ha-proxy需要的副本数和前端URL。最后是podspec pod的规格标志,它调用Kubernetes获取有关端口配置,映像等的信息。这是JSON格式的相当简单的描述符。

作为Amdatu开源项目一部分的另一个工具是Deploymentctl。它具有用于配置部署的用户界面UI,存储部署历史记录,并包含用于第三方用户和开发人员回调的Webhooks。由于Amdatu Deployer本身是REST API,因此无法使用UI,但是此接口可以使您更轻松地部署而不涉及任何API。 Deploymentctl是使用Angular 2用OSGi / Vertx编写的。

现在,我将使用预制的录音在屏幕上演示上述内容,因此您不必等待。我们将在Go上部署一个简单的应用程序。不用担心,如果您以前从未接触过Go,那么这是一个非常简单的应用程序,因此您应该了解所有内容。



在这里,我们创建一个仅响应/运行状况的HTTP服务器,因此此应用程序仅检查运行状况检查,而没有其他检查。如果检查通过,则会调用下面显示的JSON结构。它包含将由部署者部署的应用程序的版本,在文件顶部看到的消息以及布尔逻辑数据类型(无论我们的应用程序是否正常工作)。

我在最后一行作弊,因为我在文件的顶部放置了一个固定的布尔值,这在将来甚至可以帮助我部署“不健康的”应用程序。我们稍后会处理。

因此,让我们开始吧。首先,我们使用〜kubectl get pods命令检查所有正在运行的Pod,如果前端URL没有响应,请确保当前未执行任何部署。



接下来,在屏幕上,您会看到我提到的Deploymentctl接口,其中设置了部署参数:名称空间,应用程序名称,部署版本,副本数量,前端URL,容器名称,图像,资源限制,用于检查运行状况检查的端口号等。 。资源限制非常重要,因为它们使您可以使用最大数量的“铁”。您还可以在此处查看“部署日志”部署日志。



如果立即重复执行〜kubectl get pods命令,您会看到系统“冻结”了20秒钟,在此期间进行了ha-proxy重新配置。之后,它开始在下面,并且我们的副本可以在部署日志中看到。



我从视频中删除了20秒的等待时间,现在您在屏幕上看到已部署了该应用程序的第一个版本。所有这些仅在UI的帮助下完成。



现在,让我们尝试第二个版本。为此,我用“你好,Kubernetes!”更改应用程序的消息。到“ Hello,Deployer!”,系统将创建此映像并将其放置在Docker注册表中,此后,我们只需再次单击Deploymentctl窗口中的“ Deploy”按钮即可。在这种情况下,部署日志将以与部署应用程序的第一个版本时相同的方式自动启动。



〜kubectl get pods命令显示该应用程序的两个版本当前正在运行,但是前端显示我们仍在运行版本1。



负载平衡器将等待直到执行运行状况检查,然后将流量重定向到新版本。 20秒后,我们切换到curl,看到现在我们已经部署了应用程序的版本2,并且第一个已删除。



这是一个“健康”(健康)应用程序的部署。让我们看看如果对于新版本的应用程序,我将Healthy参数的值从true更改为false,也就是说,我将尝试部署未通过运行状况检查的不健康的应用程序。如果在开发阶段在应用程序中犯了一些配置错误,并以这种形式投入生产,则可能会发生这种情况。

如您所见,部署过程通过上述所有步骤完成,〜kubectl get pods显示两个pod都在运行。但是与以前的部署不同,该日志显示了超时状态。也就是说,由于没有通过运行状况检查,因此无法部署该应用程序的新版本。结果,您看到系统恢复使用该应用程序的旧版本,而新版本仅被删除。



这样做的好处是,即使有大量同时请求进入应用程序,它们也不会在部署过程的实施过程中注意到停机时间。如果使用加特林框架测试该应用程序,该框架向该应用程序发送最大可能的请求数,则不会丢弃这些请求之一。这意味着我们的用户甚至不会注意到实时版本更新。如果失败,将继续使用旧版本;如果成功,则用户将切换到新版本。

只有一件事会导致失败-如果运行状况检查成功,并且应用程序在收到工作负载后便崩溃了,也就是说,崩溃只会在部署完成后才会发生。在这种情况下,您将必须手动回滚到旧版本。因此,我们研究了如何在其开源工具中使用Kubernetes。如果将这些工具嵌入到Build / Deploy管道创建/部署管道中,则部署过程将更加简单。同时,要开始部署,可以同时使用用户界面和完全自动化此过程,例如,应用到主服务器。



我们的构建服务器构建服务器将创建一个Docker映像,将其粘贴到Docker Hub或您使用的任何其他注册表中。 Docker集线器支持webhook,因此我们可以通过Deployer启动远程部署,如上所示。因此,您可以在潜在生产中完全自动化应用程序的部署。

让我们继续下一个主题-扩展Kubernetes集群。我注意到,kubectl命令是缩放命令。在另一个的帮助下,您可以轻松地增加集群中的副本数量。但是,实际上,我们通常要增加节点数量,而不是节点数量。



同时,在工作时间内,您可能需要增加费用,而在晚上,则需要减少Amazon服务成本,减少正在运行的应用程序实例的数量。这并不意味着只有足够数量的Pod可以扩展,因为即使其中一个节点不忙,您仍然必须为此付费。也就是说,除了扩展炉床外,还需要扩展使用的计算机数量。

这可能很棘手,因为无论我们使用亚马逊还是其他云服务,Kubernetes都不知道所用机器的数量。它缺少允许您在节点级别扩展系统的工具。



因此,我们将不得不照顾节点和豆荚。我们可以使用AWS API和Scaling组机器轻松配置新节点的启动规模,以配置Kubernetes工作节点的数量。您还可以使用cloud-init或类似脚本在Kubernetes集群中注册节点。

新计算机将在Scaling组中启动,将自身启动为一个节点,在向导的注册表中注册并开始工作。之后,您可以增加在结果节点上使用的副本数。减小规模需要付出更多的努力,因为您需要确保在关闭“不必要的”计算机后,此步骤不会导致破坏已经在运行的应用程序。为避免这种情况,您需要将节点置于“不可计划”状态。这意味着在调度DaemonSet Pod时,默认调度程序将忽略这些节点。调度程序不会从这些服务器中删除任何内容,但也不会在那里启动任何新容器。下一步是移动排水节点,即将工作炉床从排水节点转移到另一台机器或对此具有足够容量的其他节点。确认这些节点上没有更多容器之后,可以从Kubernetes中删除它们。在那之后,对于Kubernetes来说,它们根本就不复存在了。接下来,您需要使用AWS API禁用不必要的节点或计算机。
您可以使用Amdatu Scalerd,这是另一个类似于AWS API的开源扩展工具。它提供用于添加或删除集群中节点的CLI。它有趣的功能是可以使用以下json文件配置调度程序。



显示的代码在夜间将集群的容量减半。它配置为可用副本的数量以及所需的Amazon集群容量。使用此调度程序将自动减少晚上的节点数量,并在早晨自动增加节点数量,从而节省了使用诸如Amazon之类的云服务节点的成本。该功能不是Kubernetes内置的功能,但是使用Scalerd将允许您根据需要扩展该平台。

我想引起您的注意,许多人告诉我:“这一切都很好,但是我的数据库通常处于静态状态呢?”我如何在Kubernetes这样的动态环境中运行类似的东西?我认为,您不应这样做,也不应尝试在Kubernetes中组织数据仓库的操作。从技术上讲,这是可能的,并且互联网上有关于此主题的手册,但这会使您的生活严重复杂化。

是的,Kubernetes中存在持久性存储的概念,您可以尝试运行诸如Mongo或MySQL之类的数据仓库,但这是一项非常耗时的任务。这是由于以下事实:数据仓库不完全支持与动态环境的交互。大多数数据库都需要进行重大调整,包括手动配置集群,而不喜欢自动扩展和其他类似的功能。
因此,尝试在Kubernetes中启动数据仓库时,请不要使您的生活复杂化。使用熟悉的服务以传统方式来组织他们的工作,并为Kubernetes提供使用它们的机会。



在本主题的最后,我想向您介绍基于我的团队正在研究的Kubernetes的Cloud RTI平台。它提供集中式日志记录,监视应用程序和集群,并具有许多对您有用的有用功能。它使用各种开源工具(例如Grafana)来显示监视。





提出了一个问题,为什么要在Kubernetes中使用ha-proxy负载均衡器。很好的问题,因为当前有2个级别的负载平衡。 Kubernetes服务仍然位于虚拟IP地址上。您不能将它们用于外部主机端口,因为如果Amazon重新启动其云主机,则地址将更改。这就是为什么我们将ha-proxy服务放在服务的前面-创建一个更加静态的结构以与Kubernetes进行无缝流量交互。

另一个好的问题是,在进行蓝/绿部署时,如何处理更改数据库架构的问题?事实是,无论使用Kubernetes,更改数据库架构都是一项复杂的任务。您需要确保新旧方案的兼容性,然后可以更新数据库,然后再更新应用程序本身。您可以热交换数据库,然后升级应用程序。我知道有人下载了使用新方案的全新数据库集群,如果您拥有像Mongo这样的无方案数据库,那么这是一个选择,但是无论如何这都不是一件容易的事。如果没有其他问题,谢谢您的关注!


一点广告:)


感谢您与我们在一起。你喜欢我们的文章吗?想看更多有趣的资料吗?通过下订单或向您的朋友推荐以支持我们,开发人员的云VPS从4.99美元起这是我们为您发明的入门级服务器 独特类似物:关于VPS(KVM)E5-2697 v3(6核)的全部真相10GB DDR4 480GB SSD 1Gbps从$ 19还是如何划分服务器?(RAID1和RAID10提供选件,最多24个内核和最大40GB DDR4)。

阿姆斯特丹的Equinix Tier IV数据中心的戴尔R730xd便宜2倍吗?在荷兰2台Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100电视戴尔R420-2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB-$ 99起!阅读有关如何构建基础设施大厦的信息。使用Dell R730xd E5-2650 v4服务器花费一欧元9000欧元的c类?

All Articles