testops测试员的那点事软件测试

番外篇.基于GCP和Spinnaker玩转金丝雀环境

2019-06-24  本文已影响2人  KalvinDai

Spinnaker简介

Spinnaker是一款企业级持续交付工具,最初由Netflix构建,是优秀的项目套件Netflix OSS的一部分,用于部署Netflix应用。它是一个开源的多云持续交付平台,能够帮助开发人员快速、自信地发布软件更改。

Spinnaker将云原生部署策略视为一类构造,处理底层编排,比如验证健康检查、禁用旧服务器群组和启用新服务器群组。Spinnaker支持红/黑(又名“蓝/绿”)策略,以及在实时开发中实行红/黑和金丝雀策略。

安装Spinnaker

开启Api

我们的旅途开始于Google Cloud Platfrom,所以你要有一个GCP账号,体验账号有300刀和1年使用期限(google还是很大方呀),同时需要在GCP上需要开启下面三个Api:

Pub/Sub API
Cloud build API
Kubernetes API

启用了上述Api之后,单击云控制台右上角的链接打开Cloud Shell。

部署Spinnaker

gsutil cp gs://gke-spinnaker-codelab/install.tgz . 

tar -xvzf install.tgz

./setup.sh

链接到Spinnaker

执行connect脚本

./connect.sh

脚本内容

#!/usr/bin/env bash

PORT=8080
DECK_POD=$(kubectl get po -n spinnaker -l "cluster=spin-deck" \
  -o jsonpath="{.items[0].metadata.name}")

EXISTING_PID=$(sudo netstat -nlp | grep $PORT | awk '{print $7}' | cut -f1 -d '/')

if [ -n "$EXISTING_PID" ]; then
  echo "PID $EXISTING_PID already listening... restarting port-forward"
  kill $EXISTING_PID
  sleep 5
fi

kubectl port-forward $DECK_POD $PORT:9000 -n spinnaker >> /dev/null &

echo "Port opened on $PORT"
image

Spinnaker的界面

Application

image

这里的application,应当是一个完整的业务应用的概念,它包含若干个服务。

Clusters

image

Spinnaker中的Clusters选项卡聚合关于在集群中运行Kubernetes工作负载的信息。在导航到演示应用程序之后,应该已经选择了Clusters选项卡。

注意,我们有两个正在运行的服务:前端和后端。它们已经部署到两个环境中:生产环境和登台环境。试着点击其中一个绿色pod,如下所示

image

可以查看到具体的pod信息

image

Pipelines

虽然Clusters选项卡提供了要执行的特殊操作,以及关于正在运行的应用程序状态的信息,但是pipeline选项卡允许您配置可重复的自动化流程来更新正在运行的代码。

image

已经配置了三个流水线按顺序运行:

  1. 部署到Staging环境:这会将您的Kubernetes资源和构建的Docker映像部署到Staging环境,并在准备好接收流量时对正在运行的后端服务运行集成测试
  2. 在生产中部署Canary版本:这将从暂存中获取Kubernetes资源和Docker映像,并将它们部署为在生产环境中接收一小部分流量。
  3. 将Canary版本推到Production环境:这使您有机会在生产中验证您的金丝雀,如果您愿意,可以促使它接收所有生产流量。 完成后,将删除Canary。

要在我们自动触发它们之前了解这些流水线的作用,请选择Configure下拉列表,然后选择Deploy to Staging流水线:

image

您应该看到流水线概述,以及几个可配置的阶段:

image

示例程序

应用程序结构

示例的应用程序有一个前端和一个后端。他们是这样交流的:


image

每次用户发出请求时,前端都会提供一些静态内容以及有关为请求提供服务的后端的一些信息。 前端和后端都由部署管理,具有多个副本(Pod),并且由负载均衡器(服务)提供。 我们将使用它来演示如何使用Spinnaker中的共享流水线独立更新这两个服务。

查看前端服务

访问创建的前端服务的服务地址,可以看到对应的前端服务。

image

通过金丝雀版本发布前端变化

在〜/ services / frontend /文件夹中,对content / index.html进行编辑。 我们建议将style =“background-color:blue”更改为白色以使更新易于查看。

<!DOCTYPE html>
<html>
  <body style="background-color:white">
    <h2>Hello, world!</h2>
    <p>Message from the backend:</p>
    <p>{{.Message}}</p>
    <p>{{.Feature}}</p>
  </body>
</html>

这将在Google Container Builder中运行几分钟,并将更新的镜像推送到项目的容器仓库中。此事件将启动Deploy to Staging流水线。

cd ~/services/frontend/

./build.sh

观察“Deploy to Staging”流水线

理论上,当新镜像推送后,spinnaker的Deploy to Staging流水线应当被触发,但是:

第一次试,启动失败了,怀疑可能和之前创建Spinnaker有关,所以重建了集群。


image

第二次试,依然没有触发,提示“There was an error loading executions. We'll try again shortly.”发现是之前通过云终端连接的connet.sh停掉了,所以是前端无法访问了而已,去服务页面为Spinnaker的deck服务创建了负载均衡器。

第三次试,终于成功了


image

点击详情,可以查看当前流水线的详细情况,什么时间开始的,运行时间,以及当前状态。在DeployStatus页面,可以查看每个资源(service、deployment、configmap)的yaml。


image

在Deployment资源下面,点击Details,会跳转到Cluster页面,可以查看deployment的详细信息。


image

当最后一个流水线阶段变为橙色时,单击“Person”图标,然后单击“Continue”以批准并完成流水线。如果需要,可以按照舞台上显示的自定义说明操作。

image

表示新版本(背景已替换为白色)正在staging环境进行人工验证。


image

在staging环境,运行check脚本验证发布

#!/usr/bin/env bash

curl http://localhost:8001/api/v1/proxy/namespaces/staging/services/frontend:80/
image

注意,在Clusters选项卡上,staging中的frontend服务已经更新,现在指向您在上面的构建中创建的映像摘要。


image

观察“Deploy Simple Canary to Production”流水线

image

这条流水线的定义和之前的定义不同

一旦批准并完成了部署到Staging环境的过程,系统将自动通过Deploy Simple canary to Production将金丝雀部署到生产环境中。


image image

当点击暂停按钮时,则提示:


image

最后可以在Clusters选项卡上,快速检查它是否部署,如下所示。


image

在这一点上,让我们看看金丝雀是否有效。 使用~/services/frontend/get-ingress.sh脚本获取前端生产服务的IP地址,并在新选项卡中打开它。 如果经常刷新页面,颜色应在白色和蓝色之间交替。

Baseline Canary
image image

注意:外部服务的负载平衡策略并不完全是循环的,因此可能经常由同一个前端服务。不断地刷新页面有助于在前端节点之间进行切换。

这条流水线结束时的人工处理节点,“Manually Validate Canary Results”,如果一切顺利,手工确认通过,就像在之前的流水线中一样,会被发布到生产环境中。

image image

观察“Promote Canary to Production”流水线

上个流水线完成后,金丝雀将被部署到生产环境,Staging中的代码现在正在生产环境中运行,而金丝雀已经没有了,我们可以在Clusters选项卡上看到这一点。

image

当部署成功后,再去刷新前端页面,不管怎么刷新,都会显示新版本(白色背景)。

通过流水线发布配置变更

编辑配置

与我们签入代码更改以构建前端服务的Docker映像类似,现在我们将更新前端服务加载的ConfigMap,以启用应用程序的登录页面中的特性

# ... other manifests
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: frontend-config
  namespace: '${ namespace }'
data:
  BACKEND_ENDPOINT: 'http://backend.${ namespace }'
  FEATURE: "A new feature!"
---
# other manifests ... 

保存文件,并在~/services/manifest/目录中运行./update-frontend.sh脚本。更新后的清单将自动通过Pub/Sub将消息推送到Spinnaker。

update-frontend.sh脚本内容

#!/usr/bin/env bash

gsutil cp frontend.yml gs://*********/manifests/frontend.yml
image

当发生错误时,可以点击回滚按钮进行回滚操作


image image image

自动回滚

此时您已经注意到从源到生产的代码更改大约需要10分钟。 如果我们正在进行更严肃的集成测试,或者我们的服务需要更长时间才能启动,或者需要运行更长时间的金丝雀,这可能需要更长的时间。 在最糟糕的情况下,我们希望逃生舱尽快回滚。

让我们创建一个编译回滚策略的流水线,并允许您通过单击按钮回滚生产。

创建新的流水线

创建一个用于回滚的流水线


image
image

创建“Undo Rollout (Manifest)”阶段(stage)

点击“添加阶段”


image

选择“Undo Rollout (Manifest)”作为类型


image

在“Undo rollout (Manifest) Configuration”下填写如下字段:

Field Value
Stage Name Rollback the Frontend
Account my-kubernetes-account
Namespace production
Kind deployment
Name frontend-primary
image

在“执行选项”下,选择“停止此分支,当其他分支完成时流水线失败”。

image

执行选项:这些选项允许您配置各个分支如何影响整个流水线执行。 通过确保此分支不会立即使整个流水线失败,我们可以确保我们的回滚不会过早中断。

点击右下角的保存按钮

复制现有阶段

现在我们已经为前端配置了回滚策略,让我们使用快捷方式为后端也配置回滚策略。选择“复制现有阶段”

image

搜索刚刚创建的“Rollback the Frontend”,并选择刚刚配置的阶段

image

将名称编辑为“Rollback the Backend”,并使用“Depends On”对“Rollback the Frontend”的依赖关系

image

完成后,执行图应该如下所示

image image

手动试一下这个回滚流水线

会发现当流水线执行完毕后,生产环境的前端代码被恢复为旧版本(蓝色背景)。

结语

Spinnaker本身还有很多待发现的特性可以挖掘,本文只是搞了一个小玩意儿供大家把玩。对于生产服务来说,它同样能够带来巨大价值并帮助简化部署流程,这种黑科技,推荐大家有空自己动手玩一下。

上一篇下一篇

猜你喜欢

热点阅读