Review Apps

原文:https://docs.gitlab.com/ee/development/testing_guide/review_apps.html

Review Apps

Review Apps 由管道自动部署.

How does it work?

CI/CD architecture diagram

图 TD A [“ build-qa-image,编译生产资产 (仅适用于规范的默认参考)”]; B [review-build-cng]; C [review-deploy]; D [CNG-mirror]; E [review-qa-smoke]; A-> |一旦准备阶段已完成| BB -.-> |触发 CNG 镜像管道并等待其完成| DD -.-> |轮询直到完成| BB-> |一旦完成view-build-cng工作完成| CC-> |完成"审查-部署"工作| E 子图" 1\. gitlabpreparestage"结束子图" 2\. gitlabreview-prepare阶段" B 结束子图" 3\. gitlabreview` stage” C [“ review-deploy

Helm 使用云部署 Review App 由 CNG 镜像管道构建的本机映像.

Cloud Native 映像已部署到” review-apps” Kubernetes(GKE)集群,位于 GCPgitlab-review-apps项目中.”]结束子图” 4. gitlabqa stage” E [review-qa-smoke

gitlab-qa 对 Review App 运行冒烟套件.]结束子图” CNG 镜像管道” D>构建了 Cloud Native 图像]; 结束

Detailed explanation

  1. prepare阶段的每个管道上,都会自动启动compile-production-assets作业.
  2. 完成compile-production-assets后, review-build-cng作业将触发 CNG-mirror项目中的管道 .
    • 仅当您的 MR 包括CI 或前端更改时review-build-cng作业才会自动开始. 在其他情况下,该工作是手动的.
    • CNG-mirror管道基于GitLab 管道的提交创建每个组件(例如gitlab-rails-eegitlab-shellgitaly等)的 Docker 映像,并将它们存储在其注册表中 .
    • 我们使用CNG-mirror项目,以便CNG (Cloud Native GitLab)项目的注册表不会因大量临时 Docker 映像而过载.
    • 请注意,官方的 CNG 图像是由cloud-native-image作业构建的,该作业仅针对标签运行,并自身触发CNG管道.
  3. 完成review-build-cng后, review-deploy作业使用官方的 GitLab Helm 图表将 Review App 部署到 GCP 上的review-apps Kubernetes 集群.
  4. 一旦review-deploy作业成功,您应该可以使用您的 Review App,这要归功于 MR 小部件与它的直接链接. 要登录 Review App,请参阅”登录我的 Review App?”. 下面.

补充笔记:

  • 如果review-deploy工作持续失败(请注意,我们已经试了两次),请在发布消息#g_qe_engineering_productivity通道和/或创建~"Engineering Productivity" ~"ep::review apps" ~bug的问题有链接到您的合并请求. 请注意,部署失败可能会揭示合并请求中引入的实际问题(即,这不一定是暂时性失败)!
  • 如果review-qa-smoke作业仍然失败(请注意,我们已经重试了两次),请检查该作业的日志:您可能会发现合并请求中引入的实际问题. 您也可以下载工件,以查看发生故障时页面的屏幕截图. 如果您找不到失败的原因,或者看起来与更改无关,请在#quality频道中发布一条消息和/或创建#quality问题,并带有指向合并请求的链接.
  • 手动review-stop可用于手动停止复查应用,一旦合并请求的分支在合并后被删除,GitLab 也将启动手动review-stop .
  • 使用GitLab 的 Kubernetes 集成将 Kubernetes 集群连接到gitlab项目. 这基本上允许直接从合并请求窗口小部件链接到 Review App.

Auto-stopping of Review Apps

借助环境自动停止功能,Review Apps 在上次部署后 2 天会自动停止.

If you need your Review App to stay up for a longer time, you can pin its environment or retry the review-deploy job to update the “latest deployed at” time.

The review-cleanup job that automatically runs in scheduled pipelines (and is manual in merge request) stops stale Review Apps after 5 days, deletes their environment after 6 days, and cleans up any dangling Helm releases and Kubernetes resources after 7 days.

自动在计划的管道中运行的review-gcp-cleanup作业(在合并请求中手动执行)将删除所有未与 Kubernetes 资源一起删除的悬空 GCP 网络资源.

QA runs

qa阶段(在review阶段之后)的每个管道上, review-qa-smoke作业都会自动启动,并运行 QA 烟雾套件.

您也可以手动启动review-qa-all :它运行完整的质量检查套件.

Performance Metrics

在每一个管道qa阶段, review-performance作业自动启动:这项工作确实使用基本的浏览器性能测试Sitespeed.io 集装箱 .

Cluster configuration

Node pools

目前, review-apps集群使用以下节点池进行设置:

  • 具有自动e2-highcpu-16 (16 vCPU,16 GB 内存)可抢占节点

Helm

使用的 Helm 版本在registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-helm3-kubectl1.14映像中定义,由review-deployreview-stop作业使用.

How to

Get access to the GCP Review Apps cluster

您需要打开 gcp-review-apps-sg GCP 组的访问请求(内部链接) . 为了加入群组,您必须在访问请求中指定所需的 GCP 角色. 该角色将授予您特定的权限,以便与 Review App 容器进行交互.

Here are some permissions you may want to have, and the roles that grant them:

Log into my Review App

默认用户名是root ,其密码可以在名为gitlab-{ce,ee} Review App's root password的 1Password 安全注释中找到.

Enable a feature flag for my Review App

  1. 打开您的 Review App 并按照上述说明登录.
  2. 创建一个个人访问令牌.
  3. 使用Feature 标志 API启用功能标志 .

Find my Review App slug

  1. 打开review-deploy作业.
  2. 查找” Checking for previous deployment of review-* .
  3. 例如,对于Checking for previous deployment of review-qa-raise-e-12chm0在这种情况下,您的 Review App Checking for previous deployment of review-qa-raise-e-12chm0将为review-qa-raise-e-12chm0 .

Run a Rails console

  1. 确保首先具有访问群集container.pods.exec权限的权限.
  2. 根据您的 Review App review-qa-raise-e-12chm0 过滤工作量 ,例如review-qa-raise-e-12chm0 .
  3. 查找并打开task-runner部署,例如review-qa-raise-e-12chm0-task-runner .
  4. 单击”托管窗格”部分中的 Pod,例如review-qa-raise-e-12chm0-task-runner-d5455cc8-2lsvz .
  5. 点击KUBECTL下拉菜单,然后Exec - > task-runner .
  6. 从默认命令-it -- gitlab-rails console -c task-runner -- ls替换为-it -- gitlab-rails console ,或者
    • 运行kubectl exec --namespace review-apps review-qa-raise-e-12chm0-task-runner-d5455cc8-2lsvz -it -- gitlab-rails console
      • 用您的 Pod 名称替换review-qa-raise-e-12chm0-task-runner-d5455cc8-2lsvz .

Dig into a Pod’s logs

  1. 确保首先有权访问集群container.pods.getLogs权限.
  2. 根据您的 Review App review-qa-raise-e-12chm0 过滤工作量 ,例如review-qa-raise-e-12chm0 .
  3. 查找并打开migrations部署,例如review-qa-raise-e-12chm0-migrations.1 .
  4. 单击”托管窗格”部分中的 Pod,例如review-qa-raise-e-12chm0-migrations.1-nqwtx .
  5. 单击Container logs链接.

Diagnosing unhealthy Review App releases

如果Review App Stability下降,则可能表明Review review-apps-ce/ee集群不健康. 领先的指标可能是导致重新启动的运行状况检查失败或 Review App 部署的多数失败.

Review Apps Overview 仪表板可帮助确定群集上的负载峰值,以及节点是否有问题或整个群集是否趋于不正常.

Release failed with ImagePullBackOff

潜在原因:

如果看到ImagePullBackoff状态,请检查缺少的 Docker 映像.

在哪里寻找进一步的调试:

要检查是否已创建 Docker 映像,请运行以下 Docker 命令:

  1. `DOCKER_CLI_EXPERIMENTAL=enabled docker manifest repository:tag`

此命令的输出指示 Docker 映像是否存在. 例如:

  1. DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect registry.gitlab.com/gitlab-org/build/cng-mirror/gitlab-rails-ee:39467-allow-a-release-s-associated-milestones-to-be-edited-thro

如果 Docker 映像不存在:

  • 验证helm upgrade --install命令中的image.repositoryimage.tag选项是否与 CNG-mirror 管道使用的存储库名称匹配.
  • review-build-cng作业中进一步查看相应的下游 CNG 镜像管道.

Node count is always increasing (i.e. never stabilizing or decreasing)

潜在原因:

这可能表明review-cleanup作业未能清除过时的审查应用和 Kubernetes 资源.

在哪里寻找进一步的调试:

查看最新的review-cleanup作业日志,并确定是否存在任何意外故障.

p99 CPU utilization is at 100% for most of the nodes and/or many components

潜在原因:

这可能表明 Helm 无法部署 Review Apps. 当 Helm 有很多FAILED版本发布时,CPU 利用率似乎正在增加,这可能是由于 Helm 或 Kubernetes 试图重新创建组件所致.

在哪里寻找进一步的调试:

查看最近的review-deploy作业日志.

有用的命令:

  1. # Identify if node spikes are common or load on specific nodes which may get rebalanced by the Kubernetes scheduler
  2. kubectl top nodes | sort --key 3 --numeric
  3. # Identify pods under heavy CPU load
  4. kubectl top pods | sort --key 2 --numeric

The logging/user/events/FailedMount chart is going up

潜在原因:

这可能表明存在太多过时的机密和/或配置图.

在哪里寻找进一步的调试:

查看配置列表kubectl get secret,cm --sort-by='{.metadata.creationTimestamp}' | grep 'review-' kubectl get secret,cm --sort-by='{.metadata.creationTimestamp}' | grep 'review-' .

怀疑任何超过 5 天的机密或配置图,应将其删除.

有用的命令:

  1. # List secrets and config maps ordered by created date
  2. kubectl get secret,cm --sort-by='{.metadata.creationTimestamp}' | grep 'review-'
  3. # Delete all secrets that are 5 to 9 days old
  4. kubectl get secret --sort-by='{.metadata.creationTimestamp}' | grep '^review-' | grep '[5-9]d$' | cut -d' ' -f1 | xargs kubectl delete secret
  5. # Delete all secrets that are 10 to 99 days old
  6. kubectl get secret --sort-by='{.metadata.creationTimestamp}' | grep '^review-' | grep '[1-9][0-9]d$' | cut -d' ' -f1 | xargs kubectl delete secret
  7. # Delete all config maps that are 5 to 9 days old
  8. kubectl get cm --sort-by='{.metadata.creationTimestamp}' | grep 'review-' | grep -v 'dns-gitlab-review-app' | grep '[5-9]d$' | cut -d' ' -f1 | xargs kubectl delete cm
  9. # Delete all config maps that are 10 to 99 days old
  10. kubectl get cm --sort-by='{.metadata.creationTimestamp}' | grep 'review-' | grep -v 'dns-gitlab-review-app' | grep '[1-9][0-9]d$' | cut -d' ' -f1 | xargs kubectl delete cm

Using K9s

K9s是功能强大的命令行仪表板,可让您按标签过滤. 这可以帮助确定趋势超过审阅应用程序资源请求的应用程序 . Kubernetes 将根据资源请求将 Pod 调度到节点,并允许 CPU 使用量达到上限.

  • 在 K9s 中,您可以通过输入/字符来排序或添加过滤器
    • -lrelease=<review-app-slug> -过滤所有发布的 Pod. 这有助于确定单个部署中存在的问题
    • -lapp=<app> -筛选特定应用程序的所有 pod. 这有助于确定应用程序的资源使用情况.
  • 您可以滚动到 Kubernetes 资源并按d (描述), s (shell), l (日志)进行更深入的检查

K9s

Troubleshoot a pending dns-gitlab-review-app-external-dns Deployment

Finding the problem

过去 ,发生了dns-gitlab-review-app-external-dns部署处于挂起状态的情况,有效地阻止了所有 Review App 分配 DNS 记录,从而使它们无法通过域名访问.

反过来,这阻止了 Review App 的其他组件正常启动(例如gitlab-runner ).

经过一番挖掘后,我们发现在使用systemd-mount瞬时作用域(例如 pod)执行新安装时,新安装失败:

  1. MountVolume.SetUp failed for volume "dns-gitlab-review-app-external-dns-token-sj5jm" : mount failed: exit status 1
  2. Mounting command: systemd-run
  3. Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/pods/06add1c3-87b4-11e9-80a9-42010a800107/volumes/kubernetes.io~secret/dns-gitlab-review-app-external-dns-token-sj5jm --scope -- mount -t tmpfs tmpfs /var/lib/kubelet/pods/06add1c3-87b4-11e9-80a9-42010a800107/volumes/kubernetes.io~secret/dns-gitlab-review-app-external-dns-token-sj5jm
  4. Output: Failed to start transient scope unit: Connection timed out

这可能是因为 GitLab 图表创建了 67 个资源,导致在基础 GCP 节点上创建了许多安装点.

根本的问题似乎是一个systemd错误是固定在systemd v237 . 不幸的是,我们的 GCP 节点当前正在使用v232 .

记录下来,找出此问题的调试步骤是:

  1. 将 kubectl 上下文切换到 review-apps-ce(我们建议使用kubectx
  2. kubectl get pods | grep dns
  3. kubectl describe pod <pod name>并确认确切的错误消息
  4. 在兔子洞中找到相关的 Kubernetes 错误报告后 ,在网上搜索确切的错误消息
  5. 通过 GCP 控制台通过 SSH 访问节点( 计算机引擎> VM 实例,然后单击dns-gitlab-review-app-external-dns pod 运行的节点的” SSH”按钮)
  6. In the node: systemctl --version => systemd 232
  7. 收集更多信息:
    • mount | grep kube | wc -l mount | grep kube | wc -l =>例如 290
    • systemctl list-units --all | grep -i var-lib-kube | wc -l systemctl list-units --all | grep -i var-lib-kube | wc -l =>例如 142
  8. 检查多少个 Pod 处于不良状态:
    • 获取运行给定节点的所有 Pod: kubectl get pods --field-selector=spec.nodeName=NODE_NAME
    • 获取给定节点上的所有Running pods: kubectl get pods --field-selector=spec.nodeName=NODE_NAME | grep Running kubectl get pods --field-selector=spec.nodeName=NODE_NAME | grep Running
    • 在给定节点上获取所有处于不良状态的 Pod: kubectl get pods --field-selector=spec.nodeName=NODE_NAME | grep -v 'Running' | grep -v 'Completed' kubectl get pods --field-selector=spec.nodeName=NODE_NAME | grep -v 'Running' | grep -v 'Completed'

Solving the problem

为了解决该问题,我们需要(强制)耗尽一些节点:

  1. 在运行dns-gitlab-review-app-external-dns pod 的节点上尝试正常排水,以使 Kubernetes 自动将其移动到另一个节点: kubectl drain NODE_NAME
  2. 如果那不起作用,您还可以通过删除所有吊舱来强制”排水”节点: kubectl delete pods --field-selector=spec.nodeName=NODE_NAME
  3. 在节点中:
    • 执行systemctl daemon-reload以删除无效/无效的单元
    • 如果那不能解决问题,请执行硬重启: sudo systemctl reboot
  4. 取消封锁所有封锁的节点: kubectl uncordon NODE_NAME封锁kubectl uncordon NODE_NAME

同时,由于大多数 Review App 处于损坏状态,因此我们将其删除以清理非Running Pod 列表. 以下是一个命令,用于根据其上次部署日期(当前日期为当时的 6 月 6 日)删除 Review Apps,

  1. helm ls -d | grep "Jun 4" | cut -f1 | xargs helm delete --purge

Mitigation steps taken to avoid this problem in the future

我们用较小的计算机创建了一个新的节点池,这样一来,将来计算机就不太可能遇到”装载点过多”的问题.

Frequently Asked Questions

在每次测试运行时触发 CNG 映像生成是否过多? 这将创建数千个未使用的 Docker 映像.

我们必须从某个地方开始,以后再改进. 另外,我们正在使用 CNG-mirror 项目来存储这些 Docker 映像,以便我们可以在某个时候清除注册表,并使用一个新的,空的注册表.

我们如何确保它免受滥用? 应用程序向世界开放,因此我们需要找到一种方法将其限制为仅限我们自己.

This isn’t enabled for forks.

Other resources

Helpful command line tools

  • K9s-启用跨 Pod 的 CLI 仪表板并启用按标签过滤
  • 船尾 -基于标签/字段选择器启用跨 Pod 日志拖尾

Return to Testing documentation